forked from OSchip/llvm-project
Enhance debug information for block literals. Radar 6867696
llvm-svn: 71763
This commit is contained in:
parent
7911002bf9
commit
31f099c8c2
|
@ -34,7 +34,8 @@ using namespace clang;
|
|||
using namespace clang::CodeGen;
|
||||
|
||||
CGDebugInfo::CGDebugInfo(CodeGenModule *m)
|
||||
: M(m), isMainCompileUnitCreated(false), DebugFactory(M->getModule()) {
|
||||
: M(m), isMainCompileUnitCreated(false), DebugFactory(M->getModule()),
|
||||
BlockLiteralGenericSet(false) {
|
||||
}
|
||||
|
||||
CGDebugInfo::~CGDebugInfo() {
|
||||
|
@ -210,6 +211,133 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
|
|||
0, Size, Align, 0, 0, EltTy);
|
||||
}
|
||||
|
||||
llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
|
||||
llvm::DICompileUnit Unit) {
|
||||
if (BlockLiteralGenericSet)
|
||||
return BlockLiteralGeneric;
|
||||
|
||||
llvm::DICompileUnit DefUnit;
|
||||
unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
|
||||
|
||||
llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
|
||||
|
||||
llvm::DIType FieldTy;
|
||||
|
||||
QualType FType;
|
||||
uint64_t FieldSize, FieldOffset;
|
||||
unsigned FieldAlign;
|
||||
|
||||
llvm::DIArray Elements;
|
||||
llvm::DIType EltTy, DescTy;
|
||||
|
||||
FieldOffset = 0;
|
||||
FType = M->getContext().UnsignedLongTy;
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"reserved", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
FType = M->getContext().UnsignedLongTy;
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"Size", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
Elements = DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());
|
||||
EltTys.clear();
|
||||
|
||||
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
|
||||
DefUnit, 0, FieldOffset, 0, 0, 0,
|
||||
llvm::DIType(), Elements);
|
||||
|
||||
// Bit size, align and offset of the type.
|
||||
uint64_t Size = M->getContext().getTypeSize(Ty);
|
||||
uint64_t Align = M->getContext().getTypeAlign(Ty);
|
||||
|
||||
DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
|
||||
Unit, "", llvm::DICompileUnit(),
|
||||
0, Size, Align, 0, 0, EltTy);
|
||||
|
||||
FieldOffset = 0;
|
||||
FType = M->getContext().getPointerType(M->getContext().VoidTy);
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"__isa", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
FType = M->getContext().IntTy;
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"__flags", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
FType = M->getContext().IntTy;
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"__reserved", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
FType = M->getContext().getPointerType(M->getContext().VoidTy);
|
||||
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
|
||||
FieldSize = M->getContext().getTypeSize(FType);
|
||||
FieldAlign = M->getContext().getTypeAlign(FType);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"__FuncPtr", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
FType = M->getContext().getPointerType(M->getContext().VoidTy);
|
||||
FieldTy = DescTy;
|
||||
FieldSize = M->getContext().getTypeSize(Ty);
|
||||
FieldAlign = M->getContext().getTypeAlign(Ty);
|
||||
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
|
||||
"__descriptor", DefUnit,
|
||||
0, FieldSize, FieldAlign,
|
||||
FieldOffset, 0, FieldTy);
|
||||
EltTys.push_back(FieldTy);
|
||||
|
||||
FieldOffset += FieldSize;
|
||||
Elements = DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());
|
||||
|
||||
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
|
||||
DefUnit, 0, FieldOffset, 0, 0, 0,
|
||||
llvm::DIType(), Elements);
|
||||
|
||||
BlockLiteralGenericSet = true;
|
||||
BlockLiteralGeneric
|
||||
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
|
||||
"", llvm::DICompileUnit(),
|
||||
0, Size, Align, 0, 0, EltTy);
|
||||
return BlockLiteralGeneric;
|
||||
}
|
||||
|
||||
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
|
||||
llvm::DICompileUnit Unit) {
|
||||
// Typedefs are derived from some other type. If we have a typedef of a
|
||||
|
@ -626,7 +754,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
|
|||
case Type::ExtVector:
|
||||
case Type::ExtQual:
|
||||
case Type::FixedWidthInt:
|
||||
case Type::BlockPointer:
|
||||
case Type::MemberPointer:
|
||||
case Type::TemplateSpecialization:
|
||||
case Type::QualifiedName:
|
||||
|
@ -641,6 +768,8 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
|
|||
case Type::Builtin: return Slot = CreateType(cast<BuiltinType>(Ty), Unit);
|
||||
case Type::Complex: return Slot = CreateType(cast<ComplexType>(Ty), Unit);
|
||||
case Type::Pointer: return Slot = CreateType(cast<PointerType>(Ty), Unit);
|
||||
case Type::BlockPointer:
|
||||
return Slot = CreateType(cast<BlockPointerType>(Ty), Unit);
|
||||
case Type::Typedef: return Slot = CreateType(cast<TypedefType>(Ty), Unit);
|
||||
case Type::Record:
|
||||
case Type::Enum:
|
||||
|
|
|
@ -46,6 +46,9 @@ class CGDebugInfo {
|
|||
// FIXME: Eliminate this map. Be careful of iterator invalidation.
|
||||
std::map<void *, llvm::DIType> TypeCache;
|
||||
|
||||
bool BlockLiteralGenericSet;
|
||||
llvm::DIType BlockLiteralGeneric;
|
||||
|
||||
std::vector<llvm::DIDescriptor> RegionStack;
|
||||
|
||||
/// Helper functions for getOrCreateType.
|
||||
|
@ -54,6 +57,7 @@ class CGDebugInfo {
|
|||
llvm::DIType CreateCVRType(QualType Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const TypedefType *Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const PointerType *Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const FunctionType *Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const TagType *Ty, llvm::DICompileUnit U);
|
||||
llvm::DIType CreateType(const RecordType *Ty, llvm::DICompileUnit U);
|
||||
|
|
Loading…
Reference in New Issue