Add support to emit debug info for virtual functions and virtual base classes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90474 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2009-12-03 19:11:07 +00:00
parent 018402d30c
commit 5d11eb0ed5
4 changed files with 73 additions and 10 deletions

View File

@ -197,7 +197,8 @@ namespace llvm {
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5
};
protected:
@ -242,6 +243,9 @@ namespace llvm {
bool isBlockByrefStruct() const {
return (getFlags() & FlagBlockByrefStruct) != 0;
}
bool isVirtual() const {
return (getFlags() & FlagVirtual) != 0;
}
/// dump - print type.
void dump() const;
@ -366,6 +370,24 @@ namespace llvm {
/// compile unit, like 'static' in C.
unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); }
unsigned getVirtuality() const {
if (DbgNode->getNumElements() < 14)
return 0;
return getUnsignedField(11);
}
unsigned getVirtualIndex() const {
if (DbgNode->getNumElements() < 14)
return 0;
return getUnsignedField(12);
}
DICompositeType getContainingType() const {
assert (DbgNode->getNumElements() >= 14 && "Invalid type!");
return getFieldAs<DICompositeType>(13);
}
StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
@ -565,7 +587,10 @@ namespace llvm {
StringRef LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
DIType Type, bool isLocalToUnit,
bool isDefinition);
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
DIType = DIType());
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.

View File

@ -866,7 +866,9 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,
bool isLocalToUnit,
bool isDefinition) {
bool isDefinition,
unsigned VK, unsigned VIndex,
DIType ContainingType) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
@ -879,9 +881,12 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Type.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition)
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
ConstantInt::get(Type::getInt32Ty(VMContext), VIndex),
ContainingType.getNode()
};
return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
}
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
@ -902,9 +907,12 @@ DISubprogram DIFactory::CreateSubprogramDefinition(DISubprogram &SPDeclaration)
DeclNode->getElement(7), // LineNo
DeclNode->getElement(8), // Type
DeclNode->getElement(9), // isLocalToUnit
ConstantInt::get(Type::getInt1Ty(VMContext), true)
ConstantInt::get(Type::getInt1Ty(VMContext), true),
DeclNode->getElement(11), // Virtuality
DeclNode->getElement(12), // VIndex
DeclNode->getElement(13) // Containting Type
};
return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
}
/// CreateGlobalVariable - Create a new descriptor for the specified global.

View File

@ -779,6 +779,7 @@ void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
DW_Unit->addDie(Buffer);
Entry->setEntry(Buffer);
Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
ModuleCU->insertDIE(Ty.getNode(), Buffer);
}
/// constructTypeDIE - Construct basic type die from DIBasicType.
@ -1073,12 +1074,17 @@ DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
if (DT.isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_protected);
else if (DT.isPrivate())
addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_private);
else if (DT.getTag() == dwarf::DW_TAG_inheritance)
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_public);
if (DT.isVirtual())
addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
dwarf::DW_VIRTUALITY_virtual);
return MemberDie;
}
@ -1113,11 +1119,22 @@ DIE *DwarfDebug::createRawSubprogramDIE(CompileUnit *DW_Unit,
DICompositeType SPTy = SP.getType();
DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
addType(DW_Unit, SPDie, SPTy);
else
addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode()));
unsigned VK = SP.getVirtuality();
if (VK) {
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
ContainingTypeMap.insert(std::make_pair(SPDie, WeakVH(SP.getContainingType().getNode())));
}
return SPDie;
}
@ -1826,6 +1843,17 @@ void DwarfDebug::endModule() {
TE = TopLevelDIEsVector.end(); TI != TE; ++TI)
ModuleCU->getCUDie()->addChild(*TI);
for (DenseMap<DIE *, WeakVH>::iterator CI = ContainingTypeMap.begin(),
CE = ContainingTypeMap.end(); CI != CE; ++CI) {
DIE *SPDie = CI->first;
MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
if (!N) continue;
DIE *NDie = ModuleCU->getDIE(N);
if (!NDie) continue;
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
}
// Standard sections final addresses.
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
EmitLabel("text_end", 0);

View File

@ -154,6 +154,8 @@ class DwarfDebug : public Dwarf {
/// (at the end of the module) as DW_AT_inline.
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
DenseMap<DIE *, WeakVH> ContainingTypeMap;
/// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs.
SmallPtrSet<DIE *, 4> AbstractSubprogramDIEs;