aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Decl.h34
-rw-r--r--include/clang/Sema/ScopeInfo.h9
-rw-r--r--include/clang/Sema/Sema.h5
-rw-r--r--lib/AST/Decl.cpp6
-rw-r--r--lib/Parse/ParsePragma.cpp3
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/SemaStmt.cpp21
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);