diff options
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r-- | include/clang/AST/DeclCXX.h | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 46136c3bab..2b56871810 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_DECLCXX_H #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Decl.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" @@ -555,6 +556,40 @@ class CXXRecordDecl : public RecordDecl { } } *DefinitionData; + /// \brief Describes a C++ closure type (generated by a lambda expression). + struct LambdaDefinitionData : public DefinitionData { + typedef LambdaExpr::Capture Capture; + + LambdaDefinitionData(CXXRecordDecl *D) + : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0), Extra(0) { + IsLambda = true; + } + + /// \brief The number of captures in this lambda. + unsigned NumCaptures : 16; + + /// \brief The number of explicit captures in this lambda. + unsigned NumExplicitCaptures : 16; + + /// \brief The "extra" data associated with the lambda, including + /// captures, capture initializers, and the body of the lambda. + void *Extra; + + /// \brief Allocate the "extra" data associated with a lambda definition. + void allocateExtra(ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, + Stmt *Body); + + /// \brief Retrieve the set of captures. + Capture *getCaptures() const { return reinterpret_cast<Capture *>(Extra); } + + /// \brief Retrieve the set of stored statements, which contains the capture + /// initializers followed by the body of the lambda. + Stmt **getStoredStmts() const { + return reinterpret_cast<Stmt **>(getCaptures() + NumCaptures); + } + }; + struct DefinitionData &data() { assert(DefinitionData && "queried property of class with no definition"); return *DefinitionData; @@ -565,6 +600,13 @@ class CXXRecordDecl : public RecordDecl { return *DefinitionData; } + struct LambdaDefinitionData &getLambdaData() const { + assert(DefinitionData && "queried property of lambda with no definition"); + assert(DefinitionData->IsLambda && + "queried lambda property of non-lambda class"); + return static_cast<LambdaDefinitionData &>(*DefinitionData); + } + /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. /// @@ -578,6 +620,7 @@ class CXXRecordDecl : public RecordDecl { TemplateOrInstantiation; friend class DeclContext; + friend class LambdaExpr; /// \brief Notify the class that member has been added. /// @@ -647,6 +690,8 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); + static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, + SourceLocation Loc); static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); bool isDynamicClass() const { @@ -928,12 +973,6 @@ public: /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { return hasDefinition() && data().IsLambda; } - /// \brief Mark this as a closure type from a lambda expression. - void makeLambda() { data().IsLambda = true; } - - /// \brief Set the lambda expression associated with this closure type. - void setLambda(LambdaExpr *Lambda); - /// \brief For a closure type, retrieve the mapping from captured /// variables and this to the non-static data members that store the /// values or references of the captures. |