10b57cec5SDimitry Andric //===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Data structures for DWARF info entries.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h"
140b57cec5SDimitry Andric #include "DwarfCompileUnit.h"
150b57cec5SDimitry Andric #include "DwarfDebug.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
170b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
210b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
230b57cec5SDimitry Andric #include "llvm/Support/Format.h"
240b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "dwarfdebug"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric // DIEAbbrevData Implementation
320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric /// Profile - Used to gather unique data for the abbreviation folding set.
350b57cec5SDimitry Andric ///
Profile(FoldingSetNodeID & ID) const360b57cec5SDimitry Andric void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
370b57cec5SDimitry Andric   // Explicitly cast to an integer type for which FoldingSetNodeID has
380b57cec5SDimitry Andric   // overloads.  Otherwise MSVC 2010 thinks this call is ambiguous.
390b57cec5SDimitry Andric   ID.AddInteger(unsigned(Attribute));
400b57cec5SDimitry Andric   ID.AddInteger(unsigned(Form));
410b57cec5SDimitry Andric   if (Form == dwarf::DW_FORM_implicit_const)
420b57cec5SDimitry Andric     ID.AddInteger(Value);
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
460b57cec5SDimitry Andric // DIEAbbrev Implementation
470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric /// Profile - Used to gather unique data for the abbreviation folding set.
500b57cec5SDimitry Andric ///
Profile(FoldingSetNodeID & ID) const510b57cec5SDimitry Andric void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
520b57cec5SDimitry Andric   ID.AddInteger(unsigned(Tag));
530b57cec5SDimitry Andric   ID.AddInteger(unsigned(Children));
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   // For each attribute description.
560b57cec5SDimitry Andric   for (unsigned i = 0, N = Data.size(); i < N; ++i)
570b57cec5SDimitry Andric     Data[i].Profile(ID);
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric /// Emit - Print the abbreviation using the specified asm printer.
610b57cec5SDimitry Andric ///
Emit(const AsmPrinter * AP) const620b57cec5SDimitry Andric void DIEAbbrev::Emit(const AsmPrinter *AP) const {
630b57cec5SDimitry Andric   // Emit its Dwarf tag type.
645ffd83dbSDimitry Andric   AP->emitULEB128(Tag, dwarf::TagString(Tag).data());
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   // Emit whether it has children DIEs.
675ffd83dbSDimitry Andric   AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   // For each attribute description.
700b57cec5SDimitry Andric   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
710b57cec5SDimitry Andric     const DIEAbbrevData &AttrData = Data[i];
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric     // Emit attribute type.
745ffd83dbSDimitry Andric     AP->emitULEB128(AttrData.getAttribute(),
750b57cec5SDimitry Andric                     dwarf::AttributeString(AttrData.getAttribute()).data());
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric     // Emit form type.
780b57cec5SDimitry Andric #ifndef NDEBUG
790b57cec5SDimitry Andric     // Could be an assertion, but this way we can see the failing form code
800b57cec5SDimitry Andric     // easily, which helps track down where it came from.
810b57cec5SDimitry Andric     if (!dwarf::isValidFormForVersion(AttrData.getForm(),
820b57cec5SDimitry Andric                                       AP->getDwarfVersion())) {
830b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
840b57cec5SDimitry Andric                         << " for DWARF version " << AP->getDwarfVersion()
850b57cec5SDimitry Andric                         << "\n");
860b57cec5SDimitry Andric       llvm_unreachable("Invalid form for specified DWARF version");
870b57cec5SDimitry Andric     }
880b57cec5SDimitry Andric #endif
895ffd83dbSDimitry Andric     AP->emitULEB128(AttrData.getForm(),
900b57cec5SDimitry Andric                     dwarf::FormEncodingString(AttrData.getForm()).data());
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric     // Emit value for DW_FORM_implicit_const.
930b57cec5SDimitry Andric     if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
945ffd83dbSDimitry Andric       AP->emitSLEB128(AttrData.getValue());
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   // Mark end of abbreviation.
985ffd83dbSDimitry Andric   AP->emitULEB128(0, "EOM(1)");
995ffd83dbSDimitry Andric   AP->emitULEB128(0, "EOM(2)");
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const1030b57cec5SDimitry Andric void DIEAbbrev::print(raw_ostream &O) const {
1040b57cec5SDimitry Andric   O << "Abbreviation @"
1050b57cec5SDimitry Andric     << format("0x%lx", (long)(intptr_t)this)
1060b57cec5SDimitry Andric     << "  "
1070b57cec5SDimitry Andric     << dwarf::TagString(Tag)
1080b57cec5SDimitry Andric     << " "
1090b57cec5SDimitry Andric     << dwarf::ChildrenString(Children)
1100b57cec5SDimitry Andric     << '\n';
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
1130b57cec5SDimitry Andric     O << "  "
1140b57cec5SDimitry Andric       << dwarf::AttributeString(Data[i].getAttribute())
1150b57cec5SDimitry Andric       << "  "
1160b57cec5SDimitry Andric       << dwarf::FormEncodingString(Data[i].getForm());
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric     if (Data[i].getForm() == dwarf::DW_FORM_implicit_const)
1190b57cec5SDimitry Andric       O << " " << Data[i].getValue();
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric     O << '\n';
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1260b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIEAbbrev::dump() const {
1270b57cec5SDimitry Andric   print(dbgs());
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric #endif
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1320b57cec5SDimitry Andric // DIEAbbrevSet Implementation
1330b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1340b57cec5SDimitry Andric 
~DIEAbbrevSet()1350b57cec5SDimitry Andric DIEAbbrevSet::~DIEAbbrevSet() {
1360b57cec5SDimitry Andric   for (DIEAbbrev *Abbrev : Abbreviations)
1370b57cec5SDimitry Andric     Abbrev->~DIEAbbrev();
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
uniqueAbbreviation(DIE & Die)1400b57cec5SDimitry Andric DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   FoldingSetNodeID ID;
1430b57cec5SDimitry Andric   DIEAbbrev Abbrev = Die.generateAbbrev();
1440b57cec5SDimitry Andric   Abbrev.Profile(ID);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   void *InsertPos;
1470b57cec5SDimitry Andric   if (DIEAbbrev *Existing =
1480b57cec5SDimitry Andric           AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
1490b57cec5SDimitry Andric     Die.setAbbrevNumber(Existing->getNumber());
1500b57cec5SDimitry Andric     return *Existing;
1510b57cec5SDimitry Andric   }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   // Move the abbreviation to the heap and assign a number.
1540b57cec5SDimitry Andric   DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));
1550b57cec5SDimitry Andric   Abbreviations.push_back(New);
1560b57cec5SDimitry Andric   New->setNumber(Abbreviations.size());
1570b57cec5SDimitry Andric   Die.setAbbrevNumber(Abbreviations.size());
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   // Store it for lookup.
1600b57cec5SDimitry Andric   AbbreviationsSet.InsertNode(New, InsertPos);
1610b57cec5SDimitry Andric   return *New;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
Emit(const AsmPrinter * AP,MCSection * Section) const1640b57cec5SDimitry Andric void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {
1650b57cec5SDimitry Andric   if (!Abbreviations.empty()) {
1660b57cec5SDimitry Andric     // Start the debug abbrev section.
16781ad6265SDimitry Andric     AP->OutStreamer->switchSection(Section);
1680b57cec5SDimitry Andric     AP->emitDwarfAbbrevs(Abbreviations);
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1730b57cec5SDimitry Andric // DIE Implementation
1740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1750b57cec5SDimitry Andric 
getParent() const17606c3fb27SDimitry Andric DIE *DIE::getParent() const { return dyn_cast_if_present<DIE *>(Owner); }
1770b57cec5SDimitry Andric 
generateAbbrev() const1780b57cec5SDimitry Andric DIEAbbrev DIE::generateAbbrev() const {
1790b57cec5SDimitry Andric   DIEAbbrev Abbrev(Tag, hasChildren());
1800b57cec5SDimitry Andric   for (const DIEValue &V : values())
1810b57cec5SDimitry Andric     if (V.getForm() == dwarf::DW_FORM_implicit_const)
1820b57cec5SDimitry Andric       Abbrev.AddImplicitConstAttribute(V.getAttribute(),
1830b57cec5SDimitry Andric                                        V.getDIEInteger().getValue());
1840b57cec5SDimitry Andric     else
1850b57cec5SDimitry Andric       Abbrev.AddAttribute(V.getAttribute(), V.getForm());
1860b57cec5SDimitry Andric   return Abbrev;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
getDebugSectionOffset() const189e8d8bef9SDimitry Andric uint64_t DIE::getDebugSectionOffset() const {
1900b57cec5SDimitry Andric   const DIEUnit *Unit = getUnit();
1910b57cec5SDimitry Andric   assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");
1920b57cec5SDimitry Andric   return Unit->getDebugSectionOffset() + getOffset();
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
getUnitDie() const1950b57cec5SDimitry Andric const DIE *DIE::getUnitDie() const {
1960b57cec5SDimitry Andric   const DIE *p = this;
1970b57cec5SDimitry Andric   while (p) {
1980b57cec5SDimitry Andric     if (p->getTag() == dwarf::DW_TAG_compile_unit ||
19981ad6265SDimitry Andric         p->getTag() == dwarf::DW_TAG_skeleton_unit ||
2000b57cec5SDimitry Andric         p->getTag() == dwarf::DW_TAG_type_unit)
2010b57cec5SDimitry Andric       return p;
2020b57cec5SDimitry Andric     p = p->getParent();
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric   return nullptr;
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
getUnit() const2070b57cec5SDimitry Andric DIEUnit *DIE::getUnit() const {
2080b57cec5SDimitry Andric   const DIE *UnitDie = getUnitDie();
2090b57cec5SDimitry Andric   if (UnitDie)
21006c3fb27SDimitry Andric     return dyn_cast_if_present<DIEUnit *>(UnitDie->Owner);
2110b57cec5SDimitry Andric   return nullptr;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
findAttribute(dwarf::Attribute Attribute) const2140b57cec5SDimitry Andric DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {
2150b57cec5SDimitry Andric   // Iterate through all the attributes until we find the one we're
2160b57cec5SDimitry Andric   // looking for, if we can't find it return NULL.
2170b57cec5SDimitry Andric   for (const auto &V : values())
2180b57cec5SDimitry Andric     if (V.getAttribute() == Attribute)
2190b57cec5SDimitry Andric       return V;
2200b57cec5SDimitry Andric   return DIEValue();
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric LLVM_DUMP_METHOD
printValues(raw_ostream & O,const DIEValueList & Values,StringRef Type,unsigned Size,unsigned IndentCount)2240b57cec5SDimitry Andric static void printValues(raw_ostream &O, const DIEValueList &Values,
2250b57cec5SDimitry Andric                         StringRef Type, unsigned Size, unsigned IndentCount) {
2260b57cec5SDimitry Andric   O << Type << ": Size: " << Size << "\n";
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   unsigned I = 0;
2290b57cec5SDimitry Andric   const std::string Indent(IndentCount, ' ');
2300b57cec5SDimitry Andric   for (const auto &V : Values.values()) {
2310b57cec5SDimitry Andric     O << Indent;
2320b57cec5SDimitry Andric     O << "Blk[" << I++ << "]";
2330b57cec5SDimitry Andric     O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";
2340b57cec5SDimitry Andric     V.print(O);
2350b57cec5SDimitry Andric     O << "\n";
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O,unsigned IndentCount) const2400b57cec5SDimitry Andric void DIE::print(raw_ostream &O, unsigned IndentCount) const {
2410b57cec5SDimitry Andric   const std::string Indent(IndentCount, ' ');
2420b57cec5SDimitry Andric   O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)
2430b57cec5SDimitry Andric     << ", Offset: " << Offset << ", Size: " << Size << "\n";
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   O << Indent << dwarf::TagString(getTag()) << " "
2460b57cec5SDimitry Andric     << dwarf::ChildrenString(hasChildren()) << "\n";
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   IndentCount += 2;
2490b57cec5SDimitry Andric   for (const auto &V : values()) {
2500b57cec5SDimitry Andric     O << Indent;
2510b57cec5SDimitry Andric     O << dwarf::AttributeString(V.getAttribute());
2520b57cec5SDimitry Andric     O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";
2530b57cec5SDimitry Andric     V.print(O);
2540b57cec5SDimitry Andric     O << "\n";
2550b57cec5SDimitry Andric   }
2560b57cec5SDimitry Andric   IndentCount -= 2;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   for (const auto &Child : children())
2590b57cec5SDimitry Andric     Child.print(O, IndentCount + 4);
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   O << "\n";
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2650b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIE::dump() const {
2660b57cec5SDimitry Andric   print(dbgs());
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric #endif
2690b57cec5SDimitry Andric 
computeOffsetsAndAbbrevs(const dwarf::FormParams & FormParams,DIEAbbrevSet & AbbrevSet,unsigned CUOffset)27004eeddc0SDimitry Andric unsigned DIE::computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams,
2710b57cec5SDimitry Andric                                        DIEAbbrevSet &AbbrevSet,
2720b57cec5SDimitry Andric                                        unsigned CUOffset) {
2730b57cec5SDimitry Andric   // Unique the abbreviation and fill in the abbreviation number so this DIE
2740b57cec5SDimitry Andric   // can be emitted.
2750b57cec5SDimitry Andric   const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   // Set compile/type unit relative offset of this DIE.
2780b57cec5SDimitry Andric   setOffset(CUOffset);
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   // Add the byte size of the abbreviation code.
2810b57cec5SDimitry Andric   CUOffset += getULEB128Size(getAbbrevNumber());
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // Add the byte size of all the DIE attribute values.
2840b57cec5SDimitry Andric   for (const auto &V : values())
28504eeddc0SDimitry Andric     CUOffset += V.sizeOf(FormParams);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   // Let the children compute their offsets and abbreviation numbers.
2880b57cec5SDimitry Andric   if (hasChildren()) {
2890b57cec5SDimitry Andric     (void)Abbrev;
2900b57cec5SDimitry Andric     assert(Abbrev.hasChildren() && "Children flag not set");
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric     for (auto &Child : children())
29304eeddc0SDimitry Andric       CUOffset =
29404eeddc0SDimitry Andric           Child.computeOffsetsAndAbbrevs(FormParams, AbbrevSet, CUOffset);
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric     // Each child chain is terminated with a zero byte, adjust the offset.
2970b57cec5SDimitry Andric     CUOffset += sizeof(int8_t);
2980b57cec5SDimitry Andric   }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // Compute the byte size of this DIE and all of its children correctly. This
3010b57cec5SDimitry Andric   // is needed so that top level DIE can help the compile unit set its length
3020b57cec5SDimitry Andric   // correctly.
3030b57cec5SDimitry Andric   setSize(CUOffset - getOffset());
3040b57cec5SDimitry Andric   return CUOffset;
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3080b57cec5SDimitry Andric // DIEUnit Implementation
3090b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
DIEUnit(dwarf::Tag UnitTag)3101fd87a68SDimitry Andric DIEUnit::DIEUnit(dwarf::Tag UnitTag) : Die(UnitTag) {
3110b57cec5SDimitry Andric   Die.Owner = this;
3120b57cec5SDimitry Andric   assert((UnitTag == dwarf::DW_TAG_compile_unit ||
313480093f4SDimitry Andric           UnitTag == dwarf::DW_TAG_skeleton_unit ||
3140b57cec5SDimitry Andric           UnitTag == dwarf::DW_TAG_type_unit ||
315480093f4SDimitry Andric           UnitTag == dwarf::DW_TAG_partial_unit) &&
316480093f4SDimitry Andric          "expected a unit TAG");
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
emitValue(const AsmPrinter * AP) const3195ffd83dbSDimitry Andric void DIEValue::emitValue(const AsmPrinter *AP) const {
3200b57cec5SDimitry Andric   switch (Ty) {
3210b57cec5SDimitry Andric   case isNone:
3220b57cec5SDimitry Andric     llvm_unreachable("Expected valid DIEValue");
3230b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T)                                                     \
3240b57cec5SDimitry Andric   case is##T:                                                                  \
3255ffd83dbSDimitry Andric     getDIE##T().emitValue(AP, Form);                                           \
3260b57cec5SDimitry Andric     break;
3270b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
sizeOf(const dwarf::FormParams & FormParams) const33104eeddc0SDimitry Andric unsigned DIEValue::sizeOf(const dwarf::FormParams &FormParams) const {
3320b57cec5SDimitry Andric   switch (Ty) {
3330b57cec5SDimitry Andric   case isNone:
3340b57cec5SDimitry Andric     llvm_unreachable("Expected valid DIEValue");
3350b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T)                                                     \
3360b57cec5SDimitry Andric   case is##T:                                                                  \
33704eeddc0SDimitry Andric     return getDIE##T().sizeOf(FormParams, Form);
3380b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3390b57cec5SDimitry Andric   }
3400b57cec5SDimitry Andric   llvm_unreachable("Unknown DIE kind");
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const3440b57cec5SDimitry Andric void DIEValue::print(raw_ostream &O) const {
3450b57cec5SDimitry Andric   switch (Ty) {
3460b57cec5SDimitry Andric   case isNone:
3470b57cec5SDimitry Andric     llvm_unreachable("Expected valid DIEValue");
3480b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T)                                                     \
3490b57cec5SDimitry Andric   case is##T:                                                                  \
3500b57cec5SDimitry Andric     getDIE##T().print(O);                                                      \
3510b57cec5SDimitry Andric     break;
3520b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3530b57cec5SDimitry Andric   }
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3570b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIEValue::dump() const {
3580b57cec5SDimitry Andric   print(dbgs());
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric #endif
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3630b57cec5SDimitry Andric // DIEInteger Implementation
3640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric /// EmitValue - Emit integer of appropriate size.
3670b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const3685ffd83dbSDimitry Andric void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
3690b57cec5SDimitry Andric   switch (Form) {
3700b57cec5SDimitry Andric   case dwarf::DW_FORM_implicit_const:
3710b57cec5SDimitry Andric   case dwarf::DW_FORM_flag_present:
3720b57cec5SDimitry Andric     // Emit something to keep the lines and comments in sync.
3730b57cec5SDimitry Andric     // FIXME: Is there a better way to do this?
37481ad6265SDimitry Andric     Asm->OutStreamer->addBlankLine();
3750b57cec5SDimitry Andric     return;
3760b57cec5SDimitry Andric   case dwarf::DW_FORM_flag:
3770b57cec5SDimitry Andric   case dwarf::DW_FORM_ref1:
3780b57cec5SDimitry Andric   case dwarf::DW_FORM_data1:
3790b57cec5SDimitry Andric   case dwarf::DW_FORM_strx1:
3800b57cec5SDimitry Andric   case dwarf::DW_FORM_addrx1:
3810b57cec5SDimitry Andric   case dwarf::DW_FORM_ref2:
3820b57cec5SDimitry Andric   case dwarf::DW_FORM_data2:
3830b57cec5SDimitry Andric   case dwarf::DW_FORM_strx2:
3840b57cec5SDimitry Andric   case dwarf::DW_FORM_addrx2:
3850b57cec5SDimitry Andric   case dwarf::DW_FORM_strx3:
38606c3fb27SDimitry Andric   case dwarf::DW_FORM_addrx3:
3870b57cec5SDimitry Andric   case dwarf::DW_FORM_strp:
3880b57cec5SDimitry Andric   case dwarf::DW_FORM_ref4:
3890b57cec5SDimitry Andric   case dwarf::DW_FORM_data4:
3900b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_sup4:
3910b57cec5SDimitry Andric   case dwarf::DW_FORM_strx4:
3920b57cec5SDimitry Andric   case dwarf::DW_FORM_addrx4:
3930b57cec5SDimitry Andric   case dwarf::DW_FORM_ref8:
3940b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_sig8:
3950b57cec5SDimitry Andric   case dwarf::DW_FORM_data8:
3960b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_sup8:
3970b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_ref_alt:
3980b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_strp_alt:
3990b57cec5SDimitry Andric   case dwarf::DW_FORM_line_strp:
4000b57cec5SDimitry Andric   case dwarf::DW_FORM_sec_offset:
4010b57cec5SDimitry Andric   case dwarf::DW_FORM_strp_sup:
4020b57cec5SDimitry Andric   case dwarf::DW_FORM_addr:
4030b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_addr:
40404eeddc0SDimitry Andric     Asm->OutStreamer->emitIntValue(Integer,
40504eeddc0SDimitry Andric                                    sizeOf(Asm->getDwarfFormParams(), Form));
4060b57cec5SDimitry Andric     return;
4070b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_str_index:
4080b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_addr_index:
4090b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_udata:
4100b57cec5SDimitry Andric   case dwarf::DW_FORM_strx:
4110b57cec5SDimitry Andric   case dwarf::DW_FORM_addrx:
4120b57cec5SDimitry Andric   case dwarf::DW_FORM_rnglistx:
4130b57cec5SDimitry Andric   case dwarf::DW_FORM_udata:
4145ffd83dbSDimitry Andric     Asm->emitULEB128(Integer);
4150b57cec5SDimitry Andric     return;
4160b57cec5SDimitry Andric   case dwarf::DW_FORM_sdata:
4175ffd83dbSDimitry Andric     Asm->emitSLEB128(Integer);
4180b57cec5SDimitry Andric     return;
4190b57cec5SDimitry Andric   default: llvm_unreachable("DIE Value form not supported yet");
4200b57cec5SDimitry Andric   }
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
42304eeddc0SDimitry Andric /// sizeOf - Determine size of integer value in bytes.
4240b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const42504eeddc0SDimitry Andric unsigned DIEInteger::sizeOf(const dwarf::FormParams &FormParams,
42604eeddc0SDimitry Andric                             dwarf::Form Form) const {
427bdd1243dSDimitry Andric   if (std::optional<uint8_t> FixedSize =
42804eeddc0SDimitry Andric           dwarf::getFixedFormByteSize(Form, FormParams))
4290b57cec5SDimitry Andric     return *FixedSize;
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   switch (Form) {
4320b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_str_index:
4330b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_addr_index:
4340b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_udata:
4350b57cec5SDimitry Andric   case dwarf::DW_FORM_strx:
4360b57cec5SDimitry Andric   case dwarf::DW_FORM_addrx:
4370b57cec5SDimitry Andric   case dwarf::DW_FORM_rnglistx:
4380b57cec5SDimitry Andric   case dwarf::DW_FORM_udata:
4390b57cec5SDimitry Andric     return getULEB128Size(Integer);
4400b57cec5SDimitry Andric   case dwarf::DW_FORM_sdata:
4410b57cec5SDimitry Andric     return getSLEB128Size(Integer);
4420b57cec5SDimitry Andric   default: llvm_unreachable("DIE Value form not supported yet");
4430b57cec5SDimitry Andric   }
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const4470b57cec5SDimitry Andric void DIEInteger::print(raw_ostream &O) const {
4480b57cec5SDimitry Andric   O << "Int: " << (int64_t)Integer << "  0x";
4490b57cec5SDimitry Andric   O.write_hex(Integer);
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4530b57cec5SDimitry Andric // DIEExpr Implementation
4540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric /// EmitValue - Emit expression value.
4570b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const4585ffd83dbSDimitry Andric void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
45904eeddc0SDimitry Andric   AP->emitDebugValue(Expr, sizeOf(AP->getDwarfFormParams(), Form));
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric /// SizeOf - Determine size of expression value in bytes.
4630b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const46404eeddc0SDimitry Andric unsigned DIEExpr::sizeOf(const dwarf::FormParams &FormParams,
46504eeddc0SDimitry Andric                          dwarf::Form Form) const {
466e8d8bef9SDimitry Andric   switch (Form) {
467e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data4:
468e8d8bef9SDimitry Andric     return 4;
469e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data8:
470e8d8bef9SDimitry Andric     return 8;
471e8d8bef9SDimitry Andric   case dwarf::DW_FORM_sec_offset:
47204eeddc0SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
473e8d8bef9SDimitry Andric   default:
474e8d8bef9SDimitry Andric     llvm_unreachable("DIE Value form not supported yet");
475e8d8bef9SDimitry Andric   }
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const4790b57cec5SDimitry Andric void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4820b57cec5SDimitry Andric // DIELabel Implementation
4830b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric /// EmitValue - Emit label value.
4860b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const4875ffd83dbSDimitry Andric void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
488e8d8bef9SDimitry Andric   bool IsSectionRelative = Form != dwarf::DW_FORM_addr;
48904eeddc0SDimitry Andric   AP->emitLabelReference(Label, sizeOf(AP->getDwarfFormParams(), Form),
49004eeddc0SDimitry Andric                          IsSectionRelative);
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric 
49304eeddc0SDimitry Andric /// sizeOf - Determine size of label value in bytes.
4940b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const49504eeddc0SDimitry Andric unsigned DIELabel::sizeOf(const dwarf::FormParams &FormParams,
49604eeddc0SDimitry Andric                           dwarf::Form Form) const {
497e8d8bef9SDimitry Andric   switch (Form) {
498e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data4:
499e8d8bef9SDimitry Andric     return 4;
500e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data8:
501e8d8bef9SDimitry Andric     return 8;
502e8d8bef9SDimitry Andric   case dwarf::DW_FORM_sec_offset:
503e8d8bef9SDimitry Andric   case dwarf::DW_FORM_strp:
50404eeddc0SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
505e8d8bef9SDimitry Andric   case dwarf::DW_FORM_addr:
50604eeddc0SDimitry Andric     return FormParams.AddrSize;
507e8d8bef9SDimitry Andric   default:
508e8d8bef9SDimitry Andric     llvm_unreachable("DIE Value form not supported yet");
509e8d8bef9SDimitry Andric   }
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5130b57cec5SDimitry Andric void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5160b57cec5SDimitry Andric // DIEBaseTypeRef Implementation
5170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5180b57cec5SDimitry Andric 
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5195ffd83dbSDimitry Andric void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5200b57cec5SDimitry Andric   uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
5210b57cec5SDimitry Andric   assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
5225ffd83dbSDimitry Andric   AP->emitULEB128(Offset, nullptr, ULEB128PadSize);
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
sizeOf(const dwarf::FormParams &,dwarf::Form) const52504eeddc0SDimitry Andric unsigned DIEBaseTypeRef::sizeOf(const dwarf::FormParams &, dwarf::Form) const {
5260b57cec5SDimitry Andric   return ULEB128PadSize;
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5300b57cec5SDimitry Andric void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5330b57cec5SDimitry Andric // DIEDelta Implementation
5340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric /// EmitValue - Emit delta value.
5370b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5385ffd83dbSDimitry Andric void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
53904eeddc0SDimitry Andric   AP->emitLabelDifference(LabelHi, LabelLo,
54004eeddc0SDimitry Andric                           sizeOf(AP->getDwarfFormParams(), Form));
5410b57cec5SDimitry Andric }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric /// SizeOf - Determine size of delta value in bytes.
5440b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const54504eeddc0SDimitry Andric unsigned DIEDelta::sizeOf(const dwarf::FormParams &FormParams,
54604eeddc0SDimitry Andric                           dwarf::Form Form) const {
547e8d8bef9SDimitry Andric   switch (Form) {
548e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data4:
549e8d8bef9SDimitry Andric     return 4;
550e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data8:
551e8d8bef9SDimitry Andric     return 8;
552e8d8bef9SDimitry Andric   case dwarf::DW_FORM_sec_offset:
55304eeddc0SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
554e8d8bef9SDimitry Andric   default:
555e8d8bef9SDimitry Andric     llvm_unreachable("DIE Value form not supported yet");
556e8d8bef9SDimitry Andric   }
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5600b57cec5SDimitry Andric void DIEDelta::print(raw_ostream &O) const {
5610b57cec5SDimitry Andric   O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5650b57cec5SDimitry Andric // DIEString Implementation
5660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric /// EmitValue - Emit string value.
5690b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5705ffd83dbSDimitry Andric void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5710b57cec5SDimitry Andric   // Index of string in symbol table.
5720b57cec5SDimitry Andric   switch (Form) {
5730b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_str_index:
5740b57cec5SDimitry Andric   case dwarf::DW_FORM_strx:
5750b57cec5SDimitry Andric   case dwarf::DW_FORM_strx1:
5760b57cec5SDimitry Andric   case dwarf::DW_FORM_strx2:
5770b57cec5SDimitry Andric   case dwarf::DW_FORM_strx3:
5780b57cec5SDimitry Andric   case dwarf::DW_FORM_strx4:
5795ffd83dbSDimitry Andric     DIEInteger(S.getIndex()).emitValue(AP, Form);
5800b57cec5SDimitry Andric     return;
5810b57cec5SDimitry Andric   case dwarf::DW_FORM_strp:
582bdd1243dSDimitry Andric     if (AP->doesDwarfUseRelocationsAcrossSections())
5835ffd83dbSDimitry Andric       DIELabel(S.getSymbol()).emitValue(AP, Form);
5840b57cec5SDimitry Andric     else
5855ffd83dbSDimitry Andric       DIEInteger(S.getOffset()).emitValue(AP, Form);
5860b57cec5SDimitry Andric     return;
5870b57cec5SDimitry Andric   default:
5880b57cec5SDimitry Andric     llvm_unreachable("Expected valid string form");
5890b57cec5SDimitry Andric   }
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
59204eeddc0SDimitry Andric /// sizeOf - Determine size of delta value in bytes.
5930b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const59404eeddc0SDimitry Andric unsigned DIEString::sizeOf(const dwarf::FormParams &FormParams,
59504eeddc0SDimitry Andric                            dwarf::Form Form) const {
5960b57cec5SDimitry Andric   // Index of string in symbol table.
5970b57cec5SDimitry Andric   switch (Form) {
5980b57cec5SDimitry Andric   case dwarf::DW_FORM_GNU_str_index:
5990b57cec5SDimitry Andric   case dwarf::DW_FORM_strx:
6000b57cec5SDimitry Andric   case dwarf::DW_FORM_strx1:
6010b57cec5SDimitry Andric   case dwarf::DW_FORM_strx2:
6020b57cec5SDimitry Andric   case dwarf::DW_FORM_strx3:
6030b57cec5SDimitry Andric   case dwarf::DW_FORM_strx4:
60404eeddc0SDimitry Andric     return DIEInteger(S.getIndex()).sizeOf(FormParams, Form);
6050b57cec5SDimitry Andric   case dwarf::DW_FORM_strp:
60604eeddc0SDimitry Andric     if (FormParams.DwarfUsesRelocationsAcrossSections)
60704eeddc0SDimitry Andric       return DIELabel(S.getSymbol()).sizeOf(FormParams, Form);
60804eeddc0SDimitry Andric     return DIEInteger(S.getOffset()).sizeOf(FormParams, Form);
6090b57cec5SDimitry Andric   default:
6100b57cec5SDimitry Andric     llvm_unreachable("Expected valid string form");
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const6150b57cec5SDimitry Andric void DIEString::print(raw_ostream &O) const {
6160b57cec5SDimitry Andric   O << "String: " << S.getString();
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6200b57cec5SDimitry Andric // DIEInlineString Implementation
6210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
emitValue(const AsmPrinter * AP,dwarf::Form Form) const6225ffd83dbSDimitry Andric void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6230b57cec5SDimitry Andric   if (Form == dwarf::DW_FORM_string) {
6245ffd83dbSDimitry Andric     AP->OutStreamer->emitBytes(S);
6250b57cec5SDimitry Andric     AP->emitInt8(0);
6260b57cec5SDimitry Andric     return;
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric   llvm_unreachable("Expected valid string form");
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric 
sizeOf(const dwarf::FormParams &,dwarf::Form) const63104eeddc0SDimitry Andric unsigned DIEInlineString::sizeOf(const dwarf::FormParams &, dwarf::Form) const {
6320b57cec5SDimitry Andric   // Emit string bytes + NULL byte.
6330b57cec5SDimitry Andric   return S.size() + 1;
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const6370b57cec5SDimitry Andric void DIEInlineString::print(raw_ostream &O) const {
6380b57cec5SDimitry Andric   O << "InlineString: " << S;
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6420b57cec5SDimitry Andric // DIEEntry Implementation
6430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric /// EmitValue - Emit debug information entry offset.
6460b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const6475ffd83dbSDimitry Andric void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6480b57cec5SDimitry Andric 
6490b57cec5SDimitry Andric   switch (Form) {
6500b57cec5SDimitry Andric   case dwarf::DW_FORM_ref1:
6510b57cec5SDimitry Andric   case dwarf::DW_FORM_ref2:
6520b57cec5SDimitry Andric   case dwarf::DW_FORM_ref4:
6530b57cec5SDimitry Andric   case dwarf::DW_FORM_ref8:
65404eeddc0SDimitry Andric     AP->OutStreamer->emitIntValue(Entry->getOffset(),
65504eeddc0SDimitry Andric                                   sizeOf(AP->getDwarfFormParams(), Form));
6560b57cec5SDimitry Andric     return;
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_udata:
6595ffd83dbSDimitry Andric     AP->emitULEB128(Entry->getOffset());
6600b57cec5SDimitry Andric     return;
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_addr: {
6630b57cec5SDimitry Andric     // Get the absolute offset for this DIE within the debug info/types section.
664e8d8bef9SDimitry Andric     uint64_t Addr = Entry->getDebugSectionOffset();
6650b57cec5SDimitry Andric     if (const MCSymbol *SectionSym =
6660b57cec5SDimitry Andric             Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
66704eeddc0SDimitry Andric       AP->emitLabelPlusOffset(SectionSym, Addr,
66804eeddc0SDimitry Andric                               sizeOf(AP->getDwarfFormParams(), Form), true);
6690b57cec5SDimitry Andric       return;
6700b57cec5SDimitry Andric     }
6710b57cec5SDimitry Andric 
67204eeddc0SDimitry Andric     AP->OutStreamer->emitIntValue(Addr, sizeOf(AP->getDwarfFormParams(), Form));
6730b57cec5SDimitry Andric     return;
6740b57cec5SDimitry Andric   }
6750b57cec5SDimitry Andric   default:
6760b57cec5SDimitry Andric     llvm_unreachable("Improper form for DIE reference");
6770b57cec5SDimitry Andric   }
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric 
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const68004eeddc0SDimitry Andric unsigned DIEEntry::sizeOf(const dwarf::FormParams &FormParams,
68104eeddc0SDimitry Andric                           dwarf::Form Form) const {
6820b57cec5SDimitry Andric   switch (Form) {
6830b57cec5SDimitry Andric   case dwarf::DW_FORM_ref1:
6840b57cec5SDimitry Andric     return 1;
6850b57cec5SDimitry Andric   case dwarf::DW_FORM_ref2:
6860b57cec5SDimitry Andric     return 2;
6870b57cec5SDimitry Andric   case dwarf::DW_FORM_ref4:
6880b57cec5SDimitry Andric     return 4;
6890b57cec5SDimitry Andric   case dwarf::DW_FORM_ref8:
6900b57cec5SDimitry Andric     return 8;
6910b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_udata:
6920b57cec5SDimitry Andric     return getULEB128Size(Entry->getOffset());
6930b57cec5SDimitry Andric   case dwarf::DW_FORM_ref_addr:
69404eeddc0SDimitry Andric     return FormParams.getRefAddrByteSize();
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   default:
6970b57cec5SDimitry Andric     llvm_unreachable("Improper form for DIE reference");
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric }
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const7020b57cec5SDimitry Andric void DIEEntry::print(raw_ostream &O) const {
7030b57cec5SDimitry Andric   O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7070b57cec5SDimitry Andric // DIELoc Implementation
7080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7090b57cec5SDimitry Andric 
computeSize(const dwarf::FormParams & FormParams) const71004eeddc0SDimitry Andric unsigned DIELoc::computeSize(const dwarf::FormParams &FormParams) const {
7110b57cec5SDimitry Andric   if (!Size) {
7120b57cec5SDimitry Andric     for (const auto &V : values())
71304eeddc0SDimitry Andric       Size += V.sizeOf(FormParams);
7140b57cec5SDimitry Andric   }
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   return Size;
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric /// EmitValue - Emit location data.
7200b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const7215ffd83dbSDimitry Andric void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7220b57cec5SDimitry Andric   switch (Form) {
7230b57cec5SDimitry Andric   default: llvm_unreachable("Improper form for block");
7240b57cec5SDimitry Andric   case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;
7250b57cec5SDimitry Andric   case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;
7260b57cec5SDimitry Andric   case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;
7270b57cec5SDimitry Andric   case dwarf::DW_FORM_block:
7280b57cec5SDimitry Andric   case dwarf::DW_FORM_exprloc:
7295ffd83dbSDimitry Andric     Asm->emitULEB128(Size);
7305ffd83dbSDimitry Andric     break;
7310b57cec5SDimitry Andric   }
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   for (const auto &V : values())
7345ffd83dbSDimitry Andric     V.emitValue(Asm);
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric 
73704eeddc0SDimitry Andric /// sizeOf - Determine size of location data in bytes.
7380b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams &,dwarf::Form Form) const73904eeddc0SDimitry Andric unsigned DIELoc::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {
7400b57cec5SDimitry Andric   switch (Form) {
7410b57cec5SDimitry Andric   case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
7420b57cec5SDimitry Andric   case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
7430b57cec5SDimitry Andric   case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
7440b57cec5SDimitry Andric   case dwarf::DW_FORM_block:
7450b57cec5SDimitry Andric   case dwarf::DW_FORM_exprloc:
7460b57cec5SDimitry Andric     return Size + getULEB128Size(Size);
7470b57cec5SDimitry Andric   default: llvm_unreachable("Improper form for block");
7480b57cec5SDimitry Andric   }
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const7520b57cec5SDimitry Andric void DIELoc::print(raw_ostream &O) const {
7530b57cec5SDimitry Andric   printValues(O, *this, "ExprLoc", Size, 5);
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7570b57cec5SDimitry Andric // DIEBlock Implementation
7580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7590b57cec5SDimitry Andric 
computeSize(const dwarf::FormParams & FormParams) const76004eeddc0SDimitry Andric unsigned DIEBlock::computeSize(const dwarf::FormParams &FormParams) const {
7610b57cec5SDimitry Andric   if (!Size) {
7620b57cec5SDimitry Andric     for (const auto &V : values())
76304eeddc0SDimitry Andric       Size += V.sizeOf(FormParams);
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   return Size;
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric /// EmitValue - Emit block data.
7700b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const7715ffd83dbSDimitry Andric void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7720b57cec5SDimitry Andric   switch (Form) {
7730b57cec5SDimitry Andric   default: llvm_unreachable("Improper form for block");
7740b57cec5SDimitry Andric   case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;
7750b57cec5SDimitry Andric   case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;
7760b57cec5SDimitry Andric   case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;
777fe6060f1SDimitry Andric   case dwarf::DW_FORM_exprloc:
7785ffd83dbSDimitry Andric   case dwarf::DW_FORM_block:
7795ffd83dbSDimitry Andric     Asm->emitULEB128(Size);
7805ffd83dbSDimitry Andric     break;
7810b57cec5SDimitry Andric   case dwarf::DW_FORM_string: break;
7820b57cec5SDimitry Andric   case dwarf::DW_FORM_data16: break;
7830b57cec5SDimitry Andric   }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   for (const auto &V : values())
7865ffd83dbSDimitry Andric     V.emitValue(Asm);
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric 
78904eeddc0SDimitry Andric /// sizeOf - Determine size of block data in bytes.
7900b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams &,dwarf::Form Form) const79104eeddc0SDimitry Andric unsigned DIEBlock::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {
7920b57cec5SDimitry Andric   switch (Form) {
7930b57cec5SDimitry Andric   case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
7940b57cec5SDimitry Andric   case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
7950b57cec5SDimitry Andric   case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
796fe6060f1SDimitry Andric   case dwarf::DW_FORM_exprloc:
7970b57cec5SDimitry Andric   case dwarf::DW_FORM_block:  return Size + getULEB128Size(Size);
7980b57cec5SDimitry Andric   case dwarf::DW_FORM_data16: return 16;
7990b57cec5SDimitry Andric   default: llvm_unreachable("Improper form for block");
8000b57cec5SDimitry Andric   }
8010b57cec5SDimitry Andric }
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const8040b57cec5SDimitry Andric void DIEBlock::print(raw_ostream &O) const {
8050b57cec5SDimitry Andric   printValues(O, *this, "Blk", Size, 5);
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8090b57cec5SDimitry Andric // DIELocList Implementation
8100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8110b57cec5SDimitry Andric 
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const81204eeddc0SDimitry Andric unsigned DIELocList::sizeOf(const dwarf::FormParams &FormParams,
81304eeddc0SDimitry Andric                             dwarf::Form Form) const {
814e8d8bef9SDimitry Andric   switch (Form) {
815e8d8bef9SDimitry Andric   case dwarf::DW_FORM_loclistx:
816480093f4SDimitry Andric     return getULEB128Size(Index);
817e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data4:
81804eeddc0SDimitry Andric     assert(FormParams.Format != dwarf::DWARF64 &&
819e8d8bef9SDimitry Andric            "DW_FORM_data4 is not suitable to emit a pointer to a location list "
820e8d8bef9SDimitry Andric            "in the 64-bit DWARF format");
8210b57cec5SDimitry Andric     return 4;
822e8d8bef9SDimitry Andric   case dwarf::DW_FORM_data8:
82304eeddc0SDimitry Andric     assert(FormParams.Format == dwarf::DWARF64 &&
824e8d8bef9SDimitry Andric            "DW_FORM_data8 is not suitable to emit a pointer to a location list "
825e8d8bef9SDimitry Andric            "in the 32-bit DWARF format");
826e8d8bef9SDimitry Andric     return 8;
827e8d8bef9SDimitry Andric   case dwarf::DW_FORM_sec_offset:
82804eeddc0SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
829e8d8bef9SDimitry Andric   default:
830e8d8bef9SDimitry Andric     llvm_unreachable("DIE Value form not supported yet");
831e8d8bef9SDimitry Andric   }
8320b57cec5SDimitry Andric }
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric /// EmitValue - Emit label value.
8350b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const8365ffd83dbSDimitry Andric void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
837480093f4SDimitry Andric   if (Form == dwarf::DW_FORM_loclistx) {
8385ffd83dbSDimitry Andric     AP->emitULEB128(Index);
839480093f4SDimitry Andric     return;
840480093f4SDimitry Andric   }
8410b57cec5SDimitry Andric   DwarfDebug *DD = AP->getDwarfDebug();
8420b57cec5SDimitry Andric   MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
8430b57cec5SDimitry Andric   AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const8470b57cec5SDimitry Andric void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }
848fe6060f1SDimitry Andric 
849fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
850fe6060f1SDimitry Andric // DIEAddrOffset Implementation
851fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
852fe6060f1SDimitry Andric 
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form) const85304eeddc0SDimitry Andric unsigned DIEAddrOffset::sizeOf(const dwarf::FormParams &FormParams,
85404eeddc0SDimitry Andric                                dwarf::Form) const {
85504eeddc0SDimitry Andric   return Addr.sizeOf(FormParams, dwarf::DW_FORM_addrx) +
85604eeddc0SDimitry Andric          Offset.sizeOf(FormParams, dwarf::DW_FORM_data4);
857fe6060f1SDimitry Andric }
858fe6060f1SDimitry Andric 
859fe6060f1SDimitry Andric /// EmitValue - Emit label value.
860fe6060f1SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const861fe6060f1SDimitry Andric void DIEAddrOffset::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
862fe6060f1SDimitry Andric   Addr.emitValue(AP, dwarf::DW_FORM_addrx);
863fe6060f1SDimitry Andric   Offset.emitValue(AP, dwarf::DW_FORM_data4);
864fe6060f1SDimitry Andric }
865fe6060f1SDimitry Andric 
866fe6060f1SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const867fe6060f1SDimitry Andric void DIEAddrOffset::print(raw_ostream &O) const {
868fe6060f1SDimitry Andric   O << "AddrOffset: ";
869fe6060f1SDimitry Andric   Addr.print(O);
870fe6060f1SDimitry Andric   O << " + ";
871fe6060f1SDimitry Andric   Offset.print(O);
872fe6060f1SDimitry Andric }
873