From bd38c8d788561f8d6d90c8d8677c95a9bf96ea48 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 30 Mar 2015 16:19:15 +0000 Subject: [PATCH] Verifier: Check operands of MDSubprogram nodes Check operands of `MDSubprogram`s in the verifier, and update the accessors and factory functions to use more specific types. There were a lot of broken testcases, which I fixed in r233466. If you have out-of-tree tests for debug info, you probably need similar changes to the ones I made there. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233559 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DebugInfoMetadata.h | 61 +++++++++++++------ lib/IR/AsmWriter.cpp | 16 ++--- lib/IR/DIBuilder.cpp | 22 ++++--- lib/IR/LLVMContextImpl.h | 29 ++++----- lib/IR/Verifier.cpp | 58 ++++++++++++++++++ unittests/IR/MetadataTest.cpp | 91 ++++++++++++++++------------- 6 files changed, 186 insertions(+), 91 deletions(-) diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 4b08e809b2a..d52c8b89fef 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -998,12 +998,13 @@ class MDSubprogram : public MDLocalScope { static MDSubprogram * getImpl(LLVMContext &Context, Metadata *Scope, StringRef Name, - StringRef LinkageName, Metadata *File, unsigned Line, Metadata *Type, - bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, - Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsOptimized, Metadata *Function, - Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, - StorageType Storage, bool ShouldCreate = true) { + StringRef LinkageName, MDFile *File, unsigned Line, + MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, + unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, + unsigned VirtualIndex, unsigned Flags, bool IsOptimized, + ConstantAsMetadata *Function, MDTuple *TemplateParams, + MDSubprogram *Declaration, MDTuple *Variables, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, @@ -1032,12 +1033,13 @@ class MDSubprogram : public MDLocalScope { public: DEFINE_MDNODE_GET( MDSubprogram, - (Metadata * Scope, StringRef Name, StringRef LinkageName, Metadata *File, - unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, - unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *Function = nullptr, Metadata *TemplateParams = nullptr, - Metadata *Declaration = nullptr, Metadata *Variables = nullptr), + (Metadata * Scope, StringRef Name, StringRef LinkageName, MDFile *File, + unsigned Line, MDSubroutineType *Type, bool IsLocalToUnit, + bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, + unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, + bool IsOptimized, ConstantAsMetadata *Function = nullptr, + MDTuple *TemplateParams = nullptr, MDSubprogram *Declaration = nullptr, + MDTuple *Variables = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, Function, TemplateParams, Declaration, Variables)) @@ -1065,7 +1067,10 @@ public: bool isDefinition() const { return IsDefinition; } bool isOptimized() const { return IsOptimized; } - Metadata *getScope() const { return getOperand(1); } + // FIXME: Remove this once MDScope::getFile() does the same. + MDFile *getFile() const { return cast_or_null(getRawFile()); } + + Metadata *getScope() const { return getRawScope(); } StringRef getName() const { return getStringOperand(2); } StringRef getDisplayName() const { return getStringOperand(3); } @@ -1074,13 +1079,31 @@ public: MDString *getRawName() const { return getOperandAs(2); } MDString *getRawLinkageName() const { return getOperandAs(4); } - Metadata *getType() const { return getOperand(5); } - Metadata *getContainingType() const { return getOperand(6); } + MDSubroutineType *getType() const { + return cast_or_null(getRawType()); + } + Metadata *getContainingType() const { return getRawContainingType(); } + + ConstantAsMetadata *getFunction() const { + return cast_or_null(getRawFunction()); + } + MDTuple *getTemplateParams() const { + return cast_or_null(getRawTemplateParams()); + } + MDSubprogram *getDeclaration() const { + return cast_or_null(getRawDeclaration()); + } + MDTuple *getVariables() const { + return cast_or_null(getRawVariables()); + } - Metadata *getFunction() const { return getOperand(7); } - Metadata *getTemplateParams() const { return getOperand(8); } - Metadata *getDeclaration() const { return getOperand(9); } - Metadata *getVariables() const { return getOperand(10); } + Metadata *getRawScope() const { return getOperand(1); } + Metadata *getRawType() const { return getOperand(5); } + Metadata *getRawContainingType() const { return getOperand(6); } + Metadata *getRawFunction() const { return getOperand(7); } + Metadata *getRawTemplateParams() const { return getOperand(8); } + Metadata *getRawDeclaration() const { return getOperand(9); } + Metadata *getRawVariables() const { return getOperand(10); } /// \brief Replace the function. /// diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index a3dde894070..c5782f5937f 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1629,23 +1629,23 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N, MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); Printer.printString("name", N->getName()); Printer.printString("linkageName", N->getLinkageName()); - Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false); - Printer.printMetadata("file", N->getFile()); + Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false); + Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLine()); - Printer.printMetadata("type", N->getType()); + Printer.printMetadata("type", N->getRawType()); Printer.printBool("isLocal", N->isLocalToUnit()); Printer.printBool("isDefinition", N->isDefinition()); Printer.printInt("scopeLine", N->getScopeLine()); - Printer.printMetadata("containingType", N->getContainingType()); + Printer.printMetadata("containingType", N->getRawContainingType()); Printer.printDwarfEnum("virtuality", N->getVirtuality(), dwarf::VirtualityString); Printer.printInt("virtualIndex", N->getVirtualIndex()); Printer.printDIFlags("flags", N->getFlags()); Printer.printBool("isOptimized", N->isOptimized()); - Printer.printMetadata("function", N->getFunction()); - Printer.printMetadata("templateParams", N->getTemplateParams()); - Printer.printMetadata("declaration", N->getDeclaration()); - Printer.printMetadata("variables", N->getVariables()); + Printer.printMetadata("function", N->getRawFunction()); + Printer.printMetadata("templateParams", N->getRawTemplateParams()); + Printer.printMetadata("declaration", N->getRawDeclaration()); + Printer.printMetadata("variables", N->getRawVariables()); Out << ")"; } diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index dfbc1315218..28d27d201c0 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -674,9 +674,11 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, "function types should be subroutines"); auto *Node = MDSubprogram::get( VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name, - LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit, isDefinition, - ScopeLine, nullptr, 0, 0, Flags, isOptimized, getConstantOrNull(Fn), - TParams, Decl, MDNode::getTemporary(VMContext, None).release()); + LinkageName, File.get(), LineNo, cast_or_null(Ty.get()), + isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized, + getConstantOrNull(Fn), cast_or_null(TParams), + cast_or_null(Decl), + MDTuple::getTemporary(VMContext, None).release()); if (isDefinition) AllSubprograms.push_back(Node); @@ -694,9 +696,11 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name, MDNode *TParams, MDNode *Decl) { return MDSubprogram::getTemporary( VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name, - LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit, + LinkageName, File.get(), LineNo, + cast_or_null(Ty.get()), isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized, - getConstantOrNull(Fn), TParams, Decl, nullptr).release(); + getConstantOrNull(Fn), cast_or_null(TParams), + cast_or_null(Decl), nullptr).release(); } DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, @@ -714,10 +718,10 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, "the compile unit."); // FIXME: Do we want to use different scope/lines? auto *Node = MDSubprogram::get( - VMContext, DIScope(Context).getRef(), Name, LinkageName, F.getFileNode(), - LineNo, Ty, isLocalToUnit, isDefinition, LineNo, VTableHolder.getRef(), - VK, VIndex, Flags, isOptimized, getConstantOrNull(Fn), TParam, nullptr, - nullptr); + VMContext, DIScope(Context).getRef(), Name, LinkageName, F.get(), LineNo, + cast_or_null(Ty.get()), isLocalToUnit, isDefinition, + LineNo, VTableHolder.getRef(), VK, VIndex, Flags, isOptimized, + getConstantOrNull(Fn), cast_or_null(TParam), nullptr, nullptr); if (isDefinition) AllSubprograms.push_back(Node); diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 21999822346..efb741f13fd 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -550,31 +550,32 @@ template <> struct MDNodeKeyImpl { Function(Function), TemplateParams(TemplateParams), Declaration(Declaration), Variables(Variables) {} MDNodeKeyImpl(const MDSubprogram *N) - : Scope(N->getScope()), Name(N->getName()), - LinkageName(N->getLinkageName()), File(N->getFile()), - Line(N->getLine()), Type(N->getType()), + : Scope(N->getRawScope()), Name(N->getName()), + LinkageName(N->getLinkageName()), File(N->getRawFile()), + Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), - ScopeLine(N->getScopeLine()), ContainingType(N->getContainingType()), + ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()), Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()), Flags(N->getFlags()), IsOptimized(N->isOptimized()), - Function(N->getFunction()), TemplateParams(N->getTemplateParams()), - Declaration(N->getDeclaration()), Variables(N->getVariables()) {} + Function(N->getRawFunction()), + TemplateParams(N->getRawTemplateParams()), + Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {} bool isKeyOf(const MDSubprogram *RHS) const { - return Scope == RHS->getScope() && Name == RHS->getName() && - LinkageName == RHS->getLinkageName() && File == RHS->getFile() && - Line == RHS->getLine() && Type == RHS->getType() && + return Scope == RHS->getRawScope() && Name == RHS->getName() && + LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() && + Line == RHS->getLine() && Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && IsDefinition == RHS->isDefinition() && ScopeLine == RHS->getScopeLine() && - ContainingType == RHS->getContainingType() && + ContainingType == RHS->getRawContainingType() && Virtuality == RHS->getVirtuality() && VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && - Function == RHS->getFunction() && - TemplateParams == RHS->getTemplateParams() && - Declaration == RHS->getDeclaration() && - Variables == RHS->getVariables(); + Function == RHS->getRawFunction() && + TemplateParams == RHS->getRawTemplateParams() && + Declaration == RHS->getRawDeclaration() && + Variables == RHS->getRawVariables(); } unsigned getHashValue() const { return hash_combine(Scope, Name, LinkageName, File, Line, Type, diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index af79984f59a..e4aea237bfc 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -296,6 +296,7 @@ private: void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty); + template bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); #include "llvm/IR/Metadata.def" void visitMDScope(const MDScope &N); @@ -679,6 +680,30 @@ static bool isScopeRef(const Metadata *MD) { return isa(MD); } +template +bool isValidMetadataArrayImpl(const MDTuple &N, bool AllowNull) { + for (Metadata *MD : N.operands()) { + if (MD) { + if (!isa(MD)) + return false; + } else { + if (!AllowNull) + return false; + } + } + return true; +} + +template +bool isValidMetadataArray(const MDTuple &N) { + return isValidMetadataArrayImpl(N, /* AllowNull */ false); +} + +template +bool isValidMetadataNullArray(const MDTuple &N) { + return isValidMetadataArrayImpl(N, /* AllowNull */ true); +} + void Verifier::visitMDLocation(const MDLocation &N) { Assert(N.getRawScope() && isa(N.getRawScope()), "location requires a valid scope", &N, N.getRawScope()); @@ -811,6 +836,39 @@ void Verifier::visitMDCompileUnit(const MDCompileUnit &N) { void Verifier::visitMDSubprogram(const MDSubprogram &N) { Assert(N.getTag() == dwarf::DW_TAG_subprogram, "invalid tag", &N); + Assert(isScopeRef(N.getRawScope()), "invalid scope", &N, N.getRawScope()); + if (auto *T = N.getRawType()) + Assert(isa(T), "invalid subroutine type", &N, T); + Assert(isTypeRef(N.getRawContainingType()), "invalid containing type", &N, + N.getRawContainingType()); + if (auto *RawF = N.getRawFunction()) { + auto *FMD = dyn_cast(RawF); + auto *F = FMD ? FMD->getValue() : nullptr; + auto *FT = F ? dyn_cast(F->getType()) : nullptr; + Assert(F && (isa(F) || isa(F)) && FT && + isa(FT->getElementType()), + "invalid function", &N, F); + } + if (N.getRawTemplateParams()) { + auto *Params = dyn_cast(N.getRawTemplateParams()); + Assert(Params, "invalid template params", &N, Params); + for (Metadata *Op : Params->operands()) { + Assert(Op && isa(Op), "invalid template parameter", + &N, Params, Op); + } + } + if (auto *S = N.getRawDeclaration()) { + Assert(isa(S) && !cast(S)->isDefinition(), + "invalid subprogram declaration", &N, S); + } + if (N.getRawVariables()) { + auto *Vars = dyn_cast(N.getRawVariables()); + Assert(Vars, "invalid variable list", &N, Vars); + for (Metadata *Op : Vars->operands()) { + Assert(Op && isa(Op), "invalid local variable", &N, Vars, + Op); + } + } } void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) { diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index ac6d3df6f80..b722ceac6f9 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -62,10 +62,11 @@ TEST(ContextAndReplaceableUsesTest, takeReplaceableUses) { class MetadataTest : public testing::Test { public: - MetadataTest() : Counter(0) {} + MetadataTest() : M("test", Context), Counter(0) {} protected: LLVMContext Context; + Module M; int Counter; MDNode *getNode() { return MDNode::get(Context, None); } @@ -76,6 +77,9 @@ protected: } MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); } + MDSubroutineType *getSubroutineType() { + return MDSubroutineType::getDistinct(Context, 0, getNode(nullptr)); + } MDSubprogram *getSubprogram() { return MDSubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, nullptr, false, false, 0, nullptr, 0, 0, 0, @@ -101,6 +105,10 @@ protected: Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, ""); } + ConstantAsMetadata *getFunctionAsMetadata(StringRef Name) { + return ConstantAsMetadata::get(M.getOrInsertFunction( + Name, FunctionType::get(Type::getVoidTy(Context), None, false))); + } }; typedef MetadataTest MDStringTest; @@ -1363,24 +1371,24 @@ TEST_F(MDCompileUnitTest, replaceArrays) { typedef MetadataTest MDSubprogramTest; TEST_F(MDSubprogramTest, get) { - Metadata *Scope = MDTuple::getDistinct(Context, None); + MDScope *Scope = getCompositeType(); StringRef Name = "name"; StringRef LinkageName = "linkage"; - Metadata *File = MDTuple::getDistinct(Context, None); + MDFile *File = getFile(); unsigned Line = 2; - Metadata *Type = MDTuple::getDistinct(Context, None); + MDSubroutineType *Type = getSubroutineType(); bool IsLocalToUnit = false; bool IsDefinition = true; unsigned ScopeLine = 3; - Metadata *ContainingType = MDTuple::getDistinct(Context, None); + MDType *ContainingType = getCompositeType(); unsigned Virtuality = 4; unsigned VirtualIndex = 5; unsigned Flags = 6; bool IsOptimized = false; - Metadata *Function = MDTuple::getDistinct(Context, None); - Metadata *TemplateParams = MDTuple::getDistinct(Context, None); - Metadata *Declaration = MDTuple::getDistinct(Context, None); - Metadata *Variables = MDTuple::getDistinct(Context, None); + ConstantAsMetadata *Function = getFunctionAsMetadata("foo"); + MDTuple *TemplateParams = getTuple(); + MDSubprogram *Declaration = getSubprogram(); + MDTuple *Variables = getTuple(); auto *N = MDSubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, @@ -1412,11 +1420,11 @@ TEST_F(MDSubprogramTest, get) { Flags, IsOptimized, Function, TemplateParams, Declaration, Variables)); - EXPECT_NE(N, MDSubprogram::get(Context, File, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, Function, TemplateParams, - Declaration, Variables)); + EXPECT_NE(N, MDSubprogram::get(Context, getCompositeType(), Name, LinkageName, + File, Line, Type, IsLocalToUnit, IsDefinition, + ScopeLine, ContainingType, Virtuality, + VirtualIndex, Flags, IsOptimized, Function, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, @@ -1427,21 +1435,21 @@ TEST_F(MDSubprogramTest, get) { ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, Function, TemplateParams, Declaration, Variables)); - EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, Scope, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, Function, TemplateParams, - Declaration, Variables)); + EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, getFile(), + Line, Type, IsLocalToUnit, IsDefinition, + ScopeLine, ContainingType, Virtuality, + VirtualIndex, Flags, IsOptimized, Function, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, Function, TemplateParams, Declaration, Variables)); - EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Scope, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, Function, TemplateParams, - Declaration, Variables)); + EXPECT_NE(N, MDSubprogram::get( + Context, Scope, Name, LinkageName, File, Line, + getSubroutineType(), IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, + Function, TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, @@ -1459,8 +1467,8 @@ TEST_F(MDSubprogramTest, get) { TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, - Type, Virtuality, VirtualIndex, Flags, - IsOptimized, Function, TemplateParams, + getCompositeType(), Virtuality, VirtualIndex, + Flags, IsOptimized, Function, TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, @@ -1482,49 +1490,50 @@ TEST_F(MDSubprogramTest, get) { ContainingType, Virtuality, VirtualIndex, Flags, !IsOptimized, Function, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, + MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, Flags, + IsOptimized, getFunctionAsMetadata("bar"), + TemplateParams, Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, Type, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, Function, Type, + Flags, IsOptimized, Function, getTuple(), Declaration, Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, Function, TemplateParams, - Type, Variables)); + getSubprogram(), Variables)); EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, Function, TemplateParams, - Declaration, Type)); + Declaration, getTuple())); TempMDSubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } TEST_F(MDSubprogramTest, replaceFunction) { - Metadata *Scope = MDTuple::getDistinct(Context, None); + MDScope *Scope = getCompositeType(); StringRef Name = "name"; StringRef LinkageName = "linkage"; - Metadata *File = MDTuple::getDistinct(Context, None); + MDFile *File = getFile(); unsigned Line = 2; - Metadata *Type = MDTuple::getDistinct(Context, None); + MDSubroutineType *Type = getSubroutineType(); bool IsLocalToUnit = false; bool IsDefinition = true; unsigned ScopeLine = 3; - Metadata *ContainingType = MDTuple::getDistinct(Context, None); + MDCompositeType *ContainingType = getCompositeType(); unsigned Virtuality = 4; unsigned VirtualIndex = 5; unsigned Flags = 6; bool IsOptimized = false; - Metadata *TemplateParams = MDTuple::getDistinct(Context, None); - Metadata *Declaration = MDTuple::getDistinct(Context, None); - Metadata *Variables = MDTuple::getDistinct(Context, None); + MDTuple *TemplateParams = getTuple(); + MDSubprogram *Declaration = getSubprogram(); + MDTuple *Variables = getTuple(); auto *N = MDSubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, -- 2.34.1