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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233446 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-03-27 23:05:04 +00:00
parent 6ed3a762fc
commit b943370653
7 changed files with 278 additions and 154 deletions

View File

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

View File

@ -282,13 +282,16 @@ protected:
~MDScope() {}
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
/// (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
/// subclasses store their file pointer.
Metadata *getFile() const {
Metadata *getRawFile() const {
return isa<MDFile>(this) ? const_cast<MDScope *>(this)
: static_cast<Metadata *>(getOperand(0));
}
@ -390,9 +393,14 @@ public:
uint64_t getOffsetInBits() const { return OffsetInBits; }
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); }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(unsigned NewFlags) {
@ -483,7 +491,8 @@ protected:
~MDDerivedTypeBase() {}
public:
Metadata *getBaseType() const { return getOperand(3); }
Metadata *getBaseType() const { return getRawBaseType(); }
Metadata *getRawBaseType() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDDerivedTypeKind ||
@ -510,7 +519,7 @@ class MDDerivedType : public MDDerivedTypeBase {
~MDDerivedType() {}
static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, Metadata *File, unsigned Line,
StringRef Name, MDFile *File, unsigned Line,
Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
@ -545,7 +554,7 @@ public:
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData))
DEFINE_MDNODE_GET(MDDerivedType,
(unsigned Tag, StringRef Name, Metadata *File,
(unsigned Tag, StringRef Name, MDFile *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
@ -562,7 +571,8 @@ public:
///
/// TODO: Separate out types that need this extra operand: pointer-to-member
/// 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) {
return MD->getMetadataID() == MDDerivedTypeKind;
@ -587,12 +597,19 @@ protected:
~MDCompositeTypeBase() {}
public:
Metadata *getElements() const { return getOperand(4); }
Metadata *getVTableHolder() const { return getOperand(5); }
Metadata *getTemplateParams() const { return getOperand(6); }
MDTuple *getElements() const {
return cast_or_null<MDTuple>(getRawElements());
}
Metadata *getVTableHolder() const { return getRawVTableHolder(); }
MDTuple *getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
StringRef getIdentifier() const { return getStringOperand(7); }
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); }
/// \brief Replace operands.
@ -730,7 +747,8 @@ public:
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) {
return MD->getMetadataID() == MDSubroutineTypeKind;
@ -756,12 +774,12 @@ class MDCompileUnit : public MDScope {
~MDCompileUnit() {}
static MDCompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
StringRef Producer, bool IsOptimized, StringRef Flags,
unsigned RuntimeVersion, StringRef SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables,
Metadata *ImportedEntities, StorageType Storage,
unsigned EmissionKind, MDTuple *EnumTypes, MDTuple *RetainedTypes,
MDTuple *Subprograms, MDTuple *GlobalVariables,
MDTuple *ImportedEntities, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, SourceLanguage, File,
getCanonicalMDString(Context, Producer), IsOptimized,
@ -789,12 +807,12 @@ class MDCompileUnit : public MDScope {
public:
DEFINE_MDNODE_GET(MDCompileUnit,
(unsigned SourceLanguage, Metadata *File,
StringRef Producer, bool IsOptimized, StringRef Flags,
unsigned RuntimeVersion, StringRef SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes,
Metadata *RetainedTypes, Metadata *Subprograms,
Metadata *GlobalVariables, Metadata *ImportedEntities),
(unsigned SourceLanguage, MDFile *File, StringRef Producer,
bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
StringRef SplitDebugFilename, unsigned EmissionKind,
MDTuple *EnumTypes, MDTuple *RetainedTypes,
MDTuple *Subprograms, MDTuple *GlobalVariables,
MDTuple *ImportedEntities),
(SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind,
EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
@ -813,6 +831,9 @@ public:
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; }
bool isOptimized() const { return IsOptimized; }
unsigned getRuntimeVersion() const { return RuntimeVersion; }
@ -820,17 +841,32 @@ public:
StringRef getProducer() const { return getStringOperand(1); }
StringRef getFlags() const { return getStringOperand(2); }
StringRef getSplitDebugFilename() const { return getStringOperand(3); }
Metadata *getEnumTypes() const { return getOperand(4); }
Metadata *getRetainedTypes() const { return getOperand(5); }
Metadata *getSubprograms() const { return getOperand(6); }
Metadata *getGlobalVariables() const { return getOperand(7); }
Metadata *getImportedEntities() const { return getOperand(8); }
MDTuple *getEnumTypes() const {
return cast_or_null<MDTuple>(getRawEnumTypes());
}
MDTuple *getRetainedTypes() const {
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 *getRawFlags() const { return getOperandAs<MDString>(2); }
MDString *getRawSplitDebugFilename() const {
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.
///

View File

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

View File

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

View File

@ -347,20 +347,20 @@ template <> struct MDNodeKeyImpl<MDDerivedType> {
BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {}
MDNodeKeyImpl(const MDDerivedType *N)
: Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
ExtraData(N->getExtraData()) {}
: Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {}
bool isKeyOf(const MDDerivedType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() &&
File == RHS->getFile() && Line == RHS->getLine() &&
Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
ExtraData == RHS->getExtraData();
ExtraData == RHS->getRawExtraData();
}
unsigned getHashValue() const {
return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
@ -397,26 +397,26 @@ template <> struct MDNodeKeyImpl<MDCompositeType> {
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
TemplateParams(TemplateParams), Identifier(Identifier) {}
MDNodeKeyImpl(const MDCompositeType *N)
: Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
Elements(N->getElements()), RuntimeLang(N->getRuntimeLang()),
VTableHolder(N->getVTableHolder()),
TemplateParams(N->getTemplateParams()), Identifier(N->getIdentifier()) {
}
: Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
Flags(N->getFlags()), Elements(N->getRawElements()),
RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
TemplateParams(N->getRawTemplateParams()),
Identifier(N->getIdentifier()) {}
bool isKeyOf(const MDCompositeType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() &&
File == RHS->getFile() && Line == RHS->getLine() &&
Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
Elements == RHS->getElements() &&
Elements == RHS->getRawElements() &&
RuntimeLang == RHS->getRuntimeLang() &&
VTableHolder == RHS->getVTableHolder() &&
TemplateParams == RHS->getTemplateParams() &&
VTableHolder == RHS->getRawVTableHolder() &&
TemplateParams == RHS->getRawTemplateParams() &&
Identifier == RHS->getIdentifier();
}
unsigned getHashValue() const {
@ -433,10 +433,10 @@ template <> struct MDNodeKeyImpl<MDSubroutineType> {
MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray)
: Flags(Flags), TypeArray(TypeArray) {}
MDNodeKeyImpl(const MDSubroutineType *N)
: Flags(N->getFlags()), TypeArray(N->getTypeArray()) {}
: Flags(N->getFlags()), TypeArray(N->getRawTypeArray()) {}
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); }
};
@ -484,27 +484,28 @@ template <> struct MDNodeKeyImpl<MDCompileUnit> {
Subprograms(Subprograms), GlobalVariables(GlobalVariables),
ImportedEntities(ImportedEntities) {}
MDNodeKeyImpl(const MDCompileUnit *N)
: SourceLanguage(N->getSourceLanguage()), File(N->getFile()),
: SourceLanguage(N->getSourceLanguage()), File(N->getRawFile()),
Producer(N->getProducer()), IsOptimized(N->isOptimized()),
Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()),
SplitDebugFilename(N->getSplitDebugFilename()),
EmissionKind(N->getEmissionKind()), EnumTypes(N->getEnumTypes()),
RetainedTypes(N->getRetainedTypes()), Subprograms(N->getSubprograms()),
GlobalVariables(N->getGlobalVariables()),
ImportedEntities(N->getImportedEntities()) {}
EmissionKind(N->getEmissionKind()), EnumTypes(N->getRawEnumTypes()),
RetainedTypes(N->getRawRetainedTypes()),
Subprograms(N->getRawSubprograms()),
GlobalVariables(N->getRawGlobalVariables()),
ImportedEntities(N->getRawImportedEntities()) {}
bool isKeyOf(const MDCompileUnit *RHS) const {
return SourceLanguage == RHS->getSourceLanguage() &&
File == RHS->getFile() && Producer == RHS->getProducer() &&
File == RHS->getRawFile() && Producer == RHS->getProducer() &&
IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() &&
RuntimeVersion == RHS->getRuntimeVersion() &&
SplitDebugFilename == RHS->getSplitDebugFilename() &&
EmissionKind == RHS->getEmissionKind() &&
EnumTypes == RHS->getEnumTypes() &&
RetainedTypes == RHS->getRetainedTypes() &&
Subprograms == RHS->getSubprograms() &&
GlobalVariables == RHS->getGlobalVariables() &&
ImportedEntities == RHS->getImportedEntities();
EnumTypes == RHS->getRawEnumTypes() &&
RetainedTypes == RHS->getRawRetainedTypes() &&
Subprograms == RHS->getRawSubprograms() &&
GlobalVariables == RHS->getRawGlobalVariables() &&
ImportedEntities == RHS->getRawImportedEntities();
}
unsigned getHashValue() const {
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);
#include "llvm/IR/Metadata.def"
void visitMDScope(const MDScope &N);
void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
void visitMDVariable(const MDVariable &N);
// InstVisitor overrides...
@ -668,6 +670,15 @@ static bool isTypeRef(const Metadata *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) {
Assert(N.getRawScope() && isa<MDLocalScope>(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);
}
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) {
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) {
@ -693,7 +710,18 @@ void Verifier::visitMDBasicType(const MDBasicType &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) {
// Common derived type checks.
visitMDDerivedTypeBase(N);
Assert(N.getTag() == dwarf::DW_TAG_typedef ||
N.getTag() == dwarf::DW_TAG_pointer_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) {
// Common derived type checks.
visitMDDerivedTypeBase(N);
Assert(N.getTag() == dwarf::DW_TAG_array_type ||
N.getTag() == dwarf::DW_TAG_structure_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_class_type,
"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) {
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) {
@ -728,6 +773,41 @@ void Verifier::visitMDFile(const MDFile &N) {
void Verifier::visitMDCompileUnit(const MDCompileUnit &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) {

View File

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