]> granicus.if.org Git - clang/commitdiff
Move CapturedStmt parameters to CapturedDecl
authorBen Langmuir <ben.langmuir@intel.com>
Fri, 3 May 2013 19:00:33 +0000 (19:00 +0000)
committerBen Langmuir <ben.langmuir@intel.com>
Fri, 3 May 2013 19:00:33 +0000 (19:00 +0000)
Move the creation of CapturedStmt parameters out of CodeGen and into
Sema, making it easier to customize the outlined function. The
ImplicitParamDecls are stored in the CapturedDecl using an
ASTContext-allocated array.

Differential Revision: http://llvm-reviews.chandlerc.com/D722

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181043 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
include/clang/Sema/ScopeInfo.h
include/clang/Sema/Sema.h
lib/AST/Decl.cpp
lib/Parse/ParsePragma.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaStmt.cpp

index a131801f4745cd5ddb95d69563755e0b7ea0b626..6c8c5051fe755944aa4041ad5ef9d405ade8eee3 100644 (file)
@@ -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; }
index c8cc6964bd76573e336291cb454e2870a8ac88f5..b232b59d3c17d6e83f6ec78da85820e09b2694ec 100644 (file)
@@ -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;
   }
index ab8ad51a0aca50b2d617862b384cfcae7824e5e5..f9475737a14e42ce16a41da1779878c5ede06c85 100644 (file)
@@ -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);
 
index a431c5317e05e3f2073b5ee6a7de93998e694cd7..01fbc3b2e0dc7e133195d1576d6c566c3b54533b 100644 (file)
@@ -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,
index 0ecd11ec97fcd49468c7d5a39b34e9976502ec1c..ef43c5b4b752eb2bf9a8c506d529bf6c4d9f5e69 100644 (file)
@@ -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();
index e9a85821830b457fb2e0152828a84ff984f7249c..72864c5dd09d72c21a011a7ba94c8ff630b3d53d 100644 (file)
@@ -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);
 }
index f91305f072a34e9cc5822b79aac6c891aca502bb..70960faf99b7f6a42676d3ffc2cf59760335b307 100644 (file)
@@ -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);