Fixing patch.  I used arc incorrectly and sent a partial patch.

Hi doug.gregor, wei.pan, rjmccall,

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

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D722?vs=1779&id=1782#toc

Files:
  include/clang/AST/Decl.h
  include/clang/Sema/ScopeInfo.h
  include/clang/Sema/Sema.h
  lib/AST/Decl.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParsePragma.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaStmt.cpp
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -3169,17 +3169,45 @@
 /// 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: include/clang/Sema/ScopeInfo.h
===================================================================
--- include/clang/Sema/ScopeInfo.h
+++ include/clang/Sema/ScopeInfo.h
@@ -29,6 +29,7 @@
 class CXXMethodDecl;
 class ObjCPropertyDecl;
 class IdentifierInfo;
+class ImplicitParamDecl;
 class LabelDecl;
 class ReturnStmt;
 class Scope;
@@ -506,13 +507,17 @@
   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: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2783,11 +2783,12 @@
   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: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -3239,8 +3239,10 @@
                                   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: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -136,7 +136,7 @@
   case Stmt::GCCAsmStmtClass:   // Intentional fall-through.
   case Stmt::MSAsmStmtClass:    EmitAsmStmt(cast<AsmStmt>(*S));           break;
   case Stmt::CapturedStmtClass:
-    EmitCapturedStmt(cast<CapturedStmt>(*S));
+    EmitCapturedStmt(cast<CapturedStmt>(*S), CR_Default);
     break;
   case Stmt::ObjCAtTryStmtClass:
     EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
@@ -1741,40 +1741,56 @@
   }
 }
 
-/// Generate an outlined function for the body of a CapturedStmt, store any
-/// captured variables into the captured struct, and call the outlined function.
-void CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S) {
-  const CapturedDecl *CD = S.getCapturedDecl();
+
+static LValue InitCapturedStruct(CodeGenFunction &CGF, const CapturedStmt &S) {
   const RecordDecl *RD = S.getCapturedRecordDecl();
-  QualType RecordTy = getContext().getRecordType(RD);
-  assert(CD->hasBody() && "missing CapturedDecl body");
+  QualType RecordTy = CGF.getContext().getRecordType(RD);
 
   // Initialize the captured struct.
-  AggValueSlot Slot = CreateAggTemp(RecordTy, "agg.captured");
-  LValue SlotLV = MakeAddrLValue(Slot.getAddr(), RecordTy, Slot.getAlignment());
+  AggValueSlot Slot = CGF.CreateAggTemp(RecordTy, "agg.captured");
+  LValue SlotLV = CGF.MakeAddrLValue(Slot.getAddr(), RecordTy,
+                                     Slot.getAlignment());
 
   RecordDecl::field_iterator CurField = RD->field_begin();
+  CapturedStmt::capture_iterator C = S.capture_begin();
   for (CapturedStmt::capture_init_iterator I = S.capture_init_begin(),
                                            E = S.capture_init_end();
-       I != E; ++I, ++CurField) {
-    LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
+       I != E; ++I, ++C, ++CurField) {
+    LValue LV = CGF.EmitLValueForFieldInitialization(SlotLV, *CurField);
     ArrayRef<VarDecl *> ArrayIndexes;
-    EmitInitializerForField(*CurField, LV, *I, ArrayIndexes);
+    CGF.EmitInitializerForField(*CurField, LV, *I, ArrayIndexes);
   }
 
-  // The function argument is the address of the captured struct.
-  llvm::SmallVector<llvm::Value *, 1> Args;
-  Args.push_back(SlotLV.getAddress());
+  return SlotLV;
+}
+
+/// Generate an outlined function for the body of a CapturedStmt, store any
+/// captured variables into the captured struct, and call the outlined function.
+llvm::Function *
+CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
+  const CapturedDecl *CD = S.getCapturedDecl();
+  const RecordDecl *RD = S.getCapturedRecordDecl();
+  assert(CD->hasBody() && "missing CapturedDecl body");
+
+  LValue CapStruct = InitCapturedStruct(*this, S);
 
   // Emit the CapturedDecl
-  CGCapturedStmtInfo CSInfo(S);
   CodeGenFunction CGF(CGM, true);
-  CGF.CapturedStmtInfo = &CSInfo;
-
+  switch (K) {
+  case CR_Default:
+    CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S);
+    break;
+  default:
+    llvm_unreachable("only CR_Default defined");
+  }
+  CGF.CapturedStmtInfo->setThisParmVarDecl(CD->getContextParam());
   llvm::Function *F = CGF.GenerateCapturedFunction(CurGD, CD, RD);
+  delete CGF.CapturedStmtInfo;
 
   // Emit call to the helper function.
-  EmitCallOrInvoke(F, Args);
+  EmitCallOrInvoke(F, CapStruct.getAddress());
+
+  return F;
 }
 
 /// Creates the outlined function for a CapturedStmt.
@@ -1791,12 +1807,8 @@
 
   // Build the argument list.
   ASTContext &Ctx = CGM.getContext();
-  QualType ThisTy = Ctx.getPointerType(Ctx.getTagDeclType(RD));
   FunctionArgList Args;
-  ImplicitParamDecl ThisDecl(const_cast<CapturedDecl*>(CD), SourceLocation(),
-                             /*Id=*/0, ThisTy);
-  Args.push_back(&ThisDecl);
-  CapturedStmtInfo->setThisParmVarDecl(&ThisDecl);
+  Args.append(CD->param_begin(), CD->param_end());
 
   // Create the function declaration.
   FunctionType::ExtInfo ExtInfo;
@@ -1807,13 +1819,12 @@
 
   llvm::Function *F =
     llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
-                           "__captured_stmt", &CGM.getModule());
+                           CapturedStmtInfo->getHelperName(), &CGM.getModule());
   CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
 
   // Generate the function.
   StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getBody()->getLocStart());
-  // TODO: lots of code here in GenerateBlockFunction - is any of it needed here?
-  EmitStmt(CD->getBody());
+  CapturedStmtInfo->EmitBody(*this, CD->getBody());
   FinishFunction(CD->getBodyRBrace());
 
   return F;
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1428,3 +1428,5 @@
 
   return V;
 }
+
+CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -23,6 +23,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/ABI.h"
+#include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -610,8 +611,9 @@
   class CGCapturedStmtInfo {
   public:
 
-    explicit CGCapturedStmtInfo(const CapturedStmt &S)
-      : ThisValue(0), CXXThisFieldDecl(0), ThisParmVarDecl(0) {
+    explicit CGCapturedStmtInfo(const CapturedStmt &S,
+                                CapturedRegionKind K = CR_Default)
+      : Kind(K), ThisValue(0), CXXThisFieldDecl(0), ThisParmVarDecl(0) {
 
       RecordDecl::field_iterator Field =
         S.getCapturedRecordDecl()->field_begin();
@@ -625,6 +627,10 @@
       }
     }
 
+    virtual ~CGCapturedStmtInfo();
+
+    CapturedRegionKind getKind() const { return Kind; }
+
     void setThisValue(llvm::Value *V) { ThisValue = V; }
     llvm::Value *getThisValue() const { return ThisValue; }
 
@@ -644,7 +650,18 @@
       ThisParmVarDecl = V;
     }
 
+    /// \brief Emit the captured statement body.
+    virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) {
+      CGF.EmitStmt(S);
+    }
+
+    /// \brief Get the name of the capture helper.
+    virtual StringRef getHelperName() const { return "__captured_stmt"; }
+
   private:
+    /// \brief The kind of captured statement being generated.
+    CapturedRegionKind Kind;
+
     /// \brief Keep the map between VarDecl and FieldDecl.
     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields;
 
@@ -2244,7 +2261,7 @@
   void EmitCXXTryStmt(const CXXTryStmt &S);
   void EmitCXXForRangeStmt(const CXXForRangeStmt &S);
 
-  void EmitCapturedStmt(const CapturedStmt &S);
+  llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
   llvm::Function *GenerateCapturedFunction(GlobalDecl GD,
                                            const CapturedDecl *CD,
                                            const RecordDecl *RD);
Index: lib/Parse/ParsePragma.cpp
===================================================================
--- lib/Parse/ParsePragma.cpp
+++ lib/Parse/ParsePragma.cpp
@@ -136,7 +136,8 @@
   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: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1317,8 +1317,8 @@
 
 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: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -2922,8 +2922,8 @@
 }
 
 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 @@
   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 @@
 }
 
 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);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to