diff options
Diffstat (limited to 'include/clang')
-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 | ||||
-rw-r--r-- | include/clang/Basic/DeclNodes.td | 1 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 50 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 15 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 2 |
9 files changed, 114 insertions, 11 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; } diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index ebcd81252f..ad2afa7a57 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -73,6 +73,7 @@ def Friend : Decl; def FriendTemplate : Decl; def StaticAssert : Decl; def Block : Decl, DeclContext; +def Captured : Decl, DeclContext; def ClassScopeFunctionSpecialization : Decl; def Import : Decl; def OMPThreadPrivate : Decl; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index cfb1798def..fd9ea51df5 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4804,6 +4804,9 @@ let CategoryName = "Lambda Issue" in { "here">; } +def err_return_in_captured_stmt : Error< + "cannot return from %0">; + def err_operator_arrow_circular : Error< "circular pointer delegation detected">; def err_pseudo_dtor_base_not_scalar : Error< diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 2295bf437c..a48422a308 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -24,6 +24,7 @@ namespace clang { class Decl; class BlockDecl; +class CapturedDecl; class CXXMethodDecl; class ObjCPropertyDecl; class IdentifierInfo; @@ -73,7 +74,8 @@ protected: enum ScopeKind { SK_Function, SK_Block, - SK_Lambda + SK_Lambda, + SK_CapturedRegion }; public: @@ -319,7 +321,8 @@ public: class CapturingScopeInfo : public FunctionScopeInfo { public: enum ImplicitCaptureStyle { - ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block + ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, + ImpCap_CapturedRegion }; ImplicitCaptureStyle ImpCaptureStyle; @@ -461,7 +464,8 @@ public: } static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; + return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda + || FSI->Kind == SK_CapturedRegion; } }; @@ -492,6 +496,46 @@ public: } }; +/// \brief Retains information about a captured region. +class CapturedRegionScopeInfo: public CapturingScopeInfo { +public: + + enum CapturedRegionKind { + CR_Default + }; + + /// \brief The CapturedDecl for this statement. + CapturedDecl *TheCapturedDecl; + /// \brief The captured record type. + RecordDecl *TheRecordDecl; + /// \brief This is the enclosing scope of the captured region. + Scope *TheScope; + /// \brief The kind of captured region. + CapturedRegionKind CapRegionKind; + + CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, + RecordDecl *RD, CapturedRegionKind K) + : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), + TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), CapRegionKind(K) + { + Kind = SK_CapturedRegion; + } + + virtual ~CapturedRegionScopeInfo(); + + /// \brief A descriptive name for the kind of captured region this is. + StringRef getRegionName() const { + switch (CapRegionKind) { + case CR_Default: + return "default captured statement"; + } + } + + static bool classof(const FunctionScopeInfo *FSI) { + return FSI->Kind == SK_CapturedRegion; + } +}; + class LambdaScopeInfo : public CapturingScopeInfo { public: /// \brief The class that describes the lambda. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 01e646ef4d..f95d6a4321 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -37,6 +37,7 @@ #include "clang/Sema/LocInfoType.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Ownership.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/TypoCorrection.h" #include "clang/Sema/Weak.h" #include "llvm/ADT/ArrayRef.h" @@ -65,6 +66,7 @@ namespace clang { class ArrayType; class AttributeList; class BlockDecl; + class CapturedDecl; class CXXBasePath; class CXXBasePaths; class CXXBindTemporaryExpr; @@ -174,6 +176,7 @@ namespace clang { namespace sema { class AccessedEntity; class BlockScopeInfo; + class CapturedRegionScopeInfo; class CapturingScopeInfo; class CompoundScopeInfo; class DelayedDiagnostic; @@ -916,6 +919,9 @@ public: void PushFunctionScope(); void PushBlockScope(Scope *BlockScope, BlockDecl *Block); void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator); + void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, + RecordDecl *RD, + sema::CapturedRegionScopeInfo::CapturedRegionKind K); void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0, const Decl *D = 0, const BlockExpr *blkExpr = 0); @@ -936,6 +942,9 @@ public: /// \brief Retrieve the current lambda expression, if any. sema::LambdaScopeInfo *getCurLambda(); + /// \brief Retrieve the current captured region, if any. + sema::CapturedRegionScopeInfo *getCurCapturedRegion(); + /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } @@ -2767,6 +2776,12 @@ public: StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); + void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, + sema::CapturedRegionScopeInfo::CapturedRegionKind Kind); + StmtResult ActOnCapturedRegionEnd(Stmt *S); + void ActOnCapturedRegionError(bool IsInstantiation = false); + RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, + SourceLocation Loc); const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, bool AllowFunctionParameters); diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 04d6a85860..9f5e8b1224 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -963,6 +963,8 @@ namespace clang { DECL_FILE_SCOPE_ASM, /// \brief A BlockDecl record. DECL_BLOCK, + /// \brief A CapturedDecl record. + DECL_CAPTURED, /// \brief A record that stores the set of declarations that are /// lexically stored within a given DeclContext. /// |