aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2009-12-07 21:41:32 +0000
committerDevang Patel <dpatel@apple.com>2009-12-07 21:41:32 +0000
commit4063f6bcc775bb0429dea2276694c4cdc2d4dca1 (patch)
treebcf90a52c90a075069888f5a8ce271103bc5ebcb /lib
parent80564f761aafad4b5630d04dce6eb65499d5a01e (diff)
downloadexternal_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.cpp28
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp75
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h4
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);