10b57cec5SDimitry Andric //===-- llvm/CodeGen/DwarfUnit.cpp - Dwarf Type and Compile Units ---------===// 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 // This file contains support for constructing a dwarf compile unit. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "DwarfUnit.h" 140b57cec5SDimitry Andric #include "AddressPool.h" 150b57cec5SDimitry Andric #include "DwarfCompileUnit.h" 160b57cec5SDimitry Andric #include "DwarfExpression.h" 170b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h" 180b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 200b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 210b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 220b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 230b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 290b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 300b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 310b57cec5SDimitry Andric #include <cassert> 320b57cec5SDimitry Andric #include <cstdint> 33*0fca6ea1SDimitry Andric #include <limits> 340b57cec5SDimitry Andric #include <string> 350b57cec5SDimitry Andric #include <utility> 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric using namespace llvm; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric #define DEBUG_TYPE "dwarfdebug" 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP, 428bcb0991SDimitry Andric DwarfCompileUnit &CU, DIELoc &DIE) 438bcb0991SDimitry Andric : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP), OutDIE(DIE) {} 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) { 468bcb0991SDimitry Andric CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric void DIEDwarfExpression::emitSigned(int64_t Value) { 508bcb0991SDimitry Andric CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value); 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric void DIEDwarfExpression::emitUnsigned(uint64_t Value) { 548bcb0991SDimitry Andric CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric void DIEDwarfExpression::emitData1(uint8_t Value) { 588bcb0991SDimitry Andric CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) { 628bcb0991SDimitry Andric CU.addBaseTypeRef(getActiveDIE(), Idx); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric 658bcb0991SDimitry Andric void DIEDwarfExpression::enableTemporaryBuffer() { 668bcb0991SDimitry Andric assert(!IsBuffering && "Already buffering?"); 678bcb0991SDimitry Andric IsBuffering = true; 688bcb0991SDimitry Andric } 698bcb0991SDimitry Andric 708bcb0991SDimitry Andric void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; } 718bcb0991SDimitry Andric 728bcb0991SDimitry Andric unsigned DIEDwarfExpression::getTemporaryBufferSize() { 7304eeddc0SDimitry Andric return TmpDIE.computeSize(AP.getDwarfFormParams()); 748bcb0991SDimitry Andric } 758bcb0991SDimitry Andric 768bcb0991SDimitry Andric void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); } 778bcb0991SDimitry Andric 780b57cec5SDimitry Andric bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, 79e8d8bef9SDimitry Andric llvm::Register MachineReg) { 800b57cec5SDimitry Andric return MachineReg == TRI.getFrameRegister(*AP.MF); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node, 845f757f3fSDimitry Andric AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, 855f757f3fSDimitry Andric unsigned UniqueID) 865f757f3fSDimitry Andric : DIEUnit(UnitTag), UniqueID(UniqueID), CUNode(Node), Asm(A), DD(DW), 875f757f3fSDimitry Andric DU(DWU) {} 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, 905f757f3fSDimitry Andric DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID, 910b57cec5SDimitry Andric MCDwarfDwoLineTable *SplitLineTable) 925f757f3fSDimitry Andric : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU, UniqueID), 935f757f3fSDimitry Andric CU(CU), SplitLineTable(SplitLineTable) {} 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric DwarfUnit::~DwarfUnit() { 96fe6060f1SDimitry Andric for (DIEBlock *B : DIEBlocks) 97fe6060f1SDimitry Andric B->~DIEBlock(); 98fe6060f1SDimitry Andric for (DIELoc *L : DIELocs) 99fe6060f1SDimitry Andric L->~DIELoc(); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric int64_t DwarfUnit::getDefaultLowerBound() const { 1030b57cec5SDimitry Andric switch (getLanguage()) { 1040b57cec5SDimitry Andric default: 1050b57cec5SDimitry Andric break; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // The languages below have valid values in all DWARF versions. 1080b57cec5SDimitry Andric case dwarf::DW_LANG_C: 1090b57cec5SDimitry Andric case dwarf::DW_LANG_C89: 1100b57cec5SDimitry Andric case dwarf::DW_LANG_C_plus_plus: 1110b57cec5SDimitry Andric return 0; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric case dwarf::DW_LANG_Fortran77: 1140b57cec5SDimitry Andric case dwarf::DW_LANG_Fortran90: 1150b57cec5SDimitry Andric return 1; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // The languages below have valid values only if the DWARF version >= 3. 1180b57cec5SDimitry Andric case dwarf::DW_LANG_C99: 1190b57cec5SDimitry Andric case dwarf::DW_LANG_ObjC: 1200b57cec5SDimitry Andric case dwarf::DW_LANG_ObjC_plus_plus: 1210b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 3) 1220b57cec5SDimitry Andric return 0; 1230b57cec5SDimitry Andric break; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric case dwarf::DW_LANG_Fortran95: 1260b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 3) 1270b57cec5SDimitry Andric return 1; 1280b57cec5SDimitry Andric break; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Starting with DWARF v4, all defined languages have valid values. 1310b57cec5SDimitry Andric case dwarf::DW_LANG_D: 1320b57cec5SDimitry Andric case dwarf::DW_LANG_Java: 1330b57cec5SDimitry Andric case dwarf::DW_LANG_Python: 1340b57cec5SDimitry Andric case dwarf::DW_LANG_UPC: 1350b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 4) 1360b57cec5SDimitry Andric return 0; 1370b57cec5SDimitry Andric break; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric case dwarf::DW_LANG_Ada83: 1400b57cec5SDimitry Andric case dwarf::DW_LANG_Ada95: 1410b57cec5SDimitry Andric case dwarf::DW_LANG_Cobol74: 1420b57cec5SDimitry Andric case dwarf::DW_LANG_Cobol85: 1430b57cec5SDimitry Andric case dwarf::DW_LANG_Modula2: 1440b57cec5SDimitry Andric case dwarf::DW_LANG_Pascal83: 1450b57cec5SDimitry Andric case dwarf::DW_LANG_PLI: 1460b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 4) 1470b57cec5SDimitry Andric return 1; 1480b57cec5SDimitry Andric break; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // The languages below are new in DWARF v5. 1510b57cec5SDimitry Andric case dwarf::DW_LANG_BLISS: 1520b57cec5SDimitry Andric case dwarf::DW_LANG_C11: 1530b57cec5SDimitry Andric case dwarf::DW_LANG_C_plus_plus_03: 1540b57cec5SDimitry Andric case dwarf::DW_LANG_C_plus_plus_11: 1550b57cec5SDimitry Andric case dwarf::DW_LANG_C_plus_plus_14: 1560b57cec5SDimitry Andric case dwarf::DW_LANG_Dylan: 1570b57cec5SDimitry Andric case dwarf::DW_LANG_Go: 1580b57cec5SDimitry Andric case dwarf::DW_LANG_Haskell: 1590b57cec5SDimitry Andric case dwarf::DW_LANG_OCaml: 1600b57cec5SDimitry Andric case dwarf::DW_LANG_OpenCL: 1610b57cec5SDimitry Andric case dwarf::DW_LANG_RenderScript: 1620b57cec5SDimitry Andric case dwarf::DW_LANG_Rust: 1630b57cec5SDimitry Andric case dwarf::DW_LANG_Swift: 1640b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) 1650b57cec5SDimitry Andric return 0; 1660b57cec5SDimitry Andric break; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric case dwarf::DW_LANG_Fortran03: 1690b57cec5SDimitry Andric case dwarf::DW_LANG_Fortran08: 1700b57cec5SDimitry Andric case dwarf::DW_LANG_Julia: 1710b57cec5SDimitry Andric case dwarf::DW_LANG_Modula3: 1720b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) 1730b57cec5SDimitry Andric return 1; 1740b57cec5SDimitry Andric break; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric return -1; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// Check whether the DIE for this MDNode can be shared across CUs. 1810b57cec5SDimitry Andric bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const { 18269ade1e0SDimitry Andric // When the MDNode can be part of the type system, the DIE can be shared 18369ade1e0SDimitry Andric // across CUs. 1840b57cec5SDimitry Andric // Combining type units and cross-CU DIE sharing is lower value (since 1850b57cec5SDimitry Andric // cross-CU DIE sharing is used in LTO and removes type redundancy at that 1860b57cec5SDimitry Andric // level already) but may be implementable for some value in projects 1870b57cec5SDimitry Andric // building multiple independent libraries with LTO and then linking those 1880b57cec5SDimitry Andric // together. 1890b57cec5SDimitry Andric if (isDwoUnit() && !DD->shareAcrossDWOCUs()) 1900b57cec5SDimitry Andric return false; 19169ade1e0SDimitry Andric return (isa<DIType>(D) || 19269ade1e0SDimitry Andric (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) && 19369ade1e0SDimitry Andric !DD->generateTypeUnits(); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric DIE *DwarfUnit::getDIE(const DINode *D) const { 1970b57cec5SDimitry Andric if (isShareableAcrossCUs(D)) 1980b57cec5SDimitry Andric return DU->getDIE(D); 1990b57cec5SDimitry Andric return MDNodeToDieMap.lookup(D); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) { 2030b57cec5SDimitry Andric if (isShareableAcrossCUs(Desc)) { 2040b57cec5SDimitry Andric DU->insertDIE(Desc, D); 2050b57cec5SDimitry Andric return; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric MDNodeToDieMap.insert(std::make_pair(Desc, D)); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2108bcb0991SDimitry Andric void DwarfUnit::insertDIE(DIE *D) { 2118bcb0991SDimitry Andric MDNodeToDieMap.insert(std::make_pair(nullptr, D)); 2128bcb0991SDimitry Andric } 2138bcb0991SDimitry Andric 2140b57cec5SDimitry Andric void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) { 2150b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 4) 216fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_flag_present, DIEInteger(1)); 2170b57cec5SDimitry Andric else 218fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_flag, DIEInteger(1)); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric void DwarfUnit::addUInt(DIEValueList &Die, dwarf::Attribute Attribute, 222bdd1243dSDimitry Andric std::optional<dwarf::Form> Form, uint64_t Integer) { 2230b57cec5SDimitry Andric if (!Form) 2240b57cec5SDimitry Andric Form = DIEInteger::BestForm(false, Integer); 2250b57cec5SDimitry Andric assert(Form != dwarf::DW_FORM_implicit_const && 2260b57cec5SDimitry Andric "DW_FORM_implicit_const is used only for signed integers"); 227fe6060f1SDimitry Andric addAttribute(Die, Attribute, *Form, DIEInteger(Integer)); 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form, 2310b57cec5SDimitry Andric uint64_t Integer) { 2320b57cec5SDimitry Andric addUInt(Block, (dwarf::Attribute)0, Form, Integer); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute, 236bdd1243dSDimitry Andric std::optional<dwarf::Form> Form, int64_t Integer) { 2370b57cec5SDimitry Andric if (!Form) 2380b57cec5SDimitry Andric Form = DIEInteger::BestForm(true, Integer); 239fe6060f1SDimitry Andric addAttribute(Die, Attribute, *Form, DIEInteger(Integer)); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 242bdd1243dSDimitry Andric void DwarfUnit::addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, 2430b57cec5SDimitry Andric int64_t Integer) { 2440b57cec5SDimitry Andric addSInt(Die, (dwarf::Attribute)0, Form, Integer); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, 2480b57cec5SDimitry Andric StringRef String) { 2490b57cec5SDimitry Andric if (CUNode->isDebugDirectivesOnly()) 2500b57cec5SDimitry Andric return; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric if (DD->useInlineStrings()) { 253fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_string, 2540b57cec5SDimitry Andric new (DIEValueAllocator) 2550b57cec5SDimitry Andric DIEInlineString(String, DIEValueAllocator)); 2560b57cec5SDimitry Andric return; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric dwarf::Form IxForm = 2590b57cec5SDimitry Andric isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric auto StringPoolEntry = 2620b57cec5SDimitry Andric useSegmentedStringOffsetsTable() || IxForm == dwarf::DW_FORM_GNU_str_index 2630b57cec5SDimitry Andric ? DU->getStringPool().getIndexedEntry(*Asm, String) 2640b57cec5SDimitry Andric : DU->getStringPool().getEntry(*Asm, String); 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric // For DWARF v5 and beyond, use the smallest strx? form possible. 2670b57cec5SDimitry Andric if (useSegmentedStringOffsetsTable()) { 2680b57cec5SDimitry Andric IxForm = dwarf::DW_FORM_strx1; 2690b57cec5SDimitry Andric unsigned Index = StringPoolEntry.getIndex(); 2700b57cec5SDimitry Andric if (Index > 0xffffff) 2710b57cec5SDimitry Andric IxForm = dwarf::DW_FORM_strx4; 2720b57cec5SDimitry Andric else if (Index > 0xffff) 2730b57cec5SDimitry Andric IxForm = dwarf::DW_FORM_strx3; 2740b57cec5SDimitry Andric else if (Index > 0xff) 2750b57cec5SDimitry Andric IxForm = dwarf::DW_FORM_strx2; 2760b57cec5SDimitry Andric } 277fe6060f1SDimitry Andric addAttribute(Die, Attribute, IxForm, DIEString(StringPoolEntry)); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 280fe6060f1SDimitry Andric void DwarfUnit::addLabel(DIEValueList &Die, dwarf::Attribute Attribute, 281fe6060f1SDimitry Andric dwarf::Form Form, const MCSymbol *Label) { 282fe6060f1SDimitry Andric addAttribute(Die, Attribute, Form, DIELabel(Label)); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) { 2860b57cec5SDimitry Andric addLabel(Die, (dwarf::Attribute)0, Form, Label); 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute, 2900b57cec5SDimitry Andric uint64_t Integer) { 291e8d8bef9SDimitry Andric addUInt(Die, Attribute, DD->getDwarfSectionOffsetForm(), Integer); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) { 2950b57cec5SDimitry Andric if (!SplitLineTable) 2960b57cec5SDimitry Andric return getCU().getOrCreateSourceID(File); 2970b57cec5SDimitry Andric if (!UsedLineTable) { 2980b57cec5SDimitry Andric UsedLineTable = true; 2990b57cec5SDimitry Andric // This is a split type unit that needs a line table. 3000b57cec5SDimitry Andric addSectionOffset(getUnitDie(), dwarf::DW_AT_stmt_list, 0); 3010b57cec5SDimitry Andric } 302e8d8bef9SDimitry Andric return SplitLineTable->getFile( 303e8d8bef9SDimitry Andric File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File), 304e8d8bef9SDimitry Andric Asm->OutContext.getDwarfVersion(), File->getSource()); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 307fe6060f1SDimitry Andric void DwarfUnit::addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label) { 308fe6060f1SDimitry Andric bool UseAddrOffsetFormOrExpressions = 309fe6060f1SDimitry Andric DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions(); 310fe6060f1SDimitry Andric 311fe6060f1SDimitry Andric const MCSymbol *Base = nullptr; 312fe6060f1SDimitry Andric if (Label->isInSection() && UseAddrOffsetFormOrExpressions) 313fe6060f1SDimitry Andric Base = DD->getSectionLabel(&Label->getSection()); 314fe6060f1SDimitry Andric 315fe6060f1SDimitry Andric uint32_t Index = DD->getAddressPool().getIndex(Base ? Base : Label); 316fe6060f1SDimitry Andric 3170b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) { 3180b57cec5SDimitry Andric addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx); 319fe6060f1SDimitry Andric addUInt(Die, dwarf::DW_FORM_addrx, Index); 320fe6060f1SDimitry Andric } else { 321fe6060f1SDimitry Andric addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); 322fe6060f1SDimitry Andric addUInt(Die, dwarf::DW_FORM_GNU_addr_index, Index); 323fe6060f1SDimitry Andric } 324fe6060f1SDimitry Andric 325fe6060f1SDimitry Andric if (Base && Base != Label) { 326fe6060f1SDimitry Andric addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_const4u); 327fe6060f1SDimitry Andric addLabelDelta(Die, (dwarf::Attribute)0, Label, Base); 328fe6060f1SDimitry Andric addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 329fe6060f1SDimitry Andric } 330fe6060f1SDimitry Andric } 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) { 333fe6060f1SDimitry Andric if (DD->getDwarfVersion() >= 5) { 334fe6060f1SDimitry Andric addPoolOpAddress(Die, Sym); 3350b57cec5SDimitry Andric return; 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric if (DD->useSplitDwarf()) { 339fe6060f1SDimitry Andric addPoolOpAddress(Die, Sym); 3400b57cec5SDimitry Andric return; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); 344e8d8bef9SDimitry Andric addLabel(Die, dwarf::DW_FORM_addr, Sym); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 347fe6060f1SDimitry Andric void DwarfUnit::addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute, 3480b57cec5SDimitry Andric const MCSymbol *Hi, const MCSymbol *Lo) { 349fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_data4, 3500b57cec5SDimitry Andric new (DIEValueAllocator) DIEDelta(Hi, Lo)); 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) { 3540b57cec5SDimitry Andric addDIEEntry(Die, Attribute, DIEEntry(Entry)); 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) { 3580b57cec5SDimitry Andric // Flag the type unit reference as a declaration so that if it contains 3590b57cec5SDimitry Andric // members (implicit special members, static data member definitions, member 3600b57cec5SDimitry Andric // declarations for definitions in this CU, etc) consumers don't get confused 3610b57cec5SDimitry Andric // and think this is a full definition. 3620b57cec5SDimitry Andric addFlag(Die, dwarf::DW_AT_declaration); 3630b57cec5SDimitry Andric 364fe6060f1SDimitry Andric addAttribute(Die, dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8, 365fe6060f1SDimitry Andric DIEInteger(Signature)); 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, 3690b57cec5SDimitry Andric DIEEntry Entry) { 3700b57cec5SDimitry Andric const DIEUnit *CU = Die.getUnit(); 3710b57cec5SDimitry Andric const DIEUnit *EntryCU = Entry.getEntry().getUnit(); 3720b57cec5SDimitry Andric if (!CU) 3730b57cec5SDimitry Andric // We assume that Die belongs to this CU, if it is not linked to any CU yet. 3740b57cec5SDimitry Andric CU = getUnitDie().getUnit(); 3750b57cec5SDimitry Andric if (!EntryCU) 3760b57cec5SDimitry Andric EntryCU = getUnitDie().getUnit(); 37781ad6265SDimitry Andric assert(EntryCU == CU || !DD->useSplitDwarf() || DD->shareAcrossDWOCUs() || 37881ad6265SDimitry Andric !static_cast<const DwarfUnit*>(CU)->isDwoUnit()); 379fe6060f1SDimitry Andric addAttribute(Die, Attribute, 3800b57cec5SDimitry Andric EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr, 3810b57cec5SDimitry Andric Entry); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 384fe6060f1SDimitry Andric DIE &DwarfUnit::createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N) { 385fe6060f1SDimitry Andric DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, Tag)); 3860b57cec5SDimitry Andric if (N) 3870b57cec5SDimitry Andric insertDIE(N, &Die); 3880b57cec5SDimitry Andric return Die; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) { 39204eeddc0SDimitry Andric Loc->computeSize(Asm->getDwarfFormParams()); 3930b57cec5SDimitry Andric DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. 394fe6060f1SDimitry Andric addAttribute(Die, Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc); 395fe6060f1SDimitry Andric } 396fe6060f1SDimitry Andric 397fe6060f1SDimitry Andric void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form, 398fe6060f1SDimitry Andric DIEBlock *Block) { 39904eeddc0SDimitry Andric Block->computeSize(Asm->getDwarfFormParams()); 400fe6060f1SDimitry Andric DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. 401fe6060f1SDimitry Andric addAttribute(Die, Attribute, Form, Block); 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, 4050b57cec5SDimitry Andric DIEBlock *Block) { 406fe6060f1SDimitry Andric addBlock(Die, Attribute, Block->BestForm(), Block); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, const DIFile *File) { 4100b57cec5SDimitry Andric if (Line == 0) 4110b57cec5SDimitry Andric return; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric unsigned FileID = getOrCreateSourceID(File); 414bdd1243dSDimitry Andric addUInt(Die, dwarf::DW_AT_decl_file, std::nullopt, FileID); 415bdd1243dSDimitry Andric addUInt(Die, dwarf::DW_AT_decl_line, std::nullopt, Line); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DILocalVariable *V) { 4190b57cec5SDimitry Andric assert(V); 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric addSourceLine(Die, V->getLine(), V->getFile()); 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DIGlobalVariable *G) { 4250b57cec5SDimitry Andric assert(G); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric addSourceLine(Die, G->getLine(), G->getFile()); 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) { 4310b57cec5SDimitry Andric assert(SP); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric addSourceLine(Die, SP->getLine(), SP->getFile()); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) { 4370b57cec5SDimitry Andric assert(L); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric addSourceLine(Die, L->getLine(), L->getFile()); 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) { 4430b57cec5SDimitry Andric assert(Ty); 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric addSourceLine(Die, Ty->getLine(), Ty->getFile()); 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) { 4490b57cec5SDimitry Andric assert(Ty); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric addSourceLine(Die, Ty->getLine(), Ty->getFile()); 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric void DwarfUnit::addConstantFPValue(DIE &Die, const ConstantFP *CFP) { 4550b57cec5SDimitry Andric // Pass this down to addConstantValue as an unsigned bag of bits. 4560b57cec5SDimitry Andric addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI, 4600b57cec5SDimitry Andric const DIType *Ty) { 4610b57cec5SDimitry Andric addConstantValue(Die, CI->getValue(), Ty); 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric void DwarfUnit::addConstantValue(DIE &Die, uint64_t Val, const DIType *Ty) { 465e8d8bef9SDimitry Andric addConstantValue(Die, DD->isUnsignedDIType(Ty), Val); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) { 4690b57cec5SDimitry Andric // FIXME: This is a bit conservative/simple - it emits negative values always 4700b57cec5SDimitry Andric // sign extended to 64 bits rather than minimizing the number of bytes. 4710b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_const_value, 4720b57cec5SDimitry Andric Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val); 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty) { 476e8d8bef9SDimitry Andric addConstantValue(Die, Val, DD->isUnsignedDIType(Ty)); 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) { 4800b57cec5SDimitry Andric unsigned CIBitWidth = Val.getBitWidth(); 4810b57cec5SDimitry Andric if (CIBitWidth <= 64) { 4820b57cec5SDimitry Andric addConstantValue(Die, Unsigned, 4830b57cec5SDimitry Andric Unsigned ? Val.getZExtValue() : Val.getSExtValue()); 4840b57cec5SDimitry Andric return; 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric DIEBlock *Block = new (DIEValueAllocator) DIEBlock; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric // Get the raw data form of the large APInt. 4900b57cec5SDimitry Andric const uint64_t *Ptr64 = Val.getRawData(); 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. 4930b57cec5SDimitry Andric bool LittleEndian = Asm->getDataLayout().isLittleEndian(); 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric // Output the constant to DWARF one byte at a time. 4960b57cec5SDimitry Andric for (int i = 0; i < NumBytes; i++) { 4970b57cec5SDimitry Andric uint8_t c; 4980b57cec5SDimitry Andric if (LittleEndian) 4990b57cec5SDimitry Andric c = Ptr64[i / 8] >> (8 * (i & 7)); 5000b57cec5SDimitry Andric else 5010b57cec5SDimitry Andric c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); 5020b57cec5SDimitry Andric addUInt(*Block, dwarf::DW_FORM_data1, c); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric addBlock(Die, dwarf::DW_AT_const_value, Block); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) { 5090b57cec5SDimitry Andric if (!LinkageName.empty()) 5100b57cec5SDimitry Andric addString(Die, 5110b57cec5SDimitry Andric DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name 5120b57cec5SDimitry Andric : dwarf::DW_AT_MIPS_linkage_name, 5130b57cec5SDimitry Andric GlobalValue::dropLLVMManglingEscape(LinkageName)); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) { 5170b57cec5SDimitry Andric // Add template parameters. 5180b57cec5SDimitry Andric for (const auto *Element : TParams) { 5190b57cec5SDimitry Andric if (auto *TTP = dyn_cast<DITemplateTypeParameter>(Element)) 5200b57cec5SDimitry Andric constructTemplateTypeParameterDIE(Buffer, TTP); 5210b57cec5SDimitry Andric else if (auto *TVP = dyn_cast<DITemplateValueParameter>(Element)) 5220b57cec5SDimitry Andric constructTemplateValueParameterDIE(Buffer, TVP); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric /// Add thrown types. 5270b57cec5SDimitry Andric void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) { 5280b57cec5SDimitry Andric for (const auto *Ty : ThrownTypes) { 5290b57cec5SDimitry Andric DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die); 5300b57cec5SDimitry Andric addType(TT, cast<DIType>(Ty)); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340eae32dcSDimitry Andric void DwarfUnit::addAccess(DIE &Die, DINode::DIFlags Flags) { 5350eae32dcSDimitry Andric if ((Flags & DINode::FlagAccessibility) == DINode::FlagProtected) 5360eae32dcSDimitry Andric addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, 5370eae32dcSDimitry Andric dwarf::DW_ACCESS_protected); 5380eae32dcSDimitry Andric else if ((Flags & DINode::FlagAccessibility) == DINode::FlagPrivate) 5390eae32dcSDimitry Andric addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, 5400eae32dcSDimitry Andric dwarf::DW_ACCESS_private); 5410eae32dcSDimitry Andric else if ((Flags & DINode::FlagAccessibility) == DINode::FlagPublic) 5420eae32dcSDimitry Andric addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, 5430eae32dcSDimitry Andric dwarf::DW_ACCESS_public); 5440eae32dcSDimitry Andric } 5450eae32dcSDimitry Andric 5460b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) { 54706c3fb27SDimitry Andric if (!Context || isa<DIFile>(Context) || isa<DICompileUnit>(Context)) 5480b57cec5SDimitry Andric return &getUnitDie(); 5490b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(Context)) 5500b57cec5SDimitry Andric return getOrCreateTypeDIE(T); 5510b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(Context)) 5520b57cec5SDimitry Andric return getOrCreateNameSpace(NS); 5530b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(Context)) 5540b57cec5SDimitry Andric return getOrCreateSubprogramDIE(SP); 5550b57cec5SDimitry Andric if (auto *M = dyn_cast<DIModule>(Context)) 5560b57cec5SDimitry Andric return getOrCreateModule(M); 5570b57cec5SDimitry Andric return getDIE(Context); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric DIE *DwarfUnit::createTypeDIE(const DICompositeType *Ty) { 5610b57cec5SDimitry Andric auto *Context = Ty->getScope(); 5620b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(Context); 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric if (DIE *TyDIE = getDIE(Ty)) 5650b57cec5SDimitry Andric return TyDIE; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric // Create new type. 5680b57cec5SDimitry Andric DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric constructTypeDIE(TyDIE, cast<DICompositeType>(Ty)); 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric updateAcceleratorTables(Context, Ty, TyDIE); 5730b57cec5SDimitry Andric return &TyDIE; 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE, 5770b57cec5SDimitry Andric const DIType *Ty) { 5780b57cec5SDimitry Andric // Create new type. 5790b57cec5SDimitry Andric DIE &TyDIE = createAndAddDIE(Ty->getTag(), ContextDIE, Ty); 5800b57cec5SDimitry Andric 581*0fca6ea1SDimitry Andric auto construct = [&](const auto *Ty) { 5820b57cec5SDimitry Andric updateAcceleratorTables(Context, Ty, TyDIE); 583*0fca6ea1SDimitry Andric constructTypeDIE(TyDIE, Ty); 584*0fca6ea1SDimitry Andric }; 5850b57cec5SDimitry Andric 586*0fca6ea1SDimitry Andric if (auto *CTy = dyn_cast<DICompositeType>(Ty)) { 5870b57cec5SDimitry Andric if (DD->generateTypeUnits() && !Ty->isForwardDecl() && 5880b57cec5SDimitry Andric (Ty->getRawName() || CTy->getRawIdentifier())) { 5890b57cec5SDimitry Andric // Skip updating the accelerator tables since this is not the full type. 590*0fca6ea1SDimitry Andric if (MDString *TypeId = CTy->getRawIdentifier()) { 591*0fca6ea1SDimitry Andric addGlobalType(Ty, TyDIE, Context); 5920b57cec5SDimitry Andric DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); 593*0fca6ea1SDimitry Andric } else { 594*0fca6ea1SDimitry Andric updateAcceleratorTables(Context, Ty, TyDIE); 5950b57cec5SDimitry Andric finishNonUnitTypeDIE(TyDIE, CTy); 596*0fca6ea1SDimitry Andric } 5970b57cec5SDimitry Andric return &TyDIE; 5980b57cec5SDimitry Andric } 599*0fca6ea1SDimitry Andric construct(CTy); 600*0fca6ea1SDimitry Andric } else if (auto *BT = dyn_cast<DIBasicType>(Ty)) 601*0fca6ea1SDimitry Andric construct(BT); 602*0fca6ea1SDimitry Andric else if (auto *ST = dyn_cast<DIStringType>(Ty)) 603*0fca6ea1SDimitry Andric construct(ST); 604*0fca6ea1SDimitry Andric else if (auto *STy = dyn_cast<DISubroutineType>(Ty)) 605*0fca6ea1SDimitry Andric construct(STy); 606*0fca6ea1SDimitry Andric else 607*0fca6ea1SDimitry Andric construct(cast<DIDerivedType>(Ty)); 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric return &TyDIE; 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) { 6130b57cec5SDimitry Andric if (!TyNode) 6140b57cec5SDimitry Andric return nullptr; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric auto *Ty = cast<DIType>(TyNode); 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric // DW_TAG_restrict_type is not supported in DWARF2 6190b57cec5SDimitry Andric if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2) 6200b57cec5SDimitry Andric return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType()); 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric // DW_TAG_atomic_type is not supported in DWARF < 5 6230b57cec5SDimitry Andric if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5) 6240b57cec5SDimitry Andric return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType()); 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 6270b57cec5SDimitry Andric // such construction creates the DIE. 6280b57cec5SDimitry Andric auto *Context = Ty->getScope(); 6290b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(Context); 6300b57cec5SDimitry Andric assert(ContextDIE); 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric if (DIE *TyDIE = getDIE(Ty)) 6330b57cec5SDimitry Andric return TyDIE; 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric return static_cast<DwarfUnit *>(ContextDIE->getUnit()) 6360b57cec5SDimitry Andric ->createTypeDIE(Context, *ContextDIE, Ty); 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric void DwarfUnit::updateAcceleratorTables(const DIScope *Context, 6400b57cec5SDimitry Andric const DIType *Ty, const DIE &TyDIE) { 641*0fca6ea1SDimitry Andric if (Ty->getName().empty()) 642*0fca6ea1SDimitry Andric return; 643*0fca6ea1SDimitry Andric if (Ty->isForwardDecl()) 644*0fca6ea1SDimitry Andric return; 645*0fca6ea1SDimitry Andric 646*0fca6ea1SDimitry Andric // add temporary record for this type to be added later 647*0fca6ea1SDimitry Andric 6480b57cec5SDimitry Andric bool IsImplementation = false; 6490b57cec5SDimitry Andric if (auto *CT = dyn_cast<DICompositeType>(Ty)) { 6500b57cec5SDimitry Andric // A runtime language of 0 actually means C/C++ and that any 6510b57cec5SDimitry Andric // non-negative value is some version of Objective-C/C++. 6520b57cec5SDimitry Andric IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete(); 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0; 6555f757f3fSDimitry Andric DD->addAccelType(*this, CUNode->getNameTableKind(), Ty->getName(), TyDIE, 6565f757f3fSDimitry Andric Flags); 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric addGlobalType(Ty, TyDIE, Context); 6590b57cec5SDimitry Andric } 660*0fca6ea1SDimitry Andric 661*0fca6ea1SDimitry Andric void DwarfUnit::addGlobalType(const DIType *Ty, const DIE &TyDIE, 662*0fca6ea1SDimitry Andric const DIScope *Context) { 663*0fca6ea1SDimitry Andric if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) || 664*0fca6ea1SDimitry Andric isa<DINamespace>(Context) || isa<DICommonBlock>(Context)) 665*0fca6ea1SDimitry Andric addGlobalTypeImpl(Ty, TyDIE, Context); 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric void DwarfUnit::addType(DIE &Entity, const DIType *Ty, 6690b57cec5SDimitry Andric dwarf::Attribute Attribute) { 6700b57cec5SDimitry Andric assert(Ty && "Trying to add a type that doesn't exist?"); 6710b57cec5SDimitry Andric addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty))); 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric std::string DwarfUnit::getParentContextString(const DIScope *Context) const { 6750b57cec5SDimitry Andric if (!Context) 6760b57cec5SDimitry Andric return ""; 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric // FIXME: Decide whether to implement this for non-C++ languages. 6798bcb0991SDimitry Andric if (!dwarf::isCPlusPlus((dwarf::SourceLanguage)getLanguage())) 6800b57cec5SDimitry Andric return ""; 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric std::string CS; 6830b57cec5SDimitry Andric SmallVector<const DIScope *, 1> Parents; 6840b57cec5SDimitry Andric while (!isa<DICompileUnit>(Context)) { 6850b57cec5SDimitry Andric Parents.push_back(Context); 6860b57cec5SDimitry Andric if (const DIScope *S = Context->getScope()) 6870b57cec5SDimitry Andric Context = S; 6880b57cec5SDimitry Andric else 6890b57cec5SDimitry Andric // Structure, etc types will have a NULL context if they're at the top 6900b57cec5SDimitry Andric // level. 6910b57cec5SDimitry Andric break; 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric // Reverse iterate over our list to go from the outermost construct to the 6950b57cec5SDimitry Andric // innermost. 696349cc55cSDimitry Andric for (const DIScope *Ctx : llvm::reverse(Parents)) { 6970b57cec5SDimitry Andric StringRef Name = Ctx->getName(); 6980b57cec5SDimitry Andric if (Name.empty() && isa<DINamespace>(Ctx)) 6990b57cec5SDimitry Andric Name = "(anonymous namespace)"; 7000b57cec5SDimitry Andric if (!Name.empty()) { 7010b57cec5SDimitry Andric CS += Name; 7020b57cec5SDimitry Andric CS += "::"; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric return CS; 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) { 7090b57cec5SDimitry Andric // Get core information. 7100b57cec5SDimitry Andric StringRef Name = BTy->getName(); 7110b57cec5SDimitry Andric // Add name if not anonymous or intermediate type. 7120b57cec5SDimitry Andric if (!Name.empty()) 7130b57cec5SDimitry Andric addString(Buffer, dwarf::DW_AT_name, Name); 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric // An unspecified type only has a name attribute. 7160b57cec5SDimitry Andric if (BTy->getTag() == dwarf::DW_TAG_unspecified_type) 7170b57cec5SDimitry Andric return; 7180b57cec5SDimitry Andric 719e8d8bef9SDimitry Andric if (BTy->getTag() != dwarf::DW_TAG_string_type) 7200b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, 7210b57cec5SDimitry Andric BTy->getEncoding()); 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric uint64_t Size = BTy->getSizeInBits() >> 3; 724bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric if (BTy->isBigEndian()) 727bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big); 7280b57cec5SDimitry Andric else if (BTy->isLittleEndian()) 729bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little); 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 732e8d8bef9SDimitry Andric void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) { 733e8d8bef9SDimitry Andric // Get core information. 734e8d8bef9SDimitry Andric StringRef Name = STy->getName(); 735e8d8bef9SDimitry Andric // Add name if not anonymous or intermediate type. 736e8d8bef9SDimitry Andric if (!Name.empty()) 737e8d8bef9SDimitry Andric addString(Buffer, dwarf::DW_AT_name, Name); 738e8d8bef9SDimitry Andric 739e8d8bef9SDimitry Andric if (DIVariable *Var = STy->getStringLength()) { 740e8d8bef9SDimitry Andric if (auto *VarDIE = getDIE(Var)) 741e8d8bef9SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE); 742e8d8bef9SDimitry Andric } else if (DIExpression *Expr = STy->getStringLengthExp()) { 743e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 744e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 745e8d8bef9SDimitry Andric // This is to describe the memory location of the 746e8d8bef9SDimitry Andric // length of a Fortran deferred length string, so 747e8d8bef9SDimitry Andric // lock it down as such. 748e8d8bef9SDimitry Andric DwarfExpr.setMemoryLocationKind(); 749e8d8bef9SDimitry Andric DwarfExpr.addExpression(Expr); 750e8d8bef9SDimitry Andric addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize()); 751e8d8bef9SDimitry Andric } else { 752e8d8bef9SDimitry Andric uint64_t Size = STy->getSizeInBits() >> 3; 753bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); 754e8d8bef9SDimitry Andric } 755e8d8bef9SDimitry Andric 75604eeddc0SDimitry Andric if (DIExpression *Expr = STy->getStringLocationExp()) { 75704eeddc0SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 75804eeddc0SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 75904eeddc0SDimitry Andric // This is to describe the memory location of the 76004eeddc0SDimitry Andric // string, so lock it down as such. 76104eeddc0SDimitry Andric DwarfExpr.setMemoryLocationKind(); 76204eeddc0SDimitry Andric DwarfExpr.addExpression(Expr); 76304eeddc0SDimitry Andric addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize()); 76404eeddc0SDimitry Andric } 76504eeddc0SDimitry Andric 766e8d8bef9SDimitry Andric if (STy->getEncoding()) { 767e8d8bef9SDimitry Andric // For eventual Unicode support. 768e8d8bef9SDimitry Andric addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, 769e8d8bef9SDimitry Andric STy->getEncoding()); 770e8d8bef9SDimitry Andric } 771e8d8bef9SDimitry Andric } 772e8d8bef9SDimitry Andric 7730b57cec5SDimitry Andric void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { 7740b57cec5SDimitry Andric // Get core information. 7750b57cec5SDimitry Andric StringRef Name = DTy->getName(); 7760b57cec5SDimitry Andric uint64_t Size = DTy->getSizeInBits() >> 3; 7770b57cec5SDimitry Andric uint16_t Tag = Buffer.getTag(); 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric // Map to main type, void will not have a type. 7800b57cec5SDimitry Andric const DIType *FromTy = DTy->getBaseType(); 7810b57cec5SDimitry Andric if (FromTy) 7820b57cec5SDimitry Andric addType(Buffer, FromTy); 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric // Add name if not anonymous or intermediate type. 7850b57cec5SDimitry Andric if (!Name.empty()) 7860b57cec5SDimitry Andric addString(Buffer, dwarf::DW_AT_name, Name); 7870b57cec5SDimitry Andric 788349cc55cSDimitry Andric addAnnotation(Buffer, DTy->getAnnotations()); 789349cc55cSDimitry Andric 790480093f4SDimitry Andric // If alignment is specified for a typedef , create and insert DW_AT_alignment 791480093f4SDimitry Andric // attribute in DW_TAG_typedef DIE. 792480093f4SDimitry Andric if (Tag == dwarf::DW_TAG_typedef && DD->getDwarfVersion() >= 5) { 793480093f4SDimitry Andric uint32_t AlignInBytes = DTy->getAlignInBytes(); 794480093f4SDimitry Andric if (AlignInBytes > 0) 795480093f4SDimitry Andric addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 796480093f4SDimitry Andric AlignInBytes); 797480093f4SDimitry Andric } 798480093f4SDimitry Andric 7990b57cec5SDimitry Andric // Add size if non-zero (derived types might be zero-sized.) 8000b57cec5SDimitry Andric if (Size && Tag != dwarf::DW_TAG_pointer_type 8010b57cec5SDimitry Andric && Tag != dwarf::DW_TAG_ptr_to_member_type 8020b57cec5SDimitry Andric && Tag != dwarf::DW_TAG_reference_type 8030b57cec5SDimitry Andric && Tag != dwarf::DW_TAG_rvalue_reference_type) 804bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric if (Tag == dwarf::DW_TAG_ptr_to_member_type) 8070b57cec5SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_containing_type, 8080b57cec5SDimitry Andric *getOrCreateTypeDIE(cast<DIDerivedType>(DTy)->getClassType())); 809bdd1243dSDimitry Andric 810bdd1243dSDimitry Andric addAccess(Buffer, DTy->getFlags()); 811bdd1243dSDimitry Andric 8120b57cec5SDimitry Andric // Add source line info if available and TyDesc is not a forward declaration. 8130b57cec5SDimitry Andric if (!DTy->isForwardDecl()) 8140b57cec5SDimitry Andric addSourceLine(Buffer, DTy); 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric // If DWARF address space value is other than None, add it. The IR 8170b57cec5SDimitry Andric // verifier checks that DWARF address space only exists for pointer 8180b57cec5SDimitry Andric // or reference types. 8190b57cec5SDimitry Andric if (DTy->getDWARFAddressSpace()) 8200b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, 82181ad6265SDimitry Andric *DTy->getDWARFAddressSpace()); 822*0fca6ea1SDimitry Andric 823*0fca6ea1SDimitry Andric // Add template alias template parameters. 824*0fca6ea1SDimitry Andric if (Tag == dwarf::DW_TAG_template_alias) 825*0fca6ea1SDimitry Andric addTemplateParams(Buffer, DTy->getTemplateParams()); 826*0fca6ea1SDimitry Andric 827*0fca6ea1SDimitry Andric if (auto PtrAuthData = DTy->getPtrAuthData()) { 828*0fca6ea1SDimitry Andric addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1, 829*0fca6ea1SDimitry Andric PtrAuthData->key()); 830*0fca6ea1SDimitry Andric if (PtrAuthData->isAddressDiscriminated()) 831*0fca6ea1SDimitry Andric addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated); 832*0fca6ea1SDimitry Andric addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator, 833*0fca6ea1SDimitry Andric dwarf::DW_FORM_data2, PtrAuthData->extraDiscriminator()); 834*0fca6ea1SDimitry Andric if (PtrAuthData->isaPointer()) 835*0fca6ea1SDimitry Andric addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer); 836*0fca6ea1SDimitry Andric if (PtrAuthData->authenticatesNullValues()) 837*0fca6ea1SDimitry Andric addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values); 838*0fca6ea1SDimitry Andric } 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { 8420b57cec5SDimitry Andric for (unsigned i = 1, N = Args.size(); i < N; ++i) { 8430b57cec5SDimitry Andric const DIType *Ty = Args[i]; 8440b57cec5SDimitry Andric if (!Ty) { 8450b57cec5SDimitry Andric assert(i == N-1 && "Unspecified parameter must be the last argument"); 8460b57cec5SDimitry Andric createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer); 8470b57cec5SDimitry Andric } else { 8480b57cec5SDimitry Andric DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer); 8490b57cec5SDimitry Andric addType(Arg, Ty); 8500b57cec5SDimitry Andric if (Ty->isArtificial()) 8510b57cec5SDimitry Andric addFlag(Arg, dwarf::DW_AT_artificial); 8520b57cec5SDimitry Andric } 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric } 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) { 8570b57cec5SDimitry Andric // Add return type. A void return won't have a type. 8580b57cec5SDimitry Andric auto Elements = cast<DISubroutineType>(CTy)->getTypeArray(); 8590b57cec5SDimitry Andric if (Elements.size()) 8600b57cec5SDimitry Andric if (auto RTy = Elements[0]) 8610b57cec5SDimitry Andric addType(Buffer, RTy); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric bool isPrototyped = true; 8640b57cec5SDimitry Andric if (Elements.size() == 2 && !Elements[1]) 8650b57cec5SDimitry Andric isPrototyped = false; 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric constructSubprogramArguments(Buffer, Elements); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // Add prototype flag if we're dealing with a C language and the function has 8700b57cec5SDimitry Andric // been prototyped. 871bdd1243dSDimitry Andric if (isPrototyped && dwarf::isC((dwarf::SourceLanguage)getLanguage())) 8720b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_prototyped); 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric // Add a DW_AT_calling_convention if this has an explicit convention. 8750b57cec5SDimitry Andric if (CTy->getCC() && CTy->getCC() != dwarf::DW_CC_normal) 8760b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, 8770b57cec5SDimitry Andric CTy->getCC()); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric if (CTy->isLValueReference()) 8800b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_reference); 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric if (CTy->isRValueReference()) 8830b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_rvalue_reference); 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric 886349cc55cSDimitry Andric void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) { 887349cc55cSDimitry Andric if (!Annotations) 888349cc55cSDimitry Andric return; 889349cc55cSDimitry Andric 890349cc55cSDimitry Andric for (const Metadata *Annotation : Annotations->operands()) { 891349cc55cSDimitry Andric const MDNode *MD = cast<MDNode>(Annotation); 892349cc55cSDimitry Andric const MDString *Name = cast<MDString>(MD->getOperand(0)); 8930eae32dcSDimitry Andric const auto &Value = MD->getOperand(1); 894349cc55cSDimitry Andric 895349cc55cSDimitry Andric DIE &AnnotationDie = createAndAddDIE(dwarf::DW_TAG_LLVM_annotation, Buffer); 896349cc55cSDimitry Andric addString(AnnotationDie, dwarf::DW_AT_name, Name->getString()); 8970eae32dcSDimitry Andric if (const auto *Data = dyn_cast<MDString>(Value)) 8980eae32dcSDimitry Andric addString(AnnotationDie, dwarf::DW_AT_const_value, Data->getString()); 8990eae32dcSDimitry Andric else if (const auto *Data = dyn_cast<ConstantAsMetadata>(Value)) 9000eae32dcSDimitry Andric addConstantValue(AnnotationDie, Data->getValue()->getUniqueInteger(), 9010eae32dcSDimitry Andric /*Unsigned=*/true); 9020eae32dcSDimitry Andric else 9030eae32dcSDimitry Andric assert(false && "Unsupported annotation value type"); 904349cc55cSDimitry Andric } 905349cc55cSDimitry Andric } 906349cc55cSDimitry Andric 9070b57cec5SDimitry Andric void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { 9080b57cec5SDimitry Andric // Add name if not anonymous or intermediate type. 9090b57cec5SDimitry Andric StringRef Name = CTy->getName(); 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric uint64_t Size = CTy->getSizeInBits() >> 3; 9120b57cec5SDimitry Andric uint16_t Tag = Buffer.getTag(); 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric switch (Tag) { 9150b57cec5SDimitry Andric case dwarf::DW_TAG_array_type: 9160b57cec5SDimitry Andric constructArrayTypeDIE(Buffer, CTy); 9170b57cec5SDimitry Andric break; 9180b57cec5SDimitry Andric case dwarf::DW_TAG_enumeration_type: 9190b57cec5SDimitry Andric constructEnumTypeDIE(Buffer, CTy); 9200b57cec5SDimitry Andric break; 9210b57cec5SDimitry Andric case dwarf::DW_TAG_variant_part: 9220b57cec5SDimitry Andric case dwarf::DW_TAG_structure_type: 9230b57cec5SDimitry Andric case dwarf::DW_TAG_union_type: 924349cc55cSDimitry Andric case dwarf::DW_TAG_class_type: 925349cc55cSDimitry Andric case dwarf::DW_TAG_namelist: { 9260b57cec5SDimitry Andric // Emit the discriminator for a variant part. 9270b57cec5SDimitry Andric DIDerivedType *Discriminator = nullptr; 9280b57cec5SDimitry Andric if (Tag == dwarf::DW_TAG_variant_part) { 9290b57cec5SDimitry Andric Discriminator = CTy->getDiscriminator(); 9300b57cec5SDimitry Andric if (Discriminator) { 9310b57cec5SDimitry Andric // DWARF says: 9320b57cec5SDimitry Andric // If the variant part has a discriminant, the discriminant is 9330b57cec5SDimitry Andric // represented by a separate debugging information entry which is 9340b57cec5SDimitry Andric // a child of the variant part entry. 9350b57cec5SDimitry Andric DIE &DiscMember = constructMemberDIE(Buffer, Discriminator); 9360b57cec5SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember); 9370b57cec5SDimitry Andric } 9380b57cec5SDimitry Andric } 9390b57cec5SDimitry Andric 940e8d8bef9SDimitry Andric // Add template parameters to a class, structure or union types. 941e8d8bef9SDimitry Andric if (Tag == dwarf::DW_TAG_class_type || 942e8d8bef9SDimitry Andric Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) 943e8d8bef9SDimitry Andric addTemplateParams(Buffer, CTy->getTemplateParams()); 944e8d8bef9SDimitry Andric 9450b57cec5SDimitry Andric // Add elements to structure type. 9460b57cec5SDimitry Andric DINodeArray Elements = CTy->getElements(); 9470b57cec5SDimitry Andric for (const auto *Element : Elements) { 9480b57cec5SDimitry Andric if (!Element) 9490b57cec5SDimitry Andric continue; 9500b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(Element)) 9510b57cec5SDimitry Andric getOrCreateSubprogramDIE(SP); 9520b57cec5SDimitry Andric else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) { 9530b57cec5SDimitry Andric if (DDTy->getTag() == dwarf::DW_TAG_friend) { 9540b57cec5SDimitry Andric DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer); 9550b57cec5SDimitry Andric addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend); 9560b57cec5SDimitry Andric } else if (DDTy->isStaticMember()) { 9570b57cec5SDimitry Andric getOrCreateStaticMemberDIE(DDTy); 9580b57cec5SDimitry Andric } else if (Tag == dwarf::DW_TAG_variant_part) { 9590b57cec5SDimitry Andric // When emitting a variant part, wrap each member in 9600b57cec5SDimitry Andric // DW_TAG_variant. 9610b57cec5SDimitry Andric DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer); 9620b57cec5SDimitry Andric if (const ConstantInt *CI = 9630b57cec5SDimitry Andric dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) { 964e8d8bef9SDimitry Andric if (DD->isUnsignedDIType(Discriminator->getBaseType())) 965bdd1243dSDimitry Andric addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt, 966bdd1243dSDimitry Andric CI->getZExtValue()); 9670b57cec5SDimitry Andric else 968bdd1243dSDimitry Andric addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt, 969bdd1243dSDimitry Andric CI->getSExtValue()); 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric constructMemberDIE(Variant, DDTy); 9720b57cec5SDimitry Andric } else { 9730b57cec5SDimitry Andric constructMemberDIE(Buffer, DDTy); 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric } else if (auto *Property = dyn_cast<DIObjCProperty>(Element)) { 9760b57cec5SDimitry Andric DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer); 9770b57cec5SDimitry Andric StringRef PropertyName = Property->getName(); 9780b57cec5SDimitry Andric addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); 9790b57cec5SDimitry Andric if (Property->getType()) 9800b57cec5SDimitry Andric addType(ElemDie, Property->getType()); 9810b57cec5SDimitry Andric addSourceLine(ElemDie, Property); 9820b57cec5SDimitry Andric StringRef GetterName = Property->getGetterName(); 9830b57cec5SDimitry Andric if (!GetterName.empty()) 9840b57cec5SDimitry Andric addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName); 9850b57cec5SDimitry Andric StringRef SetterName = Property->getSetterName(); 9860b57cec5SDimitry Andric if (!SetterName.empty()) 9870b57cec5SDimitry Andric addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName); 9880b57cec5SDimitry Andric if (unsigned PropertyAttributes = Property->getAttributes()) 989bdd1243dSDimitry Andric addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, std::nullopt, 9900b57cec5SDimitry Andric PropertyAttributes); 9910b57cec5SDimitry Andric } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) { 9920b57cec5SDimitry Andric if (Composite->getTag() == dwarf::DW_TAG_variant_part) { 9930b57cec5SDimitry Andric DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer); 9940b57cec5SDimitry Andric constructTypeDIE(VariantPart, Composite); 9950b57cec5SDimitry Andric } 996349cc55cSDimitry Andric } else if (Tag == dwarf::DW_TAG_namelist) { 997349cc55cSDimitry Andric auto *Var = dyn_cast<DINode>(Element); 998349cc55cSDimitry Andric auto *VarDIE = getDIE(Var); 999349cc55cSDimitry Andric if (VarDIE) { 1000349cc55cSDimitry Andric DIE &ItemDie = createAndAddDIE(dwarf::DW_TAG_namelist_item, Buffer); 1001349cc55cSDimitry Andric addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE); 1002349cc55cSDimitry Andric } 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric if (CTy->isAppleBlockExtension()) 10070b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_APPLE_block); 10080b57cec5SDimitry Andric 10098bcb0991SDimitry Andric if (CTy->getExportSymbols()) 10108bcb0991SDimitry Andric addFlag(Buffer, dwarf::DW_AT_export_symbols); 10118bcb0991SDimitry Andric 10120b57cec5SDimitry Andric // This is outside the DWARF spec, but GDB expects a DW_AT_containing_type 10130b57cec5SDimitry Andric // inside C++ composite types to point to the base class with the vtable. 10140b57cec5SDimitry Andric // Rust uses DW_AT_containing_type to link a vtable to the type 10150b57cec5SDimitry Andric // for which it was created. 10160b57cec5SDimitry Andric if (auto *ContainingType = CTy->getVTableHolder()) 10170b57cec5SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_containing_type, 10180b57cec5SDimitry Andric *getOrCreateTypeDIE(ContainingType)); 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric if (CTy->isObjcClassComplete()) 10210b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type); 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric // Add the type's non-standard calling convention. 1024fe6060f1SDimitry Andric // DW_CC_pass_by_value/DW_CC_pass_by_reference are introduced in DWARF 5. 1025fe6060f1SDimitry Andric if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 5) { 10260b57cec5SDimitry Andric uint8_t CC = 0; 10270b57cec5SDimitry Andric if (CTy->isTypePassByValue()) 10280b57cec5SDimitry Andric CC = dwarf::DW_CC_pass_by_value; 10290b57cec5SDimitry Andric else if (CTy->isTypePassByReference()) 10300b57cec5SDimitry Andric CC = dwarf::DW_CC_pass_by_reference; 10310b57cec5SDimitry Andric if (CC) 10320b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, 10330b57cec5SDimitry Andric CC); 1034fe6060f1SDimitry Andric } 10350b57cec5SDimitry Andric break; 10360b57cec5SDimitry Andric } 10370b57cec5SDimitry Andric default: 10380b57cec5SDimitry Andric break; 10390b57cec5SDimitry Andric } 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric // Add name if not anonymous or intermediate type. 10420b57cec5SDimitry Andric if (!Name.empty()) 10430b57cec5SDimitry Andric addString(Buffer, dwarf::DW_AT_name, Name); 10440b57cec5SDimitry Andric 1045349cc55cSDimitry Andric addAnnotation(Buffer, CTy->getAnnotations()); 1046349cc55cSDimitry Andric 10470b57cec5SDimitry Andric if (Tag == dwarf::DW_TAG_enumeration_type || 10480b57cec5SDimitry Andric Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || 10490b57cec5SDimitry Andric Tag == dwarf::DW_TAG_union_type) { 10500b57cec5SDimitry Andric // Add size if non-zero (derived types might be zero-sized.) 1051e8d8bef9SDimitry Andric // Ignore the size if it's a non-enum forward decl. 10520b57cec5SDimitry Andric // TODO: Do we care about size for enum forward declarations? 1053e8d8bef9SDimitry Andric if (Size && 1054e8d8bef9SDimitry Andric (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type)) 1055bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); 10560b57cec5SDimitry Andric else if (!CTy->isForwardDecl()) 10570b57cec5SDimitry Andric // Add zero size if it is not a forward declaration. 1058bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0); 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // If we're a forward decl, say so. 10610b57cec5SDimitry Andric if (CTy->isForwardDecl()) 10620b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_declaration); 10630b57cec5SDimitry Andric 10640eae32dcSDimitry Andric // Add accessibility info if available. 10650eae32dcSDimitry Andric addAccess(Buffer, CTy->getFlags()); 10660eae32dcSDimitry Andric 10670b57cec5SDimitry Andric // Add source line info if available. 10680b57cec5SDimitry Andric if (!CTy->isForwardDecl()) 10690b57cec5SDimitry Andric addSourceLine(Buffer, CTy); 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric // No harm in adding the runtime language to the declaration. 10720b57cec5SDimitry Andric unsigned RLang = CTy->getRuntimeLang(); 10730b57cec5SDimitry Andric if (RLang) 10740b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1, 10750b57cec5SDimitry Andric RLang); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric // Add align info if available. 10780b57cec5SDimitry Andric if (uint32_t AlignInBytes = CTy->getAlignInBytes()) 10790b57cec5SDimitry Andric addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 10800b57cec5SDimitry Andric AlignInBytes); 10810b57cec5SDimitry Andric } 10820b57cec5SDimitry Andric } 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric void DwarfUnit::constructTemplateTypeParameterDIE( 10850b57cec5SDimitry Andric DIE &Buffer, const DITemplateTypeParameter *TP) { 10860b57cec5SDimitry Andric DIE &ParamDIE = 10870b57cec5SDimitry Andric createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer); 10880b57cec5SDimitry Andric // Add the type if it exists, it could be void and therefore no type. 10890b57cec5SDimitry Andric if (TP->getType()) 10900b57cec5SDimitry Andric addType(ParamDIE, TP->getType()); 10910b57cec5SDimitry Andric if (!TP->getName().empty()) 10920b57cec5SDimitry Andric addString(ParamDIE, dwarf::DW_AT_name, TP->getName()); 1093bdd1243dSDimitry Andric if (TP->isDefault() && isCompatibleWithVersion(5)) 10945ffd83dbSDimitry Andric addFlag(ParamDIE, dwarf::DW_AT_default_value); 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric void DwarfUnit::constructTemplateValueParameterDIE( 10980b57cec5SDimitry Andric DIE &Buffer, const DITemplateValueParameter *VP) { 10990b57cec5SDimitry Andric DIE &ParamDIE = createAndAddDIE(VP->getTag(), Buffer); 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric // Add the type if there is one, template template and template parameter 11020b57cec5SDimitry Andric // packs will not have a type. 11030b57cec5SDimitry Andric if (VP->getTag() == dwarf::DW_TAG_template_value_parameter) 11040b57cec5SDimitry Andric addType(ParamDIE, VP->getType()); 11050b57cec5SDimitry Andric if (!VP->getName().empty()) 11060b57cec5SDimitry Andric addString(ParamDIE, dwarf::DW_AT_name, VP->getName()); 1107bdd1243dSDimitry Andric if (VP->isDefault() && isCompatibleWithVersion(5)) 11085ffd83dbSDimitry Andric addFlag(ParamDIE, dwarf::DW_AT_default_value); 11090b57cec5SDimitry Andric if (Metadata *Val = VP->getValue()) { 11100b57cec5SDimitry Andric if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val)) 11110b57cec5SDimitry Andric addConstantValue(ParamDIE, CI, VP->getType()); 11120b57cec5SDimitry Andric else if (GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) { 11130b57cec5SDimitry Andric // We cannot describe the location of dllimport'd entities: the 11140b57cec5SDimitry Andric // computation of their address requires loads from the IAT. 11150b57cec5SDimitry Andric if (!GV->hasDLLImportStorageClass()) { 11160b57cec5SDimitry Andric // For declaration non-type template parameters (such as global values 11170b57cec5SDimitry Andric // and functions) 11180b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 11190b57cec5SDimitry Andric addOpAddress(*Loc, Asm->getSymbol(GV)); 11200b57cec5SDimitry Andric // Emit DW_OP_stack_value to use the address as the immediate value of 11210b57cec5SDimitry Andric // the parameter, rather than a pointer to it. 11220b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); 11230b57cec5SDimitry Andric addBlock(ParamDIE, dwarf::DW_AT_location, Loc); 11240b57cec5SDimitry Andric } 11250b57cec5SDimitry Andric } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) { 11260b57cec5SDimitry Andric assert(isa<MDString>(Val)); 11270b57cec5SDimitry Andric addString(ParamDIE, dwarf::DW_AT_GNU_template_name, 11280b57cec5SDimitry Andric cast<MDString>(Val)->getString()); 11290b57cec5SDimitry Andric } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) { 11300b57cec5SDimitry Andric addTemplateParams(ParamDIE, cast<MDTuple>(Val)); 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric } 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) { 11360b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 11370b57cec5SDimitry Andric // such construction creates the DIE. 11380b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(NS->getScope()); 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric if (DIE *NDie = getDIE(NS)) 11410b57cec5SDimitry Andric return NDie; 11420b57cec5SDimitry Andric DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS); 11430b57cec5SDimitry Andric 11440b57cec5SDimitry Andric StringRef Name = NS->getName(); 11450b57cec5SDimitry Andric if (!Name.empty()) 11460b57cec5SDimitry Andric addString(NDie, dwarf::DW_AT_name, NS->getName()); 11470b57cec5SDimitry Andric else 11480b57cec5SDimitry Andric Name = "(anonymous namespace)"; 11495f757f3fSDimitry Andric DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, NDie); 11500b57cec5SDimitry Andric addGlobalName(Name, NDie, NS->getScope()); 11510b57cec5SDimitry Andric if (NS->getExportSymbols()) 11520b57cec5SDimitry Andric addFlag(NDie, dwarf::DW_AT_export_symbols); 11530b57cec5SDimitry Andric return &NDie; 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateModule(const DIModule *M) { 11570b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 11580b57cec5SDimitry Andric // such construction creates the DIE. 11590b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(M->getScope()); 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andric if (DIE *MDie = getDIE(M)) 11620b57cec5SDimitry Andric return MDie; 11630b57cec5SDimitry Andric DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M); 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric if (!M->getName().empty()) { 11660b57cec5SDimitry Andric addString(MDie, dwarf::DW_AT_name, M->getName()); 11670b57cec5SDimitry Andric addGlobalName(M->getName(), MDie, M->getScope()); 11680b57cec5SDimitry Andric } 11690b57cec5SDimitry Andric if (!M->getConfigurationMacros().empty()) 11700b57cec5SDimitry Andric addString(MDie, dwarf::DW_AT_LLVM_config_macros, 11710b57cec5SDimitry Andric M->getConfigurationMacros()); 11720b57cec5SDimitry Andric if (!M->getIncludePath().empty()) 11730b57cec5SDimitry Andric addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath()); 11745ffd83dbSDimitry Andric if (!M->getAPINotesFile().empty()) 11755ffd83dbSDimitry Andric addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile()); 11765ffd83dbSDimitry Andric if (M->getFile()) 1177bdd1243dSDimitry Andric addUInt(MDie, dwarf::DW_AT_decl_file, std::nullopt, 11785ffd83dbSDimitry Andric getOrCreateSourceID(M->getFile())); 11795ffd83dbSDimitry Andric if (M->getLineNo()) 1180bdd1243dSDimitry Andric addUInt(MDie, dwarf::DW_AT_decl_line, std::nullopt, M->getLineNo()); 1181e8d8bef9SDimitry Andric if (M->getIsDecl()) 1182e8d8bef9SDimitry Andric addFlag(MDie, dwarf::DW_AT_declaration); 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric return &MDie; 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { 11880b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 11890b57cec5SDimitry Andric // such construction creates the DIE (as is the case for member function 11900b57cec5SDimitry Andric // declarations). 11910b57cec5SDimitry Andric DIE *ContextDIE = 11920b57cec5SDimitry Andric Minimal ? &getUnitDie() : getOrCreateContextDIE(SP->getScope()); 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric if (DIE *SPDie = getDIE(SP)) 11950b57cec5SDimitry Andric return SPDie; 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric if (auto *SPDecl = SP->getDeclaration()) { 11980b57cec5SDimitry Andric if (!Minimal) { 11990b57cec5SDimitry Andric // Add subprogram definitions to the CU die directly. 12000b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 12010b57cec5SDimitry Andric // Build the decl now to ensure it precedes the definition. 12020b57cec5SDimitry Andric getOrCreateSubprogramDIE(SPDecl); 12030b57cec5SDimitry Andric } 12040b57cec5SDimitry Andric } 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric // DW_TAG_inlined_subroutine may refer to this DIE. 12070b57cec5SDimitry Andric DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP); 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric // Stop here and fill this in later, depending on whether or not this 12100b57cec5SDimitry Andric // subprogram turns out to have inlined instances or not. 12110b57cec5SDimitry Andric if (SP->isDefinition()) 12120b57cec5SDimitry Andric return &SPDie; 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric static_cast<DwarfUnit *>(SPDie.getUnit()) 12150b57cec5SDimitry Andric ->applySubprogramAttributes(SP, SPDie); 12160b57cec5SDimitry Andric return &SPDie; 12170b57cec5SDimitry Andric } 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, 1220fe6060f1SDimitry Andric DIE &SPDie, bool Minimal) { 12210b57cec5SDimitry Andric DIE *DeclDie = nullptr; 12220b57cec5SDimitry Andric StringRef DeclLinkageName; 12230b57cec5SDimitry Andric if (auto *SPDecl = SP->getDeclaration()) { 1224fe6060f1SDimitry Andric if (!Minimal) { 12255ffd83dbSDimitry Andric DITypeRefArray DeclArgs, DefinitionArgs; 12265ffd83dbSDimitry Andric DeclArgs = SPDecl->getType()->getTypeArray(); 12275ffd83dbSDimitry Andric DefinitionArgs = SP->getType()->getTypeArray(); 12285ffd83dbSDimitry Andric 12295ffd83dbSDimitry Andric if (DeclArgs.size() && DefinitionArgs.size()) 123004eeddc0SDimitry Andric if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0]) 12315ffd83dbSDimitry Andric addType(SPDie, DefinitionArgs[0]); 12325ffd83dbSDimitry Andric 12330b57cec5SDimitry Andric DeclDie = getDIE(SPDecl); 12340b57cec5SDimitry Andric assert(DeclDie && "This DIE should've already been constructed when the " 12350b57cec5SDimitry Andric "definition DIE was created in " 12360b57cec5SDimitry Andric "getOrCreateSubprogramDIE"); 12370b57cec5SDimitry Andric // Look at the Decl's linkage name only if we emitted it. 12380b57cec5SDimitry Andric if (DD->useAllLinkageNames()) 12390b57cec5SDimitry Andric DeclLinkageName = SPDecl->getLinkageName(); 12400b57cec5SDimitry Andric unsigned DeclID = getOrCreateSourceID(SPDecl->getFile()); 12410b57cec5SDimitry Andric unsigned DefID = getOrCreateSourceID(SP->getFile()); 12420b57cec5SDimitry Andric if (DeclID != DefID) 1243bdd1243dSDimitry Andric addUInt(SPDie, dwarf::DW_AT_decl_file, std::nullopt, DefID); 12440b57cec5SDimitry Andric 12450b57cec5SDimitry Andric if (SP->getLine() != SPDecl->getLine()) 1246bdd1243dSDimitry Andric addUInt(SPDie, dwarf::DW_AT_decl_line, std::nullopt, SP->getLine()); 12470b57cec5SDimitry Andric } 1248fe6060f1SDimitry Andric } 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // Add function template parameters. 12510b57cec5SDimitry Andric addTemplateParams(SPDie, SP->getTemplateParams()); 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric // Add the linkage name if we have one and it isn't in the Decl. 12540b57cec5SDimitry Andric StringRef LinkageName = SP->getLinkageName(); 12550b57cec5SDimitry Andric assert(((LinkageName.empty() || DeclLinkageName.empty()) || 12560b57cec5SDimitry Andric LinkageName == DeclLinkageName) && 12570b57cec5SDimitry Andric "decl has a linkage name and it is different"); 12580b57cec5SDimitry Andric if (DeclLinkageName.empty() && 12590b57cec5SDimitry Andric // Always emit it for abstract subprograms. 126006c3fb27SDimitry Andric (DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP))) 12610b57cec5SDimitry Andric addLinkageName(SPDie, LinkageName); 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric if (!DeclDie) 12640b57cec5SDimitry Andric return false; 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric // Refer to the function declaration where all the other attributes will be 12670b57cec5SDimitry Andric // found. 12680b57cec5SDimitry Andric addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie); 12690b57cec5SDimitry Andric return true; 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, 12730b57cec5SDimitry Andric bool SkipSPAttributes) { 12740b57cec5SDimitry Andric // If -fdebug-info-for-profiling is enabled, need to emit the subprogram 12750b57cec5SDimitry Andric // and its source location. 12760b57cec5SDimitry Andric bool SkipSPSourceLocation = SkipSPAttributes && 12770b57cec5SDimitry Andric !CUNode->getDebugInfoForProfiling(); 12780b57cec5SDimitry Andric if (!SkipSPSourceLocation) 1279fe6060f1SDimitry Andric if (applySubprogramDefinitionAttributes(SP, SPDie, SkipSPAttributes)) 12800b57cec5SDimitry Andric return; 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric // Constructors and operators for anonymous aggregates do not have names. 12830b57cec5SDimitry Andric if (!SP->getName().empty()) 12840b57cec5SDimitry Andric addString(SPDie, dwarf::DW_AT_name, SP->getName()); 12850b57cec5SDimitry Andric 1286349cc55cSDimitry Andric addAnnotation(SPDie, SP->getAnnotations()); 1287349cc55cSDimitry Andric 12880b57cec5SDimitry Andric if (!SkipSPSourceLocation) 12890b57cec5SDimitry Andric addSourceLine(SPDie, SP); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric // Skip the rest of the attributes under -gmlt to save space. 12920b57cec5SDimitry Andric if (SkipSPAttributes) 12930b57cec5SDimitry Andric return; 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric // Add the prototype if we have a prototype and we have a C like 12960b57cec5SDimitry Andric // language. 1297bdd1243dSDimitry Andric if (SP->isPrototyped() && dwarf::isC((dwarf::SourceLanguage)getLanguage())) 12980b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_prototyped); 12990b57cec5SDimitry Andric 1300480093f4SDimitry Andric if (SP->isObjCDirect()) 1301480093f4SDimitry Andric addFlag(SPDie, dwarf::DW_AT_APPLE_objc_direct); 1302480093f4SDimitry Andric 13030b57cec5SDimitry Andric unsigned CC = 0; 13040b57cec5SDimitry Andric DITypeRefArray Args; 13050b57cec5SDimitry Andric if (const DISubroutineType *SPTy = SP->getType()) { 13060b57cec5SDimitry Andric Args = SPTy->getTypeArray(); 13070b57cec5SDimitry Andric CC = SPTy->getCC(); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric // Add a DW_AT_calling_convention if this has an explicit convention. 13110b57cec5SDimitry Andric if (CC && CC != dwarf::DW_CC_normal) 13120b57cec5SDimitry Andric addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC); 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric // Add a return type. If this is a type like a C/C++ void type we don't add a 13150b57cec5SDimitry Andric // return type. 13160b57cec5SDimitry Andric if (Args.size()) 13170b57cec5SDimitry Andric if (auto Ty = Args[0]) 13180b57cec5SDimitry Andric addType(SPDie, Ty); 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric unsigned VK = SP->getVirtuality(); 13210b57cec5SDimitry Andric if (VK) { 13220b57cec5SDimitry Andric addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK); 13230b57cec5SDimitry Andric if (SP->getVirtualIndex() != -1u) { 13240b57cec5SDimitry Andric DIELoc *Block = getDIELoc(); 13250b57cec5SDimitry Andric addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); 13260b57cec5SDimitry Andric addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex()); 13270b57cec5SDimitry Andric addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block); 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric ContainingTypeMap.insert(std::make_pair(&SPDie, SP->getContainingType())); 13300b57cec5SDimitry Andric } 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric if (!SP->isDefinition()) { 13330b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_declaration); 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric // Add arguments. Do not add arguments for subprogram definition. They will 13360b57cec5SDimitry Andric // be handled while processing variables. 13370b57cec5SDimitry Andric constructSubprogramArguments(SPDie, Args); 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric addThrownTypes(SPDie, SP->getThrownTypes()); 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric if (SP->isArtificial()) 13430b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_artificial); 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric if (!SP->isLocalToUnit()) 13460b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_external); 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric if (DD->useAppleExtensionAttributes()) { 13490b57cec5SDimitry Andric if (SP->isOptimized()) 13500b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_APPLE_optimized); 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric if (unsigned isa = Asm->getISAEncoding()) 13530b57cec5SDimitry Andric addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); 13540b57cec5SDimitry Andric } 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric if (SP->isLValueReference()) 13570b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_reference); 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric if (SP->isRValueReference()) 13600b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_rvalue_reference); 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric if (SP->isNoReturn()) 13630b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_noreturn); 13640b57cec5SDimitry Andric 13650eae32dcSDimitry Andric addAccess(SPDie, SP->getFlags()); 13660b57cec5SDimitry Andric 13670b57cec5SDimitry Andric if (SP->isExplicit()) 13680b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_explicit); 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric if (SP->isMainSubprogram()) 13710b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_main_subprogram); 13720b57cec5SDimitry Andric if (SP->isPure()) 13730b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_pure); 13740b57cec5SDimitry Andric if (SP->isElemental()) 13750b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_elemental); 13760b57cec5SDimitry Andric if (SP->isRecursive()) 13770b57cec5SDimitry Andric addFlag(SPDie, dwarf::DW_AT_recursive); 1378480093f4SDimitry Andric 137981ad6265SDimitry Andric if (!SP->getTargetFuncName().empty()) 138081ad6265SDimitry Andric addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName()); 138181ad6265SDimitry Andric 1382480093f4SDimitry Andric if (DD->getDwarfVersion() >= 5 && SP->isDeleted()) 1383480093f4SDimitry Andric addFlag(SPDie, dwarf::DW_AT_deleted); 13840b57cec5SDimitry Andric } 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andric void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, 13870b57cec5SDimitry Andric DIE *IndexTy) { 13880b57cec5SDimitry Andric DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer); 13890b57cec5SDimitry Andric addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy); 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric // The LowerBound value defines the lower bounds which is typically zero for 13920b57cec5SDimitry Andric // C/C++. The Count value is the number of elements. Values are 64 bit. If 13930b57cec5SDimitry Andric // Count == -1 then the array is unbounded and we do not emit 13940b57cec5SDimitry Andric // DW_AT_lower_bound and DW_AT_count attributes. 13950b57cec5SDimitry Andric int64_t DefaultLowerBound = getDefaultLowerBound(); 13960b57cec5SDimitry Andric 1397e8d8bef9SDimitry Andric auto AddBoundTypeEntry = [&](dwarf::Attribute Attr, 13985ffd83dbSDimitry Andric DISubrange::BoundType Bound) -> void { 139906c3fb27SDimitry Andric if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) { 14005ffd83dbSDimitry Andric if (auto *VarDIE = getDIE(BV)) 14015ffd83dbSDimitry Andric addDIEEntry(DW_Subrange, Attr, *VarDIE); 140206c3fb27SDimitry Andric } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) { 14035ffd83dbSDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 14045ffd83dbSDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 14055ffd83dbSDimitry Andric DwarfExpr.setMemoryLocationKind(); 14065ffd83dbSDimitry Andric DwarfExpr.addExpression(BE); 14075ffd83dbSDimitry Andric addBlock(DW_Subrange, Attr, DwarfExpr.finalize()); 140806c3fb27SDimitry Andric } else if (auto *BI = dyn_cast_if_present<ConstantInt *>(Bound)) { 1409fe6060f1SDimitry Andric if (Attr == dwarf::DW_AT_count) { 1410fe6060f1SDimitry Andric if (BI->getSExtValue() != -1) 1411bdd1243dSDimitry Andric addUInt(DW_Subrange, Attr, std::nullopt, BI->getSExtValue()); 1412fe6060f1SDimitry Andric } else if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 || 14135ffd83dbSDimitry Andric BI->getSExtValue() != DefaultLowerBound) 14145ffd83dbSDimitry Andric addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue()); 14155ffd83dbSDimitry Andric } 14165ffd83dbSDimitry Andric }; 14175ffd83dbSDimitry Andric 1418e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound()); 14190b57cec5SDimitry Andric 1420fe6060f1SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_count, SR->getCount()); 14215ffd83dbSDimitry Andric 1422e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound()); 14235ffd83dbSDimitry Andric 1424e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride()); 1425e8d8bef9SDimitry Andric } 1426e8d8bef9SDimitry Andric 1427e8d8bef9SDimitry Andric void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer, 1428e8d8bef9SDimitry Andric const DIGenericSubrange *GSR, 1429e8d8bef9SDimitry Andric DIE *IndexTy) { 1430e8d8bef9SDimitry Andric DIE &DwGenericSubrange = 1431e8d8bef9SDimitry Andric createAndAddDIE(dwarf::DW_TAG_generic_subrange, Buffer); 1432e8d8bef9SDimitry Andric addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy); 1433e8d8bef9SDimitry Andric 1434e8d8bef9SDimitry Andric int64_t DefaultLowerBound = getDefaultLowerBound(); 1435e8d8bef9SDimitry Andric 1436e8d8bef9SDimitry Andric auto AddBoundTypeEntry = [&](dwarf::Attribute Attr, 1437e8d8bef9SDimitry Andric DIGenericSubrange::BoundType Bound) -> void { 143806c3fb27SDimitry Andric if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) { 1439e8d8bef9SDimitry Andric if (auto *VarDIE = getDIE(BV)) 1440e8d8bef9SDimitry Andric addDIEEntry(DwGenericSubrange, Attr, *VarDIE); 144106c3fb27SDimitry Andric } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) { 1442fe6060f1SDimitry Andric if (BE->isConstant() && 1443fe6060f1SDimitry Andric DIExpression::SignedOrUnsignedConstant::SignedConstant == 1444fe6060f1SDimitry Andric *BE->isConstant()) { 1445e8d8bef9SDimitry Andric if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 || 1446e8d8bef9SDimitry Andric static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound) 1447e8d8bef9SDimitry Andric addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata, 1448e8d8bef9SDimitry Andric BE->getElement(1)); 1449e8d8bef9SDimitry Andric } else { 1450e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1451e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 1452e8d8bef9SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1453e8d8bef9SDimitry Andric DwarfExpr.addExpression(BE); 1454e8d8bef9SDimitry Andric addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize()); 1455e8d8bef9SDimitry Andric } 1456e8d8bef9SDimitry Andric } 1457e8d8bef9SDimitry Andric }; 1458e8d8bef9SDimitry Andric 1459e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->getLowerBound()); 1460e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_count, GSR->getCount()); 1461e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->getUpperBound()); 1462e8d8bef9SDimitry Andric AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->getStride()); 14630b57cec5SDimitry Andric } 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric DIE *DwarfUnit::getIndexTyDie() { 14660b57cec5SDimitry Andric if (IndexTyDie) 14670b57cec5SDimitry Andric return IndexTyDie; 14680b57cec5SDimitry Andric // Construct an integer type to use for indexes. 14690b57cec5SDimitry Andric IndexTyDie = &createAndAddDIE(dwarf::DW_TAG_base_type, getUnitDie()); 14700b57cec5SDimitry Andric StringRef Name = "__ARRAY_SIZE_TYPE__"; 14710b57cec5SDimitry Andric addString(*IndexTyDie, dwarf::DW_AT_name, Name); 1472bdd1243dSDimitry Andric addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, std::nullopt, sizeof(int64_t)); 14730b57cec5SDimitry Andric addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, 147481ad6265SDimitry Andric dwarf::getArrayIndexTypeEncoding( 147581ad6265SDimitry Andric (dwarf::SourceLanguage)getLanguage())); 14765f757f3fSDimitry Andric DD->addAccelType(*this, CUNode->getNameTableKind(), Name, *IndexTyDie, 14775f757f3fSDimitry Andric /*Flags*/ 0); 14780b57cec5SDimitry Andric return IndexTyDie; 14790b57cec5SDimitry Andric } 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric /// Returns true if the vector's size differs from the sum of sizes of elements 14820b57cec5SDimitry Andric /// the user specified. This can occur if the vector has been rounded up to 14830b57cec5SDimitry Andric /// fit memory alignment constraints. 14840b57cec5SDimitry Andric static bool hasVectorBeenPadded(const DICompositeType *CTy) { 14850b57cec5SDimitry Andric assert(CTy && CTy->isVector() && "Composite type is not a vector"); 14860b57cec5SDimitry Andric const uint64_t ActualSize = CTy->getSizeInBits(); 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric // Obtain the size of each element in the vector. 14890b57cec5SDimitry Andric DIType *BaseTy = CTy->getBaseType(); 14900b57cec5SDimitry Andric assert(BaseTy && "Unknown vector element type."); 14910b57cec5SDimitry Andric const uint64_t ElementSize = BaseTy->getSizeInBits(); 14920b57cec5SDimitry Andric 14930b57cec5SDimitry Andric // Locate the number of elements in the vector. 14940b57cec5SDimitry Andric const DINodeArray Elements = CTy->getElements(); 14950b57cec5SDimitry Andric assert(Elements.size() == 1 && 14960b57cec5SDimitry Andric Elements[0]->getTag() == dwarf::DW_TAG_subrange_type && 14970b57cec5SDimitry Andric "Invalid vector element array, expected one element of type subrange"); 14980b57cec5SDimitry Andric const auto Subrange = cast<DISubrange>(Elements[0]); 149916d6b3b3SDimitry Andric const auto NumVecElements = 150016d6b3b3SDimitry Andric Subrange->getCount() 150106c3fb27SDimitry Andric ? cast<ConstantInt *>(Subrange->getCount())->getSExtValue() 150216d6b3b3SDimitry Andric : 0; 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric // Ensure we found the element count and that the actual size is wide 15050b57cec5SDimitry Andric // enough to contain the requested size. 15060b57cec5SDimitry Andric assert(ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size"); 15070b57cec5SDimitry Andric return ActualSize != (NumVecElements * ElementSize); 15080b57cec5SDimitry Andric } 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) { 15110b57cec5SDimitry Andric if (CTy->isVector()) { 15120b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_GNU_vector); 15130b57cec5SDimitry Andric if (hasVectorBeenPadded(CTy)) 1514bdd1243dSDimitry Andric addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 15150b57cec5SDimitry Andric CTy->getSizeInBits() / CHAR_BIT); 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric 15185ffd83dbSDimitry Andric if (DIVariable *Var = CTy->getDataLocation()) { 15195ffd83dbSDimitry Andric if (auto *VarDIE = getDIE(Var)) 15205ffd83dbSDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE); 15215ffd83dbSDimitry Andric } else if (DIExpression *Expr = CTy->getDataLocationExp()) { 15225ffd83dbSDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 15235ffd83dbSDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 15245ffd83dbSDimitry Andric DwarfExpr.setMemoryLocationKind(); 15255ffd83dbSDimitry Andric DwarfExpr.addExpression(Expr); 15265ffd83dbSDimitry Andric addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize()); 15275ffd83dbSDimitry Andric } 15285ffd83dbSDimitry Andric 1529e8d8bef9SDimitry Andric if (DIVariable *Var = CTy->getAssociated()) { 1530e8d8bef9SDimitry Andric if (auto *VarDIE = getDIE(Var)) 1531e8d8bef9SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE); 1532e8d8bef9SDimitry Andric } else if (DIExpression *Expr = CTy->getAssociatedExp()) { 1533e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1534e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 1535e8d8bef9SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1536e8d8bef9SDimitry Andric DwarfExpr.addExpression(Expr); 1537e8d8bef9SDimitry Andric addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize()); 1538e8d8bef9SDimitry Andric } 1539e8d8bef9SDimitry Andric 1540e8d8bef9SDimitry Andric if (DIVariable *Var = CTy->getAllocated()) { 1541e8d8bef9SDimitry Andric if (auto *VarDIE = getDIE(Var)) 1542e8d8bef9SDimitry Andric addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE); 1543e8d8bef9SDimitry Andric } else if (DIExpression *Expr = CTy->getAllocatedExp()) { 1544e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1545e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 1546e8d8bef9SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1547e8d8bef9SDimitry Andric DwarfExpr.addExpression(Expr); 1548e8d8bef9SDimitry Andric addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize()); 1549e8d8bef9SDimitry Andric } 1550e8d8bef9SDimitry Andric 1551e8d8bef9SDimitry Andric if (auto *RankConst = CTy->getRankConst()) { 1552e8d8bef9SDimitry Andric addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata, 1553e8d8bef9SDimitry Andric RankConst->getSExtValue()); 1554e8d8bef9SDimitry Andric } else if (auto *RankExpr = CTy->getRankExp()) { 1555e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1556e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); 1557e8d8bef9SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1558e8d8bef9SDimitry Andric DwarfExpr.addExpression(RankExpr); 1559e8d8bef9SDimitry Andric addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize()); 1560e8d8bef9SDimitry Andric } 1561e8d8bef9SDimitry Andric 15620b57cec5SDimitry Andric // Emit the element type. 15630b57cec5SDimitry Andric addType(Buffer, CTy->getBaseType()); 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric // Get an anonymous type for index type. 15660b57cec5SDimitry Andric // FIXME: This type should be passed down from the front end 15670b57cec5SDimitry Andric // as different languages may have different sizes for indexes. 15680b57cec5SDimitry Andric DIE *IdxTy = getIndexTyDie(); 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric // Add subranges to array type. 15710b57cec5SDimitry Andric DINodeArray Elements = CTy->getElements(); 1572fe6060f1SDimitry Andric for (DINode *E : Elements) { 15730b57cec5SDimitry Andric // FIXME: Should this really be such a loose cast? 1574fe6060f1SDimitry Andric if (auto *Element = dyn_cast_or_null<DINode>(E)) { 15750b57cec5SDimitry Andric if (Element->getTag() == dwarf::DW_TAG_subrange_type) 15760b57cec5SDimitry Andric constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy); 1577e8d8bef9SDimitry Andric else if (Element->getTag() == dwarf::DW_TAG_generic_subrange) 1578e8d8bef9SDimitry Andric constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element), 1579e8d8bef9SDimitry Andric IdxTy); 1580e8d8bef9SDimitry Andric } 15810b57cec5SDimitry Andric } 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) { 15850b57cec5SDimitry Andric const DIType *DTy = CTy->getBaseType(); 1586e8d8bef9SDimitry Andric bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy); 15870b57cec5SDimitry Andric if (DTy) { 1588*0fca6ea1SDimitry Andric if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 3) 15890b57cec5SDimitry Andric addType(Buffer, DTy); 15900b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass)) 15910b57cec5SDimitry Andric addFlag(Buffer, dwarf::DW_AT_enum_class); 15920b57cec5SDimitry Andric } 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andric auto *Context = CTy->getScope(); 15950b57cec5SDimitry Andric bool IndexEnumerators = !Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) || 15960b57cec5SDimitry Andric isa<DINamespace>(Context) || isa<DICommonBlock>(Context); 15970b57cec5SDimitry Andric DINodeArray Elements = CTy->getElements(); 15980b57cec5SDimitry Andric 15990b57cec5SDimitry Andric // Add enumerators to enumeration type. 1600fe6060f1SDimitry Andric for (const DINode *E : Elements) { 1601fe6060f1SDimitry Andric auto *Enum = dyn_cast_or_null<DIEnumerator>(E); 16020b57cec5SDimitry Andric if (Enum) { 16030b57cec5SDimitry Andric DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer); 16040b57cec5SDimitry Andric StringRef Name = Enum->getName(); 16050b57cec5SDimitry Andric addString(Enumerator, dwarf::DW_AT_name, Name); 16065ffd83dbSDimitry Andric addConstantValue(Enumerator, Enum->getValue(), IsUnsigned); 16070b57cec5SDimitry Andric if (IndexEnumerators) 16080b57cec5SDimitry Andric addGlobalName(Name, Enumerator, Context); 16090b57cec5SDimitry Andric } 16100b57cec5SDimitry Andric } 16110b57cec5SDimitry Andric } 16120b57cec5SDimitry Andric 16130b57cec5SDimitry Andric void DwarfUnit::constructContainingTypeDIEs() { 1614fe6060f1SDimitry Andric for (auto &P : ContainingTypeMap) { 1615fe6060f1SDimitry Andric DIE &SPDie = *P.first; 1616fe6060f1SDimitry Andric const DINode *D = P.second; 16170b57cec5SDimitry Andric if (!D) 16180b57cec5SDimitry Andric continue; 16190b57cec5SDimitry Andric DIE *NDie = getDIE(D); 16200b57cec5SDimitry Andric if (!NDie) 16210b57cec5SDimitry Andric continue; 16220b57cec5SDimitry Andric addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie); 16230b57cec5SDimitry Andric } 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { 16270b57cec5SDimitry Andric DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer); 16280b57cec5SDimitry Andric StringRef Name = DT->getName(); 16290b57cec5SDimitry Andric if (!Name.empty()) 16300b57cec5SDimitry Andric addString(MemberDie, dwarf::DW_AT_name, Name); 16310b57cec5SDimitry Andric 1632349cc55cSDimitry Andric addAnnotation(MemberDie, DT->getAnnotations()); 1633349cc55cSDimitry Andric 16340b57cec5SDimitry Andric if (DIType *Resolved = DT->getBaseType()) 16350b57cec5SDimitry Andric addType(MemberDie, Resolved); 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andric addSourceLine(MemberDie, DT); 16380b57cec5SDimitry Andric 16390b57cec5SDimitry Andric if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) { 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andric // For C++, virtual base classes are not at fixed offset. Use following 16420b57cec5SDimitry Andric // expression to extract appropriate offset from vtable. 16430b57cec5SDimitry Andric // BaseAddr = ObAddr + *((*ObAddr) - Offset) 16440b57cec5SDimitry Andric 16450b57cec5SDimitry Andric DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc; 16460b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); 16470b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 16480b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); 16490b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits()); 16500b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus); 16510b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 16520b57cec5SDimitry Andric addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie); 16550b57cec5SDimitry Andric } else { 16560b57cec5SDimitry Andric uint64_t Size = DT->getSizeInBits(); 16570b57cec5SDimitry Andric uint64_t FieldSize = DD->getBaseTypeSize(DT); 16580b57cec5SDimitry Andric uint32_t AlignInBytes = DT->getAlignInBytes(); 16590b57cec5SDimitry Andric uint64_t OffsetInBytes; 16600b57cec5SDimitry Andric 1661bdd1243dSDimitry Andric bool IsBitfield = DT->isBitField(); 16620b57cec5SDimitry Andric if (IsBitfield) { 16630b57cec5SDimitry Andric // Handle bitfield, assume bytes are 8 bits. 16640b57cec5SDimitry Andric if (DD->useDWARF2Bitfields()) 1665bdd1243dSDimitry Andric addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8); 1666bdd1243dSDimitry Andric addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size); 16670b57cec5SDimitry Andric 1668*0fca6ea1SDimitry Andric assert(DT->getOffsetInBits() <= 1669*0fca6ea1SDimitry Andric (uint64_t)std::numeric_limits<int64_t>::max()); 1670*0fca6ea1SDimitry Andric int64_t Offset = DT->getOffsetInBits(); 16710b57cec5SDimitry Andric // We can't use DT->getAlignInBits() here: AlignInBits for member type 16720b57cec5SDimitry Andric // is non-zero if and only if alignment was forced (e.g. _Alignas()), 16730b57cec5SDimitry Andric // which can't be done with bitfields. Thus we use FieldSize here. 16740b57cec5SDimitry Andric uint32_t AlignInBits = FieldSize; 16750b57cec5SDimitry Andric uint32_t AlignMask = ~(AlignInBits - 1); 16760b57cec5SDimitry Andric // The bits from the start of the storage unit to the start of the field. 16770b57cec5SDimitry Andric uint64_t StartBitOffset = Offset - (Offset & AlignMask); 16780b57cec5SDimitry Andric // The byte offset of the field's aligned storage unit inside the struct. 16790b57cec5SDimitry Andric OffsetInBytes = (Offset - StartBitOffset) / 8; 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andric if (DD->useDWARF2Bitfields()) { 16820b57cec5SDimitry Andric uint64_t HiMark = (Offset + FieldSize) & AlignMask; 16830b57cec5SDimitry Andric uint64_t FieldOffset = (HiMark - FieldSize); 16840b57cec5SDimitry Andric Offset -= FieldOffset; 16850b57cec5SDimitry Andric 16860b57cec5SDimitry Andric // Maybe we need to work from the other end. 16870b57cec5SDimitry Andric if (Asm->getDataLayout().isLittleEndian()) 16880b57cec5SDimitry Andric Offset = FieldSize - (Offset + Size); 16890b57cec5SDimitry Andric 1690*0fca6ea1SDimitry Andric if (Offset < 0) 1691*0fca6ea1SDimitry Andric addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata, 1692*0fca6ea1SDimitry Andric Offset); 1693*0fca6ea1SDimitry Andric else 1694*0fca6ea1SDimitry Andric addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt, 1695*0fca6ea1SDimitry Andric (uint64_t)Offset); 16960b57cec5SDimitry Andric OffsetInBytes = FieldOffset >> 3; 16970b57cec5SDimitry Andric } else { 1698bdd1243dSDimitry Andric addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset); 16990b57cec5SDimitry Andric } 17000b57cec5SDimitry Andric } else { 17010b57cec5SDimitry Andric // This is not a bitfield. 17020b57cec5SDimitry Andric OffsetInBytes = DT->getOffsetInBits() / 8; 17030b57cec5SDimitry Andric if (AlignInBytes) 17040b57cec5SDimitry Andric addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 17050b57cec5SDimitry Andric AlignInBytes); 17060b57cec5SDimitry Andric } 17070b57cec5SDimitry Andric 17080b57cec5SDimitry Andric if (DD->getDwarfVersion() <= 2) { 17090b57cec5SDimitry Andric DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; 17100b57cec5SDimitry Andric addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); 17110b57cec5SDimitry Andric addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); 17120b57cec5SDimitry Andric addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); 1713fe6060f1SDimitry Andric } else if (!IsBitfield || DD->useDWARF2Bitfields()) { 1714fe6060f1SDimitry Andric // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are 1715fe6060f1SDimitry Andric // interpreted as location-list pointers. Interpreting constants as 1716fe6060f1SDimitry Andric // pointers is not expected, so we use DW_FORM_udata to encode the 1717fe6060f1SDimitry Andric // constants here. 1718fe6060f1SDimitry Andric if (DD->getDwarfVersion() == 3) 1719fe6060f1SDimitry Andric addUInt(MemberDie, dwarf::DW_AT_data_member_location, 1720fe6060f1SDimitry Andric dwarf::DW_FORM_udata, OffsetInBytes); 1721fe6060f1SDimitry Andric else 1722bdd1243dSDimitry Andric addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt, 17230b57cec5SDimitry Andric OffsetInBytes); 17240b57cec5SDimitry Andric } 1725fe6060f1SDimitry Andric } 17260b57cec5SDimitry Andric 17270eae32dcSDimitry Andric addAccess(MemberDie, DT->getFlags()); 17280eae32dcSDimitry Andric 17290b57cec5SDimitry Andric if (DT->isVirtual()) 17300b57cec5SDimitry Andric addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, 17310b57cec5SDimitry Andric dwarf::DW_VIRTUALITY_virtual); 17320b57cec5SDimitry Andric 17330b57cec5SDimitry Andric // Objective-C properties. 17340b57cec5SDimitry Andric if (DINode *PNode = DT->getObjCProperty()) 17350b57cec5SDimitry Andric if (DIE *PDie = getDIE(PNode)) 1736fe6060f1SDimitry Andric addAttribute(MemberDie, dwarf::DW_AT_APPLE_property, 17370b57cec5SDimitry Andric dwarf::DW_FORM_ref4, DIEEntry(*PDie)); 17380b57cec5SDimitry Andric 17390b57cec5SDimitry Andric if (DT->isArtificial()) 17400b57cec5SDimitry Andric addFlag(MemberDie, dwarf::DW_AT_artificial); 17410b57cec5SDimitry Andric 17420b57cec5SDimitry Andric return MemberDie; 17430b57cec5SDimitry Andric } 17440b57cec5SDimitry Andric 17450b57cec5SDimitry Andric DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) { 17460b57cec5SDimitry Andric if (!DT) 17470b57cec5SDimitry Andric return nullptr; 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 17500b57cec5SDimitry Andric // such construction creates the DIE. 17510b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(DT->getScope()); 17520b57cec5SDimitry Andric assert(dwarf::isType(ContextDIE->getTag()) && 17530b57cec5SDimitry Andric "Static member should belong to a type."); 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric if (DIE *StaticMemberDIE = getDIE(DT)) 17560b57cec5SDimitry Andric return StaticMemberDIE; 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT); 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric const DIType *Ty = DT->getBaseType(); 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName()); 17630b57cec5SDimitry Andric addType(StaticMemberDIE, Ty); 17640b57cec5SDimitry Andric addSourceLine(StaticMemberDIE, DT); 17650b57cec5SDimitry Andric addFlag(StaticMemberDIE, dwarf::DW_AT_external); 17660b57cec5SDimitry Andric addFlag(StaticMemberDIE, dwarf::DW_AT_declaration); 17670b57cec5SDimitry Andric 17680b57cec5SDimitry Andric // FIXME: We could omit private if the parent is a class_type, and 17690b57cec5SDimitry Andric // public if the parent is something else. 17700eae32dcSDimitry Andric addAccess(StaticMemberDIE, DT->getFlags()); 17710b57cec5SDimitry Andric 17720b57cec5SDimitry Andric if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant())) 17730b57cec5SDimitry Andric addConstantValue(StaticMemberDIE, CI, Ty); 17740b57cec5SDimitry Andric if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant())) 17750b57cec5SDimitry Andric addConstantFPValue(StaticMemberDIE, CFP); 17760b57cec5SDimitry Andric 17770b57cec5SDimitry Andric if (uint32_t AlignInBytes = DT->getAlignInBytes()) 17780b57cec5SDimitry Andric addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 17790b57cec5SDimitry Andric AlignInBytes); 17800b57cec5SDimitry Andric 17810b57cec5SDimitry Andric return &StaticMemberDIE; 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) { 17850b57cec5SDimitry Andric // Emit size of content not including length itself 1786fe6060f1SDimitry Andric if (!DD->useSectionsAsReferences()) 1787fe6060f1SDimitry Andric EndLabel = Asm->emitDwarfUnitLength( 1788fe6060f1SDimitry Andric isDwoUnit() ? "debug_info_dwo" : "debug_info", "Length of Unit"); 1789fe6060f1SDimitry Andric else 1790e8d8bef9SDimitry Andric Asm->emitDwarfUnitLength(getHeaderSize() + getUnitDie().getSize(), 1791e8d8bef9SDimitry Andric "Length of Unit"); 17920b57cec5SDimitry Andric 17930b57cec5SDimitry Andric Asm->OutStreamer->AddComment("DWARF version number"); 17940b57cec5SDimitry Andric unsigned Version = DD->getDwarfVersion(); 17950b57cec5SDimitry Andric Asm->emitInt16(Version); 17960b57cec5SDimitry Andric 17970b57cec5SDimitry Andric // DWARF v5 reorders the address size and adds a unit type. 17980b57cec5SDimitry Andric if (Version >= 5) { 17990b57cec5SDimitry Andric Asm->OutStreamer->AddComment("DWARF Unit Type"); 18000b57cec5SDimitry Andric Asm->emitInt8(UT); 18010b57cec5SDimitry Andric Asm->OutStreamer->AddComment("Address Size (in bytes)"); 18020b57cec5SDimitry Andric Asm->emitInt8(Asm->MAI->getCodePointerSize()); 18030b57cec5SDimitry Andric } 18040b57cec5SDimitry Andric 18050b57cec5SDimitry Andric // We share one abbreviations table across all units so it's always at the 18060b57cec5SDimitry Andric // start of the section. Use a relocatable offset where needed to ensure 18070b57cec5SDimitry Andric // linking doesn't invalidate that offset. 18080b57cec5SDimitry Andric Asm->OutStreamer->AddComment("Offset Into Abbrev. Section"); 18090b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 18100b57cec5SDimitry Andric if (UseOffsets) 1811e8d8bef9SDimitry Andric Asm->emitDwarfLengthOrOffset(0); 18120b57cec5SDimitry Andric else 18130b57cec5SDimitry Andric Asm->emitDwarfSymbolReference( 18140b57cec5SDimitry Andric TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false); 18150b57cec5SDimitry Andric 18160b57cec5SDimitry Andric if (Version <= 4) { 18170b57cec5SDimitry Andric Asm->OutStreamer->AddComment("Address Size (in bytes)"); 18180b57cec5SDimitry Andric Asm->emitInt8(Asm->MAI->getCodePointerSize()); 18190b57cec5SDimitry Andric } 18200b57cec5SDimitry Andric } 18210b57cec5SDimitry Andric 18220b57cec5SDimitry Andric void DwarfTypeUnit::emitHeader(bool UseOffsets) { 18235f757f3fSDimitry Andric if (!DD->useSplitDwarf()) { 18245f757f3fSDimitry Andric LabelBegin = Asm->createTempSymbol("tu_begin"); 18255f757f3fSDimitry Andric Asm->OutStreamer->emitLabel(LabelBegin); 18265f757f3fSDimitry Andric } 18270b57cec5SDimitry Andric DwarfUnit::emitCommonHeader(UseOffsets, 18280b57cec5SDimitry Andric DD->useSplitDwarf() ? dwarf::DW_UT_split_type 18290b57cec5SDimitry Andric : dwarf::DW_UT_type); 18300b57cec5SDimitry Andric Asm->OutStreamer->AddComment("Type Signature"); 18315ffd83dbSDimitry Andric Asm->OutStreamer->emitIntValue(TypeSignature, sizeof(TypeSignature)); 18320b57cec5SDimitry Andric Asm->OutStreamer->AddComment("Type DIE Offset"); 18330b57cec5SDimitry Andric // In a skeleton type unit there is no type DIE so emit a zero offset. 1834e8d8bef9SDimitry Andric Asm->emitDwarfLengthOrOffset(Ty ? Ty->getOffset() : 0); 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric 1837fe6060f1SDimitry Andric void DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, 18380b57cec5SDimitry Andric const MCSymbol *Hi, const MCSymbol *Lo) { 1839fe6060f1SDimitry Andric addAttribute(Die, Attribute, DD->getDwarfSectionOffsetForm(), 18400b57cec5SDimitry Andric new (DIEValueAllocator) DIEDelta(Hi, Lo)); 18410b57cec5SDimitry Andric } 18420b57cec5SDimitry Andric 1843fe6060f1SDimitry Andric void DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, 18440b57cec5SDimitry Andric const MCSymbol *Label, const MCSymbol *Sec) { 1845bdd1243dSDimitry Andric if (Asm->doesDwarfUseRelocationsAcrossSections()) 1846fe6060f1SDimitry Andric addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label); 1847fe6060f1SDimitry Andric else 1848fe6060f1SDimitry Andric addSectionDelta(Die, Attribute, Label, Sec); 18490b57cec5SDimitry Andric } 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric bool DwarfTypeUnit::isDwoUnit() const { 18520b57cec5SDimitry Andric // Since there are no skeleton type units, all type units are dwo type units 18530b57cec5SDimitry Andric // when split DWARF is being used. 18540b57cec5SDimitry Andric return DD->useSplitDwarf(); 18550b57cec5SDimitry Andric } 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric void DwarfTypeUnit::addGlobalName(StringRef Name, const DIE &Die, 18580b57cec5SDimitry Andric const DIScope *Context) { 18590b57cec5SDimitry Andric getCU().addGlobalNameForTypeUnit(Name, Context); 18600b57cec5SDimitry Andric } 18610b57cec5SDimitry Andric 1862*0fca6ea1SDimitry Andric void DwarfTypeUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die, 18630b57cec5SDimitry Andric const DIScope *Context) { 18640b57cec5SDimitry Andric getCU().addGlobalTypeUnitType(Ty, Context); 18650b57cec5SDimitry Andric } 18660b57cec5SDimitry Andric 18670b57cec5SDimitry Andric const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const { 1868bdd1243dSDimitry Andric if (!Asm->doesDwarfUseRelocationsAcrossSections()) 18690b57cec5SDimitry Andric return nullptr; 18700b57cec5SDimitry Andric if (isDwoUnit()) 18710b57cec5SDimitry Andric return nullptr; 18720b57cec5SDimitry Andric return getSection()->getBeginSymbol(); 18730b57cec5SDimitry Andric } 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric void DwarfUnit::addStringOffsetsStart() { 18760b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 18770b57cec5SDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_str_offsets_base, 18780b57cec5SDimitry Andric DU->getStringOffsetsStartSym(), 18790b57cec5SDimitry Andric TLOF.getDwarfStrOffSection()->getBeginSymbol()); 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric 18820b57cec5SDimitry Andric void DwarfUnit::addRnglistsBase() { 18830b57cec5SDimitry Andric assert(DD->getDwarfVersion() >= 5 && 18840b57cec5SDimitry Andric "DW_AT_rnglists_base requires DWARF version 5 or later"); 18850b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 18860b57cec5SDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_rnglists_base, 18870b57cec5SDimitry Andric DU->getRnglistsTableBaseSym(), 18880b57cec5SDimitry Andric TLOF.getDwarfRnglistsSection()->getBeginSymbol()); 18890b57cec5SDimitry Andric } 18900b57cec5SDimitry Andric 18910b57cec5SDimitry Andric void DwarfTypeUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { 189281ad6265SDimitry Andric DD->getAddressPool().resetUsedFlag(true); 18930b57cec5SDimitry Andric } 1894bdd1243dSDimitry Andric 1895bdd1243dSDimitry Andric bool DwarfUnit::isCompatibleWithVersion(uint16_t Version) const { 1896bdd1243dSDimitry Andric return !Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= Version; 1897bdd1243dSDimitry Andric } 1898