45 #define DEBUG_TYPE "dwarfdebug"
49 cl::desc(
"Generate DWARF4 type units."),
70 unsigned MachineReg) {
77 Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) {
83 :
DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), CU(CU),
84 SplitLineTable(SplitLineTable) {
90 for (
unsigned j = 0, M =
DIEBlocks.size(); j < M; ++j)
92 for (
unsigned j = 0, M =
DIELocs.size(); j < M; ++j)
96 int64_t DwarfUnit::getDefaultLowerBound()
const {
101 case dwarf::DW_LANG_C89:
102 case dwarf::DW_LANG_C99:
103 case dwarf::DW_LANG_C:
104 case dwarf::DW_LANG_C_plus_plus:
105 case dwarf::DW_LANG_ObjC:
106 case dwarf::DW_LANG_ObjC_plus_plus:
109 case dwarf::DW_LANG_Fortran77:
110 case dwarf::DW_LANG_Fortran90:
111 case dwarf::DW_LANG_Fortran95:
115 case dwarf::DW_LANG_Java:
116 case dwarf::DW_LANG_Python:
117 case dwarf::DW_LANG_UPC:
118 case dwarf::DW_LANG_D:
123 case dwarf::DW_LANG_Ada83:
124 case dwarf::DW_LANG_Ada95:
125 case dwarf::DW_LANG_Cobol74:
126 case dwarf::DW_LANG_Cobol85:
127 case dwarf::DW_LANG_Modula2:
128 case dwarf::DW_LANG_Pascal83:
129 case dwarf::DW_LANG_PLI:
135 case dwarf::DW_LANG_OpenCL:
136 case dwarf::DW_LANG_Go:
137 case dwarf::DW_LANG_Haskell:
138 case dwarf::DW_LANG_C_plus_plus_03:
139 case dwarf::DW_LANG_C_plus_plus_11:
140 case dwarf::DW_LANG_OCaml:
141 case dwarf::DW_LANG_Rust:
142 case dwarf::DW_LANG_C11:
143 case dwarf::DW_LANG_Swift:
144 case dwarf::DW_LANG_Dylan:
145 case dwarf::DW_LANG_C_plus_plus_14:
150 case dwarf::DW_LANG_Modula3:
151 case dwarf::DW_LANG_Julia:
152 case dwarf::DW_LANG_Fortran03:
153 case dwarf::DW_LANG_Fortran08:
171 return (isa<DIType>(D) ||
172 (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&
203 assert(Form != dwarf::DW_FORM_implicit_const &&
204 "DW_FORM_implicit_const is used only for signed integers");
228 isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp,
246 addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
248 addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
252 return SplitLineTable ? SplitLineTable->
getFile(DirName, FileName)
258 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
259 addLabel(Die, dwarf::DW_FORM_udata, Sym);
261 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
262 addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
282 addFlag(Die, dwarf::DW_AT_declaration);
285 dwarf::DW_FORM_ref_sig8,
DIEInteger(Signature));
305 EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
336 assert(FileID &&
"Invalid file id");
337 addUInt(Die, dwarf::DW_AT_decl_file,
None, FileID);
436 bool isPointer =
false;
440 if (Tag == dwarf::DW_TAG_pointer_type) {
441 auto *DTy = cast<DIDerivedType>(Ty);
442 TmpTy =
resolve(DTy->getBaseType());
448 DINodeArray Fields = cast<DICompositeType>(TmpTy)->getElements();
452 for (
unsigned i = 0,
N = Fields.size();
i <
N; ++
i) {
453 auto *DT = cast<DIDerivedType>(Fields[
i]);
455 if (fieldName ==
"__forwarding")
456 forwardingField = DT;
457 else if (fieldName == varName)
462 unsigned forwardingFieldOffset = forwardingField->
getOffsetInBits() >> 3;
472 if (Location.
isReg())
491 if (forwardingFieldOffset > 0) {
503 if (varFieldOffset > 0) {
516 if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
519 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type)
527 if (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
534 if (T == dwarf::DW_TAG_pointer_type ||
535 T == dwarf::DW_TAG_ptr_to_member_type ||
536 T == dwarf::DW_TAG_reference_type ||
537 T == dwarf::DW_TAG_rvalue_reference_type)
539 assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
540 T == dwarf::DW_TAG_volatile_type ||
541 T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
543 assert(Deriv &&
"Expected valid base type");
547 auto *BTy = cast<DIBasicType>(Ty);
548 unsigned Encoding = BTy->getEncoding();
549 assert((Encoding == dwarf::DW_ATE_unsigned ||
550 Encoding == dwarf::DW_ATE_unsigned_char ||
551 Encoding == dwarf::DW_ATE_signed ||
552 Encoding == dwarf::DW_ATE_signed_char ||
553 Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
554 Encoding == dwarf::DW_ATE_boolean ||
555 (Ty->
getTag() == dwarf::DW_TAG_unspecified_type &&
556 Ty->
getName() ==
"decltype(nullptr)")) &&
557 "Unsupported encoding");
558 return Encoding == dwarf::DW_ATE_unsigned ||
559 Encoding == dwarf::DW_ATE_unsigned_char ||
560 Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
561 Ty->
getTag() == dwarf::DW_TAG_unspecified_type;
571 const char *FltPtr = (
const char *)FltVal.
getRawData();
575 int Incr = (LittleEndian ? 1 : -1);
576 int Start = (LittleEndian ? 0 : NumBytes - 1);
577 int Stop = (LittleEndian ? NumBytes : -1);
580 for (; Start != Stop; Start += Incr)
581 addUInt(*Block, dwarf::DW_FORM_data1, (
unsigned char)0xFF & FltPtr[Start]);
583 addBlock(Die, dwarf::DW_AT_const_value, Block);
606 addUInt(Die, dwarf::DW_AT_const_value,
607 Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
616 if (CIBitWidth <= 64) {
631 for (
int i = 0;
i < NumBytes;
i++) {
634 c = Ptr64[
i / 8] >> (8 * (
i & 7));
636 c = Ptr64[(NumBytes - 1 -
i) / 8] >> (8 * ((NumBytes - 1 -
i) & 7));
637 addUInt(*Block, dwarf::DW_FORM_data1, c);
640 addBlock(Die, dwarf::DW_AT_const_value, Block);
644 if (!LinkageName.
empty())
647 : dwarf::DW_AT_MIPS_linkage_name,
653 for (
const auto *Element : TParams) {
654 if (
auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))
655 constructTemplateTypeParameterDIE(Buffer, TTP);
656 else if (
auto *TVP = dyn_cast<DITemplateValueParameter>(Element))
657 constructTemplateValueParameterDIE(Buffer, TVP);
662 if (!Context || isa<DIFile>(Context))
664 if (
auto *
T = dyn_cast<DIType>(Context))
666 if (
auto *NS = dyn_cast<DINamespace>(Context))
668 if (
auto *SP = dyn_cast<DISubprogram>(Context))
670 if (
auto *M = dyn_cast<DIModule>(Context))
688 updateAcceleratorTables(
Context, Ty, TyDIE);
696 auto *Ty = cast<DIType>(TyNode);
718 updateAcceleratorTables(
Context, Ty, TyDIE);
720 if (
auto *
BT = dyn_cast<DIBasicType>(Ty))
722 else if (
auto *STy = dyn_cast<DISubroutineType>(Ty))
724 else if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
726 if (
MDString *TypeId = CTy->getRawIdentifier()) {
742 bool IsImplementation =
false;
743 if (
auto *CT = dyn_cast<DICompositeType>(Ty)) {
746 IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
751 if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(
Context) ||
752 isa<DINamespace>(Context))
759 assert(Ty &&
"Trying to add a type that doesn't exist?");
773 while (!isa<DICompileUnit>(Context)) {
787 if (Name.
empty() && isa<DINamespace>(Ctx))
788 Name =
"(anonymous namespace)";
802 addString(Buffer, dwarf::DW_AT_name, Name);
805 if (BTy->
getTag() == dwarf::DW_TAG_unspecified_type)
808 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
812 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
828 addString(Buffer, dwarf::DW_AT_name, Name);
831 if (Size && Tag != dwarf::DW_TAG_pointer_type
832 && Tag != dwarf::DW_TAG_ptr_to_member_type
833 && Tag != dwarf::DW_TAG_reference_type
834 && Tag != dwarf::DW_TAG_rvalue_reference_type)
835 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
837 if (Tag == dwarf::DW_TAG_ptr_to_member_type)
839 Buffer, dwarf::DW_AT_containing_type,
847 for (
unsigned i = 1,
N = Args.
size();
i <
N; ++
i) {
850 assert(i == N-1 &&
"Unspecified parameter must be the last argument");
856 addFlag(Arg, dwarf::DW_AT_artificial);
863 auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();
865 if (
auto RTy =
resolve(Elements[0]))
868 bool isPrototyped =
true;
869 if (Elements.size() == 2 && !Elements[1])
870 isPrototyped =
false;
878 (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
879 Language == dwarf::DW_LANG_ObjC))
880 addFlag(Buffer, dwarf::DW_AT_prototyped);
883 if (CTy->
getCC() && CTy->
getCC() != dwarf::DW_CC_normal)
884 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
888 addFlag(Buffer, dwarf::DW_AT_reference);
891 addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
897 assert(!Identifier.
empty() &&
"external type ref without identifier");
898 addFlag(Buffer, dwarf::DW_AT_declaration);
906 uint16_t Tag = Buffer.
getTag();
909 case dwarf::DW_TAG_array_type:
910 constructArrayTypeDIE(Buffer, CTy);
912 case dwarf::DW_TAG_enumeration_type:
913 constructEnumTypeDIE(Buffer, CTy);
915 case dwarf::DW_TAG_structure_type:
916 case dwarf::DW_TAG_union_type:
917 case dwarf::DW_TAG_class_type: {
920 for (
const auto *Element : Elements) {
923 if (
auto *SP = dyn_cast<DISubprogram>(Element))
925 else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
926 if (DDTy->getTag() == dwarf::DW_TAG_friend) {
928 addType(ElemDie,
resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
929 }
else if (DDTy->isStaticMember()) {
932 constructMemberDIE(Buffer, DDTy);
934 }
else if (
auto *Property = dyn_cast<DIObjCProperty>(Element)) {
936 StringRef PropertyName = Property->getName();
937 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
938 if (Property->getType())
941 StringRef GetterName = Property->getGetterName();
942 if (!GetterName.
empty())
943 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
944 StringRef SetterName = Property->getSetterName();
945 if (!SetterName.
empty())
946 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
947 if (
unsigned PropertyAttributes = Property->getAttributes())
948 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute,
None,
954 addFlag(Buffer, dwarf::DW_AT_APPLE_block);
958 if (
auto *ContainingType =
964 addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
968 if (Tag == dwarf::DW_TAG_class_type ||
969 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
980 addString(Buffer, dwarf::DW_AT_name, Name);
982 if (Tag == dwarf::DW_TAG_enumeration_type ||
983 Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
984 Tag == dwarf::DW_TAG_union_type) {
988 addUInt(Buffer, dwarf::DW_AT_byte_size,
None, Size);
995 addFlag(Buffer, dwarf::DW_AT_declaration);
1004 addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
1009 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1014 void DwarfUnit::constructTemplateTypeParameterDIE(
1025 void DwarfUnit::constructTemplateValueParameterDIE(
1031 if (VP->
getTag() == dwarf::DW_TAG_template_value_parameter)
1036 if (
ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
1038 else if (
GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
1041 if (!GV->hasDLLImportStorageClass()) {
1048 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
1049 addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
1051 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_template_param) {
1052 assert(isa<MDString>(Val));
1053 addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
1054 cast<MDString>(Val)->getString());
1055 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
1074 Name =
"(anonymous namespace)";
1079 addFlag(NDie, dwarf::DW_AT_export_symbols);
1097 addString(MDie, dwarf::DW_AT_LLVM_config_macros,
1117 if (
auto *SPDecl = SP->getDeclaration()) {
1131 if (SP->isDefinition())
1140 DIE *DeclDie =
nullptr;
1142 if (
auto *SPDecl = SP->getDeclaration()) {
1143 DeclDie =
getDIE(SPDecl);
1144 assert(DeclDie &&
"This DIE should've already been constructed when the "
1145 "definition DIE was created in "
1146 "getOrCreateSubprogramDIE");
1149 DeclLinkageName = SPDecl->getLinkageName();
1153 if (DeclID != DefID)
1154 addUInt(SPDie, dwarf::DW_AT_decl_file,
None, DefID);
1156 if (SP->getLine() != SPDecl->getLine())
1157 addUInt(SPDie, dwarf::DW_AT_decl_line,
None, SP->getLine());
1165 assert(((LinkageName.empty() || DeclLinkageName.
empty()) ||
1166 LinkageName == DeclLinkageName) &&
1167 "decl has a linkage name and it is different");
1168 if (DeclLinkageName.
empty() &&
1178 addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
1201 if (SP->isPrototyped() &&
1202 (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
1203 Language == dwarf::DW_LANG_ObjC))
1204 addFlag(SPDie, dwarf::DW_AT_prototyped);
1209 Args = SPTy->getTypeArray();
1214 if (CC && CC != dwarf::DW_CC_normal)
1215 addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);
1220 if (
auto Ty =
resolve(Args[0]))
1223 unsigned VK = SP->getVirtuality();
1225 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
1226 if (SP->getVirtualIndex() != -1u) {
1228 addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1229 addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());
1230 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);
1233 std::make_pair(&SPDie,
resolve(SP->getContainingType())));
1236 if (!SP->isDefinition()) {
1237 addFlag(SPDie, dwarf::DW_AT_declaration);
1244 if (SP->isArtificial())
1245 addFlag(SPDie, dwarf::DW_AT_artificial);
1247 if (!SP->isLocalToUnit())
1248 addFlag(SPDie, dwarf::DW_AT_external);
1251 if (SP->isOptimized())
1252 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
1255 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag,
isa);
1258 if (SP->isLValueReference())
1259 addFlag(SPDie, dwarf::DW_AT_reference);
1261 if (SP->isRValueReference())
1262 addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
1264 if (SP->isNoReturn())
1265 addFlag(SPDie, dwarf::DW_AT_noreturn);
1267 if (SP->isProtected())
1268 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1270 else if (SP->isPrivate())
1271 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1273 else if (SP->isPublic())
1274 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1277 if (SP->isExplicit())
1278 addFlag(SPDie, dwarf::DW_AT_explicit);
1280 if (SP->isMainSubprogram())
1281 addFlag(SPDie, dwarf::DW_AT_main_subprogram);
1284 void DwarfUnit::constructSubrangeDIE(
DIE &Buffer,
const DISubrange *SR,
1287 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
1294 int64_t DefaultLowerBound = getDefaultLowerBound();
1297 if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
1298 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound,
None, LowerBound);
1303 addUInt(DW_Subrange, dwarf::DW_AT_count,
None, Count);
1306 DIE *DwarfUnit::getIndexTyDie() {
1314 dwarf::DW_ATE_unsigned);
1320 addFlag(Buffer, dwarf::DW_AT_GNU_vector);
1328 DIE *IdxTy = getIndexTyDie();
1332 for (
unsigned i = 0,
N = Elements.size();
i <
N; ++
i) {
1334 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
i]))
1335 if (Element->getTag() == dwarf::DW_TAG_subrange_type)
1336 constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
1344 for (
unsigned i = 0, N = Elements.size(); i <
N; ++
i) {
1345 auto *
Enum = dyn_cast_or_null<DIEnumerator>(Elements[
i]);
1349 addString(Enumerator, dwarf::DW_AT_name, Name);
1351 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
1358 addFlag(Buffer, dwarf::DW_AT_enum_class);
1365 DIE &SPDie = *CI->first;
1372 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
1380 addString(MemberDie, dwarf::DW_AT_name, Name);
1393 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1394 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1395 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1397 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1398 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1399 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1401 addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
1406 uint64_t OffsetInBytes;
1408 bool IsBitfield = FieldSize && Size != FieldSize;
1412 addUInt(MemberDie, dwarf::DW_AT_byte_size,
None, FieldSize/8);
1413 addUInt(MemberDie, dwarf::DW_AT_bit_size,
None, Size);
1420 uint32_t AlignMask = ~(AlignInBits - 1);
1422 uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1424 OffsetInBytes = (Offset - StartBitOffset) / 8;
1427 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1428 uint64_t FieldOffset = (HiMark - FieldSize);
1429 Offset -= FieldOffset;
1433 Offset = FieldSize - (Offset + Size);
1435 addUInt(MemberDie, dwarf::DW_AT_bit_offset,
None, Offset);
1436 OffsetInBytes = FieldOffset >> 3;
1438 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset,
None, Offset);
1444 addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1450 addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1451 addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1452 addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1454 addUInt(MemberDie, dwarf::DW_AT_data_member_location,
None,
1459 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1462 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1466 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1469 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
1470 dwarf::DW_VIRTUALITY_virtual);
1473 if (
DINode *PNode = DT->getObjCProperty())
1476 dwarf::DW_FORM_ref4,
DIEEntry(*PDie));
1479 addFlag(MemberDie, dwarf::DW_AT_artificial);
1490 "Static member should belong to a type.");
1493 return StaticMemberDIE;
1502 addFlag(StaticMemberDIE, dwarf::DW_AT_external);
1503 addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
1508 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1511 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1514 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1517 if (
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
1519 if (
const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
1523 addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1526 return &StaticMemberDIE;
1555 Asm->
OutStreamer->EmitIntValue(TypeSignature,
sizeof(TypeSignature));
1559 sizeof(Ty->getOffset()));
1562 bool DwarfTypeUnit::isDwoUnit()
const {
StringRef getName() const
void push_back(const T &Elt)
static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty)
Return true if type encoding is unsigned.
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
StringRef getName() const
StringRef getIdentifier() const
bool isArtificial() 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.
MCSymbol * getSymbol(const GlobalValue *GV) const
std::vector< DIELoc * > DIELocs
A list of all the DIELocs in use.
DIELoc - Represents an expression location.
bool useAppleExtensionAttributes() const
DITypeRef getType() const
DIE * getOrCreateStaticMemberDIE(const DIDerivedType *DT)
Create new static data member DIE.
const ConstantFP * getFPImm() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const DataLayout & getDataLayout() const
Return information about data layout.
void EmitInt8(int Value) const
Emit a byte directive and value.
static bool isShareableAcrossCUs(const DINode *D)
Check whether the DIE for this MDNode can be shared across CUs.
DILocalScope * getScope() const
Get the local scope for this variable.
bool isRValueReference() const
virtual void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context)
Add a new global type to the compile unit.
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.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
Collects and handles dwarf debug information.
void AddExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable=nullptr)
const MachineFunction * MF
The current machine function.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
StringRef getDirectory() const
bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg, int Offset=0)
Emit an indirect dwarf register operation for the given machine register.
void EmitSigned(int64_t Value) override
Emit a raw signed value.
dwarf::Form BestForm(unsigned DwarfVersion) const
BestForm - Choose the best form for data.
StringRef getName() const
DITypeRef getBaseType() const
void EmitInt32(int Value) const
Emit a long directive and value.
StringRef getName() const
DwarfUnit(dwarf::Tag, const DICompileUnit *CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
void addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute=dwarf::DW_AT_type)
Add a new type attribute to the specified entity.
bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) override
Return whether the given machine register is the frame register in the current function.
virtual DwarfCompileUnit & getCU()=0
AsmPrinter * Asm
Target of Dwarf emission.
Tagged DWARF-like metadata node.
DIE * getOrCreateTypeDIE(const MDNode *N)
Find existing DIE or create new DIE for the given type.
void addAccelNamespace(StringRef Name, const DIE &Die)
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)
bool useDWARF2Bitfields() const
Returns whether to use the DWARF2 format for bitfields instyead of the DWARF4 format.
virtual void addGlobalName(StringRef Name, DIE &Die, const DIScope *Context)
Add a new global name to the compile unit.
void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Block)
Add block data.
virtual void emitHeader(bool UseOffsets)
Emit the header for this unit, not including the initial length field.
DIScope * getScope() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
struct fuzzer::@269 Flags
const APInt & getValue() const
Return the constant as an APInt value reference.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
virtual unsigned getOrCreateSourceID(StringRef File, StringRef Directory)=0
Look up the source ID with the given directory and source file names.
T * resolve(TypedDINodeRef< T > Ref) const
Look in the DwarfDebug map for the MDNode that corresponds to the reference.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
DINodeArray getElements() const
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
void addConstantFPValue(DIE &Die, const MachineOperand &MO)
Add constant value entry in variable DIE.
uint32_t getAlignInBytes() const
APInt bitcastToAPInt() const
void EmitOp(uint8_t Op, const char *Comment=nullptr) override
Output a dwarf operand and an optional assembler comment.
StringRef getFilename() const
bool isAppleBlockExtension() 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.
bool getExportSymbols() const
This file implements a class to represent arbitrary precision integral constant values and operations...
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.
AddressPool & getAddressPool()
bool isExternalTypeRef() const
DenseMap< const MDNode *, DIE * > & getAbstractSPDies()
This class is used to track local variable information.
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
void EmitInt16(int Value) const
Emit a short directive and value.
DwarfCompileUnit & getCU() override
bool isLittleEndian() const
Layout endianness...
DIScopeRef getScope() const
virtual unsigned getHeaderSize() const
Compute the size of a header for this unit, not including the initial length field.
StringRef getConfigurationMacros() const
DIE * getOrCreateNameSpace(const DINamespace *NS)
DIE & addChild(DIE *Child)
Add a child to the DIE.
dwarf::Tag getTag() const
DIScopeRef getScope() const
StringRef getDirectory() const
void addConstantValue(DIE &Die, const MachineOperand &MO, const DIType *Ty)
Add constant value entry in variable DIE.
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
unsigned getRuntimeLang() const
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support...
StringRef getIncludePath() 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.
initializer< Ty > init(const Ty &Val)
unsigned getFile(StringRef Directory, StringRef FileName)
const DIType * getType() const
bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie)
StringRef getName() const
void EmitUnsigned(uint64_t Value) override
Emit a raw unsigned value.
void addSourceLine(DIE &Die, unsigned Line, StringRef File, StringRef Directory)
Add location information to specified debug information entry.
int64_t getSExtValue() const
Get sign extended value.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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.
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...
DIScope * getScope() const
T * resolve(TypedDINodeRef< T > Ref) const
Find the MDNode for the given reference.
unsigned getBitWidth() const
Return the number of bits in the APInt.
void addAccelType(StringRef Name, const DIE &Die, char Flags)
DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal=false)
Metadata * getValue() const
unsigned getEncoding() const
uint64_t getOffsetInBits() const
bool isLValueReference() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A container for string pool string values.
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.
DIE * getDIE(const DINode *D) const
Returns the DIE map slot for the specified debug variable.
Base class for scope-like contexts.
A simple label difference DIE.
void insertDIE(const MDNode *TypeMD, DIE *Die)
StringRef getDirectory() const
StringRef getFilename() const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef getISysRoot() const
unsigned getOrCreateSourceID(StringRef FileName, StringRef DirName) override
Look up the source ID with the given directory and source file names.
This is the shared class of boolean and integer constants.
const DIEUnit * getUnit() const
Climb up the parent chain to get the compile unit or type unit that this DIE belongs to...
uint16_t getLanguage() 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()
LLVM_NODISCARD bool isa(const Y &Val)
void addTemplateParams(DIE &Buffer, DINodeArray TParams)
Add template parameters in buffer.
StringRef getFilename() const
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
Class for arbitrary precision integers.
A (clang) module that has been imported by the compile unit.
bool isForwardDecl() const
std::string getParentContextString(const DIScope *Context) const
Get string containing language specific context for a global name.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)
Add a DIE attribute data and value.
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
Type array for a subprogram.
bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
dwarf::Form BestForm() const
BestForm - Choose the best form for data.
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
DITemplateParameterArray getTemplateParams() const
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
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...
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
DIE * getDIE(const MDNode *TypeMD)
void emitHeader(bool UseOffsets) override
Emit the header for this unit, not including the initial length field.
DIE * getOrCreateModule(const DIModule *M)
uint64_t getSizeInBits() const
void addBlockByrefAddress(const DbgVariable &DV, 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 * createTypeDIE(const DICompositeType *Ty)
Get context owner's DIE.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
virtual unsigned getISAEncoding()
Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
DITypeRef getVTableHolder() const
void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer)
Add an offset into a section attribute data and value.
DwarfExpression implementation for singular DW_AT_location.
void addDIETypeSignature(DIE &Die, uint64_t Signature)
Add a type's DW_AT_signature and set the declaration flag.
bool isObjcClassComplete() const
const APFloat & getValueAPF() const
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
reverse_iterator rbegin()
BumpPtrAllocator DIEValueAllocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned ComputeSize(const AsmPrinter *AP) const
ComputeSize - Calculate the size of the location expression.
std::string DirName(const std::string &FileName)
LLVM Value Representation.
std::vector< DIEBlock * > DIEBlocks
A list of all the DIEBlocks in use.
unsigned ComputeSize(const AsmPrinter *AP) const
ComputeSize - Calculate the size of the location expression.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
static uint64_t getBaseTypeSize(const DITypeRef TyRef)
If this type is derived from a base type then return base type size.
void addOpAddress(DIELoc &Die, const MCSymbol *Label)
Add a dwarf op address data and value using the form given and an op of either DW_FORM_addr or DW_FOR...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
int64_t getLowerBound() const
DIEBlock - Represents a block of values.
MCSection * getDwarfAbbrevSection() const
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size FIXME: The defaults need to be removed once all of the backends/clients are updat...
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, bool Minimal=false)
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI)
void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args)
Construct function argument DIEs.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
Basic type, like 'int' or 'float'.
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.