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