Index: lib/CodeGen/AsmPrinter/DwarfAccelTable.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -162,19 +162,37 @@ public: struct HashDataContents { const DIE *Die; // Offsets - char Flags; // Specific flags to output - HashDataContents(const DIE *D, char Flags) : Die(D), Flags(Flags) {} + HashDataContents(const DIE *D) : Die(D) {} #ifndef NDEBUG void print(raw_ostream &OS) const { - OS << " Offset: " << Die->getOffset() << "\n" - << " Tag: " << dwarf::TagString(Die->getTag()) << "\n" - << " Flags: " << Flags << "\n"; + OS << " Offset: " << Die->getOffset() << "\n"; + OS << " Tag: " << dwarf::TagString(Die->getTag()) << "\n"; } #endif }; + using DataForAtomFunction = + std::function; + static uint64_t DefaultGetDataForAtom(const HashDataContents &HDC, + unsigned AtomIdx) { + switch (AtomIdx) { + // First atom is a DIE offset. + case 0: + return HDC.Die->getDebugSectionOffset(); + // Second atom is a DIE offset. + case 1: + return HDC.Die->getTag(); + // Third atom is a flag field that's always zero. + case 2: + return 0; + default: + break; + } + return 0; + } + private: // String Data struct DataArray { @@ -206,9 +224,7 @@ OS << ""; OS << "\n"; for (HashDataContents *C : Data.Values) { - OS << " Offset: " << C->Die->getOffset() << "\n"; - OS << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n"; - OS << " Flags: " << C->Flags << "\n"; + C->print(OS); } } @@ -231,25 +247,28 @@ TableHeaderData HeaderData; std::vector Data; - using StringEntries = StringMap; + DataForAtomFunction DataForAtom; + using StringEntries = StringMap; StringEntries Entries; - // Buckets/Hashes/Offsets using HashList = std::vector; + HashList Hashes; + using BucketList = std::vector; BucketList Buckets; - HashList Hashes; // Public Implementation public: - DwarfAccelTable(ArrayRef); + DwarfAccelTable(ArrayRef, + DataForAtomFunction DataForAtom = DefaultGetDataForAtom); DwarfAccelTable(const DwarfAccelTable &) = delete; DwarfAccelTable &operator=(const DwarfAccelTable &) = delete; - void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags = 0); + void AddName(DwarfStringPoolEntryRef Name, const DIE *Die); void FinalizeTable(AsmPrinter *, StringRef); void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *); + #ifndef NDEBUG void print(raw_ostream &OS); void dump() { print(dbgs()); } Index: lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -31,20 +31,36 @@ using namespace llvm; +/// Return the size (in bytes) for the given Form. +static unsigned GetSizeForForm(uint16_t Form) { + switch (Form) { + case dwarf::DW_FORM_data1: + return 1; + case dwarf::DW_FORM_data2: + return 2; + case dwarf::DW_FORM_data4: + return 4; + case dwarf::DW_FORM_data8: + return 8; + default: + llvm_unreachable("Unsupported atom type"); + } +} + // The length of the header data is always going to be 4 + 4 + 4*NumAtoms. -DwarfAccelTable::DwarfAccelTable(ArrayRef atomList) - : Header(8 + (atomList.size() * 4)), HeaderData(atomList), - Entries(Allocator) {} +DwarfAccelTable::DwarfAccelTable(ArrayRef AtomList, + DataForAtomFunction DataForAtom) + : Header(8 + (AtomList.size() * 4)), HeaderData(AtomList), + DataForAtom(std::move(DataForAtom)), Entries(Allocator) {} -void DwarfAccelTable::AddName(DwarfStringPoolEntryRef Name, const DIE *die, - char Flags) { +void DwarfAccelTable::AddName(DwarfStringPoolEntryRef Name, const DIE *die) { assert(Data.empty() && "Already finalized!"); // If the string is in the list already then add this die to the list // otherwise add a new one. DataArray &DIEs = Entries[Name.getString()]; assert(!DIEs.Name || DIEs.Name == Name); DIEs.Name = Name; - DIEs.Values.push_back(new (Allocator) HashDataContents(die, Flags)); + DIEs.Values.push_back(new (Allocator) HashDataContents(die)); } void DwarfAccelTable::ComputeBucketCount() { @@ -68,7 +84,7 @@ Header.hashes_count = num; } -// compareDIEs - comparison predicate that sorts DIEs by their offset. +/// Comparison predicate that sorts DIEs by their offset. static bool compareDIEs(const DwarfAccelTable::HashDataContents *A, const DwarfAccelTable::HashDataContents *B) { return A->Die->getOffset() < B->Die->getOffset(); @@ -227,13 +243,12 @@ Asm->OutStreamer->AddComment("Num DIEs"); Asm->EmitInt32((*HI)->Data.Values.size()); for (HashDataContents *HD : (*HI)->Data.Values) { - // Emit the DIE offset - Asm->EmitInt32(HD->Die->getDebugSectionOffset()); - // If we have multiple Atoms emit that info too. - // FIXME: A bit of a hack, we either emit only one atom or all info. - if (HeaderData.Atoms.size() > 1) { - Asm->EmitInt16(HD->Die->getTag()); - Asm->EmitInt8(HD->Flags); + // Emit data for Atoms. + unsigned AtomIdx = 0; + for (auto Atom : HeaderData.Atoms) { + Asm->OutStreamer->EmitIntValue(DataForAtom(*HD, AtomIdx), + GetSizeForForm(Atom.form)); + AtomIdx++; } } PrevHash = (*HI)->HashValue;