diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:09:07 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:09:07 +0000 |
commit | 40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (patch) | |
tree | 076117cdf3579003f07cad4cdf0593347ce58150 /lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | e7908924d847e63b02bc82bfaa1709ab9c774dcd (diff) | |
download | FreeBSD-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.cpp | 411 |
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( |