From a9d82a512ff65b334a4619761c4a1ef5856725f5 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Wed, 18 Feb 2015 20:32:57 +0000 Subject: [PATCH] IR: Add MDSubprogram::replaceFunction() git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229742 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DebugInfoMetadata.h | 11 +++++++++ lib/IR/DebugInfoMetadata.cpp | 6 +++++ unittests/IR/MetadataTest.cpp | 37 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index b43027cc04a..57d8bb01b29 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -968,6 +968,17 @@ public: Metadata *getDeclaration() const { return getOperand(9); } Metadata *getVariables() const { return getOperand(10); } + /// \brief Replace the function. + /// + /// If \a isUniqued() and not \a isResolved(), this could node will be + /// RAUW'ed and deleted out from under the caller. Use a \a TrackingMDRef if + /// that's a problem. + /// @{ + void replaceFunction(Function *F); + void replaceFunction(ConstantAsMetadata *MD) { replaceOperandWith(7, MD); } + void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); } + /// @} + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDSubprogramKind; } diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 3d6ebbce1b4..f6dfbf6cfa5 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "LLVMContextImpl.h" #include "MetadataImpl.h" +#include "llvm/IR/Function.h" using namespace llvm; @@ -264,6 +265,11 @@ MDSubprogram *MDSubprogram::getImpl( Ops); } +void MDSubprogram::replaceFunction(Function *F) { + replaceFunction(F ? ConstantAsMetadata::get(F) + : static_cast(nullptr)); +} + MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope, Metadata *File, unsigned Line, unsigned Column, StorageType Storage, diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 31a71473507..db06fb62fa1 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -1189,6 +1190,42 @@ TEST_F(MDSubprogramTest, get) { EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } +TEST_F(MDSubprogramTest, replaceFunction) { + Metadata *Scope = MDTuple::getDistinct(Context, None); + StringRef Name = "name"; + StringRef LinkageName = "linkage"; + Metadata *File = MDTuple::getDistinct(Context, None); + unsigned Line = 2; + Metadata *Type = MDTuple::getDistinct(Context, None); + bool IsLocalToUnit = false; + bool IsDefinition = true; + unsigned ScopeLine = 3; + Metadata *ContainingType = MDTuple::getDistinct(Context, None); + 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); + + auto *N = MDSubprogram::get( + Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, + IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, + IsOptimized, nullptr, TemplateParams, Declaration, Variables); + + EXPECT_EQ(nullptr, N->getFunction()); + + std::unique_ptr F( + Function::Create(FunctionType::get(Type::getVoidTy(Context), false), + GlobalValue::ExternalLinkage)); + N->replaceFunction(F.get()); + EXPECT_EQ(ConstantAsMetadata::get(F.get()), N->getFunction()); + + N->replaceFunction(nullptr); + EXPECT_EQ(nullptr, N->getFunction()); +} + typedef MetadataTest MDLexicalBlockTest; TEST_F(MDLexicalBlockTest, get) { -- 2.34.1