-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[DebugInfo] Add a specification attribute to LLVM DebugInfo #115362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-llvm-ir Author: Augusto Noronha (augusto2112) ChangesAdd 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. Patch is 36.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115362.diff 13 Files Affected:
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 046890d0c7e1f1..bd0cfbed874a42 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -488,6 +488,9 @@ namespace llvm {
/// \param Elements Struct elements.
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
/// \param UniqueIdentifier A unique identifier for the struct.
+ /// \param SpecificationOf The type that this type completes (is a
+ /// specification of). For example, this could be a templated type whose
+ /// template parameters have been substituted in.
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
/// An extra inhabitant is a bit pattern that does not represent a valid
/// value for instances of a given type. This is used by the Swift language.
@@ -496,7 +499,7 @@ namespace llvm {
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
- uint32_t NumExtraInhabitants = 0);
+ DIType *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0);
/// Create debugging information entry for an union.
/// \param Scope Scope in which this union is defined.
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 5c8394e45c9d7f..643f242c040829 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1201,7 +1201,7 @@ class DICompositeType : public DIType {
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits, DIType *SpecificationOf,
uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams, StringRef Identifier,
@@ -1215,7 +1215,7 @@ class DICompositeType : public DIType {
TemplateParams.get(),
getCanonicalMDString(Context, Identifier), Discriminator,
DataLocation, Associated, Allocated, Rank, Annotations.get(),
- NumExtraInhabitants, Storage, ShouldCreate);
+ SpecificationOf, NumExtraInhabitants, Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1225,8 +1225,9 @@ class DICompositeType : public DIType {
Metadata *VTableHolder, Metadata *TemplateParams,
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
- Metadata *Annotations, uint32_t NumExtraInhabitants,
- StorageType Storage, bool ShouldCreate = true);
+ Metadata *Annotations, Metadata *SpecificationOf,
+ uint32_t NumExtraInhabitants, StorageType Storage,
+ bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
return getTemporary(
@@ -1235,7 +1236,8 @@ class DICompositeType : public DIType {
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
getTemplateParams(), getIdentifier(), getDiscriminator(),
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
- getRawRank(), getAnnotations(), getNumExtraInhabitants());
+ getRawRank(), getAnnotations(), getSpecificationOf(),
+ getNumExtraInhabitants());
}
public:
@@ -1249,11 +1251,12 @@ class DICompositeType : public DIType {
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
- DINodeArray Annotations = nullptr, uint32_t NumExtraInhabitants = 0),
+ DINodeArray Annotations = nullptr, DIType *SpecificationOf = nullptr,
+ uint32_t NumExtraInhabitants = 0),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
- OffsetInBits, NumExtraInhabitants, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation,
- Associated, Allocated, Rank, Annotations))
+ OffsetInBits, SpecificationOf, NumExtraInhabitants, Flags, Elements,
+ RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator,
+ DataLocation, Associated, Allocated, Rank, Annotations))
DEFINE_MDNODE_GET(
DICompositeType,
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1264,11 +1267,11 @@ class DICompositeType : public DIType {
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
- uint32_t NumExtraInhabitants = 0),
+ Metadata *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
- Annotations, NumExtraInhabitants))
+ Annotations, SpecificationOf, NumExtraInhabitants))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -1283,8 +1286,9 @@ class DICompositeType : public DIType {
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags,
- Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
+ uint64_t OffsetInBits, Metadata *SpecificationOf,
+ uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
+ unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
Metadata *Rank, Metadata *Annotations);
@@ -1300,14 +1304,16 @@ class DICompositeType : public DIType {
///
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
/// nullptr.
- static DICompositeType *buildODRType(
- LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
- Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
- uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
- unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams,
- Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
- Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
+ static DICompositeType *
+ buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
+ MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
+ Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
+ uint64_t OffsetInBits, Metadata *SpecificationOf,
+ uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
+ unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams, Metadata *Discriminator,
+ Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
DINodeArray getElements() const {
@@ -1367,6 +1373,10 @@ class DICompositeType : public DIType {
return cast_or_null<MDTuple>(getRawAnnotations());
}
+ Metadata *getRawSpecificationOf() const { return getOperand(14); }
+ DIType *getSpecificationOf() const {
+ return cast_or_null<DIType>(getRawSpecificationOf());
+ }
/// Replace operands.
///
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index dd1baabc7e9ac4..4bae02c069b9f9 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -5437,7 +5437,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(allocated, MDField, ); \
OPTIONAL(rank, MDSignedOrMDField, ); \
OPTIONAL(annotations, MDField, ); \
- OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX));
+ OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(specification_of, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -5453,10 +5454,10 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
if (auto *CT = DICompositeType::buildODRType(
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
- num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val,
- vtableHolder.Val, templateParams.Val, discriminator.Val,
- dataLocation.Val, associated.Val, allocated.Val, Rank,
- annotations.Val)) {
+ specification_of.Val, num_extra_inhabitants.Val, flags.Val,
+ elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
+ discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
+ Rank, annotations.Val)) {
Result = CT;
return false;
}
@@ -5469,7 +5470,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
- annotations.Val, num_extra_inhabitants.Val));
+ annotations.Val, specification_of.Val, num_extra_inhabitants.Val));
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 8ca46a4ce821a5..b4936870d7a6df 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1600,7 +1600,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
- if (Record.size() < 16 || Record.size() > 23)
+ if (Record.size() < 16 || Record.size() > 24)
return error("Invalid record");
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1630,6 +1630,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
Metadata *Allocated = nullptr;
Metadata *Rank = nullptr;
Metadata *Annotations = nullptr;
+ Metadata *SpecificationOf = nullptr;
auto *Identifier = getMDString(Record[15]);
// If this module is being parsed so that it can be ThinLTO imported
// into another module, composite types only need to be imported as
@@ -1678,14 +1679,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 21) {
Annotations = getMDOrNull(Record[21]);
}
+ if (Record.size() > 23) {
+ SpecificationOf = getMDOrNull(Record[23]);
+ }
}
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
- SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags,
- Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator,
- DataLocation, Associated, Allocated, Rank, Annotations);
+ SizeInBits, AlignInBits, OffsetInBits, SpecificationOf,
+ NumExtraInhabitants, Flags, Elements, RuntimeLang, VTableHolder,
+ TemplateParams, Discriminator, DataLocation, Associated, Allocated,
+ Rank, Annotations);
// Create a node if we didn't get a lazy ODR type.
if (!CT)
@@ -1694,7 +1699,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
SizeInBits, AlignInBits, OffsetInBits, Flags,
Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated,
- Allocated, Rank, Annotations, NumExtraInhabitants));
+ Allocated, Rank, Annotations, SpecificationOf,
+ NumExtraInhabitants));
if (!IsNotUsedInTypeRef && Identifier)
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index de01750857bba3..97994b0e913508 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1947,6 +1947,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
Record.push_back(N->getNumExtraInhabitants());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSpecificationOf()));
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
Record.clear();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index c6d9fcfb0b76c1..0e6ef631bff0f9 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1043,6 +1043,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
CC);
}
+
+ if (auto *SpecifiedFrom = CTy->getSpecificationOf())
+ addDIEEntry(Buffer, dwarf::DW_AT_specification,
+ *getOrCreateContextDIE(SpecifiedFrom));
+
break;
}
default:
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 8716a7ce2aec36..1cad4be4db73e3 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2235,6 +2235,8 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
else
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
Printer.printMetadata("annotations", N->getRawAnnotations());
+ if (auto *SpecificationOf = N->getRawSpecificationOf())
+ Printer.printMetadata("specification_of", SpecificationOf);
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 8bc8c2d81fb01a..bfc33ff0f955cf 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -521,13 +521,13 @@ DICompositeType *DIBuilder::createStructType(
DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
- DIType *VTableHolder, StringRef UniqueIdentifier,
+ DIType *VTableHolder, StringRef UniqueIdentifier, DIType *SpecificationOf,
uint32_t NumExtraInhabitants) {
auto *R = DICompositeType::get(
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, SpecificationOf,
NumExtraInhabitants);
trackIfUnresolved(R);
return R;
@@ -554,7 +554,8 @@ DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File,
auto *R = DICompositeType::get(
VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,
getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,
- Elements, 0, nullptr, nullptr, UniqueIdentifier, 0, Discriminator);
+ Elements, 0, nullptr, nullptr, UniqueIdentifier, nullptr, 0,
+ Discriminator);
trackIfUnresolved(R);
return R;
}
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index f7268a51406283..a06db3f8387136 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -770,21 +770,21 @@ DICompositeType *DICompositeType::getImpl(
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank, Metadata *Annotations, uint32_t NumExtraInhabitants,
- StorageType Storage, bool ShouldCreate) {
+ Metadata *Rank, Metadata *Annotations, Metadata *SpecificationOf,
+ uint32_t NumExtraInhabitants, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
// Keep this in sync with buildODRType.
- DEFINE_GETIMPL_LOOKUP(DICompositeType,
- (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
- AlignInBits, OffsetInBits, Flags, Elements,
- RuntimeLang, VTableHolder, TemplateParams, Identifier,
- Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations, NumExtraInhabitants));
+ DEFINE_GETIMPL_LOOKUP(
+ DICompositeType,
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
+ Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
+ Annotations, SpecificationOf, NumExtraInhabitants));
Metadata *Ops[] = {File, Scope, Name, BaseType,
Elements, VTableHolder, TemplateParams, Identifier,
Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations};
+ Rank, Annotations, SpecificationOf};
DEFINE_GETIMPL_STORE(DICompositeType,
(Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
OffsetInBits, NumExtraInhabitants, Flags),
@@ -795,10 +795,11 @@ DICompositeType *DICompositeType::buildODRType(
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
- uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
- unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams,
- Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
- Metadata *Allocated, Metadata *Rank, Metadata *Annotations) {
+ Metadata *SpecificationOf, uint32_t NumExtraInhabitants, DIFlags Flags,
+ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation,
+ Metadata *Associated, Metadata *Allocated, Metadata *Rank,
+ Metadata *Annotations) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -809,8 +810,7 @@ DICompositeType *DICompositeType::buildODRType(
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams, &Identifier, Discriminator,
DataLocation, Associated, Allocated, Rank, Annotations,
- NumExtraInhabitants);
-
+ SpecificationOf, NumExtraInhabitants);
if (CT->getTag() != Tag)
return nullptr;
@@ -825,7 +825,7 @@ DICompositeType *DICompositeT...
[truncated]
|
I'm upstreaming this from the downstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update SourceLevelDebugging.rst to explain the attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mechanically, the patch looks fine to me!
I'd probably call the attribute just "specification" same as DWARF does? but also it worries me a bit - the reason we haven't had "specification" in LLVM IR debug info for types so far is that we never have a declaration and a definition of the same type simultaneously - we deduplicate them via the So, yeah, maybe a bit more detail on how this works - and maybe it deserves a different name once we look at the details. |
I see. On the Swift side this works since the identifiers (type mangled names) are different: you have a generic "Type" and a specification "Type", "Type", etc. I can remove any references to C++ if needed, but I'll leave it to @Michael137 to decide if we can adapt this for C++ or not. |
d7e9b4f
to
47f302d
Compare
Could you add a more complete description/examples of the Swift situation this is used for currently? |
Do you mean in the commit message? |
47f302d
to
4be040d
Compare
Sure, that would be fine |
Add a specification 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. This is used by Swift to represent generic types. For example, given this Swift program: ``` struct MyStruct<T> { let t: T } let variable = MyStruct<Int>(t: 43) ``` The Swift compiler emits (roughly) an unsubtituted type for MyStruct<T>: ``` DW_TAG_structure_type DW_AT_name ("MyStruct") // "$s1w8MyStructVyxGD" is a Swift mangled name roughly equivalent to // MyStruct<T> DW_AT_linkage_name ("$s1w8MyStructVyxGD") // other attributes here ``` And a specification for MyStruct<Int>: ``` DW_TAG_structure_type DW_AT_specification (<link to "MyStruct">) // "$s1w8MyStructVySiGD" is a Swift mangled name equivalent to // MyStruct<Int> DW_AT_linkage_name ("$s1w8MyStructVySiGD") DW_AT_byte_size (0x08) // other attributes here ```
4be040d
to
8b3d1e3
Compare
I updated the description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be worth splitting this into smaller steps - asm reading/writing, separate from the functional change in LLVM AsmPrinter, etc.
I still have reservations about using DW_AT_specification for this, but DWARF is permissive and all that, so if it's what you folks want to use for Swift, guess that's fine.
Testing locally, looks like |
) Add a specification 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. This is used by Swift to represent generic types. For example, given this Swift program: ``` struct MyStruct<T> { let t: T } let variable = MyStruct<Int>(t: 43) ``` The Swift compiler emits (roughly) an unsubtituted type for MyStruct<T>: ``` DW_TAG_structure_type DW_AT_name ("MyStruct") // "$s1w8MyStructVyxGD" is a Swift mangled name roughly equivalent to // MyStruct<T> DW_AT_linkage_name ("$s1w8MyStructVyxGD") // other attributes here ``` And a specification for MyStruct<Int>: ``` DW_TAG_structure_type DW_AT_specification (<link to "MyStruct">) // "$s1w8MyStructVySiGD" is a Swift mangled name equivalent to // MyStruct<Int> DW_AT_linkage_name ("$s1w8MyStructVySiGD") DW_AT_byte_size (0x08) // other attributes here ``` (cherry picked from commit 67fb268)
[DebugInfo] Add a specification attribute to LLVM DebugInfo (llvm#115362)
Add a specification 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. This is
used by Swift to represent generic types. For example, given this Swift
program:
The Swift compiler emits (roughly) an unsubtituted type for MyStruct:
And a specification for MyStruct: