46 #define DEBUG_TYPE "dwarfdebug" 52 void DIEDwarfExpression::emitOp(uint8_t
Op,
const char* Comment) {
53 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1,
Op);
56 void DIEDwarfExpression::emitSigned(int64_t
Value) {
57 CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata,
Value);
60 void DIEDwarfExpression::emitUnsigned(uint64_t
Value) {
61 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata,
Value);
64 void DIEDwarfExpression::emitData1(uint8_t
Value) {
65 CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1,
Value);
68 void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
69 CU.addBaseTypeRef(getActiveDIE(), Idx);
72 void DIEDwarfExpression::enableTemporaryBuffer() {
73 assert(!IsBuffering &&
"Already buffering?");
77 void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
79 unsigned DIEDwarfExpression::getTemporaryBufferSize() {
83 void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.
takeValues(TmpDIE); }
87 return MachineReg ==
TRI.getFrameRegister(*AP.
MF);
92 :
DIEUnit(UnitTag), CUNode(Node),
Asm(A), DD(DW), DU(DWU),
93 IndexTyDie(nullptr) {}
98 :
DwarfUnit(dwarf::DW_TAG_type_unit,
CU.getCUNode(), A, DW, DWU),
CU(
CU),
99 SplitLineTable(SplitLineTable) {
103 for (
unsigned j = 0, M =
DIEBlocks.size(); j < M; ++j)
105 for (
unsigned j = 0, M =
DIELocs.size(); j < M; ++j)
109 int64_t DwarfUnit::getDefaultLowerBound()
const {
115 case dwarf::DW_LANG_C:
116 case dwarf::DW_LANG_C89:
117 case dwarf::DW_LANG_C_plus_plus:
120 case dwarf::DW_LANG_Fortran77:
121 case dwarf::DW_LANG_Fortran90:
125 case dwarf::DW_LANG_C99:
126 case dwarf::DW_LANG_ObjC:
127 case dwarf::DW_LANG_ObjC_plus_plus:
132 case dwarf::DW_LANG_Fortran95:
138 case dwarf::DW_LANG_D:
139 case dwarf::DW_LANG_Java:
140 case dwarf::DW_LANG_Python:
141 case dwarf::DW_LANG_UPC:
146 case dwarf::DW_LANG_Ada83:
147 case dwarf::DW_LANG_Ada95:
148 case dwarf::DW_LANG_Cobol74:
149 case dwarf::DW_LANG_Cobol85:
150 case dwarf::DW_LANG_Modula2:
151 case dwarf::DW_LANG_Pascal83:
152 case dwarf::DW_LANG_PLI:
158 case dwarf::DW_LANG_BLISS:
159 case dwarf::DW_LANG_C11:
160 case dwarf::DW_LANG_C_plus_plus_03:
161 case dwarf::DW_LANG_C_plus_plus_11:
162 case dwarf::DW_LANG_C_plus_plus_14:
163 case dwarf::DW_LANG_Dylan:
164 case dwarf::DW_LANG_Go:
165 case dwarf::DW_LANG_Haskell:
166 case dwarf::DW_LANG_OCaml:
167 case dwarf::DW_LANG_OpenCL:
168 case dwarf::DW_LANG_RenderScript:
169 case dwarf::DW_LANG_Rust:
170 case dwarf::DW_LANG_Swift:
175 case dwarf::DW_LANG_Fortran03:
176 case dwarf::DW_LANG_Fortran08:
177 case dwarf::DW_LANG_Julia:
178 case dwarf::DW_LANG_Modula3:
233 assert(
Form != dwarf::DW_FORM_implicit_const &&
234 "DW_FORM_implicit_const is used only for signed integers");
267 isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;
269 auto StringPoolEntry =
276 IxForm = dwarf::DW_FORM_strx1;
277 unsigned Index = StringPoolEntry.getIndex();
278 if (
Index > 0xffffff)
279 IxForm = dwarf::DW_FORM_strx4;
280 else if (
Index > 0xffff)
281 IxForm = dwarf::DW_FORM_strx3;
282 else if (
Index > 0xff)
283 IxForm = dwarf::DW_FORM_strx2;
305 unsigned DwarfTypeUnit::getOrCreateSourceID(
const DIFile *
File) {
308 if (!UsedLineTable) {
309 UsedLineTable =
true;
313 return SplitLineTable->
getFile(
320 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);
326 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
327 addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
332 addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
333 addLabel(Die, dwarf::DW_FORM_addr, Sym);
351 addFlag(Die, dwarf::DW_AT_declaration);
354 dwarf::DW_FORM_ref_sig8,
DIEInteger(Signature));
360 const DIEUnit *EntryCU = Entry.getEntry().getUnit();
367 EntryCU ==
CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
397 addUInt(Die, dwarf::DW_AT_decl_file,
None, FileID);
454 addUInt(Die, dwarf::DW_AT_const_value,
455 Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
464 if (CIBitWidth <= 64) {
479 for (
int i = 0; i < NumBytes; i++) {
482 c = Ptr64[i / 8] >> (8 * (i & 7));
484 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
495 : dwarf::DW_AT_MIPS_linkage_name,
501 for (
const auto *Element : TParams) {
502 if (
auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))
503 constructTemplateTypeParameterDIE(Buffer, TTP);
504 else if (
auto *TVP = dyn_cast<DITemplateValueParameter>(Element))
505 constructTemplateValueParameterDIE(Buffer, TVP);
511 for (
const auto *Ty : ThrownTypes) {
520 if (
auto *
T = dyn_cast<DIType>(
Context))
522 if (
auto *NS = dyn_cast<DINamespace>(
Context))
524 if (
auto *SP = dyn_cast<DISubprogram>(
Context))
526 if (
auto *M = dyn_cast<DIModule>(
Context))
543 updateAcceleratorTables(
Context, Ty, TyDIE);
552 updateAcceleratorTables(
Context, Ty, TyDIE);
554 if (
auto *
BT = dyn_cast<DIBasicType>(Ty))
556 else if (
auto *
ST = dyn_cast<DIStringType>(Ty))
558 else if (
auto *STy = dyn_cast<DISubroutineType>(Ty))
560 else if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
562 (Ty->
getRawName() || CTy->getRawIdentifier())) {
564 if (
MDString *TypeId = CTy->getRawIdentifier())
568 finishNonUnitTypeDIE(TyDIE, CTy);
584 auto *Ty = cast<DIType>(TyNode);
596 auto *
Context = Ty->getScope();
603 return static_cast<DwarfUnit *>(ContextDIE->
getUnit())
610 bool IsImplementation =
false;
611 if (
auto *CT = dyn_cast<DICompositeType>(Ty)) {
614 IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
627 assert(Ty &&
"Trying to add a type that doesn't exist?");
641 while (!isa<DICompileUnit>(
Context)) {
655 if (
Name.empty() && isa<DINamespace>(Ctx))
656 Name =
"(anonymous namespace)";
673 if (BTy->
getTag() == dwarf::DW_TAG_unspecified_type)
676 if (BTy->
getTag() != dwarf::DW_TAG_string_type)
677 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
684 addUInt(Buffer, dwarf::DW_AT_endianity,
None, dwarf::DW_END_big);
686 addUInt(Buffer, dwarf::DW_AT_endianity,
None, dwarf::DW_END_little);
697 if (
auto *VarDIE =
getDIE(Var))
698 addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);
705 DwarfExpr.setMemoryLocationKind();
706 DwarfExpr.addExpression(Expr);
707 addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());
715 addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
727 const DIType *FromTy = DTy->getBaseType();
739 if (AlignInBytes > 0)
740 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
745 if (
Size &&
Tag != dwarf::DW_TAG_pointer_type
746 &&
Tag != dwarf::DW_TAG_ptr_to_member_type
747 &&
Tag != dwarf::DW_TAG_reference_type
748 &&
Tag != dwarf::DW_TAG_rvalue_reference_type)
751 if (
Tag == dwarf::DW_TAG_ptr_to_member_type)
761 if (DTy->getDWARFAddressSpace())
762 addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,
763 DTy->getDWARFAddressSpace().getValue());
767 for (
unsigned i = 1,
N =
Args.size(); i <
N; ++i) {
770 assert(i ==
N-1 &&
"Unspecified parameter must be the last argument");
783 auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();
785 if (
auto RTy = Elements[0])
788 bool isPrototyped =
true;
789 if (Elements.size() == 2 && !Elements[1])
790 isPrototyped =
false;
800 addFlag(Buffer, dwarf::DW_AT_prototyped);
803 if (CTy->
getCC() && CTy->
getCC() != dwarf::DW_CC_normal)
804 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
808 addFlag(Buffer, dwarf::DW_AT_reference);
811 addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
822 case dwarf::DW_TAG_array_type:
823 constructArrayTypeDIE(Buffer, CTy);
825 case dwarf::DW_TAG_enumeration_type:
826 constructEnumTypeDIE(Buffer, CTy);
828 case dwarf::DW_TAG_variant_part:
829 case dwarf::DW_TAG_structure_type:
830 case dwarf::DW_TAG_union_type:
831 case dwarf::DW_TAG_class_type: {
834 if (
Tag == dwarf::DW_TAG_variant_part) {
841 DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
842 addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
847 if (
Tag == dwarf::DW_TAG_class_type ||
848 Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type)
853 for (
const auto *Element : Elements) {
856 if (
auto *SP = dyn_cast<DISubprogram>(Element))
858 else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
859 if (DDTy->getTag() == dwarf::DW_TAG_friend) {
861 addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend);
862 }
else if (DDTy->isStaticMember()) {
864 }
else if (
Tag == dwarf::DW_TAG_variant_part) {
869 dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
871 addUInt(Variant, dwarf::DW_AT_discr_value,
None, CI->getZExtValue());
873 addSInt(Variant, dwarf::DW_AT_discr_value,
None, CI->getSExtValue());
875 constructMemberDIE(Variant, DDTy);
877 constructMemberDIE(Buffer, DDTy);
879 }
else if (
auto *Property = dyn_cast<DIObjCProperty>(Element)) {
881 StringRef PropertyName = Property->getName();
882 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
883 if (Property->getType())
884 addType(ElemDie, Property->getType());
886 StringRef GetterName = Property->getGetterName();
887 if (!GetterName.
empty())
888 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
889 StringRef SetterName = Property->getSetterName();
890 if (!SetterName.
empty())
891 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
892 if (
unsigned PropertyAttributes = Property->getAttributes())
893 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute,
None,
895 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
896 if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
904 addFlag(Buffer, dwarf::DW_AT_APPLE_block);
907 addFlag(Buffer, dwarf::DW_AT_export_symbols);
918 addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
923 CC = dwarf::DW_CC_pass_by_value;
925 CC = dwarf::DW_CC_pass_by_reference;
927 addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
939 if (
Tag == dwarf::DW_TAG_enumeration_type ||
940 Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type ||
941 Tag == dwarf::DW_TAG_union_type) {
954 addFlag(Buffer, dwarf::DW_AT_declaration);
963 addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
968 addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
973 void DwarfUnit::constructTemplateTypeParameterDIE(
983 addFlag(ParamDIE, dwarf::DW_AT_default_value);
986 void DwarfUnit::constructTemplateValueParameterDIE(
992 if (VP->
getTag() == dwarf::DW_TAG_template_value_parameter)
997 addFlag(ParamDIE, dwarf::DW_AT_default_value);
999 if (
ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
1001 else if (
GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
1004 if (!GV->hasDLLImportStorageClass()) {
1011 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
1012 addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
1014 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_template_param) {
1015 assert(isa<MDString>(Val));
1016 addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
1017 cast<MDString>(Val)->getString());
1018 }
else if (VP->
getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
1037 Name =
"(anonymous namespace)";
1041 addFlag(NDie, dwarf::DW_AT_export_symbols);
1054 if (!M->getName().empty()) {
1055 addString(MDie, dwarf::DW_AT_name, M->getName());
1058 if (!M->getConfigurationMacros().empty())
1059 addString(MDie, dwarf::DW_AT_LLVM_config_macros,
1060 M->getConfigurationMacros());
1061 if (!M->getIncludePath().empty())
1062 addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());
1063 if (!M->getAPINotesFile().empty())
1064 addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile());
1069 addUInt(MDie, dwarf::DW_AT_decl_line,
None, M->getLineNo());
1071 addFlag(MDie, dwarf::DW_AT_declaration);
1086 if (
auto *SPDecl = SP->getDeclaration()) {
1100 if (SP->isDefinition())
1103 static_cast<DwarfUnit *>(SPDie.
getUnit())
1110 DIE *DeclDie =
nullptr;
1112 if (
auto *SPDecl = SP->getDeclaration()) {
1114 DeclArgs = SPDecl->getType()->getTypeArray();
1115 DefinitionArgs = SP->getType()->getTypeArray();
1117 if (DeclArgs.
size() && DefinitionArgs.
size())
1118 if (DefinitionArgs[0] != NULL && DeclArgs[0] != DefinitionArgs[0])
1119 addType(SPDie, DefinitionArgs[0]);
1121 DeclDie =
getDIE(SPDecl);
1122 assert(DeclDie &&
"This DIE should've already been constructed when the " 1123 "definition DIE was created in " 1124 "getOrCreateSubprogramDIE");
1127 DeclLinkageName = SPDecl->getLinkageName();
1130 if (DeclID != DefID)
1131 addUInt(SPDie, dwarf::DW_AT_decl_file,
None, DefID);
1133 if (SP->getLine() != SPDecl->getLine())
1134 addUInt(SPDie, dwarf::DW_AT_decl_line,
None, SP->getLine());
1144 "decl has a linkage name and it is different");
1145 if (DeclLinkageName.
empty() &&
1155 addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
1160 bool SkipSPAttributes) {
1163 bool SkipSPSourceLocation = SkipSPAttributes &&
1165 if (!SkipSPSourceLocation)
1173 if (!SkipSPSourceLocation)
1177 if (SkipSPAttributes)
1183 if (SP->isPrototyped() &&
1186 addFlag(SPDie, dwarf::DW_AT_prototyped);
1188 if (SP->isObjCDirect())
1189 addFlag(SPDie, dwarf::DW_AT_APPLE_objc_direct);
1194 Args = SPTy->getTypeArray();
1199 if (CC && CC != dwarf::DW_CC_normal)
1200 addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);
1205 if (
auto Ty =
Args[0])
1208 unsigned VK = SP->getVirtuality();
1210 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
1211 if (SP->getVirtualIndex() != -1u) {
1213 addUInt(*
Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1214 addUInt(*
Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());
1220 if (!SP->isDefinition()) {
1221 addFlag(SPDie, dwarf::DW_AT_declaration);
1230 if (SP->isArtificial())
1231 addFlag(SPDie, dwarf::DW_AT_artificial);
1233 if (!SP->isLocalToUnit())
1234 addFlag(SPDie, dwarf::DW_AT_external);
1237 if (SP->isOptimized())
1238 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
1241 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag,
isa);
1244 if (SP->isLValueReference())
1245 addFlag(SPDie, dwarf::DW_AT_reference);
1247 if (SP->isRValueReference())
1248 addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
1250 if (SP->isNoReturn())
1251 addFlag(SPDie, dwarf::DW_AT_noreturn);
1253 if (SP->isProtected())
1254 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1256 else if (SP->isPrivate())
1257 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1259 else if (SP->isPublic())
1260 addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1263 if (SP->isExplicit())
1264 addFlag(SPDie, dwarf::DW_AT_explicit);
1266 if (SP->isMainSubprogram())
1267 addFlag(SPDie, dwarf::DW_AT_main_subprogram);
1269 addFlag(SPDie, dwarf::DW_AT_pure);
1270 if (SP->isElemental())
1271 addFlag(SPDie, dwarf::DW_AT_elemental);
1272 if (SP->isRecursive())
1273 addFlag(SPDie, dwarf::DW_AT_recursive);
1276 addFlag(SPDie, dwarf::DW_AT_deleted);
1279 void DwarfUnit::constructSubrangeDIE(
DIE &Buffer,
const DISubrange *SR,
1282 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
1288 int64_t DefaultLowerBound = getDefaultLowerBound();
1291 Count = CI->getSExtValue();
1295 if (
auto *BV = Bound.dyn_cast<
DIVariable *>()) {
1296 if (
auto *VarDIE =
getDIE(BV))
1298 }
else if (
auto *BE = Bound.dyn_cast<
DIExpression *>()) {
1301 DwarfExpr.setMemoryLocationKind();
1302 DwarfExpr.addExpression(BE);
1303 addBlock(DW_Subrange, Attr, DwarfExpr.finalize());
1304 }
else if (
auto *BI = Bound.dyn_cast<
ConstantInt *>()) {
1305 if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
1306 BI->getSExtValue() != DefaultLowerBound)
1307 addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue());
1311 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->
getLowerBound());
1314 if (
auto *CountVarDIE =
getDIE(CV))
1315 addDIEEntry(DW_Subrange, dwarf::DW_AT_count, *CountVarDIE);
1316 }
else if (Count != -1)
1317 addUInt(DW_Subrange, dwarf::DW_AT_count,
None, Count);
1319 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->
getUpperBound());
1321 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->
getStride());
1324 void DwarfUnit::constructGenericSubrangeDIE(
DIE &Buffer,
1327 DIE &DwGenericSubrange =
1329 addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);
1331 int64_t DefaultLowerBound = getDefaultLowerBound();
1335 if (
auto *BV = Bound.dyn_cast<
DIVariable *>()) {
1336 if (
auto *VarDIE =
getDIE(BV))
1338 }
else if (
auto *BE = Bound.dyn_cast<
DIExpression *>()) {
1339 if (BE->isSignedConstant()) {
1340 if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
1341 static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound)
1342 addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,
1347 DwarfExpr.setMemoryLocationKind();
1348 DwarfExpr.addExpression(BE);
1349 addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());
1354 AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->
getLowerBound());
1355 AddBoundTypeEntry(dwarf::DW_AT_count, GSR->
getCount());
1356 AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->
getUpperBound());
1357 AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->
getStride());
1360 DIE *DwarfUnit::getIndexTyDie() {
1369 dwarf::DW_ATE_unsigned);
1378 assert(CTy && CTy->
isVector() &&
"Composite type is not a vector");
1383 assert(BaseTy &&
"Unknown vector element type.");
1388 assert(Elements.size() == 1 &&
1389 Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&
1390 "Invalid vector element array, expected one element of type subrange");
1391 const auto Subrange = cast<DISubrange>(Elements[0]);
1392 const auto NumVecElements =
1393 Subrange->getCount()
1394 ? Subrange->getCount().get<
ConstantInt *>()->getSExtValue()
1399 assert(ActualSize >= (NumVecElements * ElementSize) &&
"Invalid vector size");
1400 return ActualSize != (NumVecElements * ElementSize);
1405 addFlag(Buffer, dwarf::DW_AT_GNU_vector);
1412 if (
auto *VarDIE =
getDIE(Var))
1413 addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);
1417 DwarfExpr.setMemoryLocationKind();
1418 DwarfExpr.addExpression(Expr);
1419 addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
1423 if (
auto *VarDIE =
getDIE(Var))
1424 addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);
1428 DwarfExpr.setMemoryLocationKind();
1429 DwarfExpr.addExpression(Expr);
1430 addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());
1434 if (
auto *VarDIE =
getDIE(Var))
1435 addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);
1439 DwarfExpr.setMemoryLocationKind();
1440 DwarfExpr.addExpression(Expr);
1441 addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
1445 addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,
1446 RankConst->getSExtValue());
1447 }
else if (
auto *RankExpr = CTy->
getRankExp()) {
1450 DwarfExpr.setMemoryLocationKind();
1451 DwarfExpr.addExpression(RankExpr);
1452 addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
1461 DIE *IdxTy = getIndexTyDie();
1465 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
1467 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[i])) {
1468 if (Element->getTag() == dwarf::DW_TAG_subrange_type)
1469 constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
1470 else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)
1471 constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element),
1484 addFlag(Buffer, dwarf::DW_AT_enum_class);
1493 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
1494 auto *
Enum = dyn_cast_or_null<DIEnumerator>(Elements[i]);
1500 if (IndexEnumerators)
1509 DIE &SPDie = *CI->first;
1516 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
1526 if (
DIType *Resolved = DT->getBaseType())
1538 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1539 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1540 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1542 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1543 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1544 addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1546 addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
1551 uint64_t OffsetInBytes;
1553 bool IsBitfield = FieldSize &&
Size != FieldSize;
1557 addUInt(MemberDie, dwarf::DW_AT_byte_size,
None, FieldSize/8);
1565 uint32_t AlignMask = ~(AlignInBits - 1);
1567 uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1569 OffsetInBytes = (Offset - StartBitOffset) / 8;
1572 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1573 uint64_t FieldOffset = (HiMark - FieldSize);
1574 Offset -= FieldOffset;
1578 Offset = FieldSize - (Offset +
Size);
1580 addUInt(MemberDie, dwarf::DW_AT_bit_offset,
None, Offset);
1581 OffsetInBytes = FieldOffset >> 3;
1583 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset,
None, Offset);
1589 addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1595 addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1596 addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1597 addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1599 addUInt(MemberDie, dwarf::DW_AT_data_member_location,
None,
1604 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1607 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1611 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1614 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
1615 dwarf::DW_VIRTUALITY_virtual);
1618 if (
DINode *PNode = DT->getObjCProperty())
1621 dwarf::DW_FORM_ref4,
DIEEntry(*PDie));
1624 addFlag(MemberDie, dwarf::DW_AT_artificial);
1637 "Static member should belong to a type.");
1640 return StaticMemberDIE;
1644 const DIType *Ty = DT->getBaseType();
1649 addFlag(StaticMemberDIE, dwarf::DW_AT_external);
1650 addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
1655 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1658 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1661 addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
1664 if (
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
1666 if (
const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
1670 addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1673 return &StaticMemberDIE;
1720 : dwarf::DW_UT_type);
1722 Asm->
OutStreamer->emitIntValue(TypeSignature,
sizeof(TypeSignature));
1744 bool DwarfTypeUnit::isDwoUnit()
const {
1760 const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress()
const {
1777 "DW_AT_rnglists_base requires DWARF version 5 or later");
1781 TLOF.getDwarfRnglistsSection()->getBeginSymbol());
1785 addFlag(
D, dwarf::DW_AT_declaration);
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
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
uint64_t getOffsetInBits() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
bool isTypePassByValue() const
uint64_t getZExtValue() const
Get zero extended value.
static bool isUnsignedDIType(const DIType *Ty)
Return true if type encoding is unsigned.
virtual unsigned getHeaderSize() const
Compute the size of a header for this unit, not including the initial length field.
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.
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 ...
NonTypeUnitContext enterNonTypeUnitContext()
MCContext & OutContext
This is the context for the output file that we are streaming.
DIVariable * getAllocated() const
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.
Collects and handles dwarf debug information.
DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable=nullptr)
ConstantInt * getRankConst() const
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
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.
bool useSegmentedStringOffsetsTable() const
uint16_t getDwarfVersion() const
DIVariable * getAssociated() const
bool isForwardDecl() const
bool getDebugInfoForProfiling() const
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.
virtual DwarfCompileUnit & getCU()=0
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.
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.
DIVariable * getDataLocation() const
DIE * getDIE(const DINode *D) const
Returns the DIE map slot for the specified debug variable.
MCSymbol * getRnglistsTableBaseSym() const
bool isLValueReference() const
bool isDebugDirectivesOnly() const
bool isShareableAcrossCUs(const DINode *D) const
Check whether the DIE for this MDNode can be shared across CUs.
BoundType getUpperBound() const
void addConstantFPValue(DIE &Die, const ConstantFP *CFP)
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.
DIExpression * getDataLocationExp() const
void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty)
Add constant value entry in variable DIE.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
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.
unsigned getEncoding() const
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.
DIType * getBaseType() 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()
MDString * getRawName() const
bool doesDwarfUseRelocationsAcrossSections() const
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.
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
MCSymbol * getStringOffsetsStartSym() const
DIScope * getScope() const
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
void takeValues(DIEValueList &Other)
Take ownership of the nodes in Other, and append them to the back of the list.
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.
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.
bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie)
DIExpression * getAssociatedExp() const
const MCAsmInfo * MAI
Target Asm Printer information.
CountType getCount() const
Instrumentation for Order File
String type, Fortran CHARACTER(n)
BoundType getStride() 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].
DIEUnit * getUnit() const
Climb up the parent chain to get the compile unit or type unit that this DIE belongs to.
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.
virtual unsigned getOrCreateSourceID(const DIFile *File)=0
Look up the source ID for the given file.
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)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, char Flags)
Base class for variables.
static uint64_t getBaseTypeSize(const DIType *Ty)
If this type is derived from a base type then return base type size.
bool isObjcClassComplete() const
DIExpression * getStringLengthExp() const
BoundType getLowerBound() const
DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE)
DIScope * getScope() 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...
DIVariable * getStringLength() const
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.
BoundType getUpperBound() const
void insertDIE(const MDNode *TypeMD, DIE *Die)
const APFloat & getValueAPF() const
uint16_t getLanguage() const
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit 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.
DIExpression * getAllocatedExp() const
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
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.
DIScope * getScope() const
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
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',...
dwarf::Form BestForm(unsigned DwarfVersion) const
BestForm - Choose the best form for data.
DIType * getVTableHolder() const
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
BoundType getStride() const
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)
Add a DIE attribute data and value.
dwarf::Tag getTag() const
virtual void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context)=0
Add a new global type to the compile unit.
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.
virtual void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context)=0
Add a new global name to the compile unit.
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.
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
DIExpression * getRankExp() const
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.
DIE * getOrCreateModule(const DIModule *M)
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.
unsigned getFile(StringRef Directory, StringRef FileName, Optional< MD5::MD5Result > Checksum, uint16_t DwarfVersion, Optional< StringRef > Source)
bool getExportSymbols() 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.
BoundType getLowerBound() const
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
reverse_iterator rbegin()
BumpPtrAllocator DIEValueAllocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BoundType getCount() const
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
void emitInt8(int Value) const
Emit a byte directive and value.
LLVM Value Representation.
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.
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.
StringRef - Represent a constant reference to a string, i.e.
APInt bitcastToAPInt() const
DIEBlock - Represents a block of values.
bool isCPlusPlus(SourceLanguage S)
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
Optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
bool isTypePassByReference() const
Wrapper class representing virtual and physical registers.
void emitInt16(int Value) const
Emit a short directive and value.
bool useInlineStrings() const
Returns whether to use inline strings.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
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.