[llvm] r324426 - Add DWARF for discriminated unions
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 6 15:46:00 PST 2018
Author: adrian
Date: Tue Feb 6 15:45:59 2018
New Revision: 324426
URL: http://llvm.org/viewvc/llvm-project?rev=324426&view=rev
Log:
Add DWARF for discriminated unions
n Rust, an enum that carries data in the variants is, essentially, a
discriminated union. Furthermore, the Rust compiler will perform
space optimizations on such enums in some situations. Previously,
DWARF for these constructs was emitted using a hack (a magic field
name); but this approach stopped working when more space optimizations
were added in https://github.com/rust-lang/rust/pull/45225.
This patch changes LLVM to allow discriminated unions to be
represented in DWARF. It adds createDiscriminatedUnionType and
createDiscriminatedMemberType to DIBuilder and then arranges for this
to be emitted using DWARF's DW_TAG_variant_part and DW_TAG_variant.
Note that DWARF requires that a discriminated union be represented as
a structure with a variant part. However, as Rust only needs to emit
pure discriminated unions, this is what I chose to expose on
DIBuilder.
Patch by Tom Tromey!
Differential Revision: https://reviews.llvm.org/D42082
Added:
llvm/trunk/test/DebugInfo/Generic/discriminated-union.ll
llvm/trunk/test/DebugInfo/Generic/univariant-discriminated-union.ll
llvm/trunk/test/Verifier/variant-part.ll
Modified:
llvm/trunk/include/llvm/IR/DIBuilder.h
llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
llvm/trunk/lib/AsmParser/LLParser.cpp
llvm/trunk/lib/BinaryFormat/Dwarf.cpp
llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
llvm/trunk/lib/IR/AsmWriter.cpp
llvm/trunk/lib/IR/DIBuilder.cpp
llvm/trunk/lib/IR/DebugInfoMetadata.cpp
llvm/trunk/lib/IR/LLVMContextImpl.h
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/test/Assembler/debug-info.ll
llvm/trunk/unittests/IR/DebugTypeODRUniquingTest.cpp
llvm/trunk/unittests/IR/MetadataTest.cpp
Modified: llvm/trunk/include/llvm/IR/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DIBuilder.h?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DIBuilder.h (original)
+++ llvm/trunk/include/llvm/IR/DIBuilder.h Tue Feb 6 15:45:59 2018
@@ -258,6 +258,27 @@ namespace llvm {
uint64_t OffsetInBits,
DINode::DIFlags Flags, DIType *Ty);
+ /// Create debugging information entry for a variant. A variant
+ /// normally should be a member of a variant part.
+ /// \param Scope Member scope.
+ /// \param Name Member name.
+ /// \param File File where this member is defined.
+ /// \param LineNo Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param OffsetInBits Member offset.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Discriminant The discriminant for this branch; null for
+ /// the default branch
+ /// \param Ty Parent type.
+ DIDerivedType *createVariantMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ uint64_t SizeInBits,
+ uint32_t AlignInBits,
+ uint64_t OffsetInBits,
+ Constant *Discriminant,
+ DINode::DIFlags Flags, DIType *Ty);
+
/// Create debugging information entry for a bit field member.
/// \param Scope Member scope.
/// \param Name Member name.
@@ -379,6 +400,27 @@ namespace llvm {
unsigned RunTimeLang = 0,
StringRef UniqueIdentifier = "");
+ /// Create debugging information entry for a variant part. A
+ /// variant part normally has a discriminator (though this is not
+ /// required) and a number of variant children.
+ /// \param Scope Scope in which this union is defined.
+ /// \param Name Union name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Discriminator Discriminant member
+ /// \param Elements Variant elements.
+ /// \param UniqueIdentifier A unique identifier for the union.
+ DICompositeType *createVariantPart(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint32_t AlignInBits,
+ DINode::DIFlags Flags,
+ DIDerivedType *Discriminator,
+ DINodeArray Elements,
+ StringRef UniqueIdentifier = "");
+
/// Create debugging information for template
/// type parameter.
/// \param Scope Scope in which this type is defined.
Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Tue Feb 6 15:45:59 2018
@@ -847,6 +847,12 @@ public:
return C->getValue();
return nullptr;
}
+ Constant *getDiscriminantValue() const {
+ assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+ }
/// @}
static bool classof(const Metadata *MD) {
@@ -889,12 +895,13 @@ class DICompositeType : public DIType {
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
- StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
+ StringRef Identifier, DIDerivedType *Discriminator,
+ StorageType Storage, bool ShouldCreate = true) {
return getImpl(
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
RuntimeLang, VTableHolder, TemplateParams.get(),
- getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
+ getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -902,14 +909,15 @@ class DICompositeType : public DIType {
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
- MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
+ MDString *Identifier, Metadata *Discriminator,
+ StorageType Storage, bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
getScope(), getBaseType(), getSizeInBits(),
getAlignInBits(), getOffsetInBits(), getFlags(),
getElements(), getRuntimeLang(), getVTableHolder(),
- getTemplateParams(), getIdentifier());
+ getTemplateParams(), getIdentifier(), getDiscriminator());
}
public:
@@ -920,10 +928,10 @@ public:
DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
DITypeRef VTableHolder,
DITemplateParameterArray TemplateParams = nullptr,
- StringRef Identifier = ""),
+ StringRef Identifier = "", DIDerivedType *Discriminator = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Identifier))
+ VTableHolder, TemplateParams, Identifier, Discriminator))
DEFINE_MDNODE_GET(DICompositeType,
(unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
@@ -931,10 +939,11 @@ public:
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams = nullptr,
- MDString *Identifier = nullptr),
+ MDString *Identifier = nullptr,
+ Metadata *Discriminator = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Identifier))
+ VTableHolder, TemplateParams, Identifier, Discriminator))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -951,7 +960,7 @@ public:
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams);
+ Metadata *TemplateParams, Metadata *Discriminator);
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
MDString &Identifier);
@@ -970,7 +979,7 @@ public:
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams);
+ Metadata *TemplateParams, Metadata *Discriminator);
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
DINodeArray getElements() const {
@@ -988,6 +997,8 @@ public:
Metadata *getRawVTableHolder() const { return getOperand(5); }
Metadata *getRawTemplateParams() const { return getOperand(6); }
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
+ Metadata *getRawDiscriminator() const { return getOperand(8); }
+ DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
/// Replace operands.
///
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Feb 6 15:45:59 2018
@@ -4156,7 +4156,8 @@ bool LLParser::ParseDICompositeType(MDNo
OPTIONAL(runtimeLang, DwarfLangField, ); \
OPTIONAL(vtableHolder, MDField, ); \
OPTIONAL(templateParams, MDField, ); \
- OPTIONAL(identifier, MDStringField, );
+ OPTIONAL(identifier, MDStringField, ); \
+ OPTIONAL(discriminator, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -4166,7 +4167,7 @@ bool LLParser::ParseDICompositeType(MDNo
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
elements.Val, runtimeLang.Val, vtableHolder.Val,
- templateParams.Val)) {
+ templateParams.Val, discriminator.Val)) {
Result = CT;
return false;
}
@@ -4177,7 +4178,8 @@ bool LLParser::ParseDICompositeType(MDNo
DICompositeType,
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.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));
return false;
}
Modified: llvm/trunk/lib/BinaryFormat/Dwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/Dwarf.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/BinaryFormat/Dwarf.cpp (original)
+++ llvm/trunk/lib/BinaryFormat/Dwarf.cpp Tue Feb 6 15:45:59 2018
@@ -393,16 +393,6 @@ StringRef llvm::dwarf::ArrayOrderString(
return StringRef();
}
-StringRef llvm::dwarf::DiscriminantString(unsigned Discriminant) {
- switch (Discriminant) {
- case DW_DSC_label:
- return "DW_DSC_label";
- case DW_DSC_range:
- return "DW_DSC_range";
- }
- return StringRef();
-}
-
StringRef llvm::dwarf::LNStandardString(unsigned Standard) {
switch (Standard) {
default:
@@ -563,8 +553,6 @@ StringRef llvm::dwarf::AttributeValueStr
return InlineCodeString(Val);
case DW_AT_ordering:
return ArrayOrderString(Val);
- case DW_AT_discr_value:
- return DiscriminantString(Val);
}
return StringRef();
Modified: llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp Tue Feb 6 15:45:59 2018
@@ -1246,7 +1246,7 @@ Error MetadataLoader::MetadataLoaderImpl
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
- if (Record.size() != 16)
+ if (Record.size() < 16 || Record.size() > 17)
return error("Invalid record");
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1269,6 +1269,7 @@ Error MetadataLoader::MetadataLoaderImpl
unsigned RuntimeLang = Record[12];
Metadata *VTableHolder = nullptr;
Metadata *TemplateParams = nullptr;
+ Metadata *Discriminator = 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
@@ -1289,13 +1290,15 @@ Error MetadataLoader::MetadataLoaderImpl
Elements = getMDOrNull(Record[11]);
VTableHolder = getDITypeRefOrNull(Record[13]);
TemplateParams = getMDOrNull(Record[14]);
+ if (Record.size() > 16)
+ Discriminator = getMDOrNull(Record[16]);
}
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams);
+ VTableHolder, TemplateParams, Discriminator);
// Create a node if we didn't get a lazy ODR type.
if (!CT)
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Feb 6 15:45:59 2018
@@ -1526,6 +1526,7 @@ void ModuleBitcodeWriter::writeDIComposi
Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
+ Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
Record.clear();
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Feb 6 15:45:59 2018
@@ -946,9 +946,24 @@ void DwarfUnit::constructTypeDIE(DIE &Bu
case dwarf::DW_TAG_enumeration_type:
constructEnumTypeDIE(Buffer, CTy);
break;
+ case dwarf::DW_TAG_variant_part:
case dwarf::DW_TAG_structure_type:
case dwarf::DW_TAG_union_type:
case dwarf::DW_TAG_class_type: {
+ // Emit the discriminator for a variant part.
+ DIDerivedType *Discriminator = nullptr;
+ if (Tag == dwarf::DW_TAG_variant_part) {
+ Discriminator = CTy->getDiscriminator();
+ if (Discriminator) {
+ // DWARF says:
+ // If the variant part has a discriminant, the discriminant is
+ // represented by a separate debugging information entry which is
+ // a child of the variant part entry.
+ DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
+ addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
+ }
+ }
+
// Add elements to structure type.
DINodeArray Elements = CTy->getElements();
for (const auto *Element : Elements) {
@@ -962,6 +977,18 @@ void DwarfUnit::constructTypeDIE(DIE &Bu
addType(ElemDie, resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
} else if (DDTy->isStaticMember()) {
getOrCreateStaticMemberDIE(DDTy);
+ } else if (Tag == dwarf::DW_TAG_variant_part) {
+ // When emitting a variant part, wrap each member in
+ // DW_TAG_variant.
+ DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
+ if (const ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
+ if (isUnsignedDIType(DD, resolve(Discriminator->getBaseType())))
+ addUInt(Variant, dwarf::DW_AT_discr_value, None, CI->getZExtValue());
+ else
+ addSInt(Variant, dwarf::DW_AT_discr_value, None, CI->getSExtValue());
+ }
+ constructMemberDIE(Variant, DDTy);
} else {
constructMemberDIE(Buffer, DDTy);
}
@@ -981,6 +1008,11 @@ void DwarfUnit::constructTypeDIE(DIE &Bu
if (unsigned PropertyAttributes = Property->getAttributes())
addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None,
PropertyAttributes);
+ } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
+ if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
+ DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer);
+ constructTypeDIE(VariantPart, Composite);
+ }
}
}
@@ -1430,7 +1462,7 @@ void DwarfUnit::constructContainingTypeD
}
}
-void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
+DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);
StringRef Name = DT->getName();
if (!Name.empty())
@@ -1535,6 +1567,8 @@ void DwarfUnit::constructMemberDIE(DIE &
if (DT->isArtificial())
addFlag(MemberDie, dwarf::DW_AT_artificial);
+
+ return MemberDie;
}
DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h Tue Feb 6 15:45:59 2018
@@ -341,7 +341,7 @@ private:
void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
- void constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
+ DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
void constructTemplateTypeParameterDIE(DIE &Buffer,
const DITemplateTypeParameter *TP);
void constructTemplateValueParameterDIE(DIE &Buffer,
Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Feb 6 15:45:59 2018
@@ -1691,6 +1691,7 @@ static void writeDICompositeType(raw_ost
Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printString("identifier", N->getIdentifier());
+ Printer.printMetadata("discriminator", N->getRawDiscriminator());
Out << ")";
}
Modified: llvm/trunk/lib/IR/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DIBuilder.cpp (original)
+++ llvm/trunk/lib/IR/DIBuilder.cpp Tue Feb 6 15:45:59 2018
@@ -333,6 +333,19 @@ static ConstantAsMetadata *getConstantOr
return nullptr;
}
+DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint32_t AlignInBits,
+ uint64_t OffsetInBits,
+ Constant *Discriminant,
+ DINode::DIFlags Flags, DIType *Ty) {
+ return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
+ LineNumber, getNonCompileUnitScope(Scope), Ty,
+ SizeInBits, AlignInBits, OffsetInBits, None, Flags,
+ getConstantOrNull(Discriminant));
+}
+
DIDerivedType *DIBuilder::createBitFieldMemberType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,
@@ -457,6 +470,18 @@ DICompositeType *DIBuilder::createUnionT
trackIfUnresolved(R);
return R;
}
+
+DICompositeType *DIBuilder::createVariantPart(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
+ DIDerivedType *Discriminator, DINodeArray Elements, StringRef UniqueIdentifier) {
+ 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, Discriminator);
+ trackIfUnresolved(R);
+ return R;
+}
DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,
DINode::DIFlags Flags,
Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Tue Feb 6 15:45:59 2018
@@ -305,17 +305,18 @@ DICompositeType *DICompositeType::getImp
unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams, MDString *Identifier, StorageType Storage,
- bool ShouldCreate) {
+ Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
+ 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));
+ VTableHolder, TemplateParams, Identifier, Discriminator));
Metadata *Ops[] = {File, Scope, Name, BaseType,
- Elements, VTableHolder, TemplateParams, Identifier};
+ Elements, VTableHolder, TemplateParams, Identifier,
+ Discriminator};
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
AlignInBits, OffsetInBits, Flags),
Ops);
@@ -326,7 +327,7 @@ DICompositeType *DICompositeType::buildO
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
- Metadata *VTableHolder, Metadata *TemplateParams) {
+ Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -335,7 +336,7 @@ DICompositeType *DICompositeType::buildO
return CT = DICompositeType::getDistinct(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, &Identifier);
+ VTableHolder, TemplateParams, &Identifier, Discriminator);
// Only mutate CT if it's a forward declaration and the new operands aren't.
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
@@ -346,7 +347,8 @@ DICompositeType *DICompositeType::buildO
CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
Flags);
Metadata *Ops[] = {File, Scope, Name, BaseType,
- Elements, VTableHolder, TemplateParams, &Identifier};
+ Elements, VTableHolder, TemplateParams, &Identifier,
+ Discriminator};
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
"Mismatched number of operands");
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
@@ -360,7 +362,7 @@ DICompositeType *DICompositeType::getODR
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
- Metadata *VTableHolder, Metadata *TemplateParams) {
+ Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -369,7 +371,7 @@ DICompositeType *DICompositeType::getODR
CT = DICompositeType::getDistinct(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
- TemplateParams, &Identifier);
+ TemplateParams, &Identifier, Discriminator);
return CT;
}
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Tue Feb 6 15:45:59 2018
@@ -499,18 +499,20 @@ template <> struct MDNodeKeyImpl<DICompo
Metadata *VTableHolder;
Metadata *TemplateParams;
MDString *Identifier;
+ Metadata *Discriminator;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
- MDString *Identifier)
+ MDString *Identifier, Metadata *Discriminator)
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
- TemplateParams(TemplateParams), Identifier(Identifier) {}
+ TemplateParams(TemplateParams), Identifier(Identifier),
+ Discriminator(Discriminator) {}
MDNodeKeyImpl(const DICompositeType *N)
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
@@ -519,7 +521,8 @@ template <> struct MDNodeKeyImpl<DICompo
Flags(N->getFlags()), Elements(N->getRawElements()),
RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
TemplateParams(N->getRawTemplateParams()),
- Identifier(N->getRawIdentifier()) {}
+ Identifier(N->getRawIdentifier()),
+ Discriminator(N->getRawDiscriminator()) {}
bool isKeyOf(const DICompositeType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
@@ -532,7 +535,8 @@ template <> struct MDNodeKeyImpl<DICompo
RuntimeLang == RHS->getRuntimeLang() &&
VTableHolder == RHS->getRawVTableHolder() &&
TemplateParams == RHS->getRawTemplateParams() &&
- Identifier == RHS->getRawIdentifier();
+ Identifier == RHS->getRawIdentifier() &&
+ Discriminator == RHS->getRawDiscriminator();
}
unsigned getHashValue() const {
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Feb 6 15:45:59 2018
@@ -945,7 +945,8 @@ void Verifier::visitDICompositeType(cons
N.getTag() == dwarf::DW_TAG_structure_type ||
N.getTag() == dwarf::DW_TAG_union_type ||
N.getTag() == dwarf::DW_TAG_enumeration_type ||
- N.getTag() == dwarf::DW_TAG_class_type,
+ N.getTag() == dwarf::DW_TAG_class_type ||
+ N.getTag() == dwarf::DW_TAG_variant_part,
"invalid tag", &N);
AssertDI(isScope(N.getRawScope()), "invalid scope", &N, N.getRawScope());
@@ -966,6 +967,11 @@ void Verifier::visitDICompositeType(cons
AssertDI(N.getFile() && !N.getFile()->getFilename().empty(),
"class/union requires a filename", &N, N.getFile());
}
+
+ if (auto *D = N.getRawDiscriminator()) {
+ AssertDI(isa<DIDerivedType>(D) && N.getTag() == dwarf::DW_TAG_variant_part,
+ "discriminator can only appear on variant part");
+ }
}
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
Modified: llvm/trunk/test/Assembler/debug-info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/debug-info.ll?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/debug-info.ll (original)
+++ llvm/trunk/test/Assembler/debug-info.ll Tue Feb 6 15:45:59 2018
@@ -1,8 +1,8 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %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, !33}
-!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}
+; 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}
+!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, !38, !39, !40}
; CHECK: !0 = !DISubrange(count: 3)
; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
@@ -85,3 +85,10 @@
!35 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "000102030405060708090a0b0c0d0e0f")
!36 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None)
!37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None, checksum: "")
+
+; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !14, size: 64)
+; CHECK-NEXT: !35 = !DIDerivedType(tag: DW_TAG_member, scope: !34, baseType: !36, size: 64, align: 64, flags: DIFlagArtificial)
+; CHECK-NEXT: !36 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
+!38 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !16, size: 64, discriminator: !39)
+!39 = !DIDerivedType(tag: DW_TAG_member, scope: !38, baseType: !40, size: 64, align: 64, flags: DIFlagArtificial)
+!40 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
Added: llvm/trunk/test/DebugInfo/Generic/discriminated-union.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/discriminated-union.ll?rev=324426&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/discriminated-union.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/discriminated-union.ll Tue Feb 6 15:45:59 2018
@@ -0,0 +1,80 @@
+; REQUIRES: object-emission
+
+; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t
+; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck %s
+
+; Check for a variant part that has two members, one of which has a
+; discriminant value.
+
+; CHECK: DW_TAG_variant_part
+; CHECK-NOT: TAG
+; CHECK: DW_AT_discr [DW_FORM_ref4] (cu + {{0x[0-9a-fA-F]+}} => {[[OFFSET:0x[0-9a-fA-F]+]]})
+; CHECK-NOT: TAG
+; CHECK: [[OFFSET]]: DW_TAG_member
+; CHECK: DW_AT_type
+; CHECK: DW_AT_alignment
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+; CHECK: DW_AT_artificial [DW_FORM_flag_present] (true)
+; CHECK: DW_TAG_variant
+; CHECK: DW_TAG_member
+; CHECK: DW_AT_type
+; CHECK: DW_AT_alignment
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+; CHECK: DW_TAG_variant
+; CHECK: DW_AT_discr_value [DW_FORM_data1] (0x00)
+; CHECK: DW_TAG_member
+; CHECK: DW_AT_type
+; CHECK: DW_AT_alignment
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+
+%F = type { [0 x i8], {}*, [8 x i8] }
+%"F::Nope" = type {}
+
+define internal void @_ZN2e34main17h934ff72f9a38d4bbE() unnamed_addr #0 !dbg !5 {
+start:
+ %qq = alloca %F, align 8
+ call void @llvm.dbg.declare(metadata %F* %qq, metadata !10, metadata !28), !dbg !29
+ %0 = bitcast %F* %qq to {}**, !dbg !29
+ store {}* null, {}** %0, !dbg !29
+ %1 = bitcast %F* %qq to %"F::Nope"*, !dbg !29
+ ret void, !dbg !30
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+
+attributes #0 = { nounwind uwtable }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+
+!0 = !{i32 1, !"PIE Level", i32 2}
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!2 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !3, producer: "clang LLVM (rustc version 1.24.0-dev)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
+!3 = !DIFile(filename: "e3.rs", directory: "/home/tromey/Rust")
+!4 = !{}
+!5 = distinct !DISubprogram(name: "main", linkageName: "_ZN2e34mainE", scope: !6, file: !3, line: 2, type: !8, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped | DIFlagMainSubprogram, isOptimized: false, unit: !2, templateParams: !4, variables: !4)
+!6 = !DINamespace(name: "e3", scope: null)
+!7 = !DIFile(filename: "<unknown>", directory: "")
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !DILocalVariable(name: "qq", scope: !11, file: !3, line: 3, type: !12, align: 8)
+!11 = distinct !DILexicalBlock(scope: !5, file: !3, line: 3, column: 4)
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "F", scope: !6, file: !7, size: 128, align: 64, elements: !13, identifier: "7ce1efff6b82281ab9ceb730566e7e20")
+!13 = !{!14}
+!14 = !DICompositeType(tag: DW_TAG_variant_part, name: "", scope: !12, file: !7, size: 128, align: 64, elements: !16, identifier: "7ce1efff6b82281ab9ceb730566e7e20", discriminator: !15)
+!15 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !27, size: 64, align: 64, flags: DIFlagArtificial)
+!16 = !{!17, !24}
+!17 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !18, size: 128, align: 64)
+!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "Yep", scope: !12, file: !7, size: 128, align: 64, elements: !19, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Yep")
+!19 = !{!20, !22}
+!20 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !18, file: !7, baseType: !21, size: 8, align: 8, offset: 64)
+!21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !7, baseType: !23, size: 64, align: 64)
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64)
+!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i64 0)
+!25 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nope", scope: !12, file: !7, size: 128, align: 64, elements: !4, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Nope")
+!27 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
+!28 = !DIExpression()
+!29 = !DILocation(line: 3, scope: !11)
+!30 = !DILocation(line: 4, scope: !5)
Added: llvm/trunk/test/DebugInfo/Generic/univariant-discriminated-union.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/univariant-discriminated-union.ll?rev=324426&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/univariant-discriminated-union.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/univariant-discriminated-union.ll Tue Feb 6 15:45:59 2018
@@ -0,0 +1,65 @@
+; REQUIRES: object-emission
+
+; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t
+; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck %s
+
+; Check for a univariant discriminated union -- that is, a variant
+; part without a discriminant and with just a single variant.
+
+; CHECK: DW_TAG_variant_part
+; CHECK-NOT: DW_AT_discr
+; CHECK: DW_TAG_variant
+; CHECK: DW_TAG_member
+; CHECK: DW_AT_type
+; CHECK: DW_AT_alignment
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+
+%F = type { [0 x i8], {}*, [8 x i8] }
+%"F::Nope" = type {}
+
+define internal void @_ZN2e34main17h934ff72f9a38d4bbE() unnamed_addr #0 !dbg !5 {
+start:
+ %qq = alloca %F, align 8
+ call void @llvm.dbg.declare(metadata %F* %qq, metadata !10, metadata !28), !dbg !29
+ %0 = bitcast %F* %qq to {}**, !dbg !29
+ store {}* null, {}** %0, !dbg !29
+ %1 = bitcast %F* %qq to %"F::Nope"*, !dbg !29
+ ret void, !dbg !30
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+
+attributes #0 = { nounwind uwtable }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+
+!0 = !{i32 1, !"PIE Level", i32 2}
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!2 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !3, producer: "clang LLVM (rustc version 1.24.0-dev)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
+!3 = !DIFile(filename: "e3.rs", directory: "/home/tromey/Rust")
+!4 = !{}
+!5 = distinct !DISubprogram(name: "main", linkageName: "_ZN2e34mainE", scope: !6, file: !3, line: 2, type: !8, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped | DIFlagMainSubprogram, isOptimized: false, unit: !2, templateParams: !4, variables: !4)
+!6 = !DINamespace(name: "e3", scope: null)
+!7 = !DIFile(filename: "<unknown>", directory: "")
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !DILocalVariable(name: "qq", scope: !11, file: !3, line: 3, type: !12, align: 8)
+!11 = distinct !DILexicalBlock(scope: !5, file: !3, line: 3, column: 4)
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "F", scope: !6, file: !7, size: 128, align: 64, elements: !13, identifier: "7ce1efff6b82281ab9ceb730566e7e20")
+!13 = !{!14}
+!14 = !DICompositeType(tag: DW_TAG_variant_part, name: "", scope: !12, file: !7, size: 128, align: 64, elements: !16, identifier: "7ce1efff6b82281ab9ceb730566e7e20")
+
+!16 = !{!17}
+!17 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !18, size: 128, align: 64)
+!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "Yep", scope: !12, file: !7, size: 128, align: 64, elements: !19, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Yep")
+!19 = !{!20, !22}
+!20 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !18, file: !7, baseType: !21, size: 8, align: 8, offset: 64)
+!21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !7, baseType: !23, size: 64, align: 64)
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64)
+
+!28 = !DIExpression()
+!29 = !DILocation(line: 3, scope: !11)
+!30 = !DILocation(line: 4, scope: !5)
Added: llvm/trunk/test/Verifier/variant-part.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/variant-part.ll?rev=324426&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/variant-part.ll (added)
+++ llvm/trunk/test/Verifier/variant-part.ll Tue Feb 6 15:45:59 2018
@@ -0,0 +1,8 @@
+; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
+
+!named = !{!0}
+!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 64, discriminator: !1)
+!1 = !DIDerivedType(tag: DW_TAG_member, scope: !0, baseType: !3, size: 64, align: 64, flags: DIFlagArtificial)
+!3 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
+
+; CHECK: discriminator can only appear on variant part
Modified: llvm/trunk/unittests/IR/DebugTypeODRUniquingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/DebugTypeODRUniquingTest.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/DebugTypeODRUniquingTest.cpp (original)
+++ llvm/trunk/unittests/IR/DebugTypeODRUniquingTest.cpp Tue Feb 6 15:45:59 2018
@@ -30,7 +30,7 @@ TEST(DebugTypeODRUniquingTest, getODRTyp
// Without a type map, this should return null.
EXPECT_FALSE(DICompositeType::getODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
- nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr));
+ nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr));
// Enable the mapping. There still shouldn't be a type.
Context.enableDebugTypeODRUniquing();
@@ -39,7 +39,7 @@ TEST(DebugTypeODRUniquingTest, getODRTyp
// Create some ODR-uniqued type.
auto &CT = *DICompositeType::getODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
- nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
+ nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr);
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
// Check that we get it back, even if we change a field.
@@ -47,12 +47,12 @@ TEST(DebugTypeODRUniquingTest, getODRTyp
EXPECT_EQ(&CT, DICompositeType::getODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
- nullptr, nullptr));
+ nullptr, nullptr, nullptr));
EXPECT_EQ(&CT,
DICompositeType::getODRType(
Context, UUID, dwarf::DW_TAG_class_type,
MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0,
- 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr));
+ 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr));
// Check that it's discarded with the type map.
Context.disableDebugTypeODRUniquing();
@@ -71,32 +71,32 @@ TEST(DebugTypeODRUniquingTest, buildODRT
MDString &UUID = *MDString::get(Context, "Type");
auto &CT = *DICompositeType::buildODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
- nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
+ nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr);
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
// Update with another forward decl. This should be a no-op.
EXPECT_EQ(&CT, DICompositeType::buildODRType(
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
- nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
+ nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr));
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
// Update with a definition. This time we should see a change.
EXPECT_EQ(&CT, DICompositeType::buildODRType(
Context, UUID, dwarf::DW_TAG_structure_type, nullptr,
nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero,
- nullptr, 0, nullptr, nullptr));
+ nullptr, 0, nullptr, nullptr, nullptr));
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
// Further updates should be ignored.
EXPECT_EQ(&CT, DICompositeType::buildODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
- nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
+ nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr));
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
EXPECT_EQ(&CT, DICompositeType::buildODRType(
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
- nullptr, nullptr));
+ nullptr, nullptr, nullptr));
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
}
@@ -108,7 +108,7 @@ TEST(DebugTypeODRUniquingTest, buildODRT
MDString &UUID = *MDString::get(Context, "UUID");
auto &CT = *DICompositeType::buildODRType(
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
- DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
+ DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr);
// Create macros for running through all the fields except Identifier and Flags.
#define FOR_EACH_MDFIELD() \
@@ -141,7 +141,7 @@ TEST(DebugTypeODRUniquingTest, buildODRT
DICompositeType::buildODRType(
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
- Elements, RuntimeLang, VTableHolder, TemplateParams));
+ Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr));
// Confirm that all the right fields got updated.
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=324426&r1=324425&r2=324426&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Tue Feb 6 15:45:59 2018
@@ -1355,6 +1355,51 @@ TEST_F(DICompositeTypeTest, replaceOpera
EXPECT_EQ(nullptr, N->getTemplateParams().get());
}
+TEST_F(DICompositeTypeTest, variant_part) {
+ unsigned Tag = dwarf::DW_TAG_variant_part;
+ StringRef Name = "some name";
+ DIFile *File = getFile();
+ unsigned Line = 1;
+ DIScope *Scope = getSubprogram();
+ DIType *BaseType = getCompositeType();
+ uint64_t SizeInBits = 2;
+ uint32_t AlignInBits = 3;
+ uint64_t OffsetInBits = 4;
+ DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
+ unsigned RuntimeLang = 6;
+ StringRef Identifier = "some id";
+ DIDerivedType *Discriminator = cast<DIDerivedType>(getDerivedType());
+ DIDerivedType *Discriminator2 = cast<DIDerivedType>(getDerivedType());
+
+ EXPECT_NE(Discriminator, Discriminator2);
+
+ auto *N = DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
+ Discriminator);
+
+ // Test the hashing.
+ auto *Same = DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
+ Discriminator);
+ auto *Other = DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
+ Discriminator2);
+ auto *NoDisc = DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
+ nullptr);
+
+ EXPECT_EQ(N, Same);
+ EXPECT_NE(Same, Other);
+ EXPECT_NE(Same, NoDisc);
+ EXPECT_NE(Other, NoDisc);
+
+ EXPECT_EQ(N->getDiscriminator(), Discriminator);
+}
+
typedef MetadataTest DISubroutineTypeTest;
TEST_F(DISubroutineTypeTest, get) {
More information about the llvm-commits
mailing list