/// 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; }
class CXXMethodDecl;
class ObjCPropertyDecl;
class IdentifierInfo;
+class ImplicitParamDecl;
class LabelDecl;
class ReturnStmt;
class Scope;
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;
}
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);
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,
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();
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);
}
}
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();
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;
}
}
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);