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