summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-12-15 18:09:07 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-12-15 18:09:07 +0000
commit40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (patch)
tree076117cdf3579003f07cad4cdf0593347ce58150 /lib/CodeGen/AsmPrinter/DwarfDebug.cpp
parente7908924d847e63b02bc82bfaa1709ab9c774dcd (diff)
downloadFreeBSD-src-40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6.zip
FreeBSD-src-40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6.tar.gz
Update LLVM to 91430.
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp411
1 files changed, 199 insertions, 212 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index c2e1e05..c200a46 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -330,8 +330,8 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Die->addValue(Attribute, Form, Value);
}
-/// addString - Add a string attribute data and value.
-///
+/// addString - Add a string attribute data and value. DIEString only
+/// keeps string reference.
void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
const StringRef String) {
DIEValue *Value = new DIEString(String);
@@ -393,7 +393,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
return;
unsigned Line = V->getLineNumber();
- unsigned FileID = findCompileUnit(V->getCompileUnit()).getID();
+ unsigned FileID = findCompileUnit(V->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -407,7 +407,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
return;
unsigned Line = G->getLineNumber();
- unsigned FileID = findCompileUnit(G->getCompileUnit()).getID();
+ unsigned FileID = findCompileUnit(G->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -425,7 +425,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
unsigned Line = SP->getLineNumber();
- unsigned FileID = findCompileUnit(SP->getCompileUnit()).getID();
+ unsigned FileID = findCompileUnit(SP->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -440,7 +440,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
return;
unsigned Line = Ty->getLineNumber();
- unsigned FileID = findCompileUnit(CU).getID();
+ unsigned FileID = findCompileUnit(CU)->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -738,13 +738,49 @@ void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
addBlock(Die, Attribute, 0, Block);
}
+/// addToContextOwner - Add Die into the list of its context owner's children.
+void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
+ if (Context.isNull())
+ ModuleCU->addDie(Die);
+ else if (Context.isType()) {
+ DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
+ ContextDIE->addChild(Die);
+ } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
+ ContextDIE->addChild(Die);
+ else
+ ModuleCU->addDie(Die);
+}
+
+/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
+/// given DIType.
+DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
+ DIE *TyDIE = ModuleCU->getDIE(Ty.getNode());
+ if (TyDIE)
+ return TyDIE;
+
+ // Create new type.
+ TyDIE = new DIE(dwarf::DW_TAG_base_type);
+ ModuleCU->insertDIE(Ty.getNode(), TyDIE);
+ if (Ty.isBasicType())
+ constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode()));
+ else if (Ty.isCompositeType())
+ constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode()));
+ else {
+ assert(Ty.isDerivedType() && "Unknown kind of DIType");
+ constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode()));
+ }
+
+ addToContextOwner(TyDIE, Ty.getContext());
+ return TyDIE;
+}
+
/// addType - Add a new type attribute to the specified entity.
-void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
+void DwarfDebug::addType(DIE *Entity, DIType Ty) {
if (Ty.isNull())
return;
// Check for pre-existence.
- DIEEntry *Entry = DW_Unit->getDIEEntry(Ty.getNode());
+ DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
// If it exists then use the existing value.
if (Entry) {
@@ -754,36 +790,17 @@ void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
// Set up proxy.
Entry = createDIEEntry();
- DW_Unit->insertDIEEntry(Ty.getNode(), Entry);
+ ModuleCU->insertDIEEntry(Ty.getNode(), Entry);
// Construct type.
- DIE *Buffer = new DIE(dwarf::DW_TAG_base_type);
- if (Ty.isBasicType())
- constructTypeDIE(DW_Unit, *Buffer, DIBasicType(Ty.getNode()));
- else if (Ty.isCompositeType())
- constructTypeDIE(DW_Unit, *Buffer, DICompositeType(Ty.getNode()));
- else {
- assert(Ty.isDerivedType() && "Unknown kind of DIType");
- constructTypeDIE(DW_Unit, *Buffer, DIDerivedType(Ty.getNode()));
- }
+ DIE *Buffer = getOrCreateTypeDIE(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 (Die)
- Die->addChild(Buffer);
- else
- DW_Unit->addDie(Buffer);
Entry->setEntry(Buffer);
Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
}
/// constructTypeDIE - Construct basic type die from DIBasicType.
-void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
- DIBasicType BTy) {
+void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
// Get core information.
StringRef Name = BTy.getName();
Buffer.setTag(dwarf::DW_TAG_base_type);
@@ -798,8 +815,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructTypeDIE - Construct derived type die from DIDerivedType.
-void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
- DIDerivedType DTy) {
+void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
// Get core information.
StringRef Name = DTy.getName();
uint64_t Size = DTy.getSizeInBits() >> 3;
@@ -812,7 +828,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
// Map to main type, void will not have a type.
DIType FromTy = DTy.getTypeDerivedFrom();
- addType(DW_Unit, &Buffer, FromTy);
+ addType(&Buffer, FromTy);
// Add name if not anonymous or intermediate type.
if (!Name.empty())
@@ -828,8 +844,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructTypeDIE - Construct type DIE from DICompositeType.
-void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
- DICompositeType CTy) {
+void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Get core information.
StringRef Name = CTy.getName();
@@ -840,7 +855,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
switch (Tag) {
case dwarf::DW_TAG_vector_type:
case dwarf::DW_TAG_array_type:
- constructArrayTypeDIE(DW_Unit, Buffer, &CTy);
+ constructArrayTypeDIE(Buffer, &CTy);
break;
case dwarf::DW_TAG_enumeration_type: {
DIArray Elements = CTy.getTypeArray();
@@ -850,7 +865,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DIE *ElemDie = NULL;
DIEnumerator Enum(Elements.getElement(i).getNode());
if (!Enum.isNull()) {
- ElemDie = constructEnumTypeDIE(DW_Unit, &Enum);
+ ElemDie = constructEnumTypeDIE(&Enum);
Buffer.addChild(ElemDie);
}
}
@@ -860,7 +875,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
// Add return type.
DIArray Elements = CTy.getTypeArray();
DIDescriptor RTy = Elements.getElement(0);
- addType(DW_Unit, &Buffer, DIType(RTy.getNode()));
+ addType(&Buffer, DIType(RTy.getNode()));
// Add prototype flag.
addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
@@ -869,7 +884,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
DIDescriptor Ty = Elements.getElement(i);
- addType(DW_Unit, Arg, DIType(Ty.getNode()));
+ addType(Arg, DIType(Ty.getNode()));
Buffer.addChild(Arg);
}
}
@@ -891,11 +906,9 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
continue;
DIE *ElemDie = NULL;
if (Element.getTag() == dwarf::DW_TAG_subprogram)
- ElemDie = createSubprogramDIE(DW_Unit,
- DISubprogram(Element.getNode()));
+ ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
else
- ElemDie = createMemberDIE(DW_Unit,
- DIDerivedType(Element.getNode()));
+ ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Buffer.addChild(ElemDie);
}
@@ -944,33 +957,32 @@ void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
if (L)
addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
- if (H)
- addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
+ addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Buffer.addChild(DW_Subrange);
}
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
-void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
+void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
DICompositeType *CTy) {
Buffer.setTag(dwarf::DW_TAG_array_type);
if (CTy->getTag() == dwarf::DW_TAG_vector_type)
addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
// Emit derived type.
- addType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom());
+ addType(&Buffer, CTy->getTypeDerivedFrom());
DIArray Elements = CTy->getTypeArray();
// Get an anonymous type for index type.
- DIE *IdxTy = DW_Unit->getIndexTyDie();
+ DIE *IdxTy = ModuleCU->getIndexTyDie();
if (!IdxTy) {
// Construct an anonymous type for index type.
IdxTy = new DIE(dwarf::DW_TAG_base_type);
addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
dwarf::DW_ATE_signed);
- DW_Unit->addDie(IdxTy);
- DW_Unit->setIndexTyDie(IdxTy);
+ ModuleCU->addDie(IdxTy);
+ ModuleCU->setIndexTyDie(IdxTy);
}
// Add subranges to array type.
@@ -982,7 +994,7 @@ void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
-DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
+DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) {
DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
StringRef Name = ETy->getName();
addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
@@ -992,8 +1004,7 @@ DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
}
/// createGlobalVariableDIE - Create new DIE using GV.
-DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
- const DIGlobalVariable &GV) {
+DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
// If the global variable was optmized out then no need to create debug info
// entry.
if (!GV.getGlobal()) return NULL;
@@ -1014,7 +1025,7 @@ DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
LinkageName);
}
- addType(DW_Unit, GVDie, GV.getType());
+ addType(GVDie, GV.getType());
if (!GV.isLocalToUnit())
addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
addSourceLine(GVDie, &GV);
@@ -1030,13 +1041,13 @@ DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
}
/// createMemberDIE - Create new member DIE.
-DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
+DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
DIE *MemberDie = new DIE(DT.getTag());
StringRef Name = DT.getName();
if (!Name.empty())
addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
- addType(DW_Unit, MemberDie, DT.getTypeDerivedFrom());
+ addType(MemberDie, DT.getTypeDerivedFrom());
addSourceLine(MemberDie, &DT);
@@ -1073,21 +1084,27 @@ 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;
}
/// createSubprogramDIE - Create new DIE using SP.
-DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
- const DISubprogram &SP,
- bool IsConstructor,
- bool IsInlined) {
- DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram);
+DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
+ DIE *SPDie = ModuleCU->getDIE(SP.getNode());
+ if (SPDie)
+ return SPDie;
+
+ SPDie = new DIE(dwarf::DW_TAG_subprogram);
addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
StringRef LinkageName = SP.getLinkageName();
@@ -1103,9 +1120,6 @@ DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
}
addSourceLine(SPDie, &SP);
- DICompositeType SPTy = SP.getType();
- DIArray Args = SPTy.getTypeArray();
-
// Add prototyped tag, if C or ObjC.
unsigned Lang = SP.getCompileUnit().getLanguage();
if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
@@ -1113,98 +1127,56 @@ DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
// Add Return Type.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
- if (!IsConstructor) {
- if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
- addType(DW_Unit, SPDie, SPTy);
- else
- addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode()));
+
+ if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
+ addType(SPDie, SPTy);
+ else
+ addType(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())));
}
- if (!SP.isDefinition()) {
+ if (MakeDecl || !SP.isDefinition()) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments. Do not add arguments for subprogram definition. They will
- // be handled through RecordVariable.
+ // be handled while processing variables.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+ unsigned SPTag = SPTy.getTag();
+
if (SPTag == dwarf::DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode()));
+ addType(Arg, DIType(Args.getElement(i).getNode()));
addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
SPDie->addChild(Arg);
}
}
// DW_TAG_inlined_subroutine may refer to this DIE.
- DW_Unit->insertDIE(SP.getNode(), SPDie);
+ ModuleCU->insertDIE(SP.getNode(), SPDie);
return SPDie;
}
/// findCompileUnit - Get the compile unit for the given descriptor.
///
-CompileUnit &DwarfDebug::findCompileUnit(DICompileUnit Unit) const {
+CompileUnit *DwarfDebug::findCompileUnit(DICompileUnit Unit) {
DenseMap<Value *, CompileUnit *>::const_iterator I =
CompileUnitMap.find(Unit.getNode());
- assert(I != CompileUnitMap.end() && "Missing compile unit.");
- return *I->second;
-}
-
-/// createDbgScopeVariable - Create a new scope variable.
-///
-DIE *DwarfDebug::createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
- // Get the descriptor.
- const DIVariable &VD = DV->getVariable();
- StringRef Name = VD.getName();
- if (Name.empty())
- return NULL;
-
- // Translate tag to proper Dwarf tag. The result variable is dropped for
- // now.
- unsigned Tag;
- switch (VD.getTag()) {
- case dwarf::DW_TAG_return_variable:
- return NULL;
- case dwarf::DW_TAG_arg_variable:
- Tag = dwarf::DW_TAG_formal_parameter;
- break;
- case dwarf::DW_TAG_auto_variable: // fall thru
- default:
- Tag = dwarf::DW_TAG_variable;
- break;
- }
-
- // Define variable debug information entry.
- DIE *VariableDie = new DIE(Tag);
- addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
-
- // Add source line info if available.
- addSourceLine(VariableDie, &VD);
-
- // Add variable type.
- // FIXME: isBlockByrefVariable should be reformulated in terms of complex
- // addresses instead.
- if (VD.isBlockByrefVariable())
- addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name));
- else
- addType(Unit, VariableDie, VD.getType());
-
- // Add variable address.
- // Variables for abstract instances of inlined functions don't get a
- // location.
- MachineLocation Location;
- unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg);
- Location.set(FrameReg, Offset);
-
-
- if (VD.hasComplexAddress())
- addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
- else if (VD.isBlockByrefVariable())
- addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
- else
- addAddress(VariableDie, dwarf::DW_AT_location, Location);
-
- return VariableDie;
+ if (I == CompileUnitMap.end())
+ return constructCompileUnit(Unit.getNode());
+ return I->second;
}
/// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction.
@@ -1295,6 +1267,28 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *SPDie = ModuleCU->getDIE(SPNode);
assert (SPDie && "Unable to find subprogram DIE!");
+ DISubprogram SP(SPNode);
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit()) {
+ addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
+ // Add arguments.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+ unsigned SPTag = SPTy.getTag();
+ if (SPTag == dwarf::DW_TAG_subroutine_type)
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
+ addType(Arg, DIType(Args.getElement(i).getNode()));
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
+ SPDie->addChild(Arg);
+ }
+ DIE *SPDeclDie = SPDie;
+ SPDie = new DIE(dwarf::DW_TAG_subprogram);
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
+ SPDeclDie);
+
+ ModuleCU->addDie(SPDie);
+ }
+
addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
DWLabel("func_begin", SubprogramCount));
addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
@@ -1305,19 +1299,6 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
if (!DISubprogram(SPNode).isLocalToUnit())
addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
- // If there are global variables at this scope then add their dies.
- for (SmallVector<WeakVH, 4>::iterator SGI = ScopedGVs.begin(),
- SGE = ScopedGVs.end(); SGI != SGE; ++SGI) {
- MDNode *N = dyn_cast_or_null<MDNode>(*SGI);
- if (!N) continue;
- DIGlobalVariable GV(N);
- if (GV.getContext().getNode() == SPNode) {
- DIE *ScopedGVDie = createGlobalVariableDIE(ModuleCU, GV);
- if (ScopedGVDie)
- SPDie->addChild(ScopedGVDie);
- }
- }
-
return SPDie;
}
@@ -1401,8 +1382,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
-DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV,
- DbgScope *Scope, CompileUnit *Unit) {
+DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
// Get the descriptor.
const DIVariable &VD = DV->getVariable();
StringRef Name = VD.getName();
@@ -1451,9 +1431,9 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV,
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead.
if (VD.isBlockByrefVariable())
- addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name));
+ addType(VariableDie, getBlockByrefType(VD.getType(), Name));
else
- addType(Unit, VariableDie, VD.getType());
+ addType(VariableDie, VD.getType());
}
// Add variable address.
@@ -1522,7 +1502,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
// Add variables to scope.
SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
- DIE *VariableDIE = constructVariableDIE(Variables[i], Scope, ModuleCU);
+ DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
if (VariableDIE)
ScopeDIE->addChild(VariableDIE);
}
@@ -1579,7 +1559,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName)
return SrcId;
}
-void DwarfDebug::constructCompileUnit(MDNode *N) {
+CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) {
DICompileUnit DIUnit(N);
StringRef FN = DIUnit.getFilename();
StringRef Dir = DIUnit.getDirectory();
@@ -1618,6 +1598,7 @@ void DwarfDebug::constructCompileUnit(MDNode *N) {
CompileUnitMap[DIUnit.getNode()] = Unit;
CompileUnits.push_back(Unit);
+ return Unit;
}
void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
@@ -1631,14 +1612,16 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
if (ModuleCU->getDIE(DI_GV.getNode()))
return;
- DIE *VariableDie = createGlobalVariableDIE(ModuleCU, DI_GV);
+ DIE *VariableDie = createGlobalVariableDIE(DI_GV);
+ if (!VariableDie)
+ return;
// Add to map.
ModuleCU->insertDIE(N, VariableDie);
// Add to context owner.
- ModuleCU->getCUDie()->addChild(VariableDie);
-
+ addToContextOwner(VariableDie, DI_GV.getContext());
+
// Expose as global. FIXME - need to check external flag.
ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
@@ -1663,13 +1646,15 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
// class type.
return;
- DIE *SubprogramDie = createSubprogramDIE(ModuleCU, SP);
+ DIE *SubprogramDie = createSubprogramDIE(SP);
// Add to map.
ModuleCU->insertDIE(N, SubprogramDie);
// Add to context owner.
- ModuleCU->getCUDie()->addChild(SubprogramDie);
+ if (SP.getContext().getNode() == SP.getCompileUnit().getNode())
+ if (TopLevelDIEs.insert(SubprogramDie))
+ TopLevelDIEsVector.push_back(SubprogramDie);
// Expose as global.
ModuleCU->addGlobal(SP.getName(), SubprogramDie);
@@ -1709,21 +1694,16 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
if (!ModuleCU)
ModuleCU = CompileUnits[0];
- // Create DIEs for each of the externally visible global variables.
- 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
- constructGlobalVariableDIE(*I);
- }
-
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I)
constructSubprogramDIE(*I);
+ // Create DIEs for each global variable.
+ for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
+ E = DbgFinder.global_variable_end(); I != E; ++I)
+ constructGlobalVariableDIE(*I);
+
MMI = mmi;
shouldEmit = true;
MMI->setDebugInfoAvailability(true);
@@ -1770,6 +1750,22 @@ void DwarfDebug::endModule() {
addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
}
+ // Insert top level DIEs.
+ for (SmallVector<DIE *, 4>::iterator TI = TopLevelDIEsVector.begin(),
+ 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);
@@ -1898,6 +1894,7 @@ void DwarfDebug::endScope(const MachineInstr *MI) {
unsigned Label = MMI->NextLabelID();
Asm->printLabel(Label);
+ O << '\n';
SmallVector<DbgScope *, 2> &SD = I->second;
for (SmallVector<DbgScope *, 2>::iterator SDI = SD.begin(), SDE = SD.end();
@@ -2092,17 +2089,15 @@ void DwarfDebug::endFunction(MachineFunction *MF) {
MMI->getFrameMoves()));
// Clear debug info
- if (CurrentFnDbgScope) {
- CurrentFnDbgScope = NULL;
- DbgScopeMap.clear();
- DbgScopeBeginMap.clear();
- DbgScopeEndMap.clear();
- ConcreteScopes.clear();
- AbstractScopesList.clear();
- }
+ CurrentFnDbgScope = NULL;
+ DbgScopeMap.clear();
+ DbgScopeBeginMap.clear();
+ DbgScopeEndMap.clear();
+ ConcreteScopes.clear();
+ AbstractScopesList.clear();
Lines.clear();
-
+
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
@@ -2337,13 +2332,16 @@ void DwarfDebug::emitDIE(DIE *Die) {
}
}
-/// emitDebugInfo / emitDebugInfoPerCU - Emit the debug info section.
+/// emitDebugInfo - Emit the debug info section.
///
-void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) {
- DIE *Die = Unit->getCUDie();
+void DwarfDebug::emitDebugInfo() {
+ // Start debug info section.
+ Asm->OutStreamer.SwitchSection(
+ Asm->getObjFileLowering().getDwarfInfoSection());
+ DIE *Die = ModuleCU->getCUDie();
// Emit the compile units header.
- EmitLabel("info_begin", Unit->getID());
+ EmitLabel("info_begin", ModuleCU->getID());
// Emit size of content not including length itself
unsigned ContentSize = Die->getSize() +
@@ -2364,17 +2362,10 @@ void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) {
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
- EmitLabel("info_end", Unit->getID());
+ EmitLabel("info_end", ModuleCU->getID());
Asm->EOL();
-}
-
-void DwarfDebug::emitDebugInfo() {
- // Start debug info section.
- Asm->OutStreamer.SwitchSection(
- Asm->getObjFileLowering().getDwarfInfoSection());
- emitDebugInfoPerCU(ModuleCU);
}
/// emitAbbreviations - Emit the abbreviation section.
@@ -2534,9 +2525,9 @@ void DwarfDebug::emitDebugLines() {
std::pair<unsigned, unsigned> SourceID =
getSourceDirectoryAndFileIds(LineInfo.getSourceID());
O << '\t' << MAI->getCommentString() << ' '
- << getSourceDirectoryName(SourceID.first) << ' '
+ << getSourceDirectoryName(SourceID.first) << '/'
<< getSourceFileName(SourceID.second)
- <<" :" << utostr_32(LineInfo.getLine()) << '\n';
+ << ':' << utostr_32(LineInfo.getLine()) << '\n';
}
// Define the line address.
@@ -2672,24 +2663,30 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){
Asm->EOL();
}
-void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) {
- EmitDifference("pubnames_end", Unit->getID(),
- "pubnames_begin", Unit->getID(), true);
+/// emitDebugPubNames - Emit visible names into a debug pubnames section.
+///
+void DwarfDebug::emitDebugPubNames() {
+ // Start the dwarf pubnames section.
+ Asm->OutStreamer.SwitchSection(
+ Asm->getObjFileLowering().getDwarfPubNamesSection());
+
+ EmitDifference("pubnames_end", ModuleCU->getID(),
+ "pubnames_begin", ModuleCU->getID(), true);
Asm->EOL("Length of Public Names Info");
- EmitLabel("pubnames_begin", Unit->getID());
+ EmitLabel("pubnames_begin", ModuleCU->getID());
Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version");
EmitSectionOffset("info_begin", "section_info",
- Unit->getID(), 0, true, false);
+ ModuleCU->getID(), 0, true, false);
Asm->EOL("Offset of Compilation Unit Info");
- EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
+ EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
true);
Asm->EOL("Compilation Unit Length");
- const StringMap<DIE*> &Globals = Unit->getGlobals();
+ const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
for (StringMap<DIE*>::const_iterator
GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
const char *Name = GI->getKeyData();
@@ -2700,21 +2697,11 @@ void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) {
}
Asm->EmitInt32(0); Asm->EOL("End Mark");
- EmitLabel("pubnames_end", Unit->getID());
+ EmitLabel("pubnames_end", ModuleCU->getID());
Asm->EOL();
}
-/// emitDebugPubNames - Emit visible names into a debug pubnames section.
-///
-void DwarfDebug::emitDebugPubNames() {
- // Start the dwarf pubnames section.
- Asm->OutStreamer.SwitchSection(
- Asm->getObjFileLowering().getDwarfPubNamesSection());
-
- emitDebugPubNamesPerCU(ModuleCU);
-}
-
void DwarfDebug::emitDebugPubTypes() {
// Start the dwarf pubnames section.
Asm->OutStreamer.SwitchSection(
OpenPOWER on IntegriCloud