Verifier: Check operands of MDType subclasses and MDCompileUnit

Add verify checks for `MDType` subclasses and for `MDCompileUnit`.
These new checks don't yet incorporate everything from `Verify()`, but
at least they sanity check the operands.  Also downcast accessors as
possible.

A lot of these accessors can't be downcast as far as we'd like because
of arrays of typed objects (stored in a generic `MDTuple`) and
`MDString`-based type references.  Eventually I'll port over `DIRef<>`
and `DITypedArray<>` from `DebugInfo.h` to clean those up as well.

Updated bitrotted testcases separately in r233415 and r233443 to reduce
churn on the off-chance this needs to be reverted.

llvm-svn: 233446
This commit is contained in:
Duncan P. N. Exon Smith 2015-03-27 23:05:04 +00:00
parent d9ccfb9e01
commit 53855f05d3
7 changed files with 278 additions and 154 deletions

View File

@ -57,11 +57,11 @@ namespace llvm {
Module &M; Module &M;
LLVMContext &VMContext; LLVMContext &VMContext;
MDNode *TempEnumTypes; MDTuple *TempEnumTypes;
MDNode *TempRetainTypes; MDTuple *TempRetainTypes;
MDNode *TempSubprograms; MDTuple *TempSubprograms;
MDNode *TempGVs; MDTuple *TempGVs;
MDNode *TempImportedModules; MDTuple *TempImportedModules;
Function *DeclareFn; // llvm.dbg.declare Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value Function *ValueFn; // llvm.dbg.value

View File

@ -282,13 +282,16 @@ protected:
~MDScope() {} ~MDScope() {}
public: public:
/// \brief Return the underlying file. // FIXME: Downcast to MDFile once we've verified all subclasses.
Metadata *getFile() const { return getRawFile(); }
/// \brief Return the raw underlying file.
/// ///
/// An \a MDFile is an \a MDScope, but it doesn't point at a separate file /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
/// (it\em is the file). If \c this is an \a MDFile, we need to return \c /// (it\em is the file). If \c this is an \a MDFile, we need to return \c
/// this. Otherwise, return the first operand, which is where all other /// this. Otherwise, return the first operand, which is where all other
/// subclasses store their file pointer. /// subclasses store their file pointer.
Metadata *getFile() const { Metadata *getRawFile() const {
return isa<MDFile>(this) ? const_cast<MDScope *>(this) return isa<MDFile>(this) ? const_cast<MDScope *>(this)
: static_cast<Metadata *>(getOperand(0)); : static_cast<Metadata *>(getOperand(0));
} }
@ -390,9 +393,14 @@ public:
uint64_t getOffsetInBits() const { return OffsetInBits; } uint64_t getOffsetInBits() const { return OffsetInBits; }
unsigned getFlags() const { return Flags; } unsigned getFlags() const { return Flags; }
Metadata *getScope() const { return getOperand(1); } // FIXME: Remove this once MDScope::getFile() does the same.
MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
Metadata *getScope() const { return getRawScope(); }
StringRef getName() const { return getStringOperand(2); } StringRef getName() const { return getStringOperand(2); }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); } MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(unsigned NewFlags) { void setFlags(unsigned NewFlags) {
@ -483,7 +491,8 @@ protected:
~MDDerivedTypeBase() {} ~MDDerivedTypeBase() {}
public: public:
Metadata *getBaseType() const { return getOperand(3); } Metadata *getBaseType() const { return getRawBaseType(); }
Metadata *getRawBaseType() const { return getOperand(3); }
static bool classof(const Metadata *MD) { static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDDerivedTypeKind || return MD->getMetadataID() == MDDerivedTypeKind ||
@ -510,7 +519,7 @@ class MDDerivedType : public MDDerivedTypeBase {
~MDDerivedType() {} ~MDDerivedType() {}
static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag, static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, Metadata *File, unsigned Line, StringRef Name, MDFile *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint64_t AlignInBits, uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags, uint64_t OffsetInBits, unsigned Flags,
@ -545,7 +554,7 @@ public:
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData)) AlignInBits, OffsetInBits, Flags, ExtraData))
DEFINE_MDNODE_GET(MDDerivedType, DEFINE_MDNODE_GET(MDDerivedType,
(unsigned Tag, StringRef Name, Metadata *File, (unsigned Tag, StringRef Name, MDFile *File,
unsigned Line, Metadata *Scope, Metadata *BaseType, unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint64_t AlignInBits, uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags, uint64_t OffsetInBits, unsigned Flags,
@ -562,7 +571,8 @@ public:
/// ///
/// TODO: Separate out types that need this extra operand: pointer-to-member /// TODO: Separate out types that need this extra operand: pointer-to-member
/// types and member fields (static members and ivars). /// types and member fields (static members and ivars).
Metadata *getExtraData() const { return getOperand(4); } Metadata *getExtraData() const { return getRawExtraData(); }
Metadata *getRawExtraData() const { return getOperand(4); }
static bool classof(const Metadata *MD) { static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDDerivedTypeKind; return MD->getMetadataID() == MDDerivedTypeKind;
@ -587,12 +597,19 @@ protected:
~MDCompositeTypeBase() {} ~MDCompositeTypeBase() {}
public: public:
Metadata *getElements() const { return getOperand(4); } MDTuple *getElements() const {
Metadata *getVTableHolder() const { return getOperand(5); } return cast_or_null<MDTuple>(getRawElements());
Metadata *getTemplateParams() const { return getOperand(6); } }
Metadata *getVTableHolder() const { return getRawVTableHolder(); }
MDTuple *getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
StringRef getIdentifier() const { return getStringOperand(7); } StringRef getIdentifier() const { return getStringOperand(7); }
unsigned getRuntimeLang() const { return RuntimeLang; } unsigned getRuntimeLang() const { return RuntimeLang; }
Metadata *getRawElements() const { return getOperand(4); }
Metadata *getRawVTableHolder() const { return getOperand(5); }
Metadata *getRawTemplateParams() const { return getOperand(6); }
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); } MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
/// \brief Replace operands. /// \brief Replace operands.
@ -730,7 +747,8 @@ public:
TempMDSubroutineType clone() const { return cloneImpl(); } TempMDSubroutineType clone() const { return cloneImpl(); }
Metadata *getTypeArray() const { return getElements(); } MDTuple *getTypeArray() const { return getElements(); }
Metadata *getRawTypeArray() const { return getRawElements(); }
static bool classof(const Metadata *MD) { static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDSubroutineTypeKind; return MD->getMetadataID() == MDSubroutineTypeKind;
@ -756,12 +774,12 @@ class MDCompileUnit : public MDScope {
~MDCompileUnit() {} ~MDCompileUnit() {}
static MDCompileUnit * static MDCompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
StringRef Producer, bool IsOptimized, StringRef Flags, StringRef Producer, bool IsOptimized, StringRef Flags,
unsigned RuntimeVersion, StringRef SplitDebugFilename, unsigned RuntimeVersion, StringRef SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, unsigned EmissionKind, MDTuple *EnumTypes, MDTuple *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables, MDTuple *Subprograms, MDTuple *GlobalVariables,
Metadata *ImportedEntities, StorageType Storage, MDTuple *ImportedEntities, StorageType Storage,
bool ShouldCreate = true) { bool ShouldCreate = true) {
return getImpl(Context, SourceLanguage, File, return getImpl(Context, SourceLanguage, File,
getCanonicalMDString(Context, Producer), IsOptimized, getCanonicalMDString(Context, Producer), IsOptimized,
@ -789,12 +807,12 @@ class MDCompileUnit : public MDScope {
public: public:
DEFINE_MDNODE_GET(MDCompileUnit, DEFINE_MDNODE_GET(MDCompileUnit,
(unsigned SourceLanguage, Metadata *File, (unsigned SourceLanguage, MDFile *File, StringRef Producer,
StringRef Producer, bool IsOptimized, StringRef Flags, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
unsigned RuntimeVersion, StringRef SplitDebugFilename, StringRef SplitDebugFilename, unsigned EmissionKind,
unsigned EmissionKind, Metadata *EnumTypes, MDTuple *EnumTypes, MDTuple *RetainedTypes,
Metadata *RetainedTypes, Metadata *Subprograms, MDTuple *Subprograms, MDTuple *GlobalVariables,
Metadata *GlobalVariables, Metadata *ImportedEntities), MDTuple *ImportedEntities),
(SourceLanguage, File, Producer, IsOptimized, Flags, (SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, RuntimeVersion, SplitDebugFilename, EmissionKind,
EnumTypes, RetainedTypes, Subprograms, GlobalVariables, EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
@ -813,6 +831,9 @@ public:
TempMDCompileUnit clone() const { return cloneImpl(); } TempMDCompileUnit clone() const { return cloneImpl(); }
// FIXME: Remove this once MDScope::getFile() does the same.
MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
unsigned getSourceLanguage() const { return SourceLanguage; } unsigned getSourceLanguage() const { return SourceLanguage; }
bool isOptimized() const { return IsOptimized; } bool isOptimized() const { return IsOptimized; }
unsigned getRuntimeVersion() const { return RuntimeVersion; } unsigned getRuntimeVersion() const { return RuntimeVersion; }
@ -820,17 +841,32 @@ public:
StringRef getProducer() const { return getStringOperand(1); } StringRef getProducer() const { return getStringOperand(1); }
StringRef getFlags() const { return getStringOperand(2); } StringRef getFlags() const { return getStringOperand(2); }
StringRef getSplitDebugFilename() const { return getStringOperand(3); } StringRef getSplitDebugFilename() const { return getStringOperand(3); }
Metadata *getEnumTypes() const { return getOperand(4); } MDTuple *getEnumTypes() const {
Metadata *getRetainedTypes() const { return getOperand(5); } return cast_or_null<MDTuple>(getRawEnumTypes());
Metadata *getSubprograms() const { return getOperand(6); } }
Metadata *getGlobalVariables() const { return getOperand(7); } MDTuple *getRetainedTypes() const {
Metadata *getImportedEntities() const { return getOperand(8); } return cast_or_null<MDTuple>(getRawRetainedTypes());
}
MDTuple *getSubprograms() const {
return cast_or_null<MDTuple>(getRawSubprograms());
}
MDTuple *getGlobalVariables() const {
return cast_or_null<MDTuple>(getRawGlobalVariables());
}
MDTuple *getImportedEntities() const {
return cast_or_null<MDTuple>(getRawImportedEntities());
}
MDString *getRawProducer() const { return getOperandAs<MDString>(1); } MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
MDString *getRawFlags() const { return getOperandAs<MDString>(2); } MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
MDString *getRawSplitDebugFilename() const { MDString *getRawSplitDebugFilename() const {
return getOperandAs<MDString>(3); return getOperandAs<MDString>(3);
} }
Metadata *getRawEnumTypes() const { return getOperand(4); }
Metadata *getRawRetainedTypes() const { return getOperand(5); }
Metadata *getRawSubprograms() const { return getOperand(6); }
Metadata *getRawGlobalVariables() const { return getOperand(7); }
Metadata *getRawImportedEntities() const { return getOperand(8); }
/// \brief Replace arrays. /// \brief Replace arrays.
/// ///

View File

@ -1539,16 +1539,16 @@ static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printTag(N); Printer.printTag(N);
Printer.printString("name", N->getName()); Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getScope()); Printer.printMetadata("scope", N->getRawScope());
Printer.printMetadata("file", N->getFile()); Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine()); Printer.printInt("line", N->getLine());
Printer.printMetadata("baseType", N->getBaseType(), Printer.printMetadata("baseType", N->getRawBaseType(),
/* ShouldSkipNull */ false); /* ShouldSkipNull */ false);
Printer.printInt("size", N->getSizeInBits()); Printer.printInt("size", N->getSizeInBits());
Printer.printInt("align", N->getAlignInBits()); Printer.printInt("align", N->getAlignInBits());
Printer.printInt("offset", N->getOffsetInBits()); Printer.printInt("offset", N->getOffsetInBits());
Printer.printDIFlags("flags", N->getFlags()); Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("extraData", N->getExtraData()); Printer.printMetadata("extraData", N->getRawExtraData());
Out << ")"; Out << ")";
} }
@ -1559,19 +1559,19 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printTag(N); Printer.printTag(N);
Printer.printString("name", N->getName()); Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getScope()); Printer.printMetadata("scope", N->getRawScope());
Printer.printMetadata("file", N->getFile()); Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine()); Printer.printInt("line", N->getLine());
Printer.printMetadata("baseType", N->getBaseType()); Printer.printMetadata("baseType", N->getRawBaseType());
Printer.printInt("size", N->getSizeInBits()); Printer.printInt("size", N->getSizeInBits());
Printer.printInt("align", N->getAlignInBits()); Printer.printInt("align", N->getAlignInBits());
Printer.printInt("offset", N->getOffsetInBits()); Printer.printInt("offset", N->getOffsetInBits());
Printer.printDIFlags("flags", N->getFlags()); Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("elements", N->getElements()); Printer.printMetadata("elements", N->getRawElements());
Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(), Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
dwarf::LanguageString); dwarf::LanguageString);
Printer.printMetadata("vtableHolder", N->getVTableHolder()); Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
Printer.printMetadata("templateParams", N->getTemplateParams()); Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printString("identifier", N->getIdentifier()); Printer.printString("identifier", N->getIdentifier());
Out << ")"; Out << ")";
} }
@ -1582,7 +1582,8 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
Out << "!MDSubroutineType("; Out << "!MDSubroutineType(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printDIFlags("flags", N->getFlags()); Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("types", N->getTypeArray(), /* ShouldSkipNull */ false); Printer.printMetadata("types", N->getRawTypeArray(),
/* ShouldSkipNull */ false);
Out << ")"; Out << ")";
} }
@ -1604,7 +1605,7 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printDwarfEnum("language", N->getSourceLanguage(), Printer.printDwarfEnum("language", N->getSourceLanguage(),
dwarf::LanguageString, /* ShouldSkipZero */ false); dwarf::LanguageString, /* ShouldSkipZero */ false);
Printer.printMetadata("file", N->getFile(), /* ShouldSkipNull */ false); Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
Printer.printString("producer", N->getProducer()); Printer.printString("producer", N->getProducer());
Printer.printBool("isOptimized", N->isOptimized()); Printer.printBool("isOptimized", N->isOptimized());
Printer.printString("flags", N->getFlags()); Printer.printString("flags", N->getFlags());
@ -1613,11 +1614,11 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
Printer.printString("splitDebugFilename", N->getSplitDebugFilename()); Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
Printer.printInt("emissionKind", N->getEmissionKind(), Printer.printInt("emissionKind", N->getEmissionKind(),
/* ShouldSkipZero */ false); /* ShouldSkipZero */ false);
Printer.printMetadata("enums", N->getEnumTypes()); Printer.printMetadata("enums", N->getRawEnumTypes());
Printer.printMetadata("retainedTypes", N->getRetainedTypes()); Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
Printer.printMetadata("subprograms", N->getSubprograms()); Printer.printMetadata("subprograms", N->getRawSubprograms());
Printer.printMetadata("globals", N->getGlobalVariables()); Printer.printMetadata("globals", N->getRawGlobalVariables());
Printer.printMetadata("imports", N->getImportedEntities()); Printer.printMetadata("imports", N->getRawImportedEntities());
Out << ")"; Out << ")";
} }

View File

@ -269,8 +269,8 @@ DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) {
DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File,
unsigned LineNo, DIDescriptor Context) { unsigned LineNo, DIDescriptor Context) {
return MDDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, return MDDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,
File.getFileNode(), LineNo, LineNo,
DIScope(getNonCompileUnitScope(Context)).getRef(), DIScope(getNonCompileUnitScope(Context)).getRef(),
Ty.getRef(), 0, 0, 0, 0); Ty.getRef(), 0, 0, 0, 0);
} }

View File

@ -347,20 +347,20 @@ template <> struct MDNodeKeyImpl<MDDerivedType> {
BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits), BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {} OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {}
MDNodeKeyImpl(const MDDerivedType *N) MDNodeKeyImpl(const MDDerivedType *N)
: Tag(N->getTag()), Name(N->getName()), File(N->getFile()), : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()), Line(N->getLine()), Scope(N->getRawScope()),
SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
ExtraData(N->getExtraData()) {} Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {}
bool isKeyOf(const MDDerivedType *RHS) const { bool isKeyOf(const MDDerivedType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() && return Tag == RHS->getTag() && Name == RHS->getName() &&
File == RHS->getFile() && Line == RHS->getLine() && File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getScope() && BaseType == RHS->getBaseType() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() && SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() && AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() && OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
ExtraData == RHS->getExtraData(); ExtraData == RHS->getRawExtraData();
} }
unsigned getHashValue() const { unsigned getHashValue() const {
return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits, return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
@ -397,26 +397,26 @@ template <> struct MDNodeKeyImpl<MDCompositeType> {
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
TemplateParams(TemplateParams), Identifier(Identifier) {} TemplateParams(TemplateParams), Identifier(Identifier) {}
MDNodeKeyImpl(const MDCompositeType *N) MDNodeKeyImpl(const MDCompositeType *N)
: Tag(N->getTag()), Name(N->getName()), File(N->getFile()), : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()), Line(N->getLine()), Scope(N->getRawScope()),
SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
Elements(N->getElements()), RuntimeLang(N->getRuntimeLang()), Flags(N->getFlags()), Elements(N->getRawElements()),
VTableHolder(N->getVTableHolder()), RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
TemplateParams(N->getTemplateParams()), Identifier(N->getIdentifier()) { TemplateParams(N->getRawTemplateParams()),
} Identifier(N->getIdentifier()) {}
bool isKeyOf(const MDCompositeType *RHS) const { bool isKeyOf(const MDCompositeType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() && return Tag == RHS->getTag() && Name == RHS->getName() &&
File == RHS->getFile() && Line == RHS->getLine() && File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getScope() && BaseType == RHS->getBaseType() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() && SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() && AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() && OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
Elements == RHS->getElements() && Elements == RHS->getRawElements() &&
RuntimeLang == RHS->getRuntimeLang() && RuntimeLang == RHS->getRuntimeLang() &&
VTableHolder == RHS->getVTableHolder() && VTableHolder == RHS->getRawVTableHolder() &&
TemplateParams == RHS->getTemplateParams() && TemplateParams == RHS->getRawTemplateParams() &&
Identifier == RHS->getIdentifier(); Identifier == RHS->getIdentifier();
} }
unsigned getHashValue() const { unsigned getHashValue() const {
@ -433,10 +433,10 @@ template <> struct MDNodeKeyImpl<MDSubroutineType> {
MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray) MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray)
: Flags(Flags), TypeArray(TypeArray) {} : Flags(Flags), TypeArray(TypeArray) {}
MDNodeKeyImpl(const MDSubroutineType *N) MDNodeKeyImpl(const MDSubroutineType *N)
: Flags(N->getFlags()), TypeArray(N->getTypeArray()) {} : Flags(N->getFlags()), TypeArray(N->getRawTypeArray()) {}
bool isKeyOf(const MDSubroutineType *RHS) const { bool isKeyOf(const MDSubroutineType *RHS) const {
return Flags == RHS->getFlags() && TypeArray == RHS->getTypeArray(); return Flags == RHS->getFlags() && TypeArray == RHS->getRawTypeArray();
} }
unsigned getHashValue() const { return hash_combine(Flags, TypeArray); } unsigned getHashValue() const { return hash_combine(Flags, TypeArray); }
}; };
@ -484,27 +484,28 @@ template <> struct MDNodeKeyImpl<MDCompileUnit> {
Subprograms(Subprograms), GlobalVariables(GlobalVariables), Subprograms(Subprograms), GlobalVariables(GlobalVariables),
ImportedEntities(ImportedEntities) {} ImportedEntities(ImportedEntities) {}
MDNodeKeyImpl(const MDCompileUnit *N) MDNodeKeyImpl(const MDCompileUnit *N)
: SourceLanguage(N->getSourceLanguage()), File(N->getFile()), : SourceLanguage(N->getSourceLanguage()), File(N->getRawFile()),
Producer(N->getProducer()), IsOptimized(N->isOptimized()), Producer(N->getProducer()), IsOptimized(N->isOptimized()),
Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()), Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()),
SplitDebugFilename(N->getSplitDebugFilename()), SplitDebugFilename(N->getSplitDebugFilename()),
EmissionKind(N->getEmissionKind()), EnumTypes(N->getEnumTypes()), EmissionKind(N->getEmissionKind()), EnumTypes(N->getRawEnumTypes()),
RetainedTypes(N->getRetainedTypes()), Subprograms(N->getSubprograms()), RetainedTypes(N->getRawRetainedTypes()),
GlobalVariables(N->getGlobalVariables()), Subprograms(N->getRawSubprograms()),
ImportedEntities(N->getImportedEntities()) {} GlobalVariables(N->getRawGlobalVariables()),
ImportedEntities(N->getRawImportedEntities()) {}
bool isKeyOf(const MDCompileUnit *RHS) const { bool isKeyOf(const MDCompileUnit *RHS) const {
return SourceLanguage == RHS->getSourceLanguage() && return SourceLanguage == RHS->getSourceLanguage() &&
File == RHS->getFile() && Producer == RHS->getProducer() && File == RHS->getRawFile() && Producer == RHS->getProducer() &&
IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() &&
RuntimeVersion == RHS->getRuntimeVersion() && RuntimeVersion == RHS->getRuntimeVersion() &&
SplitDebugFilename == RHS->getSplitDebugFilename() && SplitDebugFilename == RHS->getSplitDebugFilename() &&
EmissionKind == RHS->getEmissionKind() && EmissionKind == RHS->getEmissionKind() &&
EnumTypes == RHS->getEnumTypes() && EnumTypes == RHS->getRawEnumTypes() &&
RetainedTypes == RHS->getRetainedTypes() && RetainedTypes == RHS->getRawRetainedTypes() &&
Subprograms == RHS->getSubprograms() && Subprograms == RHS->getRawSubprograms() &&
GlobalVariables == RHS->getGlobalVariables() && GlobalVariables == RHS->getRawGlobalVariables() &&
ImportedEntities == RHS->getImportedEntities(); ImportedEntities == RHS->getRawImportedEntities();
} }
unsigned getHashValue() const { unsigned getHashValue() const {
return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags, return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags,

View File

@ -298,6 +298,8 @@ private:
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
void visitMDScope(const MDScope &N);
void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
void visitMDVariable(const MDVariable &N); void visitMDVariable(const MDVariable &N);
// InstVisitor overrides... // InstVisitor overrides...
@ -668,6 +670,15 @@ static bool isTypeRef(const Metadata *MD) {
return isa<MDType>(MD); return isa<MDType>(MD);
} }
/// \brief Check if a value can be a ScopeRef.
static bool isScopeRef(const Metadata *MD) {
if (!MD)
return true;
if (auto *S = dyn_cast<MDString>(MD))
return !S->getString().empty();
return isa<MDScope>(MD);
}
void Verifier::visitMDLocation(const MDLocation &N) { void Verifier::visitMDLocation(const MDLocation &N) {
Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()), Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
"location requires a valid scope", &N, N.getRawScope()); "location requires a valid scope", &N, N.getRawScope());
@ -679,8 +690,14 @@ void Verifier::visitGenericDebugNode(const GenericDebugNode &N) {
Assert(N.getTag(), "invalid tag", &N); Assert(N.getTag(), "invalid tag", &N);
} }
void Verifier::visitMDScope(const MDScope &N) {
if (auto *F = N.getRawFile())
Assert(isa<MDFile>(F), "invalid file", &N, F);
}
void Verifier::visitMDSubrange(const MDSubrange &N) { void Verifier::visitMDSubrange(const MDSubrange &N) {
Assert(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N); Assert(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N);
Assert(N.getCount() >= -1, "invalid subrange count", &N);
} }
void Verifier::visitMDEnumerator(const MDEnumerator &N) { void Verifier::visitMDEnumerator(const MDEnumerator &N) {
@ -693,7 +710,18 @@ void Verifier::visitMDBasicType(const MDBasicType &N) {
"invalid tag", &N); "invalid tag", &N);
} }
void Verifier::visitMDDerivedTypeBase(const MDDerivedTypeBase &N) {
// Common scope checks.
visitMDScope(N);
Assert(isScopeRef(N.getScope()), "invalid scope", &N, N.getScope());
Assert(isTypeRef(N.getBaseType()), "invalid base type", &N, N.getBaseType());
}
void Verifier::visitMDDerivedType(const MDDerivedType &N) { void Verifier::visitMDDerivedType(const MDDerivedType &N) {
// Common derived type checks.
visitMDDerivedTypeBase(N);
Assert(N.getTag() == dwarf::DW_TAG_typedef || Assert(N.getTag() == dwarf::DW_TAG_typedef ||
N.getTag() == dwarf::DW_TAG_pointer_type || N.getTag() == dwarf::DW_TAG_pointer_type ||
N.getTag() == dwarf::DW_TAG_ptr_to_member_type || N.getTag() == dwarf::DW_TAG_ptr_to_member_type ||
@ -709,6 +737,9 @@ void Verifier::visitMDDerivedType(const MDDerivedType &N) {
} }
void Verifier::visitMDCompositeType(const MDCompositeType &N) { void Verifier::visitMDCompositeType(const MDCompositeType &N) {
// Common derived type checks.
visitMDDerivedTypeBase(N);
Assert(N.getTag() == dwarf::DW_TAG_array_type || Assert(N.getTag() == dwarf::DW_TAG_array_type ||
N.getTag() == dwarf::DW_TAG_structure_type || N.getTag() == dwarf::DW_TAG_structure_type ||
N.getTag() == dwarf::DW_TAG_union_type || N.getTag() == dwarf::DW_TAG_union_type ||
@ -716,10 +747,24 @@ void Verifier::visitMDCompositeType(const MDCompositeType &N) {
N.getTag() == dwarf::DW_TAG_subroutine_type || N.getTag() == dwarf::DW_TAG_subroutine_type ||
N.getTag() == dwarf::DW_TAG_class_type, N.getTag() == dwarf::DW_TAG_class_type,
"invalid tag", &N); "invalid tag", &N);
Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
"invalid composite elements", &N, N.getRawElements());
Assert(isTypeRef(N.getRawVTableHolder()), "invalid vtable holder", &N,
N.getRawVTableHolder());
Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
"invalid composite elements", &N, N.getRawElements());
} }
void Verifier::visitMDSubroutineType(const MDSubroutineType &N) { void Verifier::visitMDSubroutineType(const MDSubroutineType &N) {
Assert(N.getTag() == dwarf::DW_TAG_subroutine_type, "invalid tag", &N); Assert(N.getTag() == dwarf::DW_TAG_subroutine_type, "invalid tag", &N);
Assert(N.getRawElements() && isa<MDTuple>(N.getRawElements()),
"invalid composite elements", &N, N.getRawElements());
for (Metadata *Ty : N.getTypeArray()->operands()) {
Assert(isTypeRef(Ty), "invalid subroutine type ref", &N, N.getTypeArray(),
Ty);
}
} }
void Verifier::visitMDFile(const MDFile &N) { void Verifier::visitMDFile(const MDFile &N) {
@ -728,6 +773,41 @@ void Verifier::visitMDFile(const MDFile &N) {
void Verifier::visitMDCompileUnit(const MDCompileUnit &N) { void Verifier::visitMDCompileUnit(const MDCompileUnit &N) {
Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N); Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N);
if (auto *Array = N.getRawEnumTypes()) {
Assert(isa<MDTuple>(Array), "invalid enum list", &N, Array);
for (Metadata *Op : N.getEnumTypes()->operands()) {
auto *Enum = dyn_cast_or_null<MDCompositeType>(Op);
Assert(Enum && Enum->getTag() == dwarf::DW_TAG_enumeration_type,
"invalid enum type", &N, N.getEnumTypes(), Op);
}
}
if (auto *Array = N.getRawRetainedTypes()) {
Assert(isa<MDTuple>(Array), "invalid retained type list", &N, Array);
for (Metadata *Op : N.getRetainedTypes()->operands()) {
Assert(Op && isa<MDType>(Op), "invalid retained type", &N, Op);
}
}
if (auto *Array = N.getRawSubprograms()) {
Assert(isa<MDTuple>(Array), "invalid subprogram list", &N, Array);
for (Metadata *Op : N.getSubprograms()->operands()) {
Assert(Op && isa<MDSubprogram>(Op), "invalid subprogram ref", &N, Op);
}
}
if (auto *Array = N.getRawGlobalVariables()) {
Assert(isa<MDTuple>(Array), "invalid global variable list", &N, Array);
for (Metadata *Op : N.getGlobalVariables()->operands()) {
Assert(Op && isa<MDGlobalVariable>(Op), "invalid global variable ref", &N,
Op);
}
}
if (auto *Array = N.getRawImportedEntities()) {
Assert(isa<MDTuple>(Array), "invalid imported entity list", &N, Array);
for (Metadata *Op : N.getImportedEntities()->operands()) {
Assert(Op && isa<MDImportedEntity>(Op), "invalid imported entity ref", &N,
Op);
}
}
} }
void Verifier::visitMDSubprogram(const MDSubprogram &N) { void Verifier::visitMDSubprogram(const MDSubprogram &N) {

View File

@ -75,6 +75,7 @@ protected:
return MDNode::get(Context, MDs); return MDNode::get(Context, MDs);
} }
MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); }
MDSubprogram *getSubprogram() { MDSubprogram *getSubprogram() {
return MDSubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, return MDSubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0,
nullptr, false, false, 0, nullptr, 0, 0, 0, nullptr, false, false, 0, nullptr, 0, 0, 0,
@ -95,6 +96,11 @@ protected:
return ConstantAsMetadata::get( return ConstantAsMetadata::get(
ConstantInt::get(Type::getInt32Ty(Context), Counter++)); ConstantInt::get(Type::getInt32Ty(Context), Counter++));
} }
MDCompositeType *getCompositeType() {
return MDCompositeType::getDistinct(
Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr,
32, 32, 0, 0, nullptr, 0, nullptr, nullptr, "");
}
}; };
typedef MetadataTest MDStringTest; typedef MetadataTest MDStringTest;
@ -901,10 +907,10 @@ TEST_F(MDTypeTest, setFlags) {
typedef MetadataTest MDDerivedTypeTest; typedef MetadataTest MDDerivedTypeTest;
TEST_F(MDDerivedTypeTest, get) { TEST_F(MDDerivedTypeTest, get) {
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
Metadata *Scope = MDTuple::getDistinct(Context, None); MDScope *Scope = getSubprogram();
Metadata *BaseType = MDTuple::getDistinct(Context, None); MDType *BaseType = getBasicType("basic");
Metadata *ExtraData = MDTuple::getDistinct(Context, None); MDTuple *ExtraData = getTuple();
auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
File, 1, Scope, BaseType, 2, 3, 4, 5, ExtraData); File, 1, Scope, BaseType, 2, 3, 4, 5, ExtraData);
@ -930,17 +936,17 @@ TEST_F(MDDerivedTypeTest, get) {
File, 1, Scope, BaseType, 2, 3, 4, 5, File, 1, Scope, BaseType, 2, 3, 4, 5,
ExtraData)); ExtraData));
EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", Scope, 1, Scope, BaseType, 2, 3, "something", getFile(), 1, Scope, BaseType, 2,
4, 5, ExtraData)); 3, 4, 5, ExtraData));
EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 2, Scope, BaseType, 2, 3, "something", File, 2, Scope, BaseType, 2, 3,
4, 5, ExtraData)); 4, 5, ExtraData));
EXPECT_NE(N, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", "something", File, 1, getSubprogram(),
File, 1, File, BaseType, 2, 3, 4, 5, ExtraData)); BaseType, 2, 3, 4, 5, ExtraData));
EXPECT_NE(N, EXPECT_NE(N, MDDerivedType::get(
MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", Context, dwarf::DW_TAG_pointer_type, "something", File, 1,
File, 1, Scope, File, 2, 3, 4, 5, ExtraData)); Scope, getBasicType("basic2"), 2, 3, 4, 5, ExtraData));
EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 3, 3, "something", File, 1, Scope, BaseType, 3, 3,
4, 5, ExtraData)); 4, 5, ExtraData));
@ -953,19 +959,19 @@ TEST_F(MDDerivedTypeTest, get) {
EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3, "something", File, 1, Scope, BaseType, 2, 3,
4, 4, ExtraData)); 4, 4, ExtraData));
EXPECT_NE(N, EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", "something", File, 1, Scope, BaseType, 2, 3,
File, 1, Scope, BaseType, 2, 3, 4, 5, File)); 4, 5, getTuple()));
TempMDDerivedType Temp = N->clone(); TempMDDerivedType Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
} }
TEST_F(MDDerivedTypeTest, getWithLargeValues) { TEST_F(MDDerivedTypeTest, getWithLargeValues) {
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
Metadata *Scope = MDTuple::getDistinct(Context, None); MDScope *Scope = getSubprogram();
Metadata *BaseType = MDTuple::getDistinct(Context, None); MDType *BaseType = getBasicType("basic");
Metadata *ExtraData = MDTuple::getDistinct(Context, None); MDTuple *ExtraData = getTuple();
auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
File, 1, Scope, BaseType, UINT64_MAX, File, 1, Scope, BaseType, UINT64_MAX,
@ -980,18 +986,18 @@ typedef MetadataTest MDCompositeTypeTest;
TEST_F(MDCompositeTypeTest, get) { TEST_F(MDCompositeTypeTest, get) {
unsigned Tag = dwarf::DW_TAG_structure_type; unsigned Tag = dwarf::DW_TAG_structure_type;
StringRef Name = "some name"; StringRef Name = "some name";
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
unsigned Line = 1; unsigned Line = 1;
Metadata *Scope = MDTuple::getDistinct(Context, None); MDScope *Scope = getSubprogram();
Metadata *BaseType = MDTuple::getDistinct(Context, None); MDType *BaseType = getCompositeType();
uint64_t SizeInBits = 2; uint64_t SizeInBits = 2;
uint64_t AlignInBits = 3; uint64_t AlignInBits = 3;
uint64_t OffsetInBits = 4; uint64_t OffsetInBits = 4;
unsigned Flags = 5; unsigned Flags = 5;
Metadata *Elements = MDTuple::getDistinct(Context, None); MDTuple *Elements = getTuple();
unsigned RuntimeLang = 6; unsigned RuntimeLang = 6;
Metadata *VTableHolder = MDTuple::getDistinct(Context, None); MDType *VTableHolder = getCompositeType();
Metadata *TemplateParams = MDTuple::getDistinct(Context, None); MDTuple *TemplateParams = getTuple();
StringRef Identifier = "some id"; StringRef Identifier = "some id";
auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope, auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
@ -1027,7 +1033,7 @@ TEST_F(MDCompositeTypeTest, get) {
BaseType, SizeInBits, AlignInBits, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, Scope, Line, Scope, EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, getFile(), Line, Scope,
BaseType, SizeInBits, AlignInBits, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
@ -1035,10 +1041,10 @@ TEST_F(MDCompositeTypeTest, get) {
BaseType, SizeInBits, AlignInBits, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, File, EXPECT_NE(N, MDCompositeType::get(
BaseType, SizeInBits, AlignInBits, Context, Tag, Name, File, Line, getSubprogram(), BaseType,
OffsetInBits, Flags, Elements, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
VTableHolder, TemplateParams, Identifier)); RuntimeLang, VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, File, EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, File,
SizeInBits, AlignInBits, OffsetInBits, SizeInBits, AlignInBits, OffsetInBits,
Flags, Elements, RuntimeLang, VTableHolder, Flags, Elements, RuntimeLang, VTableHolder,
@ -1059,22 +1065,22 @@ TEST_F(MDCompositeTypeTest, get) {
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags + 1, Elements, RuntimeLang, AlignInBits, OffsetInBits, Flags + 1, Elements, RuntimeLang,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, EXPECT_NE(N, MDCompositeType::get(
BaseType, SizeInBits, AlignInBits, Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
OffsetInBits, Flags, File, RuntimeLang, AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get( EXPECT_NE(N, MDCompositeType::get(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1,
VTableHolder, TemplateParams, Identifier)); VTableHolder, TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
getCompositeType(), TemplateParams, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
BaseType, SizeInBits, AlignInBits, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, OffsetInBits, Flags, Elements, RuntimeLang,
File, TemplateParams, Identifier)); VTableHolder, getTuple(), Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, File, Identifier));
EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
BaseType, SizeInBits, AlignInBits, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, OffsetInBits, Flags, Elements, RuntimeLang,
@ -1097,18 +1103,18 @@ TEST_F(MDCompositeTypeTest, get) {
TEST_F(MDCompositeTypeTest, getWithLargeValues) { TEST_F(MDCompositeTypeTest, getWithLargeValues) {
unsigned Tag = dwarf::DW_TAG_structure_type; unsigned Tag = dwarf::DW_TAG_structure_type;
StringRef Name = "some name"; StringRef Name = "some name";
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
unsigned Line = 1; unsigned Line = 1;
Metadata *Scope = MDTuple::getDistinct(Context, None); MDScope *Scope = getSubprogram();
Metadata *BaseType = MDTuple::getDistinct(Context, None); MDType *BaseType = getCompositeType();
uint64_t SizeInBits = UINT64_MAX; uint64_t SizeInBits = UINT64_MAX;
uint64_t AlignInBits = UINT64_MAX - 1; uint64_t AlignInBits = UINT64_MAX - 1;
uint64_t OffsetInBits = UINT64_MAX - 2; uint64_t OffsetInBits = UINT64_MAX - 2;
unsigned Flags = 5; unsigned Flags = 5;
Metadata *Elements = MDTuple::getDistinct(Context, None); MDTuple *Elements = getTuple();
unsigned RuntimeLang = 6; unsigned RuntimeLang = 6;
Metadata *VTableHolder = MDTuple::getDistinct(Context, None); MDType *VTableHolder = getCompositeType();
Metadata *TemplateParams = MDTuple::getDistinct(Context, None); MDTuple *TemplateParams = getTuple();
StringRef Identifier = "some id"; StringRef Identifier = "some id";
auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope, auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
@ -1123,10 +1129,10 @@ TEST_F(MDCompositeTypeTest, getWithLargeValues) {
TEST_F(MDCompositeTypeTest, replaceOperands) { TEST_F(MDCompositeTypeTest, replaceOperands) {
unsigned Tag = dwarf::DW_TAG_structure_type; unsigned Tag = dwarf::DW_TAG_structure_type;
StringRef Name = "some name"; StringRef Name = "some name";
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
unsigned Line = 1; unsigned Line = 1;
Metadata *Scope = MDTuple::getDistinct(Context, None); MDScope *Scope = getSubprogram();
Metadata *BaseType = MDTuple::getDistinct(Context, None); MDType *BaseType = getCompositeType();
uint64_t SizeInBits = 2; uint64_t SizeInBits = 2;
uint64_t AlignInBits = 3; uint64_t AlignInBits = 3;
uint64_t OffsetInBits = 4; uint64_t OffsetInBits = 4;
@ -1165,7 +1171,7 @@ typedef MetadataTest MDSubroutineTypeTest;
TEST_F(MDSubroutineTypeTest, get) { TEST_F(MDSubroutineTypeTest, get) {
unsigned Flags = 1; unsigned Flags = 1;
Metadata *TypeArray = MDTuple::getDistinct(Context, None); MDTuple *TypeArray = getTuple();
auto *N = MDSubroutineType::get(Context, Flags, TypeArray); auto *N = MDSubroutineType::get(Context, Flags, TypeArray);
EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag()); EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag());
@ -1174,8 +1180,7 @@ TEST_F(MDSubroutineTypeTest, get) {
EXPECT_EQ(N, MDSubroutineType::get(Context, Flags, TypeArray)); EXPECT_EQ(N, MDSubroutineType::get(Context, Flags, TypeArray));
EXPECT_NE(N, MDSubroutineType::get(Context, Flags + 1, TypeArray)); EXPECT_NE(N, MDSubroutineType::get(Context, Flags + 1, TypeArray));
EXPECT_NE(N, MDSubroutineType::get(Context, Flags, EXPECT_NE(N, MDSubroutineType::get(Context, Flags, getTuple()));
MDTuple::getDistinct(Context, None)));
TempMDSubroutineType Temp = N->clone(); TempMDSubroutineType Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
@ -1219,18 +1224,18 @@ typedef MetadataTest MDCompileUnitTest;
TEST_F(MDCompileUnitTest, get) { TEST_F(MDCompileUnitTest, get) {
unsigned SourceLanguage = 1; unsigned SourceLanguage = 1;
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
StringRef Producer = "some producer"; StringRef Producer = "some producer";
bool IsOptimized = false; bool IsOptimized = false;
StringRef Flags = "flag after flag"; StringRef Flags = "flag after flag";
unsigned RuntimeVersion = 2; unsigned RuntimeVersion = 2;
StringRef SplitDebugFilename = "another/file"; StringRef SplitDebugFilename = "another/file";
unsigned EmissionKind = 3; unsigned EmissionKind = 3;
Metadata *EnumTypes = MDTuple::getDistinct(Context, None); MDTuple *EnumTypes = getTuple();
Metadata *RetainedTypes = MDTuple::getDistinct(Context, None); MDTuple *RetainedTypes = getTuple();
Metadata *Subprograms = MDTuple::getDistinct(Context, None); MDTuple *Subprograms = getTuple();
Metadata *GlobalVariables = MDTuple::getDistinct(Context, None); MDTuple *GlobalVariables = getTuple();
Metadata *ImportedEntities = MDTuple::getDistinct(Context, None); MDTuple *ImportedEntities = getTuple();
auto *N = MDCompileUnit::get( auto *N = MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags, Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
@ -1261,7 +1266,7 @@ TEST_F(MDCompileUnitTest, get) {
SplitDebugFilename, EmissionKind, EnumTypes, SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables, RetainedTypes, Subprograms, GlobalVariables,
ImportedEntities)); ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, EnumTypes, Producer, EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, getFile(), Producer,
IsOptimized, Flags, RuntimeVersion, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables, RetainedTypes, Subprograms, GlobalVariables,
@ -1298,25 +1303,26 @@ TEST_F(MDCompileUnitTest, get) {
GlobalVariables, ImportedEntities)); GlobalVariables, ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer, EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, File, SplitDebugFilename, EmissionKind, getTuple(),
RetainedTypes, Subprograms, GlobalVariables, RetainedTypes, Subprograms, GlobalVariables,
ImportedEntities)); ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get( EXPECT_NE(N, MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags, Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
File, Subprograms, GlobalVariables, ImportedEntities)); getTuple(), Subprograms, GlobalVariables, ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, getTuple(), GlobalVariables,
ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get( EXPECT_NE(N, MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags, Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, File, GlobalVariables, ImportedEntities)); RetainedTypes, Subprograms, getTuple(), ImportedEntities));
EXPECT_NE(N, MDCompileUnit::get( EXPECT_NE(N, MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags, Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, File, ImportedEntities)); RetainedTypes, Subprograms, GlobalVariables, getTuple()));
EXPECT_NE(N, MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables, File));
TempMDCompileUnit Temp = N->clone(); TempMDCompileUnit Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
@ -1324,16 +1330,16 @@ TEST_F(MDCompileUnitTest, get) {
TEST_F(MDCompileUnitTest, replaceArrays) { TEST_F(MDCompileUnitTest, replaceArrays) {
unsigned SourceLanguage = 1; unsigned SourceLanguage = 1;
Metadata *File = MDTuple::getDistinct(Context, None); MDFile *File = getFile();
StringRef Producer = "some producer"; StringRef Producer = "some producer";
bool IsOptimized = false; bool IsOptimized = false;
StringRef Flags = "flag after flag"; StringRef Flags = "flag after flag";
unsigned RuntimeVersion = 2; unsigned RuntimeVersion = 2;
StringRef SplitDebugFilename = "another/file"; StringRef SplitDebugFilename = "another/file";
unsigned EmissionKind = 3; unsigned EmissionKind = 3;
Metadata *EnumTypes = MDTuple::getDistinct(Context, None); MDTuple *EnumTypes = MDTuple::getDistinct(Context, None);
Metadata *RetainedTypes = MDTuple::getDistinct(Context, None); MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None);
Metadata *ImportedEntities = MDTuple::getDistinct(Context, None); MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None);
auto *N = MDCompileUnit::get( auto *N = MDCompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags, Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,