1*0b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains support for constructing a dwarf compile unit. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "DwarfCompileUnit.h" 14*0b57cec5SDimitry Andric #include "AddressPool.h" 15*0b57cec5SDimitry Andric #include "DwarfDebug.h" 16*0b57cec5SDimitry Andric #include "DwarfExpression.h" 17*0b57cec5SDimitry Andric #include "DwarfUnit.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/None.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 20*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 21*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 22*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 23*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 24*0b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 25*0b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h" 26*0b57cec5SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h" 27*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 28*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 30*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 31*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 32*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 33*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 35*0b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 36*0b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 37*0b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 38*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 39*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 40*0b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 41*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 42*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 43*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 44*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 45*0b57cec5SDimitry Andric #include <algorithm> 46*0b57cec5SDimitry Andric #include <cassert> 47*0b57cec5SDimitry Andric #include <cstdint> 48*0b57cec5SDimitry Andric #include <iterator> 49*0b57cec5SDimitry Andric #include <memory> 50*0b57cec5SDimitry Andric #include <string> 51*0b57cec5SDimitry Andric #include <utility> 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric using namespace llvm; 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, 56*0b57cec5SDimitry Andric AsmPrinter *A, DwarfDebug *DW, 57*0b57cec5SDimitry Andric DwarfFile *DWU) 58*0b57cec5SDimitry Andric : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) { 59*0b57cec5SDimitry Andric insertDIE(Node, &getUnitDie()); 60*0b57cec5SDimitry Andric MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); 61*0b57cec5SDimitry Andric } 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric /// addLabelAddress - Add a dwarf label attribute data and value using 64*0b57cec5SDimitry Andric /// DW_FORM_addr or DW_FORM_GNU_addr_index. 65*0b57cec5SDimitry Andric void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, 66*0b57cec5SDimitry Andric const MCSymbol *Label) { 67*0b57cec5SDimitry Andric // Don't use the address pool in non-fission or in the skeleton unit itself. 68*0b57cec5SDimitry Andric // FIXME: Once GDB supports this, it's probably worthwhile using the address 69*0b57cec5SDimitry Andric // pool from the skeleton - maybe even in non-fission (possibly fewer 70*0b57cec5SDimitry Andric // relocations by sharing them in the pool, but we have other ideas about how 71*0b57cec5SDimitry Andric // to reduce the number of relocations as well/instead). 72*0b57cec5SDimitry Andric if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) 73*0b57cec5SDimitry Andric return addLocalLabelAddress(Die, Attribute, Label); 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric if (Label) 76*0b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label)); 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric unsigned idx = DD->getAddressPool().getIndex(Label); 79*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, 80*0b57cec5SDimitry Andric DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx 81*0b57cec5SDimitry Andric : dwarf::DW_FORM_GNU_addr_index, 82*0b57cec5SDimitry Andric DIEInteger(idx)); 83*0b57cec5SDimitry Andric } 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, 86*0b57cec5SDimitry Andric dwarf::Attribute Attribute, 87*0b57cec5SDimitry Andric const MCSymbol *Label) { 88*0b57cec5SDimitry Andric if (Label) 89*0b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label)); 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric if (Label) 92*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 93*0b57cec5SDimitry Andric DIELabel(Label)); 94*0b57cec5SDimitry Andric else 95*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 96*0b57cec5SDimitry Andric DIEInteger(0)); 97*0b57cec5SDimitry Andric } 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { 100*0b57cec5SDimitry Andric // If we print assembly, we can't separate .file entries according to 101*0b57cec5SDimitry Andric // compile units. Thus all files will belong to the default compile unit. 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric // FIXME: add a better feature test than hasRawTextSupport. Even better, 104*0b57cec5SDimitry Andric // extend .file to support this. 105*0b57cec5SDimitry Andric unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); 106*0b57cec5SDimitry Andric if (!File) 107*0b57cec5SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", None, None, CUID); 108*0b57cec5SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective( 109*0b57cec5SDimitry Andric 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), 110*0b57cec5SDimitry Andric File->getSource(), CUID); 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( 114*0b57cec5SDimitry Andric const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 115*0b57cec5SDimitry Andric // Check for pre-existence. 116*0b57cec5SDimitry Andric if (DIE *Die = getDIE(GV)) 117*0b57cec5SDimitry Andric return Die; 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric assert(GV); 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric auto *GVContext = GV->getScope(); 122*0b57cec5SDimitry Andric const DIType *GTy = GV->getType(); 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in 125*0b57cec5SDimitry Andric // case such construction creates the DIE. 126*0b57cec5SDimitry Andric auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr; 127*0b57cec5SDimitry Andric DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs) 128*0b57cec5SDimitry Andric : getOrCreateContextDIE(GVContext); 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric // Add to map. 131*0b57cec5SDimitry Andric DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV); 132*0b57cec5SDimitry Andric DIScope *DeclContext; 133*0b57cec5SDimitry Andric if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { 134*0b57cec5SDimitry Andric DeclContext = SDMDecl->getScope(); 135*0b57cec5SDimitry Andric assert(SDMDecl->isStaticMember() && "Expected static member decl"); 136*0b57cec5SDimitry Andric assert(GV->isDefinition()); 137*0b57cec5SDimitry Andric // We need the declaration DIE that is in the static member's class. 138*0b57cec5SDimitry Andric DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); 139*0b57cec5SDimitry Andric addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); 140*0b57cec5SDimitry Andric // If the global variable's type is different from the one in the class 141*0b57cec5SDimitry Andric // member type, assume that it's more specific and also emit it. 142*0b57cec5SDimitry Andric if (GTy != SDMDecl->getBaseType()) 143*0b57cec5SDimitry Andric addType(*VariableDIE, GTy); 144*0b57cec5SDimitry Andric } else { 145*0b57cec5SDimitry Andric DeclContext = GV->getScope(); 146*0b57cec5SDimitry Andric // Add name and type. 147*0b57cec5SDimitry Andric addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); 148*0b57cec5SDimitry Andric addType(*VariableDIE, GTy); 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric // Add scoping info. 151*0b57cec5SDimitry Andric if (!GV->isLocalToUnit()) 152*0b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_external); 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric // Add line number info. 155*0b57cec5SDimitry Andric addSourceLine(*VariableDIE, GV); 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric if (!GV->isDefinition()) 159*0b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_declaration); 160*0b57cec5SDimitry Andric else 161*0b57cec5SDimitry Andric addGlobalName(GV->getName(), *VariableDIE, DeclContext); 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric if (uint32_t AlignInBytes = GV->getAlignInBytes()) 164*0b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 165*0b57cec5SDimitry Andric AlignInBytes); 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric if (MDTuple *TP = GV->getTemplateParams()) 168*0b57cec5SDimitry Andric addTemplateParams(*VariableDIE, DINodeArray(TP)); 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric // Add location. 171*0b57cec5SDimitry Andric addLocationAttribute(VariableDIE, GV, GlobalExprs); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric return VariableDIE; 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric void DwarfCompileUnit::addLocationAttribute( 177*0b57cec5SDimitry Andric DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 178*0b57cec5SDimitry Andric bool addToAccelTable = false; 179*0b57cec5SDimitry Andric DIELoc *Loc = nullptr; 180*0b57cec5SDimitry Andric Optional<unsigned> NVPTXAddressSpace; 181*0b57cec5SDimitry Andric std::unique_ptr<DIEDwarfExpression> DwarfExpr; 182*0b57cec5SDimitry Andric for (const auto &GE : GlobalExprs) { 183*0b57cec5SDimitry Andric const GlobalVariable *Global = GE.Var; 184*0b57cec5SDimitry Andric const DIExpression *Expr = GE.Expr; 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric // For compatibility with DWARF 3 and earlier, 187*0b57cec5SDimitry Andric // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes 188*0b57cec5SDimitry Andric // DW_AT_const_value(X). 189*0b57cec5SDimitry Andric if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { 190*0b57cec5SDimitry Andric addToAccelTable = true; 191*0b57cec5SDimitry Andric addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); 192*0b57cec5SDimitry Andric break; 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric // We cannot describe the location of dllimport'd variables: the 196*0b57cec5SDimitry Andric // computation of their address requires loads from the IAT. 197*0b57cec5SDimitry Andric if (Global && Global->hasDLLImportStorageClass()) 198*0b57cec5SDimitry Andric continue; 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric // Nothing to describe without address or constant. 201*0b57cec5SDimitry Andric if (!Global && (!Expr || !Expr->isConstant())) 202*0b57cec5SDimitry Andric continue; 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric if (Global && Global->isThreadLocal() && 205*0b57cec5SDimitry Andric !Asm->getObjFileLowering().supportDebugThreadLocalLocation()) 206*0b57cec5SDimitry Andric continue; 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric if (!Loc) { 209*0b57cec5SDimitry Andric addToAccelTable = true; 210*0b57cec5SDimitry Andric Loc = new (DIEValueAllocator) DIELoc; 211*0b57cec5SDimitry Andric DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc); 212*0b57cec5SDimitry Andric } 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric if (Expr) { 215*0b57cec5SDimitry Andric // According to 216*0b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 217*0b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 218*0b57cec5SDimitry Andric // correctly interpret address space of the variable address. 219*0b57cec5SDimitry Andric // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 220*0b57cec5SDimitry Andric // sequence for the NVPTX + gdb target. 221*0b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 222*0b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 223*0b57cec5SDimitry Andric const DIExpression *NewExpr = 224*0b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 225*0b57cec5SDimitry Andric if (NewExpr != Expr) { 226*0b57cec5SDimitry Andric Expr = NewExpr; 227*0b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric } 230*0b57cec5SDimitry Andric DwarfExpr->addFragmentOffset(Expr); 231*0b57cec5SDimitry Andric } 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric if (Global) { 234*0b57cec5SDimitry Andric const MCSymbol *Sym = Asm->getSymbol(Global); 235*0b57cec5SDimitry Andric if (Global->isThreadLocal()) { 236*0b57cec5SDimitry Andric if (Asm->TM.useEmulatedTLS()) { 237*0b57cec5SDimitry Andric // TODO: add debug info for emulated thread local mode. 238*0b57cec5SDimitry Andric } else { 239*0b57cec5SDimitry Andric // FIXME: Make this work with -gsplit-dwarf. 240*0b57cec5SDimitry Andric unsigned PointerSize = Asm->getDataLayout().getPointerSize(); 241*0b57cec5SDimitry Andric assert((PointerSize == 4 || PointerSize == 8) && 242*0b57cec5SDimitry Andric "Add support for other sizes if necessary"); 243*0b57cec5SDimitry Andric // Based on GCC's support for TLS: 244*0b57cec5SDimitry Andric if (!DD->useSplitDwarf()) { 245*0b57cec5SDimitry Andric // 1) Start with a constNu of the appropriate pointer size 246*0b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, 247*0b57cec5SDimitry Andric PointerSize == 4 ? dwarf::DW_OP_const4u 248*0b57cec5SDimitry Andric : dwarf::DW_OP_const8u); 249*0b57cec5SDimitry Andric // 2) containing the (relocated) offset of the TLS variable 250*0b57cec5SDimitry Andric // within the module's TLS block. 251*0b57cec5SDimitry Andric addExpr(*Loc, dwarf::DW_FORM_udata, 252*0b57cec5SDimitry Andric Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); 253*0b57cec5SDimitry Andric } else { 254*0b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); 255*0b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_udata, 256*0b57cec5SDimitry Andric DD->getAddressPool().getIndex(Sym, /* TLS */ true)); 257*0b57cec5SDimitry Andric } 258*0b57cec5SDimitry Andric // 3) followed by an OP to make the debugger do a TLS lookup. 259*0b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, 260*0b57cec5SDimitry Andric DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address 261*0b57cec5SDimitry Andric : dwarf::DW_OP_form_tls_address); 262*0b57cec5SDimitry Andric } 263*0b57cec5SDimitry Andric } else { 264*0b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Sym)); 265*0b57cec5SDimitry Andric addOpAddress(*Loc, Sym); 266*0b57cec5SDimitry Andric } 267*0b57cec5SDimitry Andric } 268*0b57cec5SDimitry Andric // Global variables attached to symbols are memory locations. 269*0b57cec5SDimitry Andric // It would be better if this were unconditional, but malformed input that 270*0b57cec5SDimitry Andric // mixes non-fragments and fragments for the same variable is too expensive 271*0b57cec5SDimitry Andric // to detect in the verifier. 272*0b57cec5SDimitry Andric if (DwarfExpr->isUnknownLocation()) 273*0b57cec5SDimitry Andric DwarfExpr->setMemoryLocationKind(); 274*0b57cec5SDimitry Andric DwarfExpr->addExpression(Expr); 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 277*0b57cec5SDimitry Andric // According to 278*0b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 279*0b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 280*0b57cec5SDimitry Andric // correctly interpret address space of the variable address. 281*0b57cec5SDimitry Andric const unsigned NVPTX_ADDR_global_space = 5; 282*0b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 283*0b57cec5SDimitry Andric NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space); 284*0b57cec5SDimitry Andric } 285*0b57cec5SDimitry Andric if (Loc) 286*0b57cec5SDimitry Andric addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric if (DD->useAllLinkageNames()) 289*0b57cec5SDimitry Andric addLinkageName(*VariableDIE, GV->getLinkageName()); 290*0b57cec5SDimitry Andric 291*0b57cec5SDimitry Andric if (addToAccelTable) { 292*0b57cec5SDimitry Andric DD->addAccelName(*CUNode, GV->getName(), *VariableDIE); 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric // If the linkage name is different than the name, go ahead and output 295*0b57cec5SDimitry Andric // that as well into the name table. 296*0b57cec5SDimitry Andric if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() && 297*0b57cec5SDimitry Andric DD->useAllLinkageNames()) 298*0b57cec5SDimitry Andric DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE); 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric 302*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateCommonBlock( 303*0b57cec5SDimitry Andric const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) { 304*0b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 305*0b57cec5SDimitry Andric // such construction creates the DIE. 306*0b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(CB->getScope()); 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric if (DIE *NDie = getDIE(CB)) 309*0b57cec5SDimitry Andric return NDie; 310*0b57cec5SDimitry Andric DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB); 311*0b57cec5SDimitry Andric StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName(); 312*0b57cec5SDimitry Andric addString(NDie, dwarf::DW_AT_name, Name); 313*0b57cec5SDimitry Andric addGlobalName(Name, NDie, CB->getScope()); 314*0b57cec5SDimitry Andric if (CB->getFile()) 315*0b57cec5SDimitry Andric addSourceLine(NDie, CB->getLineNo(), CB->getFile()); 316*0b57cec5SDimitry Andric if (DIGlobalVariable *V = CB->getDecl()) 317*0b57cec5SDimitry Andric getCU().addLocationAttribute(&NDie, V, GlobalExprs); 318*0b57cec5SDimitry Andric return &NDie; 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric void DwarfCompileUnit::addRange(RangeSpan Range) { 322*0b57cec5SDimitry Andric bool SameAsPrevCU = this == DD->getPrevCU(); 323*0b57cec5SDimitry Andric DD->setPrevCU(this); 324*0b57cec5SDimitry Andric // If we have no current ranges just add the range and return, otherwise, 325*0b57cec5SDimitry Andric // check the current section and CU against the previous section and CU we 326*0b57cec5SDimitry Andric // emitted into and the subprogram was contained within. If these are the 327*0b57cec5SDimitry Andric // same then extend our current range, otherwise add this as a new range. 328*0b57cec5SDimitry Andric if (CURanges.empty() || !SameAsPrevCU || 329*0b57cec5SDimitry Andric (&CURanges.back().getEnd()->getSection() != 330*0b57cec5SDimitry Andric &Range.getEnd()->getSection())) { 331*0b57cec5SDimitry Andric CURanges.push_back(Range); 332*0b57cec5SDimitry Andric DD->addSectionLabel(Range.getStart()); 333*0b57cec5SDimitry Andric return; 334*0b57cec5SDimitry Andric } 335*0b57cec5SDimitry Andric 336*0b57cec5SDimitry Andric CURanges.back().setEnd(Range.getEnd()); 337*0b57cec5SDimitry Andric } 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric void DwarfCompileUnit::initStmtList() { 340*0b57cec5SDimitry Andric if (CUNode->isDebugDirectivesOnly()) 341*0b57cec5SDimitry Andric return; 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric // Define start line table label for each Compile Unit. 344*0b57cec5SDimitry Andric MCSymbol *LineTableStartSym; 345*0b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 346*0b57cec5SDimitry Andric if (DD->useSectionsAsReferences()) { 347*0b57cec5SDimitry Andric LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); 348*0b57cec5SDimitry Andric } else { 349*0b57cec5SDimitry Andric LineTableStartSym = 350*0b57cec5SDimitry Andric Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); 351*0b57cec5SDimitry Andric } 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andric // DW_AT_stmt_list is a offset of line number information for this 354*0b57cec5SDimitry Andric // compile unit in debug_line section. For split dwarf this is 355*0b57cec5SDimitry Andric // left in the skeleton CU and so not included. 356*0b57cec5SDimitry Andric // The line table entries are not always emitted in assembly, so it 357*0b57cec5SDimitry Andric // is not okay to use line_table_start here. 358*0b57cec5SDimitry Andric StmtListValue = 359*0b57cec5SDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, 360*0b57cec5SDimitry Andric TLOF.getDwarfLineSection()->getBeginSymbol()); 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric void DwarfCompileUnit::applyStmtList(DIE &D) { 364*0b57cec5SDimitry Andric D.addValue(DIEValueAllocator, *StmtListValue); 365*0b57cec5SDimitry Andric } 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 368*0b57cec5SDimitry Andric const MCSymbol *End) { 369*0b57cec5SDimitry Andric assert(Begin && "Begin label should not be null!"); 370*0b57cec5SDimitry Andric assert(End && "End label should not be null!"); 371*0b57cec5SDimitry Andric assert(Begin->isDefined() && "Invalid starting label"); 372*0b57cec5SDimitry Andric assert(End->isDefined() && "Invalid end label"); 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); 375*0b57cec5SDimitry Andric if (DD->getDwarfVersion() < 4) 376*0b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_high_pc, End); 377*0b57cec5SDimitry Andric else 378*0b57cec5SDimitry Andric addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); 379*0b57cec5SDimitry Andric } 380*0b57cec5SDimitry Andric 381*0b57cec5SDimitry Andric // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 382*0b57cec5SDimitry Andric // and DW_AT_high_pc attributes. If there are global variables in this 383*0b57cec5SDimitry Andric // scope then create and insert DIEs for these variables. 384*0b57cec5SDimitry Andric DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { 385*0b57cec5SDimitry Andric DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); 386*0b57cec5SDimitry Andric 387*0b57cec5SDimitry Andric attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd()); 388*0b57cec5SDimitry Andric if (DD->useAppleExtensionAttributes() && 389*0b57cec5SDimitry Andric !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( 390*0b57cec5SDimitry Andric *DD->getCurrentFunction())) 391*0b57cec5SDimitry Andric addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); 392*0b57cec5SDimitry Andric 393*0b57cec5SDimitry Andric // Only include DW_AT_frame_base in full debug info 394*0b57cec5SDimitry Andric if (!includeMinimalInlineScopes()) { 395*0b57cec5SDimitry Andric if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) { 396*0b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 397*0b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa); 398*0b57cec5SDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 399*0b57cec5SDimitry Andric } else { 400*0b57cec5SDimitry Andric const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo(); 401*0b57cec5SDimitry Andric MachineLocation Location(RI->getFrameRegister(*Asm->MF)); 402*0b57cec5SDimitry Andric if (RI->isPhysicalRegister(Location.getReg())) 403*0b57cec5SDimitry Andric addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); 404*0b57cec5SDimitry Andric } 405*0b57cec5SDimitry Andric } 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 408*0b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_subprogram nodes. 409*0b57cec5SDimitry Andric DD->addSubprogramNames(*CUNode, SP, *SPDie); 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric return *SPDie; 412*0b57cec5SDimitry Andric } 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric // Construct a DIE for this scope. 415*0b57cec5SDimitry Andric void DwarfCompileUnit::constructScopeDIE( 416*0b57cec5SDimitry Andric LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { 417*0b57cec5SDimitry Andric if (!Scope || !Scope->getScopeNode()) 418*0b57cec5SDimitry Andric return; 419*0b57cec5SDimitry Andric 420*0b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andric assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && 423*0b57cec5SDimitry Andric "Only handle inlined subprograms here, use " 424*0b57cec5SDimitry Andric "constructSubprogramScopeDIE for non-inlined " 425*0b57cec5SDimitry Andric "subprograms"); 426*0b57cec5SDimitry Andric 427*0b57cec5SDimitry Andric SmallVector<DIE *, 8> Children; 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric // We try to create the scope DIE first, then the children DIEs. This will 430*0b57cec5SDimitry Andric // avoid creating un-used children then removing them later when we find out 431*0b57cec5SDimitry Andric // the scope DIE is null. 432*0b57cec5SDimitry Andric DIE *ScopeDIE; 433*0b57cec5SDimitry Andric if (Scope->getParent() && isa<DISubprogram>(DS)) { 434*0b57cec5SDimitry Andric ScopeDIE = constructInlinedScopeDIE(Scope); 435*0b57cec5SDimitry Andric if (!ScopeDIE) 436*0b57cec5SDimitry Andric return; 437*0b57cec5SDimitry Andric // We create children when the scope DIE is not null. 438*0b57cec5SDimitry Andric createScopeChildrenDIE(Scope, Children); 439*0b57cec5SDimitry Andric } else { 440*0b57cec5SDimitry Andric // Early exit when we know the scope DIE is going to be null. 441*0b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 442*0b57cec5SDimitry Andric return; 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric bool HasNonScopeChildren = false; 445*0b57cec5SDimitry Andric 446*0b57cec5SDimitry Andric // We create children here when we know the scope DIE is not going to be 447*0b57cec5SDimitry Andric // null and the children will be added to the scope DIE. 448*0b57cec5SDimitry Andric createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric // If there are only other scopes as children, put them directly in the 451*0b57cec5SDimitry Andric // parent instead, as this scope would serve no purpose. 452*0b57cec5SDimitry Andric if (!HasNonScopeChildren) { 453*0b57cec5SDimitry Andric FinalChildren.insert(FinalChildren.end(), 454*0b57cec5SDimitry Andric std::make_move_iterator(Children.begin()), 455*0b57cec5SDimitry Andric std::make_move_iterator(Children.end())); 456*0b57cec5SDimitry Andric return; 457*0b57cec5SDimitry Andric } 458*0b57cec5SDimitry Andric ScopeDIE = constructLexicalScopeDIE(Scope); 459*0b57cec5SDimitry Andric assert(ScopeDIE && "Scope DIE should not be null."); 460*0b57cec5SDimitry Andric } 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric // Add children 463*0b57cec5SDimitry Andric for (auto &I : Children) 464*0b57cec5SDimitry Andric ScopeDIE->addChild(std::move(I)); 465*0b57cec5SDimitry Andric 466*0b57cec5SDimitry Andric FinalChildren.push_back(std::move(ScopeDIE)); 467*0b57cec5SDimitry Andric } 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, 470*0b57cec5SDimitry Andric SmallVector<RangeSpan, 2> Range) { 471*0b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable 474*0b57cec5SDimitry Andric // label. emitDIE() will handle emitting it appropriately. 475*0b57cec5SDimitry Andric const MCSymbol *RangeSectionSym = 476*0b57cec5SDimitry Andric DD->getDwarfVersion() >= 5 477*0b57cec5SDimitry Andric ? TLOF.getDwarfRnglistsSection()->getBeginSymbol() 478*0b57cec5SDimitry Andric : TLOF.getDwarfRangesSection()->getBeginSymbol(); 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric HasRangeLists = true; 481*0b57cec5SDimitry Andric 482*0b57cec5SDimitry Andric // Add the range list to the set of ranges to be emitted. 483*0b57cec5SDimitry Andric auto IndexAndList = 484*0b57cec5SDimitry Andric (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU) 485*0b57cec5SDimitry Andric ->addRange(*(Skeleton ? Skeleton : this), std::move(Range)); 486*0b57cec5SDimitry Andric 487*0b57cec5SDimitry Andric uint32_t Index = IndexAndList.first; 488*0b57cec5SDimitry Andric auto &List = *IndexAndList.second; 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andric // Under fission, ranges are specified by constant offsets relative to the 491*0b57cec5SDimitry Andric // CU's DW_AT_GNU_ranges_base. 492*0b57cec5SDimitry Andric // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 493*0b57cec5SDimitry Andric // fission until we support the forms using the .debug_addr section 494*0b57cec5SDimitry Andric // (DW_RLE_startx_endx etc.). 495*0b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) 496*0b57cec5SDimitry Andric addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index); 497*0b57cec5SDimitry Andric else if (isDwoUnit()) 498*0b57cec5SDimitry Andric addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 499*0b57cec5SDimitry Andric RangeSectionSym); 500*0b57cec5SDimitry Andric else 501*0b57cec5SDimitry Andric addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 502*0b57cec5SDimitry Andric RangeSectionSym); 503*0b57cec5SDimitry Andric } 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 506*0b57cec5SDimitry Andric DIE &Die, SmallVector<RangeSpan, 2> Ranges) { 507*0b57cec5SDimitry Andric if (Ranges.size() == 1 || !DD->useRangesSection()) { 508*0b57cec5SDimitry Andric const RangeSpan &Front = Ranges.front(); 509*0b57cec5SDimitry Andric const RangeSpan &Back = Ranges.back(); 510*0b57cec5SDimitry Andric attachLowHighPC(Die, Front.getStart(), Back.getEnd()); 511*0b57cec5SDimitry Andric } else 512*0b57cec5SDimitry Andric addScopeRangeList(Die, std::move(Ranges)); 513*0b57cec5SDimitry Andric } 514*0b57cec5SDimitry Andric 515*0b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 516*0b57cec5SDimitry Andric DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { 517*0b57cec5SDimitry Andric SmallVector<RangeSpan, 2> List; 518*0b57cec5SDimitry Andric List.reserve(Ranges.size()); 519*0b57cec5SDimitry Andric for (const InsnRange &R : Ranges) 520*0b57cec5SDimitry Andric List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), 521*0b57cec5SDimitry Andric DD->getLabelAfterInsn(R.second))); 522*0b57cec5SDimitry Andric attachRangesOrLowHighPC(Die, std::move(List)); 523*0b57cec5SDimitry Andric } 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric // This scope represents inlined body of a function. Construct DIE to 526*0b57cec5SDimitry Andric // represent this concrete inlined copy of the function. 527*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { 528*0b57cec5SDimitry Andric assert(Scope->getScopeNode()); 529*0b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 530*0b57cec5SDimitry Andric auto *InlinedSP = getDISubprogram(DS); 531*0b57cec5SDimitry Andric // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 532*0b57cec5SDimitry Andric // was inlined from another compile unit. 533*0b57cec5SDimitry Andric DIE *OriginDIE = getAbstractSPDies()[InlinedSP]; 534*0b57cec5SDimitry Andric assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); 535*0b57cec5SDimitry Andric 536*0b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); 537*0b57cec5SDimitry Andric addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); 538*0b57cec5SDimitry Andric 539*0b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 540*0b57cec5SDimitry Andric 541*0b57cec5SDimitry Andric // Add the call site information to the DIE. 542*0b57cec5SDimitry Andric const DILocation *IA = Scope->getInlinedAt(); 543*0b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, 544*0b57cec5SDimitry Andric getOrCreateSourceID(IA->getFile())); 545*0b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine()); 546*0b57cec5SDimitry Andric if (IA->getColumn()) 547*0b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_column, None, IA->getColumn()); 548*0b57cec5SDimitry Andric if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4) 549*0b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None, 550*0b57cec5SDimitry Andric IA->getDiscriminator()); 551*0b57cec5SDimitry Andric 552*0b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 553*0b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_inlined_subprogram nodes. 554*0b57cec5SDimitry Andric DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE); 555*0b57cec5SDimitry Andric 556*0b57cec5SDimitry Andric return ScopeDIE; 557*0b57cec5SDimitry Andric } 558*0b57cec5SDimitry Andric 559*0b57cec5SDimitry Andric // Construct new DW_TAG_lexical_block for this scope and attach 560*0b57cec5SDimitry Andric // DW_AT_low_pc/DW_AT_high_pc labels. 561*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { 562*0b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 563*0b57cec5SDimitry Andric return nullptr; 564*0b57cec5SDimitry Andric 565*0b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); 566*0b57cec5SDimitry Andric if (Scope->isAbstractScope()) 567*0b57cec5SDimitry Andric return ScopeDIE; 568*0b57cec5SDimitry Andric 569*0b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 570*0b57cec5SDimitry Andric 571*0b57cec5SDimitry Andric return ScopeDIE; 572*0b57cec5SDimitry Andric } 573*0b57cec5SDimitry Andric 574*0b57cec5SDimitry Andric /// constructVariableDIE - Construct a DIE for the given DbgVariable. 575*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { 576*0b57cec5SDimitry Andric auto D = constructVariableDIEImpl(DV, Abstract); 577*0b57cec5SDimitry Andric DV.setDIE(*D); 578*0b57cec5SDimitry Andric return D; 579*0b57cec5SDimitry Andric } 580*0b57cec5SDimitry Andric 581*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, 582*0b57cec5SDimitry Andric const LexicalScope &Scope) { 583*0b57cec5SDimitry Andric auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); 584*0b57cec5SDimitry Andric insertDIE(DL.getLabel(), LabelDie); 585*0b57cec5SDimitry Andric DL.setDIE(*LabelDie); 586*0b57cec5SDimitry Andric 587*0b57cec5SDimitry Andric if (Scope.isAbstractScope()) 588*0b57cec5SDimitry Andric applyLabelAttributes(DL, *LabelDie); 589*0b57cec5SDimitry Andric 590*0b57cec5SDimitry Andric return LabelDie; 591*0b57cec5SDimitry Andric } 592*0b57cec5SDimitry Andric 593*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, 594*0b57cec5SDimitry Andric bool Abstract) { 595*0b57cec5SDimitry Andric // Define variable debug information entry. 596*0b57cec5SDimitry Andric auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); 597*0b57cec5SDimitry Andric insertDIE(DV.getVariable(), VariableDie); 598*0b57cec5SDimitry Andric 599*0b57cec5SDimitry Andric if (Abstract) { 600*0b57cec5SDimitry Andric applyVariableAttributes(DV, *VariableDie); 601*0b57cec5SDimitry Andric return VariableDie; 602*0b57cec5SDimitry Andric } 603*0b57cec5SDimitry Andric 604*0b57cec5SDimitry Andric // Add variable address. 605*0b57cec5SDimitry Andric 606*0b57cec5SDimitry Andric unsigned Offset = DV.getDebugLocListIndex(); 607*0b57cec5SDimitry Andric if (Offset != ~0U) { 608*0b57cec5SDimitry Andric addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); 609*0b57cec5SDimitry Andric return VariableDie; 610*0b57cec5SDimitry Andric } 611*0b57cec5SDimitry Andric 612*0b57cec5SDimitry Andric // Check if variable has a single location description. 613*0b57cec5SDimitry Andric if (auto *DVal = DV.getValueLoc()) { 614*0b57cec5SDimitry Andric if (DVal->isLocation()) 615*0b57cec5SDimitry Andric addVariableAddress(DV, *VariableDie, DVal->getLoc()); 616*0b57cec5SDimitry Andric else if (DVal->isInt()) { 617*0b57cec5SDimitry Andric auto *Expr = DV.getSingleExpression(); 618*0b57cec5SDimitry Andric if (Expr && Expr->getNumElements()) { 619*0b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 620*0b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 621*0b57cec5SDimitry Andric // If there is an expression, emit raw unsigned bytes. 622*0b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 623*0b57cec5SDimitry Andric DwarfExpr.addUnsignedConstant(DVal->getInt()); 624*0b57cec5SDimitry Andric DwarfExpr.addExpression(Expr); 625*0b57cec5SDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 626*0b57cec5SDimitry Andric } else 627*0b57cec5SDimitry Andric addConstantValue(*VariableDie, DVal->getInt(), DV.getType()); 628*0b57cec5SDimitry Andric } else if (DVal->isConstantFP()) { 629*0b57cec5SDimitry Andric addConstantFPValue(*VariableDie, DVal->getConstantFP()); 630*0b57cec5SDimitry Andric } else if (DVal->isConstantInt()) { 631*0b57cec5SDimitry Andric addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType()); 632*0b57cec5SDimitry Andric } 633*0b57cec5SDimitry Andric return VariableDie; 634*0b57cec5SDimitry Andric } 635*0b57cec5SDimitry Andric 636*0b57cec5SDimitry Andric // .. else use frame index. 637*0b57cec5SDimitry Andric if (!DV.hasFrameIndexExprs()) 638*0b57cec5SDimitry Andric return VariableDie; 639*0b57cec5SDimitry Andric 640*0b57cec5SDimitry Andric Optional<unsigned> NVPTXAddressSpace; 641*0b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 642*0b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 643*0b57cec5SDimitry Andric for (auto &Fragment : DV.getFrameIndexExprs()) { 644*0b57cec5SDimitry Andric unsigned FrameReg = 0; 645*0b57cec5SDimitry Andric const DIExpression *Expr = Fragment.Expr; 646*0b57cec5SDimitry Andric const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 647*0b57cec5SDimitry Andric int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg); 648*0b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 649*0b57cec5SDimitry Andric SmallVector<uint64_t, 8> Ops; 650*0b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_plus_uconst); 651*0b57cec5SDimitry Andric Ops.push_back(Offset); 652*0b57cec5SDimitry Andric // According to 653*0b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 654*0b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 655*0b57cec5SDimitry Andric // correctly interpret address space of the variable address. 656*0b57cec5SDimitry Andric // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 657*0b57cec5SDimitry Andric // sequence for the NVPTX + gdb target. 658*0b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 659*0b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 660*0b57cec5SDimitry Andric const DIExpression *NewExpr = 661*0b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 662*0b57cec5SDimitry Andric if (NewExpr != Expr) { 663*0b57cec5SDimitry Andric Expr = NewExpr; 664*0b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 665*0b57cec5SDimitry Andric } 666*0b57cec5SDimitry Andric } 667*0b57cec5SDimitry Andric if (Expr) 668*0b57cec5SDimitry Andric Ops.append(Expr->elements_begin(), Expr->elements_end()); 669*0b57cec5SDimitry Andric DIExpressionCursor Cursor(Ops); 670*0b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 671*0b57cec5SDimitry Andric if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) 672*0b57cec5SDimitry Andric addOpAddress(*Loc, FrameSymbol); 673*0b57cec5SDimitry Andric else 674*0b57cec5SDimitry Andric DwarfExpr.addMachineRegExpression( 675*0b57cec5SDimitry Andric *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); 676*0b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 677*0b57cec5SDimitry Andric } 678*0b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 679*0b57cec5SDimitry Andric // According to 680*0b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 681*0b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 682*0b57cec5SDimitry Andric // correctly interpret address space of the variable address. 683*0b57cec5SDimitry Andric const unsigned NVPTX_ADDR_local_space = 6; 684*0b57cec5SDimitry Andric addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 685*0b57cec5SDimitry Andric NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); 686*0b57cec5SDimitry Andric } 687*0b57cec5SDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 688*0b57cec5SDimitry Andric if (DwarfExpr.TagOffset) 689*0b57cec5SDimitry Andric addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 690*0b57cec5SDimitry Andric *DwarfExpr.TagOffset); 691*0b57cec5SDimitry Andric 692*0b57cec5SDimitry Andric return VariableDie; 693*0b57cec5SDimitry Andric } 694*0b57cec5SDimitry Andric 695*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, 696*0b57cec5SDimitry Andric const LexicalScope &Scope, 697*0b57cec5SDimitry Andric DIE *&ObjectPointer) { 698*0b57cec5SDimitry Andric auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); 699*0b57cec5SDimitry Andric if (DV.isObjectPointer()) 700*0b57cec5SDimitry Andric ObjectPointer = Var; 701*0b57cec5SDimitry Andric return Var; 702*0b57cec5SDimitry Andric } 703*0b57cec5SDimitry Andric 704*0b57cec5SDimitry Andric /// Return all DIVariables that appear in count: expressions. 705*0b57cec5SDimitry Andric static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) { 706*0b57cec5SDimitry Andric SmallVector<const DIVariable *, 2> Result; 707*0b57cec5SDimitry Andric auto *Array = dyn_cast<DICompositeType>(Var->getType()); 708*0b57cec5SDimitry Andric if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) 709*0b57cec5SDimitry Andric return Result; 710*0b57cec5SDimitry Andric for (auto *El : Array->getElements()) { 711*0b57cec5SDimitry Andric if (auto *Subrange = dyn_cast<DISubrange>(El)) { 712*0b57cec5SDimitry Andric auto Count = Subrange->getCount(); 713*0b57cec5SDimitry Andric if (auto *Dependency = Count.dyn_cast<DIVariable *>()) 714*0b57cec5SDimitry Andric Result.push_back(Dependency); 715*0b57cec5SDimitry Andric } 716*0b57cec5SDimitry Andric } 717*0b57cec5SDimitry Andric return Result; 718*0b57cec5SDimitry Andric } 719*0b57cec5SDimitry Andric 720*0b57cec5SDimitry Andric /// Sort local variables so that variables appearing inside of helper 721*0b57cec5SDimitry Andric /// expressions come first. 722*0b57cec5SDimitry Andric static SmallVector<DbgVariable *, 8> 723*0b57cec5SDimitry Andric sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) { 724*0b57cec5SDimitry Andric SmallVector<DbgVariable *, 8> Result; 725*0b57cec5SDimitry Andric SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList; 726*0b57cec5SDimitry Andric // Map back from a DIVariable to its containing DbgVariable. 727*0b57cec5SDimitry Andric SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar; 728*0b57cec5SDimitry Andric // Set of DbgVariables in Result. 729*0b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visited; 730*0b57cec5SDimitry Andric // For cycle detection. 731*0b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visiting; 732*0b57cec5SDimitry Andric 733*0b57cec5SDimitry Andric // Initialize the worklist and the DIVariable lookup table. 734*0b57cec5SDimitry Andric for (auto Var : reverse(Input)) { 735*0b57cec5SDimitry Andric DbgVar.insert({Var->getVariable(), Var}); 736*0b57cec5SDimitry Andric WorkList.push_back({Var, 0}); 737*0b57cec5SDimitry Andric } 738*0b57cec5SDimitry Andric 739*0b57cec5SDimitry Andric // Perform a stable topological sort by doing a DFS. 740*0b57cec5SDimitry Andric while (!WorkList.empty()) { 741*0b57cec5SDimitry Andric auto Item = WorkList.back(); 742*0b57cec5SDimitry Andric DbgVariable *Var = Item.getPointer(); 743*0b57cec5SDimitry Andric bool visitedAllDependencies = Item.getInt(); 744*0b57cec5SDimitry Andric WorkList.pop_back(); 745*0b57cec5SDimitry Andric 746*0b57cec5SDimitry Andric // Dependency is in a different lexical scope or a global. 747*0b57cec5SDimitry Andric if (!Var) 748*0b57cec5SDimitry Andric continue; 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric // Already handled. 751*0b57cec5SDimitry Andric if (Visited.count(Var)) 752*0b57cec5SDimitry Andric continue; 753*0b57cec5SDimitry Andric 754*0b57cec5SDimitry Andric // Add to Result if all dependencies are visited. 755*0b57cec5SDimitry Andric if (visitedAllDependencies) { 756*0b57cec5SDimitry Andric Visited.insert(Var); 757*0b57cec5SDimitry Andric Result.push_back(Var); 758*0b57cec5SDimitry Andric continue; 759*0b57cec5SDimitry Andric } 760*0b57cec5SDimitry Andric 761*0b57cec5SDimitry Andric // Detect cycles. 762*0b57cec5SDimitry Andric auto Res = Visiting.insert(Var); 763*0b57cec5SDimitry Andric if (!Res.second) { 764*0b57cec5SDimitry Andric assert(false && "dependency cycle in local variables"); 765*0b57cec5SDimitry Andric return Result; 766*0b57cec5SDimitry Andric } 767*0b57cec5SDimitry Andric 768*0b57cec5SDimitry Andric // Push dependencies and this node onto the worklist, so that this node is 769*0b57cec5SDimitry Andric // visited again after all of its dependencies are handled. 770*0b57cec5SDimitry Andric WorkList.push_back({Var, 1}); 771*0b57cec5SDimitry Andric for (auto *Dependency : dependencies(Var)) { 772*0b57cec5SDimitry Andric auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency); 773*0b57cec5SDimitry Andric WorkList.push_back({DbgVar[Dep], 0}); 774*0b57cec5SDimitry Andric } 775*0b57cec5SDimitry Andric } 776*0b57cec5SDimitry Andric return Result; 777*0b57cec5SDimitry Andric } 778*0b57cec5SDimitry Andric 779*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, 780*0b57cec5SDimitry Andric SmallVectorImpl<DIE *> &Children, 781*0b57cec5SDimitry Andric bool *HasNonScopeChildren) { 782*0b57cec5SDimitry Andric assert(Children.empty()); 783*0b57cec5SDimitry Andric DIE *ObjectPointer = nullptr; 784*0b57cec5SDimitry Andric 785*0b57cec5SDimitry Andric // Emit function arguments (order is significant). 786*0b57cec5SDimitry Andric auto Vars = DU->getScopeVariables().lookup(Scope); 787*0b57cec5SDimitry Andric for (auto &DV : Vars.Args) 788*0b57cec5SDimitry Andric Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); 789*0b57cec5SDimitry Andric 790*0b57cec5SDimitry Andric // Emit local variables. 791*0b57cec5SDimitry Andric auto Locals = sortLocalVars(Vars.Locals); 792*0b57cec5SDimitry Andric for (DbgVariable *DV : Locals) 793*0b57cec5SDimitry Andric Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); 794*0b57cec5SDimitry Andric 795*0b57cec5SDimitry Andric // Skip imported directives in gmlt-like data. 796*0b57cec5SDimitry Andric if (!includeMinimalInlineScopes()) { 797*0b57cec5SDimitry Andric // There is no need to emit empty lexical block DIE. 798*0b57cec5SDimitry Andric for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) 799*0b57cec5SDimitry Andric Children.push_back( 800*0b57cec5SDimitry Andric constructImportedEntityDIE(cast<DIImportedEntity>(IE))); 801*0b57cec5SDimitry Andric } 802*0b57cec5SDimitry Andric 803*0b57cec5SDimitry Andric if (HasNonScopeChildren) 804*0b57cec5SDimitry Andric *HasNonScopeChildren = !Children.empty(); 805*0b57cec5SDimitry Andric 806*0b57cec5SDimitry Andric for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) 807*0b57cec5SDimitry Andric Children.push_back(constructLabelDIE(*DL, *Scope)); 808*0b57cec5SDimitry Andric 809*0b57cec5SDimitry Andric for (LexicalScope *LS : Scope->getChildren()) 810*0b57cec5SDimitry Andric constructScopeDIE(LS, Children); 811*0b57cec5SDimitry Andric 812*0b57cec5SDimitry Andric return ObjectPointer; 813*0b57cec5SDimitry Andric } 814*0b57cec5SDimitry Andric 815*0b57cec5SDimitry Andric DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, 816*0b57cec5SDimitry Andric LexicalScope *Scope) { 817*0b57cec5SDimitry Andric DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); 818*0b57cec5SDimitry Andric 819*0b57cec5SDimitry Andric if (Scope) { 820*0b57cec5SDimitry Andric assert(!Scope->getInlinedAt()); 821*0b57cec5SDimitry Andric assert(!Scope->isAbstractScope()); 822*0b57cec5SDimitry Andric // Collect lexical scope children first. 823*0b57cec5SDimitry Andric // ObjectPointer might be a local (non-argument) local variable if it's a 824*0b57cec5SDimitry Andric // block's synthetic this pointer. 825*0b57cec5SDimitry Andric if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) 826*0b57cec5SDimitry Andric addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); 827*0b57cec5SDimitry Andric } 828*0b57cec5SDimitry Andric 829*0b57cec5SDimitry Andric // If this is a variadic function, add an unspecified parameter. 830*0b57cec5SDimitry Andric DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); 831*0b57cec5SDimitry Andric 832*0b57cec5SDimitry Andric // If we have a single element of null, it is a function that returns void. 833*0b57cec5SDimitry Andric // If we have more than one elements and the last one is null, it is a 834*0b57cec5SDimitry Andric // variadic function. 835*0b57cec5SDimitry Andric if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && 836*0b57cec5SDimitry Andric !includeMinimalInlineScopes()) 837*0b57cec5SDimitry Andric ScopeDIE.addChild( 838*0b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); 839*0b57cec5SDimitry Andric 840*0b57cec5SDimitry Andric return ScopeDIE; 841*0b57cec5SDimitry Andric } 842*0b57cec5SDimitry Andric 843*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, 844*0b57cec5SDimitry Andric DIE &ScopeDIE) { 845*0b57cec5SDimitry Andric // We create children when the scope DIE is not null. 846*0b57cec5SDimitry Andric SmallVector<DIE *, 8> Children; 847*0b57cec5SDimitry Andric DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); 848*0b57cec5SDimitry Andric 849*0b57cec5SDimitry Andric // Add children 850*0b57cec5SDimitry Andric for (auto &I : Children) 851*0b57cec5SDimitry Andric ScopeDIE.addChild(std::move(I)); 852*0b57cec5SDimitry Andric 853*0b57cec5SDimitry Andric return ObjectPointer; 854*0b57cec5SDimitry Andric } 855*0b57cec5SDimitry Andric 856*0b57cec5SDimitry Andric void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( 857*0b57cec5SDimitry Andric LexicalScope *Scope) { 858*0b57cec5SDimitry Andric DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()]; 859*0b57cec5SDimitry Andric if (AbsDef) 860*0b57cec5SDimitry Andric return; 861*0b57cec5SDimitry Andric 862*0b57cec5SDimitry Andric auto *SP = cast<DISubprogram>(Scope->getScopeNode()); 863*0b57cec5SDimitry Andric 864*0b57cec5SDimitry Andric DIE *ContextDIE; 865*0b57cec5SDimitry Andric DwarfCompileUnit *ContextCU = this; 866*0b57cec5SDimitry Andric 867*0b57cec5SDimitry Andric if (includeMinimalInlineScopes()) 868*0b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 869*0b57cec5SDimitry Andric // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 870*0b57cec5SDimitry Andric // the important distinction that the debug node is not associated with the 871*0b57cec5SDimitry Andric // DIE (since the debug node will be associated with the concrete DIE, if 872*0b57cec5SDimitry Andric // any). It could be refactored to some common utility function. 873*0b57cec5SDimitry Andric else if (auto *SPDecl = SP->getDeclaration()) { 874*0b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 875*0b57cec5SDimitry Andric getOrCreateSubprogramDIE(SPDecl); 876*0b57cec5SDimitry Andric } else { 877*0b57cec5SDimitry Andric ContextDIE = getOrCreateContextDIE(SP->getScope()); 878*0b57cec5SDimitry Andric // The scope may be shared with a subprogram that has already been 879*0b57cec5SDimitry Andric // constructed in another CU, in which case we need to construct this 880*0b57cec5SDimitry Andric // subprogram in the same CU. 881*0b57cec5SDimitry Andric ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); 882*0b57cec5SDimitry Andric } 883*0b57cec5SDimitry Andric 884*0b57cec5SDimitry Andric // Passing null as the associated node because the abstract definition 885*0b57cec5SDimitry Andric // shouldn't be found by lookup. 886*0b57cec5SDimitry Andric AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); 887*0b57cec5SDimitry Andric ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); 888*0b57cec5SDimitry Andric 889*0b57cec5SDimitry Andric if (!ContextCU->includeMinimalInlineScopes()) 890*0b57cec5SDimitry Andric ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); 891*0b57cec5SDimitry Andric if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) 892*0b57cec5SDimitry Andric ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); 893*0b57cec5SDimitry Andric } 894*0b57cec5SDimitry Andric 895*0b57cec5SDimitry Andric DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE, 896*0b57cec5SDimitry Andric const DISubprogram &CalleeSP, 897*0b57cec5SDimitry Andric bool IsTail, 898*0b57cec5SDimitry Andric const MCExpr *PCOffset) { 899*0b57cec5SDimitry Andric // Insert a call site entry DIE within ScopeDIE. 900*0b57cec5SDimitry Andric DIE &CallSiteDIE = 901*0b57cec5SDimitry Andric createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr); 902*0b57cec5SDimitry Andric 903*0b57cec5SDimitry Andric // For the purposes of showing tail call frames in backtraces, a key piece of 904*0b57cec5SDimitry Andric // information is DW_AT_call_origin, a pointer to the callee DIE. 905*0b57cec5SDimitry Andric DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP); 906*0b57cec5SDimitry Andric assert(CalleeDIE && "Could not create DIE for call site entry origin"); 907*0b57cec5SDimitry Andric addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE); 908*0b57cec5SDimitry Andric 909*0b57cec5SDimitry Andric if (IsTail) { 910*0b57cec5SDimitry Andric // Attach DW_AT_call_tail_call to tail calls for standards compliance. 911*0b57cec5SDimitry Andric addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call); 912*0b57cec5SDimitry Andric } else { 913*0b57cec5SDimitry Andric // Attach the return PC to allow the debugger to disambiguate call paths 914*0b57cec5SDimitry Andric // from one function to another. 915*0b57cec5SDimitry Andric assert(PCOffset && "Missing return PC information for a call"); 916*0b57cec5SDimitry Andric addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset); 917*0b57cec5SDimitry Andric } 918*0b57cec5SDimitry Andric return CallSiteDIE; 919*0b57cec5SDimitry Andric } 920*0b57cec5SDimitry Andric 921*0b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructImportedEntityDIE( 922*0b57cec5SDimitry Andric const DIImportedEntity *Module) { 923*0b57cec5SDimitry Andric DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); 924*0b57cec5SDimitry Andric insertDIE(Module, IMDie); 925*0b57cec5SDimitry Andric DIE *EntityDie; 926*0b57cec5SDimitry Andric auto *Entity = Module->getEntity(); 927*0b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(Entity)) 928*0b57cec5SDimitry Andric EntityDie = getOrCreateNameSpace(NS); 929*0b57cec5SDimitry Andric else if (auto *M = dyn_cast<DIModule>(Entity)) 930*0b57cec5SDimitry Andric EntityDie = getOrCreateModule(M); 931*0b57cec5SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(Entity)) 932*0b57cec5SDimitry Andric EntityDie = getOrCreateSubprogramDIE(SP); 933*0b57cec5SDimitry Andric else if (auto *T = dyn_cast<DIType>(Entity)) 934*0b57cec5SDimitry Andric EntityDie = getOrCreateTypeDIE(T); 935*0b57cec5SDimitry Andric else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) 936*0b57cec5SDimitry Andric EntityDie = getOrCreateGlobalVariableDIE(GV, {}); 937*0b57cec5SDimitry Andric else 938*0b57cec5SDimitry Andric EntityDie = getDIE(Entity); 939*0b57cec5SDimitry Andric assert(EntityDie); 940*0b57cec5SDimitry Andric addSourceLine(*IMDie, Module->getLine(), Module->getFile()); 941*0b57cec5SDimitry Andric addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); 942*0b57cec5SDimitry Andric StringRef Name = Module->getName(); 943*0b57cec5SDimitry Andric if (!Name.empty()) 944*0b57cec5SDimitry Andric addString(*IMDie, dwarf::DW_AT_name, Name); 945*0b57cec5SDimitry Andric 946*0b57cec5SDimitry Andric return IMDie; 947*0b57cec5SDimitry Andric } 948*0b57cec5SDimitry Andric 949*0b57cec5SDimitry Andric void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { 950*0b57cec5SDimitry Andric DIE *D = getDIE(SP); 951*0b57cec5SDimitry Andric if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) { 952*0b57cec5SDimitry Andric if (D) 953*0b57cec5SDimitry Andric // If this subprogram has an abstract definition, reference that 954*0b57cec5SDimitry Andric addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); 955*0b57cec5SDimitry Andric } else { 956*0b57cec5SDimitry Andric assert(D || includeMinimalInlineScopes()); 957*0b57cec5SDimitry Andric if (D) 958*0b57cec5SDimitry Andric // And attach the attributes 959*0b57cec5SDimitry Andric applySubprogramAttributesToDefinition(SP, *D); 960*0b57cec5SDimitry Andric } 961*0b57cec5SDimitry Andric } 962*0b57cec5SDimitry Andric 963*0b57cec5SDimitry Andric void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { 964*0b57cec5SDimitry Andric DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); 965*0b57cec5SDimitry Andric 966*0b57cec5SDimitry Andric auto *Die = Entity->getDIE(); 967*0b57cec5SDimitry Andric /// Label may be used to generate DW_AT_low_pc, so put it outside 968*0b57cec5SDimitry Andric /// if/else block. 969*0b57cec5SDimitry Andric const DbgLabel *Label = nullptr; 970*0b57cec5SDimitry Andric if (AbsEntity && AbsEntity->getDIE()) { 971*0b57cec5SDimitry Andric addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); 972*0b57cec5SDimitry Andric Label = dyn_cast<const DbgLabel>(Entity); 973*0b57cec5SDimitry Andric } else { 974*0b57cec5SDimitry Andric if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) 975*0b57cec5SDimitry Andric applyVariableAttributes(*Var, *Die); 976*0b57cec5SDimitry Andric else if ((Label = dyn_cast<const DbgLabel>(Entity))) 977*0b57cec5SDimitry Andric applyLabelAttributes(*Label, *Die); 978*0b57cec5SDimitry Andric else 979*0b57cec5SDimitry Andric llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); 980*0b57cec5SDimitry Andric } 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric if (Label) 983*0b57cec5SDimitry Andric if (const auto *Sym = Label->getSymbol()) 984*0b57cec5SDimitry Andric addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); 985*0b57cec5SDimitry Andric } 986*0b57cec5SDimitry Andric 987*0b57cec5SDimitry Andric DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { 988*0b57cec5SDimitry Andric auto &AbstractEntities = getAbstractEntities(); 989*0b57cec5SDimitry Andric auto I = AbstractEntities.find(Node); 990*0b57cec5SDimitry Andric if (I != AbstractEntities.end()) 991*0b57cec5SDimitry Andric return I->second.get(); 992*0b57cec5SDimitry Andric return nullptr; 993*0b57cec5SDimitry Andric } 994*0b57cec5SDimitry Andric 995*0b57cec5SDimitry Andric void DwarfCompileUnit::createAbstractEntity(const DINode *Node, 996*0b57cec5SDimitry Andric LexicalScope *Scope) { 997*0b57cec5SDimitry Andric assert(Scope && Scope->isAbstractScope()); 998*0b57cec5SDimitry Andric auto &Entity = getAbstractEntities()[Node]; 999*0b57cec5SDimitry Andric if (isa<const DILocalVariable>(Node)) { 1000*0b57cec5SDimitry Andric Entity = llvm::make_unique<DbgVariable>( 1001*0b57cec5SDimitry Andric cast<const DILocalVariable>(Node), nullptr /* IA */);; 1002*0b57cec5SDimitry Andric DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); 1003*0b57cec5SDimitry Andric } else if (isa<const DILabel>(Node)) { 1004*0b57cec5SDimitry Andric Entity = llvm::make_unique<DbgLabel>( 1005*0b57cec5SDimitry Andric cast<const DILabel>(Node), nullptr /* IA */); 1006*0b57cec5SDimitry Andric DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); 1007*0b57cec5SDimitry Andric } 1008*0b57cec5SDimitry Andric } 1009*0b57cec5SDimitry Andric 1010*0b57cec5SDimitry Andric void DwarfCompileUnit::emitHeader(bool UseOffsets) { 1011*0b57cec5SDimitry Andric // Don't bother labeling the .dwo unit, as its offset isn't used. 1012*0b57cec5SDimitry Andric if (!Skeleton && !DD->useSectionsAsReferences()) { 1013*0b57cec5SDimitry Andric LabelBegin = Asm->createTempSymbol("cu_begin"); 1014*0b57cec5SDimitry Andric Asm->OutStreamer->EmitLabel(LabelBegin); 1015*0b57cec5SDimitry Andric } 1016*0b57cec5SDimitry Andric 1017*0b57cec5SDimitry Andric dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile 1018*0b57cec5SDimitry Andric : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton 1019*0b57cec5SDimitry Andric : dwarf::DW_UT_compile; 1020*0b57cec5SDimitry Andric DwarfUnit::emitCommonHeader(UseOffsets, UT); 1021*0b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) 1022*0b57cec5SDimitry Andric Asm->emitInt64(getDWOId()); 1023*0b57cec5SDimitry Andric } 1024*0b57cec5SDimitry Andric 1025*0b57cec5SDimitry Andric bool DwarfCompileUnit::hasDwarfPubSections() const { 1026*0b57cec5SDimitry Andric switch (CUNode->getNameTableKind()) { 1027*0b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::None: 1028*0b57cec5SDimitry Andric return false; 1029*0b57cec5SDimitry Andric // Opting in to GNU Pubnames/types overrides the default to ensure these are 1030*0b57cec5SDimitry Andric // generated for things like Gold's gdb_index generation. 1031*0b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::GNU: 1032*0b57cec5SDimitry Andric return true; 1033*0b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::Default: 1034*0b57cec5SDimitry Andric return DD->tuneForGDB() && !includeMinimalInlineScopes() && 1035*0b57cec5SDimitry Andric !CUNode->isDebugDirectivesOnly() && 1036*0b57cec5SDimitry Andric DD->getAccelTableKind() != AccelTableKind::Apple && 1037*0b57cec5SDimitry Andric DD->getDwarfVersion() < 5; 1038*0b57cec5SDimitry Andric } 1039*0b57cec5SDimitry Andric llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum"); 1040*0b57cec5SDimitry Andric } 1041*0b57cec5SDimitry Andric 1042*0b57cec5SDimitry Andric /// addGlobalName - Add a new global name to the compile unit. 1043*0b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, 1044*0b57cec5SDimitry Andric const DIScope *Context) { 1045*0b57cec5SDimitry Andric if (!hasDwarfPubSections()) 1046*0b57cec5SDimitry Andric return; 1047*0b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 1048*0b57cec5SDimitry Andric GlobalNames[FullName] = &Die; 1049*0b57cec5SDimitry Andric } 1050*0b57cec5SDimitry Andric 1051*0b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, 1052*0b57cec5SDimitry Andric const DIScope *Context) { 1053*0b57cec5SDimitry Andric if (!hasDwarfPubSections()) 1054*0b57cec5SDimitry Andric return; 1055*0b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 1056*0b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 1057*0b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 1058*0b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 1059*0b57cec5SDimitry Andric // in a type unit" 1060*0b57cec5SDimitry Andric GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie())); 1061*0b57cec5SDimitry Andric } 1062*0b57cec5SDimitry Andric 1063*0b57cec5SDimitry Andric /// Add a new global type to the unit. 1064*0b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, 1065*0b57cec5SDimitry Andric const DIScope *Context) { 1066*0b57cec5SDimitry Andric if (!hasDwarfPubSections()) 1067*0b57cec5SDimitry Andric return; 1068*0b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 1069*0b57cec5SDimitry Andric GlobalTypes[FullName] = &Die; 1070*0b57cec5SDimitry Andric } 1071*0b57cec5SDimitry Andric 1072*0b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, 1073*0b57cec5SDimitry Andric const DIScope *Context) { 1074*0b57cec5SDimitry Andric if (!hasDwarfPubSections()) 1075*0b57cec5SDimitry Andric return; 1076*0b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 1077*0b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 1078*0b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 1079*0b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 1080*0b57cec5SDimitry Andric // in a type unit" 1081*0b57cec5SDimitry Andric GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie())); 1082*0b57cec5SDimitry Andric } 1083*0b57cec5SDimitry Andric 1084*0b57cec5SDimitry Andric /// addVariableAddress - Add DW_AT_location attribute for a 1085*0b57cec5SDimitry Andric /// DbgVariable based on provided MachineLocation. 1086*0b57cec5SDimitry Andric void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, 1087*0b57cec5SDimitry Andric MachineLocation Location) { 1088*0b57cec5SDimitry Andric // addBlockByrefAddress is obsolete and will be removed soon. 1089*0b57cec5SDimitry Andric // The clang frontend always generates block byref variables with a 1090*0b57cec5SDimitry Andric // complex expression that encodes exactly what addBlockByrefAddress 1091*0b57cec5SDimitry Andric // would do. 1092*0b57cec5SDimitry Andric assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) && 1093*0b57cec5SDimitry Andric "block byref variable without a complex expression"); 1094*0b57cec5SDimitry Andric if (DV.hasComplexAddress()) 1095*0b57cec5SDimitry Andric addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); 1096*0b57cec5SDimitry Andric else 1097*0b57cec5SDimitry Andric addAddress(Die, dwarf::DW_AT_location, Location); 1098*0b57cec5SDimitry Andric } 1099*0b57cec5SDimitry Andric 1100*0b57cec5SDimitry Andric /// Add an address attribute to a die based on the location provided. 1101*0b57cec5SDimitry Andric void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, 1102*0b57cec5SDimitry Andric const MachineLocation &Location) { 1103*0b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1104*0b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1105*0b57cec5SDimitry Andric if (Location.isIndirect()) 1106*0b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1107*0b57cec5SDimitry Andric 1108*0b57cec5SDimitry Andric DIExpressionCursor Cursor({}); 1109*0b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1110*0b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 1111*0b57cec5SDimitry Andric return; 1112*0b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 1113*0b57cec5SDimitry Andric 1114*0b57cec5SDimitry Andric // Now attach the location information to the DIE. 1115*0b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 1116*0b57cec5SDimitry Andric } 1117*0b57cec5SDimitry Andric 1118*0b57cec5SDimitry Andric /// Start with the address based on the location provided, and generate the 1119*0b57cec5SDimitry Andric /// DWARF information necessary to find the actual variable given the extra 1120*0b57cec5SDimitry Andric /// address information encoded in the DbgVariable, starting from the starting 1121*0b57cec5SDimitry Andric /// location. Add the DWARF information to the die. 1122*0b57cec5SDimitry Andric void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, 1123*0b57cec5SDimitry Andric dwarf::Attribute Attribute, 1124*0b57cec5SDimitry Andric const MachineLocation &Location) { 1125*0b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1126*0b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1127*0b57cec5SDimitry Andric const DIExpression *DIExpr = DV.getSingleExpression(); 1128*0b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(DIExpr); 1129*0b57cec5SDimitry Andric if (Location.isIndirect()) 1130*0b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 1131*0b57cec5SDimitry Andric 1132*0b57cec5SDimitry Andric DIExpressionCursor Cursor(DIExpr); 1133*0b57cec5SDimitry Andric 1134*0b57cec5SDimitry Andric if (DIExpr->isEntryValue()) { 1135*0b57cec5SDimitry Andric DwarfExpr.setEntryValueFlag(); 1136*0b57cec5SDimitry Andric DwarfExpr.addEntryValueExpression(Cursor); 1137*0b57cec5SDimitry Andric } 1138*0b57cec5SDimitry Andric 1139*0b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1140*0b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 1141*0b57cec5SDimitry Andric return; 1142*0b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 1143*0b57cec5SDimitry Andric 1144*0b57cec5SDimitry Andric // Now attach the location information to the DIE. 1145*0b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 1146*0b57cec5SDimitry Andric } 1147*0b57cec5SDimitry Andric 1148*0b57cec5SDimitry Andric /// Add a Dwarf loclistptr attribute data and value. 1149*0b57cec5SDimitry Andric void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, 1150*0b57cec5SDimitry Andric unsigned Index) { 1151*0b57cec5SDimitry Andric dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset 1152*0b57cec5SDimitry Andric : dwarf::DW_FORM_data4; 1153*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index)); 1154*0b57cec5SDimitry Andric } 1155*0b57cec5SDimitry Andric 1156*0b57cec5SDimitry Andric void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, 1157*0b57cec5SDimitry Andric DIE &VariableDie) { 1158*0b57cec5SDimitry Andric StringRef Name = Var.getName(); 1159*0b57cec5SDimitry Andric if (!Name.empty()) 1160*0b57cec5SDimitry Andric addString(VariableDie, dwarf::DW_AT_name, Name); 1161*0b57cec5SDimitry Andric const auto *DIVar = Var.getVariable(); 1162*0b57cec5SDimitry Andric if (DIVar) 1163*0b57cec5SDimitry Andric if (uint32_t AlignInBytes = DIVar->getAlignInBytes()) 1164*0b57cec5SDimitry Andric addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 1165*0b57cec5SDimitry Andric AlignInBytes); 1166*0b57cec5SDimitry Andric 1167*0b57cec5SDimitry Andric addSourceLine(VariableDie, DIVar); 1168*0b57cec5SDimitry Andric addType(VariableDie, Var.getType()); 1169*0b57cec5SDimitry Andric if (Var.isArtificial()) 1170*0b57cec5SDimitry Andric addFlag(VariableDie, dwarf::DW_AT_artificial); 1171*0b57cec5SDimitry Andric } 1172*0b57cec5SDimitry Andric 1173*0b57cec5SDimitry Andric void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, 1174*0b57cec5SDimitry Andric DIE &LabelDie) { 1175*0b57cec5SDimitry Andric StringRef Name = Label.getName(); 1176*0b57cec5SDimitry Andric if (!Name.empty()) 1177*0b57cec5SDimitry Andric addString(LabelDie, dwarf::DW_AT_name, Name); 1178*0b57cec5SDimitry Andric const auto *DILabel = Label.getLabel(); 1179*0b57cec5SDimitry Andric addSourceLine(LabelDie, DILabel); 1180*0b57cec5SDimitry Andric } 1181*0b57cec5SDimitry Andric 1182*0b57cec5SDimitry Andric /// Add a Dwarf expression attribute data and value. 1183*0b57cec5SDimitry Andric void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, 1184*0b57cec5SDimitry Andric const MCExpr *Expr) { 1185*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr)); 1186*0b57cec5SDimitry Andric } 1187*0b57cec5SDimitry Andric 1188*0b57cec5SDimitry Andric void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute, 1189*0b57cec5SDimitry Andric const MCExpr *Expr) { 1190*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 1191*0b57cec5SDimitry Andric DIEExpr(Expr)); 1192*0b57cec5SDimitry Andric } 1193*0b57cec5SDimitry Andric 1194*0b57cec5SDimitry Andric void DwarfCompileUnit::applySubprogramAttributesToDefinition( 1195*0b57cec5SDimitry Andric const DISubprogram *SP, DIE &SPDie) { 1196*0b57cec5SDimitry Andric auto *SPDecl = SP->getDeclaration(); 1197*0b57cec5SDimitry Andric auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope(); 1198*0b57cec5SDimitry Andric applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); 1199*0b57cec5SDimitry Andric addGlobalName(SP->getName(), SPDie, Context); 1200*0b57cec5SDimitry Andric } 1201*0b57cec5SDimitry Andric 1202*0b57cec5SDimitry Andric bool DwarfCompileUnit::isDwoUnit() const { 1203*0b57cec5SDimitry Andric return DD->useSplitDwarf() && Skeleton; 1204*0b57cec5SDimitry Andric } 1205*0b57cec5SDimitry Andric 1206*0b57cec5SDimitry Andric void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { 1207*0b57cec5SDimitry Andric constructTypeDIE(D, CTy); 1208*0b57cec5SDimitry Andric } 1209*0b57cec5SDimitry Andric 1210*0b57cec5SDimitry Andric bool DwarfCompileUnit::includeMinimalInlineScopes() const { 1211*0b57cec5SDimitry Andric return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || 1212*0b57cec5SDimitry Andric (DD->useSplitDwarf() && !Skeleton); 1213*0b57cec5SDimitry Andric } 1214*0b57cec5SDimitry Andric 1215*0b57cec5SDimitry Andric void DwarfCompileUnit::addAddrTableBase() { 1216*0b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 1217*0b57cec5SDimitry Andric MCSymbol *Label = DD->getAddressPool().getLabel(); 1218*0b57cec5SDimitry Andric addSectionLabel(getUnitDie(), 1219*0b57cec5SDimitry Andric getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base 1220*0b57cec5SDimitry Andric : dwarf::DW_AT_GNU_addr_base, 1221*0b57cec5SDimitry Andric Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); 1222*0b57cec5SDimitry Andric } 1223*0b57cec5SDimitry Andric 1224*0b57cec5SDimitry Andric void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { 1225*0b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata, 1226*0b57cec5SDimitry Andric new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); 1227*0b57cec5SDimitry Andric } 1228*0b57cec5SDimitry Andric 1229*0b57cec5SDimitry Andric void DwarfCompileUnit::createBaseTypeDIEs() { 1230*0b57cec5SDimitry Andric // Insert the base_type DIEs directly after the CU so that their offsets will 1231*0b57cec5SDimitry Andric // fit in the fixed size ULEB128 used inside the location expressions. 1232*0b57cec5SDimitry Andric // Maintain order by iterating backwards and inserting to the front of CU 1233*0b57cec5SDimitry Andric // child list. 1234*0b57cec5SDimitry Andric for (auto &Btr : reverse(ExprRefedBaseTypes)) { 1235*0b57cec5SDimitry Andric DIE &Die = getUnitDie().addChildFront( 1236*0b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type)); 1237*0b57cec5SDimitry Andric SmallString<32> Str; 1238*0b57cec5SDimitry Andric addString(Die, dwarf::DW_AT_name, 1239*0b57cec5SDimitry Andric Twine(dwarf::AttributeEncodingString(Btr.Encoding) + 1240*0b57cec5SDimitry Andric "_" + Twine(Btr.BitSize)).toStringRef(Str)); 1241*0b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding); 1242*0b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_byte_size, None, Btr.BitSize / 8); 1243*0b57cec5SDimitry Andric 1244*0b57cec5SDimitry Andric Btr.Die = &Die; 1245*0b57cec5SDimitry Andric } 1246*0b57cec5SDimitry Andric } 1247