39#define DEBUG_TYPE "dwarfdebug"
45void DIEDwarfExpression::emitOp(
uint8_t Op,
const char* Comment) {
46 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1,
Op);
49void DIEDwarfExpression::emitSigned(int64_t
Value) {
50 CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata,
Value);
54 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata,
Value);
58 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1,
Value);
61void DIEDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
62 CU.addBaseTypeRef(getActiveDIE(),
Idx);
65void DIEDwarfExpression::enableTemporaryBuffer() {
66 assert(!IsBuffering &&
"Already buffering?");
70void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
72unsigned DIEDwarfExpression::getTemporaryBufferSize() {
76void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.
takeValues(TmpDIE); }
80 return MachineReg ==
TRI.getFrameRegister(*AP.
MF);
86 :
DIEUnit(UnitTag), UniqueID(UniqueID), CUNode(Node), Asm(
A), DD(DW),
92 :
DwarfUnit(dwarf::DW_TAG_type_unit,
CU.getCUNode(),
A, DW, DWU, UniqueID),
93 CU(
CU), SplitLineTable(SplitLineTable) {}
102int64_t DwarfUnit::getDefaultLowerBound()
const {
108 case dwarf::DW_LANG_C:
109 case dwarf::DW_LANG_C89:
110 case dwarf::DW_LANG_C_plus_plus:
113 case dwarf::DW_LANG_Fortran77:
114 case dwarf::DW_LANG_Fortran90:
118 case dwarf::DW_LANG_C99:
119 case dwarf::DW_LANG_ObjC:
120 case dwarf::DW_LANG_ObjC_plus_plus:
125 case dwarf::DW_LANG_Fortran95:
131 case dwarf::DW_LANG_D:
132 case dwarf::DW_LANG_Java:
133 case dwarf::DW_LANG_Python:
134 case dwarf::DW_LANG_UPC:
139 case dwarf::DW_LANG_Ada83:
140 case dwarf::DW_LANG_Ada95:
141 case dwarf::DW_LANG_Cobol74:
142 case dwarf::DW_LANG_Cobol85:
143 case dwarf::DW_LANG_Modula2:
144 case dwarf::DW_LANG_Pascal83:
145 case dwarf::DW_LANG_PLI:
151 case dwarf::DW_LANG_BLISS:
152 case dwarf::DW_LANG_C11:
153 case dwarf::DW_LANG_C_plus_plus_03:
154 case dwarf::DW_LANG_C_plus_plus_11:
155 case dwarf::DW_LANG_C_plus_plus_14:
156 case dwarf::DW_LANG_Dylan:
157 case dwarf::DW_LANG_Go:
158 case dwarf::DW_LANG_Haskell:
159 case dwarf::DW_LANG_OCaml:
160 case dwarf::DW_LANG_OpenCL:
161 case dwarf::DW_LANG_RenderScript:
162 case dwarf::DW_LANG_Rust:
163 case dwarf::DW_LANG_Swift:
168 case dwarf::DW_LANG_Fortran03:
169 case dwarf::DW_LANG_Fortran08:
170 case dwarf::DW_LANG_Julia:
171 case dwarf::DW_LANG_Modula3:
191 return (isa<DIType>(
D) ||
192 (isa<DISubprogram>(
D) && !cast<DISubprogram>(
D)->isDefinition())) &&
225 assert(Form != dwarf::DW_FORM_implicit_const &&
226 "DW_FORM_implicit_const is used only for signed integers");
245 for (
int i = 0; i < NumBytes; i++) {
248 c = Ptr64[i / 8] >> (8 * (i & 7));
250 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
260 if (CIBitWidth <= 64) {
272 std::optional<dwarf::Form> Form, int64_t
Integer) {
295 isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;
297 auto StringPoolEntry =
304 IxForm = dwarf::DW_FORM_strx1;
305 unsigned Index = StringPoolEntry.getIndex();
306 if (Index > 0xffffff)
307 IxForm = dwarf::DW_FORM_strx4;
308 else if (Index > 0xffff)
309 IxForm = dwarf::DW_FORM_strx3;
310 else if (Index > 0xff)
311 IxForm = dwarf::DW_FORM_strx2;
330unsigned DwarfTypeUnit::getOrCreateSourceID(
const DIFile *File) {
333 if (!UsedLineTable) {
334 UsedLineTable =
true;
338 return SplitLineTable->
getFile(
344 bool UseAddrOffsetFormOrExpressions =
348 if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
354 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);
355 addUInt(Die, dwarf::DW_FORM_addrx, Index);
357 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
358 addUInt(Die, dwarf::DW_FORM_GNU_addr_index, Index);
362 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_const4u);
364 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
379 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
398 addFlag(Die, dwarf::DW_AT_declaration);
400 addAttribute(Die, dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,
407 const DIEUnit *EntryCU = Entry.getEntry().getUnit();
416 EntryCU ==
CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
450 addUInt(Die, dwarf::DW_AT_decl_file, std::nullopt, FileID);
451 addUInt(Die, dwarf::DW_AT_decl_line, std::nullopt, Line);
507 addUInt(Die, dwarf::DW_AT_const_value,
508 Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
517 if (CIBitWidth <= 64) {
523 addIntAsBlock(Die, dwarf::DW_AT_const_value, Val);
530 : dwarf::DW_AT_MIPS_linkage_name,
536 for (
const auto *Element : TParams) {
537 if (
auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))
538 constructTemplateTypeParameterDIE(Buffer, TTP);
539 else if (
auto *TVP = dyn_cast<DITemplateValueParameter>(Element))
540 constructTemplateValueParameterDIE(Buffer, TVP);
546 for (
const auto *Ty : ThrownTypes) {
554 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
557 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
560 addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
565 if (!Context || isa<DIFile>(Context) || isa<DICompileUnit>(Context))
567 if (
auto *
T = dyn_cast<DIType>(Context))
569 if (
auto *NS = dyn_cast<DINamespace>(Context))
571 if (
auto *SP = dyn_cast<DISubprogram>(Context))
573 if (
auto *M = dyn_cast<DIModule>(Context))
599 auto construct = [&](
const auto *Ty) {
604 if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
606 (Ty->
getRawName() || CTy->getRawIdentifier())) {
608 if (
MDString *TypeId = CTy->getRawIdentifier()) {
613 finishNonUnitTypeDIE(TyDIE, CTy);
618 }
else if (
auto *
BT = dyn_cast<DIBasicType>(Ty))
620 else if (
auto *ST = dyn_cast<DIStringType>(Ty))
622 else if (
auto *STy = dyn_cast<DISubroutineType>(Ty))
625 construct(cast<DIDerivedType>(Ty));
634 auto *Ty = cast<DIType>(TyNode);
646 auto *Context = Ty->getScope();
667 if (
auto *CT = dyn_cast<DICompositeType>(Ty)) {
670 if (CT->getRuntimeLang() == 0 || CT->isObjcClassComplete())
677 if (
auto *CT = dyn_cast<DICompositeType>(Ty))
678 if (Ty->
getName() != CT->getIdentifier() &&
679 CT->getRuntimeLang() == dwarf::DW_LANG_Swift)
688 if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||
689 isa<DINamespace>(Context) || isa<DICommonBlock>(Context))
695 assert(Ty &&
"Trying to add a type that doesn't exist?");
709 while (!isa<DICompileUnit>(Context)) {
710 Parents.push_back(Context);
723 if (
Name.empty() && isa<DINamespace>(Ctx))
724 Name =
"(anonymous namespace)";
741 if (BTy->
getTag() == dwarf::DW_TAG_unspecified_type)
744 if (BTy->
getTag() != dwarf::DW_TAG_string_type)
745 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
749 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,
Size);
752 addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big);
754 addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little);
757 addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,
758 NumExtraInhabitants);
769 if (
auto *VarDIE =
getDIE(Var))
770 addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);
777 DwarfExpr.setMemoryLocationKind();
778 DwarfExpr.addExpression(Expr);
779 addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());
782 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,
Size);
790 DwarfExpr.setMemoryLocationKind();
791 DwarfExpr.addExpression(Expr);
792 addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
797 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
809 const DIType *FromTy = DTy->getBaseType();
823 if (AlignInBytes > 0)
824 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
829 if (
Size &&
Tag != dwarf::DW_TAG_pointer_type
830 &&
Tag != dwarf::DW_TAG_ptr_to_member_type
831 &&
Tag != dwarf::DW_TAG_reference_type
832 &&
Tag != dwarf::DW_TAG_rvalue_reference_type)
833 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,
Size);
835 if (
Tag == dwarf::DW_TAG_ptr_to_member_type)
848 if (DTy->getDWARFAddressSpace())
849 addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,
850 *DTy->getDWARFAddressSpace());
853 if (
Tag == dwarf::DW_TAG_template_alias)
856 if (
auto PtrAuthData = DTy->getPtrAuthData()) {
857 addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1,
859 if (PtrAuthData->isAddressDiscriminated())
860 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated);
861 addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator,
862 dwarf::DW_FORM_data2, PtrAuthData->extraDiscriminator());
863 if (PtrAuthData->isaPointer())
864 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer);
865 if (PtrAuthData->authenticatesNullValues())
866 addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values);
871 for (
unsigned i = 1,
N = Args.size(); i <
N; ++i) {
872 const DIType *Ty = Args[i];
874 assert(i ==
N-1 &&
"Unspecified parameter must be the last argument");
880 addFlag(Arg, dwarf::DW_AT_artificial);
887 auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();
889 if (
auto RTy = Elements[0])
892 bool isPrototyped =
true;
893 if (Elements.size() == 2 && !Elements[1])
894 isPrototyped =
false;
901 addFlag(Buffer, dwarf::DW_AT_prototyped);
904 if (CTy->
getCC() && CTy->
getCC() != dwarf::DW_CC_normal)
905 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
909 addFlag(Buffer, dwarf::DW_AT_reference);
912 addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
920 const MDNode *MD = cast<MDNode>(Annotation);
925 addString(AnnotationDie, dwarf::DW_AT_name,
Name->getString());
926 if (
const auto *
Data = dyn_cast<MDString>(
Value))
927 addString(AnnotationDie, dwarf::DW_AT_const_value,
Data->getString());
928 else if (
const auto *
Data = dyn_cast<ConstantAsMetadata>(
Value))
932 assert(
false &&
"Unsupported annotation value type");
944 case dwarf::DW_TAG_array_type:
945 constructArrayTypeDIE(Buffer, CTy);
947 case dwarf::DW_TAG_enumeration_type:
948 constructEnumTypeDIE(Buffer, CTy);
950 case dwarf::DW_TAG_variant_part:
951 case dwarf::DW_TAG_structure_type:
952 case dwarf::DW_TAG_union_type:
953 case dwarf::DW_TAG_class_type:
954 case dwarf::DW_TAG_namelist: {
957 if (
Tag == dwarf::DW_TAG_variant_part) {
964 DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
965 addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
970 if (
Tag == dwarf::DW_TAG_class_type ||
971 Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type)
976 for (
const auto *Element : Elements) {
979 if (
auto *SP = dyn_cast<DISubprogram>(Element))
981 else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
982 if (DDTy->getTag() == dwarf::DW_TAG_friend) {
984 addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend);
985 }
else if (DDTy->isStaticMember()) {
987 }
else if (
Tag == dwarf::DW_TAG_variant_part) {
992 dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
993 addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(),
996 constructMemberDIE(Variant, DDTy);
998 constructMemberDIE(Buffer, DDTy);
1000 }
else if (
auto *Property = dyn_cast<DIObjCProperty>(Element)) {
1002 StringRef PropertyName = Property->getName();
1003 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
1004 if (Property->getType())
1005 addType(ElemDie, Property->getType());
1007 StringRef GetterName = Property->getGetterName();
1008 if (!GetterName.
empty())
1009 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
1010 StringRef SetterName = Property->getSetterName();
1011 if (!SetterName.
empty())
1012 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
1013 if (
unsigned PropertyAttributes = Property->getAttributes())
1014 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, std::nullopt,
1015 PropertyAttributes);
1016 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
1017 if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
1021 }
else if (
Tag == dwarf::DW_TAG_namelist) {
1022 auto *Var = dyn_cast<DINode>(Element);
1023 auto *VarDIE =
getDIE(Var);
1026 addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE);
1032 addFlag(Buffer, dwarf::DW_AT_APPLE_block);
1035 addFlag(Buffer, dwarf::DW_AT_export_symbols);
1046 addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
1053 CC = dwarf::DW_CC_pass_by_value;
1055 CC = dwarf::DW_CC_pass_by_reference;
1057 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
1081 if (
Tag == dwarf::DW_TAG_enumeration_type ||
1082 Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type ||
1083 Tag == dwarf::DW_TAG_union_type) {
1089 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,
Size);
1092 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0);
1096 addFlag(Buffer, dwarf::DW_AT_declaration);
1108 addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
1113 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1117 addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,
1118 NumExtraInhabitants);
1122void DwarfUnit::constructTemplateTypeParameterDIE(
1131 if (TP->
isDefault() && isCompatibleWithVersion(5))
1132 addFlag(ParamDIE, dwarf::DW_AT_default_value);
1135void DwarfUnit::constructTemplateValueParameterDIE(
1141 if (VP->
getTag() == dwarf::DW_TAG_template_value_parameter)
1145 if (VP->
isDefault() && isCompatibleWithVersion(5))
1146 addFlag(ParamDIE, dwarf::DW_AT_default_value);
1148 if (
ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
1150 else if (
GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
1153 if (!GV->hasDLLImportStorageClass()) {
1160 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
1161 addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
1163 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_template_param) {
1164 assert(isa<MDString>(Val));
1165 addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
1166 cast<MDString>(Val)->getString());
1167 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
1186 Name =
"(anonymous namespace)";
1190 addFlag(NDie, dwarf::DW_AT_export_symbols);
1203 if (!M->getName().empty()) {
1204 addString(MDie, dwarf::DW_AT_name, M->getName());
1207 if (!M->getConfigurationMacros().empty())
1208 addString(MDie, dwarf::DW_AT_LLVM_config_macros,
1209 M->getConfigurationMacros());
1210 if (!M->getIncludePath().empty())
1211 addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());
1212 if (!M->getAPINotesFile().empty())
1213 addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile());
1215 addUInt(MDie, dwarf::DW_AT_decl_file, std::nullopt,
1218 addUInt(MDie, dwarf::DW_AT_decl_line, std::nullopt, M->getLineNo());
1220 addFlag(MDie, dwarf::DW_AT_declaration);
1235 if (
auto *SPDecl = SP->getDeclaration()) {
1249 if (SP->isDefinition())
1258 DIE &SPDie,
bool Minimal) {
1259 DIE *DeclDie =
nullptr;
1261 if (
auto *SPDecl = SP->getDeclaration()) {
1264 DeclArgs = SPDecl->getType()->getTypeArray();
1265 DefinitionArgs = SP->getType()->getTypeArray();
1267 if (DeclArgs.
size() && DefinitionArgs.
size())
1268 if (DefinitionArgs[0] !=
nullptr && DeclArgs[0] != DefinitionArgs[0])
1269 addType(SPDie, DefinitionArgs[0]);
1271 DeclDie =
getDIE(SPDecl);
1272 assert(DeclDie &&
"This DIE should've already been constructed when the "
1273 "definition DIE was created in "
1274 "getOrCreateSubprogramDIE");
1277 DeclLinkageName = SPDecl->getLinkageName();
1280 if (DeclID != DefID)
1281 addUInt(SPDie, dwarf::DW_AT_decl_file, std::nullopt, DefID);
1283 if (SP->getLine() != SPDecl->getLine())
1284 addUInt(SPDie, dwarf::DW_AT_decl_line, std::nullopt, SP->getLine());
1295 "decl has a linkage name and it is different");
1296 if (DeclLinkageName.
empty() &&
1306 addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
1311 bool SkipSPAttributes) {
1314 bool SkipSPSourceLocation = SkipSPAttributes &&
1316 if (!SkipSPSourceLocation)
1326 if (!SkipSPSourceLocation)
1330 if (SkipSPAttributes)
1336 addFlag(SPDie, dwarf::DW_AT_prototyped);
1338 if (SP->isObjCDirect())
1339 addFlag(SPDie, dwarf::DW_AT_APPLE_objc_direct);
1344 Args = SPTy->getTypeArray();
1349 if (
CC &&
CC != dwarf::DW_CC_normal)
1350 addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
CC);
1355 if (
auto Ty = Args[0])
1358 unsigned VK = SP->getVirtuality();
1360 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
1361 if (SP->getVirtualIndex() != -1u) {
1363 addUInt(*
Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1364 addUInt(*
Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());
1370 if (!SP->isDefinition()) {
1371 addFlag(SPDie, dwarf::DW_AT_declaration);
1380 if (SP->isArtificial())
1381 addFlag(SPDie, dwarf::DW_AT_artificial);
1383 if (!SP->isLocalToUnit())
1384 addFlag(SPDie, dwarf::DW_AT_external);
1387 if (SP->isOptimized())
1388 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
1391 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag,
isa);
1394 if (SP->isLValueReference())
1395 addFlag(SPDie, dwarf::DW_AT_reference);
1397 if (SP->isRValueReference())
1398 addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
1400 if (SP->isNoReturn())
1401 addFlag(SPDie, dwarf::DW_AT_noreturn);
1405 if (SP->isExplicit())
1406 addFlag(SPDie, dwarf::DW_AT_explicit);
1408 if (SP->isMainSubprogram())
1409 addFlag(SPDie, dwarf::DW_AT_main_subprogram);
1411 addFlag(SPDie, dwarf::DW_AT_pure);
1412 if (SP->isElemental())
1413 addFlag(SPDie, dwarf::DW_AT_elemental);
1414 if (SP->isRecursive())
1415 addFlag(SPDie, dwarf::DW_AT_recursive);
1417 if (!SP->getTargetFuncName().empty())
1418 addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName());
1421 addFlag(SPDie, dwarf::DW_AT_deleted);
1424void DwarfUnit::constructSubrangeDIE(
DIE &Buffer,
const DISubrange *SR,
1427 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
1433 int64_t DefaultLowerBound = getDefaultLowerBound();
1436 DISubrange::BoundType Bound) ->
void {
1437 if (
auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {
1438 if (
auto *VarDIE =
getDIE(BV))
1440 }
else if (
auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {
1443 DwarfExpr.setMemoryLocationKind();
1444 DwarfExpr.addExpression(BE);
1445 addBlock(DW_Subrange, Attr, DwarfExpr.finalize());
1446 }
else if (
auto *BI = dyn_cast_if_present<ConstantInt *>(Bound)) {
1447 if (Attr == dwarf::DW_AT_count) {
1448 if (BI->getSExtValue() != -1)
1449 addUInt(DW_Subrange, Attr, std::nullopt, BI->getSExtValue());
1450 }
else if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
1451 BI->getSExtValue() != DefaultLowerBound)
1452 addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue());
1456 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->
getLowerBound());
1458 AddBoundTypeEntry(dwarf::DW_AT_count, SR->
getCount());
1460 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->
getUpperBound());
1462 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->
getStride());
1465void DwarfUnit::constructGenericSubrangeDIE(
DIE &Buffer,
1468 DIE &DwGenericSubrange =
1470 addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);
1472 int64_t DefaultLowerBound = getDefaultLowerBound();
1476 if (
auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {
1477 if (
auto *VarDIE =
getDIE(BV))
1479 }
else if (
auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {
1480 if (BE->isConstant() &&
1482 *BE->isConstant()) {
1483 if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
1484 static_cast<int64_t
>(BE->getElement(1)) != DefaultLowerBound)
1485 addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,
1490 DwarfExpr.setMemoryLocationKind();
1491 DwarfExpr.addExpression(BE);
1492 addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());
1497 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->
getLowerBound());
1498 AddBoundTypeEntry(dwarf::DW_AT_count, GSR->
getCount());
1499 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->
getUpperBound());
1500 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->
getStride());
1503DIE *DwarfUnit::getIndexTyDie() {
1523 assert(CTy && CTy->
isVector() &&
"Composite type is not a vector");
1533 assert(Elements.size() == 1 &&
1534 Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&
1535 "Invalid vector element array, expected one element of type subrange");
1536 const auto Subrange = cast<DISubrange>(Elements[0]);
1537 const auto NumVecElements =
1538 Subrange->getCount()
1539 ? cast<ConstantInt *>(Subrange->getCount())->getSExtValue()
1544 assert(ActualSize >= (NumVecElements * ElementSize) &&
"Invalid vector size");
1545 return ActualSize != (NumVecElements * ElementSize);
1550 addFlag(Buffer, dwarf::DW_AT_GNU_vector);
1552 addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,
1557 if (
auto *VarDIE =
getDIE(Var))
1558 addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);
1562 DwarfExpr.setMemoryLocationKind();
1563 DwarfExpr.addExpression(Expr);
1564 addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
1568 if (
auto *VarDIE =
getDIE(Var))
1569 addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);
1573 DwarfExpr.setMemoryLocationKind();
1574 DwarfExpr.addExpression(Expr);
1575 addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());
1579 if (
auto *VarDIE =
getDIE(Var))
1580 addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);
1584 DwarfExpr.setMemoryLocationKind();
1585 DwarfExpr.addExpression(Expr);
1586 addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
1590 addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,
1591 RankConst->getSExtValue());
1592 }
else if (
auto *RankExpr = CTy->
getRankExp()) {
1595 DwarfExpr.setMemoryLocationKind();
1596 DwarfExpr.addExpression(RankExpr);
1597 addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
1606 DIE *IdxTy = getIndexTyDie();
1610 for (
DINode *E : Elements) {
1612 if (
auto *Element = dyn_cast_or_null<DINode>(E)) {
1613 if (Element->getTag() == dwarf::DW_TAG_subrange_type)
1614 constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
1615 else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)
1616 constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element),
1629 addFlag(Buffer, dwarf::DW_AT_enum_class);
1633 addUInt(Buffer, dwarf::DW_AT_APPLE_enum_kind, dwarf::DW_FORM_data1, *Kind);
1636 bool IndexEnumerators = !Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||
1637 isa<DINamespace>(Context) || isa<DICommonBlock>(Context);
1641 for (
const DINode *E : Elements) {
1642 auto *
Enum = dyn_cast_or_null<DIEnumerator>(E);
1648 if (IndexEnumerators)
1656 DIE &SPDie = *
P.first;
1663 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
1675 if (
DIType *Resolved = DT->getBaseType())
1680 if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) {
1687 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1688 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1689 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1690 addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits());
1691 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1692 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1693 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1695 addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
1699 uint32_t AlignInBytes = DT->getAlignInBytes();
1702 bool IsBitfield = DT->isBitField();
1706 addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8);
1707 addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt,
Size);
1709 assert(DT->getOffsetInBits() <=
1710 (
uint64_t)std::numeric_limits<int64_t>::max());
1711 int64_t Offset = DT->getOffsetInBits();
1716 uint32_t AlignMask = ~(AlignInBits - 1);
1718 uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1720 OffsetInBytes = (Offset - StartBitOffset) / 8;
1723 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1724 uint64_t FieldOffset = (HiMark - FieldSize);
1725 Offset -= FieldOffset;
1729 Offset = FieldSize - (Offset +
Size);
1732 addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
1735 addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,
1737 OffsetInBytes = FieldOffset >> 3;
1739 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset);
1743 OffsetInBytes = DT->getOffsetInBits() / 8;
1745 addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1751 addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1752 addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1753 addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1760 addUInt(MemberDie, dwarf::DW_AT_data_member_location,
1761 dwarf::DW_FORM_udata, OffsetInBytes);
1763 addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,
1770 if (DT->isVirtual())
1771 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
1772 dwarf::DW_VIRTUALITY_virtual);
1775 if (
DINode *PNode = DT->getObjCProperty())
1778 dwarf::DW_FORM_ref4,
DIEEntry(*PDie));
1780 if (DT->isArtificial())
1781 addFlag(MemberDie, dwarf::DW_AT_artificial);
1794 "Static member should belong to a type.");
1797 return StaticMemberDIE;
1801 const DIType *Ty = DT->getBaseType();
1803 addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName());
1806 addFlag(StaticMemberDIE, dwarf::DW_AT_external);
1807 addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
1810 if (DT->isArtificial())
1811 addFlag(StaticMemberDIE, dwarf::DW_AT_artificial);
1815 addAccess(StaticMemberDIE, DT->getFlags());
1817 if (
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
1819 if (
const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
1822 if (
uint32_t AlignInBytes = DT->getAlignInBytes())
1823 addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1826 return &StaticMemberDIE;
1833 isDwoUnit() ?
"debug_info_dwo" :
"debug_info",
"Length of Unit");
1874 : dwarf::DW_UT_type);
1876 Asm->
OutStreamer->emitIntValue(TypeSignature,
sizeof(TypeSignature));
1896bool DwarfTypeUnit::isDwoUnit()
const {
1912const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress()
const {
1929 "DW_AT_rnglists_base requires DWARF version 5 or later");
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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 bool hasVectorBeenPadded(const DICompositeType *CTy)
Returns true if the vector's size differs from the sum of sizes of elements the user specified.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null,...
static unsigned getSize(unsigned Kind)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
int64_t getSExtValue() const
Get sign extended value.
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
void resetUsedFlag(bool HasBeenUsed=false)
Annotations lets you mark points and ranges inside source code, for tests:
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
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
TargetMachine & TM
Target machine description.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
void emitInt8(int Value) const
Emit a byte directive and value.
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
virtual unsigned getISAEncoding()
Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
void emitInt16(int Value) const
Emit a short directive and value.
const DataLayout & getDataLayout() const
Return information about data layout.
dwarf::FormParams getDwarfFormParams() const
Returns information about the byte size of DW_FORM values.
bool doesDwarfUseRelocationsAcrossSections() const
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
Basic type, like 'int' or 'float'.
unsigned getEncoding() const
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
static std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
DIExpression * getRankExp() const
DIExpression * getAssociatedExp() const
DIVariable * getAllocated() const
DIExpression * getDataLocationExp() const
DIVariable * getAssociated() const
DIDerivedType * getDiscriminator() const
DIVariable * getDataLocation() const
unsigned getRuntimeLang() const
DIType * getSpecification() const
StringRef getIdentifier() const
DINodeArray getElements() const
DITemplateParameterArray getTemplateParams() const
DIExpression * getAllocatedExp() const
std::optional< uint32_t > getEnumKind() const
DIType * getVTableHolder() const
DINodeArray getAnnotations() const
ConstantInt * getRankConst() const
MDString * getRawIdentifier() const
DIType * getBaseType() const
DINodeArray getAnnotations() const
Get annotations associated with this derived type.
DITemplateParameterArray getTemplateParams() const
Get the template parameters from a template alias.
DIEBlock - Represents a block of values.
A simple label difference DIE.
DwarfExpression implementation for singular DW_AT_location.
DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE)
A pointer to another debug information entry.
A container for inline string values.
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
DIELoc - Represents an expression location.
unsigned computeSize(const dwarf::FormParams &FormParams) const
Calculate the size of the location expression.
dwarf::Form BestForm(unsigned DwarfVersion) const
BestForm - Choose the best form for data.
A container for string pool string values.
Represents a compile or type unit.
MCSection * getSection() const
Return the section that this DIEUnit will be emitted into.
void takeValues(DIEValueList &Other)
Take ownership of the nodes in Other, and append them to the back of the list.
A structured debug information entry.
DIE & addChild(DIE *Child)
Add a child to the DIE.
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
DIEUnit * getUnit() const
Climb up the parent chain to get the compile unit or type unit that this DIE belongs to.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
dwarf::Tag getTag() const
BoundType getLowerBound() const
BoundType getCount() const
BoundType getUpperBound() const
BoundType getStride() const
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
DIScope * getScope() const
StringRef getName() const
bool getExportSymbols() const
Tagged DWARF-like metadata node.
dwarf::Tag getTag() const
Base class for scope-like contexts.
StringRef getName() const
DIScope * getScope() const
String type, Fortran CHARACTER(n)
unsigned getEncoding() const
DIExpression * getStringLengthExp() const
DIVariable * getStringLength() const
DIExpression * getStringLocationExp() const
BoundType getUpperBound() const
BoundType getStride() const
BoundType getLowerBound() const
BoundType getCount() const
Type array for a subprogram.
StringRef getName() const
Metadata * getValue() const
bool isLittleEndian() const
uint32_t getNumExtraInhabitants() const
bool isLValueReference() const
bool isObjcClassComplete() const
MDString * getRawName() const
bool isAppleBlockExtension() const
StringRef getName() const
bool isForwardDecl() const
bool isTypePassByValue() const
uint64_t getSizeInBits() const
uint32_t getAlignInBytes() const
bool isRValueReference() const
bool isArtificial() const
bool getExportSymbols() const
DIScope * getScope() const
bool isTypePassByReference() const
Base class for variables.
This class represents an Operation in the Expression.
bool isLittleEndian() const
Layout endianness...
static bool isUnsignedDIType(const DIType *Ty)
Return true if type encoding is unsigned.
static uint64_t getBaseTypeSize(const DIType *Ty)
If this type is derived from a base type then return base type size.
void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context)
Add a new global name present in a type unit to this compile unit.
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context)
Add a new global type present in a type unit to this compile unit.
Collects and handles dwarf debug information.
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 useAddrOffsetForm() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
bool useInlineStrings() const
Returns whether to use inline strings.
bool generateTypeUnits() const
Returns whether to generate DWARF v4 type units.
AddressPool & getAddressPool()
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
bool shareAcrossDWOCUs() const
const MCSymbol * getSectionLabel(const MCSection *S)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
bool useDWARF2Bitfields() const
Returns whether to use the DWARF2 format for bitfields instyead of the DWARF4 format.
bool useAddrOffsetExpressions() const
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
MCSymbol * getStringOffsetsStartSym() const
MCSymbol * getRnglistsTableBaseSym() const
DwarfStringPool & getStringPool()
Returns the string pool.
DenseMap< const DILocalScope *, DIE * > & getAbstractScopeDIEs()
void insertDIE(const MDNode *TypeMD, DIE *Die)
DIE * getDIE(const MDNode *TypeMD)
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)
Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....
DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID, MCDwarfDwoLineTable *SplitLineTable=nullptr)
void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context) override
Add a new global type to the compile unit.
DwarfCompileUnit & getCU() override
void emitHeader(bool UseOffsets) override
Emit the header for this unit, not including the initial length field.
void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override
Add a new global name to the compile unit.
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.
void addInt(DIE &Die, dwarf::Attribute Attribute, const APInt &Integer, bool Unsigned)
Add an integer attribute data and value; value may be any width.
void addThrownTypes(DIE &Die, DINodeArray ThrownTypes)
Add thrown types.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void addAnnotation(DIE &Buffer, DINodeArray Annotations)
Add DW_TAG_LLVM_annotation.
std::vector< DIEBlock * > DIEBlocks
A list of all the DIEBlocks in use.
std::vector< DIELoc * > DIELocs
A list of all the DIELocs in use.
uint16_t getLanguage() const
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.
bool useSegmentedStringOffsetsTable() const
bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie, bool Minimal)
DIELoc * getDIELoc()
Returns a fresh newly allocated DIELoc.
void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, const DIE &TyDIE)
If this is a named finished type then include it in the list of types for the accelerator tables.
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 addAccess(DIE &Die, DINode::DIFlags Flags)
Add the accessibility attribute.
void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
addSectionDelta - Add a label delta attribute data and value.
void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context)
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
DenseMap< DIE *, const DINode * > ContainingTypeMap
This map is used to keep track of subprogram DIEs that need DW_AT_containing_type attribute.
const DICompileUnit * CUNode
MDNode for the compile unit.
virtual unsigned getOrCreateSourceID(const DIFile *File)=0
Look up the source ID for the given file.
virtual void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context)=0
Add a new global type to the compile unit.
void addDIETypeSignature(DIE &Die, uint64_t Signature)
Add a type's DW_AT_signature and set the declaration flag.
virtual DwarfCompileUnit & getCU()=0
DIE * getDIE(const DINode *D) const
Returns the DIE map slot for the specified debug variable.
virtual unsigned getHeaderSize() const
Compute the size of a header for this unit, not including the initial length field.
void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args)
Construct function argument DIEs.
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, 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 * IndexTyDie
An anonymous type for index type. Owned by DIEUnit.
void addRnglistsBase()
Add the DW_AT_rnglists_base attribute to the unit DIE.
DIE * getOrCreateModule(const DIModule *M)
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.
void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer)
Add an offset into a section attribute data and value.
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 constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
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.
bool isShareableAcrossCUs(const DINode *D) const
Check whether the DIE for this MDNode can be shared across CUs.
void addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label)
DenseMap< const MDNode *, DIE * > MDNodeToDieMap
Tracks the mapping of unit level debug information variables to debug information entries.
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)
virtual void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context)=0
Add a new global name to the compile unit.
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.
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.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
uint16_t getDwarfVersion() const
unsigned getFile(StringRef Directory, StringRef FileName, std::optional< MD5::MD5Result > Checksum, uint16_t DwarfVersion, std::optional< StringRef > Source)
MCSection * getDwarfStrOffSection() const
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfAbbrevSection() const
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MDOperand & getOperand(unsigned I) const
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
unsigned DebugStrictDwarf
When set to true, don't use DWARF extensions in later DWARF versions.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
UnitType
Constants for unit types in DWARF v5.
bool isCPlusPlus(SourceLanguage S)
TypeKind getArrayIndexTypeEncoding(SourceLanguage S)
@ DW_FLAG_type_implementation
bool isC(SourceLanguage S)
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
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...
Description of the encoding of one expression Op.