Author: Tapasweni Pathak Date: 2022-06-26T13:21:23Z New Revision: e881d85371bf9b024e0668f1667fefde4df05711
URL: https://github.com/llvm/llvm-project/commit/e881d85371bf9b024e0668f1667fefde4df05711 DIFF: https://github.com/llvm/llvm-project/commit/e881d85371bf9b024e0668f1667fefde4df05711.diff LOG: Allow interfaces to operate on in-memory buffers with no source location info. This patch is a part of the upstreaming efforts. Cling has the ability to spawn child interpreters (mainly for auto completions). The child interpreter import Decls using the ASTImporter which casuses the assertion here https://github.com/llvm/llvm-project/blob/65eb74e94b414fcde6bfa810d1c30c7fcb136b77/clang/include/clang/Basic/SourceLocation.h#L322 The patch is co-developed with V. Vassilev. Differential revision: https://reviews.llvm.org/D88780 Added: Modified: clang/include/clang/Basic/SourceManager.h clang/unittests/Basic/SourceManagerTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index 73e6353109d92..5bdeecb07cd9e 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1473,24 +1473,35 @@ class SourceManager : public RefCountedBase<SourceManager> { /// Returns whether \p Loc is located in a <built-in> file. bool isWrittenInBuiltinFile(SourceLocation Loc) const { - StringRef Filename(getPresumedLoc(Loc).getFilename()); + PresumedLoc Presumed = getPresumedLoc(Loc); + if (Presumed.isInvalid()) + return false; + StringRef Filename(Presumed.getFilename()); return Filename.equals("<built-in>"); } /// Returns whether \p Loc is located in a <command line> file. bool isWrittenInCommandLineFile(SourceLocation Loc) const { - StringRef Filename(getPresumedLoc(Loc).getFilename()); + PresumedLoc Presumed = getPresumedLoc(Loc); + if (Presumed.isInvalid()) + return false; + StringRef Filename(Presumed.getFilename()); return Filename.equals("<command line>"); } /// Returns whether \p Loc is located in a <scratch space> file. bool isWrittenInScratchSpace(SourceLocation Loc) const { - StringRef Filename(getPresumedLoc(Loc).getFilename()); + PresumedLoc Presumed = getPresumedLoc(Loc); + if (Presumed.isInvalid()) + return false; + StringRef Filename(Presumed.getFilename()); return Filename.equals("<scratch space>"); } /// Returns if a SourceLocation is in a system header. bool isInSystemHeader(SourceLocation Loc) const { + if (Loc.isInvalid()) + return false; return isSystem(getFileCharacteristic(Loc)); } diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index dadfcc94ac0d3..e98100faedbe2 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -51,6 +51,73 @@ class SourceManagerTest : public ::testing::Test { IntrusiveRefCntPtr<TargetInfo> Target; }; +TEST_F(SourceManagerTest, isInMemoryBuffersNoSourceLocationInfo) { + // Check for invalid source location for each method + SourceLocation LocEmpty; + bool isWrittenInBuiltInFileFalse = SourceMgr.isWrittenInBuiltinFile(LocEmpty); + bool isWrittenInCommandLineFileFalse = + SourceMgr.isWrittenInCommandLineFile(LocEmpty); + bool isWrittenInScratchSpaceFalse = + SourceMgr.isWrittenInScratchSpace(LocEmpty); + + EXPECT_FALSE(isWrittenInBuiltInFileFalse); + EXPECT_FALSE(isWrittenInCommandLineFileFalse); + EXPECT_FALSE(isWrittenInScratchSpaceFalse); + + // Check for valid source location per filename for each method + const char *Source = "int x"; + + std::unique_ptr<llvm::MemoryBuffer> BuiltInBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *BuiltInFile = + FileMgr.getVirtualFile("<built-in>", BuiltInBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(BuiltInFile, std::move(BuiltInBuf)); + FileID BuiltInFileID = + SourceMgr.getOrCreateFileID(BuiltInFile, SrcMgr::C_User); + SourceMgr.setMainFileID(BuiltInFileID); + SourceLocation LocBuiltIn = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInBuiltInFileTrue = + SourceMgr.isWrittenInBuiltinFile(LocBuiltIn); + + std::unique_ptr<llvm::MemoryBuffer> CommandLineBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *CommandLineFile = FileMgr.getVirtualFile( + "<command line>", CommandLineBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(CommandLineFile, std::move(CommandLineBuf)); + FileID CommandLineFileID = + SourceMgr.getOrCreateFileID(CommandLineFile, SrcMgr::C_User); + SourceMgr.setMainFileID(CommandLineFileID); + SourceLocation LocCommandLine = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInCommandLineFileTrue = + SourceMgr.isWrittenInCommandLineFile(LocCommandLine); + + std::unique_ptr<llvm::MemoryBuffer> ScratchSpaceBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *ScratchSpaceFile = FileMgr.getVirtualFile( + "<scratch space>", ScratchSpaceBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(ScratchSpaceFile, std::move(ScratchSpaceBuf)); + FileID ScratchSpaceFileID = + SourceMgr.getOrCreateFileID(ScratchSpaceFile, SrcMgr::C_User); + SourceMgr.setMainFileID(ScratchSpaceFileID); + SourceLocation LocScratchSpace = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInScratchSpaceTrue = + SourceMgr.isWrittenInScratchSpace(LocScratchSpace); + + EXPECT_TRUE(isWrittenInBuiltInFileTrue); + EXPECT_TRUE(isWrittenInCommandLineFileTrue); + EXPECT_TRUE(isWrittenInScratchSpaceTrue); +} + +TEST_F(SourceManagerTest, isInSystemHeader) { + // Check for invalid source location + SourceLocation LocEmpty; + bool isInSystemHeaderFalse = SourceMgr.isInSystemHeader(LocEmpty); + ASSERT_FALSE(isInSystemHeaderFalse); +} + TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { const char *source = "#define M(x) [x]\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits