diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1470,24 +1470,35 @@ /// Returns whether \p Loc is located in a 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(""); } /// Returns whether \p Loc is located in a 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(""); } /// Returns whether \p Loc is located in a 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(""); } /// 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/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp --- a/unittests/Basic/SourceManagerTest.cpp +++ b/unittests/Basic/SourceManagerTest.cpp @@ -51,6 +51,64 @@ IntrusiveRefCntPtr Target; }; +TEST_F(SourceManagerTest, isInMemoryBuffersNoSourceLocationInfo) { + SourceLocation Loc = NULL; + bool isWrittenInBuiltInFileFalse = SourceMgr.isWrittenInBuiltinFile(Loc); + bool isWrittenInCommandLineFileFalse = + SourceManager::isWrittenInCommandLineFile(Loc); + bool isWrittenInScratchSpaceFalse = SourceMgr.isWrittenInScratchSpace(Loc); + + EXPECT_FALSE(inBuiltInFileFalse); + EXPECT_FALSE(isWrittenInCommandLindFileFalse); + EXPECT_FALSE(isWrittenInScratchSpaceFalse); + + const char *Source = "int x"; + + std::unique_ptr BuiltInBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *BuiltInFile = + FileMgr.getVirtualFile("", BuiltInBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(BuiltInFile, std::move(BuiltInBuf)); + FileID BuiltInFileID = + SourceMgr.getOrCreateFileID(BuiltInFile, SrcMgr::C_User); + SourceMgr.setMainFileID(BuiltInFileID); + Loc = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInBuiltInFileTrue = SourceMgr.isWrittenInBuiltinFile(Loc); + + std::unique_ptr CommandLineBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *CommandLineFile = FileMgr.getVirtualFile( + "", CommandLineBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(CommandLineFile, std::move(CommandLineBuf)); + FileID BuiltInFileID = + SourceMgr.getOrCreateFileID(CommandLineFile, SrcMgr::C_User); + SourceMgr.setMainFileID(CommandLineFileID); + Loc = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInCommandLineFileTrue = + SourceMgr.isWrittenInCommandLineFile(Loc); + + std::unique_ptr ScratchSpaceBuf = + llvm::MemoryBuffer::getMemBuffer(Source); + const FileEntry *ScratchSpaceFile = FileMgr.getVirtualFile( + "", ScratchSpaceBuf->getBufferSize(), 0); + SourceMgr.overrideFileContents(CommandLineFile, std::move(ScratchSpaceBuf)); + FileID ScratchSpaceID = + SourceMgr.getOrCreateFileID(ScratchSpaceFile, SrcMgr::C_User); + SourceMgr.setMainFileID(ScratchSpaceFileID); + Loc = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + bool isWrittenInScratchSpaceTrue = SourceMgr.isWrittenInScratchSpace(Loc); + + EXPECT_TRUE(inWrittenInBuiltInFileTrue); + EXPECT_TRUE(isWrittenInCommandLineFileTrue); + EXPECT_TRUE(isWrittenInScratchSpaceTrue); +} + +TEST_F(SourceManagerTest, isInSystemHeader) { + SourceLocation Loc = NULL; + bool isInSystemHeaderFalse = SourceMgr.isInSystemHeader(Loc); + ASSERT_FALSE(isInSystemHeaderFalse); +} + TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { const char *source = "#define M(x) [x]\n"