1//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file contains support for constructing a dwarf compile unit. 11//===----------------------------------------------------------------------===// 45/// Query value using AddLinkageNamesToDeclCallOriginsForTuning. 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."));
53"emit-func-debug-line-table-offsets",
cl::Hidden,
54cl::desc(
"Include line table offset in function's debug info and emit end " 55"sequence after each function's line data."),
67// According to DWARF Debugging Information Format Version 5, 68// 3.1.2 Skeleton Compilation Unit Entries: 69// "When generating a split DWARF object file (see Section 7.3.2 70// on page 187), the compilation unit in the .debug_info section 71// is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit" 73return dwarf::DW_TAG_skeleton_unit;
75return dwarf::DW_TAG_compile_unit;
86/// addLabelAddress - Add a dwarf label attribute data and value using 87/// DW_FORM_addr or DW_FORM_GNU_addr_index. 93// Don't use the address pool in non-fission or in the skeleton unit itself. 97bool UseAddrOffsetFormOrExpressions =
101if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
108 : dwarf::DW_FORM_GNU_addr_index,
113// Could be extended to work with DWARFv4 Split DWARF if that's important for 114// someone. In that case DW_FORM_data would be used. 116"Addr+offset expressions are only valuable when using debug_addr (to " 117"reduce relocations) available in DWARFv5 or higher");
138// If we print assembly, we can't separate .file entries according to 139// compile units. Thus all files will belong to the default compile unit. 141// FIXME: add a better feature test than hasRawTextSupport. Even better, 142// extend .file to support this. 145returnAsm->
OutStreamer->emitDwarfFileDirective(0,
"",
"", std::nullopt,
148if (LastFile != File) {
152 File->getSource(), CUID);
159// Check for pre-existence. 168auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) :
nullptr;
177assert(SDMDecl->isStaticMember() &&
"Expected static member decl");
179// We need the declaration DIE that is in the static member's class. 181addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
182// If the global variable's type is different from the one in the class 183// member type, assume that it's more specific and also emit it. 184if (GTy != SDMDecl->getBaseType())
190if (!DisplayName.
empty())
197addFlag(*VariableDIE, dwarf::DW_AT_external);
199// Add line number info. 204addFlag(*VariableDIE, dwarf::DW_AT_declaration);
211addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
225bool addToAccelTable =
false;
227 std::optional<unsigned> NVPTXAddressSpace;
228 std::unique_ptr<DIEDwarfExpression> DwarfExpr;
229for (
constauto &GE : GlobalExprs) {
233// For compatibility with DWARF 3 and earlier, 234// DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or 235// DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes 236// DW_AT_const_value(X). 238 addToAccelTable =
true;
247// We cannot describe the location of dllimport'd variables: the 248// computation of their address requires loads from the IAT. 252// Nothing to describe without address or constant. 261 addToAccelTable =
true;
263 DwarfExpr = std::make_unique<DIEDwarfExpression>(*
Asm, *
this, *Loc);
268// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 269// cuda-gdb requires DW_AT_address_class for all variables to be able to 270// correctly interpret address space of the variable address. 271// Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 272// sequence for the NVPTX + gdb target. 273unsigned LocalNVPTXAddressSpace;
279 NVPTXAddressSpace = LocalNVPTXAddressSpace;
282 DwarfExpr->addFragmentOffset(Expr);
287// 16-bit platforms like MSP430 and AVR take this path, so sink this 288// assert to platforms that use it. 289auto GetPointerSizedFormAndOp = [
this]() {
291assert((PointerSize == 4 || PointerSize == 8) &&
292"Add support for other sizes if necessary");
297return PointerSize == 4
298 ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
299 : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
301if (
Global->isThreadLocal()) {
303// FIXME This is not guaranteed, but in practice, in static linking, 304// if present, __tls_base's index is 1. This doesn't hold for dynamic 305// linking, so TLS variables used in dynamic linking won't have 306// correct debug info for now. See 307// https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823 308 addWasmRelocBaseGlobal(Loc,
"__tls_base", 1);
310addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
312// TODO: add debug info for emulated thread local mode. 314// FIXME: Make this work with -gsplit-dwarf. 315// Based on GCC's support for TLS: 317auto FormAndOp = GetPointerSizedFormAndOp();
318// 1) Start with a constNu of the appropriate pointer size 319addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
320// 2) containing the (relocated) offset of the TLS variable 321// within the module's TLS block. 325addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
326addUInt(*Loc, dwarf::DW_FORM_udata,
329// 3) followed by an OP to make the debugger do a TLS lookup. 330addUInt(*Loc, dwarf::DW_FORM_data1,
332 : dwarf::DW_OP_form_tls_address);
336// FIXME This is not guaranteed, but in practice, if present, 337// __memory_base's index is 1. See 338// https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823 339 addWasmRelocBaseGlobal(Loc,
"__memory_base", 1);
341addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
347auto FormAndOp = GetPointerSizedFormAndOp();
349addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
355unsigned DwarfBaseReg =
357addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DwarfBaseReg);
358// Offset from base register 359addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
361addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
367// Global variables attached to symbols are memory locations. 368// It would be better if this were unconditional, but malformed input that 369// mixes non-fragments and fragments for the same variable is too expensive 370// to detect in the verifier. 371if (DwarfExpr->isUnknownLocation())
372 DwarfExpr->setMemoryLocationKind();
373 DwarfExpr->addExpression(Expr);
377// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 378// cuda-gdb requires DW_AT_address_class for all variables to be able to 379// correctly interpret address space of the variable address. 380constunsigned NVPTX_ADDR_global_space = 5;
381addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
382 NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));
385addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
390if (addToAccelTable) {
394// If the linkage name is different than the name, go ahead and output 395// that as well into the name table. 405// Check for pre-existence. 424bool SameAsPrevCU =
this == PrevCU;
426// If we have no current ranges just add the range and return, otherwise, 427// check the current section and CU against the previous section and CU we 428// emitted into and the subprogram was contained within. If these are the 429// same then extend our current range, otherwise add this as a new range. 430if (CURanges.empty() || !SameAsPrevCU ||
431 (&CURanges.back().End->getSection() !=
432 &
Range.End->getSection())) {
433// Before a new range is added, always terminate the prior line table. 436 CURanges.push_back(
Range);
440 CURanges.back().End =
Range.End;
455// DW_AT_stmt_list is a offset of line number information for this 456// compile unit in debug_line section. For split dwarf this is 457// left in the skeleton CU and so not included. 458// The line table entries are not always emitted in assembly, so it 459// is not okay to use line_table_start here. 472assert(Begin &&
"Begin label should not be null!");
473assert(
End &&
"End label should not be null!");
475assert(
End->isDefined() &&
"Invalid end label");
484// Add info for Wasm-global-based relocation. 485// 'GlobalIndex' is used for split dwarf, which currently relies on a few 486// assumptions that are not guaranteed in a formal way but work in practice. 487void DwarfCompileUnit::addWasmRelocBaseGlobal(
DIELoc *Loc,
StringRef GlobalName,
489// FIXME: duplicated from Target/WebAssembly/WebAssembly.h 490// don't want to depend on target specific headers in this code? 491constunsigned TI_GLOBAL_RELOC = 3;
494// FIXME: this repeats what WebAssemblyMCInstLower:: 495// GetExternalSymbolSymbol does, since if there's no code that 496// refers to this symbol, we have to set it here. 502addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
503addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
507// FIXME: when writing dwo, we need to avoid relocations. Probably 508// the "right" solution is to treat globals the way func and data 509// symbols are (with entries in .debug_addr). 510// For now we hardcode the indices in the callsites. Global indices are not 511// fixed, but in practice a few are fixed; for example, __stack_pointer is 513addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);
517// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 518// and DW_AT_high_pc attributes. If there are global variables in this 519// scope then create and insert DIEs for these variables. 524// If basic block sections are on, ranges for each basic block section has 525// to be emitted separately. 527 BB_List.
push_back({R.second.BeginLabel, R.second.EndLabel});
534addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
538 *SPDie, dwarf::DW_AT_LLVM_stmt_sequence, LineTableSym,
542// Only include DW_AT_frame_base in full debug info 547switch (FrameBase.
Kind) {
551addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
557addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
559addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);
561addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
563addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
567// FIXME: duplicated from Target/WebAssembly/WebAssembly.h 568constunsigned TI_GLOBAL_RELOC = 3;
570// These need to be relocatable. 573// For now, since we only ever use index 0, this should work as-is. 574 addWasmRelocBaseGlobal(Loc,
"__stack_pointer",
576addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
577addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
592// Add name to the name table, we do this here because we're guaranteed 593// to have concrete versions of our DW_TAG_subprogram nodes. 599// Construct a DIE for this scope. 601DIE &ParentScopeDIE) {
602if (!Scope || !Scope->getScopeNode())
605auto *DS = Scope->getScopeNode();
607assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
608"Only handle inlined subprograms here, use " 609"constructSubprogramScopeDIE for non-inlined " 612// Emit inlined subprograms. 613if (Scope->getParent() && isa<DISubprogram>(DS)) {
615assert(ScopeDIE &&
"Scope DIE should not be null.");
620// Early exit when we know the scope DIE is going to be null. 624// Emit lexical blocks. 626assert(ScopeDIE &&
"Scope DIE should not be null.");
637// Add the range list to the set of ranges to be emitted. 643auto &
List = *IndexAndList.second;
645// Under fission, ranges are specified by constant offsets relative to the 646// CU's DW_AT_GNU_ranges_base. 647// FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 648// fission until we support the forms using the .debug_addr section 649// (DW_RLE_startx_endx etc.). 651addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
669 (Ranges.size() == 1 &&
672 Ranges.front().Begin))) {
683List.reserve(Ranges.size());
688constauto *BeginMBB = R.first->getParent();
689constauto *EndMBB = R.second->getParent();
691constauto *
MBB = BeginMBB;
692// Basic block sections allows basic block subsets to be placed in unique 693// sections. For each section, the begin and end label must be added to the 694// list. If there is more than one range, debug ranges must be used. 695// Otherwise, low/high PC can be used. 696// FIXME: Debug Info Emission depends on block order and this assumes that 697// the order of blocks will be frozen beyond this point. 703 : MBBSectionRange.BeginLabel,
715DIE &ParentScopeDIE) {
716assert(Scope->getScopeNode());
717auto *DS = Scope->getScopeNode();
719// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 720// was inlined from another compile unit. 721DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];
722assert(OriginDIE &&
"Unable to find original DIE for an inlined subprogram.");
726addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
730// Add the call site information to the DIE. 732addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,
734addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());
736addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());
738addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,
739 IA->getDiscriminator());
741// Add name to the name table, we do this here because we're guaranteed 742// to have concrete versions of our DW_TAG_inlined_subprogram nodes. 749// Construct new DW_TAG_lexical_block for this scope and attach 750// DW_AT_low_pc/DW_AT_high_pc labels. 754constauto *DS = Scope->getScopeNode();
757if (Scope->isAbstractScope()) {
759"Abstract DIE for this scope exists!");
760 getAbstractScopeDIEs()[DS] = ScopeDIE;
763if (!Scope->getInlinedAt()) {
764assert(!LexicalBlockDIEs.count(DS) &&
765"Concrete out-of-line DIE for this scope exists!");
766 LexicalBlockDIEs[DS] = ScopeDIE;
778// Abstract variables don't get common attributes later, so apply them now. 784 applyConcreteDbgVariableAttributes(V, DV, *VariableDie);
791void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
796// Lack of expression means it is a register. Registers for PTX need to 797// be marked with DW_AT_address_class = 2. See 798// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 799addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 2);
803if (Entry->isLocation()) {
805 }
elseif (
Entry->isInt()) {
806auto *Expr =
Single.getExpr();
807if (Expr && Expr->getNumElements()) {
810// If there is an expression, emit raw unsigned bytes. 811 DwarfExpr.addFragmentOffset(Expr);
812 DwarfExpr.addUnsignedConstant(
Entry->getInt());
813 DwarfExpr.addExpression(Expr);
814addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
815if (DwarfExpr.TagOffset)
816addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,
817 dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
820 }
elseif (
Entry->isConstantFP()) {
822 }
elseif (
Entry->isConstantInt()) {
824 }
elseif (
Entry->isTargetIndexLocation()) {
830addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
834// If any of the location entries are registers with the value 0, 835// then the location is undefined. 837 return Entry.isLocation() && !Entry.getLoc().getReg();
841assert(Expr &&
"Variadic Debug Value must have an Expression.");
844 DwarfExpr.addFragmentOffset(Expr);
850if (
Entry.isLocation()) {
851if (!DwarfExpr.addMachineRegExpression(
TRI, Cursor,
852Entry.getLoc().getReg()))
854 }
elseif (
Entry.isInt()) {
855// If there is an expression, emit raw unsigned bytes. 856 DwarfExpr.addUnsignedConstant(
Entry.getInt());
857 }
elseif (
Entry.isConstantFP()) {
858// DwarfExpression does not support arguments wider than 64 bits 860// TODO: Consider chunking expressions containing overly wide 861// arguments into separate pointer-sized fragment expressions. 862APInt RawBytes =
Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
866 }
elseif (
Entry.isConstantInt()) {
867APInt RawBytes =
Entry.getConstantInt()->getValue();
871 }
elseif (
Entry.isTargetIndexLocation()) {
873// TODO TargetIndexLocation is a target-independent. Currently 874// only the WebAssembly-specific encoding is supported. 883if (!DwarfExpr.addExpression(
886 return AddEntry(DVal->getLocEntries()[Idx], Cursor);
890// Now attach the location information to the DIE. 891addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
892if (DwarfExpr.TagOffset)
893addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
894 *DwarfExpr.TagOffset);
897void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
903addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
907void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
constLoc::MMI &MMI,
910 std::optional<unsigned> NVPTXAddressSpace;
919 DwarfExpr.addFragmentOffset(Expr);
923TRI->getOffsetOpcodes(Offset, Ops);
926// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 927// cuda-gdb requires DW_AT_address_class for all variables to be 928// able to correctly interpret address space of the variable 929// address. Decode DW_OP_constu <DWARF Address Space> DW_OP_swap 930// DW_OP_xderef sequence for the NVPTX + gdb target. 931unsigned LocalNVPTXAddressSpace;
937 NVPTXAddressSpace = LocalNVPTXAddressSpace;
943 DwarfExpr.setMemoryLocationKind();
947 DwarfExpr.addMachineRegExpression(
949 DwarfExpr.addExpression(std::move(Cursor));
953// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 954// cuda-gdb requires DW_AT_address_class for all variables to be 955// able to correctly interpret address space of the variable 957constunsigned NVPTX_ADDR_local_space = 6;
958addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
959 NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
961addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
962if (DwarfExpr.TagOffset)
963addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
964 *DwarfExpr.TagOffset);
967void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
972// Emit each expression as: EntryValue(Register) <other ops> <Fragment>. 974 DwarfExpr.addFragmentOffset(&Expr);
976 DwarfExpr.beginEntryValueExpression(Cursor);
977 DwarfExpr.addMachineRegExpression(
979 DwarfExpr.addExpression(std::move(Cursor));
981addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
984void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
989DIE *&ObjectPointer) {
1000DL.setDIE(*LabelDie);
1002if (Scope.isAbstractScope())
1008/// Return all DIVariables that appear in count: expressions. 1011auto *Array = dyn_cast<DICompositeType>(Var->
getType());
1012if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
1014if (
auto *DLVar = Array->getDataLocation())
1015 Result.push_back(DLVar);
1016if (
auto *AsVar = Array->getAssociated())
1017 Result.push_back(AsVar);
1018if (
auto *AlVar = Array->getAllocated())
1019 Result.push_back(AlVar);
1020for (
auto *El : Array->getElements()) {
1021if (
auto *Subrange = dyn_cast<DISubrange>(El)) {
1022if (
auto Count = Subrange->getCount())
1023if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))
1024 Result.push_back(Dependency);
1025if (
auto LB = Subrange->getLowerBound())
1026if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))
1027 Result.push_back(Dependency);
1028if (
auto UB = Subrange->getUpperBound())
1029if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))
1030 Result.push_back(Dependency);
1031if (
auto ST = Subrange->getStride())
1032if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))
1033 Result.push_back(Dependency);
1034 }
elseif (
auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
1035if (
auto Count = GenericSubrange->getCount())
1036if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))
1037 Result.push_back(Dependency);
1038if (
auto LB = GenericSubrange->getLowerBound())
1039if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))
1040 Result.push_back(Dependency);
1041if (
auto UB = GenericSubrange->getUpperBound())
1042if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))
1043 Result.push_back(Dependency);
1044if (
auto ST = GenericSubrange->getStride())
1045if (
auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))
1046 Result.push_back(Dependency);
1052/// Sort local variables so that variables appearing inside of helper 1053/// expressions come first. 1058// Map back from a DIVariable to its containing DbgVariable. 1060// Set of DbgVariables in Result. 1062// For cycle detection. 1065// Initialize the worklist and the DIVariable lookup table. 1066for (
auto *Var :
reverse(Input)) {
1067 DbgVar.
insert({Var->getVariable(), Var});
1071// Perform a stable topological sort by doing a DFS. 1072while (!WorkList.
empty()) {
1073auto Item = WorkList.
back();
1075bool visitedAllDependencies = Item.getInt();
1081if (Visited.
count(Var))
1084// Add to Result if all dependencies are visited. 1085if (visitedAllDependencies) {
1087 Result.push_back(Var);
1092auto Res = Visiting.
insert(Var);
1094assert(
false &&
"dependency cycle in local variables");
1098// Push dependencies and this node onto the worklist, so that this node is 1099// visited again after all of its dependencies are handled. 1102// Don't add dependency if it is in a different lexical scope or a global. 1103if (
constauto *Dep = dyn_cast<const DILocalVariable>(Dependency))
1117assert(!Scope->getInlinedAt());
1118assert(!Scope->isAbstractScope());
1119// Collect lexical scope children first. 1120// ObjectPointer might be a local (non-argument) local variable if it's a 1121// block's synthetic this pointer. 1123addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
1126// If this is a variadic function, add an unspecified parameter. 1129// If we have a single element of null, it is a function that returns void. 1130// If we have more than one elements and the last one is null, it is a 1131// variadic function. 1132if (FnArgs.
size() > 1 && !FnArgs[FnArgs.
size() - 1] &&
1142DIE *ObjectPointer =
nullptr;
1144// Emit function arguments (order is significant). 1146for (
auto &DV : Vars.Args)
1149// Emit local variables. 1158// Track other local entities (skipped in gmlt-like data). 1159// This creates mapping between CU and a set of local declarations that 1160// should be emitted for subprograms in this CU. 1163 DeferredLocalDecls.
insert(LocalDecls.begin(), LocalDecls.end());
1166// Emit inner lexical scopes. 1167auto skipLexicalScope = [
this](
LexicalScope *S) ->
bool {
1168if (isa<DISubprogram>(S->getScopeNode()))
1171if (!Vars.Args.empty() || !Vars.Locals.empty())
1177// If the lexical block doesn't have non-scope children, skip 1178// its emission and put its children directly to the parent scope. 1179if (skipLexicalScope(LS))
1185return ObjectPointer;
1190auto *SP = cast<DISubprogram>(Scope->getScopeNode());
1191if (getAbstractScopeDIEs().
count(SP))
1199// Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 1200// the important distinction that the debug node is not associated with the 1201// DIE (since the debug node will be associated with the concrete DIE, if 1202// any). It could be refactored to some common utility function. 1203elseif (
auto *SPDecl = SP->getDeclaration()) {
1208// The scope may be shared with a subprogram that has already been 1209// constructed in another CU, in which case we need to construct this 1210// subprogram in the same CU. 1214// Passing null as the associated node because the abstract definition 1215// shouldn't be found by lookup. 1217 *ContextDIE,
nullptr);
1219// Store the DIE before creating children. 1220 ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;
1223 ContextCU->
addSInt(AbsDef, dwarf::DW_AT_inline,
1225 : dwarf::DW_FORM_implicit_const,
1228 ContextCU->
addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
1239case dwarf::DW_TAG_call_site:
1240return dwarf::DW_TAG_GNU_call_site;
1241case dwarf::DW_TAG_call_site_parameter:
1242return dwarf::DW_TAG_GNU_call_site_parameter;
1253case dwarf::DW_AT_call_all_calls:
1254return dwarf::DW_AT_GNU_all_call_sites;
1255case dwarf::DW_AT_call_target:
1256return dwarf::DW_AT_GNU_call_site_target;
1257case dwarf::DW_AT_call_origin:
1258return dwarf::DW_AT_abstract_origin;
1259case dwarf::DW_AT_call_return_pc:
1260return dwarf::DW_AT_low_pc;
1261case dwarf::DW_AT_call_value:
1262return dwarf::DW_AT_GNU_call_site_value;
1263case dwarf::DW_AT_call_tail_call:
1264return dwarf::DW_AT_GNU_tail_call;
1275case dwarf::DW_OP_entry_value:
1276return dwarf::DW_OP_GNU_entry_value;
1288// Insert a call site entry DIE within ScopeDIE. 1298assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
1300 !CalleeSP->isDefinition() &&
1310// Attach DW_AT_call_tail_call to tail calls for standards compliance. 1313// Attach the address of the branch instruction to allow the debugger to 1314// show where the tail call occurred. This attribute has no GNU analog. 1316// GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4 1317// mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call 1318// site entries to figure out the PC of tail-calling branch instructions. 1319// This means it doesn't need the compiler to emit DW_AT_call_pc, so we 1320// don't emit it here. 1322// There's no need to tie non-GDB debuggers to this non-standardness, as it 1323// adds unnecessary complexity to the debugger. For non-GDB debuggers, emit 1324// the standard DW_AT_call_pc info. 1329// Attach the return PC to allow the debugger to disambiguate call paths 1330// from one function to another. 1332// The return PC is only really needed when the call /isn't/ a tail call, but 1333// GDB expects it in DWARF4 mode, even for tail calls (see the comment above 1334// the DW_AT_call_pc emission logic for an explanation). 1336assert(PCAddr &&
"Missing return PC information for a call");
1346for (
constauto &Param : Params) {
1347unsignedRegister = Param.getRegister();
1348auto CallSiteDieParam =
1352addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
1364 CallSiteDIE.
addChild(CallSiteDieParam);
1373auto *Entity =
Module->getEntity();
1374if (
auto *NS = dyn_cast<DINamespace>(Entity))
1376elseif (
auto *M = dyn_cast<DIModule>(Entity))
1378elseif (
auto *SP = dyn_cast<DISubprogram>(Entity)) {
1379// If there is an abstract subprogram, refer to it. Note that this assumes 1380// that all the abstract subprograms have been already created (which is 1381// correct until imported entities get emitted in DwarfDebug::endModule()). 1382if (
auto *AbsSPDie = getAbstractScopeDIEs().
lookup(SP))
1383 EntityDie = AbsSPDie;
1386 }
elseif (
auto *
T = dyn_cast<DIType>(Entity))
1388elseif (
auto *GV = dyn_cast<DIGlobalVariable>(Entity))
1390elseif (
auto *IE = dyn_cast<DIImportedEntity>(Entity))
1393 EntityDie =
getDIE(Entity);
1396addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
1401// FIXME: if consumers ever start caring about handling 1402// unnamed import declarations such as `using ::nullptr_t` 1403// or `using namespace std::ranges`, we could add the 1404// import declaration into the accelerator table with the 1405// name being the one of the entity being imported. 1409// This is for imported module with renamed entities (such as variables and 1411 DINodeArray Elements =
Module->getElements();
1412for (
constauto *Element : Elements) {
1425// Check for pre-existence. 1430assert(ContextDIE &&
"Empty scope for the imported entity!");
1439if (
DIE *AbsSPDIE = getAbstractScopeDIEs().
lookup(SP)) {
1441// If this subprogram has an abstract definition, reference that 1442addDIEEntry(*
D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
1446// And attach the attributes 1454auto *Die = Entity->
getDIE();
1455 /// Label may be used to generate DW_AT_low_pc, so put it outside 1458if (AbsEntity && AbsEntity->
getDIE()) {
1460 Label = dyn_cast<const DbgLabel>(Entity);
1462if (
constDbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
1464elseif ((Label = dyn_cast<const DbgLabel>(Entity)))
1473constauto *
Sym = Label->getSymbol();
1479// A TAG_label with a name and an AT_low_pc must be placed in debug_names. 1485auto &AbstractEntities = getAbstractEntities();
1486autoI = AbstractEntities.find(Node);
1487if (
I != AbstractEntities.end())
1488returnI->second.get();
1494assert(Scope && Scope->isAbstractScope());
1495auto &Entity = getAbstractEntities()[Node];
1496if (isa<const DILocalVariable>(Node)) {
1497 Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
1500 }
elseif (isa<const DILabel>(Node)) {
1501 Entity = std::make_unique<DbgLabel>(
1502 cast<const DILabel>(Node),
nullptr/* IA */);
1508// Don't bother labeling the .dwo unit, as its offset isn't used. 1516 : dwarf::DW_UT_compile;
1526// Opting in to GNU Pubnames/types overrides the default to ensure these are 1527// generated for things like Gold's gdb_index generation. 1541/// addGlobalName - Add a new global name to the compile unit. 1547 GlobalNames[FullName] = &Die;
1555// Insert, allowing the entry to remain as-is if it's already present 1556// This way the CU-level type DIE is preferred over the "can't describe this 1557// type as a unit offset because it's not really in the CU at all, it's only 1559 GlobalNames.insert(std::make_pair(std::move(FullName), &
getUnitDie()));
1562/// Add a new global type to the unit. 1568 GlobalTypes[FullName] = &Die;
1576// Insert, allowing the entry to remain as-is if it's already present 1577// This way the CU-level type DIE is preferred over the "can't describe this 1578// type as a unit offset because it's not really in the CU at all, it's only 1580 GlobalTypes.insert(std::make_pair(std::move(FullName), &
getUnitDie()));
1585auto *Single = std::get_if<Loc::Single>(&DV);
1586if (Single && Single->getExpr())
1589addAddress(Die, dwarf::DW_AT_location, Location);
1592/// Add an address attribute to a die based on the location provided. 1597if (Location.isIndirect())
1606// Now attach the location information to the DIE. 1610addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1614/// Start with the address based on the location provided, and generate the 1615/// DWARF information necessary to find the actual variable given the extra 1616/// address information encoded in the DbgVariable, starting from the starting 1617/// location. Add the DWARF information to the die. 1636// Now attach the location information to the DIE. 1640addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1644/// Add a Dwarf loclistptr attribute data and value. 1648 ? dwarf::DW_FORM_loclistx
1660if (
uint32_t AlignInBytes = DIVar->getAlignInBytes())
1661addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1669addFlag(VariableDie, dwarf::DW_AT_artificial);
1677constauto *
DILabel = Label.getLabel();
1681/// Add a Dwarf expression attribute data and value. 1689auto *SPDecl = SP->getDeclaration();
1695bool DwarfCompileUnit::isDwoUnit()
const{
1717 : dwarf::DW_AT_GNU_addr_base,
1727// Insert the base_type DIEs directly after the CU so that their offsets will 1728// fit in the fixed size ULEB128 used inside the location expressions. 1729// Maintain order by iterating backwards and inserting to the front of CU 1738addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1739// Round up to smallest number of bytes that contains this number of bits. 1740addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
1748// Assume if there is an abstract tree all the DIEs are already emitted. 1749bool isAbstract = getAbstractScopeDIEs().count(LB->
getSubprogram());
1750if (isAbstract && getAbstractScopeDIEs().
count(LB))
1751return getAbstractScopeDIEs()[LB];
1752assert(!isAbstract &&
"Missed lexical block DIE in abstract tree!");
1754// Return a concrete DIE if it exists or nullptr otherwise. 1755return LexicalBlockDIEs.lookup(LB);
1759if (isa_and_nonnull<DILocalScope>(Context)) {
1760if (
auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))
1761 Context = LFScope->getNonLexicalBlockFileScope();
1762if (
auto *LScope = dyn_cast<DILexicalBlock>(Context))
1765// Otherwise the context must be a DISubprogram. 1766auto *SPScope = cast<DISubprogram>(Context);
1767if (getAbstractScopeDIEs().
count(SPScope))
1768return getAbstractScopeDIEs()[SPScope];
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static SmallVector< DbgVariable *, 8 > sortLocalVars(SmallVectorImpl< DbgVariable * > &Input)
Sort local variables so that variables appearing inside of helper expressions come first.
static SmallVector< const DIVariable *, 2 > dependencies(DbgVariable *Var)
Return all DIVariables that appear in count: expressions.
static cl::opt< bool > EmitFuncLineTableOffsetsOption("emit-func-debug-line-table-offsets", cl::Hidden, cl::desc("Include line table offset in function's debug info and emit end " "sequence after each function's line data."), cl::init(false))
static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD)
static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW)
cl::opt< cl::boolOrDefault > AddLinkageNamesToDeclCallOrigins("add-linkage-names-to-declaration-call-origins", cl::Hidden, cl::desc("Add DW_AT_linkage_name to function declaration DIEs " "referenced by DW_AT_call_origin attributes. Enabled by default " "for -gsce debugger tuning."))
Query value using AddLinkageNamesToDeclCallOriginsForTuning.
This file contains constants used for implementing Dwarf debug support.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
MapVector< MBBSectionID, MBBSectionRange > MBBSectionRanges
TargetMachine & TM
Target machine description.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
virtual const MCSymbol * getFunctionFrameSymbol() const
Return symbol for the function pseudo stack if the stack frame is not a register based.
MCSymbol * createTempSymbol(const Twine &Name) const
MCSymbol * GetExternalSymbolSymbol(Twine Sym) const
Return the MCSymbol for the specified ExternalSymbol.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const DataLayout & getDataLayout() const
Return information about data layout.
void emitInt64(uint64_t Value) const
Emit a long long directive and value.
Basic type, like 'int' or 'float'.
unsigned getLineNo() const
StringRef getName() const
DIScope * getScope() const
DIGlobalVariable * getDecl() const
bool isDebugDirectivesOnly() const
static std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
static std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
DIEBlock - Represents a block of values.
DwarfExpression implementation for singular DW_AT_location.
Represents a pointer to a location list in the debug_loc section.
DIELoc - Represents an expression location.
A structured debug information entry.
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
DIE & addChild(DIE *Child)
Add a child to the DIE.
DIE & addChildFront(DIE *Child)
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
Holds a DIExpression and keeps track of how many operands have been consumed so far.
element_iterator elements_end() const
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
element_iterator elements_begin() const
ArrayRef< uint64_t > getElements() const
uint64_t getElement(unsigned I) const
std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
static const DIExpression * extractAddressClass(const DIExpression *Expr, unsigned &AddrClass)
Checks if the last 4 elements of the expression are DW_OP_constu <DWARF Address Space> DW_OP_swap DW_...
DIDerivedType * getStaticDataMemberDeclaration() const
MDTuple * getTemplateParams() const
bool isLocalToUnit() const
StringRef getLinkageName() const
StringRef getDisplayName() const
bool isDefinition() const
DINodeArray getAnnotations() const
An imported module (C++ using directive or similar).
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Tagged DWARF-like metadata node.
dwarf::Tag getTag() const
Base class for scope-like contexts.
StringRef getName() const
DIScope * getScope() const
StringRef getName() const
uint32_t getAlignInBytes() const
DIScope * getScope() const
StringRef getName() const
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size in bytes, rounded up to a whole number of bytes.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
const DINode * getEntity() const
Accessors.
This class is used to track label information.
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
ArrayRef< DbgValueLocEntry > getLocEntries() const
This class is used to track local variable information.
bool isArtificial() const
Return true if DbgVariable is artificial.
dwarf::Tag getTag() const
bool isObjectPointer() const
const DILocalVariable * getVariable() const
StringRef getName() const
const DIType * getType() const
Loc::Variant & asVariant()
To workaround P2162R0 https://github.com/cplusplus/papers/issues/873 the base class subobject needs t...
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool useGNUAnalogForDwarf5Feature() const
Whether to use the GNU analog for a DWARF5 tag, attribute, or location atom.
void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE, SmallVector< DbgCallSiteParam, 4 > &Params)
Construct call site parameter DIEs for the CallSiteDIE.
void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End)
void emitHeader(bool UseOffsets) override
Emit the header for this unit, not including the initial length field.
dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const
This takes a DWARF 5 tag and returns it or a GNU analog.
DIE & updateSubprogramScopeDIE(const DISubprogram *SP, MCSymbol *LineTableSym)
Find DIE for the given subprogram and attach appropriate DW_AT_low_pc, DW_AT_high_pc and DW_AT_LLVM_s...
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
bool includeMinimalInlineScopes() const
DIE * getOrCreateImportedEntityDIE(const DIImportedEntity *IE)
Get or create a DIE for an imported entity.
void addBaseTypeRef(DIEValueList &Die, int64_t Idx)
void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context)
Add a new global name present in a type unit to this compile unit.
void finishEntityDefinition(const DbgEntity *Entity)
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
void addAddrTableBase()
Add the DW_AT_addr_base attribute to the unit DIE.
DIE & constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr, unsigned CallReg)
Construct a call site entry DIE describing a call within Scope to a callee described by CalleeSP.
std::vector< BaseTypeRef > ExprRefedBaseTypes
DIE * constructInlinedScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE)
This scope represents an inlined body of a function.
void createBaseTypeDIEs()
void addScopeRangeList(DIE &ScopeDIE, SmallVector< RangeSpan, 2 > Range)
A helper function to construct a RangeSpanList for a given lexical scope.
uint64_t getDWOId() const
DIE * getOrCreateCommonBlock(const DICommonBlock *CB, ArrayRef< GlobalExpr > GlobalExprs)
void addVariableAddress(const DbgVariable &DV, DIE &Die, MachineLocation Location)
Add DW_AT_location attribute for a DbgVariable based on provided MachineLocation.
DIE * getLexicalBlockDIE(const DILexicalBlock *LB)
Get a DIE for the given DILexicalBlock.
void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override
Add a new global name to the compile unit.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
void applyStmtList(DIE &D)
Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
DIE * getOrCreateContextDIE(const DIScope *Ty) override
Construct a DIE for a given scope.
void applyCommonDbgVariableAttributes(const DbgVariable &Var, DIE &VariableDie)
Add attributes to Var which reflect the common attributes of VariableDie, namely those which are not ...
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
DIE * constructVariableDIE(DbgVariable &DV, bool Abstract=false)
Construct a DIE for the given DbgVariable.
dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const
This takes a DWARF 5 location atom and either returns it or a GNU analog.
DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, ArrayRef< GlobalExpr > GlobalExprs)
Get or create global variable DIE.
void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV, ArrayRef< GlobalExpr > GlobalExprs)
void applySubprogramAttributesToDefinition(const DISubprogram *SP, DIE &SPDie)
DIE * createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE)
void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr)
Add a Dwarf expression attribute data and value.
dwarf::Attribute getDwarf5OrGNUAttr(dwarf::Attribute Attr) const
This takes a DWARF 5 attribute and returns it or a GNU analog.
void addAddress(DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location)
Add an address attribute to a die based on the location provided.
void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie)
void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label)
addLocalLabelAddress - Add a dwarf label attribute data and value using DW_FORM_addr only.
DIE * constructLexicalScopeDIE(LexicalScope *Scope)
Construct new DW_TAG_lexical_block for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context) override
Add a new global type to the compile unit.
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE)
DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, UnitKind Kind=UnitKind::Full)
DIE * constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope)
Construct a DIE for the given DbgLabel.
void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context)
Add a new global type present in a type unit to this compile unit.
DbgEntity * getExistingAbstractEntity(const DINode *Node)
bool hasDwarfPubSections() const
void addLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label)
addLabelAddress - Add a dwarf label attribute data and value using either DW_FORM_addr or DW_FORM_GNU...
void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index)
Add a Dwarf loclistptr attribute data and value.
bool emitFuncLineTableOffsets() const
void addComplexAddress(const DIExpression *DIExpr, DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location)
Start with the address based on the location provided, and generate the DWARF information necessary t...
DIE * constructImportedEntityDIE(const DIImportedEntity *IE)
DwarfCompileUnit & getCU() override
void attachRangesOrLowHighPC(DIE &D, SmallVector< RangeSpan, 2 > Ranges)
void finishSubprogramDefinition(const DISubprogram *SP)
Collects and handles dwarf debug information.
MDNodeSet & getLocalDeclsForScope(const DILocalScope *S)
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
bool useGNUTLSOpcode() const
Returns whether to use DW_OP_GNU_push_tls_address, instead of the standard DW_OP_form_tls_address opc...
bool useAddrOffsetForm() const
const DwarfCompileUnit * getPrevCU() const
Returns the previous CU that was being updated.
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void setPrevCU(const DwarfCompileUnit *PrevCU)
const MachineFunction * getCurrentFunction() const
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
AddressPool & getAddressPool()
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
DwarfCompileUnit * lookupCU(const DIE *Die)
Find the matching DwarfCompileUnit for the given CU DIE.
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
bool useAddrOffsetExpressions() const
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void setCallSiteParamValueFlag()
Lock this down to become a call site parameter location.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void addScopeLabel(LexicalScope *LS, DbgLabel *Label)
DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()
DenseMap< LexicalScope *, LabelList > & getScopeLabels()
void addScopeVariable(LexicalScope *LS, DbgVariable *Var)
This dwarf writer support class manages information associated with a source file.
virtual DIE * getOrCreateTypeDIE(const MDNode *TyNode)
Find existing DIE or create new DIE for the given type.
DwarfDebug & getDwarfDebug() const
void addAnnotation(DIE &Buffer, DINodeArray Annotations)
Add DW_TAG_LLVM_annotation.
void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc)
Add block data.
void addTemplateParams(DIE &Buffer, DINodeArray TParams)
Add template parameters in buffer.
virtual DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
void addAttribute(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, T &&Value)
void addOpAddress(DIELoc &Die, const MCSymbol *Sym)
Add a dwarf op address data and value using the form given and an op of either DW_FORM_addr or DW_FOR...
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty)
Add constant value entry in variable DIE.
DIE * getOrCreateNameSpace(const DINamespace *NS)
void insertDIE(const DINode *Desc, DIE *D)
Insert DIE into the map.
void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
addSectionDelta - Add a label delta attribute data and value.
const DICompileUnit * CUNode
MDNode for the compile unit.
DIE * getDIE(const DINode *D) const
Returns the DIE map slot for the specified debug variable.
MCSymbol * LabelBegin
The start of the unit within its section.
void addSInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, int64_t Integer)
Add an signed integer attribute data and value.
void addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
Add a label delta attribute data and value.
void addLinkageName(DIE &Die, StringRef LinkageName)
Add a linkage name, if it isn't empty.
std::string getParentContextString(const DIScope *Context) const
Get string containing language specific context for a global name.
void addSourceLine(DIE &Die, unsigned Line, const DIFile *File)
Add location information to specified debug information entry.
void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT)
Emit the common part of the header for this unit.
BumpPtrAllocator DIEValueAllocator
DIE * getOrCreateModule(const DIModule *M)
const DICompileUnit * getCUNode() const
DIE & createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N=nullptr)
Create a DIE with the given Tag, add the DIE to its parent, and call insertDIE if MD is not null.
DIE * getOrCreateStaticMemberDIE(const DIDerivedType *DT)
Create new static data member DIE.
void addLabel(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label)
Add a Dwarf label attribute data and value.
void addConstantFPValue(DIE &Die, const ConstantFP *CFP)
Add constant value entry in variable DIE.
DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal=false)
void addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)
Add a Dwarf section label attribute data and value.
void addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label)
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)
MCSymbol * EndLabel
Emitted at the end of the CU and used to compute the CU Length field.
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
AsmPrinter * Asm
Target of Dwarf emission.
unsigned getUniqueID() const
Gets Unique ID for this unit.
void addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute=dwarf::DW_AT_type)
Add a new type attribute to the specified entity.
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, bool SkipSPAttributes=false)
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)
Add a DIE attribute data and value.
LexicalScope - This class is used to track scope information.
Multi-value location description.
unsigned getDebugLocListIndex() const
std::optional< uint8_t > getDebugLocListTagOffset() const
Single value location description.
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Base class for the full range of assembler expressions which are needed for parsing.
MCSection * getDwarfRangesSection() const
MCSection * getDwarfAddrSection() const
MCSection * getDwarfLineSection() const
virtual int64_t getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
bool sameSection(const MachineBasicBlock *MBB) const
Returns true if this and MBB belong to the same section.
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
bool isEndSection() const
Returns true if this block ends any section.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Root of the metadata hierarchy.
A Module instance is used to store all the information related to an LLVM module.
StringRef getName() const
Get a short "name" for the module.
Wrapper class representing virtual and physical registers.
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
Information about stack frame layout on the target.
virtual DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const
Return the frame base information to be encoded in the DWARF subprogram debug info.
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
virtual MCRegister getStaticBase() const
Returns the register used as static base in RWPI variants.
static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM)
Classify the specified global variable into a set of target independent categories embodied in Sectio...
bool supportDebugThreadLocalLocation() const
Target supports TLS offset relocation in debug section?
virtual const MCExpr * getIndirectSymViaRWPI(const MCSymbol *Sym) const
Get the target specific RWPI relocation.
virtual const MCExpr * getDebugThreadLocalSymbol(const MCSymbol *Sym) const
Create a symbol reference to describe the given TLS variable when emitting the address in debug info.
const Triple & getTargetTriple() const
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
const MCRegisterInfo * getMCRegisterInfo() const
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
A DeclContext is a named program scope that is used for ODR uniquing of types.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
StringRef AttributeEncodingString(unsigned Encoding)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
UnitType
Constants for unit types in DWARF v5.
@ WASM_SYMBOL_TYPE_GLOBAL
This is an optimization pass for GlobalISel generic memory operations.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Global
Append to llvm.global_dtors.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
Single location defined by (potentially multiple) EntryValueInfo.
std::set< EntryValueInfo > EntryValues
Single location defined by (potentially multiple) MMI entries.
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
Helper used to pair up a symbol and its DWARF compile unit.
union llvm::TargetFrameLowering::DwarfFrameBase::@248 Location
enum llvm::TargetFrameLowering::DwarfFrameBase::FrameBaseKind Kind
struct WasmFrameBase WasmLoc
This struct describes target specific location.