[DebugInfo] Add a specification attribute to LLVM DebugInfo (#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: ``` 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 ```
This commit is contained in:
parent
2bd6af8cbc
commit
67fb2686fb
@ -488,6 +488,8 @@ namespace llvm {
|
|||||||
/// \param Elements Struct elements.
|
/// \param Elements Struct elements.
|
||||||
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
|
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
|
||||||
/// \param UniqueIdentifier A unique identifier for the struct.
|
/// \param UniqueIdentifier A unique identifier for the struct.
|
||||||
|
/// \param Specification The type that this type completes. This is used by
|
||||||
|
/// Swift to represent generic types.
|
||||||
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
|
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
|
||||||
/// An extra inhabitant is a bit pattern that does not represent a valid
|
/// 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.
|
/// value for instances of a given type. This is used by the Swift language.
|
||||||
@ -496,7 +498,7 @@ namespace llvm {
|
|||||||
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
|
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
|
||||||
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
|
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
|
||||||
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
|
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
|
||||||
uint32_t NumExtraInhabitants = 0);
|
DIType *Specification = nullptr, uint32_t NumExtraInhabitants = 0);
|
||||||
|
|
||||||
/// Create debugging information entry for an union.
|
/// Create debugging information entry for an union.
|
||||||
/// \param Scope Scope in which this union is defined.
|
/// \param Scope Scope in which this union is defined.
|
||||||
|
@ -1201,7 +1201,7 @@ class DICompositeType : public DIType {
|
|||||||
static DICompositeType *
|
static DICompositeType *
|
||||||
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
|
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
|
||||||
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
|
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
|
||||||
uint32_t AlignInBits, uint64_t OffsetInBits,
|
uint32_t AlignInBits, uint64_t OffsetInBits, DIType *Specification,
|
||||||
uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
|
uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
|
||||||
unsigned RuntimeLang, DIType *VTableHolder,
|
unsigned RuntimeLang, DIType *VTableHolder,
|
||||||
DITemplateParameterArray TemplateParams, StringRef Identifier,
|
DITemplateParameterArray TemplateParams, StringRef Identifier,
|
||||||
@ -1215,7 +1215,7 @@ class DICompositeType : public DIType {
|
|||||||
TemplateParams.get(),
|
TemplateParams.get(),
|
||||||
getCanonicalMDString(Context, Identifier), Discriminator,
|
getCanonicalMDString(Context, Identifier), Discriminator,
|
||||||
DataLocation, Associated, Allocated, Rank, Annotations.get(),
|
DataLocation, Associated, Allocated, Rank, Annotations.get(),
|
||||||
NumExtraInhabitants, Storage, ShouldCreate);
|
Specification, NumExtraInhabitants, Storage, ShouldCreate);
|
||||||
}
|
}
|
||||||
static DICompositeType *
|
static DICompositeType *
|
||||||
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
||||||
@ -1225,8 +1225,9 @@ class DICompositeType : public DIType {
|
|||||||
Metadata *VTableHolder, Metadata *TemplateParams,
|
Metadata *VTableHolder, Metadata *TemplateParams,
|
||||||
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
|
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
|
||||||
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
||||||
Metadata *Annotations, uint32_t NumExtraInhabitants,
|
Metadata *Annotations, Metadata *Specification,
|
||||||
StorageType Storage, bool ShouldCreate = true);
|
uint32_t NumExtraInhabitants, StorageType Storage,
|
||||||
|
bool ShouldCreate = true);
|
||||||
|
|
||||||
TempDICompositeType cloneImpl() const {
|
TempDICompositeType cloneImpl() const {
|
||||||
return getTemporary(
|
return getTemporary(
|
||||||
@ -1235,7 +1236,8 @@ class DICompositeType : public DIType {
|
|||||||
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
|
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
|
||||||
getTemplateParams(), getIdentifier(), getDiscriminator(),
|
getTemplateParams(), getIdentifier(), getDiscriminator(),
|
||||||
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
|
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
|
||||||
getRawRank(), getAnnotations(), getNumExtraInhabitants());
|
getRawRank(), getAnnotations(), getSpecification(),
|
||||||
|
getNumExtraInhabitants());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1249,11 +1251,12 @@ public:
|
|||||||
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
|
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
|
||||||
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
|
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
|
||||||
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
|
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
|
||||||
DINodeArray Annotations = nullptr, uint32_t NumExtraInhabitants = 0),
|
DINodeArray Annotations = nullptr, DIType *Specification = nullptr,
|
||||||
|
uint32_t NumExtraInhabitants = 0),
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, NumExtraInhabitants, Flags, Elements, RuntimeLang,
|
OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements,
|
||||||
VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation,
|
RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator,
|
||||||
Associated, Allocated, Rank, Annotations))
|
DataLocation, Associated, Allocated, Rank, Annotations))
|
||||||
DEFINE_MDNODE_GET(
|
DEFINE_MDNODE_GET(
|
||||||
DICompositeType,
|
DICompositeType,
|
||||||
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||||
@ -1264,11 +1267,11 @@ public:
|
|||||||
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
|
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
|
||||||
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
|
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
|
||||||
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
|
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
|
||||||
uint32_t NumExtraInhabitants = 0),
|
Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0),
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
|
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
|
||||||
Annotations, NumExtraInhabitants))
|
Annotations, Specification, NumExtraInhabitants))
|
||||||
|
|
||||||
TempDICompositeType clone() const { return cloneImpl(); }
|
TempDICompositeType clone() const { return cloneImpl(); }
|
||||||
|
|
||||||
@ -1283,8 +1286,9 @@ public:
|
|||||||
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
||||||
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
||||||
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
|
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
|
||||||
uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags,
|
uint64_t OffsetInBits, Metadata *Specification,
|
||||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
|
||||||
|
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *TemplateParams, Metadata *Discriminator,
|
Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
Metadata *Rank, Metadata *Annotations);
|
Metadata *Rank, Metadata *Annotations);
|
||||||
@ -1300,14 +1304,16 @@ public:
|
|||||||
///
|
///
|
||||||
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
|
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
|
||||||
/// nullptr.
|
/// nullptr.
|
||||||
static DICompositeType *buildODRType(
|
static DICompositeType *
|
||||||
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
||||||
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
|
||||||
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
|
uint64_t OffsetInBits, Metadata *Specification,
|
||||||
unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams,
|
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
|
||||||
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
|
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
|
Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
|
Metadata *DataLocation, Metadata *Associated,
|
||||||
|
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
|
||||||
|
|
||||||
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
|
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
|
||||||
DINodeArray getElements() const {
|
DINodeArray getElements() const {
|
||||||
@ -1367,6 +1373,10 @@ public:
|
|||||||
return cast_or_null<MDTuple>(getRawAnnotations());
|
return cast_or_null<MDTuple>(getRawAnnotations());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Metadata *getRawSpecification() const { return getOperand(14); }
|
||||||
|
DIType *getSpecification() const {
|
||||||
|
return cast_or_null<DIType>(getRawSpecification());
|
||||||
|
}
|
||||||
/// Replace operands.
|
/// Replace operands.
|
||||||
///
|
///
|
||||||
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
|
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
|
||||||
|
@ -5437,7 +5437,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
OPTIONAL(allocated, MDField, ); \
|
OPTIONAL(allocated, MDField, ); \
|
||||||
OPTIONAL(rank, MDSignedOrMDField, ); \
|
OPTIONAL(rank, MDSignedOrMDField, ); \
|
||||||
OPTIONAL(annotations, MDField, ); \
|
OPTIONAL(annotations, MDField, ); \
|
||||||
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX));
|
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
|
||||||
|
OPTIONAL(specification, MDField, );
|
||||||
PARSE_MD_FIELDS();
|
PARSE_MD_FIELDS();
|
||||||
#undef VISIT_MD_FIELDS
|
#undef VISIT_MD_FIELDS
|
||||||
|
|
||||||
@ -5453,10 +5454,10 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
if (auto *CT = DICompositeType::buildODRType(
|
if (auto *CT = DICompositeType::buildODRType(
|
||||||
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
||||||
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
|
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
|
||||||
num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val,
|
specification.Val, num_extra_inhabitants.Val, flags.Val,
|
||||||
vtableHolder.Val, templateParams.Val, discriminator.Val,
|
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
|
||||||
dataLocation.Val, associated.Val, allocated.Val, Rank,
|
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
|
||||||
annotations.Val)) {
|
Rank, annotations.Val)) {
|
||||||
Result = CT;
|
Result = CT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -5469,7 +5470,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
||||||
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
|
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
|
||||||
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
|
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
|
||||||
annotations.Val, num_extra_inhabitants.Val));
|
annotations.Val, specification.Val, num_extra_inhabitants.Val));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,7 +1600,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::METADATA_COMPOSITE_TYPE: {
|
case bitc::METADATA_COMPOSITE_TYPE: {
|
||||||
if (Record.size() < 16 || Record.size() > 23)
|
if (Record.size() < 16 || Record.size() > 24)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
// If we have a UUID and this is not a forward declaration, lookup the
|
// 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 *Allocated = nullptr;
|
||||||
Metadata *Rank = nullptr;
|
Metadata *Rank = nullptr;
|
||||||
Metadata *Annotations = nullptr;
|
Metadata *Annotations = nullptr;
|
||||||
|
Metadata *Specification = nullptr;
|
||||||
auto *Identifier = getMDString(Record[15]);
|
auto *Identifier = getMDString(Record[15]);
|
||||||
// If this module is being parsed so that it can be ThinLTO imported
|
// If this module is being parsed so that it can be ThinLTO imported
|
||||||
// into another module, composite types only need to be imported as
|
// into another module, composite types only need to be imported as
|
||||||
@ -1678,14 +1679,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
if (Record.size() > 21) {
|
if (Record.size() > 21) {
|
||||||
Annotations = getMDOrNull(Record[21]);
|
Annotations = getMDOrNull(Record[21]);
|
||||||
}
|
}
|
||||||
|
if (Record.size() > 23) {
|
||||||
|
Specification = getMDOrNull(Record[23]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DICompositeType *CT = nullptr;
|
DICompositeType *CT = nullptr;
|
||||||
if (Identifier)
|
if (Identifier)
|
||||||
CT = DICompositeType::buildODRType(
|
CT = DICompositeType::buildODRType(
|
||||||
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
||||||
SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags,
|
SizeInBits, AlignInBits, OffsetInBits, Specification,
|
||||||
Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator,
|
NumExtraInhabitants, Flags, Elements, RuntimeLang, VTableHolder,
|
||||||
DataLocation, Associated, Allocated, Rank, Annotations);
|
TemplateParams, Discriminator, DataLocation, Associated, Allocated,
|
||||||
|
Rank, Annotations);
|
||||||
|
|
||||||
// Create a node if we didn't get a lazy ODR type.
|
// Create a node if we didn't get a lazy ODR type.
|
||||||
if (!CT)
|
if (!CT)
|
||||||
@ -1694,7 +1699,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
||||||
Elements, RuntimeLang, VTableHolder, TemplateParams,
|
Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Identifier, Discriminator, DataLocation, Associated,
|
Identifier, Discriminator, DataLocation, Associated,
|
||||||
Allocated, Rank, Annotations, NumExtraInhabitants));
|
Allocated, Rank, Annotations, Specification,
|
||||||
|
NumExtraInhabitants));
|
||||||
if (!IsNotUsedInTypeRef && Identifier)
|
if (!IsNotUsedInTypeRef && Identifier)
|
||||||
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
|
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
|
||||||
|
|
||||||
|
@ -1947,6 +1947,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
|
|||||||
Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
|
Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
|
||||||
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
|
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
|
||||||
Record.push_back(N->getNumExtraInhabitants());
|
Record.push_back(N->getNumExtraInhabitants());
|
||||||
|
Record.push_back(VE.getMetadataOrNullID(N->getRawSpecification()));
|
||||||
|
|
||||||
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
||||||
Record.clear();
|
Record.clear();
|
||||||
|
@ -1043,6 +1043,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
|
|||||||
addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
|
addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
|
||||||
CC);
|
CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto *SpecifiedFrom = CTy->getSpecification())
|
||||||
|
addDIEEntry(Buffer, dwarf::DW_AT_specification,
|
||||||
|
*getOrCreateContextDIE(SpecifiedFrom));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -2235,6 +2235,8 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
|
|||||||
else
|
else
|
||||||
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
|
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
|
||||||
Printer.printMetadata("annotations", N->getRawAnnotations());
|
Printer.printMetadata("annotations", N->getRawAnnotations());
|
||||||
|
if (auto *Specification = N->getRawSpecification())
|
||||||
|
Printer.printMetadata("specification", Specification);
|
||||||
Out << ")";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,13 +521,13 @@ DICompositeType *DIBuilder::createStructType(
|
|||||||
DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
|
DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
|
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
|
||||||
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
|
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
|
||||||
DIType *VTableHolder, StringRef UniqueIdentifier,
|
DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification,
|
||||||
uint32_t NumExtraInhabitants) {
|
uint32_t NumExtraInhabitants) {
|
||||||
auto *R = DICompositeType::get(
|
auto *R = DICompositeType::get(
|
||||||
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
|
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
|
||||||
getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
|
getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
|
||||||
Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier,
|
Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Specification,
|
||||||
NumExtraInhabitants);
|
NumExtraInhabitants);
|
||||||
trackIfUnresolved(R);
|
trackIfUnresolved(R);
|
||||||
return R;
|
return R;
|
||||||
|
@ -770,21 +770,21 @@ DICompositeType *DICompositeType::getImpl(
|
|||||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
|
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
Metadata *Rank, Metadata *Annotations, uint32_t NumExtraInhabitants,
|
Metadata *Rank, Metadata *Annotations, Metadata *Specification,
|
||||||
StorageType Storage, bool ShouldCreate) {
|
uint32_t NumExtraInhabitants, StorageType Storage, bool ShouldCreate) {
|
||||||
assert(isCanonical(Name) && "Expected canonical MDString");
|
assert(isCanonical(Name) && "Expected canonical MDString");
|
||||||
|
|
||||||
// Keep this in sync with buildODRType.
|
// Keep this in sync with buildODRType.
|
||||||
DEFINE_GETIMPL_LOOKUP(DICompositeType,
|
DEFINE_GETIMPL_LOOKUP(
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
DICompositeType,
|
||||||
AlignInBits, OffsetInBits, Flags, Elements,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
RuntimeLang, VTableHolder, TemplateParams, Identifier,
|
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Discriminator, DataLocation, Associated, Allocated,
|
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
|
||||||
Rank, Annotations, NumExtraInhabitants));
|
Annotations, Specification, NumExtraInhabitants));
|
||||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||||
Elements, VTableHolder, TemplateParams, Identifier,
|
Elements, VTableHolder, TemplateParams, Identifier,
|
||||||
Discriminator, DataLocation, Associated, Allocated,
|
Discriminator, DataLocation, Associated, Allocated,
|
||||||
Rank, Annotations};
|
Rank, Annotations, Specification};
|
||||||
DEFINE_GETIMPL_STORE(DICompositeType,
|
DEFINE_GETIMPL_STORE(DICompositeType,
|
||||||
(Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
|
(Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, NumExtraInhabitants, Flags),
|
OffsetInBits, NumExtraInhabitants, Flags),
|
||||||
@ -795,10 +795,11 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
||||||
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||||
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
|
Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
|
||||||
unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams,
|
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
|
Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation,
|
||||||
Metadata *Allocated, Metadata *Rank, Metadata *Annotations) {
|
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
||||||
|
Metadata *Annotations) {
|
||||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
if (!Context.isODRUniquingDebugTypes())
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -809,8 +810,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||||
VTableHolder, TemplateParams, &Identifier, Discriminator,
|
VTableHolder, TemplateParams, &Identifier, Discriminator,
|
||||||
DataLocation, Associated, Allocated, Rank, Annotations,
|
DataLocation, Associated, Allocated, Rank, Annotations,
|
||||||
NumExtraInhabitants);
|
Specification, NumExtraInhabitants);
|
||||||
|
|
||||||
if (CT->getTag() != Tag)
|
if (CT->getTag() != Tag)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -825,7 +825,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||||
Elements, VTableHolder, TemplateParams, &Identifier,
|
Elements, VTableHolder, TemplateParams, &Identifier,
|
||||||
Discriminator, DataLocation, Associated, Allocated,
|
Discriminator, DataLocation, Associated, Allocated,
|
||||||
Rank, Annotations};
|
Rank, Annotations, Specification};
|
||||||
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
|
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
|
||||||
"Mismatched number of operands");
|
"Mismatched number of operands");
|
||||||
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
|
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
|
||||||
@ -838,10 +838,11 @@ DICompositeType *DICompositeType::getODRType(
|
|||||||
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
||||||
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||||
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
|
Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
|
||||||
unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams,
|
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
|
Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation,
|
||||||
Metadata *Allocated, Metadata *Rank, Metadata *Annotations) {
|
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
||||||
|
Metadata *Annotations) {
|
||||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
if (!Context.isODRUniquingDebugTypes())
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -851,7 +852,7 @@ DICompositeType *DICompositeType::getODRType(
|
|||||||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
||||||
TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
|
TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
|
||||||
Allocated, Rank, Annotations, NumExtraInhabitants);
|
Allocated, Rank, Annotations, Specification, NumExtraInhabitants);
|
||||||
} else {
|
} else {
|
||||||
if (CT->getTag() != Tag)
|
if (CT->getTag() != Tag)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -655,6 +655,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Metadata *Allocated;
|
Metadata *Allocated;
|
||||||
Metadata *Rank;
|
Metadata *Rank;
|
||||||
Metadata *Annotations;
|
Metadata *Annotations;
|
||||||
|
Metadata *Specification;
|
||||||
uint32_t NumExtraInhabitants;
|
uint32_t NumExtraInhabitants;
|
||||||
|
|
||||||
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||||
@ -665,7 +666,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
MDString *Identifier, Metadata *Discriminator,
|
MDString *Identifier, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated,
|
Metadata *DataLocation, Metadata *Associated,
|
||||||
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
|
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
|
||||||
uint32_t NumExtraInhabitants)
|
Metadata *Specification, uint32_t NumExtraInhabitants)
|
||||||
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
|
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
|
||||||
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
|
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
|
||||||
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
|
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
|
||||||
@ -673,7 +674,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
TemplateParams(TemplateParams), Identifier(Identifier),
|
TemplateParams(TemplateParams), Identifier(Identifier),
|
||||||
Discriminator(Discriminator), DataLocation(DataLocation),
|
Discriminator(Discriminator), DataLocation(DataLocation),
|
||||||
Associated(Associated), Allocated(Allocated), Rank(Rank),
|
Associated(Associated), Allocated(Allocated), Rank(Rank),
|
||||||
Annotations(Annotations), NumExtraInhabitants(NumExtraInhabitants) {}
|
Annotations(Annotations), Specification(Specification),
|
||||||
|
NumExtraInhabitants(NumExtraInhabitants) {}
|
||||||
MDNodeKeyImpl(const DICompositeType *N)
|
MDNodeKeyImpl(const DICompositeType *N)
|
||||||
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
|
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
|
||||||
Line(N->getLine()), Scope(N->getRawScope()),
|
Line(N->getLine()), Scope(N->getRawScope()),
|
||||||
@ -687,6 +689,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
DataLocation(N->getRawDataLocation()),
|
DataLocation(N->getRawDataLocation()),
|
||||||
Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
|
Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
|
||||||
Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
|
Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
|
||||||
|
Specification(N->getSpecification()),
|
||||||
NumExtraInhabitants(N->getNumExtraInhabitants()) {}
|
NumExtraInhabitants(N->getNumExtraInhabitants()) {}
|
||||||
|
|
||||||
bool isKeyOf(const DICompositeType *RHS) const {
|
bool isKeyOf(const DICompositeType *RHS) const {
|
||||||
@ -706,6 +709,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Associated == RHS->getRawAssociated() &&
|
Associated == RHS->getRawAssociated() &&
|
||||||
Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
|
Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
|
||||||
Annotations == RHS->getRawAnnotations() &&
|
Annotations == RHS->getRawAnnotations() &&
|
||||||
|
Specification == RHS->getSpecification() &&
|
||||||
NumExtraInhabitants == RHS->getNumExtraInhabitants();
|
NumExtraInhabitants == RHS->getNumExtraInhabitants();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||||
; RUN: verify-uselistorder %s
|
; RUN: verify-uselistorder %s
|
||||||
|
|
||||||
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45}
|
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47}
|
||||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48}
|
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50}
|
||||||
|
|
||||||
; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0)
|
; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0)
|
||||||
; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
|
; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
|
||||||
@ -117,3 +117,8 @@
|
|||||||
|
|
||||||
;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
|
;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
|
||||||
!48 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
|
!48 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
|
||||||
|
|
||||||
|
!49 = !DICompositeType(tag: DW_TAG_structure_type, name: "BaseType", file: !12, size: 64, identifier: "BaseType")
|
||||||
|
|
||||||
|
; CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !10, size: 64, identifier: "SpecificationType", specification: !46)
|
||||||
|
!50 = !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !12, size: 64, identifier: "SpecificationType", specification: !49)
|
||||||
|
31
llvm/test/DebugInfo/AArch64/specification.ll
Normal file
31
llvm/test/DebugInfo/AArch64/specification.ll
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
; RUN: llc %s -filetype=obj -mtriple arm64e-apple-darwin -o - \
|
||||||
|
; RUN: | llvm-dwarfdump - | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: DW_TAG_structure_type
|
||||||
|
; CHECK: DW_AT_specification ({{.*}} "BaseType")
|
||||||
|
; CHECK: DW_AT_name ("SpecificationType")
|
||||||
|
; CHECK: DW_AT_byte_size (0x08)
|
||||||
|
|
||||||
|
; CHECK: DW_TAG_structure_type
|
||||||
|
; CHECK: DW_AT_name ("BaseType")
|
||||||
|
; CHECK: DW_AT_byte_size (0x08)
|
||||||
|
|
||||||
|
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
||||||
|
|
||||||
|
@p = common global i8* null, align 8, !dbg !0
|
||||||
|
|
||||||
|
!llvm.dbg.cu = !{!2}
|
||||||
|
!llvm.module.flags = !{!6, !7}
|
||||||
|
|
||||||
|
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
|
||||||
|
!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
|
||||||
|
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
|
||||||
|
!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
|
||||||
|
!4 = !{}
|
||||||
|
!5 = !{!0}
|
||||||
|
!6 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
|
!7 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
|
|
||||||
|
!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "BaseType", file: !3, size: 64, identifier: "BaseType")
|
||||||
|
|
||||||
|
!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !3, size: 64, identifier: "SpecificationType", specification: !10)
|
@ -30,8 +30,8 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||||||
// Without a type map, this should return null.
|
// Without a type map, this should return null.
|
||||||
EXPECT_FALSE(DICompositeType::getODRType(
|
EXPECT_FALSE(DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr,
|
nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Enable the mapping. There still shouldn't be a type.
|
// Enable the mapping. There still shouldn't be a type.
|
||||||
Context.enableDebugTypeODRUniquing();
|
Context.enableDebugTypeODRUniquing();
|
||||||
@ -40,23 +40,23 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||||||
// Create some ODR-uniqued type.
|
// Create some ODR-uniqued type.
|
||||||
auto &CT = *DICompositeType::getODRType(
|
auto &CT = *DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr,
|
nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
||||||
|
|
||||||
// Check that we get it back, even if we change a field.
|
// Check that we get it back, even if we change a field.
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr,
|
0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero,
|
||||||
0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr));
|
nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(&CT,
|
EXPECT_EQ(&CT,
|
||||||
DICompositeType::getODRType(
|
DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type,
|
Context, UUID, dwarf::DW_TAG_class_type,
|
||||||
MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0,
|
MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0,
|
||||||
0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr,
|
0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Check that it's discarded with the type map.
|
// Check that it's discarded with the type map.
|
||||||
Context.disableDebugTypeODRUniquing();
|
Context.disableDebugTypeODRUniquing();
|
||||||
@ -75,43 +75,43 @@ TEST(DebugTypeODRUniquingTest, buildODRType) {
|
|||||||
MDString &UUID = *MDString::get(Context, "Type");
|
MDString &UUID = *MDString::get(Context, "Type");
|
||||||
auto &CT = *DICompositeType::buildODRType(
|
auto &CT = *DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
|
nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||||
|
|
||||||
// Update with another forward decl. This should be a no-op.
|
// Update with another forward decl. This should be a no-op.
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl,
|
0, nullptr, nullptr, 0, 0, 0, nullptr, 0,
|
||||||
nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr,
|
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
EXPECT_FALSE(DICompositeType::buildODRType(
|
EXPECT_FALSE(DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
|
nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Update with a definition. This time we should see a change.
|
// Update with a definition. This time we should see a change.
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr,
|
0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero,
|
||||||
0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr));
|
nullptr, nullptr, nullptr));
|
||||||
EXPECT_FALSE(CT.isForwardDecl());
|
EXPECT_FALSE(CT.isForwardDecl());
|
||||||
|
|
||||||
// Further updates should be ignored.
|
// Further updates should be ignored.
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl,
|
0, nullptr, nullptr, 0, 0, 0, nullptr, 0,
|
||||||
nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr,
|
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_FALSE(CT.isForwardDecl());
|
EXPECT_FALSE(CT.isForwardDecl());
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||||
111u, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero,
|
111u, nullptr, nullptr, 0, 0, 0, nullptr, 0,
|
||||||
nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr,
|
DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_NE(111u, CT.getLine());
|
EXPECT_NE(111u, CT.getLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,8 +122,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||||||
// Build an ODR type that's a forward decl with no other fields set.
|
// Build an ODR type that's a forward decl with no other fields set.
|
||||||
MDString &UUID = *MDString::get(Context, "UUID");
|
MDString &UUID = *MDString::get(Context, "UUID");
|
||||||
auto &CT = *DICompositeType::buildODRType(
|
auto &CT = *DICompositeType::buildODRType(
|
||||||
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, 0,
|
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, nullptr,
|
||||||
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr,
|
0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
// Create macros for running through all the fields except Identifier and Flags.
|
// Create macros for running through all the fields except Identifier and Flags.
|
||||||
@ -155,10 +155,10 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||||||
// Replace all the fields with new values that are distinct from each other.
|
// Replace all the fields with new values that are distinct from each other.
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||||
Context, UUID, 0, Name, File, Line, Scope, BaseType,
|
Context, UUID, 0, Name, File, Line, Scope, BaseType,
|
||||||
SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants,
|
SizeInBits, AlignInBits, OffsetInBits, nullptr,
|
||||||
DINode::FlagArtificial, Elements, RuntimeLang,
|
NumExtraInhabitants, DINode::FlagArtificial, Elements,
|
||||||
VTableHolder, TemplateParams, nullptr, nullptr, nullptr,
|
RuntimeLang, VTableHolder, TemplateParams, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Confirm that all the right fields got updated.
|
// Confirm that all the right fields got updated.
|
||||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user