16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// 23443575cSPaul Robinson // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63443575cSPaul Robinson // 73443575cSPaul Robinson //===----------------------------------------------------------------------===// 83443575cSPaul Robinson // 93443575cSPaul Robinson // This file contains support for constructing a dwarf compile unit. 103443575cSPaul Robinson // 113443575cSPaul Robinson //===----------------------------------------------------------------------===// 123443575cSPaul Robinson 1337c52310SDavid Blaikie #include "DwarfCompileUnit.h" 146e07bfd0SEugene Zelenko #include "AddressPool.h" 156e07bfd0SEugene Zelenko #include "DwarfDebug.h" 167813d9c9SAdrian Prantl #include "DwarfExpression.h" 176e07bfd0SEugene Zelenko #include "DwarfUnit.h" 186e07bfd0SEugene Zelenko #include "llvm/ADT/None.h" 196e07bfd0SEugene Zelenko #include "llvm/ADT/STLExtras.h" 20b86ce219SMarkus Lavin #include "llvm/ADT/SmallString.h" 216e07bfd0SEugene Zelenko #include "llvm/ADT/SmallVector.h" 226e07bfd0SEugene Zelenko #include "llvm/ADT/StringRef.h" 236e07bfd0SEugene Zelenko #include "llvm/BinaryFormat/Dwarf.h" 246e07bfd0SEugene Zelenko #include "llvm/CodeGen/AsmPrinter.h" 256e07bfd0SEugene Zelenko #include "llvm/CodeGen/DIE.h" 266e07bfd0SEugene Zelenko #include "llvm/CodeGen/LexicalScopes.h" 27cda2aa82SDavid Blaikie #include "llvm/CodeGen/MachineFunction.h" 286e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineInstr.h" 296e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineOperand.h" 30b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetFrameLowering.h" 31b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h" 32b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h" 3337c52310SDavid Blaikie #include "llvm/IR/DataLayout.h" 346e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfo.h" 356e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfoMetadata.h" 3637c52310SDavid Blaikie #include "llvm/IR/GlobalVariable.h" 376e07bfd0SEugene Zelenko #include "llvm/MC/MCSection.h" 3837c52310SDavid Blaikie #include "llvm/MC/MCStreamer.h" 396e07bfd0SEugene Zelenko #include "llvm/MC/MCSymbol.h" 40b3bde2eaSDavid Blaikie #include "llvm/MC/MachineLocation.h" 416e07bfd0SEugene Zelenko #include "llvm/Support/Casting.h" 426054e650SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h" 43cda2aa82SDavid Blaikie #include "llvm/Target/TargetMachine.h" 446e07bfd0SEugene Zelenko #include "llvm/Target/TargetOptions.h" 456e07bfd0SEugene Zelenko #include <algorithm> 466e07bfd0SEugene Zelenko #include <cassert> 476e07bfd0SEugene Zelenko #include <cstdint> 486e07bfd0SEugene Zelenko #include <iterator> 496e07bfd0SEugene Zelenko #include <memory> 506e07bfd0SEugene Zelenko #include <string> 516e07bfd0SEugene Zelenko #include <utility> 5237c52310SDavid Blaikie 536e07bfd0SEugene Zelenko using namespace llvm; 5437c52310SDavid Blaikie 55a9308c49SDuncan P. N. Exon Smith DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, 5637c52310SDavid Blaikie AsmPrinter *A, DwarfDebug *DW, 5737c52310SDavid Blaikie DwarfFile *DWU) 586e07bfd0SEugene Zelenko : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) { 5937c52310SDavid Blaikie insertDIE(Node, &getUnitDie()); 608bbce8adSAmjad Aboud MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); 6137c52310SDavid Blaikie } 6237c52310SDavid Blaikie 6337c52310SDavid Blaikie /// addLabelAddress - Add a dwarf label attribute data and value using 6437c52310SDavid Blaikie /// DW_FORM_addr or DW_FORM_GNU_addr_index. 6537c52310SDavid Blaikie void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, 6637c52310SDavid Blaikie const MCSymbol *Label) { 6737c52310SDavid Blaikie // Don't use the address pool in non-fission or in the skeleton unit itself. 6837c52310SDavid Blaikie // FIXME: Once GDB supports this, it's probably worthwhile using the address 6937c52310SDavid Blaikie // pool from the skeleton - maybe even in non-fission (possibly fewer 7037c52310SDavid Blaikie // relocations by sharing them in the pool, but we have other ideas about how 7137c52310SDavid Blaikie // to reduce the number of relocations as well/instead). 72161dd3c1SDavid Blaikie if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) 7337c52310SDavid Blaikie return addLocalLabelAddress(Die, Attribute, Label); 7437c52310SDavid Blaikie 7537c52310SDavid Blaikie if (Label) 7637c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Label)); 7737c52310SDavid Blaikie 7837c52310SDavid Blaikie unsigned idx = DD->getAddressPool().getIndex(Label); 79161dd3c1SDavid Blaikie Die.addValue(DIEValueAllocator, Attribute, 80161dd3c1SDavid Blaikie DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx 81161dd3c1SDavid Blaikie : dwarf::DW_FORM_GNU_addr_index, 824fb1f9cdSDuncan P. N. Exon Smith DIEInteger(idx)); 8337c52310SDavid Blaikie } 8437c52310SDavid Blaikie 8537c52310SDavid Blaikie void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, 8637c52310SDavid Blaikie dwarf::Attribute Attribute, 8737c52310SDavid Blaikie const MCSymbol *Label) { 8837c52310SDavid Blaikie if (Label) 8937c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Label)); 9037c52310SDavid Blaikie 91815a6eb5SDuncan P. N. Exon Smith if (Label) 924fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 934fb1f9cdSDuncan P. N. Exon Smith DIELabel(Label)); 94815a6eb5SDuncan P. N. Exon Smith else 954fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 964fb1f9cdSDuncan P. N. Exon Smith DIEInteger(0)); 9737c52310SDavid Blaikie } 9837c52310SDavid Blaikie 99612e89d7SPaul Robinson unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { 10037c52310SDavid Blaikie // If we print assembly, we can't separate .file entries according to 10137c52310SDavid Blaikie // compile units. Thus all files will belong to the default compile unit. 10237c52310SDavid Blaikie 10337c52310SDavid Blaikie // FIXME: add a better feature test than hasRawTextSupport. Even better, 10437c52310SDavid Blaikie // extend .file to support this. 105612e89d7SPaul Robinson unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); 106612e89d7SPaul Robinson if (!File) 107798e83b5SEric Christopher return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", None, None, CUID); 1089ff69c8fSLang Hames return Asm->OutStreamer->EmitDwarfFileDirective( 10916c7bdafSScott Linder 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), 11016c7bdafSScott Linder File->getSource(), CUID); 11137c52310SDavid Blaikie } 11237c52310SDavid Blaikie 11360635e39SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( 114bceaaa96SAdrian Prantl const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 11537c52310SDavid Blaikie // Check for pre-existence. 11637c52310SDavid Blaikie if (DIE *Die = getDIE(GV)) 11737c52310SDavid Blaikie return Die; 11837c52310SDavid Blaikie 119e686f159SDuncan P. N. Exon Smith assert(GV); 12037c52310SDavid Blaikie 121be9e4fe7SDuncan P. N. Exon Smith auto *GVContext = GV->getScope(); 122*da82ce99SFangrui Song const DIType *GTy = GV->getType(); 12337c52310SDavid Blaikie 12437c52310SDavid Blaikie // Construct the context before querying for the existence of the DIE in 12537c52310SDavid Blaikie // case such construction creates the DIE. 1266ed5706aSAdrian Prantl auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr; 1276ed5706aSAdrian Prantl DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs) 1286ed5706aSAdrian Prantl : getOrCreateContextDIE(GVContext); 12937c52310SDavid Blaikie 13072da9391SAmjad Aboud // Add to map. 13172da9391SAmjad Aboud DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV); 132a9308c49SDuncan P. N. Exon Smith DIScope *DeclContext; 133b1055640SDuncan P. N. Exon Smith if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { 134*da82ce99SFangrui Song DeclContext = SDMDecl->getScope(); 135b1055640SDuncan P. N. Exon Smith assert(SDMDecl->isStaticMember() && "Expected static member decl"); 1367348ddaaSDuncan P. N. Exon Smith assert(GV->isDefinition()); 13749cfc8caSDavid Blaikie // We need the declaration DIE that is in the static member's class. 13849cfc8caSDavid Blaikie DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); 13949cfc8caSDavid Blaikie addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); 1403502f208SAdrian Prantl // If the global variable's type is different from the one in the class 1413502f208SAdrian Prantl // member type, assume that it's more specific and also emit it. 142*da82ce99SFangrui Song if (GTy != SDMDecl->getBaseType()) 1433502f208SAdrian Prantl addType(*VariableDIE, GTy); 14449cfc8caSDavid Blaikie } else { 1457348ddaaSDuncan P. N. Exon Smith DeclContext = GV->getScope(); 14637c52310SDavid Blaikie // Add name and type. 1477348ddaaSDuncan P. N. Exon Smith addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); 14837c52310SDavid Blaikie addType(*VariableDIE, GTy); 14937c52310SDavid Blaikie 15037c52310SDavid Blaikie // Add scoping info. 1517348ddaaSDuncan P. N. Exon Smith if (!GV->isLocalToUnit()) 15237c52310SDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_external); 15337c52310SDavid Blaikie 15437c52310SDavid Blaikie // Add line number info. 15537c52310SDavid Blaikie addSourceLine(*VariableDIE, GV); 15637c52310SDavid Blaikie } 15737c52310SDavid Blaikie 1587348ddaaSDuncan P. N. Exon Smith if (!GV->isDefinition()) 15949cfc8caSDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_declaration); 160877354a2SDavid Blaikie else 161877354a2SDavid Blaikie addGlobalName(GV->getName(), *VariableDIE, DeclContext); 16249cfc8caSDavid Blaikie 1633c989984SVictor Leschuk if (uint32_t AlignInBytes = GV->getAlignInBytes()) 1643c989984SVictor Leschuk addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 1653c989984SVictor Leschuk AlignInBytes); 1663c989984SVictor Leschuk 167f8ab35a4SMatthew Voss if (MDTuple *TP = GV->getTemplateParams()) 168f8ab35a4SMatthew Voss addTemplateParams(*VariableDIE, DINodeArray(TP)); 169f8ab35a4SMatthew Voss 17037c52310SDavid Blaikie // Add location. 1716ed5706aSAdrian Prantl addLocationAttribute(VariableDIE, GV, GlobalExprs); 1726ed5706aSAdrian Prantl 1736ed5706aSAdrian Prantl return VariableDIE; 1746ed5706aSAdrian Prantl } 1756ed5706aSAdrian Prantl 1766ed5706aSAdrian Prantl void DwarfCompileUnit::addLocationAttribute( 1776ed5706aSAdrian Prantl DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 17837c52310SDavid Blaikie bool addToAccelTable = false; 179bceaaa96SAdrian Prantl DIELoc *Loc = nullptr; 180f3a91503SAlexey Bataev Optional<unsigned> NVPTXAddressSpace; 181bceaaa96SAdrian Prantl std::unique_ptr<DIEDwarfExpression> DwarfExpr; 182bceaaa96SAdrian Prantl for (const auto &GE : GlobalExprs) { 183bceaaa96SAdrian Prantl const GlobalVariable *Global = GE.Var; 184bceaaa96SAdrian Prantl const DIExpression *Expr = GE.Expr; 185b216e3e9SAdrian Prantl 186d4135bbcSPeter Collingbourne // For compatibility with DWARF 3 and earlier, 187d4135bbcSPeter Collingbourne // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes 188d4135bbcSPeter Collingbourne // DW_AT_const_value(X). 189bceaaa96SAdrian Prantl if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { 190b216e3e9SAdrian Prantl addToAccelTable = true; 191d4135bbcSPeter Collingbourne addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); 192b216e3e9SAdrian Prantl break; 193b216e3e9SAdrian Prantl } 194b216e3e9SAdrian Prantl 195bceaaa96SAdrian Prantl // We cannot describe the location of dllimport'd variables: the 196bceaaa96SAdrian Prantl // computation of their address requires loads from the IAT. 197b216e3e9SAdrian Prantl if (Global && Global->hasDLLImportStorageClass()) 198b216e3e9SAdrian Prantl continue; 199b216e3e9SAdrian Prantl 200b216e3e9SAdrian Prantl // Nothing to describe without address or constant. 201b216e3e9SAdrian Prantl if (!Global && (!Expr || !Expr->isConstant())) 202b216e3e9SAdrian Prantl continue; 203b216e3e9SAdrian Prantl 2048e422b84SLei Liu if (Global && Global->isThreadLocal() && 2058e422b84SLei Liu !Asm->getObjFileLowering().supportDebugThreadLocalLocation()) 2068e422b84SLei Liu continue; 2078e422b84SLei Liu 208bceaaa96SAdrian Prantl if (!Loc) { 209b216e3e9SAdrian Prantl addToAccelTable = true; 210bceaaa96SAdrian Prantl Loc = new (DIEValueAllocator) DIELoc; 211bceaaa96SAdrian Prantl DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc); 212bceaaa96SAdrian Prantl } 213b216e3e9SAdrian Prantl 214f3a91503SAlexey Bataev if (Expr) { 215f3a91503SAlexey Bataev // According to 216f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 217f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to 218f3a91503SAlexey Bataev // correctly interpret address space of the variable address. 219f3a91503SAlexey Bataev // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 220f3a91503SAlexey Bataev // sequence for the NVPTX + gdb target. 221f3a91503SAlexey Bataev unsigned LocalNVPTXAddressSpace; 222f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 223f3a91503SAlexey Bataev const DIExpression *NewExpr = 224f3a91503SAlexey Bataev DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 225f3a91503SAlexey Bataev if (NewExpr != Expr) { 226f3a91503SAlexey Bataev Expr = NewExpr; 227f3a91503SAlexey Bataev NVPTXAddressSpace = LocalNVPTXAddressSpace; 228f3a91503SAlexey Bataev } 229f3a91503SAlexey Bataev } 230a9e31537SMikael Holmen DwarfExpr->addFragmentOffset(Expr); 231f3a91503SAlexey Bataev } 232a9e31537SMikael Holmen 233bceaaa96SAdrian Prantl if (Global) { 234cca5f68eSDuncan P. N. Exon Smith const MCSymbol *Sym = Asm->getSymbol(Global); 235cca5f68eSDuncan P. N. Exon Smith if (Global->isThreadLocal()) { 2369f9e4681SChih-Hung Hsieh if (Asm->TM.useEmulatedTLS()) { 2371e859582SChih-Hung Hsieh // TODO: add debug info for emulated thread local mode. 2381e859582SChih-Hung Hsieh } else { 23937c52310SDavid Blaikie // FIXME: Make this work with -gsplit-dwarf. 24037c52310SDavid Blaikie unsigned PointerSize = Asm->getDataLayout().getPointerSize(); 24137c52310SDavid Blaikie assert((PointerSize == 4 || PointerSize == 8) && 24237c52310SDavid Blaikie "Add support for other sizes if necessary"); 24337c52310SDavid Blaikie // Based on GCC's support for TLS: 24437c52310SDavid Blaikie if (!DD->useSplitDwarf()) { 24537c52310SDavid Blaikie // 1) Start with a constNu of the appropriate pointer size 246bceaaa96SAdrian Prantl addUInt(*Loc, dwarf::DW_FORM_data1, 247bceaaa96SAdrian Prantl PointerSize == 4 ? dwarf::DW_OP_const4u 24854511353SDehao Chen : dwarf::DW_OP_const8u); 24937c52310SDavid Blaikie // 2) containing the (relocated) offset of the TLS variable 25037c52310SDavid Blaikie // within the module's TLS block. 25137c52310SDavid Blaikie addExpr(*Loc, dwarf::DW_FORM_udata, 25237c52310SDavid Blaikie Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); 25337c52310SDavid Blaikie } else { 25437c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); 25537c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_udata, 25637c52310SDavid Blaikie DD->getAddressPool().getIndex(Sym, /* TLS */ true)); 25737c52310SDavid Blaikie } 25878cc0821SPaul Robinson // 3) followed by an OP to make the debugger do a TLS lookup. 25978cc0821SPaul Robinson addUInt(*Loc, dwarf::DW_FORM_data1, 26078cc0821SPaul Robinson DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address 26178cc0821SPaul Robinson : dwarf::DW_OP_form_tls_address); 2621e859582SChih-Hung Hsieh } 26337c52310SDavid Blaikie } else { 26437c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Sym)); 26537c52310SDavid Blaikie addOpAddress(*Loc, Sym); 26637c52310SDavid Blaikie } 267bceaaa96SAdrian Prantl } 2684b542c6eSAdrian Prantl // Global variables attached to symbols are memory locations. 2694b542c6eSAdrian Prantl // It would be better if this were unconditional, but malformed input that 2704b542c6eSAdrian Prantl // mixes non-fragments and fragments for the same variable is too expensive 2714b542c6eSAdrian Prantl // to detect in the verifier. 2723edc63a5SAdrian Prantl if (DwarfExpr->isUnknownLocation()) 2734b542c6eSAdrian Prantl DwarfExpr->setMemoryLocationKind(); 274a63b8e82SAdrian Prantl DwarfExpr->addExpression(Expr); 275d4135bbcSPeter Collingbourne } 276f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 277f3a91503SAlexey Bataev // According to 278f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 279f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to 280f3a91503SAlexey Bataev // correctly interpret address space of the variable address. 281f3a91503SAlexey Bataev const unsigned NVPTX_ADDR_global_space = 5; 282f3a91503SAlexey Bataev addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 283f3a91503SAlexey Bataev NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space); 284f3a91503SAlexey Bataev } 285bceaaa96SAdrian Prantl if (Loc) 286bceaaa96SAdrian Prantl addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); 287d4135bbcSPeter Collingbourne 28843d1e453SPaul Robinson if (DD->useAllLinkageNames()) 2897348ddaaSDuncan P. N. Exon Smith addLinkageName(*VariableDIE, GV->getLinkageName()); 29037c52310SDavid Blaikie 29137c52310SDavid Blaikie if (addToAccelTable) { 29266cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getName(), *VariableDIE); 29337c52310SDavid Blaikie 29437c52310SDavid Blaikie // If the linkage name is different than the name, go ahead and output 29537c52310SDavid Blaikie // that as well into the name table. 2962a6afe5fSPavel Labath if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() && 2972a6afe5fSPavel Labath DD->useAllLinkageNames()) 29866cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE); 29937c52310SDavid Blaikie } 3006ed5706aSAdrian Prantl } 30137c52310SDavid Blaikie 3026ed5706aSAdrian Prantl DIE *DwarfCompileUnit::getOrCreateCommonBlock( 3036ed5706aSAdrian Prantl const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) { 3046ed5706aSAdrian Prantl // Construct the context before querying for the existence of the DIE in case 3056ed5706aSAdrian Prantl // such construction creates the DIE. 3066ed5706aSAdrian Prantl DIE *ContextDIE = getOrCreateContextDIE(CB->getScope()); 3076ed5706aSAdrian Prantl 3086ed5706aSAdrian Prantl if (DIE *NDie = getDIE(CB)) 3096ed5706aSAdrian Prantl return NDie; 3106ed5706aSAdrian Prantl DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB); 3116ed5706aSAdrian Prantl StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName(); 3126ed5706aSAdrian Prantl addString(NDie, dwarf::DW_AT_name, Name); 3136ed5706aSAdrian Prantl addGlobalName(Name, NDie, CB->getScope()); 3146ed5706aSAdrian Prantl if (CB->getFile()) 3156ed5706aSAdrian Prantl addSourceLine(NDie, CB->getLineNo(), CB->getFile()); 3166ed5706aSAdrian Prantl if (DIGlobalVariable *V = CB->getDecl()) 3176ed5706aSAdrian Prantl getCU().addLocationAttribute(&NDie, V, GlobalExprs); 3186ed5706aSAdrian Prantl return &NDie; 31937c52310SDavid Blaikie } 32037c52310SDavid Blaikie 32137c52310SDavid Blaikie void DwarfCompileUnit::addRange(RangeSpan Range) { 32237c52310SDavid Blaikie bool SameAsPrevCU = this == DD->getPrevCU(); 32337c52310SDavid Blaikie DD->setPrevCU(this); 32437c52310SDavid Blaikie // If we have no current ranges just add the range and return, otherwise, 32537c52310SDavid Blaikie // check the current section and CU against the previous section and CU we 32637c52310SDavid Blaikie // emitted into and the subprogram was contained within. If these are the 32737c52310SDavid Blaikie // same then extend our current range, otherwise add this as a new range. 32837c52310SDavid Blaikie if (CURanges.empty() || !SameAsPrevCU || 32937c52310SDavid Blaikie (&CURanges.back().getEnd()->getSection() != 33037c52310SDavid Blaikie &Range.getEnd()->getSection())) { 33137c52310SDavid Blaikie CURanges.push_back(Range); 33260fddac9SDavid Blaikie DD->addSectionLabel(Range.getStart()); 33337c52310SDavid Blaikie return; 33437c52310SDavid Blaikie } 33537c52310SDavid Blaikie 33637c52310SDavid Blaikie CURanges.back().setEnd(Range.getEnd()); 33737c52310SDavid Blaikie } 33837c52310SDavid Blaikie 339063d725fSRafael Espindola void DwarfCompileUnit::initStmtList() { 340d4dd7215SAlexey Bataev if (CUNode->isDebugDirectivesOnly()) 341d4dd7215SAlexey Bataev return; 342d4dd7215SAlexey Bataev 34337c52310SDavid Blaikie // Define start line table label for each Compile Unit. 344bff36086SAlexey Bataev MCSymbol *LineTableStartSym; 345bff36086SAlexey Bataev const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 346bff36086SAlexey Bataev if (DD->useSectionsAsReferences()) { 347bff36086SAlexey Bataev LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); 348bff36086SAlexey Bataev } else { 349bff36086SAlexey Bataev LineTableStartSym = 3509ff69c8fSLang Hames Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); 351bff36086SAlexey Bataev } 35237c52310SDavid Blaikie 35337c52310SDavid Blaikie // DW_AT_stmt_list is a offset of line number information for this 35437c52310SDavid Blaikie // compile unit in debug_line section. For split dwarf this is 35537c52310SDavid Blaikie // left in the skeleton CU and so not included. 35637c52310SDavid Blaikie // The line table entries are not always emitted in assembly, so it 35737c52310SDavid Blaikie // is not okay to use line_table_start here. 3584fb1f9cdSDuncan P. N. Exon Smith StmtListValue = 35935630c33SGreg Clayton addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, 360063d725fSRafael Espindola TLOF.getDwarfLineSection()->getBeginSymbol()); 36137c52310SDavid Blaikie } 36237c52310SDavid Blaikie 36337c52310SDavid Blaikie void DwarfCompileUnit::applyStmtList(DIE &D) { 3644fb1f9cdSDuncan P. N. Exon Smith D.addValue(DIEValueAllocator, *StmtListValue); 36537c52310SDavid Blaikie } 36637c52310SDavid Blaikie 36714499a7dSDavid Blaikie void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 36814499a7dSDavid Blaikie const MCSymbol *End) { 36914499a7dSDavid Blaikie assert(Begin && "Begin label should not be null!"); 37014499a7dSDavid Blaikie assert(End && "End label should not be null!"); 37114499a7dSDavid Blaikie assert(Begin->isDefined() && "Invalid starting label"); 37214499a7dSDavid Blaikie assert(End->isDefined() && "Invalid end label"); 37314499a7dSDavid Blaikie 37414499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); 37514499a7dSDavid Blaikie if (DD->getDwarfVersion() < 4) 37614499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_high_pc, End); 37714499a7dSDavid Blaikie else 37814499a7dSDavid Blaikie addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); 37914499a7dSDavid Blaikie } 38014499a7dSDavid Blaikie 381cda2aa82SDavid Blaikie // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 382cda2aa82SDavid Blaikie // and DW_AT_high_pc attributes. If there are global variables in this 383cda2aa82SDavid Blaikie // scope then create and insert DIEs for these variables. 384a9308c49SDuncan P. N. Exon Smith DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { 3853a443c29SDavid Blaikie DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); 386cda2aa82SDavid Blaikie 38707c03d31SRafael Espindola attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd()); 388c53e18d9SDavid Blaikie if (DD->useAppleExtensionAttributes() && 389c53e18d9SDavid Blaikie !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( 390cda2aa82SDavid Blaikie *DD->getCurrentFunction())) 391cda2aa82SDavid Blaikie addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); 392cda2aa82SDavid Blaikie 393cda2aa82SDavid Blaikie // Only include DW_AT_frame_base in full debug info 3943a443c29SDavid Blaikie if (!includeMinimalInlineScopes()) { 3957ae86fe7SAlexey Bataev if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) { 3967ae86fe7SAlexey Bataev DIELoc *Loc = new (DIEValueAllocator) DIELoc; 3977ae86fe7SAlexey Bataev addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa); 3987ae86fe7SAlexey Bataev addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 3997ae86fe7SAlexey Bataev } else { 400d4e723f2SEric Christopher const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo(); 401cda2aa82SDavid Blaikie MachineLocation Location(RI->getFrameRegister(*Asm->MF)); 4028efadbf8SAdrian Prantl if (RI->isPhysicalRegister(Location.getReg())) 403cda2aa82SDavid Blaikie addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); 404cda2aa82SDavid Blaikie } 4057ae86fe7SAlexey Bataev } 406cda2aa82SDavid Blaikie 407cda2aa82SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed 408cda2aa82SDavid Blaikie // to have concrete versions of our DW_TAG_subprogram nodes. 40966cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, SP, *SPDie); 410cda2aa82SDavid Blaikie 411cda2aa82SDavid Blaikie return *SPDie; 412cda2aa82SDavid Blaikie } 413cda2aa82SDavid Blaikie 4149c65b135SDavid Blaikie // Construct a DIE for this scope. 4159c65b135SDavid Blaikie void DwarfCompileUnit::constructScopeDIE( 416827200c8SDuncan P. N. Exon Smith LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { 4179c65b135SDavid Blaikie if (!Scope || !Scope->getScopeNode()) 4189c65b135SDavid Blaikie return; 4199c65b135SDavid Blaikie 420be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode(); 4219c65b135SDavid Blaikie 422a9308c49SDuncan P. N. Exon Smith assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && 4239c65b135SDavid Blaikie "Only handle inlined subprograms here, use " 4249c65b135SDavid Blaikie "constructSubprogramScopeDIE for non-inlined " 4259c65b135SDavid Blaikie "subprograms"); 4269c65b135SDavid Blaikie 427827200c8SDuncan P. N. Exon Smith SmallVector<DIE *, 8> Children; 4289c65b135SDavid Blaikie 4299c65b135SDavid Blaikie // We try to create the scope DIE first, then the children DIEs. This will 4309c65b135SDavid Blaikie // avoid creating un-used children then removing them later when we find out 4319c65b135SDavid Blaikie // the scope DIE is null. 432827200c8SDuncan P. N. Exon Smith DIE *ScopeDIE; 433a9308c49SDuncan P. N. Exon Smith if (Scope->getParent() && isa<DISubprogram>(DS)) { 43401b48a84SDavid Blaikie ScopeDIE = constructInlinedScopeDIE(Scope); 4359c65b135SDavid Blaikie if (!ScopeDIE) 4369c65b135SDavid Blaikie return; 4379c65b135SDavid Blaikie // We create children when the scope DIE is not null. 4388b2fdb83SDavid Blaikie createScopeChildrenDIE(Scope, Children); 4399c65b135SDavid Blaikie } else { 4409c65b135SDavid Blaikie // Early exit when we know the scope DIE is going to be null. 4419c65b135SDavid Blaikie if (DD->isLexicalScopeDIENull(Scope)) 4429c65b135SDavid Blaikie return; 4439c65b135SDavid Blaikie 4442195e136SDavid Blaikie bool HasNonScopeChildren = false; 4459c65b135SDavid Blaikie 4469c65b135SDavid Blaikie // We create children here when we know the scope DIE is not going to be 4479c65b135SDavid Blaikie // null and the children will be added to the scope DIE. 4482195e136SDavid Blaikie createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); 4493a443c29SDavid Blaikie 4509c65b135SDavid Blaikie // If there are only other scopes as children, put them directly in the 4519c65b135SDavid Blaikie // parent instead, as this scope would serve no purpose. 4522195e136SDavid Blaikie if (!HasNonScopeChildren) { 4539c65b135SDavid Blaikie FinalChildren.insert(FinalChildren.end(), 4549c65b135SDavid Blaikie std::make_move_iterator(Children.begin()), 4559c65b135SDavid Blaikie std::make_move_iterator(Children.end())); 4569c65b135SDavid Blaikie return; 4579c65b135SDavid Blaikie } 4580fbf8bdbSDavid Blaikie ScopeDIE = constructLexicalScopeDIE(Scope); 4599c65b135SDavid Blaikie assert(ScopeDIE && "Scope DIE should not be null."); 4609c65b135SDavid Blaikie } 4619c65b135SDavid Blaikie 4629c65b135SDavid Blaikie // Add children 4639c65b135SDavid Blaikie for (auto &I : Children) 4649c65b135SDavid Blaikie ScopeDIE->addChild(std::move(I)); 4659c65b135SDavid Blaikie 4669c65b135SDavid Blaikie FinalChildren.push_back(std::move(ScopeDIE)); 4679c65b135SDavid Blaikie } 4689c65b135SDavid Blaikie 4695b02a19fSDavid Blaikie void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, 4705b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> Range) { 471063d725fSRafael Espindola const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 472063d725fSRafael Espindola 473fcf3810cSWolfgang Pieb // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable 474fcf3810cSWolfgang Pieb // label. emitDIE() will handle emitting it appropriately. 475063d725fSRafael Espindola const MCSymbol *RangeSectionSym = 476fcf3810cSWolfgang Pieb DD->getDwarfVersion() >= 5 477fcf3810cSWolfgang Pieb ? TLOF.getDwarfRnglistsSection()->getBeginSymbol() 478fcf3810cSWolfgang Pieb : TLOF.getDwarfRangesSection()->getBeginSymbol(); 47952400200SDavid Blaikie 480c4af8bf2SDavid Blaikie HasRangeLists = true; 481c4af8bf2SDavid Blaikie 482c4af8bf2SDavid Blaikie // Add the range list to the set of ranges to be emitted. 483c4af8bf2SDavid Blaikie auto IndexAndList = 484c4af8bf2SDavid Blaikie (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU) 485c8f7e6c1SDavid Blaikie ->addRange(*(Skeleton ? Skeleton : this), std::move(Range)); 486c4af8bf2SDavid Blaikie 487c4af8bf2SDavid Blaikie uint32_t Index = IndexAndList.first; 488c4af8bf2SDavid Blaikie auto &List = *IndexAndList.second; 4895b02a19fSDavid Blaikie 49052400200SDavid Blaikie // Under fission, ranges are specified by constant offsets relative to the 49152400200SDavid Blaikie // CU's DW_AT_GNU_ranges_base. 492fcf3810cSWolfgang Pieb // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 493fcf3810cSWolfgang Pieb // fission until we support the forms using the .debug_addr section 494fcf3810cSWolfgang Pieb // (DW_RLE_startx_endx etc.). 49532e09de9SDavid Blaikie if (DD->getDwarfVersion() >= 5) 49632e09de9SDavid Blaikie addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index); 49732e09de9SDavid Blaikie else if (isDwoUnit()) 4985b02a19fSDavid Blaikie addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 4995b02a19fSDavid Blaikie RangeSectionSym); 500c4af8bf2SDavid Blaikie else 5015b02a19fSDavid Blaikie addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 5025b02a19fSDavid Blaikie RangeSectionSym); 503fcf3810cSWolfgang Pieb } 50452400200SDavid Blaikie 505de12375cSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC( 5065b02a19fSDavid Blaikie DIE &Die, SmallVector<RangeSpan, 2> Ranges) { 507858a7dd6SAlexey Bataev if (Ranges.size() == 1 || !DD->useRangesSection()) { 508858a7dd6SAlexey Bataev const RangeSpan &Front = Ranges.front(); 509858a7dd6SAlexey Bataev const RangeSpan &Back = Ranges.back(); 510858a7dd6SAlexey Bataev attachLowHighPC(Die, Front.getStart(), Back.getEnd()); 5115b02a19fSDavid Blaikie } else 5125b02a19fSDavid Blaikie addScopeRangeList(Die, std::move(Ranges)); 5135b02a19fSDavid Blaikie } 5145b02a19fSDavid Blaikie 5155b02a19fSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC( 516de12375cSDavid Blaikie DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { 5175b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> List; 5185b02a19fSDavid Blaikie List.reserve(Ranges.size()); 5195b02a19fSDavid Blaikie for (const InsnRange &R : Ranges) 5205b02a19fSDavid Blaikie List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), 5215b02a19fSDavid Blaikie DD->getLabelAfterInsn(R.second))); 5225b02a19fSDavid Blaikie attachRangesOrLowHighPC(Die, std::move(List)); 523de12375cSDavid Blaikie } 524de12375cSDavid Blaikie 52501b48a84SDavid Blaikie // This scope represents inlined body of a function. Construct DIE to 52601b48a84SDavid Blaikie // represent this concrete inlined copy of the function. 527827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { 52801b48a84SDavid Blaikie assert(Scope->getScopeNode()); 529be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode(); 530be9e4fe7SDuncan P. N. Exon Smith auto *InlinedSP = getDISubprogram(DS); 53101b48a84SDavid Blaikie // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 53201b48a84SDavid Blaikie // was inlined from another compile unit. 533488393f8SDavid Blaikie DIE *OriginDIE = getAbstractSPDies()[InlinedSP]; 53401b48a84SDavid Blaikie assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); 53501b48a84SDavid Blaikie 536827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); 53701b48a84SDavid Blaikie addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); 53801b48a84SDavid Blaikie 53901b48a84SDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 54001b48a84SDavid Blaikie 54101b48a84SDavid Blaikie // Add the call site information to the DIE. 542a9308c49SDuncan P. N. Exon Smith const DILocation *IA = Scope->getInlinedAt(); 54301b48a84SDavid Blaikie addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, 544612e89d7SPaul Robinson getOrCreateSourceID(IA->getFile())); 545b7e221baSDuncan P. N. Exon Smith addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine()); 5466e0c8446SDehao Chen if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4) 54754511353SDehao Chen addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None, 54854511353SDehao Chen IA->getDiscriminator()); 54901b48a84SDavid Blaikie 55001b48a84SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed 55101b48a84SDavid Blaikie // to have concrete versions of our DW_TAG_inlined_subprogram nodes. 55266cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE); 55301b48a84SDavid Blaikie 55401b48a84SDavid Blaikie return ScopeDIE; 55501b48a84SDavid Blaikie } 55601b48a84SDavid Blaikie 5570fbf8bdbSDavid Blaikie // Construct new DW_TAG_lexical_block for this scope and attach 5580fbf8bdbSDavid Blaikie // DW_AT_low_pc/DW_AT_high_pc labels. 559827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { 5600fbf8bdbSDavid Blaikie if (DD->isLexicalScopeDIENull(Scope)) 5610fbf8bdbSDavid Blaikie return nullptr; 5620fbf8bdbSDavid Blaikie 563827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); 5640fbf8bdbSDavid Blaikie if (Scope->isAbstractScope()) 5650fbf8bdbSDavid Blaikie return ScopeDIE; 5660fbf8bdbSDavid Blaikie 5670fbf8bdbSDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 5680fbf8bdbSDavid Blaikie 5690fbf8bdbSDavid Blaikie return ScopeDIE; 5700fbf8bdbSDavid Blaikie } 5710fbf8bdbSDavid Blaikie 572ee7df553SDavid Blaikie /// constructVariableDIE - Construct a DIE for the given DbgVariable. 573827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { 574ee7df553SDavid Blaikie auto D = constructVariableDIEImpl(DV, Abstract); 575ee7df553SDavid Blaikie DV.setDIE(*D); 576ee7df553SDavid Blaikie return D; 577ee7df553SDavid Blaikie } 578ee7df553SDavid Blaikie 5792532ac88SHsiangkai Wang DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, 5802532ac88SHsiangkai Wang const LexicalScope &Scope) { 5812532ac88SHsiangkai Wang auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); 5822532ac88SHsiangkai Wang insertDIE(DL.getLabel(), LabelDie); 5832532ac88SHsiangkai Wang DL.setDIE(*LabelDie); 5842532ac88SHsiangkai Wang 5852532ac88SHsiangkai Wang if (Scope.isAbstractScope()) 5862532ac88SHsiangkai Wang applyLabelAttributes(DL, *LabelDie); 5872532ac88SHsiangkai Wang 5882532ac88SHsiangkai Wang return LabelDie; 5892532ac88SHsiangkai Wang } 5902532ac88SHsiangkai Wang 591827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, 592ee7df553SDavid Blaikie bool Abstract) { 593ee7df553SDavid Blaikie // Define variable debug information entry. 594827200c8SDuncan P. N. Exon Smith auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); 595dc00becdSSander de Smalen insertDIE(DV.getVariable(), VariableDie); 596ee7df553SDavid Blaikie 597ee7df553SDavid Blaikie if (Abstract) { 598ee7df553SDavid Blaikie applyVariableAttributes(DV, *VariableDie); 599ee7df553SDavid Blaikie return VariableDie; 600ee7df553SDavid Blaikie } 601ee7df553SDavid Blaikie 602ee7df553SDavid Blaikie // Add variable address. 603ee7df553SDavid Blaikie 604364a3005SDuncan P. N. Exon Smith unsigned Offset = DV.getDebugLocListIndex(); 605ee7df553SDavid Blaikie if (Offset != ~0U) { 606ee7df553SDavid Blaikie addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); 607ee7df553SDavid Blaikie return VariableDie; 608ee7df553SDavid Blaikie } 609ee7df553SDavid Blaikie 610ee7df553SDavid Blaikie // Check if variable is described by a DBG_VALUE instruction. 611ee7df553SDavid Blaikie if (const MachineInstr *DVInsn = DV.getMInsn()) { 612ee7df553SDavid Blaikie assert(DVInsn->getNumOperands() == 4); 613ee7df553SDavid Blaikie if (DVInsn->getOperand(0).isReg()) { 614bd6d291cSAdrian Prantl auto RegOp = DVInsn->getOperand(0); 615bd6d291cSAdrian Prantl auto Op1 = DVInsn->getOperand(1); 616ee7df553SDavid Blaikie // If the second operand is an immediate, this is an indirect value. 617bd6d291cSAdrian Prantl assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); 618bd6d291cSAdrian Prantl MachineLocation Location(RegOp.getReg(), Op1.isImm()); 619ee7df553SDavid Blaikie addVariableAddress(DV, *VariableDie, Location); 6203b89e663SAdrian Prantl } else if (DVInsn->getOperand(0).isImm()) { 6213b89e663SAdrian Prantl // This variable is described by a single constant. 6223b89e663SAdrian Prantl // Check whether it has a DIExpression. 6233b89e663SAdrian Prantl auto *Expr = DV.getSingleExpression(); 6243b89e663SAdrian Prantl if (Expr && Expr->getNumElements()) { 6253b89e663SAdrian Prantl DIELoc *Loc = new (DIEValueAllocator) DIELoc; 6263b89e663SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 6273b89e663SAdrian Prantl // If there is an expression, emit raw unsigned bytes. 6288fafb8d3SAdrian Prantl DwarfExpr.addFragmentOffset(Expr); 629a63b8e82SAdrian Prantl DwarfExpr.addUnsignedConstant(DVInsn->getOperand(0).getImm()); 630a63b8e82SAdrian Prantl DwarfExpr.addExpression(Expr); 631bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 6323b89e663SAdrian Prantl } else 633ee7df553SDavid Blaikie addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); 6343b89e663SAdrian Prantl } else if (DVInsn->getOperand(0).isFPImm()) 635ee7df553SDavid Blaikie addConstantFPValue(*VariableDie, DVInsn->getOperand(0)); 636ee7df553SDavid Blaikie else if (DVInsn->getOperand(0).isCImm()) 637ee7df553SDavid Blaikie addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(), 638ee7df553SDavid Blaikie DV.getType()); 639ee7df553SDavid Blaikie 640ee7df553SDavid Blaikie return VariableDie; 641ee7df553SDavid Blaikie } 642ee7df553SDavid Blaikie 643ee7df553SDavid Blaikie // .. else use frame index. 64467c24422SAdrian Prantl if (!DV.hasFrameIndexExprs()) 645ca7e4702SAdrian Prantl return VariableDie; 646ca7e4702SAdrian Prantl 647f3a91503SAlexey Bataev Optional<unsigned> NVPTXAddressSpace; 648e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 649ca7e4702SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 65067c24422SAdrian Prantl for (auto &Fragment : DV.getFrameIndexExprs()) { 651ee7df553SDavid Blaikie unsigned FrameReg = 0; 6526825fb64SAdrian Prantl const DIExpression *Expr = Fragment.Expr; 653d4e723f2SEric Christopher const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 65467c24422SAdrian Prantl int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg); 6556825fb64SAdrian Prantl DwarfExpr.addFragmentOffset(Expr); 656956484b7SAdrian Prantl SmallVector<uint64_t, 8> Ops; 657ffc498dfSFlorian Hahn Ops.push_back(dwarf::DW_OP_plus_uconst); 658956484b7SAdrian Prantl Ops.push_back(Offset); 659f3a91503SAlexey Bataev // According to 660f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 661f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to 662f3a91503SAlexey Bataev // correctly interpret address space of the variable address. 663f3a91503SAlexey Bataev // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 664f3a91503SAlexey Bataev // sequence for the NVPTX + gdb target. 665f3a91503SAlexey Bataev unsigned LocalNVPTXAddressSpace; 666f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 667f3a91503SAlexey Bataev const DIExpression *NewExpr = 668f3a91503SAlexey Bataev DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 669f3a91503SAlexey Bataev if (NewExpr != Expr) { 670f3a91503SAlexey Bataev Expr = NewExpr; 671f3a91503SAlexey Bataev NVPTXAddressSpace = LocalNVPTXAddressSpace; 672f3a91503SAlexey Bataev } 673f3a91503SAlexey Bataev } 674f3a91503SAlexey Bataev if (Expr) 6756825fb64SAdrian Prantl Ops.append(Expr->elements_begin(), Expr->elements_end()); 6766825fb64SAdrian Prantl DIExpressionCursor Cursor(Ops); 677c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 6784dd7558fSAlexey Bataev if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) 6794dd7558fSAlexey Bataev addOpAddress(*Loc, FrameSymbol); 6804dd7558fSAlexey Bataev else 681c12cee36SAdrian Prantl DwarfExpr.addMachineRegExpression( 682c12cee36SAdrian Prantl *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); 6836825fb64SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 684ee7df553SDavid Blaikie } 685f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 686f3a91503SAlexey Bataev // According to 687f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 688f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to 689f3a91503SAlexey Bataev // correctly interpret address space of the variable address. 690f3a91503SAlexey Bataev const unsigned NVPTX_ADDR_local_space = 6; 691f3a91503SAlexey Bataev addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 692f3a91503SAlexey Bataev NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); 693f3a91503SAlexey Bataev } 694bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 695ee7df553SDavid Blaikie 696ee7df553SDavid Blaikie return VariableDie; 697ee7df553SDavid Blaikie } 698ee7df553SDavid Blaikie 699827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, 700827200c8SDuncan P. N. Exon Smith const LexicalScope &Scope, 701827200c8SDuncan P. N. Exon Smith DIE *&ObjectPointer) { 7024a1a44e3SDavid Blaikie auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); 7034a1a44e3SDavid Blaikie if (DV.isObjectPointer()) 704827200c8SDuncan P. N. Exon Smith ObjectPointer = Var; 7054a1a44e3SDavid Blaikie return Var; 7064a1a44e3SDavid Blaikie } 7074a1a44e3SDavid Blaikie 70803dd6f57SAdrian Prantl /// Return all DIVariables that appear in count: expressions. 70903dd6f57SAdrian Prantl static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) { 71003dd6f57SAdrian Prantl SmallVector<const DIVariable *, 2> Result; 71103dd6f57SAdrian Prantl auto *Array = dyn_cast<DICompositeType>(Var->getType()); 712c929f7adSAdrian Prantl if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) 71303dd6f57SAdrian Prantl return Result; 71403dd6f57SAdrian Prantl for (auto *El : Array->getElements()) { 715c929f7adSAdrian Prantl if (auto *Subrange = dyn_cast<DISubrange>(El)) { 716c929f7adSAdrian Prantl auto Count = Subrange->getCount(); 71703dd6f57SAdrian Prantl if (auto *Dependency = Count.dyn_cast<DIVariable *>()) 71803dd6f57SAdrian Prantl Result.push_back(Dependency); 719c929f7adSAdrian Prantl } 72003dd6f57SAdrian Prantl } 72103dd6f57SAdrian Prantl return Result; 722c929f7adSAdrian Prantl } 723c929f7adSAdrian Prantl 724c929f7adSAdrian Prantl /// Sort local variables so that variables appearing inside of helper 725c929f7adSAdrian Prantl /// expressions come first. 72603dd6f57SAdrian Prantl static SmallVector<DbgVariable *, 8> 72703dd6f57SAdrian Prantl sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) { 72803dd6f57SAdrian Prantl SmallVector<DbgVariable *, 8> Result; 72903dd6f57SAdrian Prantl SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList; 73003dd6f57SAdrian Prantl // Map back from a DIVariable to its containing DbgVariable. 73103dd6f57SAdrian Prantl SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar; 73203dd6f57SAdrian Prantl // Set of DbgVariables in Result. 73303dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visited; 73403dd6f57SAdrian Prantl // For cycle detection. 73503dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visiting; 73603dd6f57SAdrian Prantl 73703dd6f57SAdrian Prantl // Initialize the worklist and the DIVariable lookup table. 73803dd6f57SAdrian Prantl for (auto Var : reverse(Input)) { 73903dd6f57SAdrian Prantl DbgVar.insert({Var->getVariable(), Var}); 74003dd6f57SAdrian Prantl WorkList.push_back({Var, 0}); 74103dd6f57SAdrian Prantl } 74203dd6f57SAdrian Prantl 74303dd6f57SAdrian Prantl // Perform a stable topological sort by doing a DFS. 74403dd6f57SAdrian Prantl while (!WorkList.empty()) { 74503dd6f57SAdrian Prantl auto Item = WorkList.back(); 74603dd6f57SAdrian Prantl DbgVariable *Var = Item.getPointer(); 74703dd6f57SAdrian Prantl bool visitedAllDependencies = Item.getInt(); 74803dd6f57SAdrian Prantl WorkList.pop_back(); 74903dd6f57SAdrian Prantl 75003dd6f57SAdrian Prantl // Dependency is in a different lexical scope or a global. 75103dd6f57SAdrian Prantl if (!Var) 75203dd6f57SAdrian Prantl continue; 75303dd6f57SAdrian Prantl 75403dd6f57SAdrian Prantl // Already handled. 75503dd6f57SAdrian Prantl if (Visited.count(Var)) 75603dd6f57SAdrian Prantl continue; 75703dd6f57SAdrian Prantl 75803dd6f57SAdrian Prantl // Add to Result if all dependencies are visited. 75903dd6f57SAdrian Prantl if (visitedAllDependencies) { 76003dd6f57SAdrian Prantl Visited.insert(Var); 76103dd6f57SAdrian Prantl Result.push_back(Var); 76203dd6f57SAdrian Prantl continue; 76303dd6f57SAdrian Prantl } 76403dd6f57SAdrian Prantl 76503dd6f57SAdrian Prantl // Detect cycles. 76603dd6f57SAdrian Prantl auto Res = Visiting.insert(Var); 76703dd6f57SAdrian Prantl if (!Res.second) { 76803dd6f57SAdrian Prantl assert(false && "dependency cycle in local variables"); 76903dd6f57SAdrian Prantl return Result; 77003dd6f57SAdrian Prantl } 77103dd6f57SAdrian Prantl 77203dd6f57SAdrian Prantl // Push dependencies and this node onto the worklist, so that this node is 77303dd6f57SAdrian Prantl // visited again after all of its dependencies are handled. 77403dd6f57SAdrian Prantl WorkList.push_back({Var, 1}); 77503dd6f57SAdrian Prantl for (auto *Dependency : dependencies(Var)) { 77603dd6f57SAdrian Prantl auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency); 77703dd6f57SAdrian Prantl WorkList.push_back({DbgVar[Dep], 0}); 77803dd6f57SAdrian Prantl } 77903dd6f57SAdrian Prantl } 78003dd6f57SAdrian Prantl return Result; 781c929f7adSAdrian Prantl } 782c929f7adSAdrian Prantl 783827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, 784827200c8SDuncan P. N. Exon Smith SmallVectorImpl<DIE *> &Children, 7852195e136SDavid Blaikie bool *HasNonScopeChildren) { 7862195e136SDavid Blaikie assert(Children.empty()); 7878b2fdb83SDavid Blaikie DIE *ObjectPointer = nullptr; 7888b2fdb83SDavid Blaikie 789c929f7adSAdrian Prantl // Emit function arguments (order is significant). 790c929f7adSAdrian Prantl auto Vars = DU->getScopeVariables().lookup(Scope); 791c929f7adSAdrian Prantl for (auto &DV : Vars.Args) 792c929f7adSAdrian Prantl Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); 793c929f7adSAdrian Prantl 794c929f7adSAdrian Prantl // Emit local variables. 79503dd6f57SAdrian Prantl auto Locals = sortLocalVars(Vars.Locals); 79603dd6f57SAdrian Prantl for (DbgVariable *DV : Locals) 7978b2fdb83SDavid Blaikie Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); 7988b2fdb83SDavid Blaikie 7992195e136SDavid Blaikie // Skip imported directives in gmlt-like data. 8002195e136SDavid Blaikie if (!includeMinimalInlineScopes()) { 8012195e136SDavid Blaikie // There is no need to emit empty lexical block DIE. 8022195e136SDavid Blaikie for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) 8032195e136SDavid Blaikie Children.push_back( 8042195e136SDavid Blaikie constructImportedEntityDIE(cast<DIImportedEntity>(IE))); 8052195e136SDavid Blaikie } 8062195e136SDavid Blaikie 8072195e136SDavid Blaikie if (HasNonScopeChildren) 8082195e136SDavid Blaikie *HasNonScopeChildren = !Children.empty(); 8098b2fdb83SDavid Blaikie 8102532ac88SHsiangkai Wang for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) 8112532ac88SHsiangkai Wang Children.push_back(constructLabelDIE(*DL, *Scope)); 8122532ac88SHsiangkai Wang 8138b2fdb83SDavid Blaikie for (LexicalScope *LS : Scope->getChildren()) 8148b2fdb83SDavid Blaikie constructScopeDIE(LS, Children); 8158b2fdb83SDavid Blaikie 8168b2fdb83SDavid Blaikie return ObjectPointer; 8178b2fdb83SDavid Blaikie } 8188b2fdb83SDavid Blaikie 8195931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, 8205931b4e5SVedant Kumar LexicalScope *Scope) { 8211d072348SDavid Blaikie DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); 8221d072348SDavid Blaikie 8233e3eb33eSDavid Blaikie if (Scope) { 8243e3eb33eSDavid Blaikie assert(!Scope->getInlinedAt()); 8253e3eb33eSDavid Blaikie assert(!Scope->isAbstractScope()); 8261dd573dbSDavid Blaikie // Collect lexical scope children first. 8271dd573dbSDavid Blaikie // ObjectPointer might be a local (non-argument) local variable if it's a 8281dd573dbSDavid Blaikie // block's synthetic this pointer. 8291dd573dbSDavid Blaikie if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) 8301dd573dbSDavid Blaikie addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); 8313e3eb33eSDavid Blaikie } 8323e3eb33eSDavid Blaikie 8333e3eb33eSDavid Blaikie // If this is a variadic function, add an unspecified parameter. 8343e3eb33eSDavid Blaikie DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); 8351dd573dbSDavid Blaikie 8361d072348SDavid Blaikie // If we have a single element of null, it is a function that returns void. 8371d072348SDavid Blaikie // If we have more than one elements and the last one is null, it is a 8381d072348SDavid Blaikie // variadic function. 839000fa2c6SDuncan P. N. Exon Smith if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && 8403a443c29SDavid Blaikie !includeMinimalInlineScopes()) 841827200c8SDuncan P. N. Exon Smith ScopeDIE.addChild( 842827200c8SDuncan P. N. Exon Smith DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); 8435931b4e5SVedant Kumar 8445931b4e5SVedant Kumar return ScopeDIE; 8451d072348SDavid Blaikie } 8461d072348SDavid Blaikie 84778b65b6fSDavid Blaikie DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, 84878b65b6fSDavid Blaikie DIE &ScopeDIE) { 84978b65b6fSDavid Blaikie // We create children when the scope DIE is not null. 850827200c8SDuncan P. N. Exon Smith SmallVector<DIE *, 8> Children; 85178b65b6fSDavid Blaikie DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); 85278b65b6fSDavid Blaikie 85378b65b6fSDavid Blaikie // Add children 85478b65b6fSDavid Blaikie for (auto &I : Children) 85578b65b6fSDavid Blaikie ScopeDIE.addChild(std::move(I)); 85678b65b6fSDavid Blaikie 85778b65b6fSDavid Blaikie return ObjectPointer; 85878b65b6fSDavid Blaikie } 85978b65b6fSDavid Blaikie 86054511353SDehao Chen void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( 86154511353SDehao Chen LexicalScope *Scope) { 862488393f8SDavid Blaikie DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()]; 86349be5b35SDavid Blaikie if (AbsDef) 86449be5b35SDavid Blaikie return; 86549be5b35SDavid Blaikie 866a9308c49SDuncan P. N. Exon Smith auto *SP = cast<DISubprogram>(Scope->getScopeNode()); 86758410f24SDavid Blaikie 86858410f24SDavid Blaikie DIE *ContextDIE; 869294e6895SJonas Devlieghere DwarfCompileUnit *ContextCU = this; 87058410f24SDavid Blaikie 8713a443c29SDavid Blaikie if (includeMinimalInlineScopes()) 8723a443c29SDavid Blaikie ContextDIE = &getUnitDie(); 87358410f24SDavid Blaikie // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 8747c60f20eSDuncan P. N. Exon Smith // the important distinction that the debug node is not associated with the 8757c60f20eSDuncan P. N. Exon Smith // DIE (since the debug node will be associated with the concrete DIE, if 87658410f24SDavid Blaikie // any). It could be refactored to some common utility function. 877537b4a81SDuncan P. N. Exon Smith else if (auto *SPDecl = SP->getDeclaration()) { 87858410f24SDavid Blaikie ContextDIE = &getUnitDie(); 87958410f24SDavid Blaikie getOrCreateSubprogramDIE(SPDecl); 880294e6895SJonas Devlieghere } else { 881*da82ce99SFangrui Song ContextDIE = getOrCreateContextDIE(SP->getScope()); 882294e6895SJonas Devlieghere // The scope may be shared with a subprogram that has already been 883294e6895SJonas Devlieghere // constructed in another CU, in which case we need to construct this 884294e6895SJonas Devlieghere // subprogram in the same CU. 885294e6895SJonas Devlieghere ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); 886294e6895SJonas Devlieghere } 88758410f24SDavid Blaikie 8887c60f20eSDuncan P. N. Exon Smith // Passing null as the associated node because the abstract definition 88958410f24SDavid Blaikie // shouldn't be found by lookup. 890294e6895SJonas Devlieghere AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); 891294e6895SJonas Devlieghere ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); 89258410f24SDavid Blaikie 893294e6895SJonas Devlieghere if (!ContextCU->includeMinimalInlineScopes()) 894294e6895SJonas Devlieghere ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); 895294e6895SJonas Devlieghere if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) 896294e6895SJonas Devlieghere ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); 89758410f24SDavid Blaikie } 89858410f24SDavid Blaikie 8995931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE, 9005931b4e5SVedant Kumar const DISubprogram &CalleeSP, 9015931b4e5SVedant Kumar bool IsTail, 90274533bd3SVedant Kumar const MCExpr *PCOffset) { 9035931b4e5SVedant Kumar // Insert a call site entry DIE within ScopeDIE. 9045931b4e5SVedant Kumar DIE &CallSiteDIE = 9055931b4e5SVedant Kumar createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr); 9065931b4e5SVedant Kumar 9075931b4e5SVedant Kumar // For the purposes of showing tail call frames in backtraces, a key piece of 9085931b4e5SVedant Kumar // information is DW_AT_call_origin, a pointer to the callee DIE. 9095931b4e5SVedant Kumar DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP); 9105931b4e5SVedant Kumar assert(CalleeDIE && "Could not create DIE for call site entry origin"); 9115931b4e5SVedant Kumar addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE); 9125931b4e5SVedant Kumar 9135931b4e5SVedant Kumar if (IsTail) { 9145931b4e5SVedant Kumar // Attach DW_AT_call_tail_call to tail calls for standards compliance. 9155931b4e5SVedant Kumar addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call); 9165931b4e5SVedant Kumar } else { 9175931b4e5SVedant Kumar // Attach the return PC to allow the debugger to disambiguate call paths 9185931b4e5SVedant Kumar // from one function to another. 91974533bd3SVedant Kumar assert(PCOffset && "Missing return PC information for a call"); 92074533bd3SVedant Kumar addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset); 9215931b4e5SVedant Kumar } 9225931b4e5SVedant Kumar return CallSiteDIE; 9235931b4e5SVedant Kumar } 9245931b4e5SVedant Kumar 925827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructImportedEntityDIE( 926827200c8SDuncan P. N. Exon Smith const DIImportedEntity *Module) { 92772da9391SAmjad Aboud DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); 92872da9391SAmjad Aboud insertDIE(Module, IMDie); 929987fe227SFrederic Riss DIE *EntityDie; 930*da82ce99SFangrui Song auto *Entity = Module->getEntity(); 931a9308c49SDuncan P. N. Exon Smith if (auto *NS = dyn_cast<DINamespace>(Entity)) 932e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateNameSpace(NS); 93308a388baSAdrian Prantl else if (auto *M = dyn_cast<DIModule>(Entity)) 93408a388baSAdrian Prantl EntityDie = getOrCreateModule(M); 935a9308c49SDuncan P. N. Exon Smith else if (auto *SP = dyn_cast<DISubprogram>(Entity)) 936e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateSubprogramDIE(SP); 937a9308c49SDuncan P. N. Exon Smith else if (auto *T = dyn_cast<DIType>(Entity)) 938e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateTypeDIE(T); 939a9308c49SDuncan P. N. Exon Smith else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) 940bceaaa96SAdrian Prantl EntityDie = getOrCreateGlobalVariableDIE(GV, {}); 941987fe227SFrederic Riss else 942987fe227SFrederic Riss EntityDie = getDIE(Entity); 943987fe227SFrederic Riss assert(EntityDie); 944612e89d7SPaul Robinson addSourceLine(*IMDie, Module->getLine(), Module->getFile()); 945987fe227SFrederic Riss addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); 946de8e4273SDuncan P. N. Exon Smith StringRef Name = Module->getName(); 947987fe227SFrederic Riss if (!Name.empty()) 948987fe227SFrederic Riss addString(*IMDie, dwarf::DW_AT_name, Name); 949987fe227SFrederic Riss 950987fe227SFrederic Riss return IMDie; 951987fe227SFrederic Riss } 952987fe227SFrederic Riss 953a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { 95472da9391SAmjad Aboud DIE *D = getDIE(SP); 955488393f8SDavid Blaikie if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) { 95672da9391SAmjad Aboud if (D) 9574191cbceSDavid Blaikie // If this subprogram has an abstract definition, reference that 9584191cbceSDavid Blaikie addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); 95972da9391SAmjad Aboud } else { 9603e3eb33eSDavid Blaikie assert(D || includeMinimalInlineScopes()); 96172da9391SAmjad Aboud if (D) 9624191cbceSDavid Blaikie // And attach the attributes 9634191cbceSDavid Blaikie applySubprogramAttributesToDefinition(SP, *D); 9644191cbceSDavid Blaikie } 9654191cbceSDavid Blaikie } 9664191cbceSDavid Blaikie 9672532ac88SHsiangkai Wang void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { 9682532ac88SHsiangkai Wang DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); 9692532ac88SHsiangkai Wang 9702532ac88SHsiangkai Wang auto *Die = Entity->getDIE(); 9712532ac88SHsiangkai Wang /// Label may be used to generate DW_AT_low_pc, so put it outside 9722532ac88SHsiangkai Wang /// if/else block. 9732532ac88SHsiangkai Wang const DbgLabel *Label = nullptr; 9742532ac88SHsiangkai Wang if (AbsEntity && AbsEntity->getDIE()) { 9752532ac88SHsiangkai Wang addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); 9762532ac88SHsiangkai Wang Label = dyn_cast<const DbgLabel>(Entity); 9772532ac88SHsiangkai Wang } else { 9782532ac88SHsiangkai Wang if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) 9792532ac88SHsiangkai Wang applyVariableAttributes(*Var, *Die); 9802532ac88SHsiangkai Wang else if ((Label = dyn_cast<const DbgLabel>(Entity))) 9812532ac88SHsiangkai Wang applyLabelAttributes(*Label, *Die); 9822532ac88SHsiangkai Wang else 9832532ac88SHsiangkai Wang llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); 984488393f8SDavid Blaikie } 985488393f8SDavid Blaikie 98655321d82SHsiangkai Wang if (Label) 98755321d82SHsiangkai Wang if (const auto *Sym = Label->getSymbol()) 9882532ac88SHsiangkai Wang addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); 9892532ac88SHsiangkai Wang } 990488393f8SDavid Blaikie 9912532ac88SHsiangkai Wang DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { 9922532ac88SHsiangkai Wang auto &AbstractEntities = getAbstractEntities(); 9932532ac88SHsiangkai Wang auto I = AbstractEntities.find(Node); 9942532ac88SHsiangkai Wang if (I != AbstractEntities.end()) 995488393f8SDavid Blaikie return I->second.get(); 996488393f8SDavid Blaikie return nullptr; 997488393f8SDavid Blaikie } 998488393f8SDavid Blaikie 9992532ac88SHsiangkai Wang void DwarfCompileUnit::createAbstractEntity(const DINode *Node, 1000488393f8SDavid Blaikie LexicalScope *Scope) { 1001488393f8SDavid Blaikie assert(Scope && Scope->isAbstractScope()); 10022532ac88SHsiangkai Wang auto &Entity = getAbstractEntities()[Node]; 10032532ac88SHsiangkai Wang if (isa<const DILocalVariable>(Node)) { 10042532ac88SHsiangkai Wang Entity = llvm::make_unique<DbgVariable>( 10052532ac88SHsiangkai Wang cast<const DILocalVariable>(Node), nullptr /* IA */);; 10062532ac88SHsiangkai Wang DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); 10072532ac88SHsiangkai Wang } else if (isa<const DILabel>(Node)) { 10082532ac88SHsiangkai Wang Entity = llvm::make_unique<DbgLabel>( 10092532ac88SHsiangkai Wang cast<const DILabel>(Node), nullptr /* IA */); 10102532ac88SHsiangkai Wang DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); 10112532ac88SHsiangkai Wang } 1012488393f8SDavid Blaikie } 1013488393f8SDavid Blaikie 1014063d725fSRafael Espindola void DwarfCompileUnit::emitHeader(bool UseOffsets) { 1015b6726a9eSDavid Blaikie // Don't bother labeling the .dwo unit, as its offset isn't used. 1016bff36086SAlexey Bataev if (!Skeleton && !DD->useSectionsAsReferences()) { 10179ab09237SRafael Espindola LabelBegin = Asm->createTempSymbol("cu_begin"); 10189ff69c8fSLang Hames Asm->OutStreamer->EmitLabel(LabelBegin); 10193c311148SRafael Espindola } 1020ae57e66eSDavid Blaikie 1021cddd6044SPaul Robinson dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile 1022cddd6044SPaul Robinson : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton 1023cddd6044SPaul Robinson : dwarf::DW_UT_compile; 1024cddd6044SPaul Robinson DwarfUnit::emitCommonHeader(UseOffsets, UT); 1025543c0e1dSPaul Robinson if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) 1026543c0e1dSPaul Robinson Asm->emitInt64(getDWOId()); 1027ae57e66eSDavid Blaikie } 1028ae57e66eSDavid Blaikie 1029b52e2366SPeter Collingbourne bool DwarfCompileUnit::hasDwarfPubSections() const { 103066cf14d0SDavid Blaikie switch (CUNode->getNameTableKind()) { 103166cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::None: 103266cf14d0SDavid Blaikie return false; 1033b52e2366SPeter Collingbourne // Opting in to GNU Pubnames/types overrides the default to ensure these are 1034b52e2366SPeter Collingbourne // generated for things like Gold's gdb_index generation. 103566cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::GNU: 1036b52e2366SPeter Collingbourne return true; 103766cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::Default: 10380e03047eSDavid Blaikie return DD->tuneForGDB() && !includeMinimalInlineScopes() && 10392f511762SDavid Blaikie !CUNode->isDebugDirectivesOnly() && 10402f511762SDavid Blaikie DD->getAccelTableKind() != AccelTableKind::Apple && 10412f511762SDavid Blaikie DD->getDwarfVersion() < 5; 1042b52e2366SPeter Collingbourne } 104322d580f2SSimon Pilgrim llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum"); 104466cf14d0SDavid Blaikie } 1045b52e2366SPeter Collingbourne 1046192b45c1SDavid Blaikie /// addGlobalName - Add a new global name to the compile unit. 1047a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, 1048a9308c49SDuncan P. N. Exon Smith const DIScope *Context) { 1049b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 1050192b45c1SDavid Blaikie return; 1051192b45c1SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str(); 1052192b45c1SDavid Blaikie GlobalNames[FullName] = &Die; 1053192b45c1SDavid Blaikie } 1054192b45c1SDavid Blaikie 1055a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, 1056a0e3c751SDavid Blaikie const DIScope *Context) { 1057b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 1058a0e3c751SDavid Blaikie return; 1059a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str(); 1060a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present 1061a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this 1062a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only 1063a0e3c751SDavid Blaikie // in a type unit" 1064a0e3c751SDavid Blaikie GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie())); 1065a0e3c751SDavid Blaikie } 1066a0e3c751SDavid Blaikie 1067192b45c1SDavid Blaikie /// Add a new global type to the unit. 1068a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, 1069a9308c49SDuncan P. N. Exon Smith const DIScope *Context) { 1070b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 1071192b45c1SDavid Blaikie return; 1072b1055640SDuncan P. N. Exon Smith std::string FullName = getParentContextString(Context) + Ty->getName().str(); 1073192b45c1SDavid Blaikie GlobalTypes[FullName] = &Die; 1074192b45c1SDavid Blaikie } 1075ae57e66eSDavid Blaikie 1076a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, 1077a0e3c751SDavid Blaikie const DIScope *Context) { 1078b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 1079a0e3c751SDavid Blaikie return; 1080a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Ty->getName().str(); 1081a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present 1082a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this 1083a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only 1084a0e3c751SDavid Blaikie // in a type unit" 1085a0e3c751SDavid Blaikie GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie())); 1086a0e3c751SDavid Blaikie } 1087a0e3c751SDavid Blaikie 10887d48be2bSDavid Blaikie /// addVariableAddress - Add DW_AT_location attribute for a 10897d48be2bSDavid Blaikie /// DbgVariable based on provided MachineLocation. 10907d48be2bSDavid Blaikie void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, 10917d48be2bSDavid Blaikie MachineLocation Location) { 1092a2f9e3a6SAdrian Prantl // addBlockByrefAddress is obsolete and will be removed soon. 1093a2f9e3a6SAdrian Prantl // The clang frontend always generates block byref variables with a 1094a2f9e3a6SAdrian Prantl // complex expression that encodes exactly what addBlockByrefAddress 1095a2f9e3a6SAdrian Prantl // would do. 1096a2f9e3a6SAdrian Prantl assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) && 1097a2f9e3a6SAdrian Prantl "block byref variable without a complex expression"); 1098e6cc531bSDuncan P. N. Exon Smith if (DV.hasComplexAddress()) 10997d48be2bSDavid Blaikie addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); 11007d48be2bSDavid Blaikie else 11015883af3fSAdrian Prantl addAddress(Die, dwarf::DW_AT_location, Location); 11027d48be2bSDavid Blaikie } 1103f7435ee6SDavid Blaikie 1104f7435ee6SDavid Blaikie /// Add an address attribute to a die based on the location provided. 1105f7435ee6SDavid Blaikie void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, 11065883af3fSAdrian Prantl const MachineLocation &Location) { 1107e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1108956484b7SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1109c12cee36SAdrian Prantl if (Location.isIndirect()) 1110c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 1111f7435ee6SDavid Blaikie 11122049c0d7SAdrian Prantl DIExpressionCursor Cursor({}); 1113956484b7SAdrian Prantl const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1114c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 1115ab255fcdSAdrian Prantl return; 1116956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 1117ab255fcdSAdrian Prantl 1118f7435ee6SDavid Blaikie // Now attach the location information to the DIE. 1119956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize()); 1120f7435ee6SDavid Blaikie } 112177895fb2SDavid Blaikie 112277895fb2SDavid Blaikie /// Start with the address based on the location provided, and generate the 112377895fb2SDavid Blaikie /// DWARF information necessary to find the actual variable given the extra 112477895fb2SDavid Blaikie /// address information encoded in the DbgVariable, starting from the starting 112577895fb2SDavid Blaikie /// location. Add the DWARF information to the die. 112677895fb2SDavid Blaikie void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, 112777895fb2SDavid Blaikie dwarf::Attribute Attribute, 112877895fb2SDavid Blaikie const MachineLocation &Location) { 1129e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 11307813d9c9SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1131956484b7SAdrian Prantl const DIExpression *DIExpr = DV.getSingleExpression(); 1132956484b7SAdrian Prantl DwarfExpr.addFragmentOffset(DIExpr); 1133c12cee36SAdrian Prantl if (Location.isIndirect()) 1134c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 1135956484b7SAdrian Prantl 11362049c0d7SAdrian Prantl DIExpressionCursor Cursor(DIExpr); 113796c9ae6aSPeter Collingbourne const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1138c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 113954286bdaSAdrian Prantl return; 1140956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 114177895fb2SDavid Blaikie 114277895fb2SDavid Blaikie // Now attach the location information to the DIE. 1143956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize()); 114477895fb2SDavid Blaikie } 11454bc0881aSDavid Blaikie 11464bc0881aSDavid Blaikie /// Add a Dwarf loclistptr attribute data and value. 11474bc0881aSDavid Blaikie void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, 11484bc0881aSDavid Blaikie unsigned Index) { 11494bc0881aSDavid Blaikie dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset 11504bc0881aSDavid Blaikie : dwarf::DW_FORM_data4; 11514fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index)); 11524bc0881aSDavid Blaikie } 115302a6333bSDavid Blaikie 11548c485b5dSDavid Blaikie void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, 115502a6333bSDavid Blaikie DIE &VariableDie) { 115602a6333bSDavid Blaikie StringRef Name = Var.getName(); 115702a6333bSDavid Blaikie if (!Name.empty()) 115802a6333bSDavid Blaikie addString(VariableDie, dwarf::DW_AT_name, Name); 11593c989984SVictor Leschuk const auto *DIVar = Var.getVariable(); 11603c989984SVictor Leschuk if (DIVar) 11613c989984SVictor Leschuk if (uint32_t AlignInBytes = DIVar->getAlignInBytes()) 11623c989984SVictor Leschuk addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 11633c989984SVictor Leschuk AlignInBytes); 11643c989984SVictor Leschuk 11653c989984SVictor Leschuk addSourceLine(VariableDie, DIVar); 116602a6333bSDavid Blaikie addType(VariableDie, Var.getType()); 116702a6333bSDavid Blaikie if (Var.isArtificial()) 116802a6333bSDavid Blaikie addFlag(VariableDie, dwarf::DW_AT_artificial); 116902a6333bSDavid Blaikie } 117097802080SDavid Blaikie 11712532ac88SHsiangkai Wang void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, 11722532ac88SHsiangkai Wang DIE &LabelDie) { 11732532ac88SHsiangkai Wang StringRef Name = Label.getName(); 11742532ac88SHsiangkai Wang if (!Name.empty()) 11752532ac88SHsiangkai Wang addString(LabelDie, dwarf::DW_AT_name, Name); 11762532ac88SHsiangkai Wang const auto *DILabel = Label.getLabel(); 11772532ac88SHsiangkai Wang addSourceLine(LabelDie, DILabel); 11782532ac88SHsiangkai Wang } 11792532ac88SHsiangkai Wang 118097802080SDavid Blaikie /// Add a Dwarf expression attribute data and value. 118197802080SDavid Blaikie void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, 118297802080SDavid Blaikie const MCExpr *Expr) { 11834fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr)); 118497802080SDavid Blaikie } 11853363a57cSDavid Blaikie 118674533bd3SVedant Kumar void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute, 118774533bd3SVedant Kumar const MCExpr *Expr) { 118874533bd3SVedant Kumar Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 118974533bd3SVedant Kumar DIEExpr(Expr)); 119074533bd3SVedant Kumar } 119174533bd3SVedant Kumar 11922fbe1354SDuncan P. N. Exon Smith void DwarfCompileUnit::applySubprogramAttributesToDefinition( 1193a9308c49SDuncan P. N. Exon Smith const DISubprogram *SP, DIE &SPDie) { 1194537b4a81SDuncan P. N. Exon Smith auto *SPDecl = SP->getDeclaration(); 1195*da82ce99SFangrui Song auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope(); 11963a443c29SDavid Blaikie applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); 1197537b4a81SDuncan P. N. Exon Smith addGlobalName(SP->getName(), SPDie, Context); 11983363a57cSDavid Blaikie } 1199cafd962dSDavid Blaikie 1200cafd962dSDavid Blaikie bool DwarfCompileUnit::isDwoUnit() const { 1201cafd962dSDavid Blaikie return DD->useSplitDwarf() && Skeleton; 1202cafd962dSDavid Blaikie } 12033a443c29SDavid Blaikie 1204832c7d9fSDavid Blaikie void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { 1205832c7d9fSDavid Blaikie constructTypeDIE(D, CTy); 1206832c7d9fSDavid Blaikie } 1207832c7d9fSDavid Blaikie 12083a443c29SDavid Blaikie bool DwarfCompileUnit::includeMinimalInlineScopes() const { 1209b939a257SAdrian Prantl return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || 12103a443c29SDavid Blaikie (DD->useSplitDwarf() && !Skeleton); 12113a443c29SDavid Blaikie } 121261c127c1SDavid Blaikie 121361c127c1SDavid Blaikie void DwarfCompileUnit::addAddrTableBase() { 121461c127c1SDavid Blaikie const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 121561c127c1SDavid Blaikie MCSymbol *Label = DD->getAddressPool().getLabel(); 121661c127c1SDavid Blaikie addSectionLabel(getUnitDie(), 121761c127c1SDavid Blaikie getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base 121861c127c1SDavid Blaikie : dwarf::DW_AT_GNU_addr_base, 121961c127c1SDavid Blaikie Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); 122061c127c1SDavid Blaikie } 1221b86ce219SMarkus Lavin 1222b86ce219SMarkus Lavin void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { 1223b86ce219SMarkus Lavin Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata, 1224b86ce219SMarkus Lavin new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); 1225b86ce219SMarkus Lavin } 1226b86ce219SMarkus Lavin 1227b86ce219SMarkus Lavin void DwarfCompileUnit::createBaseTypeDIEs() { 1228b86ce219SMarkus Lavin // Insert the base_type DIEs directly after the CU so that their offsets will 1229b86ce219SMarkus Lavin // fit in the fixed size ULEB128 used inside the location expressions. 1230b86ce219SMarkus Lavin // Maintain order by iterating backwards and inserting to the front of CU 1231b86ce219SMarkus Lavin // child list. 1232b86ce219SMarkus Lavin for (auto &Btr : reverse(ExprRefedBaseTypes)) { 1233b86ce219SMarkus Lavin DIE &Die = getUnitDie().addChildFront( 1234b86ce219SMarkus Lavin DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type)); 1235b86ce219SMarkus Lavin SmallString<32> Str; 1236b86ce219SMarkus Lavin addString(Die, dwarf::DW_AT_name, 1237b86ce219SMarkus Lavin Twine(dwarf::AttributeEncodingString(Btr.Encoding) + 1238b86ce219SMarkus Lavin "_" + Twine(Btr.BitSize)).toStringRef(Str)); 1239b86ce219SMarkus Lavin addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding); 1240b86ce219SMarkus Lavin addUInt(Die, dwarf::DW_AT_byte_size, None, Btr.BitSize / 8); 1241b86ce219SMarkus Lavin 1242b86ce219SMarkus Lavin Btr.Die = &Die; 1243b86ce219SMarkus Lavin } 1244b86ce219SMarkus Lavin } 1245