Skip to content

Commit c56fd93

Browse files
committed
[DebugInfo] Add an specification_of attribute to LLVM DebugInfo
Add a specification_of attribute to LLVM DebugInfo, which is analogous to DWARF's DW_AT_specification. According to the DWARF spec: "A debugging information entry that represents a declaration that completes another (earlier) non-defining declaration may have a DW_AT_specification attribute whose value is a reference to the debugging information entry representing the non-defining declaration." This patch allows types to be specifications of other types. For example, a templated type where the template parameters are substituted in could be a specification of the non-substituted template type.
1 parent 5408250 commit c56fd93

File tree

12 files changed

+134
-64
lines changed

12 files changed

+134
-64
lines changed

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,18 @@ namespace llvm {
458458
/// \param Elements Struct elements.
459459
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
460460
/// \param UniqueIdentifier A unique identifier for the struct.
461+
/// \param SpecificationOf The type that this type completes (is a
462+
/// specification of). For example, this could be a templated type whose
463+
/// template parameters have been substituted in.
461464
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
462465
/// An extra inhabitant is a bit pattern that does not represent a valid
463466
/// value for objects of a given type.
464467
DICompositeType *createStructType(
465468
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
466469
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
467470
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
468-
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
469-
uint32_t NumExtraInhabitants = 0);
471+
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
472+
DIType *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0);
470473

471474
/// Create debugging information entry for an union.
472475
/// \param Scope Scope in which this union is defined.

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,8 +1160,8 @@ class DICompositeType : public DIType {
11601160
DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
11611161
unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
11621162
uint32_t AlignInBits, uint64_t OffsetInBits,
1163-
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1164-
ArrayRef<Metadata *> Ops)
1163+
uint32_t NumExtraInhabitants, APInt SpareBitsMask,
1164+
DIFlags Flags, ArrayRef<Metadata *> Ops)
11651165
: DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
11661166
AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops),
11671167
RuntimeLang(RuntimeLang), SpareBitsMask(SpareBitsMask) {}
@@ -1181,21 +1181,21 @@ class DICompositeType : public DIType {
11811181
static DICompositeType *
11821182
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
11831183
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1184-
uint32_t AlignInBits, uint64_t OffsetInBits,
1185-
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags, DINodeArray Elements,
1186-
unsigned RuntimeLang, DIType *VTableHolder,
1184+
uint32_t AlignInBits, uint64_t OffsetInBits, DIType *SpecificationOf,
1185+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1186+
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
11871187
DITemplateParameterArray TemplateParams, StringRef Identifier,
11881188
DIDerivedType *Discriminator, Metadata *DataLocation,
11891189
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
11901190
DINodeArray Annotations, StorageType Storage,
11911191
bool ShouldCreate = true) {
1192-
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
1193-
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1194-
Flags, Elements.get(), RuntimeLang, VTableHolder,
1195-
TemplateParams.get(),
1196-
getCanonicalMDString(Context, Identifier), Discriminator,
1197-
DataLocation, Associated, Allocated, Rank, Annotations.get(),
1198-
NumExtraInhabitants, SpareBitsMask, Storage, ShouldCreate);
1192+
return getImpl(
1193+
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1194+
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1195+
RuntimeLang, VTableHolder, TemplateParams.get(),
1196+
getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1197+
Associated, Allocated, Rank, Annotations.get(), SpecificationOf,
1198+
NumExtraInhabitants, SpareBitsMask, Storage, ShouldCreate);
11991199
}
12001200
static DICompositeType *
12011201
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1205,7 +1205,8 @@ class DICompositeType : public DIType {
12051205
Metadata *VTableHolder, Metadata *TemplateParams,
12061206
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
12071207
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1208-
Metadata *Annotations, uint32_t NumExtraInhabitants, APInt SpareBitsMask,
1208+
Metadata *Annotations, Metadata *SpecificationOf,
1209+
uint32_t NumExtraInhabitants, APInt SpareBitsMask,
12091210
StorageType Storage, bool ShouldCreate = true);
12101211

12111212
TempDICompositeType cloneImpl() const {
@@ -1215,7 +1216,8 @@ class DICompositeType : public DIType {
12151216
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
12161217
getTemplateParams(), getIdentifier(), getDiscriminator(),
12171218
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
1218-
getRawRank(), getAnnotations(), getNumExtraInhabitants(), getSpareBitsMask());
1219+
getRawRank(), getAnnotations(), getSpecificationOf(),
1220+
getNumExtraInhabitants(), getSpareBitsMask());
12191221
}
12201222

12211223
public:
@@ -1229,11 +1231,12 @@ class DICompositeType : public DIType {
12291231
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
12301232
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
12311233
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
1232-
DINodeArray Annotations = nullptr, uint32_t NumExtraInhabitants = 0, APInt SpareBitsMask = APInt()),
1234+
DINodeArray Annotations = nullptr, DIType *SpecificationOf = nullptr,
1235+
uint32_t NumExtraInhabitants = 0, APInt SpareBitsMask = APInt()),
12331236
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1234-
OffsetInBits, NumExtraInhabitants, SpareBitsMask, Flags, Elements, RuntimeLang,
1235-
VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation,
1236-
Associated, Allocated, Rank, Annotations))
1237+
OffsetInBits, SpecificationOf, NumExtraInhabitants, SpareBitsMask, Flags,
1238+
Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier,
1239+
Discriminator, DataLocation, Associated, Allocated, Rank, Annotations))
12371240
DEFINE_MDNODE_GET(
12381241
DICompositeType,
12391242
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1244,11 +1247,12 @@ class DICompositeType : public DIType {
12441247
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
12451248
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
12461249
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
1247-
uint32_t NumExtraInhabitants = 0, APInt SpareBitsMask = APInt()),
1250+
Metadata *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0,
1251+
APInt SpareBitsMask = APInt()),
12481252
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
12491253
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
12501254
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
1251-
Annotations, NumExtraInhabitants, SpareBitsMask))
1255+
Annotations, SpecificationOf, NumExtraInhabitants, SpareBitsMask))
12521256

12531257
TempDICompositeType clone() const { return cloneImpl(); }
12541258

@@ -1263,9 +1267,9 @@ class DICompositeType : public DIType {
12631267
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
12641268
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
12651269
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1266-
uint64_t OffsetInBits, uint32_t NumExtraInhabitants,
1267-
APInt SpareBitsMask, DIFlags Flags, Metadata *Elements,
1268-
unsigned RuntimeLang, Metadata *VTableHolder,
1270+
uint64_t OffsetInBits, Metadata *SpecificationOf,
1271+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1272+
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
12691273
Metadata *TemplateParams, Metadata *Discriminator,
12701274
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
12711275
Metadata *Rank, Metadata *Annotations);
@@ -1285,9 +1289,9 @@ class DICompositeType : public DIType {
12851289
buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
12861290
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
12871291
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1288-
uint64_t OffsetInBits, uint32_t NumExtraInhabitants,
1289-
APInt SpareBitsMask, DIFlags Flags, Metadata *Elements,
1290-
unsigned RuntimeLang, Metadata *VTableHolder,
1292+
uint64_t OffsetInBits, Metadata *SpecificationOf,
1293+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1294+
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
12911295
Metadata *TemplateParams, Metadata *Discriminator,
12921296
Metadata *DataLocation, Metadata *Associated,
12931297
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
@@ -1351,6 +1355,10 @@ class DICompositeType : public DIType {
13511355
return cast_or_null<MDTuple>(getRawAnnotations());
13521356
}
13531357

1358+
Metadata *getRawSpecificationOf() const { return getOperand(14); }
1359+
DIType *getSpecificationOf() const {
1360+
return cast_or_null<DIType>(getRawSpecificationOf());
1361+
}
13541362
/// Replace operands.
13551363
///
13561364
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5079,6 +5079,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
50795079
OPTIONAL(rank, MDSignedOrMDField, ); \
50805080
OPTIONAL(annotations, MDField, ); \
50815081
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
5082+
OPTIONAL(specification_of, MDField, ); \
50825083
OPTIONAL(spare_bits_mask, MDAPSIntField, );
50835084
PARSE_MD_FIELDS();
50845085
#undef VISIT_MD_FIELDS
@@ -5095,10 +5096,11 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
50955096
if (auto *CT = DICompositeType::buildODRType(
50965097
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
50975098
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
5098-
num_extra_inhabitants.Val, spare_bits_mask.Val, flags.Val, elements.Val,
5099-
runtimeLang.Val, vtableHolder.Val, templateParams.Val,
5100-
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
5101-
Rank, annotations.Val)) {
5099+
specification_of.Val, num_extra_inhabitants.Val,
5100+
spare_bits_mask.Val, flags.Val, elements.Val, runtimeLang.Val,
5101+
vtableHolder.Val, templateParams.Val, discriminator.Val,
5102+
dataLocation.Val, associated.Val, allocated.Val, Rank,
5103+
annotations.Val)) {
51025104
Result = CT;
51035105
return false;
51045106
}
@@ -5111,7 +5113,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
51115113
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
51125114
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
51135115
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
5114-
annotations.Val, num_extra_inhabitants.Val, spare_bits_mask.Val));
5116+
annotations.Val, specification_of.Val, num_extra_inhabitants.Val,
5117+
spare_bits_mask.Val));
51155118
return false;
51165119
}
51175120

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16041604
Metadata *Allocated = nullptr;
16051605
Metadata *Rank = nullptr;
16061606
Metadata *Annotations = nullptr;
1607+
Metadata *SpecificationOf = nullptr;
16071608
auto *Identifier = getMDString(Record[15]);
16081609
// If this module is being parsed so that it can be ThinLTO imported
16091610
// into another module, composite types only need to be imported
@@ -1647,30 +1648,33 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16471648
if (Record.size() > 21) {
16481649
Annotations = getMDOrNull(Record[21]);
16491650
}
1651+
if (Record.size() > 23) {
1652+
SpecificationOf = getMDOrNull(Record[23]);
1653+
}
16501654
}
16511655
DICompositeType *CT = nullptr;
16521656
APInt SpareBitsMask;
16531657
// SpareBitsMask is an optional field so the metadata loader has to check if
16541658
// it was emitted before accessing it.
1655-
if (Record.size() > 23) {
1659+
if (Record.size() > 24) {
16561660
if (IsBigInt) {
1657-
const uint64_t BitWidth = Record[23];
1661+
const uint64_t BitWidth = Record[24];
16581662
const size_t NumWords = Record.size() - 3;
16591663
SpareBitsMask =
1660-
readWideAPInt(ArrayRef(&Record[24], NumWords), BitWidth);
1664+
readWideAPInt(ArrayRef(&Record[25], NumWords), BitWidth);
16611665
} else {
1662-
const uint64_t IntValue = Record[23];
1666+
const uint64_t IntValue = Record[24];
16631667
SpareBitsMask = APInt(64, IntValue);
16641668
}
16651669
}
16661670

16671671
if (Identifier)
16681672
CT = DICompositeType::buildODRType(
16691673
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
1670-
SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants,
1671-
SpareBitsMask, Flags, Elements, RuntimeLang, VTableHolder,
1672-
TemplateParams, Discriminator, DataLocation, Associated, Allocated,
1673-
Rank, Annotations);
1674+
SizeInBits, AlignInBits, OffsetInBits, SpecificationOf,
1675+
NumExtraInhabitants, SpareBitsMask, Flags, Elements, RuntimeLang,
1676+
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
1677+
Allocated, Rank, Annotations);
16741678

16751679
// Create a node if we didn't get a lazy ODR type.
16761680
if (!CT)
@@ -1679,8 +1683,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16791683
SizeInBits, AlignInBits, OffsetInBits, Flags,
16801684
Elements, RuntimeLang, VTableHolder, TemplateParams,
16811685
Identifier, Discriminator, DataLocation, Associated,
1682-
Allocated, Rank, Annotations, NumExtraInhabitants,
1683-
SpareBitsMask));
1686+
Allocated, Rank, Annotations, SpecificationOf,
1687+
NumExtraInhabitants, SpareBitsMask));
16841688
if (!IsNotUsedInTypeRef && Identifier)
16851689
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
16861690

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
17851785
Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
17861786
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
17871787
Record.push_back(N->getNumExtraInhabitants());
1788+
Record.push_back(VE.getMetadataOrNullID(N->getRawSpecificationOf()));
17881789

17891790

17901791
if (!SpareBitsMask.isZero()) {

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
10121012
addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
10131013
CC);
10141014
}
1015+
1016+
if (auto *SpecifiedFrom = CTy->getSpecificationOf())
1017+
addDIEEntry(Buffer, dwarf::DW_AT_specification,
1018+
*getOrCreateContextDIE(SpecifiedFrom));
1019+
10151020
break;
10161021
}
10171022
default:

llvm/lib/IR/AsmWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,8 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
20842084
else
20852085
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
20862086
Printer.printMetadata("annotations", N->getRawAnnotations());
2087+
if (auto *SpecificationOf = N->getRawSpecificationOf())
2088+
Printer.printMetadata("specification_of", SpecificationOf);
20872089
Out << ")";
20882090
}
20892091

llvm/lib/IR/DIBuilder.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,13 +508,13 @@ DICompositeType *DIBuilder::createStructType(
508508
DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
509509
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
510510
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
511-
DIType *VTableHolder, StringRef UniqueIdentifier,
511+
DIType *VTableHolder, StringRef UniqueIdentifier, DIType *SpecificationOf,
512512
uint32_t NumExtraInhabitants) {
513513
auto *R = DICompositeType::get(
514514
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
515515
getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
516516
Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier,
517-
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
517+
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, SpecificationOf,
518518
NumExtraInhabitants);
519519
trackIfUnresolved(R);
520520
return R;
@@ -540,8 +540,9 @@ DICompositeType *DIBuilder::createVariantPart(
540540
auto *R = DICompositeType::get(
541541
VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,
542542
getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits,
543-
OffsetInBits, Flags, Elements, 0, nullptr, nullptr, UniqueIdentifier, 0,
544-
Discriminator, nullptr, nullptr, nullptr, {}, {}, SpareBitsMask);
543+
OffsetInBits, Flags, Elements, 0, nullptr, nullptr, UniqueIdentifier,
544+
nullptr, 0, Discriminator, nullptr, nullptr, nullptr, {}, {},
545+
SpareBitsMask);
545546
trackIfUnresolved(R);
546547
return R;
547548
}

0 commit comments

Comments
 (0)