diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 4534a149257..1f47f8a1cc3 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -330,7 +330,15 @@ protected: ~MDScope() {} public: - Metadata *getFile() const { return getOperand(0); } + /// \brief Return the 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 { + return isa<MDFile>(this) ? const_cast<MDScope *>(this) : getOperand(0); + } static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 6f2372d58cb..4de6ecc0f9b 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -1041,6 +1041,12 @@ TEST_F(MDFileTest, get) { EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } +TEST_F(MDFileTest, ScopeGetFile) { + // Ensure that MDScope::getFile() returns itself. + MDScope *N = MDFile::get(Context, "file", "dir"); + EXPECT_EQ(N, N->getFile()); +} + typedef MetadataTest MDCompileUnitTest; TEST_F(MDCompileUnitTest, get) {