48 #define DEBUG_TYPE "dwarfdebug" 55 void DIEDwarfExpression::emitOp(uint8_t
Op,
const char* Comment) {
59 void DIEDwarfExpression::emitSigned(int64_t
Value) {
63 void DIEDwarfExpression::emitUnsigned(uint64_t
Value) {
68 unsigned MachineReg) {
74 :
DIEUnit(A->getDwarfVersion(), A->MAI->getCodePointerSize(), UnitTag),
75 CUNode(Node),
Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) {
82 SplitLineTable(SplitLineTable) {
86 for (
unsigned j = 0, M =
DIEBlocks.size(); j < M; ++j)
88 for (
unsigned j = 0, M =
DIELocs.size(); j < M; ++j)
92 int64_t DwarfUnit::getDefaultLowerBound()
const {
98 case dwarf::DW_LANG_C:
99 case dwarf::DW_LANG_C89:
100 case dwarf::DW_LANG_C_plus_plus:
103 case dwarf::DW_LANG_Fortran77:
104 case dwarf::DW_LANG_Fortran90:
108 case dwarf::DW_LANG_C99:
109 case dwarf::DW_LANG_ObjC:
110 case dwarf::DW_LANG_ObjC_plus_plus:
115 case dwarf::DW_LANG_Fortran95:
121 case dwarf::DW_LANG_D:
122 case dwarf::DW_LANG_Java:
123 case dwarf::DW_LANG_Python:
124 case dwarf::DW_LANG_UPC:
129 case dwarf::DW_LANG_Ada83:
130 case dwarf::DW_LANG_Ada95:
131 case dwarf::DW_LANG_Cobol74:
132 case dwarf::DW_LANG_Cobol85:
133 case dwarf::DW_LANG_Modula2:
134 case dwarf::DW_LANG_Pascal83:
135 case dwarf::DW_LANG_PLI:
141 case dwarf::DW_LANG_BLISS:
142 case dwarf::DW_LANG_C11:
143 case dwarf::DW_LANG_C_plus_plus_03:
144 case dwarf::DW_LANG_C_plus_plus_11:
145 case dwarf::DW_LANG_C_plus_plus_14:
146 case dwarf::DW_LANG_Dylan:
147 case dwarf::DW_LANG_Go:
148 case dwarf::DW_LANG_Haskell:
149 case dwarf::DW_LANG_OCaml:
150 case dwarf::DW_LANG_OpenCL:
151 case dwarf::DW_LANG_RenderScript:
152 case dwarf::DW_LANG_Rust:
153 case dwarf::DW_LANG_Swift:
158 case dwarf::DW_LANG_Fortran03:
159 case dwarf::DW_LANG_Fortran08:
160 case dwarf::DW_LANG_Julia:
161 case dwarf::DW_LANG_Modula3:
181 return (isa<DIType>(D) ||
182 (isa<DISubprogram>(
D) && !cast<DISubprogram>(D)->isDefinition())) &&
213 assert(Form != dwarf::DW_FORM_implicit_const &&
214 "DW_FORM_implicit_const is used only for signed integers");
247 isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;
249 auto StringPoolEntry =
256 IxForm = dwarf::DW_FORM_strx1;
257 unsigned Index = StringPoolEntry.getIndex();
258 if (Index > 0xffffff)
259 IxForm = dwarf::DW_FORM_strx4;
260 else if (Index > 0xffff)
261 IxForm = dwarf::DW_FORM_strx3;
262 else if (Index > 0xff)
263 IxForm = dwarf::DW_FORM_strx2;
283 addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
285 addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
299 std::string ChecksumString =
fromHex(Checksum->Value);
301 memcpy(CKMem, ChecksumString.data(), 16);
305 unsigned DwarfTypeUnit::getOrCreateSourceID(
const DIFile *
File) {
308 if (!UsedLineTable) {
309 UsedLineTable =
true;
319 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);
325 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
326 addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
331 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
332 addLabel(Die, dwarf::DW_FORM_udata, Sym);
350 addFlag(Die, dwarf::DW_AT_declaration);
353 dwarf::DW_FORM_ref_sig8,
DIEInteger(Signature));
366 EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
395 unsigned FileID = getOrCreateSourceID(File);
396 assert(FileID &&
"Invalid file id");
397 addUInt(Die, dwarf::DW_AT_decl_file,
None, FileID);
439 if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
442 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type)
450 if (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
457 if (T == dwarf::DW_TAG_pointer_type ||
458 T == dwarf::DW_TAG_ptr_to_member_type ||
459 T == dwarf::DW_TAG_reference_type ||
460 T == dwarf::DW_TAG_rvalue_reference_type)
462 assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
463 T == dwarf::DW_TAG_volatile_type ||
464 T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
466 assert(Deriv &&
"Expected valid base type");
470 auto *BTy = cast<DIBasicType>(Ty);
471 unsigned Encoding = BTy->getEncoding();
472 assert((Encoding == dwarf::DW_ATE_unsigned ||
473 Encoding == dwarf::DW_ATE_unsigned_char ||
474 Encoding == dwarf::DW_ATE_signed ||
475 Encoding == dwarf::DW_ATE_signed_char ||
476 Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
477 Encoding == dwarf::DW_ATE_boolean ||
478 (Ty->
getTag() == dwarf::DW_TAG_unspecified_type &&
479 Ty->
getName() ==
"decltype(nullptr)")) &&
480 "Unsupported encoding");
481 return Encoding == dwarf::DW_ATE_unsigned ||
482 Encoding == dwarf::DW_ATE_unsigned_char ||
483 Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
484 Ty->
getTag() == dwarf::DW_TAG_unspecified_type;
494 const char *FltPtr = (
const char *)FltVal.
getRawData();
498 int Incr = (LittleEndian ? 1 : -1);
499 int Start = (LittleEndian ? 0 : NumBytes - 1);
500 int Stop = (LittleEndian ? NumBytes : -1);
503 for (; Start != Stop; Start += Incr)
504 addUInt(*Block, dwarf::DW_FORM_data1, (
unsigned char)0xFF & FltPtr[Start]);
506 addBlock(Die, dwarf::DW_AT_const_value, Block);
529 addUInt(Die, dwarf::DW_AT_const_value,
530 Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
539 if (CIBitWidth <= 64) {
554 for (
int i = 0; i < NumBytes; i++) {
557 c = Ptr64[i / 8] >> (8 * (i & 7));
559 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
560 addUInt(*Block, dwarf::DW_FORM_data1, c);
563 addBlock(Die, dwarf::DW_AT_const_value, Block);
567 if (!LinkageName.
empty())
570 : dwarf::DW_AT_MIPS_linkage_name,
576 for (
const auto *Element : TParams) {
577 if (
auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))
578 constructTemplateTypeParameterDIE(Buffer, TTP);
579 else if (
auto *TVP = dyn_cast<DITemplateValueParameter>(Element))
580 constructTemplateValueParameterDIE(Buffer, TVP);
586 for (
const auto *Ty : ThrownTypes) {
593 if (!Context || isa<DIFile>(Context))
595 if (
auto *
T = dyn_cast<DIType>(Context))
597 if (
auto *NS = dyn_cast<DINamespace>(Context))
599 if (
auto *
SP = dyn_cast<DISubprogram>(Context))
601 if (
auto *M = dyn_cast<DIModule>(Context))
626 auto *Ty = cast<DIType>(TyNode);
650 if (
auto *
BT = dyn_cast<DIBasicType>(Ty))
652 else if (
auto *STy = dyn_cast<DISubroutineType>(Ty))
654 else if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
656 if (
MDString *TypeId = CTy->getRawIdentifier()) {
672 bool IsImplementation =
false;
673 if (
auto *CT = dyn_cast<DICompositeType>(Ty)) {
676 IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
681 if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(
Context) ||
682 isa<DINamespace>(Context))
689 assert(Ty &&
"Trying to add a type that doesn't exist?");
703 while (!isa<DICompileUnit>(Context)) {
717 if (Name.
empty() && isa<DINamespace>(Ctx))
718 Name =
"(anonymous namespace)";
732 addString(Buffer, dwarf::DW_AT_name, Name);
735 if (BTy->
getTag() == dwarf::DW_TAG_unspecified_type)
738 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
742 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
745 addUInt(Buffer, dwarf::DW_AT_endianity,
None, dwarf::DW_END_big);
747 addUInt(Buffer, dwarf::DW_AT_endianity,
None, dwarf::DW_END_little);
763 addString(Buffer, dwarf::DW_AT_name, Name);
766 if (Size && Tag != dwarf::DW_TAG_pointer_type
767 && Tag != dwarf::DW_TAG_ptr_to_member_type
768 && Tag != dwarf::DW_TAG_reference_type
769 && Tag != dwarf::DW_TAG_rvalue_reference_type)
770 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
772 if (Tag == dwarf::DW_TAG_ptr_to_member_type)
774 Buffer, dwarf::DW_AT_containing_type,
782 if (DTy->getDWARFAddressSpace() && (Tag == dwarf::DW_TAG_pointer_type ||
783 Tag == dwarf::DW_TAG_reference_type))
784 addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,
785 DTy->getDWARFAddressSpace().getValue());
789 for (
unsigned i = 1,
N = Args.
size(); i <
N; ++i) {
792 assert(i == N-1 &&
"Unspecified parameter must be the last argument");
798 addFlag(Arg, dwarf::DW_AT_artificial);
805 auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();
807 if (
auto RTy =
resolve(Elements[0]))
810 bool isPrototyped =
true;
811 if (Elements.size() == 2 && !Elements[1])
812 isPrototyped =
false;
820 (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
821 Language == dwarf::DW_LANG_ObjC))
822 addFlag(Buffer, dwarf::DW_AT_prototyped);
825 if (CTy->
getCC() && CTy->
getCC() != dwarf::DW_CC_normal)
826 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
830 addFlag(Buffer, dwarf::DW_AT_reference);
833 addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
844 case dwarf::DW_TAG_array_type:
845 constructArrayTypeDIE(Buffer, CTy);
847 case dwarf::DW_TAG_enumeration_type:
848 constructEnumTypeDIE(Buffer, CTy);
850 case dwarf::DW_TAG_variant_part:
851 case dwarf::DW_TAG_structure_type:
852 case dwarf::DW_TAG_union_type:
853 case dwarf::DW_TAG_class_type: {
856 if (Tag == dwarf::DW_TAG_variant_part) {
863 DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
864 addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
870 for (
const auto *Element : Elements) {
873 if (
auto *
SP = dyn_cast<DISubprogram>(Element))
875 else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
876 if (DDTy->getTag() == dwarf::DW_TAG_friend) {
878 addType(ElemDie,
resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
879 }
else if (DDTy->isStaticMember()) {
881 }
else if (Tag == dwarf::DW_TAG_variant_part) {
886 dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
888 addUInt(Variant, dwarf::DW_AT_discr_value,
None, CI->getZExtValue());
890 addSInt(Variant, dwarf::DW_AT_discr_value,
None, CI->getSExtValue());
892 constructMemberDIE(Variant, DDTy);
894 constructMemberDIE(Buffer, DDTy);
896 }
else if (
auto *Property = dyn_cast<DIObjCProperty>(Element)) {
898 StringRef PropertyName = Property->getName();
899 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
900 if (Property->getType())
903 StringRef GetterName = Property->getGetterName();
904 if (!GetterName.
empty())
905 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
906 StringRef SetterName = Property->getSetterName();
907 if (!SetterName.
empty())
908 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
909 if (
unsigned PropertyAttributes = Property->getAttributes())
910 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute,
None,
912 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
913 if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
921 addFlag(Buffer, dwarf::DW_AT_APPLE_block);
932 addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
936 if (Tag == dwarf::DW_TAG_class_type ||
937 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
943 CC = dwarf::DW_CC_pass_by_value;
945 CC = dwarf::DW_CC_pass_by_reference;
947 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
957 addString(Buffer, dwarf::DW_AT_name, Name);
959 if (Tag == dwarf::DW_TAG_enumeration_type ||
960 Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
961 Tag == dwarf::DW_TAG_union_type) {
965 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
972 addFlag(Buffer, dwarf::DW_AT_declaration);
981 addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
986 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
991 void DwarfUnit::constructTemplateTypeParameterDIE(
1002 void DwarfUnit::constructTemplateValueParameterDIE(
1008 if (VP->
getTag() == dwarf::DW_TAG_template_value_parameter)
1013 if (
ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
1015 else if (
GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
1018 if (!GV->hasDLLImportStorageClass()) {
1025 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
1026 addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
1028 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_template_param) {
1029 assert(isa<MDString>(Val));
1030 addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
1031 cast<MDString>(Val)->getString());
1032 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
1051 Name =
"(anonymous namespace)";
1055 addFlag(NDie, dwarf::DW_AT_export_symbols);
1073 addString(MDie, dwarf::DW_AT_LLVM_config_macros,
1093 if (
auto *SPDecl = SP->getDeclaration()) {
1107 if (SP->isDefinition())
1116 DIE *DeclDie =
nullptr;
1118 if (
auto *SPDecl = SP->getDeclaration()) {
1119 DeclDie =
getDIE(SPDecl);
1120 assert(DeclDie &&
"This DIE should've already been constructed when the " 1121 "definition DIE was created in " 1122 "getOrCreateSubprogramDIE");
1125 DeclLinkageName = SPDecl->getLinkageName();
1126 unsigned DeclID = getOrCreateSourceID(SPDecl->getFile());
1127 unsigned DefID = getOrCreateSourceID(SP->
getFile());
1128 if (DeclID != DefID)
1129 addUInt(SPDie, dwarf::DW_AT_decl_file,
None, DefID);
1131 if (SP->getLine() != SPDecl->getLine())
1132 addUInt(SPDie, dwarf::DW_AT_decl_line,
None, SP->getLine());
1140 assert(((LinkageName.empty() || DeclLinkageName.
empty()) ||
1141 LinkageName == DeclLinkageName) &&
1142 "decl has a linkage name and it is different");
1143 if (DeclLinkageName.
empty() &&
1153 addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
1158 bool SkipSPAttributes) {
1161 bool SkipSPSourceLocation = SkipSPAttributes &&
1163 if (!SkipSPSourceLocation)
1171 if (!SkipSPSourceLocation)
1175 if (SkipSPAttributes)
1181 if (SP->isPrototyped() &&
1182 (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
1183 Language == dwarf::DW_LANG_ObjC))
1184 addFlag(SPDie, dwarf::DW_AT_prototyped);
1189 Args = SPTy->getTypeArray();
1194 if (CC && CC != dwarf::DW_CC_normal)
1195 addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);
1200 if (
auto Ty =
resolve(Args[0]))
1203 unsigned VK = SP->getVirtuality();
1205 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
1206 if (SP->getVirtualIndex() != -1u) {
1208 addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1209 addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());
1210 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);
1213 std::make_pair(&SPDie,
resolve(SP->getContainingType())));
1216 if (!SP->isDefinition()) {
1217 addFlag(SPDie, dwarf::DW_AT_declaration);
1226 if (SP->isArtificial())
1227 addFlag(SPDie, dwarf::DW_AT_artificial);
1229 if (!SP->isLocalToUnit())
1230 addFlag(SPDie, dwarf::DW_AT_external);
1233 if (SP->isOptimized())
1234 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
1237 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag,
isa);
1240 if (SP->isLValueReference())
1241 addFlag(SPDie, dwarf::DW_AT_reference);
1243 if (SP->isRValueReference())
1244 addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
1246 if (SP->isNoReturn())
1247 addFlag(SPDie, dwarf::DW_AT_noreturn);
1249 if (SP->isProtected())
1250 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1252 else if (SP->isPrivate())
1253 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1255 else if (SP->isPublic())
1256 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1259 if (SP->isExplicit())
1260 addFlag(SPDie, dwarf::DW_AT_explicit);
1262 if (SP->isMainSubprogram())
1263 addFlag(SPDie, dwarf::DW_AT_main_subprogram);
1266 void DwarfUnit::constructSubrangeDIE(
DIE &Buffer,
const DISubrange *SR,
1269 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
1275 int64_t LowerBound = SR->getLowerBound();
1276 int64_t DefaultLowerBound = getDefaultLowerBound();
1279 Count = CI->getSExtValue();
1281 if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
1282 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound,
None, LowerBound);
1285 if (
auto *CountVarDIE =
getDIE(CV))
1286 addDIEEntry(DW_Subrange, dwarf::DW_AT_count, *CountVarDIE);
1287 }
else if (Count != -1)
1288 addUInt(DW_Subrange, dwarf::DW_AT_count,
None, Count);
1291 DIE *DwarfUnit::getIndexTyDie() {
1300 dwarf::DW_ATE_unsigned);
1309 assert(CTy && CTy->
isVector() &&
"Composite type is not a vector");
1314 assert(BaseTy &&
"Unknown vector element type.");
1319 assert(Elements.size() == 1 &&
1320 Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&
1321 "Invalid vector element array, expected one element of type subrange");
1322 const auto Subrange = cast<DISubrange>(Elements[0]);
1323 const auto CI = Subrange->getCount().get<
ConstantInt *>();
1328 assert(ActualSize >= (NumVecElements * ElementSize) &&
"Invalid vector size");
1329 return ActualSize != (NumVecElements * ElementSize);
1334 addFlag(Buffer, dwarf::DW_AT_GNU_vector);
1346 DIE *IdxTy = getIndexTyDie();
1350 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
1352 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[i]))
1353 if (Element->getTag() == dwarf::DW_TAG_subrange_type)
1354 constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
1365 addFlag(Buffer, dwarf::DW_AT_enum_class);
1371 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
1372 auto *Enum = dyn_cast_or_null<DIEnumerator>(Elements[i]);
1376 addString(Enumerator, dwarf::DW_AT_name, Name);
1377 auto Value =
static_cast<uint64_t
>(Enum->getValue());
1386 DIE &SPDie = *CI->first;
1393 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
1401 addString(MemberDie, dwarf::DW_AT_name, Name);
1415 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1416 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1417 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1419 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1420 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1421 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1423 addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
1428 uint64_t OffsetInBytes;
1430 bool IsBitfield = FieldSize && Size != FieldSize;
1434 addUInt(MemberDie, dwarf::DW_AT_byte_size,
None, FieldSize/8);
1435 addUInt(MemberDie, dwarf::DW_AT_bit_size,
None, Size);
1442 uint32_t AlignMask = ~(AlignInBits - 1);
1444 uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1446 OffsetInBytes = (Offset - StartBitOffset) / 8;
1449 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1450 uint64_t FieldOffset = (HiMark - FieldSize);
1451 Offset -= FieldOffset;
1455 Offset = FieldSize - (Offset + Size);
1457 addUInt(MemberDie, dwarf::DW_AT_bit_offset,
None, Offset);
1458 OffsetInBytes = FieldOffset >> 3;
1460 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset,
None, Offset);
1466 addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1472 addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1473 addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1474 addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1476 addUInt(MemberDie, dwarf::DW_AT_data_member_location,
None,
1481 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1484 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1488 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1491 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
1492 dwarf::DW_VIRTUALITY_virtual);
1495 if (
DINode *PNode = DT->getObjCProperty())
1498 dwarf::DW_FORM_ref4,
DIEEntry(*PDie));
1501 addFlag(MemberDie, dwarf::DW_AT_artificial);
1514 "Static member should belong to a type.");
1517 return StaticMemberDIE;
1526 addFlag(StaticMemberDIE, dwarf::DW_AT_external);
1527 addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
1532 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1535 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1538 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1541 if (
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
1543 if (
const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
1547 addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1550 return &StaticMemberDIE;
1597 : dwarf::DW_UT_type);
1599 Asm->
OutStreamer->EmitIntValue(TypeSignature,
sizeof(TypeSignature));
1611 : dwarf::DW_FORM_data4,
1621 : dwarf::DW_FORM_data4,
1626 bool DwarfTypeUnit::isDwoUnit()
const {
1642 const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress()
const {
1659 "DW_AT_rnglists_base requires DWARF version 5 or later");
1663 TLOF.getDwarfRnglistsSection()->getBeginSymbol());
1668 "DW_AT_loclists_base requires DWARF version 5 or later");
1672 TLOF.getDwarfLoclistsSection()->getBeginSymbol());
const DICompileUnit * getCUNode() const
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...
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
addSectionDelta - Add a label delta attribute data and value.
MCSection * getDwarfStrOffSection() const
static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty)
Return true if type encoding is unsigned.
uint64_t getOffsetInBits() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
bool isTypePassByValue() const
uint64_t getZExtValue() const
Get zero extended value.
void addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
Add a label delta attribute data and value.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
StringRef getName() const
std::vector< DIELoc * > DIELocs
A list of all the DIELocs in use.
DIELoc - Represents an expression location.
This class represents lattice values for constants.
StringRef getName() const
DIE * getOrCreateStaticMemberDIE(const DIDerivedType *DT)
Create new static data member DIE.
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...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void push_back(const T &Elt)
void addThrownTypes(DIE &Die, DINodeArray ThrownTypes)
Add thrown types.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
void insertDIE(const DINode *Desc, DIE *D)
Insert DIE into the map.
DITypeRef getBaseType() const
Collects and handles dwarf debug information.
DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable=nullptr)
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
MD5::MD5Result * getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null, or not exclusively derived from constant.
void addLoclistsBase()
Add the DW_AT_loclists_base attribute to the unit DIE.
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
unsigned const TargetRegisterInfo * TRI
static bool hasVectorBeenPadded(const DICompositeType *CTy)
Returns true if the vector's size differs from the sum of sizes of elements the user specified...
MachineFunction * MF
The current machine function.
StringRef getConfigurationMacros() const
bool useSegmentedStringOffsetsTable() const
bool isForwardDecl() const
bool getDebugInfoForProfiling() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute=dwarf::DW_AT_type)
Add a new type attribute to the specified entity.
DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)
Add a Dwarf section label attribute data and value.
StringRef getName() const
AsmPrinter * Asm
Target of Dwarf emission.
Tagged DWARF-like metadata node.
unsigned getBitWidth() const
Return the number of bits in the APInt.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation.
DINodeArray getElements() const
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support...
constexpr char Language[]
Key for Kernel::Metadata::mLanguage.
DIE * getDIE(const DINode *D) const
Returns the DIE map slot for the specified debug variable.
T * resolve(TypedDINodeRef< T > Ref) const
Look in the DwarfDebug map for the MDNode that corresponds to the reference.
MCSymbol * getRnglistsTableBaseSym() const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
MCSymbol * getLoclistsTableBaseSym() const
bool isLValueReference() const
bool isDebugDirectivesOnly() const
const ConstantFP * getFPImm() const
bool isShareableAcrossCUs(const DINode *D) const
Check whether the DIE for this MDNode can be shared across CUs.
void addConstantFPValue(DIE &Die, const MachineOperand &MO)
Add constant value entry in variable DIE.
void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context)
Add a new global type present in a type unit to this compile unit.
uint64_t getSizeInBits() const
void constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
Holds a subclass of DINode.
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
DITypeRef getVTableHolder() const
StringRef getFilename() const
This file implements a class to represent arbitrary precision integral constant values and operations...
DIE * getOrCreateTypeDIE(const MDNode *TyNode)
Find existing DIE or create new DIE for the given type.
void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc)
Add block data.
DenseMap< DIE *, const DINode * > ContainingTypeMap
This map is used to keep track of subprogram DIEs that need DW_AT_containing_type attribute...
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
bool getExportSymbols() const
AddressPool & getAddressPool()
int64_t getSExtValue() const
Get sign extended value.
StringRef getIncludePath() const
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...
unsigned getRuntimeLang() const
DenseMap< const MDNode *, DIE * > & getAbstractSPDies()
unsigned getFile(StringRef Directory, StringRef FileName, MD5::MD5Result *Checksum, Optional< StringRef > Source)
bool doesDwarfUseRelocationsAcrossSections() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
uint32_t getAlignInBytes() const
DwarfCompileUnit & getCU() override
const APInt & getValue() const
Return the constant as an APInt value reference.
bool isLittleEndian() const
Layout endianness...
MCSymbol * EndLabel
Emitted at the end of the CU and used to compute the CU Length field.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context)
Add a new global name present in a type unit to this compile unit.
DIE * getOrCreateNameSpace(const DINamespace *NS)
DIE & addChild(DIE *Child)
Add a child to the DIE.
MCSection * getDwarfAbbrevSection() const
void addConstantValue(DIE &Die, const MachineOperand &MO, const DIType *Ty)
Add constant value entry in variable DIE.
MCSymbol * getStringOffsetsStartSym() const
DIScope * getScope() const
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
Metadata * getValue() const
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, bool SkipSPAttributes=false)
void addSourceLine(DIE &Die, unsigned Line, const DIFile *File)
Add location information to specified debug information entry.
void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override
Add a new global name to the compile unit.
A pointer to another debug information entry.
DITemplateParameterArray getTemplateParams() const
This dwarf writer support class manages information associated with a source file.
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE)
DwarfStringPool & getStringPool()
Returns the string pool.
DIEValueList::value_iterator addLabel(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label)
Add a Dwarf label attribute data and value.
const DIEUnit * getUnit() const
Climb up the parent chain to get the compile unit or type unit that this DIE belongs to...
bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie)
const MCAsmInfo * MAI
Target Asm Printer information.
CountType getCount() const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
A container for inline string values.
A structured debug information entry.
DIELoc * getDIELoc()
Returns a fresh newly allocated DIELoc.
ConstantFP - Floating Point Values [float, double].
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
This class is intended to be used as a driving class for all asm writers.
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.
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
DenseMap< const MDNode *, DIE * > MDNodeToDieMap
Tracks the mapping of unit level debug information variables to debug information entries...
bool useDWARF2Bitfields() const
Returns whether to use the DWARF2 format for bitfields instyead of the DWARF4 format.
void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT)
Emit the common part of the header for this unit.
DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal=false)
void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, char Flags)
Base class for variables.
bool isObjcClassComplete() const
T * resolve(TypedDINodeRef< T > Ref) const
Find the MDNode for the given reference.
StringRef getDirectory() const
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A container for string pool string values.
bool isRValueReference() const
void addSInt(DIEValueList &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, int64_t Integer)
Add an signed integer attribute data and value.
DIE * IndexTyDie
An anonymous type for index type. Owned by DIEUnit.
Base class for scope-like contexts.
A simple label difference DIE.
std::string getParentContextString(const DIScope *Context) const
Get string containing language specific context for a global name.
UnitType
Constants for unit types in DWARF v5.
void insertDIE(const MDNode *TypeMD, DIE *Die)
const APFloat & getValueAPF() const
uint16_t getLanguage() const
unsigned getHeaderSize() const override
Compute the size of a header for this unit, not including the initial length field.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isLittleEndian() const
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
This is the shared class of boolean and integer constants.
void addAccelNamespace(const DICompileUnit &CU, StringRef Name, const DIE &Die)
StringRef getName() const
MCSection * getSection() const
Return the section that this DIEUnit will be emitted into.
MCSymbol * getSymbol(const GlobalValue *GV) const
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void addLinkageName(DIE &Die, StringRef LinkageName)
Add a linkage name, if it isn't empty.
Represents a compile or type unit.
MCSymbol * getBeginSymbol()
void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context) override
Add a new global type to the compile unit.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
LLVM_NODISCARD bool isa(const Y &Val)
bool useAppleExtensionAttributes() const
DITypeRef getType() const
void emitInt32(int Value) const
Emit a long directive and value.
void addRnglistsBase()
Add the DW_AT_rnglists_base attribute to the unit DIE.
void addTemplateParams(DIE &Buffer, DINodeArray TParams)
Add template parameters in buffer.
Class for arbitrary precision integers.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1', drop it.
dwarf::Form BestForm(unsigned DwarfVersion) const
BestForm - Choose the best form for data.
A (clang) module that has been imported by the compile unit.
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)
Add a DIE attribute data and value.
dwarf::Tag getTag() const
amdgpu Simplify well known AMD library false Value Value * Arg
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
Type array for a subprogram.
StringRef getName() const
bool isArtificial() const
unsigned getEncoding() const
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
dwarf::Form BestForm() const
BestForm - Choose the best form for data.
DIE & createAndAddDIE(unsigned 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...
StringRef getName() const
Return a constant reference to the value's name.
bool shareAcrossDWOCUs() const
DIE * getDIE(const MDNode *TypeMD)
void emitHeader(bool UseOffsets) override
Emit the header for this unit, not including the initial length field.
Optional< StringRef > getSource() const
DIE * getOrCreateModule(const DIModule *M)
void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
const DICompileUnit * CUNode
MDNode for the compile unit.
virtual unsigned getISAEncoding()
Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer)
Add an offset into a section attribute data and value.
void addDIETypeSignature(DIE &Die, uint64_t Signature)
Add a type's DW_AT_signature and set the declaration flag.
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
reverse_iterator rbegin()
BumpPtrAllocator DIEValueAllocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitInt8(int Value) const
Emit a byte directive and value.
LLVM Value Representation.
DIScopeRef getScope() const
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
unsigned ComputeSize(const AsmPrinter *AP) const
ComputeSize - Calculate the size of the location expression.
DIScope * getScope() const
std::vector< DIEBlock * > DIEBlocks
A list of all the DIEBlocks in use.
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
bool isAppleBlockExtension() const
DIDerivedType * getDiscriminator() const
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
const DataLayout & getDataLayout() const
Return information about data layout.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
static uint64_t getBaseTypeSize(const DITypeRef TyRef)
If this type is derived from a base type then return base type size.
StringRef - Represent a constant reference to a string, i.e.
APInt bitcastToAPInt() const
unsigned ComputeSize(const AsmPrinter *AP) const
ComputeSize - Calculate the size of the location expression.
DIEBlock - Represents a block of values.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args)
Construct function argument DIEs.
bool generateTypeUnits() const
Returns whether to generate DWARF v4 type units.
DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
MCSymbol * createTempSymbol(const Twine &Name) const
StringRef getISysRoot() const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
bool isTypePassByReference() const
void emitInt16(int Value) const
Emit a short directive and value.
bool useInlineStrings() const
Returns whether to use inline strings.
DIE * createTypeDIE(const DICompositeType *Ty)
Get context owner's DIE.
Basic type, like 'int' or 'float'.
DIScopeRef getScope() const
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.