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

Add DWARF for discriminated unions #118

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions include/llvm/IR/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,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.
Expand Down Expand Up @@ -376,6 +397,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.
Expand Down
31 changes: 21 additions & 10 deletions include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,12 @@ class DIDerivedType : public DIType {
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) {
Expand Down Expand Up @@ -861,27 +867,29 @@ 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,
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 = 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:
Expand All @@ -892,21 +900,22 @@ class DICompositeType : public DIType {
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,
uint64_t SizeInBits, uint32_t AlignInBits,
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(); }

Expand All @@ -923,7 +932,7 @@ class DICompositeType : public DIType {
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);

Expand All @@ -942,7 +951,7 @@ class DICompositeType : public DIType {
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 {
Expand All @@ -960,6 +969,8 @@ class DICompositeType : public DIType {
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.
///
Expand Down
8 changes: 5 additions & 3 deletions lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4068,7 +4068,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
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

Expand All @@ -4078,7 +4079,7 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
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;
}
Expand All @@ -4089,7 +4090,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
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;
}

Expand Down
12 changes: 0 additions & 12 deletions lib/BinaryFormat/Dwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,16 +393,6 @@ StringRef llvm::dwarf::ArrayOrderString(unsigned Order) {
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:
Expand Down Expand Up @@ -560,8 +550,6 @@ StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
return InlineCodeString(Val);
case DW_AT_ordering:
return ArrayOrderString(Val);
case DW_AT_discr_value:
return DiscriminantString(Val);
}

return StringRef();
Expand Down
7 changes: 5 additions & 2 deletions lib/Bitcode/Reader/MetadataLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
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
Expand All @@ -1258,6 +1258,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
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
Expand All @@ -1278,13 +1279,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
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)
Expand Down
1 change: 1 addition & 0 deletions lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
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();
Expand Down
36 changes: 35 additions & 1 deletion lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,24 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
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) {
Expand All @@ -933,6 +948,18 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
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);
}
Expand All @@ -952,6 +979,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
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);
}
}
}

Expand Down Expand Up @@ -1385,7 +1417,7 @@ void DwarfUnit::constructContainingTypeDIEs() {
}
}

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())
Expand Down Expand Up @@ -1490,6 +1522,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {

if (DT->isArtificial())
addFlag(MemberDie, dwarf::DW_AT_artificial);

return MemberDie;
}

DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {
Expand Down
2 changes: 1 addition & 1 deletion lib/CodeGen/AsmPrinter/DwarfUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ class DwarfUnit : public DIEUnit {
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,
Expand Down
1 change: 1 addition & 0 deletions lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printString("identifier", N->getIdentifier());
Printer.printMetadata("discriminator", N->getRawDiscriminator());
Out << ")";
}

Expand Down
25 changes: 25 additions & 0 deletions lib/IR/DIBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,19 @@ static ConstantAsMetadata *getConstantOrNull(Constant *C) {
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,
Expand Down Expand Up @@ -458,6 +471,18 @@ DICompositeType *DIBuilder::createUnionType(
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,
unsigned CC) {
Expand Down
Loading