Complete out debug info generation for captured __block variables. WIP.

llvm-svn: 84768
This commit is contained in:
Mike Stump 2009-10-21 18:16:27 +00:00
parent 0db964a3a0
commit 9496790211
2 changed files with 67 additions and 8 deletions

View File

@ -412,7 +412,10 @@ public:
QualType getBlockParmType(llvm::SmallVector<const Expr *, 8> &BDRDs);
/// This builds the struct used for __block variables.
QualType BuildByRefType(QualType Ty);
QualType BuildByRefType(const char *DeclName, QualType Ty);
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty);
/// getLValueReferenceType - Return the uniqued reference to the type for an
/// lvalue reference to the specified type.

View File

@ -2741,17 +2741,72 @@ void ASTContext::setBlockDescriptorType(QualType T) {
BlockDescriptorType = Rec->getDecl();
}
QualType ASTContext::BuildByRefType(QualType Ty) {
// type = struct __Block_byref_1_done {
bool ASTContext::BlockRequiresCopying(QualType Ty) {
if (Ty->isBlockPointerType())
return true;
if (isObjCNSObjectType(Ty))
return true;
if (Ty->isObjCObjectPointerType())
return true;
return false;
}
QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
// type = struct __Block_byref_1_X {
// void *__isa;
// struct __Block_byref_1_done *__forwarding;
// struct __Block_byref_1_X *__forwarding;
// unsigned int __flags;
// unsigned int __size;
// int done;
// void *__copy_helper;
// void *__destroy_helper;
// int X;
// } *
// FIXME: Build up reference type.
return getPointerType(VoidPtrTy);
bool HasCopyAndDispose = BlockRequiresCopying(Ty);
// FIXME: Move up
static int UniqueBlockByRefTypeID = 0;
char Name[36];
sprintf(Name, "__Block_byref_%d_%s", ++UniqueBlockByRefTypeID, DeclName);
RecordDecl *T;
T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
&Idents.get(Name));
T->startDefinition();
QualType Int32Ty = IntTy;
assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported");
QualType FieldTypes[] = {
getPointerType(VoidPtrTy),
getPointerType(getTagDeclType(T)),
Int32Ty,
Int32Ty,
getPointerType(VoidPtrTy),
getPointerType(VoidPtrTy),
Ty
};
const char *FieldNames[] = {
"__isa",
"__forwarding",
"__flags",
"__size",
"__copy_helper",
"__destroy_helper",
DeclName,
};
for (size_t i = 0; i < 7; ++i) {
if (!HasCopyAndDispose && i >=4 && i <= 5)
continue;
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
&Idents.get(FieldNames[i]),
FieldTypes[i], /*DInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
T->addDecl(Field);
}
T->completeDefinition(*this);
return getPointerType(getTagDeclType(T));
}
@ -2799,7 +2854,8 @@ QualType ASTContext::getBlockParmType(
QualType FieldType = E->getType();
if (BDRE && BDRE->isByRef())
FieldType = BuildByRefType(FieldType);
FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(),
FieldType);
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
Name, FieldType, /*DInfo=*/0,