Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 7a5f6ca

Browse files
authored
Merge pull request #118 from tromey/variant-part-backport
Add DWARF for discriminated unions
2 parents 9ad4b7e + 9a09a46 commit 7a5f6ca

19 files changed

+380
-56
lines changed

include/llvm/IR/DIBuilder.h

+42
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,27 @@ namespace llvm {
255255
uint64_t OffsetInBits,
256256
DINode::DIFlags Flags, DIType *Ty);
257257

258+
/// Create debugging information entry for a variant. A variant
259+
/// normally should be a member of a variant part.
260+
/// \param Scope Member scope.
261+
/// \param Name Member name.
262+
/// \param File File where this member is defined.
263+
/// \param LineNo Line number.
264+
/// \param SizeInBits Member size.
265+
/// \param AlignInBits Member alignment.
266+
/// \param OffsetInBits Member offset.
267+
/// \param Flags Flags to encode member attribute, e.g. private
268+
/// \param Discriminant The discriminant for this branch; null for
269+
/// the default branch
270+
/// \param Ty Parent type.
271+
DIDerivedType *createVariantMemberType(DIScope *Scope, StringRef Name,
272+
DIFile *File, unsigned LineNo,
273+
uint64_t SizeInBits,
274+
uint32_t AlignInBits,
275+
uint64_t OffsetInBits,
276+
Constant *Discriminant,
277+
DINode::DIFlags Flags, DIType *Ty);
278+
258279
/// Create debugging information entry for a bit field member.
259280
/// \param Scope Member scope.
260281
/// \param Name Member name.
@@ -376,6 +397,27 @@ namespace llvm {
376397
unsigned RunTimeLang = 0,
377398
StringRef UniqueIdentifier = "");
378399

400+
/// Create debugging information entry for a variant part. A
401+
/// variant part normally has a discriminator (though this is not
402+
/// required) and a number of variant children.
403+
/// \param Scope Scope in which this union is defined.
404+
/// \param Name Union name.
405+
/// \param File File where this member is defined.
406+
/// \param LineNumber Line number.
407+
/// \param SizeInBits Member size.
408+
/// \param AlignInBits Member alignment.
409+
/// \param Flags Flags to encode member attribute, e.g. private
410+
/// \param Discriminator Discriminant member
411+
/// \param Elements Variant elements.
412+
/// \param UniqueIdentifier A unique identifier for the union.
413+
DICompositeType *createVariantPart(DIScope *Scope, StringRef Name,
414+
DIFile *File, unsigned LineNumber,
415+
uint64_t SizeInBits, uint32_t AlignInBits,
416+
DINode::DIFlags Flags,
417+
DIDerivedType *Discriminator,
418+
DINodeArray Elements,
419+
StringRef UniqueIdentifier = "");
420+
379421
/// Create debugging information for template
380422
/// type parameter.
381423
/// \param Scope Scope in which this type is defined.

include/llvm/IR/DebugInfoMetadata.h

+21-10
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,12 @@ class DIDerivedType : public DIType {
819819
return C->getValue();
820820
return nullptr;
821821
}
822+
Constant *getDiscriminantValue() const {
823+
assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
824+
if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
825+
return C->getValue();
826+
return nullptr;
827+
}
822828
/// @}
823829

824830
static bool classof(const Metadata *MD) {
@@ -861,27 +867,29 @@ class DICompositeType : public DIType {
861867
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
862868
DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
863869
DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
864-
StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
870+
StringRef Identifier, DIDerivedType *Discriminator,
871+
StorageType Storage, bool ShouldCreate = true) {
865872
return getImpl(
866873
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
867874
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
868875
RuntimeLang, VTableHolder, TemplateParams.get(),
869-
getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
876+
getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
870877
}
871878
static DICompositeType *
872879
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
873880
unsigned Line, Metadata *Scope, Metadata *BaseType,
874881
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
875882
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
876883
Metadata *VTableHolder, Metadata *TemplateParams,
877-
MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
884+
MDString *Identifier, Metadata *Discriminator,
885+
StorageType Storage, bool ShouldCreate = true);
878886

879887
TempDICompositeType cloneImpl() const {
880888
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
881889
getScope(), getBaseType(), getSizeInBits(),
882890
getAlignInBits(), getOffsetInBits(), getFlags(),
883891
getElements(), getRuntimeLang(), getVTableHolder(),
884-
getTemplateParams(), getIdentifier());
892+
getTemplateParams(), getIdentifier(), getDiscriminator());
885893
}
886894

887895
public:
@@ -892,21 +900,22 @@ class DICompositeType : public DIType {
892900
DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
893901
DITypeRef VTableHolder,
894902
DITemplateParameterArray TemplateParams = nullptr,
895-
StringRef Identifier = ""),
903+
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr),
896904
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
897905
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
898-
VTableHolder, TemplateParams, Identifier))
906+
VTableHolder, TemplateParams, Identifier, Discriminator))
899907
DEFINE_MDNODE_GET(DICompositeType,
900908
(unsigned Tag, MDString *Name, Metadata *File,
901909
unsigned Line, Metadata *Scope, Metadata *BaseType,
902910
uint64_t SizeInBits, uint32_t AlignInBits,
903911
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
904912
unsigned RuntimeLang, Metadata *VTableHolder,
905913
Metadata *TemplateParams = nullptr,
906-
MDString *Identifier = nullptr),
914+
MDString *Identifier = nullptr,
915+
Metadata *Discriminator = nullptr),
907916
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
908917
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
909-
VTableHolder, TemplateParams, Identifier))
918+
VTableHolder, TemplateParams, Identifier, Discriminator))
910919

911920
TempDICompositeType clone() const { return cloneImpl(); }
912921

@@ -923,7 +932,7 @@ class DICompositeType : public DIType {
923932
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
924933
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
925934
unsigned RuntimeLang, Metadata *VTableHolder,
926-
Metadata *TemplateParams);
935+
Metadata *TemplateParams, Metadata *Discriminator);
927936
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
928937
MDString &Identifier);
929938

@@ -942,7 +951,7 @@ class DICompositeType : public DIType {
942951
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
943952
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
944953
unsigned RuntimeLang, Metadata *VTableHolder,
945-
Metadata *TemplateParams);
954+
Metadata *TemplateParams, Metadata *Discriminator);
946955

947956
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
948957
DINodeArray getElements() const {
@@ -960,6 +969,8 @@ class DICompositeType : public DIType {
960969
Metadata *getRawVTableHolder() const { return getOperand(5); }
961970
Metadata *getRawTemplateParams() const { return getOperand(6); }
962971
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
972+
Metadata *getRawDiscriminator() const { return getOperand(8); }
973+
DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
963974

964975
/// Replace operands.
965976
///

lib/AsmParser/LLParser.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -4068,7 +4068,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
40684068
OPTIONAL(runtimeLang, DwarfLangField, ); \
40694069
OPTIONAL(vtableHolder, MDField, ); \
40704070
OPTIONAL(templateParams, MDField, ); \
4071-
OPTIONAL(identifier, MDStringField, );
4071+
OPTIONAL(identifier, MDStringField, ); \
4072+
OPTIONAL(discriminator, MDField, );
40724073
PARSE_MD_FIELDS();
40734074
#undef VISIT_MD_FIELDS
40744075

@@ -4078,7 +4079,7 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
40784079
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
40794080
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
40804081
elements.Val, runtimeLang.Val, vtableHolder.Val,
4081-
templateParams.Val)) {
4082+
templateParams.Val, discriminator.Val)) {
40824083
Result = CT;
40834084
return false;
40844085
}
@@ -4089,7 +4090,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
40894090
DICompositeType,
40904091
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
40914092
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
4092-
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
4093+
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
4094+
discriminator.Val));
40934095
return false;
40944096
}
40954097

lib/BinaryFormat/Dwarf.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -393,16 +393,6 @@ StringRef llvm::dwarf::ArrayOrderString(unsigned Order) {
393393
return StringRef();
394394
}
395395

396-
StringRef llvm::dwarf::DiscriminantString(unsigned Discriminant) {
397-
switch (Discriminant) {
398-
case DW_DSC_label:
399-
return "DW_DSC_label";
400-
case DW_DSC_range:
401-
return "DW_DSC_range";
402-
}
403-
return StringRef();
404-
}
405-
406396
StringRef llvm::dwarf::LNStandardString(unsigned Standard) {
407397
switch (Standard) {
408398
default:
@@ -560,8 +550,6 @@ StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
560550
return InlineCodeString(Val);
561551
case DW_AT_ordering:
562552
return ArrayOrderString(Val);
563-
case DW_AT_discr_value:
564-
return DiscriminantString(Val);
565553
}
566554

567555
return StringRef();

lib/Bitcode/Reader/MetadataLoader.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
12351235
break;
12361236
}
12371237
case bitc::METADATA_COMPOSITE_TYPE: {
1238-
if (Record.size() != 16)
1238+
if (Record.size() < 16 || Record.size() > 17)
12391239
return error("Invalid record");
12401240

12411241
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1258,6 +1258,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
12581258
unsigned RuntimeLang = Record[12];
12591259
Metadata *VTableHolder = nullptr;
12601260
Metadata *TemplateParams = nullptr;
1261+
Metadata *Discriminator = nullptr;
12611262
auto *Identifier = getMDString(Record[15]);
12621263
// If this module is being parsed so that it can be ThinLTO imported
12631264
// into another module, composite types only need to be imported
@@ -1278,13 +1279,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
12781279
Elements = getMDOrNull(Record[11]);
12791280
VTableHolder = getDITypeRefOrNull(Record[13]);
12801281
TemplateParams = getMDOrNull(Record[14]);
1282+
if (Record.size() > 16)
1283+
Discriminator = getMDOrNull(Record[16]);
12811284
}
12821285
DICompositeType *CT = nullptr;
12831286
if (Identifier)
12841287
CT = DICompositeType::buildODRType(
12851288
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
12861289
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1287-
VTableHolder, TemplateParams);
1290+
VTableHolder, TemplateParams, Discriminator);
12881291

12891292
// Create a node if we didn't get a lazy ODR type.
12901293
if (!CT)

lib/Bitcode/Writer/BitcodeWriter.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
15211521
Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));
15221522
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
15231523
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
1524+
Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));
15241525

15251526
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
15261527
Record.clear();

lib/CodeGen/AsmPrinter/DwarfUnit.cpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -917,9 +917,24 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
917917
case dwarf::DW_TAG_enumeration_type:
918918
constructEnumTypeDIE(Buffer, CTy);
919919
break;
920+
case dwarf::DW_TAG_variant_part:
920921
case dwarf::DW_TAG_structure_type:
921922
case dwarf::DW_TAG_union_type:
922923
case dwarf::DW_TAG_class_type: {
924+
// Emit the discriminator for a variant part.
925+
DIDerivedType *Discriminator = nullptr;
926+
if (Tag == dwarf::DW_TAG_variant_part) {
927+
Discriminator = CTy->getDiscriminator();
928+
if (Discriminator) {
929+
// DWARF says:
930+
// If the variant part has a discriminant, the discriminant is
931+
// represented by a separate debugging information entry which is
932+
// a child of the variant part entry.
933+
DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
934+
addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
935+
}
936+
}
937+
923938
// Add elements to structure type.
924939
DINodeArray Elements = CTy->getElements();
925940
for (const auto *Element : Elements) {
@@ -933,6 +948,18 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
933948
addType(ElemDie, resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
934949
} else if (DDTy->isStaticMember()) {
935950
getOrCreateStaticMemberDIE(DDTy);
951+
} else if (Tag == dwarf::DW_TAG_variant_part) {
952+
// When emitting a variant part, wrap each member in
953+
// DW_TAG_variant.
954+
DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
955+
if (const ConstantInt *CI =
956+
dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
957+
if (isUnsignedDIType(DD, resolve(Discriminator->getBaseType())))
958+
addUInt(Variant, dwarf::DW_AT_discr_value, None, CI->getZExtValue());
959+
else
960+
addSInt(Variant, dwarf::DW_AT_discr_value, None, CI->getSExtValue());
961+
}
962+
constructMemberDIE(Variant, DDTy);
936963
} else {
937964
constructMemberDIE(Buffer, DDTy);
938965
}
@@ -952,6 +979,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
952979
if (unsigned PropertyAttributes = Property->getAttributes())
953980
addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None,
954981
PropertyAttributes);
982+
} else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
983+
if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
984+
DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer);
985+
constructTypeDIE(VariantPart, Composite);
986+
}
955987
}
956988
}
957989

@@ -1385,7 +1417,7 @@ void DwarfUnit::constructContainingTypeDIEs() {
13851417
}
13861418
}
13871419

1388-
void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
1420+
DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
13891421
DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);
13901422
StringRef Name = DT->getName();
13911423
if (!Name.empty())
@@ -1490,6 +1522,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
14901522

14911523
if (DT->isArtificial())
14921524
addFlag(MemberDie, dwarf::DW_AT_artificial);
1525+
1526+
return MemberDie;
14931527
}
14941528

14951529
DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {

lib/CodeGen/AsmPrinter/DwarfUnit.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ class DwarfUnit : public DIEUnit {
331331
void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
332332
void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
333333
void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
334-
void constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
334+
DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
335335
void constructTemplateTypeParameterDIE(DIE &Buffer,
336336
const DITemplateTypeParameter *TP);
337337
void constructTemplateValueParameterDIE(DIE &Buffer,

lib/IR/AsmWriter.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
16961696
Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
16971697
Printer.printMetadata("templateParams", N->getRawTemplateParams());
16981698
Printer.printString("identifier", N->getIdentifier());
1699+
Printer.printMetadata("discriminator", N->getRawDiscriminator());
16991700
Out << ")";
17001701
}
17011702

lib/IR/DIBuilder.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,19 @@ static ConstantAsMetadata *getConstantOrNull(Constant *C) {
333333
return nullptr;
334334
}
335335

336+
DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope, StringRef Name,
337+
DIFile *File, unsigned LineNumber,
338+
uint64_t SizeInBits,
339+
uint32_t AlignInBits,
340+
uint64_t OffsetInBits,
341+
Constant *Discriminant,
342+
DINode::DIFlags Flags, DIType *Ty) {
343+
return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
344+
LineNumber, getNonCompileUnitScope(Scope), Ty,
345+
SizeInBits, AlignInBits, OffsetInBits, None, Flags,
346+
getConstantOrNull(Discriminant));
347+
}
348+
336349
DIDerivedType *DIBuilder::createBitFieldMemberType(
337350
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
338351
uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,
@@ -458,6 +471,18 @@ DICompositeType *DIBuilder::createUnionType(
458471
return R;
459472
}
460473

474+
DICompositeType *DIBuilder::createVariantPart(
475+
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
476+
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
477+
DIDerivedType *Discriminator, DINodeArray Elements, StringRef UniqueIdentifier) {
478+
auto *R = DICompositeType::get(
479+
VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,
480+
getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,
481+
Elements, 0, nullptr, nullptr, UniqueIdentifier, Discriminator);
482+
trackIfUnresolved(R);
483+
return R;
484+
}
485+
461486
DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,
462487
DINode::DIFlags Flags,
463488
unsigned CC) {

0 commit comments

Comments
 (0)