From 5d11eb0ed54116b7f33507999617661fb2ae99df Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 3 Dec 2009 19:11:07 +0000 Subject: [PATCH] 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 --- include/llvm/Analysis/DebugInfo.h | 29 +++++++++++++++++++++-- lib/Analysis/DebugInfo.cpp | 18 ++++++++++---- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 34 ++++++++++++++++++++++++--- lib/CodeGen/AsmPrinter/DwarfDebug.h | 2 ++ 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index b67468d8557..c560ec2e359 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -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(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. diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index b1eff9efe16..4a012ce484f 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -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. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 0c31d4671d7..e16bc2adf2c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -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::iterator CI = ContainingTypeMap.begin(), + CE = ContainingTypeMap.end(); CI != CE; ++CI) { + DIE *SPDie = CI->first; + MDNode *N = dyn_cast_or_null(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); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 002e7772546..6c8a28d6831 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -154,6 +154,8 @@ class DwarfDebug : public Dwarf { /// (at the end of the module) as DW_AT_inline. SmallPtrSet InlinedSubprogramDIEs; + DenseMap ContainingTypeMap; + /// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs. SmallPtrSet AbstractSubprogramDIEs; -- 2.34.1