diff options
-rw-r--r-- | include/clang/AST/Decl.h | 34 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 9 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 21 |
7 files changed, 65 insertions, 17 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index a131801f47..6c8c5051fe 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -3169,17 +3169,45 @@ public: /// DeclContext. class CapturedDecl : public Decl, public DeclContext { private: + /// \brief The number of parameters to the outlined function. + unsigned NumParams; + /// \brief The body of the outlined function. Stmt *Body; - explicit CapturedDecl(DeclContext *DC) - : Decl(Captured, DC, SourceLocation()), DeclContext(Captured) { } + explicit CapturedDecl(DeclContext *DC, unsigned NumParams) + : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), + NumParams(NumParams), Body(0) { } + + ImplicitParamDecl **getParams() const { + return reinterpret_cast<ImplicitParamDecl **>( + const_cast<CapturedDecl *>(this) + 1); + } public: - static CapturedDecl *Create(ASTContext &C, DeclContext *DC); + static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); Stmt *getBody() const { return Body; } void setBody(Stmt *B) { Body = B; } + ImplicitParamDecl *getParam(unsigned i) const { + assert(i < NumParams); + return getParams()[i]; + } + void setParam(unsigned i, ImplicitParamDecl *P) { + assert(i < NumParams); + getParams()[i] = P; + } + + /// \brief Retrieve the parameter containing captured variables. + ImplicitParamDecl *getContextParam() const { return getParam(0); } + void setContextParam(ImplicitParamDecl *P) { setParam(0, P); } + + typedef ImplicitParamDecl **param_iterator; + /// \brief Retrieve an iterator pointing to the first parameter decl. + param_iterator param_begin() const { return getParams(); } + /// \brief Retrieve an iterator one past the last parameter decl. + param_iterator param_end() const { return getParams() + NumParams; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Captured; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index c8cc6964bd..b232b59d3c 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -29,6 +29,7 @@ class CapturedDecl; class CXXMethodDecl; class ObjCPropertyDecl; class IdentifierInfo; +class ImplicitParamDecl; class LabelDecl; class ReturnStmt; class Scope; @@ -506,13 +507,17 @@ public: RecordDecl *TheRecordDecl; /// \brief This is the enclosing scope of the captured region. Scope *TheScope; + /// \brief The implicit parameter for the captured variables. + ImplicitParamDecl *ContextParam; /// \brief The kind of captured region. CapturedRegionKind CapRegionKind; CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, - RecordDecl *RD, CapturedRegionKind K) + RecordDecl *RD, ImplicitParamDecl *Context, + CapturedRegionKind K) : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), - TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), CapRegionKind(K) + TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), + ContextParam(Context), CapRegionKind(K) { Kind = SK_CapturedRegion; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ab8ad51a0a..f9475737a1 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2796,11 +2796,12 @@ public: StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - CapturedRegionKind Kind); + CapturedRegionKind Kind, unsigned NumParams); StmtResult ActOnCapturedRegionEnd(Stmt *S); void ActOnCapturedRegionError(bool IsInstantiation = false); RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, - SourceLocation Loc); + SourceLocation Loc, + unsigned NumParams); const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, bool AllowFunctionParameters); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a431c5317e..01fbc3b2e0 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3247,8 +3247,10 @@ MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, 0, 0); } -CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC) { - return new (C) CapturedDecl(DC); +CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, + unsigned NumParams) { + unsigned Size = sizeof(CapturedDecl) + NumParams *sizeof(ImplicitParamDecl*); + return new (C.Allocate(Size)) CapturedDecl(DC, NumParams); } EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 0ecd11ec97..ef43c5b4b7 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -136,7 +136,8 @@ StmtResult Parser::HandlePragmaCaptured() SourceLocation Loc = Tok.getLocation(); ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); - Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default); + Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, + /*NumParams=*/1); StmtResult R = ParseCompoundStatement(); CapturedRegionScope.Exit(); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index e9a8582183..72864c5dd0 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -1316,8 +1316,8 @@ IdentifierInfo *Sema::getSuperIdentifier() const { void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K) { - CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), - S, CD, RD, K); + CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), S, CD, RD, + CD->getContextParam(), K); CSI->ReturnType = Context.VoidTy; FunctionScopes.push_back(CSI); } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index f91305f072..70960faf99 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2922,8 +2922,8 @@ StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, } RecordDecl* -Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc) -{ +Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, + unsigned NumParams) { DeclContext *DC = CurContext; while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) DC = DC->getParent(); @@ -2938,9 +2938,20 @@ Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc) RD->setImplicit(); RD->startDefinition(); - CD = CapturedDecl::Create(Context, CurContext); + CD = CapturedDecl::Create(Context, CurContext, NumParams); DC->addDecl(CD); + // Build the context parameter + assert(NumParams > 0 && "CapturedStmt requires context parameter"); + DC = CapturedDecl::castToDeclContext(CD); + IdentifierInfo *VarName = &Context.Idents.get("__context"); + QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD)); + ImplicitParamDecl *Param + = ImplicitParamDecl::Create(Context, DC, Loc, VarName, ParamType); + DC->addDecl(Param); + + CD->setContextParam(Param); + return RD; } @@ -2970,9 +2981,9 @@ static void buildCapturedStmtCaptureList( } void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - CapturedRegionKind Kind) { + CapturedRegionKind Kind, unsigned NumParams) { CapturedDecl *CD = 0; - RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc); + RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams); // Enter the capturing scope for this captured region. PushCapturedRegionScope(CurScope, CD, RD, Kind); |