Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
35271 views
//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains support for constructing a dwarf compile unit.9//10//===----------------------------------------------------------------------===//1112#include "DwarfCompileUnit.h"13#include "AddressPool.h"14#include "DwarfExpression.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/ADT/SmallString.h"17#include "llvm/BinaryFormat/Dwarf.h"18#include "llvm/CodeGen/AsmPrinter.h"19#include "llvm/CodeGen/DIE.h"20#include "llvm/CodeGen/MachineFunction.h"21#include "llvm/CodeGen/MachineInstr.h"22#include "llvm/CodeGen/TargetFrameLowering.h"23#include "llvm/CodeGen/TargetRegisterInfo.h"24#include "llvm/CodeGen/TargetSubtargetInfo.h"25#include "llvm/IR/DataLayout.h"26#include "llvm/IR/DebugInfo.h"27#include "llvm/IR/GlobalVariable.h"28#include "llvm/MC/MCAsmInfo.h"29#include "llvm/MC/MCSection.h"30#include "llvm/MC/MCStreamer.h"31#include "llvm/MC/MCSymbol.h"32#include "llvm/MC/MCSymbolWasm.h"33#include "llvm/MC/MachineLocation.h"34#include "llvm/Support/CommandLine.h"35#include "llvm/Target/TargetLoweringObjectFile.h"36#include "llvm/Target/TargetMachine.h"37#include "llvm/Target/TargetOptions.h"38#include <iterator>39#include <optional>40#include <string>41#include <utility>4243using namespace llvm;4445/// Query value using AddLinkageNamesToDeclCallOriginsForTuning.46cl::opt<cl::boolOrDefault> AddLinkageNamesToDeclCallOrigins(47"add-linkage-names-to-declaration-call-origins", cl::Hidden,48cl::desc("Add DW_AT_linkage_name to function declaration DIEs "49"referenced by DW_AT_call_origin attributes. Enabled by default "50"for -gsce debugger tuning."));5152static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD) {53bool EnabledByDefault = DD->tuneForSCE();54if (EnabledByDefault)55return AddLinkageNamesToDeclCallOrigins != cl::boolOrDefault::BOU_FALSE;56return AddLinkageNamesToDeclCallOrigins == cl::boolOrDefault::BOU_TRUE;57}5859static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {6061// According to DWARF Debugging Information Format Version 5,62// 3.1.2 Skeleton Compilation Unit Entries:63// "When generating a split DWARF object file (see Section 7.3.264// on page 187), the compilation unit in the .debug_info section65// is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"66if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)67return dwarf::DW_TAG_skeleton_unit;6869return dwarf::DW_TAG_compile_unit;70}7172DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,73AsmPrinter *A, DwarfDebug *DW,74DwarfFile *DWU, UnitKind Kind)75: DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU, UID) {76insertDIE(Node, &getUnitDie());77MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");78}7980/// addLabelAddress - Add a dwarf label attribute data and value using81/// DW_FORM_addr or DW_FORM_GNU_addr_index.82void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,83const MCSymbol *Label) {84if ((Skeleton || !DD->useSplitDwarf()) && Label)85DD->addArangeLabel(SymbolCU(this, Label));8687// Don't use the address pool in non-fission or in the skeleton unit itself.88if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)89return addLocalLabelAddress(Die, Attribute, Label);9091bool UseAddrOffsetFormOrExpressions =92DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();9394const MCSymbol *Base = nullptr;95if (Label->isInSection() && UseAddrOffsetFormOrExpressions)96Base = DD->getSectionLabel(&Label->getSection());9798if (!Base || Base == Label) {99unsigned idx = DD->getAddressPool().getIndex(Label);100addAttribute(Die, Attribute,101DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx102: dwarf::DW_FORM_GNU_addr_index,103DIEInteger(idx));104return;105}106107// Could be extended to work with DWARFv4 Split DWARF if that's important for108// someone. In that case DW_FORM_data would be used.109assert(DD->getDwarfVersion() >= 5 &&110"Addr+offset expressions are only valuable when using debug_addr (to "111"reduce relocations) available in DWARFv5 or higher");112if (DD->useAddrOffsetExpressions()) {113auto *Loc = new (DIEValueAllocator) DIEBlock();114addPoolOpAddress(*Loc, Label);115addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);116} else117addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,118new (DIEValueAllocator) DIEAddrOffset(119DD->getAddressPool().getIndex(Base), Label, Base));120}121122void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,123dwarf::Attribute Attribute,124const MCSymbol *Label) {125if (Label)126addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));127else128addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));129}130131unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {132// If we print assembly, we can't separate .file entries according to133// compile units. Thus all files will belong to the default compile unit.134135// FIXME: add a better feature test than hasRawTextSupport. Even better,136// extend .file to support this.137unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();138if (!File)139return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,140std::nullopt, CUID);141142if (LastFile != File) {143LastFile = File;144LastFileID = Asm->OutStreamer->emitDwarfFileDirective(1450, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),146File->getSource(), CUID);147}148return LastFileID;149}150151DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(152const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {153// Check for pre-existence.154if (DIE *Die = getDIE(GV))155return Die;156157assert(GV);158159auto *GVContext = GV->getScope();160const DIType *GTy = GV->getType();161162auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;163DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)164: getOrCreateContextDIE(GVContext);165166// Add to map.167DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);168DIScope *DeclContext;169if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {170DeclContext = SDMDecl->getScope();171assert(SDMDecl->isStaticMember() && "Expected static member decl");172assert(GV->isDefinition());173// We need the declaration DIE that is in the static member's class.174DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);175addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);176// If the global variable's type is different from the one in the class177// member type, assume that it's more specific and also emit it.178if (GTy != SDMDecl->getBaseType())179addType(*VariableDIE, GTy);180} else {181DeclContext = GV->getScope();182// Add name and type.183StringRef DisplayName = GV->getDisplayName();184if (!DisplayName.empty())185addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());186if (GTy)187addType(*VariableDIE, GTy);188189// Add scoping info.190if (!GV->isLocalToUnit())191addFlag(*VariableDIE, dwarf::DW_AT_external);192193// Add line number info.194addSourceLine(*VariableDIE, GV);195}196197if (!GV->isDefinition())198addFlag(*VariableDIE, dwarf::DW_AT_declaration);199else200addGlobalName(GV->getName(), *VariableDIE, DeclContext);201202addAnnotation(*VariableDIE, GV->getAnnotations());203204if (uint32_t AlignInBytes = GV->getAlignInBytes())205addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,206AlignInBytes);207208if (MDTuple *TP = GV->getTemplateParams())209addTemplateParams(*VariableDIE, DINodeArray(TP));210211// Add location.212addLocationAttribute(VariableDIE, GV, GlobalExprs);213214return VariableDIE;215}216217void DwarfCompileUnit::addLocationAttribute(218DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {219bool addToAccelTable = false;220DIELoc *Loc = nullptr;221std::optional<unsigned> NVPTXAddressSpace;222std::unique_ptr<DIEDwarfExpression> DwarfExpr;223for (const auto &GE : GlobalExprs) {224const GlobalVariable *Global = GE.Var;225const DIExpression *Expr = GE.Expr;226227// For compatibility with DWARF 3 and earlier,228// DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or229// DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes230// DW_AT_const_value(X).231if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {232addToAccelTable = true;233addConstantValue(234*VariableDIE,235DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==236*Expr->isConstant(),237Expr->getElement(1));238break;239}240241// We cannot describe the location of dllimport'd variables: the242// computation of their address requires loads from the IAT.243if (Global && Global->hasDLLImportStorageClass())244continue;245246// Nothing to describe without address or constant.247if (!Global && (!Expr || !Expr->isConstant()))248continue;249250if (Global && Global->isThreadLocal() &&251!Asm->getObjFileLowering().supportDebugThreadLocalLocation())252continue;253254if (!Loc) {255addToAccelTable = true;256Loc = new (DIEValueAllocator) DIELoc;257DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);258}259260if (Expr) {261// According to262// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf263// cuda-gdb requires DW_AT_address_class for all variables to be able to264// correctly interpret address space of the variable address.265// Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef266// sequence for the NVPTX + gdb target.267unsigned LocalNVPTXAddressSpace;268if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {269const DIExpression *NewExpr =270DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);271if (NewExpr != Expr) {272Expr = NewExpr;273NVPTXAddressSpace = LocalNVPTXAddressSpace;274}275}276DwarfExpr->addFragmentOffset(Expr);277}278279if (Global) {280const MCSymbol *Sym = Asm->getSymbol(Global);281// 16-bit platforms like MSP430 and AVR take this path, so sink this282// assert to platforms that use it.283auto GetPointerSizedFormAndOp = [this]() {284unsigned PointerSize = Asm->MAI->getCodePointerSize();285assert((PointerSize == 4 || PointerSize == 8) &&286"Add support for other sizes if necessary");287struct FormAndOp {288dwarf::Form Form;289dwarf::LocationAtom Op;290};291return PointerSize == 4292? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}293: FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};294};295if (Global->isThreadLocal()) {296if (Asm->TM.getTargetTriple().isWasm()) {297// FIXME This is not guaranteed, but in practice, in static linking,298// if present, __tls_base's index is 1. This doesn't hold for dynamic299// linking, so TLS variables used in dynamic linking won't have300// correct debug info for now. See301// https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823302addWasmRelocBaseGlobal(Loc, "__tls_base", 1);303addOpAddress(*Loc, Sym);304addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);305} else if (Asm->TM.useEmulatedTLS()) {306// TODO: add debug info for emulated thread local mode.307} else {308// FIXME: Make this work with -gsplit-dwarf.309// Based on GCC's support for TLS:310if (!DD->useSplitDwarf()) {311auto FormAndOp = GetPointerSizedFormAndOp();312// 1) Start with a constNu of the appropriate pointer size313addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);314// 2) containing the (relocated) offset of the TLS variable315// within the module's TLS block.316addExpr(*Loc, FormAndOp.Form,317Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));318} else {319addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);320addUInt(*Loc, dwarf::DW_FORM_udata,321DD->getAddressPool().getIndex(Sym, /* TLS */ true));322}323// 3) followed by an OP to make the debugger do a TLS lookup.324addUInt(*Loc, dwarf::DW_FORM_data1,325DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address326: dwarf::DW_OP_form_tls_address);327}328} else if (Asm->TM.getTargetTriple().isWasm() &&329Asm->TM.getRelocationModel() == Reloc::PIC_) {330// FIXME This is not guaranteed, but in practice, if present,331// __memory_base's index is 1. See332// https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823333addWasmRelocBaseGlobal(Loc, "__memory_base", 1);334addOpAddress(*Loc, Sym);335addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);336} else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||337Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&338!Asm->getObjFileLowering()339.getKindForGlobal(Global, Asm->TM)340.isReadOnly()) {341auto FormAndOp = GetPointerSizedFormAndOp();342// Constant343addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);344// Relocation offset345addExpr(*Loc, FormAndOp.Form,346Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));347// Base register348Register BaseReg = Asm->getObjFileLowering().getStaticBase();349BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);350addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg);351// Offset from base register352addSInt(*Loc, dwarf::DW_FORM_sdata, 0);353// Operation354addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);355} else {356DD->addArangeLabel(SymbolCU(this, Sym));357addOpAddress(*Loc, Sym);358}359}360// Global variables attached to symbols are memory locations.361// It would be better if this were unconditional, but malformed input that362// mixes non-fragments and fragments for the same variable is too expensive363// to detect in the verifier.364if (DwarfExpr->isUnknownLocation())365DwarfExpr->setMemoryLocationKind();366DwarfExpr->addExpression(Expr);367}368if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {369// According to370// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf371// cuda-gdb requires DW_AT_address_class for all variables to be able to372// correctly interpret address space of the variable address.373const unsigned NVPTX_ADDR_global_space = 5;374addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,375NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));376}377if (Loc)378addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());379380if (DD->useAllLinkageNames())381addLinkageName(*VariableDIE, GV->getLinkageName());382383if (addToAccelTable) {384DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getName(),385*VariableDIE);386387// If the linkage name is different than the name, go ahead and output388// that as well into the name table.389if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&390DD->useAllLinkageNames())391DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getLinkageName(),392*VariableDIE);393}394}395396DIE *DwarfCompileUnit::getOrCreateCommonBlock(397const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {398// Check for pre-existence.399if (DIE *NDie = getDIE(CB))400return NDie;401DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());402DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);403StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();404addString(NDie, dwarf::DW_AT_name, Name);405addGlobalName(Name, NDie, CB->getScope());406if (CB->getFile())407addSourceLine(NDie, CB->getLineNo(), CB->getFile());408if (DIGlobalVariable *V = CB->getDecl())409getCU().addLocationAttribute(&NDie, V, GlobalExprs);410return &NDie;411}412413void DwarfCompileUnit::addRange(RangeSpan Range) {414DD->insertSectionLabel(Range.Begin);415416auto *PrevCU = DD->getPrevCU();417bool SameAsPrevCU = this == PrevCU;418DD->setPrevCU(this);419// If we have no current ranges just add the range and return, otherwise,420// check the current section and CU against the previous section and CU we421// emitted into and the subprogram was contained within. If these are the422// same then extend our current range, otherwise add this as a new range.423if (CURanges.empty() || !SameAsPrevCU ||424(&CURanges.back().End->getSection() !=425&Range.End->getSection())) {426// Before a new range is added, always terminate the prior line table.427if (PrevCU)428DD->terminateLineTable(PrevCU);429CURanges.push_back(Range);430return;431}432433CURanges.back().End = Range.End;434}435436void DwarfCompileUnit::initStmtList() {437if (CUNode->isDebugDirectivesOnly())438return;439440const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();441if (DD->useSectionsAsReferences()) {442LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();443} else {444LineTableStartSym =445Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());446}447448// DW_AT_stmt_list is a offset of line number information for this449// compile unit in debug_line section. For split dwarf this is450// left in the skeleton CU and so not included.451// The line table entries are not always emitted in assembly, so it452// is not okay to use line_table_start here.453addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,454TLOF.getDwarfLineSection()->getBeginSymbol());455}456457void DwarfCompileUnit::applyStmtList(DIE &D) {458const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();459addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,460TLOF.getDwarfLineSection()->getBeginSymbol());461}462463void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,464const MCSymbol *End) {465assert(Begin && "Begin label should not be null!");466assert(End && "End label should not be null!");467assert(Begin->isDefined() && "Invalid starting label");468assert(End->isDefined() && "Invalid end label");469470addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);471if (DD->getDwarfVersion() < 4)472addLabelAddress(D, dwarf::DW_AT_high_pc, End);473else474addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);475}476477// Add info for Wasm-global-based relocation.478// 'GlobalIndex' is used for split dwarf, which currently relies on a few479// assumptions that are not guaranteed in a formal way but work in practice.480void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,481uint64_t GlobalIndex) {482// FIXME: duplicated from Target/WebAssembly/WebAssembly.h483// don't want to depend on target specific headers in this code?484const unsigned TI_GLOBAL_RELOC = 3;485unsigned PointerSize = Asm->getDataLayout().getPointerSize();486auto *Sym = cast<MCSymbolWasm>(Asm->GetExternalSymbolSymbol(GlobalName));487// FIXME: this repeats what WebAssemblyMCInstLower::488// GetExternalSymbolSymbol does, since if there's no code that489// refers to this symbol, we have to set it here.490Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);491Sym->setGlobalType(wasm::WasmGlobalType{492static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32493: wasm::WASM_TYPE_I64),494true});495addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);496addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);497if (!isDwoUnit()) {498addLabel(*Loc, dwarf::DW_FORM_data4, Sym);499} else {500// FIXME: when writing dwo, we need to avoid relocations. Probably501// the "right" solution is to treat globals the way func and data502// symbols are (with entries in .debug_addr).503// For now we hardcode the indices in the callsites. Global indices are not504// fixed, but in practice a few are fixed; for example, __stack_pointer is505// always index 0.506addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);507}508}509510// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc511// and DW_AT_high_pc attributes. If there are global variables in this512// scope then create and insert DIEs for these variables.513DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {514DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());515SmallVector<RangeSpan, 2> BB_List;516// If basic block sections are on, ranges for each basic block section has517// to be emitted separately.518for (const auto &R : Asm->MBBSectionRanges)519BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});520521attachRangesOrLowHighPC(*SPDie, BB_List);522523if (DD->useAppleExtensionAttributes() &&524!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(525*DD->getCurrentFunction()))526addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);527528// Only include DW_AT_frame_base in full debug info529if (!includeMinimalInlineScopes()) {530const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();531TargetFrameLowering::DwarfFrameBase FrameBase =532TFI->getDwarfFrameBase(*Asm->MF);533switch (FrameBase.Kind) {534case TargetFrameLowering::DwarfFrameBase::Register: {535if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {536MachineLocation Location(FrameBase.Location.Reg);537addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);538}539break;540}541case TargetFrameLowering::DwarfFrameBase::CFA: {542DIELoc *Loc = new (DIEValueAllocator) DIELoc;543addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);544if (FrameBase.Location.Offset != 0) {545addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);546addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.Offset);547addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);548}549addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);550break;551}552case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {553// FIXME: duplicated from Target/WebAssembly/WebAssembly.h554const unsigned TI_GLOBAL_RELOC = 3;555if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {556// These need to be relocatable.557DIELoc *Loc = new (DIEValueAllocator) DIELoc;558assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.559// For now, since we only ever use index 0, this should work as-is.560addWasmRelocBaseGlobal(Loc, "__stack_pointer",561FrameBase.Location.WasmLoc.Index);562addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);563addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);564} else {565DIELoc *Loc = new (DIEValueAllocator) DIELoc;566DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);567DIExpressionCursor Cursor({});568DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,569FrameBase.Location.WasmLoc.Index);570DwarfExpr.addExpression(std::move(Cursor));571addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());572}573break;574}575}576}577578// Add name to the name table, we do this here because we're guaranteed579// to have concrete versions of our DW_TAG_subprogram nodes.580DD->addSubprogramNames(*this, CUNode->getNameTableKind(), SP, *SPDie);581582return *SPDie;583}584585// Construct a DIE for this scope.586void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,587DIE &ParentScopeDIE) {588if (!Scope || !Scope->getScopeNode())589return;590591auto *DS = Scope->getScopeNode();592593assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&594"Only handle inlined subprograms here, use "595"constructSubprogramScopeDIE for non-inlined "596"subprograms");597598// Emit inlined subprograms.599if (Scope->getParent() && isa<DISubprogram>(DS)) {600DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE);601assert(ScopeDIE && "Scope DIE should not be null.");602createAndAddScopeChildren(Scope, *ScopeDIE);603return;604}605606// Early exit when we know the scope DIE is going to be null.607if (DD->isLexicalScopeDIENull(Scope))608return;609610// Emit lexical blocks.611DIE *ScopeDIE = constructLexicalScopeDIE(Scope);612assert(ScopeDIE && "Scope DIE should not be null.");613614ParentScopeDIE.addChild(ScopeDIE);615createAndAddScopeChildren(Scope, *ScopeDIE);616}617618void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,619SmallVector<RangeSpan, 2> Range) {620621HasRangeLists = true;622623// Add the range list to the set of ranges to be emitted.624auto IndexAndList =625(DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)626->addRange(*(Skeleton ? Skeleton : this), std::move(Range));627628uint32_t Index = IndexAndList.first;629auto &List = *IndexAndList.second;630631// Under fission, ranges are specified by constant offsets relative to the632// CU's DW_AT_GNU_ranges_base.633// FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under634// fission until we support the forms using the .debug_addr section635// (DW_RLE_startx_endx etc.).636if (DD->getDwarfVersion() >= 5)637addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);638else {639const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();640const MCSymbol *RangeSectionSym =641TLOF.getDwarfRangesSection()->getBeginSymbol();642if (isDwoUnit())643addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,644RangeSectionSym);645else646addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,647RangeSectionSym);648}649}650651void DwarfCompileUnit::attachRangesOrLowHighPC(652DIE &Die, SmallVector<RangeSpan, 2> Ranges) {653assert(!Ranges.empty());654if (!DD->useRangesSection() ||655(Ranges.size() == 1 &&656(!DD->alwaysUseRanges(*this) ||657DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==658Ranges.front().Begin))) {659const RangeSpan &Front = Ranges.front();660const RangeSpan &Back = Ranges.back();661attachLowHighPC(Die, Front.Begin, Back.End);662} else663addScopeRangeList(Die, std::move(Ranges));664}665666void DwarfCompileUnit::attachRangesOrLowHighPC(667DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {668SmallVector<RangeSpan, 2> List;669List.reserve(Ranges.size());670for (const InsnRange &R : Ranges) {671auto *BeginLabel = DD->getLabelBeforeInsn(R.first);672auto *EndLabel = DD->getLabelAfterInsn(R.second);673674const auto *BeginMBB = R.first->getParent();675const auto *EndMBB = R.second->getParent();676677const auto *MBB = BeginMBB;678// Basic block sections allows basic block subsets to be placed in unique679// sections. For each section, the begin and end label must be added to the680// list. If there is more than one range, debug ranges must be used.681// Otherwise, low/high PC can be used.682// FIXME: Debug Info Emission depends on block order and this assumes that683// the order of blocks will be frozen beyond this point.684do {685if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {686auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionID()];687List.push_back(688{MBB->sameSection(BeginMBB) ? BeginLabel689: MBBSectionRange.BeginLabel,690MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});691}692if (MBB->sameSection(EndMBB))693break;694MBB = MBB->getNextNode();695} while (true);696}697attachRangesOrLowHighPC(Die, std::move(List));698}699700DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,701DIE &ParentScopeDIE) {702assert(Scope->getScopeNode());703auto *DS = Scope->getScopeNode();704auto *InlinedSP = getDISubprogram(DS);705// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram706// was inlined from another compile unit.707DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];708assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");709710auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);711ParentScopeDIE.addChild(ScopeDIE);712addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);713714attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());715716// Add the call site information to the DIE.717const DILocation *IA = Scope->getInlinedAt();718addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,719getOrCreateSourceID(IA->getFile()));720addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());721if (IA->getColumn())722addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());723if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)724addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,725IA->getDiscriminator());726727// Add name to the name table, we do this here because we're guaranteed728// to have concrete versions of our DW_TAG_inlined_subprogram nodes.729DD->addSubprogramNames(*this, CUNode->getNameTableKind(), InlinedSP,730*ScopeDIE);731732return ScopeDIE;733}734735// Construct new DW_TAG_lexical_block for this scope and attach736// DW_AT_low_pc/DW_AT_high_pc labels.737DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {738if (DD->isLexicalScopeDIENull(Scope))739return nullptr;740const auto *DS = Scope->getScopeNode();741742auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);743if (Scope->isAbstractScope()) {744assert(!getAbstractScopeDIEs().count(DS) &&745"Abstract DIE for this scope exists!");746getAbstractScopeDIEs()[DS] = ScopeDIE;747return ScopeDIE;748}749if (!Scope->getInlinedAt()) {750assert(!LexicalBlockDIEs.count(DS) &&751"Concrete out-of-line DIE for this scope exists!");752LexicalBlockDIEs[DS] = ScopeDIE;753}754755attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());756757return ScopeDIE;758}759760DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {761auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag());762insertDIE(DV.getVariable(), VariableDie);763DV.setDIE(*VariableDie);764// Abstract variables don't get common attributes later, so apply them now.765if (Abstract) {766applyCommonDbgVariableAttributes(DV, *VariableDie);767} else {768std::visit(769[&](const auto &V) {770applyConcreteDbgVariableAttributes(V, DV, *VariableDie);771},772DV.asVariant());773}774return VariableDie;775}776777void DwarfCompileUnit::applyConcreteDbgVariableAttributes(778const Loc::Single &Single, const DbgVariable &DV, DIE &VariableDie) {779const DbgValueLoc *DVal = &Single.getValueLoc();780if (!DVal->isVariadic()) {781const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();782if (Entry->isLocation()) {783addVariableAddress(DV, VariableDie, Entry->getLoc());784} else if (Entry->isInt()) {785auto *Expr = Single.getExpr();786if (Expr && Expr->getNumElements()) {787DIELoc *Loc = new (DIEValueAllocator) DIELoc;788DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);789// If there is an expression, emit raw unsigned bytes.790DwarfExpr.addFragmentOffset(Expr);791DwarfExpr.addUnsignedConstant(Entry->getInt());792DwarfExpr.addExpression(Expr);793addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());794if (DwarfExpr.TagOffset)795addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,796dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);797} else798addConstantValue(VariableDie, Entry->getInt(), DV.getType());799} else if (Entry->isConstantFP()) {800addConstantFPValue(VariableDie, Entry->getConstantFP());801} else if (Entry->isConstantInt()) {802addConstantValue(VariableDie, Entry->getConstantInt(), DV.getType());803} else if (Entry->isTargetIndexLocation()) {804DIELoc *Loc = new (DIEValueAllocator) DIELoc;805DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);806const DIBasicType *BT = dyn_cast<DIBasicType>(807static_cast<const Metadata *>(DV.getVariable()->getType()));808DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);809addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());810}811return;812}813// If any of the location entries are registers with the value 0,814// then the location is undefined.815if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {816return Entry.isLocation() && !Entry.getLoc().getReg();817}))818return;819const DIExpression *Expr = Single.getExpr();820assert(Expr && "Variadic Debug Value must have an Expression.");821DIELoc *Loc = new (DIEValueAllocator) DIELoc;822DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);823DwarfExpr.addFragmentOffset(Expr);824DIExpressionCursor Cursor(Expr);825const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();826827auto AddEntry = [&](const DbgValueLocEntry &Entry,828DIExpressionCursor &Cursor) {829if (Entry.isLocation()) {830if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,831Entry.getLoc().getReg()))832return false;833} else if (Entry.isInt()) {834// If there is an expression, emit raw unsigned bytes.835DwarfExpr.addUnsignedConstant(Entry.getInt());836} else if (Entry.isConstantFP()) {837// DwarfExpression does not support arguments wider than 64 bits838// (see PR52584).839// TODO: Consider chunking expressions containing overly wide840// arguments into separate pointer-sized fragment expressions.841APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();842if (RawBytes.getBitWidth() > 64)843return false;844DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());845} else if (Entry.isConstantInt()) {846APInt RawBytes = Entry.getConstantInt()->getValue();847if (RawBytes.getBitWidth() > 64)848return false;849DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());850} else if (Entry.isTargetIndexLocation()) {851TargetIndexLocation Loc = Entry.getTargetIndexLocation();852// TODO TargetIndexLocation is a target-independent. Currently853// only the WebAssembly-specific encoding is supported.854assert(Asm->TM.getTargetTriple().isWasm());855DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));856} else {857llvm_unreachable("Unsupported Entry type.");858}859return true;860};861862if (!DwarfExpr.addExpression(863std::move(Cursor),864[&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {865return AddEntry(DVal->getLocEntries()[Idx], Cursor);866}))867return;868869// Now attach the location information to the DIE.870addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());871if (DwarfExpr.TagOffset)872addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,873*DwarfExpr.TagOffset);874}875876void DwarfCompileUnit::applyConcreteDbgVariableAttributes(877const Loc::Multi &Multi, const DbgVariable &DV, DIE &VariableDie) {878addLocationList(VariableDie, dwarf::DW_AT_location,879Multi.getDebugLocListIndex());880auto TagOffset = Multi.getDebugLocListTagOffset();881if (TagOffset)882addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,883*TagOffset);884}885886void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,887const DbgVariable &DV,888DIE &VariableDie) {889std::optional<unsigned> NVPTXAddressSpace;890DIELoc *Loc = new (DIEValueAllocator) DIELoc;891DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);892for (const auto &Fragment : MMI.getFrameIndexExprs()) {893Register FrameReg;894const DIExpression *Expr = Fragment.Expr;895const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();896StackOffset Offset =897TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);898DwarfExpr.addFragmentOffset(Expr);899900auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();901SmallVector<uint64_t, 8> Ops;902TRI->getOffsetOpcodes(Offset, Ops);903904// According to905// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf906// cuda-gdb requires DW_AT_address_class for all variables to be907// able to correctly interpret address space of the variable908// address. Decode DW_OP_constu <DWARF Address Space> DW_OP_swap909// DW_OP_xderef sequence for the NVPTX + gdb target.910unsigned LocalNVPTXAddressSpace;911if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {912const DIExpression *NewExpr =913DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);914if (NewExpr != Expr) {915Expr = NewExpr;916NVPTXAddressSpace = LocalNVPTXAddressSpace;917}918}919if (Expr)920Ops.append(Expr->elements_begin(), Expr->elements_end());921DIExpressionCursor Cursor(Ops);922DwarfExpr.setMemoryLocationKind();923if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())924addOpAddress(*Loc, FrameSymbol);925else926DwarfExpr.addMachineRegExpression(927*Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);928DwarfExpr.addExpression(std::move(Cursor));929}930if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {931// According to932// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf933// cuda-gdb requires DW_AT_address_class for all variables to be934// able to correctly interpret address space of the variable935// address.936const unsigned NVPTX_ADDR_local_space = 6;937addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,938NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));939}940addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());941if (DwarfExpr.TagOffset)942addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,943*DwarfExpr.TagOffset);944}945946void DwarfCompileUnit::applyConcreteDbgVariableAttributes(947const Loc::EntryValue &EntryValue, const DbgVariable &DV,948DIE &VariableDie) {949DIELoc *Loc = new (DIEValueAllocator) DIELoc;950DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);951// Emit each expression as: EntryValue(Register) <other ops> <Fragment>.952for (auto [Register, Expr] : EntryValue.EntryValues) {953DwarfExpr.addFragmentOffset(&Expr);954DIExpressionCursor Cursor(Expr.getElements());955DwarfExpr.beginEntryValueExpression(Cursor);956DwarfExpr.addMachineRegExpression(957*Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);958DwarfExpr.addExpression(std::move(Cursor));959}960addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());961}962963void DwarfCompileUnit::applyConcreteDbgVariableAttributes(964const std::monostate &, const DbgVariable &DV, DIE &VariableDie) {}965966DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,967const LexicalScope &Scope,968DIE *&ObjectPointer) {969auto Var = constructVariableDIE(DV, Scope.isAbstractScope());970if (DV.isObjectPointer())971ObjectPointer = Var;972return Var;973}974975DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,976const LexicalScope &Scope) {977auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());978insertDIE(DL.getLabel(), LabelDie);979DL.setDIE(*LabelDie);980981if (Scope.isAbstractScope())982applyLabelAttributes(DL, *LabelDie);983984return LabelDie;985}986987/// Return all DIVariables that appear in count: expressions.988static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {989SmallVector<const DIVariable *, 2> Result;990auto *Array = dyn_cast<DICompositeType>(Var->getType());991if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)992return Result;993if (auto *DLVar = Array->getDataLocation())994Result.push_back(DLVar);995if (auto *AsVar = Array->getAssociated())996Result.push_back(AsVar);997if (auto *AlVar = Array->getAllocated())998Result.push_back(AlVar);999for (auto *El : Array->getElements()) {1000if (auto *Subrange = dyn_cast<DISubrange>(El)) {1001if (auto Count = Subrange->getCount())1002if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1003Result.push_back(Dependency);1004if (auto LB = Subrange->getLowerBound())1005if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1006Result.push_back(Dependency);1007if (auto UB = Subrange->getUpperBound())1008if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1009Result.push_back(Dependency);1010if (auto ST = Subrange->getStride())1011if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1012Result.push_back(Dependency);1013} else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {1014if (auto Count = GenericSubrange->getCount())1015if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1016Result.push_back(Dependency);1017if (auto LB = GenericSubrange->getLowerBound())1018if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1019Result.push_back(Dependency);1020if (auto UB = GenericSubrange->getUpperBound())1021if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1022Result.push_back(Dependency);1023if (auto ST = GenericSubrange->getStride())1024if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1025Result.push_back(Dependency);1026}1027}1028return Result;1029}10301031/// Sort local variables so that variables appearing inside of helper1032/// expressions come first.1033static SmallVector<DbgVariable *, 8>1034sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {1035SmallVector<DbgVariable *, 8> Result;1036SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;1037// Map back from a DIVariable to its containing DbgVariable.1038SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;1039// Set of DbgVariables in Result.1040SmallDenseSet<DbgVariable *, 8> Visited;1041// For cycle detection.1042SmallDenseSet<DbgVariable *, 8> Visiting;10431044// Initialize the worklist and the DIVariable lookup table.1045for (auto *Var : reverse(Input)) {1046DbgVar.insert({Var->getVariable(), Var});1047WorkList.push_back({Var, 0});1048}10491050// Perform a stable topological sort by doing a DFS.1051while (!WorkList.empty()) {1052auto Item = WorkList.back();1053DbgVariable *Var = Item.getPointer();1054bool visitedAllDependencies = Item.getInt();1055WorkList.pop_back();10561057assert(Var);10581059// Already handled.1060if (Visited.count(Var))1061continue;10621063// Add to Result if all dependencies are visited.1064if (visitedAllDependencies) {1065Visited.insert(Var);1066Result.push_back(Var);1067continue;1068}10691070// Detect cycles.1071auto Res = Visiting.insert(Var);1072if (!Res.second) {1073assert(false && "dependency cycle in local variables");1074return Result;1075}10761077// Push dependencies and this node onto the worklist, so that this node is1078// visited again after all of its dependencies are handled.1079WorkList.push_back({Var, 1});1080for (const auto *Dependency : dependencies(Var)) {1081// Don't add dependency if it is in a different lexical scope or a global.1082if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))1083if (DbgVariable *Var = DbgVar.lookup(Dep))1084WorkList.push_back({Var, 0});1085}1086}1087return Result;1088}10891090DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,1091LexicalScope *Scope) {1092DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);10931094if (Scope) {1095assert(!Scope->getInlinedAt());1096assert(!Scope->isAbstractScope());1097// Collect lexical scope children first.1098// ObjectPointer might be a local (non-argument) local variable if it's a1099// block's synthetic this pointer.1100if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))1101addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);1102}11031104// If this is a variadic function, add an unspecified parameter.1105DITypeRefArray FnArgs = Sub->getType()->getTypeArray();11061107// If we have a single element of null, it is a function that returns void.1108// If we have more than one elements and the last one is null, it is a1109// variadic function.1110if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&1111!includeMinimalInlineScopes())1112ScopeDIE.addChild(1113DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));11141115return ScopeDIE;1116}11171118DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,1119DIE &ScopeDIE) {1120DIE *ObjectPointer = nullptr;11211122// Emit function arguments (order is significant).1123auto Vars = DU->getScopeVariables().lookup(Scope);1124for (auto &DV : Vars.Args)1125ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));11261127// Emit local variables.1128auto Locals = sortLocalVars(Vars.Locals);1129for (DbgVariable *DV : Locals)1130ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));11311132// Emit labels.1133for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))1134ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));11351136// Track other local entities (skipped in gmlt-like data).1137// This creates mapping between CU and a set of local declarations that1138// should be emitted for subprograms in this CU.1139if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) {1140auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode());1141DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end());1142}11431144// Emit inner lexical scopes.1145auto skipLexicalScope = [this](LexicalScope *S) -> bool {1146if (isa<DISubprogram>(S->getScopeNode()))1147return false;1148auto Vars = DU->getScopeVariables().lookup(S);1149if (!Vars.Args.empty() || !Vars.Locals.empty())1150return false;1151return includeMinimalInlineScopes() ||1152DD->getLocalDeclsForScope(S->getScopeNode()).empty();1153};1154for (LexicalScope *LS : Scope->getChildren()) {1155// If the lexical block doesn't have non-scope children, skip1156// its emission and put its children directly to the parent scope.1157if (skipLexicalScope(LS))1158createAndAddScopeChildren(LS, ScopeDIE);1159else1160constructScopeDIE(LS, ScopeDIE);1161}11621163return ObjectPointer;1164}11651166void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(1167LexicalScope *Scope) {1168auto *SP = cast<DISubprogram>(Scope->getScopeNode());1169if (getAbstractScopeDIEs().count(SP))1170return;11711172DIE *ContextDIE;1173DwarfCompileUnit *ContextCU = this;11741175if (includeMinimalInlineScopes())1176ContextDIE = &getUnitDie();1177// Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with1178// the important distinction that the debug node is not associated with the1179// DIE (since the debug node will be associated with the concrete DIE, if1180// any). It could be refactored to some common utility function.1181else if (auto *SPDecl = SP->getDeclaration()) {1182ContextDIE = &getUnitDie();1183getOrCreateSubprogramDIE(SPDecl);1184} else {1185ContextDIE = getOrCreateContextDIE(SP->getScope());1186// The scope may be shared with a subprogram that has already been1187// constructed in another CU, in which case we need to construct this1188// subprogram in the same CU.1189ContextCU = DD->lookupCU(ContextDIE->getUnitDie());1190}11911192// Passing null as the associated node because the abstract definition1193// shouldn't be found by lookup.1194DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,1195*ContextDIE, nullptr);11961197// Store the DIE before creating children.1198ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;11991200ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef);1201ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,1202DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()1203: dwarf::DW_FORM_implicit_const,1204dwarf::DW_INL_inlined);1205if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef))1206ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);1207}12081209bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {1210return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();1211}12121213dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {1214if (!useGNUAnalogForDwarf5Feature())1215return Tag;1216switch (Tag) {1217case dwarf::DW_TAG_call_site:1218return dwarf::DW_TAG_GNU_call_site;1219case dwarf::DW_TAG_call_site_parameter:1220return dwarf::DW_TAG_GNU_call_site_parameter;1221default:1222llvm_unreachable("DWARF5 tag with no GNU analog");1223}1224}12251226dwarf::Attribute1227DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {1228if (!useGNUAnalogForDwarf5Feature())1229return Attr;1230switch (Attr) {1231case dwarf::DW_AT_call_all_calls:1232return dwarf::DW_AT_GNU_all_call_sites;1233case dwarf::DW_AT_call_target:1234return dwarf::DW_AT_GNU_call_site_target;1235case dwarf::DW_AT_call_origin:1236return dwarf::DW_AT_abstract_origin;1237case dwarf::DW_AT_call_return_pc:1238return dwarf::DW_AT_low_pc;1239case dwarf::DW_AT_call_value:1240return dwarf::DW_AT_GNU_call_site_value;1241case dwarf::DW_AT_call_tail_call:1242return dwarf::DW_AT_GNU_tail_call;1243default:1244llvm_unreachable("DWARF5 attribute with no GNU analog");1245}1246}12471248dwarf::LocationAtom1249DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {1250if (!useGNUAnalogForDwarf5Feature())1251return Loc;1252switch (Loc) {1253case dwarf::DW_OP_entry_value:1254return dwarf::DW_OP_GNU_entry_value;1255default:1256llvm_unreachable("DWARF5 location atom with no GNU analog");1257}1258}12591260DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,1261const DISubprogram *CalleeSP,1262bool IsTail,1263const MCSymbol *PCAddr,1264const MCSymbol *CallAddr,1265unsigned CallReg) {1266// Insert a call site entry DIE within ScopeDIE.1267DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),1268ScopeDIE, nullptr);12691270if (CallReg) {1271// Indirect call.1272addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),1273MachineLocation(CallReg));1274} else {1275DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);1276assert(CalleeDIE && "Could not create DIE for call site entry origin");1277if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&1278!CalleeSP->isDefinition() &&1279!CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {1280addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());1281}12821283addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),1284*CalleeDIE);1285}12861287if (IsTail) {1288// Attach DW_AT_call_tail_call to tail calls for standards compliance.1289addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));12901291// Attach the address of the branch instruction to allow the debugger to1292// show where the tail call occurred. This attribute has no GNU analog.1293//1294// GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF41295// mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call1296// site entries to figure out the PC of tail-calling branch instructions.1297// This means it doesn't need the compiler to emit DW_AT_call_pc, so we1298// don't emit it here.1299//1300// There's no need to tie non-GDB debuggers to this non-standardness, as it1301// adds unnecessary complexity to the debugger. For non-GDB debuggers, emit1302// the standard DW_AT_call_pc info.1303if (!useGNUAnalogForDwarf5Feature())1304addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);1305}13061307// Attach the return PC to allow the debugger to disambiguate call paths1308// from one function to another.1309//1310// The return PC is only really needed when the call /isn't/ a tail call, but1311// GDB expects it in DWARF4 mode, even for tail calls (see the comment above1312// the DW_AT_call_pc emission logic for an explanation).1313if (!IsTail || useGNUAnalogForDwarf5Feature()) {1314assert(PCAddr && "Missing return PC information for a call");1315addLabelAddress(CallSiteDIE,1316getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);1317}13181319return CallSiteDIE;1320}13211322void DwarfCompileUnit::constructCallSiteParmEntryDIEs(1323DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {1324for (const auto &Param : Params) {1325unsigned Register = Param.getRegister();1326auto CallSiteDieParam =1327DIE::get(DIEValueAllocator,1328getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));1329insertDIE(CallSiteDieParam);1330addAddress(*CallSiteDieParam, dwarf::DW_AT_location,1331MachineLocation(Register));13321333DIELoc *Loc = new (DIEValueAllocator) DIELoc;1334DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1335DwarfExpr.setCallSiteParamValueFlag();13361337DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);13381339addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),1340DwarfExpr.finalize());13411342CallSiteDIE.addChild(CallSiteDieParam);1343}1344}13451346DIE *DwarfCompileUnit::constructImportedEntityDIE(1347const DIImportedEntity *Module) {1348DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());1349insertDIE(Module, IMDie);1350DIE *EntityDie;1351auto *Entity = Module->getEntity();1352if (auto *NS = dyn_cast<DINamespace>(Entity))1353EntityDie = getOrCreateNameSpace(NS);1354else if (auto *M = dyn_cast<DIModule>(Entity))1355EntityDie = getOrCreateModule(M);1356else if (auto *SP = dyn_cast<DISubprogram>(Entity)) {1357// If there is an abstract subprogram, refer to it. Note that this assumes1358// that all the abstract subprograms have been already created (which is1359// correct until imported entities get emitted in DwarfDebug::endModule()).1360if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))1361EntityDie = AbsSPDie;1362else1363EntityDie = getOrCreateSubprogramDIE(SP);1364} else if (auto *T = dyn_cast<DIType>(Entity))1365EntityDie = getOrCreateTypeDIE(T);1366else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))1367EntityDie = getOrCreateGlobalVariableDIE(GV, {});1368else if (auto *IE = dyn_cast<DIImportedEntity>(Entity))1369EntityDie = getOrCreateImportedEntityDIE(IE);1370else1371EntityDie = getDIE(Entity);1372assert(EntityDie);1373addSourceLine(*IMDie, Module->getLine(), Module->getFile());1374addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);1375StringRef Name = Module->getName();1376if (!Name.empty()) {1377addString(*IMDie, dwarf::DW_AT_name, Name);13781379// FIXME: if consumers ever start caring about handling1380// unnamed import declarations such as `using ::nullptr_t`1381// or `using namespace std::ranges`, we could add the1382// import declaration into the accelerator table with the1383// name being the one of the entity being imported.1384DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, *IMDie);1385}13861387// This is for imported module with renamed entities (such as variables and1388// subprograms).1389DINodeArray Elements = Module->getElements();1390for (const auto *Element : Elements) {1391if (!Element)1392continue;1393IMDie->addChild(1394constructImportedEntityDIE(cast<DIImportedEntity>(Element)));1395}13961397return IMDie;1398}13991400DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(1401const DIImportedEntity *IE) {14021403// Check for pre-existence.1404if (DIE *Die = getDIE(IE))1405return Die;14061407DIE *ContextDIE = getOrCreateContextDIE(IE->getScope());1408assert(ContextDIE && "Empty scope for the imported entity!");14091410DIE *IMDie = constructImportedEntityDIE(IE);1411ContextDIE->addChild(IMDie);1412return IMDie;1413}14141415void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {1416DIE *D = getDIE(SP);1417if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {1418if (D)1419// If this subprogram has an abstract definition, reference that1420addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);1421} else {1422assert(D || includeMinimalInlineScopes());1423if (D)1424// And attach the attributes1425applySubprogramAttributesToDefinition(SP, *D);1426}1427}14281429void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {1430DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());14311432auto *Die = Entity->getDIE();1433/// Label may be used to generate DW_AT_low_pc, so put it outside1434/// if/else block.1435const DbgLabel *Label = nullptr;1436if (AbsEntity && AbsEntity->getDIE()) {1437addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());1438Label = dyn_cast<const DbgLabel>(Entity);1439} else {1440if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))1441applyCommonDbgVariableAttributes(*Var, *Die);1442else if ((Label = dyn_cast<const DbgLabel>(Entity)))1443applyLabelAttributes(*Label, *Die);1444else1445llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");1446}14471448if (!Label)1449return;14501451const auto *Sym = Label->getSymbol();1452if (!Sym)1453return;14541455addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);14561457// A TAG_label with a name and an AT_low_pc must be placed in debug_names.1458if (StringRef Name = Label->getName(); !Name.empty())1459getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die);1460}14611462DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {1463auto &AbstractEntities = getAbstractEntities();1464auto I = AbstractEntities.find(Node);1465if (I != AbstractEntities.end())1466return I->second.get();1467return nullptr;1468}14691470void DwarfCompileUnit::createAbstractEntity(const DINode *Node,1471LexicalScope *Scope) {1472assert(Scope && Scope->isAbstractScope());1473auto &Entity = getAbstractEntities()[Node];1474if (isa<const DILocalVariable>(Node)) {1475Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),1476nullptr /* IA */);1477DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));1478} else if (isa<const DILabel>(Node)) {1479Entity = std::make_unique<DbgLabel>(1480cast<const DILabel>(Node), nullptr /* IA */);1481DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));1482}1483}14841485void DwarfCompileUnit::emitHeader(bool UseOffsets) {1486// Don't bother labeling the .dwo unit, as its offset isn't used.1487if (!Skeleton && !DD->useSectionsAsReferences()) {1488LabelBegin = Asm->createTempSymbol("cu_begin");1489Asm->OutStreamer->emitLabel(LabelBegin);1490}14911492dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile1493: DD->useSplitDwarf() ? dwarf::DW_UT_skeleton1494: dwarf::DW_UT_compile;1495DwarfUnit::emitCommonHeader(UseOffsets, UT);1496if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)1497Asm->emitInt64(getDWOId());1498}14991500bool DwarfCompileUnit::hasDwarfPubSections() const {1501switch (CUNode->getNameTableKind()) {1502case DICompileUnit::DebugNameTableKind::None:1503return false;1504// Opting in to GNU Pubnames/types overrides the default to ensure these are1505// generated for things like Gold's gdb_index generation.1506case DICompileUnit::DebugNameTableKind::GNU:1507return true;1508case DICompileUnit::DebugNameTableKind::Apple:1509return false;1510case DICompileUnit::DebugNameTableKind::Default:1511return DD->tuneForGDB() && !includeMinimalInlineScopes() &&1512!CUNode->isDebugDirectivesOnly() &&1513DD->getAccelTableKind() != AccelTableKind::Apple &&1514DD->getDwarfVersion() < 5;1515}1516llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");1517}15181519/// addGlobalName - Add a new global name to the compile unit.1520void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,1521const DIScope *Context) {1522if (!hasDwarfPubSections())1523return;1524std::string FullName = getParentContextString(Context) + Name.str();1525GlobalNames[FullName] = &Die;1526}15271528void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,1529const DIScope *Context) {1530if (!hasDwarfPubSections())1531return;1532std::string FullName = getParentContextString(Context) + Name.str();1533// Insert, allowing the entry to remain as-is if it's already present1534// This way the CU-level type DIE is preferred over the "can't describe this1535// type as a unit offset because it's not really in the CU at all, it's only1536// in a type unit"1537GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));1538}15391540/// Add a new global type to the unit.1541void DwarfCompileUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die,1542const DIScope *Context) {1543if (!hasDwarfPubSections())1544return;1545std::string FullName = getParentContextString(Context) + Ty->getName().str();1546GlobalTypes[FullName] = &Die;1547}15481549void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,1550const DIScope *Context) {1551if (!hasDwarfPubSections())1552return;1553std::string FullName = getParentContextString(Context) + Ty->getName().str();1554// Insert, allowing the entry to remain as-is if it's already present1555// This way the CU-level type DIE is preferred over the "can't describe this1556// type as a unit offset because it's not really in the CU at all, it's only1557// in a type unit"1558GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));1559}15601561void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,1562MachineLocation Location) {1563auto *Single = std::get_if<Loc::Single>(&DV);1564if (Single && Single->getExpr())1565addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location);1566else1567addAddress(Die, dwarf::DW_AT_location, Location);1568}15691570/// Add an address attribute to a die based on the location provided.1571void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,1572const MachineLocation &Location) {1573DIELoc *Loc = new (DIEValueAllocator) DIELoc;1574DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1575if (Location.isIndirect())1576DwarfExpr.setMemoryLocationKind();15771578DIExpressionCursor Cursor({});1579const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1580if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1581return;1582DwarfExpr.addExpression(std::move(Cursor));15831584// Now attach the location information to the DIE.1585addBlock(Die, Attribute, DwarfExpr.finalize());15861587if (DwarfExpr.TagOffset)1588addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1589*DwarfExpr.TagOffset);1590}15911592/// Start with the address based on the location provided, and generate the1593/// DWARF information necessary to find the actual variable given the extra1594/// address information encoded in the DbgVariable, starting from the starting1595/// location. Add the DWARF information to the die.1596void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,1597dwarf::Attribute Attribute,1598const MachineLocation &Location) {1599DIELoc *Loc = new (DIEValueAllocator) DIELoc;1600DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1601DwarfExpr.addFragmentOffset(DIExpr);1602DwarfExpr.setLocation(Location, DIExpr);16031604DIExpressionCursor Cursor(DIExpr);16051606if (DIExpr->isEntryValue())1607DwarfExpr.beginEntryValueExpression(Cursor);16081609const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1610if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1611return;1612DwarfExpr.addExpression(std::move(Cursor));16131614// Now attach the location information to the DIE.1615addBlock(Die, Attribute, DwarfExpr.finalize());16161617if (DwarfExpr.TagOffset)1618addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1619*DwarfExpr.TagOffset);1620}16211622/// Add a Dwarf loclistptr attribute data and value.1623void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,1624unsigned Index) {1625dwarf::Form Form = (DD->getDwarfVersion() >= 5)1626? dwarf::DW_FORM_loclistx1627: DD->getDwarfSectionOffsetForm();1628addAttribute(Die, Attribute, Form, DIELocList(Index));1629}16301631void DwarfCompileUnit::applyCommonDbgVariableAttributes(const DbgVariable &Var,1632DIE &VariableDie) {1633StringRef Name = Var.getName();1634if (!Name.empty())1635addString(VariableDie, dwarf::DW_AT_name, Name);1636const auto *DIVar = Var.getVariable();1637if (DIVar) {1638if (uint32_t AlignInBytes = DIVar->getAlignInBytes())1639addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1640AlignInBytes);1641addAnnotation(VariableDie, DIVar->getAnnotations());1642}16431644addSourceLine(VariableDie, DIVar);1645addType(VariableDie, Var.getType());1646if (Var.isArtificial())1647addFlag(VariableDie, dwarf::DW_AT_artificial);1648}16491650void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,1651DIE &LabelDie) {1652StringRef Name = Label.getName();1653if (!Name.empty())1654addString(LabelDie, dwarf::DW_AT_name, Name);1655const auto *DILabel = Label.getLabel();1656addSourceLine(LabelDie, DILabel);1657}16581659/// Add a Dwarf expression attribute data and value.1660void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,1661const MCExpr *Expr) {1662addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));1663}16641665void DwarfCompileUnit::applySubprogramAttributesToDefinition(1666const DISubprogram *SP, DIE &SPDie) {1667auto *SPDecl = SP->getDeclaration();1668auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();1669applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());1670addGlobalName(SP->getName(), SPDie, Context);1671}16721673bool DwarfCompileUnit::isDwoUnit() const {1674return DD->useSplitDwarf() && Skeleton;1675}16761677void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {1678constructTypeDIE(D, CTy);1679}16801681bool DwarfCompileUnit::includeMinimalInlineScopes() const {1682return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||1683(DD->useSplitDwarf() && !Skeleton);1684}16851686void DwarfCompileUnit::addAddrTableBase() {1687const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1688MCSymbol *Label = DD->getAddressPool().getLabel();1689addSectionLabel(getUnitDie(),1690DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base1691: dwarf::DW_AT_GNU_addr_base,1692Label, TLOF.getDwarfAddrSection()->getBeginSymbol());1693}16941695void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {1696addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,1697new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));1698}16991700void DwarfCompileUnit::createBaseTypeDIEs() {1701// Insert the base_type DIEs directly after the CU so that their offsets will1702// fit in the fixed size ULEB128 used inside the location expressions.1703// Maintain order by iterating backwards and inserting to the front of CU1704// child list.1705for (auto &Btr : reverse(ExprRefedBaseTypes)) {1706DIE &Die = getUnitDie().addChildFront(1707DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));1708SmallString<32> Str;1709addString(Die, dwarf::DW_AT_name,1710Twine(dwarf::AttributeEncodingString(Btr.Encoding) +1711"_" + Twine(Btr.BitSize)).toStringRef(Str));1712addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);1713// Round up to smallest number of bytes that contains this number of bits.1714addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,1715divideCeil(Btr.BitSize, 8));17161717Btr.Die = &Die;1718}1719}17201721DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) {1722// Assume if there is an abstract tree all the DIEs are already emitted.1723bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());1724if (isAbstract && getAbstractScopeDIEs().count(LB))1725return getAbstractScopeDIEs()[LB];1726assert(!isAbstract && "Missed lexical block DIE in abstract tree!");17271728// Return a concrete DIE if it exists or nullptr otherwise.1729return LexicalBlockDIEs.lookup(LB);1730}17311732DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {1733if (isa_and_nonnull<DILocalScope>(Context)) {1734if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))1735Context = LFScope->getNonLexicalBlockFileScope();1736if (auto *LScope = dyn_cast<DILexicalBlock>(Context))1737return getLexicalBlockDIE(LScope);17381739// Otherwise the context must be a DISubprogram.1740auto *SPScope = cast<DISubprogram>(Context);1741if (getAbstractScopeDIEs().count(SPScope))1742return getAbstractScopeDIEs()[SPScope];1743}1744return DwarfUnit::getOrCreateContextDIE(Context);1745}174617471748