46 "add-linkage-names-to-declaration-call-origins",
cl::Hidden,
47 cl::desc(
"Add DW_AT_linkage_name to function declaration DIEs "
48 "referenced by DW_AT_call_origin attributes. Enabled by default "
49 "for -gsce debugger tuning."));
52 "emit-func-debug-line-table-offsets",
cl::Hidden,
53 cl::desc(
"Include line table offset in function's debug info and emit end "
54 "sequence after each function's line data."),
72 return dwarf::DW_TAG_skeleton_unit;
74 return dwarf::DW_TAG_compile_unit;
82 MacroLabelBegin =
Asm->createTempSymbol(
"cu_macro_begin");
90 if ((Skeleton || !
DD->useSplitDwarf()) && Label)
94 if ((!
DD->useSplitDwarf() || !Skeleton) &&
DD->getDwarfVersion() < 5)
97 bool UseAddrOffsetFormOrExpressions =
98 DD->useAddrOffsetForm() ||
DD->useAddrOffsetExpressions();
101 if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
102 Base =
DD->getSectionLabel(&Label->getSection());
105 unsigned idx =
DD->getAddressPool().getIndex(Label);
107 DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
108 : dwarf::DW_FORM_GNU_addr_index,
115 assert(
DD->getDwarfVersion() >= 5 &&
116 "Addr+offset expressions are only valuable when using debug_addr (to "
117 "reduce relocations) available in DWARFv5 or higher");
118 if (
DD->useAddrOffsetExpressions()) {
125 DD->getAddressPool().getIndex(
Base), Label,
Base));
143 unsigned CUID =
Asm->OutStreamer->hasRawTextSupport() ? 0 :
getUniqueID();
145 return Asm->OutStreamer->emitDwarfFileDirective(0,
"",
"", std::nullopt,
148 if (LastFile != File) {
150 LastFileID =
Asm->OutStreamer->emitDwarfFileDirective(
151 0, File->getDirectory(), File->getFilename(),
DD->getMD5AsBytes(File),
152 File->getSource(), CUID);
177 assert(SDMDecl->isStaticMember() &&
"Expected static member decl");
181 addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
184 if (GTy != SDMDecl->getBaseType())
190 if (!DisplayName.
empty())
197 addFlag(*VariableDIE, dwarf::DW_AT_external);
204 addFlag(*VariableDIE, dwarf::DW_AT_declaration);
211 addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
225 bool addToAccelTable =
false;
227 std::optional<unsigned> TargetAddrSpace;
228 std::unique_ptr<DIEDwarfExpression> DwarfExpr;
230 for (
const auto &GE : GlobalExprs) {
239 addToAccelTable =
true;
258 !
Asm->getObjFileLowering().supportDebugThreadLocalLocation())
262 addToAccelTable =
true;
264 DwarfExpr = std::make_unique<DIEDwarfExpression>(*
Asm, *
this, *
Loc);
268 Expr =
DD->adjustExpressionForTarget(Expr, TargetAddrSpace);
269 DwarfExpr->addFragmentOffset(Expr);
276 auto GetPointerSizedFormAndOp = [
this]() {
277 unsigned PointerSize =
Asm->MAI.getCodePointerSize();
278 assert((PointerSize == 4 || PointerSize == 8) &&
279 "Add support for other sizes if necessary");
284 return PointerSize == 4
285 ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
286 : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
288 if (
Global->isThreadLocal()) {
289 if (
Asm->TM.getTargetTriple().isWasm()) {
295 addWasmRelocBaseGlobal(
Loc,
"__tls_base", 1);
297 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
298 }
else if (
Asm->TM.useEmulatedTLS()) {
303 if (!
DD->useSplitDwarf()) {
304 auto FormAndOp = GetPointerSizedFormAndOp();
306 addUInt(*
Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
310 Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
312 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
314 DD->getAddressPool().getIndex(Sym,
true));
318 DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
319 : dwarf::DW_OP_form_tls_address);
321 }
else if (
Asm->TM.getTargetTriple().isWasm() &&
326 addWasmRelocBaseGlobal(
Loc,
"__memory_base", 1);
328 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
331 !
Asm->getObjFileLowering()
334 auto FormAndOp = GetPointerSizedFormAndOp();
336 addUInt(*
Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
339 Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));
341 Register BaseReg =
Asm->getObjFileLowering().getStaticBase();
342 unsigned DwarfBaseReg =
343 Asm->TM.getMCRegisterInfo().getDwarfRegNum(BaseReg,
false);
344 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DwarfBaseReg);
348 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
359 if (DwarfExpr->isUnknownLocation())
360 DwarfExpr->setMemoryLocationKind();
361 DwarfExpr->addExpression(Expr);
363 DD->addTargetVariableAttributes(*
this, *VariableDIE, TargetAddrSpace,
367 addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
369 if (
DD->useAllLinkageNames())
372 if (addToAccelTable) {
379 DD->useAllLinkageNames())
393 addString(NDie, dwarf::DW_AT_name, Name);
403 DD->insertSectionLabel(
Range.Begin);
405 auto *PrevCU =
DD->getPrevCU();
406 bool SameAsPrevCU =
this == PrevCU;
412 if (CURanges.empty() || !SameAsPrevCU ||
413 (&CURanges.back().End->getSection() !=
414 &
Range.End->getSection())) {
417 DD->terminateLineTable(PrevCU);
418 CURanges.push_back(
Range);
422 CURanges.back().End =
Range.End;
426 if (
CUNode->isDebugDirectivesOnly())
430 if (
DD->useSectionsAsReferences()) {
454 assert(Begin &&
"Begin label should not be null!");
455 assert(
End &&
"End label should not be null!");
457 assert(
End->isDefined() &&
"Invalid end label");
460 if (
DD->getDwarfVersion() >= 4 &&
472 uint64_t GlobalIndex) {
475 const unsigned TI_GLOBAL_RELOC = 3;
487 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
488 addSInt(*
Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
498 addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);
512 for (
const auto &R :
Asm->MBBSectionRanges)
513 BB_List.
push_back({R.second.BeginLabel, R.second.EndLabel});
517 if (
DD->useAppleExtensionAttributes() &&
518 !
DD->getCurrentFunction()->disableFramePointerElim())
519 addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
523 Asm->getObjFileLowering().getDwarfLineSection()->getBeginSymbol();
533 switch (FrameBase.
Kind) {
537 addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
543 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
545 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);
547 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
554 const unsigned TI_GLOBAL_RELOC = 3;
560 addWasmRelocBaseGlobal(
Loc,
"__stack_pointer",
562 addUInt(*
Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
580 DD->addSubprogramNames(*
this,
CUNode->getNameTableKind(), SP, *SPDie);
587 DIE &ParentScopeDIE) {
588 if (!Scope || !Scope->getScopeNode())
591 auto *DS = Scope->getScopeNode();
594 "Only handle inlined subprograms here, use "
595 "constructSubprogramScopeDIE for non-inlined "
601 assert(ScopeDIE &&
"Scope DIE should not be null.");
607 if (
DD->isLexicalScopeDIENull(Scope))
612 assert(ScopeDIE &&
"Scope DIE should not be null.");
620 HasRangeLists =
true;
624 (
DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU :
DU)
625 ->addRange(*(Skeleton ? Skeleton :
this), std::move(
Range));
627 uint32_t Index = IndexAndList.first;
628 auto &
List = *IndexAndList.second;
635 if (
DD->getDwarfVersion() >= 5)
636 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
648 if (!
DD->useRangesSection() ||
649 (Ranges.size() == 1 &&
650 (!
DD->alwaysUseRanges(*
this) ||
651 DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
652 Ranges.front().Begin))) {
663 List.reserve(Ranges.size());
665 auto *BeginLabel =
DD->getLabelBeforeInsn(R.first);
666 auto *
EndLabel =
DD->getLabelAfterInsn(R.second);
668 const auto *BeginMBB = R.first->getParent();
669 const auto *EndMBB = R.second->getParent();
671 const auto *
MBB = BeginMBB;
679 if (
MBB->sameSection(EndMBB) ||
MBB->isEndSection()) {
680 auto MBBSectionRange =
Asm->MBBSectionRanges[
MBB->getSectionID()];
682 {
MBB->sameSection(BeginMBB) ? BeginLabel
683 : MBBSectionRange.BeginLabel,
684 MBB->sameSection(EndMBB) ?
EndLabel : MBBSectionRange.EndLabel});
686 if (
MBB->sameSection(EndMBB))
695 DIE &ParentScopeDIE) {
696 assert(Scope->getScopeNode());
697 auto *DS = Scope->getScopeNode();
701 DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];
702 assert(OriginDIE &&
"Unable to find original DIE for an inlined subprogram.");
706 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
712 addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,
714 addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());
716 addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());
717 if (IA->getDiscriminator() &&
DD->getDwarfVersion() >= 4)
718 addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,
719 IA->getDiscriminator());
723 DD->addSubprogramNames(*
this,
CUNode->getNameTableKind(), InlinedSP,
730 DIE &ParentScopeDIE) {
731 if (
DD->isLexicalScopeDIENull(Scope))
733 const auto *DS = Scope->getScopeNode();
738 if (Scope->isAbstractScope()) {
740 "Abstract DIE for this scope exists!");
741 getAbstractScopeDIEs()[DS] = ScopeDIE;
744 if (!Scope->getInlinedAt()) {
745 assert(!LexicalBlockDIEs.count(DS) &&
746 "Concrete out-of-line DIE for this scope exists!");
747 LexicalBlockDIEs[DS] = ScopeDIE;
749 InlinedLocalScopeDIEs[DS].push_back(ScopeDIE);
767 applyConcreteDbgVariableAttributes(V, DV, *VariableDie);
776 switch (DT->getTag()) {
777 case dwarf::DW_TAG_typedef:
778 case dwarf::DW_TAG_const_type:
779 case dwarf::DW_TAG_volatile_type:
780 case dwarf::DW_TAG_restrict_type:
781 case dwarf::DW_TAG_atomic_type:
782 Ty = DT->getBaseType();
794 const DIExpression *Expr =
Single.getExpr();
808 auto FirstOp = ExprOps.begin();
809 if (FirstOp == ExprOps.end() ||
813 if (
DD->getDwarfVersion() < 4)
816 const DbgValueLoc &DVal =
Single.getValueLoc();
821 "Non-variadic value must have one entry");
827 const DIDerivedType *PtrTy =
832 if (PtrTy->
getTag() != dwarf::DW_TAG_pointer_type &&
833 PtrTy->
getTag() != dwarf::DW_TAG_reference_type &&
834 PtrTy->
getTag() != dwarf::DW_TAG_rvalue_reference_type)
837 const DIType *PointeeTy = PtrTy->getBaseType();
843 DIE *ArtificialDIEPtr =
nullptr;
844 if (
Entry.isInt() && PointeeTy) {
845 auto It = ImplicitPointerDIEs.find({PointeeTy,
Entry.getInt()});
846 if (It != ImplicitPointerDIEs.end())
847 ArtificialDIEPtr = It->second;
850 if (!ArtificialDIEPtr) {
857 if (
Entry.isLocation()) {
859 }
else if (
Entry.isInt()) {
866 ArtificialDIEPtr = &ProcDIE;
869 if (
Entry.isInt() && PointeeTy)
870 ImplicitPointerDIEs.insert(
871 {{PointeeTy,
Entry.getInt()}, ArtificialDIEPtr});
876 const unsigned ImplicitPtrOp =
DD->getDwarfVersion() >= 5
877 ? dwarf::DW_OP_implicit_pointer
878 : dwarf::DW_OP_GNU_implicit_pointer;
879 addUInt(*Loc, dwarf::DW_FORM_data1, ImplicitPtrOp);
882 dwarf::DW_FORM_ref_addr, DIEEntry(*ArtificialDIEPtr));
884 addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
886 addBlock(VariableDie, dwarf::DW_AT_location, Loc);
890void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
893 if (emitImplicitPointerLocation(
Single, DV, VariableDie))
896 const DbgValueLoc *DVal = &
Single.getValueLoc();
898 DD->addTargetVariableAttributes(*
this, VariableDie, std::nullopt,
902 if (
Entry->isLocation()) {
904 }
else if (
Entry->isInt()) {
905 auto *Expr =
Single.getExpr();
908 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
910 DwarfExpr.addFragmentOffset(Expr);
911 DwarfExpr.addUnsignedConstant(
Entry->getInt());
912 DwarfExpr.addExpression(Expr);
913 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
914 if (DwarfExpr.TagOffset)
915 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,
916 dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
919 }
else if (
Entry->isConstantFP()) {
921 }
else if (
Entry->isConstantInt()) {
923 }
else if (
Entry->isGlobalAddress()) {
924 auto *Expr =
Single.getExpr();
926 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
927 DwarfExpr.addFragmentOffset(Expr);
928 if (!DwarfExpr.addGlobalAddress(
Entry->getGlobalAddress(),
929 Entry->getGlobalOffset()))
933 if (!DwarfExpr.addExpression(Expr))
935 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
936 if (DwarfExpr.TagOffset)
937 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
938 *DwarfExpr.TagOffset);
939 }
else if (
Entry->isTargetIndexLocation()) {
941 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
945 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
952 return Entry.isLocation() && !Entry.getLoc().getReg();
955 const DIExpression *Expr =
Single.getExpr();
956 assert(Expr &&
"Variadic Debug Value must have an Expression.");
958 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
959 DwarfExpr.addFragmentOffset(Expr);
960 DIExpressionCursor Cursor(Expr);
961 const TargetRegisterInfo &
TRI = *
Asm->MF->getSubtarget().getRegisterInfo();
963 auto AddEntry = [&](
const DbgValueLocEntry &
Entry,
964 DIExpressionCursor &Cursor) {
965 if (
Entry.isLocation()) {
966 if (!DwarfExpr.addMachineRegExpression(
TRI, Cursor,
967 Entry.getLoc().getReg()))
969 }
else if (
Entry.isInt()) {
971 DwarfExpr.addUnsignedConstant(
Entry.getInt());
972 }
else if (
Entry.isConstantFP()) {
977 APInt RawBytes =
Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
981 }
else if (
Entry.isConstantInt()) {
982 APInt RawBytes =
Entry.getConstantInt()->getValue();
986 }
else if (
Entry.isTargetIndexLocation()) {
987 TargetIndexLocation Loc =
Entry.getTargetIndexLocation();
990 assert(
Asm->TM.getTargetTriple().isWasm());
992 }
else if (
Entry.isGlobalAddress()) {
993 if (!DwarfExpr.addGlobalAddress(
Entry.getGlobalAddress(),
994 Entry.getGlobalOffset()))
1002 if (!DwarfExpr.addExpression(
1004 [&](
unsigned Idx, DIExpressionCursor &Cursor) ->
bool {
1005 return AddEntry(DVal->getLocEntries()[Idx], Cursor);
1010 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
1011 if (DwarfExpr.TagOffset)
1012 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1013 *DwarfExpr.TagOffset);
1016void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
1022 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1026void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
const Loc::MMI &MMI,
1029 std::optional<unsigned> TargetAddrSpace;
1031 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
1034 const DIExpression *Expr =
Fragment.Expr;
1035 const TargetFrameLowering *TFI =
Asm->MF->getSubtarget().getFrameLowering();
1036 StackOffset Offset =
1038 DwarfExpr.addFragmentOffset(Expr);
1040 auto *
TRI =
Asm->MF->getSubtarget().getRegisterInfo();
1041 SmallVector<uint64_t, 8>
Ops;
1042 TRI->getOffsetOpcodes(Offset,
Ops);
1044 Expr =
DD->adjustExpressionForTarget(Expr, TargetAddrSpace);
1047 DIExpressionCursor Cursor(
Ops);
1048 DwarfExpr.setMemoryLocationKind();
1049 if (
const MCSymbol *FrameSymbol =
Asm->getFunctionFrameSymbol())
1052 DwarfExpr.addMachineRegExpression(
1053 *
Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
1054 DwarfExpr.addExpression(std::move(Cursor));
1056 DD->addTargetVariableAttributes(*
this, VariableDie, TargetAddrSpace,
1058 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
1059 if (DwarfExpr.TagOffset)
1060 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1061 *DwarfExpr.TagOffset);
1064void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
1068 DIEDwarfExpression DwarfExpr(*
Asm, *
this, *Loc);
1071 DwarfExpr.addFragmentOffset(&Expr);
1073 DwarfExpr.beginEntryValueExpression(Cursor);
1074 DwarfExpr.addMachineRegExpression(
1075 *
Asm->MF->getSubtarget().getRegisterInfo(), Cursor,
Register);
1076 DwarfExpr.addExpression(std::move(Cursor));
1078 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
1081void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
1082 const std::monostate &,
const DbgVariable &DV,
DIE &VariableDie) {}
1086 DIE *&ObjectPointer) {
1089 ObjectPointer = Var;
1097 DL.setDIE(*LabelDie);
1099 if (Scope.isAbstractScope())
1109 if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
1111 if (
auto *DLVar = Array->getDataLocation())
1112 Result.push_back(DLVar);
1113 if (
auto *AsVar = Array->getAssociated())
1114 Result.push_back(AsVar);
1115 if (
auto *AlVar = Array->getAllocated())
1116 Result.push_back(AlVar);
1117 for (
auto *El : Array->getElements()) {
1119 if (
auto Count = Subrange->getCount())
1121 Result.push_back(Dependency);
1122 if (
auto LB = Subrange->getLowerBound())
1124 Result.push_back(Dependency);
1125 if (
auto UB = Subrange->getUpperBound())
1127 Result.push_back(Dependency);
1128 if (
auto ST = Subrange->getStride())
1130 Result.push_back(Dependency);
1132 if (
auto Count = GenericSubrange->getCount())
1134 Result.push_back(Dependency);
1135 if (
auto LB = GenericSubrange->getLowerBound())
1137 Result.push_back(Dependency);
1138 if (
auto UB = GenericSubrange->getUpperBound())
1140 Result.push_back(Dependency);
1141 if (
auto ST = GenericSubrange->getStride())
1143 Result.push_back(Dependency);
1164 DbgVar.
insert({Var->getVariable(), Var});
1169 while (!WorkList.
empty()) {
1170 auto Item = WorkList.
back();
1172 bool visitedAllDependencies = Item.getInt();
1178 if (Visited.
count(Var))
1182 if (visitedAllDependencies) {
1184 Result.push_back(Var);
1189 auto Res = Visiting.
insert(Var);
1191 assert(
false &&
"dependency cycle in local variables");
1215 assert(!Scope->getInlinedAt());
1216 assert(!Scope->isAbstractScope());
1221 addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
1225 auto *SPTy =
Sub->getType();
1229 DITypeArray FnArgs = SPTy->getTypeArray();
1234 if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
1244 DIE *ObjectPointer =
nullptr;
1247 auto Vars =
DU->getScopeVariables().lookup(Scope);
1248 for (
auto &DV : Vars.Args)
1257 for (
DbgLabel *
DL :
DU->getScopeLabels().lookup(Scope))
1264 auto &LocalDecls =
DD->getLocalDeclsForScope(Scope->getScopeNode());
1265 DeferredLocalDecls.insert_range(LocalDecls);
1269 auto skipLexicalScope = [
this](
LexicalScope *S) ->
bool {
1276 if (getAbstractScopeDIEs().
lookup(DS))
1278 auto Vars =
DU->getScopeVariables().lookup(S);
1279 if (!Vars.Args.empty() || !Vars.Locals.empty())
1282 DD->getLocalDeclsForScope(DS).empty();
1288 if (skipLexicalScope(LS))
1294 return ObjectPointer;
1299 if (
auto *AbsDef = getAbstractScopeDIEs().
lookup(SP))
1302 auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
1303 return createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
1306DIE &DwarfCompileUnit::createAbstractSubprogramDIE(
1311 *ContextDIE,
nullptr);
1314 ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;
1317 ContextCU->
addSInt(AbsDef, dwarf::DW_AT_inline,
1319 : dwarf::DW_FORM_implicit_const,
1325std::pair<DIE *, DwarfCompileUnit *>
1326DwarfCompileUnit::getOrCreateAbstractSubprogramContextDIE(
1332 if (
auto *SPDecl = SP->getDeclaration())
1341 return std::make_pair(ContextDIE, ContextCU);
1349 if (!getFinalizedAbstractSubprograms().insert(SP).second)
1352 auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
1353 DIE *AbsDef = getAbstractScopeDIEs().lookup(SP);
1355 AbsDef = &createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
1358 ContextCU->
addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer,
1363 return DD->getDwarfVersion() <= 4 && !
DD->tuneForLLDB();
1370 case dwarf::DW_TAG_call_site:
1371 return dwarf::DW_TAG_GNU_call_site;
1372 case dwarf::DW_TAG_call_site_parameter:
1373 return dwarf::DW_TAG_GNU_call_site_parameter;
1384 case dwarf::DW_AT_call_all_calls:
1385 return dwarf::DW_AT_GNU_all_call_sites;
1386 case dwarf::DW_AT_call_target:
1387 return dwarf::DW_AT_GNU_call_site_target;
1388 case dwarf::DW_AT_call_target_clobbered:
1389 return dwarf::DW_AT_GNU_call_site_target_clobbered;
1390 case dwarf::DW_AT_call_origin:
1391 return dwarf::DW_AT_abstract_origin;
1392 case dwarf::DW_AT_call_return_pc:
1393 return dwarf::DW_AT_low_pc;
1394 case dwarf::DW_AT_call_value:
1395 return dwarf::DW_AT_GNU_call_site_value;
1396 case dwarf::DW_AT_call_tail_call:
1397 return dwarf::DW_AT_GNU_tail_call;
1408 case dwarf::DW_OP_entry_value:
1409 return dwarf::DW_OP_GNU_entry_value;
1424 if (CallTarget.
getReg()) {
1431 TRI.isCalleeSavedPhysReg(CallTarget.
getReg(), *
Asm->MF)
1432 ? dwarf::DW_AT_call_target
1433 : dwarf::DW_AT_call_target_clobbered);
1441 }
else if (CalleeSP) {
1443 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
1477 assert(PCAddr &&
"Missing return PC information for a call");
1483 addType(CallSiteDIE, AllocSiteTy, dwarf::DW_AT_LLVM_alloc_type);
1490 for (
const auto &Param : Params) {
1491 unsigned Register = Param.getRegister();
1492 auto CallSiteDieParam =
1496 addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
1508 CallSiteDIE.
addChild(CallSiteDieParam);
1517 auto *Entity =
Module->getEntity();
1526 if (
auto *AbsSPDie = getAbstractScopeDIEs().
lookup(SP))
1527 EntityDie = AbsSPDie;
1537 EntityDie =
getDIE(Entity);
1540 addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
1542 if (!Name.empty()) {
1543 addString(*IMDie, dwarf::DW_AT_name, Name);
1550 DD->addAccelNamespace(*
this,
CUNode->getNameTableKind(), Name, *IMDie);
1555 DINodeArray Elements =
Module->getElements();
1556 for (
const auto *Element : Elements) {
1574 assert(ContextDIE &&
"Empty scope for the imported entity!");
1583 if (
DIE *AbsSPDIE = getAbstractScopeDIEs().
lookup(SP)) {
1586 addDIEEntry(*
D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
1598 auto *Die = Entity->
getDIE();
1602 if (AbsEntity && AbsEntity->
getDIE()) {
1617 const auto *Sym = Label->getSymbol();
1624 if (
StringRef Name = Label->getName(); !Name.empty())
1630 if (
auto *AbsLSDie = getAbstractScopeDIEs().
lookup(LS))
1631 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *AbsLSDie);
1634 for (
auto [LScope, ScopeDIE] : LexicalBlockDIEs)
1635 AttachAO(LScope, ScopeDIE);
1636 for (
auto &[LScope, ScopeDIEs] : InlinedLocalScopeDIEs)
1637 for (
auto *ScopeDIE : ScopeDIEs)
1638 AttachAO(LScope, ScopeDIE);
1642 auto &AbstractEntities = getAbstractEntities();
1643 auto I = AbstractEntities.find(
Node);
1644 if (
I != AbstractEntities.end())
1645 return I->second.get();
1651 assert(Scope && Scope->isAbstractScope());
1652 auto &Entity = getAbstractEntities()[
Node];
1658 Entity = std::make_unique<DbgLabel>(
1666 if (!Skeleton && !
DD->useSectionsAsReferences()) {
1672 :
DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
1673 : dwarf::DW_UT_compile;
1675 if (
DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
1680 if (!
DD->shouldEmitDwarfPubSections())
1683 switch (
CUNode->getNameTableKind()) {
1694 !
CUNode->isDebugDirectivesOnly() &&
1696 DD->getDwarfVersion() < 5;
1707 GlobalNames[FullName] = &Die;
1719 GlobalNames.insert(std::make_pair(std::move(FullName), &
getUnitDie()));
1728 GlobalTypes[FullName] = &Die;
1740 GlobalTypes.insert(std::make_pair(std::move(FullName), &
getUnitDie()));
1745 auto *
Single = std::get_if<Loc::Single>(&DV);
1749 addAddress(Die, dwarf::DW_AT_location, Location);
1757 if (Location.isIndirect())
1758 DwarfExpr.setMemoryLocationKind();
1762 if (!DwarfExpr.addMachineRegExpression(
TRI, Cursor, Location.getReg()))
1764 DwarfExpr.addExpression(std::move(Cursor));
1769 if (DwarfExpr.TagOffset)
1770 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1771 *DwarfExpr.TagOffset);
1777 addLocationWithExpr(Die,
Attribute, Location, {});
1785 assert(Location.isIndirect() &&
"Memory loc should be indirect");
1817 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1825 ? dwarf::DW_FORM_loclistx
1826 :
DD->getDwarfSectionOffsetForm();
1834 addString(VariableDie, dwarf::DW_AT_name, Name);
1837 if (
uint32_t AlignInBytes = DIVar->getAlignInBytes())
1838 addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1846 addFlag(VariableDie, dwarf::DW_AT_artificial);
1853 addString(LabelDie, dwarf::DW_AT_name, Name);
1854 const auto *
DILabel = Label.getLabel();
1857 addFlag(LabelDie, dwarf::DW_AT_artificial);
1859 addUInt(LabelDie, dwarf::DW_AT_LLVM_coro_suspend_idx, std::nullopt,
1871 auto *SPDecl = SP->getDeclaration();
1872 auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();
1877bool DwarfCompileUnit::isDwoUnit()
const {
1887 (
DD->useSplitDwarf() && !Skeleton);
1896 MCSymbol *Label =
DD->getAddressPool().getLabel();
1898 DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
1899 : dwarf::DW_AT_GNU_addr_base,
1920 addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1927 addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
1937DIE *DwarfCompileUnit::getOrCreateLocalScopeDIE(
const DILocalScope *Scope) {
1938 const DISubprogram *
SP =
Scope->getSubprogram();
1939 if (!
SP->isDefinition())
1945 if (&ScopeCU !=
this)
1946 return ScopeCU.getOrCreateLocalScopeDIE(Scope);
1950 auto &AbstractDIEs = getAbstractScopeDIEs();
1951 if (AbstractDIEs.contains(SP)) {
1952 const DILocalScope *S =
Scope;
1953 auto I = AbstractDIEs.find(S);
1954 while (
I == AbstractDIEs.end()) {
1956 I = AbstractDIEs.find(S);
1964 if (!
DD->allFunctionsProcessed())
1965 return &getOrCreatePendingLocalScopeDIE(Scope);
1969 if (DIE *ScopeDIE = LexicalBlockDIEs.lookup(LB))
1978DIE &DwarfCompileUnit::getOrCreatePendingLocalScopeDIE(
1980 DIE *&PendingDIE = PendingLocalScopeDIEs[
Scope];
1987 if (!PendingLocalScopesDIE)
1988 PendingLocalScopesDIE =
1990 PendingDIE = &PendingLocalScopesDIE->
addChild(
1996 assert(
DD->allFunctionsProcessed() &&
1997 "Local scope DIEs can be resolved only after all functions");
1998 for (
auto [Scope, PendingDIE] : PendingLocalScopeDIEs) {
1999 DIE *ScopeDIE = getOrCreateLocalScopeDIE(Scope);
2004 PendingLocalScopeDIEs.clear();
2006 if (PendingLocalScopesDIE) {
2008 PendingLocalScopesDIE =
nullptr;
2014 return getOrCreateLocalScopeDIE(LScope->getNonLexicalBlockFileScope());
2021 if (!
F && SP->isDefinition()) {
2025 DD->getOrCreateAbstractSubprogramCU(SP, *
this);
2026 if (
DIE *AbstractDIE = AbstractCU.getAbstractScopeDIEs().lookup(SP))
2035 if (
DD->allFunctionsProcessed() && !
DD->isProcessedSubprogram(SP))
2045 !CalleeSP.isDefinition() &&
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")
static const DILocalScope * getParentLocalScope(const DILexicalBlockBase *LB)
static SmallVector< DbgVariable *, 8 > sortLocalVars(SmallVectorImpl< DbgVariable * > &Input)
Sort local variables so that variables appearing inside of helper expressions come first.
static const DIType * resolveTypeQualifiers(const DIType *Ty)
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)
static 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, GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file defines the SmallString class.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
This class is intended to be used as a driving class for all asm writers.
MachineFunction * MF
The current machine function.
const DataLayout & getDataLayout() const
Return information about data layout.
MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const
Return the MCSymbol for the specified ExternalSymbol.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
unsigned getLineNo() const
StringRef getName() const
DIScope * getScope() const
DIGlobalVariable * getDecl() const
static LLVM_ABI 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.
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI void takeChildren(DIE &Other, bool AtFront=false)
Move all children of Other to this DIE, preserving their order.
DIE & addChild(DIE *Child)
Add a child to the DIE.
static DIE * getPlaceholder(BumpPtrAllocator &Alloc)
Create a temporary placeholder DIE.
DIE & addChildFront(DIE *Child)
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
LLVM_ABI void removeChild(DIE &Child)
Remove Child from the children of this DIE.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the 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
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
iterator_range< expr_op_iterator > expr_ops() const
unsigned getNumElements() const
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
element_iterator elements_begin() const
LLVM_ABI uint64_t getConstantValue() const
Return the value of a constant expression, as recognized by isConstant().
ArrayRef< uint64_t > getElements() const
LLVM_ABI std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
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).
bool isArtificial() const
std::optional< unsigned > getCoroSuspendIdx() const
DILocalScope * getScope() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
Base class for scope-like contexts.
Subprogram description. Uses SubclassData1.
uint32_t getAlignInBytes() const
DIScope * getScope() const
StringRef getName() const
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation 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.
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...
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
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 addLinkageNamesToDeclarations(const DwarfDebug &DD, const DISubprogram &CalleeSP, DIE &CalleeDIE)
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.
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 addMemoryLocation(DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location, int64_t Offset)
Add a memory location exprloc to DIE with attribute Attribute at Location + Offset.
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.
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 & constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP, const Function *CalleeF, bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr, MachineLocation CallTarget, int64_t Offset, DIType *AllocSiteTy)
Construct a call site entry DIE describing a call within Scope to a callee described by CalleeSP and ...
DIE & getOrCreateAbstractSubprogramDIE(const DISubprogram *SP)
Create an abstract subprogram DIE, that should later be populated by constructAbstractSubprogramScope...
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override
Add a new global name to the compile unit.
DIE & updateSubprogramScopeDIE(const DISubprogram *SP, const Function &F, 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 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 * getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *F, bool Minimal=false) override
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 * 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.
DIE * getOrCreateLexicalBlockDIE(LexicalScope *Scope, DIE &ParentDIE)
Get if available or create a new DW_TAG_lexical_block for the given LexicalScope and attach DW_AT_low...
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.
void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context) override
Add a new global type to the compile unit.
void resolvePendingLocalScopeDIEs()
Move DIEs of function-local entities from pending DIEs to the DIEs of their scopes in abstract or con...
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE)
void attachLexicalScopesAbstractOrigins()
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.
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
DwarfCompileUnit * lookupCU(const DIE *Die)
Find the matching DwarfCompileUnit for the given CU DIE.
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 split DWARF.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
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...
bool addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
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 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.
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.
bool shouldPlaceInUnitDIE(const DISubprogram *SP, bool Minimal)
const DICompileUnit * CUNode
MDNode for the compile unit.
virtual DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *FnHint, bool Minimal=false)
DIE * getOrCreateSubprogramContextDIE(const DISubprogram *SP, bool IgnoreScope)
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.
DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID=0)
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, unsigned Column, 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.
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.
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.
Base class for the full range of assembler expressions which are needed for parsing.
MCSection * getDwarfRangesSection() const
MCSection * getDwarfAddrSection() const
MCSection * getDwarfLineSection() const
MCSymbol * getBeginSymbol()
void setType(wasm::WasmSymbolType type)
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).
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
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 push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
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...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
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.
LLVM_ABI 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.
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
@ WASM_SYMBOL_TYPE_GLOBAL
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
LLVM_ABI bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
This is used to track range of instructions with identical lexical scope.
auto dyn_cast_or_null(const Y &Val)
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.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Global
Append to llvm.global_dtors.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI 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::@004076321055032247336074224075335064105264310375 Location
enum llvm::TargetFrameLowering::DwarfFrameBase::FrameBaseKind Kind
struct WasmFrameBase WasmLoc