diff options
author | Devang Patel <dpatel@apple.com> | 2009-12-07 21:41:32 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-12-07 21:41:32 +0000 |
commit | 4063f6bcc775bb0429dea2276694c4cdc2d4dca1 (patch) | |
tree | bcf90a52c90a075069888f5a8ce271103bc5ebcb /lib | |
parent | 80564f761aafad4b5630d04dce6eb65499d5a01e (diff) | |
download | external_llvm-4063f6bcc775bb0429dea2276694c4cdc2d4dca1.zip external_llvm-4063f6bcc775bb0429dea2276694c4cdc2d4dca1.tar.gz external_llvm-4063f6bcc775bb0429dea2276694c4cdc2d4dca1.tar.bz2 |
Add support to emit debug info for c++ style namespaces.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90805 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 28 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 75 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 4 |
3 files changed, 99 insertions, 8 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 74d9e1e..7dc652f 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -227,6 +227,7 @@ bool DIDescriptor::isScope() const { case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_lexical_block: case dwarf::DW_TAG_subprogram: + case dwarf::DW_TAG_namespace: return true; default: break; @@ -242,6 +243,14 @@ bool DIDescriptor::isCompileUnit() const { return Tag == dwarf::DW_TAG_compile_unit; } +/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. +bool DIDescriptor::isNameSpace() const { + assert (!isNull() && "Invalid descriptor!"); + unsigned Tag = getTag(); + + return Tag == dwarf::DW_TAG_namespace; +} + /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { assert (!isNull() && "Invalid descriptor!"); @@ -438,6 +447,8 @@ StringRef DIScope::getFilename() const { return DISubprogram(DbgNode).getFilename(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getFilename(); + else if (isNameSpace()) + return DINameSpace(DbgNode).getFilename(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -450,6 +461,8 @@ StringRef DIScope::getDirectory() const { return DISubprogram(DbgNode).getDirectory(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getDirectory(); + else if (isNameSpace()) + return DINameSpace(DbgNode).getDirectory(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -996,6 +1009,21 @@ DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) { return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); } +/// CreateNameSpace - This creates new descriptor for a namespace +/// with the specified parent context. +DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNo) { + Value *Elts[] = { + GetTagConstant(dwarf::DW_TAG_namespace), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) + }; + return DINameSpace(MDNode::get(VMContext, &Elts[0], 5)); +} + /// CreateLocation - Creates a debug info location. DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc) { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 3adb520..f4f6fce 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -446,6 +446,23 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) { addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); } +/// addSourceLine - Add location information to specified debug information +/// entry. +void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) { + // If there is no compile unit specified, don't add a line #. + if (NS->getCompileUnit().isNull()) + return; + + unsigned Line = NS->getLineNumber(); + StringRef FN = NS->getFilename(); + StringRef Dir = NS->getDirectory(); + + unsigned FileID = GetOrCreateSourceID(Dir, FN); + assert(FileID && "Invalid file id"); + addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); + addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); +} + /* Byref variables, in Blocks, are declared by the programmer as "SomeType VarName;", but the compiler creates a __Block_byref_x_VarName struct, and gives the variable VarName @@ -771,9 +788,13 @@ void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { // Add debug information entry to entity and appropriate context. DIE *Die = NULL; DIDescriptor Context = Ty.getContext(); - if (!Context.isNull()) - Die = DW_Unit->getDIE(Context.getNode()); - + if (!Context.isNull()) { + if (Context.isNameSpace()) { + DINameSpace NS(Context.getNode()); + Die = getOrCreateNameSpace(NS); + } else + Die = DW_Unit->getDIE(Context.getNode()); + } if (Die) Die->addChild(Buffer); else @@ -1643,6 +1664,29 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName) return SrcId; } +/// getOrCreateNameSpace - Create a DIE for DINameSpace. +DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace &NS) { + DIE *NDie = ModuleCU->getDIE(NS.getNode()); + if (NDie) + return NDie; + + NDie = new DIE(dwarf::DW_TAG_namespace); + ModuleCU->insertDIE(NS.getNode(), NDie); + if (!NS.getName().empty()) + addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName()); + addSourceLine(NDie, &NS); + DIDescriptor NSContext = NS.getContext(); + DIE *Context = NULL; + if (NSContext.isNameSpace()) { + DINameSpace NS2(NSContext.getNode()); + Context = getOrCreateNameSpace(NS2); + } + else + Context = ModuleCU->getCUDie(); + Context->addChild(NDie); + return NDie; +} + void DwarfDebug::constructCompileUnit(MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); @@ -1734,10 +1778,17 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) { ModuleCU->insertDIE(N, SubprogramDie); // Add to context owner. - if (SP.getContext().getNode() == SP.getCompileUnit().getNode()) + DIDescriptor SPContext = SP.getContext(); + if (SPContext.isCompileUnit() + && SPContext.getNode() == SP.getCompileUnit().getNode()) { if (TopLevelDIEs.insert(SubprogramDie)) TopLevelDIEsVector.push_back(SubprogramDie); - + } else if (SPContext.isNameSpace()) { + DINameSpace NS(SPContext.getNode()); + DIE *NDie = getOrCreateNameSpace(NS); + NDie->addChild(SubprogramDie); + } + // Expose as global. ModuleCU->addGlobal(SP.getName(), SubprogramDie); @@ -1780,10 +1831,18 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) { for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), E = DbgFinder.global_variable_end(); I != E; ++I) { DIGlobalVariable GV(*I); - if (GV.getContext().getNode() != GV.getCompileUnit().getNode()) - ScopedGVs.push_back(*I); - else + DIDescriptor GVContext = GV.getContext(); + if (GVContext.isCompileUnit() + && GVContext.getNode() == GV.getCompileUnit().getNode()) constructGlobalVariableDIE(*I); + else if (GVContext.isNameSpace()) { + DIE *GVDie = createGlobalVariableDIE(ModuleCU, GV); + DINameSpace NS(GVContext.getNode()); + DIE *NDie = getOrCreateNameSpace(NS); + NDie->addChild(GVDie); + } + else + ScopedGVs.push_back(*I); } // Create DIEs for each subprogram. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 6c8a28d..3319cf5 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -289,6 +289,7 @@ class DwarfDebug : public Dwarf { void addSourceLine(DIE *Die, const DIGlobal *G); void addSourceLine(DIE *Die, const DISubprogram *SP); void addSourceLine(DIE *Die, const DIType *Ty); + void addSourceLine(DIE *Die, const DINameSpace *NS); /// addAddress - Add an address attribute to a die based on the location /// provided. @@ -340,6 +341,9 @@ class DwarfDebug : public Dwarf { /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy); + /// getOrCreateNameSpace - Create a DIE for DINameSpace. + DIE *getOrCreateNameSpace(DINameSpace &NS); + /// createGlobalVariableDIE - Create new DIE using GV. DIE *createGlobalVariableDIE(CompileUnit *DW_Unit, const DIGlobalVariable &GV); |