forked from OSchip/llvm-project
Extend out the block descriptor structure for debug information with
the copy/dispose helpers as appropriate. llvm-svn: 84817
This commit is contained in:
parent
cc81526176
commit
e1b19ba05b
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -486,7 +486,9 @@ uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
|
|||
return offset;
|
||||
|
||||
// Don't run the expensive check, unless we have to.
|
||||
if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
|
||||
if (!BlockHasCopyDispose)
|
||||
if (E->isByRef()
|
||||
|| BlockRequiresCopying(E->getType()))
|
||||
BlockHasCopyDispose = true;
|
||||
|
||||
// if not, allocate one now.
|
||||
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue