Extend out the block descriptor structure for debug information with

the copy/dispose helpers as appropriate.

llvm-svn: 84817
This commit is contained in:
Mike Stump 2009-10-22 00:49:09 +00:00
parent cc81526176
commit e1b19ba05b
6 changed files with 86 additions and 8 deletions

View File

@ -147,6 +147,9 @@ class ASTContext {
/// \brief Type for the Block descriptor for Blocks CodeGen.
RecordDecl *BlockDescriptorType;
/// \brief Type for the Block descriptor for Blocks CodeGen.
RecordDecl *BlockDescriptorExtendedType;
/// \brief Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
@ -407,9 +410,24 @@ public:
return QualType();
}
/// This gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
QualType getBlockDescriptorExtendedType();
// Set the type for a Block descriptor extended type.
void setBlockDescriptorExtendedType(QualType T);
/// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been
/// built.
QualType getRawBlockdescriptorExtendedType() {
if (BlockDescriptorExtendedType)
return getTagDeclType(BlockDescriptorExtendedType);
return QualType();
}
/// This gets the struct used to keep track of pointer to blocks, complete
/// with captured variables.
QualType getBlockParmType(llvm::SmallVector<const Expr *, 8> &BDRDs);
QualType getBlockParmType(bool BlockHasCopyDispose,
llvm::SmallVector<const Expr *, 8> &BDRDs);
/// This builds the struct used for __block variables.
QualType BuildByRefType(const char *DeclName, QualType Ty);

View File

@ -438,7 +438,9 @@ namespace clang {
/// \brief Objective-C "Class" redefinition type
SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11,
/// \brief Block descriptor type for Blocks CodeGen
SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12
SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12,
/// \brief Block extedned descriptor type for Blocks CodeGen
SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13
};
/// \brief Record codes for each kind of declaration.

View File

@ -40,7 +40,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
bool FreeMem, unsigned size_reserve) :
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
sigjmp_bufDecl(0), BlockDescriptorType(0), SourceMgr(SM), LangOpts(LOpts),
sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0),
SourceMgr(SM), LangOpts(LOpts),
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
@ -2714,7 +2715,7 @@ QualType ASTContext::getBlockDescriptorType() {
const char *FieldNames[] = {
"reserved",
"Size",
"Size"
};
for (size_t i = 0; i < 2; ++i) {
@ -2741,6 +2742,53 @@ void ASTContext::setBlockDescriptorType(QualType T) {
BlockDescriptorType = Rec->getDecl();
}
QualType ASTContext::getBlockDescriptorExtendedType() {
if (BlockDescriptorExtendedType)
return getTagDeclType(BlockDescriptorExtendedType);
RecordDecl *T;
// FIXME: Needs the FlagAppleBlock bit.
T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
&Idents.get("__block_descriptor_withcopydispose"));
QualType FieldTypes[] = {
UnsignedLongTy,
UnsignedLongTy,
getPointerType(VoidPtrTy),
getPointerType(VoidPtrTy)
};
const char *FieldNames[] = {
"reserved",
"Size",
"CopyFuncPtr",
"DestroyFuncPtr"
};
for (size_t i = 0; i < 4; ++i) {
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);
BlockDescriptorExtendedType = T;
return getTagDeclType(BlockDescriptorExtendedType);
}
void ASTContext::setBlockDescriptorExtendedType(QualType T) {
const RecordType *Rec = T->getAs<RecordType>();
assert(Rec && "Invalid BlockDescriptorType");
BlockDescriptorExtendedType = Rec->getDecl();
}
bool ASTContext::BlockRequiresCopying(QualType Ty) {
if (Ty->isBlockPointerType())
return true;
@ -2811,6 +2859,7 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
QualType ASTContext::getBlockParmType(
bool BlockHasCopyDispose,
llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
// FIXME: Move up
static int UniqueBlockParmTypeID = 0;
@ -2824,7 +2873,9 @@ QualType ASTContext::getBlockParmType(
IntTy,
IntTy,
getPointerType(VoidPtrTy),
getPointerType(getBlockDescriptorType()),
(BlockHasCopyDispose ?
getPointerType(getBlockDescriptorExtendedType()) :
getPointerType(getBlockDescriptorType()))
};
const char *FieldNames[] = {

View File

@ -486,8 +486,10 @@ uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
return offset;
// Don't run the expensive check, unless we have to.
if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
BlockHasCopyDispose = true;
if (!BlockHasCopyDispose)
if (E->isByRef()
|| BlockRequiresCopying(E->getType()))
BlockHasCopyDispose = true;
// if not, allocate one now.
offset = getBlockOffset(E);
@ -680,7 +682,8 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
// Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below.
AllocateAllBlockDeclRefs(Info, this);
QualType ParmTy = getContext().getBlockParmType(BlockDeclRefDecls);
QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
BlockDeclRefDecls);
// FIXME: This leaks
ImplicitParamDecl *SelfDecl =
ImplicitParamDecl::Create(getContext(), 0,

View File

@ -1591,6 +1591,9 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {
Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Context->setBlockDescriptorType(GetType(String));
if (unsigned String
= SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Context->setBlockDescriptorExtendedType(GetType(String));
}
/// \brief Retrieve the name of the original source file name

View File

@ -1988,6 +1988,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
AddTypeRef(Context.ObjCIdRedefinitionType, Record);
AddTypeRef(Context.ObjCClassRedefinitionType, Record);
AddTypeRef(Context.getRawBlockdescriptorType(), Record);
AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);
Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
// Keep writing types and declarations until all types and