[cfe-commits] r84737 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CodeGenFunction.h
Mike Stump
mrs at apple.com
Tue Oct 20 20:49:15 PDT 2009
Author: mrs
Date: Tue Oct 20 22:49:08 2009
New Revision: 84737
URL: http://llvm.org/viewvc/llvm-project?rev=84737&view=rev
Log:
Prep work to always preallocate BlockDeclRefExprs so that we can
generate the debug information for the first parameter to the block
invoke functions. WIP.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGBlocks.h
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=84737&r1=84736&r2=84737&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 20 22:49:08 2009
@@ -409,11 +409,10 @@
/// This gets the struct used to keep track of pointer to blocks, complete
/// with captured variables.
- QualType getBlockParmType();
+ QualType getBlockParmType(llvm::SmallVector<const Expr *, 8> &BDRDs);
- /// This completes a type created by getBlockParmType.
- void completeBlockParmType(QualType Ty,
- llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls);
+ /// This builds the struct used for __block variables.
+ QualType BuildByRefType(QualType Ty);
/// getLValueReferenceType - Return the uniqued reference to the type for an
/// lvalue reference to the specified type.
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=84737&r1=84736&r2=84737&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 20 22:49:08 2009
@@ -2741,7 +2741,22 @@
BlockDescriptorType = Rec->getDecl();
}
-QualType ASTContext::getBlockParmType() {
+QualType ASTContext::BuildByRefType(QualType Ty) {
+ // type = struct __Block_byref_1_done {
+ // void *__isa;
+ // struct __Block_byref_1_done *__forwarding;
+ // unsigned int __flags;
+ // unsigned int __size;
+ // int done;
+ // } *
+
+ // FIXME: Build up reference type.
+ return getPointerType(VoidPtrTy);
+}
+
+
+QualType ASTContext::getBlockParmType(
+ llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
// FIXME: Move up
static int UniqueBlockParmTypeID = 0;
char Name[36];
@@ -2749,30 +2764,6 @@
RecordDecl *T;
T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
&Idents.get(Name));
-
-#define REV2
-#ifdef REV2
- cast<TagDecl>(T)->startDefinition();
-#endif
-
- return getPointerType(getTagDeclType(T));
-}
-
-void ASTContext::completeBlockParmType(QualType Ty,
- llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
- RecordDecl *PT = Ty->getPointeeType()->getAs<RecordType>()->getDecl();
- llvm::StringRef Name = PT->getIdentifier()->getName();
-
- RecordDecl *T;
-#ifdef REV2
- T = PT;
-#else
- T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get(Name), SourceLocation(), PT);
-
- cast<TagDecl>(T)->startDefinition();
-#endif
-
QualType FieldTypes[] = {
getPointerType(VoidPtrTy),
IntTy,
@@ -2790,19 +2781,35 @@
};
for (size_t i = 0; i < 5; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this,
- T,
- SourceLocation(),
+ FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
&Idents.get(FieldNames[i]),
FieldTypes[i], /*DInfo=*/0,
- /*BitWidth=*/0,
- /*Mutable=*/false);
- // FIXME: Do this instead or addDecl?
- // PushOnScopeChains(FieldTypes, S);
+ /*BitWidth=*/0, /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) {
+ const Expr *E = BlockDeclRefDecls[i];
+ const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+ clang::IdentifierInfo *Name = 0;
+ if (BDRE) {
+ const ValueDecl *D = BDRE->getDecl();
+ Name = &Idents.get(D->getName());
+ }
+ QualType FieldType = E->getType();
+
+ if (BDRE && BDRE->isByRef())
+ FieldType = BuildByRefType(FieldType);
+
+ FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+ Name, FieldType, /*DInfo=*/0,
+ /*BitWidth=*/0, /*Mutable=*/false);
T->addDecl(Field);
}
T->completeDefinition(*this);
+
+ return getPointerType(getTagDeclType(T));
}
void ASTContext::setObjCFastEnumerationStateType(QualType T) {
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=84737&r1=84736&r2=84737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Oct 20 22:49:08 2009
@@ -80,22 +80,48 @@
if (*I)
CollectBlockDeclRefInfo(*I, Info);
+ // We want to ensure we walk down into block literals so we can find
+ // all nested BlockDeclRefExprs.
+ if (const BlockExpr *BE = dyn_cast<BlockExpr>(S))
+ CollectBlockDeclRefInfo(BE->getBody(), Info);
+
if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) {
// FIXME: Handle enums.
if (isa<FunctionDecl>(DE->getDecl()))
return;
- if (DE->isByRef())
- Info.ByRefDeclRefs.push_back(DE);
- else
- Info.ByCopyDeclRefs.push_back(DE);
+ Info.DeclRefs.push_back(DE);
}
}
/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
/// declared as a global variable instead of on the stack.
static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
- return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty();
+ return Info.DeclRefs.empty();
+}
+
+/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
+/// ensure we can generate the debug information for the parameter for the block
+/// invoke function.
+static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info,
+ CodeGenFunction *CGF) {
+ // Always allocate self, as it is often handy in the debugger, even if there
+ // is no codegen in the block that uses it. This is also useful to always do
+ // this as if we didn't, we'd have to figure out all code that uses a self
+ // pointer, including implicit uses.
+ if (const ObjCMethodDecl *OMD
+ = dyn_cast_or_null<ObjCMethodDecl>(CGF->CurFuncDecl)) {
+ ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
+ BlockDeclRefExpr *BDRE = new (CGF->getContext())
+ BlockDeclRefExpr(SelfDecl,
+ SelfDecl->getType(), SourceLocation(), false);
+ CGF->AllocateBlockDecl(BDRE);
+ }
+
+ // FIXME: Also always forward the this pointer in C++ as well.
+
+ for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
+ CGF->AllocateBlockDecl(Info.DeclRefs[i]);
}
// FIXME: Push most into CGM, passing down a few bits, like current function
@@ -159,7 +185,8 @@
if (subBlockDeclRefDecls.size() == 0) {
// __descriptor
- Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0);
+ Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize,
+ 0, 0);
// Optimize to being a global block.
Elts[0] = CGM.getNSConcreteGlobalBlock();
@@ -269,7 +296,7 @@
llvm::Value *BlockLiteral = LoadBlockStruct();
Loc = Builder.CreateGEP(BlockLiteral,
- llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
offset),
"block.literal");
Ty = llvm::PointerType::get(Ty, 0);
@@ -447,24 +474,32 @@
return EmitCall(FnInfo, Func, Args);
}
-llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
const ValueDecl *VD = E->getDecl();
-
uint64_t &offset = BlockDecls[VD];
-
// See if we have already allocated an offset for this variable.
- if (offset == 0) {
- // Don't run the expensive check, unless we have to.
- if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
- BlockHasCopyDispose = true;
- // if not, allocate one now.
- offset = getBlockOffset(E);
- }
+ if (offset)
+ return offset;
+
+ // Don't run the expensive check, unless we have to.
+ if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
+ BlockHasCopyDispose = true;
+
+ // if not, allocate one now.
+ offset = getBlockOffset(E);
+
+ return offset;
+}
+
+llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+ const ValueDecl *VD = E->getDecl();
+ uint64_t offset = AllocateBlockDecl(E);
+
llvm::Value *BlockLiteral = LoadBlockStruct();
llvm::Value *V = Builder.CreateGEP(BlockLiteral,
- llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
offset),
"block.literal");
if (E->isByRef()) {
@@ -633,12 +668,19 @@
FunctionArgList Args;
+ CurFuncDecl = OuterFuncDecl;
+
const BlockDecl *BD = BExpr->getBlockDecl();
- IdentifierInfo *II
- = &CGM.getContext().Idents.get(".block_descriptor");
+ IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
+
+ // Allocate all BlockDeclRefDecls, so we can calculate the the
+ // right ParmTy below.
+ // FIXME: Resolve testsuite problems, then enable.
+ if (0)
+ AllocateAllBlockDeclRefs(Info, this);
- QualType ParmTy = getContext().getBlockParmType();
+ QualType ParmTy = getContext().getBlockParmType(BlockDeclRefDecls);
// FIXME: This leaks
ImplicitParamDecl *SelfDecl =
ImplicitParamDecl::Create(getContext(), 0,
@@ -708,22 +750,6 @@
FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
- // And now finish off the type for the parameter, since now we know
- // BlockDeclRefDecls is complete.
- getContext().completeBlockParmType(ParmTy, BlockDeclRefDecls);
-
-#define REV2
-#ifdef REV2
- TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl();
- CGM.UpdateCompletedType(TD);
-#else
- TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl();
- TagDecl::redecl_iterator rdi = TD->redecls_begin();
- ++rdi;
- TD = *rdi;
- CGM.UpdateCompletedType(TD);
-#endif
-
// The runtime needs a minimum alignment of a void *.
uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8;
BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign);
@@ -781,11 +807,13 @@
FunctionArgList Args;
// FIXME: This leaks
ImplicitParamDecl *Dst =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Dst, Dst->getType()));
ImplicitParamDecl *Src =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Src, Src->getType()));
@@ -866,7 +894,8 @@
FunctionArgList Args;
// FIXME: This leaks
ImplicitParamDecl *Src =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Src, Src->getType()));
@@ -945,13 +974,15 @@
FunctionArgList Args;
// FIXME: This leaks
ImplicitParamDecl *Dst =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Dst, Dst->getType()));
// FIXME: This leaks
ImplicitParamDecl *Src =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Src, Src->getType()));
@@ -1014,7 +1045,8 @@
FunctionArgList Args;
// FIXME: This leaks
ImplicitParamDecl *Src =
- ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+ ImplicitParamDecl::Create(getContext(), 0,
+ SourceLocation(), 0,
getContext().getPointerType(getContext().VoidTy));
Args.push_back(std::make_pair(Src, Src->getType()));
Modified: cfe/trunk/lib/CodeGen/CGBlocks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=84737&r1=84736&r2=84737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Tue Oct 20 22:49:08 2009
@@ -165,11 +165,7 @@
/// ByCopyDeclRefs - Variables from parent scopes that have been imported
/// into this block.
- llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs;
-
- // ByRefDeclRefs - __block variables from parent scopes that have been
- // imported into this block.
- llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs;
+ llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
BlockInfo(const llvm::Type *blt, const char *n)
: BlockLiteralTy(blt), Name(n) {
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=84737&r1=84736&r2=84737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Oct 20 22:49:08 2009
@@ -356,6 +356,7 @@
void BlockForwardSelf();
llvm::Value *LoadBlockStruct();
+ uint64_t AllocateBlockDecl(const BlockDeclRefExpr *E);
llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
const llvm::Type *BuildByRefType(const ValueDecl *D);
More information about the cfe-commits
mailing list