diff options
author | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 19:37:38 +0000 |
---|---|---|
committer | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 19:37:38 +0000 |
commit | 6afcf8875d4e447645cd7bf3733dd8e2eb8455dc (patch) | |
tree | 492ea5c7e442ea915d1f9feeafc8b24624942d96 /include/clang/AST | |
parent | 596eea7cc26979c952a0b177d024787a99b299df (diff) |
Sema for Captured Statements
Add CapturedDecl to be the DeclContext for CapturedStmt, and perform semantic
analysis. Currently captures all variables by reference.
TODO: templates
Author: Ben Langmuir <ben.langmuir@intel.com>
Differential Revision: http://llvm-reviews.chandlerc.com/D433
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179618 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/Decl.h | 26 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 1 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 17 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 10 |
4 files changed, 46 insertions, 8 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 4260ab0bb2..f7286a0388 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -3165,6 +3165,32 @@ public: } }; +/// \brief This represents the body of a CapturedStmt, and serves as its +/// DeclContext. +class CapturedDecl : public Decl, public DeclContext { +private: + Stmt *Body; + + explicit CapturedDecl(DeclContext *DC) + : Decl(Captured, DC, SourceLocation()), DeclContext(Captured) { } + +public: + static CapturedDecl *Create(ASTContext &C, DeclContext *DC); + + Stmt *getBody() const { return Body; } + void setBody(Stmt *B) { Body = B; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Captured; } + static DeclContext *castToDeclContext(const CapturedDecl *D) { + return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D)); + } + static CapturedDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC)); + } +}; + /// \brief Describes a module import declaration, which makes the contents /// of the named module visible in the current translation unit. /// diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index a3e69c0af2..bceb703060 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1046,6 +1046,7 @@ public: bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: + case Decl::Captured: case Decl::ObjCMethod: return true; default: diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 9b4e481bfd..df41b6fa5a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1228,8 +1228,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { for (DeclContext::decl_iterator Child = DC->decls_begin(), ChildEnd = DC->decls_end(); Child != ChildEnd; ++Child) { - // BlockDecls are traversed through BlockExprs. - if (!isa<BlockDecl>(*Child)) + // BlockDecls and CapturedDecls are traversed through BlockExprs and + // CapturedStmts respectively. + if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child)) TRY_TO(TraverseDecl(*Child)); } @@ -1258,6 +1259,14 @@ DEF_TRAVERSE_DECL(BlockDecl, { return true; }) +DEF_TRAVERSE_DECL(CapturedDecl, { + TRY_TO(TraverseStmt(D->getBody())); + // This return statement makes sure the traversal of nodes in + // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) + // is skipped - don't remove it. + return true; + }) + DEF_TRAVERSE_DECL(EmptyDecl, { }) DEF_TRAVERSE_DECL(FileScopeAsmDecl, { @@ -2218,7 +2227,9 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { DEF_TRAVERSE_STMT(SEHTryStmt, {}) DEF_TRAVERSE_STMT(SEHExceptStmt, {}) DEF_TRAVERSE_STMT(SEHFinallyStmt,{}) -DEF_TRAVERSE_STMT(CapturedStmt, {}) +DEF_TRAVERSE_STMT(CapturedStmt, { + TRY_TO(TraverseDecl(S->getCapturedDecl())); +}) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { }) DEF_TRAVERSE_STMT(OpaqueValueExpr, { }) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index c2cfaa486c..019e678620 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -31,9 +31,9 @@ namespace llvm { namespace clang { class ASTContext; class Attr; + class CapturedDecl; class Decl; class Expr; - class FunctionDecl; class IdentifierInfo; class LabelDecl; class ParmVarDecl; @@ -1959,7 +1959,7 @@ private: unsigned NumCaptures; /// \brief The implicit outlined function. - FunctionDecl *TheFuncDecl; + CapturedDecl *TheCapturedDecl; /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl. RecordDecl *TheRecordDecl; @@ -1967,7 +1967,7 @@ private: /// \brief Construct a captured statement. CapturedStmt(Stmt *S, ArrayRef<Capture> Captures, ArrayRef<Expr *> CaptureInits, - FunctionDecl *FD, RecordDecl *RD); + CapturedDecl *CD, RecordDecl *RD); /// \brief Construct an empty captured statement. CapturedStmt(EmptyShell Empty, unsigned NumCaptures); @@ -1982,7 +1982,7 @@ public: static CapturedStmt *Create(ASTContext &Context, Stmt *S, ArrayRef<Capture> Captures, ArrayRef<Expr *> CaptureInits, - FunctionDecl *FD, RecordDecl *RD); + CapturedDecl *CD, RecordDecl *RD); static CapturedStmt *CreateDeserialized(ASTContext &Context, unsigned NumCaptures); @@ -1994,7 +1994,7 @@ public: } /// \brief Retrieve the outlined function declaration. - const FunctionDecl *getCapturedFunctionDecl() const { return TheFuncDecl; } + CapturedDecl *getCapturedDecl() const { return TheCapturedDecl; } /// \brief Retrieve the record declaration for captured variables. const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } |