[llvm-commits] [llvm] r91440 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DIE.h lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h
Devang Patel
dpatel at apple.com
Tue Dec 15 11:16:48 PST 2009
Author: dpatel
Date: Tue Dec 15 13:16:48 2009
New Revision: 91440
URL: http://llvm.org/viewvc/llvm-project?rev=91440&view=rev
Log:
Add support to emit debug info for C++ namespaces.
Modified:
llvm/trunk/include/llvm/Analysis/DebugInfo.h
llvm/trunk/lib/Analysis/DebugInfo.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=91440&r1=91439&r2=91440&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Dec 15 13:16:48 2009
@@ -99,6 +99,7 @@
bool isGlobalVariable() const;
bool isScope() const;
bool isCompileUnit() const;
+ bool isNameSpace() const;
bool isLexicalBlock() const;
bool isSubrange() const;
bool isEnumerator() const;
@@ -218,7 +219,7 @@
virtual ~DIType() {}
DIDescriptor getContext() const { return getDescriptorField(1); }
- StringRef getName() const { return getStringField(2); }
+ StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
@@ -470,6 +471,22 @@
StringRef getFilename() const { return getContext().getFilename(); }
};
+ /// DINameSpace - A wrapper for a C++ style name space.
+ class DINameSpace : public DIScope {
+ public:
+ explicit DINameSpace(MDNode *N = 0) : DIScope(N) {
+ if (DbgNode && !isNameSpace())
+ DbgNode = 0;
+ }
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ StringRef getDirectory() const { return getContext().getDirectory(); }
+ StringRef getFilename() const { return getContext().getFilename(); }
+ DICompileUnit getCompileUnit() const { return getFieldAs<DICompileUnit>(3); }
+ unsigned getLineNumber() const { return getUnsignedField(4); }
+ };
+
/// DILocation - This object holds location information. This object
/// is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
@@ -624,6 +641,11 @@
/// with the specified parent context.
DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
+ /// CreateNameSpace - This creates new descriptor for a namespace
+ /// with the specified parent context.
+ DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
+ DICompileUnit CU, unsigned LineNo);
+
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
DIScope S, DILocation OrigLoc);
Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=91440&r1=91439&r2=91440&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Dec 15 13:16:48 2009
@@ -227,6 +227,7 @@
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 @@
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 @@
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 @@
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 @@
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) {
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=91440&r1=91439&r2=91440&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h Tue Dec 15 13:16:48 2009
@@ -68,6 +68,7 @@
/// Data - Raw data bytes for abbreviation.
///
SmallVector<DIEAbbrevData, 8> Data;
+
public:
DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {}
virtual ~DIEAbbrev() {}
@@ -131,19 +132,18 @@
///
std::vector<DIE *> Children;
+ DIE *Parent;
+
/// Attributes values.
///
SmallVector<DIEValue*, 32> Values;
- /// Abstract compile unit.
- CompileUnit *AbstractCU;
-
// Private data for print()
mutable unsigned IndentCount;
public:
explicit DIE(unsigned Tag)
: Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0),
- Size(0), IndentCount(0) {}
+ Size(0), Parent (0), IndentCount(0) {}
virtual ~DIE();
// Accessors.
@@ -154,13 +154,12 @@
unsigned getSize() const { return Size; }
const std::vector<DIE *> &getChildren() const { return Children; }
SmallVector<DIEValue*, 32> &getValues() { return Values; }
- CompileUnit *getAbstractCompileUnit() const { return AbstractCU; }
-
+ DIE *getParent() const { return Parent; }
void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
- void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; }
-
+ void setParent(DIE *P) { Parent = P; }
+
/// addValue - Add a value and attributes to a DIE.
///
void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
@@ -179,8 +178,13 @@
/// addChild - Add a child to the DIE.
///
void addChild(DIE *Child) {
+ if (Child->getParent()) {
+ assert (Child->getParent() == this && "Unexpected DIE Parent!");
+ return;
+ }
Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
Children.push_back(Child);
+ Child->setParent(this);
}
#ifndef NDEBUG
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=91440&r1=91439&r2=91440&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Dec 15 13:16:48 2009
@@ -112,7 +112,12 @@
/// getDIEEntry - Returns the debug information entry for the speciefied
/// debug variable.
- DIEEntry *getDIEEntry(MDNode *N) { return GVToDIEEntryMap.lookup(N); }
+ DIEEntry *getDIEEntry(MDNode *N) {
+ ValueMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
+ if (I == GVToDIEEntryMap.end())
+ return NULL;
+ return I->second;
+ }
/// insertDIEEntry - Insert debug information entry into the map.
void insertDIEEntry(MDNode *N, DIEEntry *E) {
@@ -446,6 +451,23 @@
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
@@ -745,6 +767,9 @@
else if (Context.isType()) {
DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
ContextDIE->addChild(Die);
+ } else if (Context.isNameSpace()) {
+ DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
+ ContextDIE->addChild(Die);
} else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
ContextDIE->addChild(Die);
else
@@ -781,7 +806,6 @@
// Check for pre-existence.
DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
-
// If it exists then use the existing value.
if (Entry) {
Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
@@ -1030,13 +1054,6 @@
addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
addSourceLine(GVDie, &GV);
- // Add address.
- DIEBlock *Block = new DIEBlock();
- addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
- addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
- Asm->Mang->getMangledName(GV.getGlobal()));
- addBlock(GVDie, dwarf::DW_AT_location, 0, Block);
-
return GVDie;
}
@@ -1285,7 +1302,6 @@
SPDie = new DIE(dwarf::DW_TAG_subprogram);
addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
SPDeclDie);
-
ModuleCU->addDie(SPDie);
}
@@ -1559,6 +1575,20 @@
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);
+ addToContextOwner(NDie, NS.getContext());
+ return NDie;
+}
+
CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) {
DICompileUnit DIUnit(N);
StringRef FN = DIUnit.getFilename();
@@ -1620,6 +1650,25 @@
ModuleCU->insertDIE(N, VariableDie);
// Add to context owner.
+ if (DI_GV.isDefinition()
+ && !DI_GV.getContext().isCompileUnit()) {
+ // Create specification DIE.
+ DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
+ addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
+ dwarf::DW_FORM_ref4, VariableDie);
+ DIEBlock *Block = new DIEBlock();
+ addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
+ addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
+ Asm->Mang->getMangledName(DI_GV.getGlobal()));
+ addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
+ ModuleCU->addDie(VariableSpecDIE);
+ } else {
+ DIEBlock *Block = new DIEBlock();
+ addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
+ addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
+ Asm->Mang->getMangledName(DI_GV.getGlobal()));
+ addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
+ }
addToContextOwner(VariableDie, DI_GV.getContext());
// Expose as global. FIXME - need to check external flag.
@@ -1652,9 +1701,7 @@
ModuleCU->insertDIE(N, SubprogramDie);
// Add to context owner.
- if (SP.getContext().getNode() == SP.getCompileUnit().getNode())
- if (TopLevelDIEs.insert(SubprogramDie))
- TopLevelDIEsVector.push_back(SubprogramDie);
+ addToContextOwner(SubprogramDie, SP.getContext());
// Expose as global.
ModuleCU->addGlobal(SP.getName(), SubprogramDie);
@@ -2365,7 +2412,6 @@
EmitLabel("info_end", ModuleCU->getID());
Asm->EOL();
-
}
/// emitAbbreviations - Emit the abbreviation section.
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=91440&r1=91439&r2=91440&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Dec 15 13:16:48 2009
@@ -285,6 +285,7 @@
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.
@@ -315,6 +316,10 @@
/// addType - Add a new type attribute to the specified entity.
void addType(DIE *Entity, DIType Ty);
+
+ /// getOrCreateNameSpace - Create a DIE for DINameSpace.
+ DIE *getOrCreateNameSpace(DINameSpace NS);
+
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *getOrCreateTypeDIE(DIType Ty);
More information about the llvm-commits
mailing list