diff options
author | kadir çetinkaya <kadircet@google.com> | 2024-08-30 11:57:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-30 11:57:37 +0200 |
commit | a2a93f02930e20930d5ef38464ca9c99eb00ff23 (patch) | |
tree | b54e4c4e60867b9b089def3f0180e862c443efea /clang/unittests/Basic/SourceManagerTest.cpp | |
parent | 1b32c3e2985f89900030289eaa44e3d92cab85af (diff) | |
download | llvm-a2a93f02930e20930d5ef38464ca9c99eb00ff23.zip llvm-a2a93f02930e20930d5ef38464ca9c99eb00ff23.tar.gz llvm-a2a93f02930e20930d5ef38464ca9c99eb00ff23.tar.bz2 |
[clang] Cleanup IncludeLocMap (#106241)
CompilerInstance can re-use same SourceManager across multiple
frontendactions. During this process it calls
`SourceManager::clearIDTables` to reset any caches based on FileIDs.
It didn't reset IncludeLocMap, resulting in wrong include locations for
workflows that triggered multiple frontend-actions through same
CompilerInstance.
Diffstat (limited to 'clang/unittests/Basic/SourceManagerTest.cpp')
-rw-r--r-- | clang/unittests/Basic/SourceManagerTest.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index 45840f5..0f2476b 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -20,6 +20,7 @@ #include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Process.h" #include "gtest/gtest.h" #include <cstddef> @@ -453,6 +454,65 @@ TEST_F(SourceManagerTest, loadedSLocEntryIsInTheSameTranslationUnit) { #if defined(LLVM_ON_UNIX) +// A single SourceManager instance is sometimes reused across multiple +// compilations. This test makes sure we're resetting caches built for tracking +// include locations that are based on FileIDs, to make sure we don't report +// wrong include locations when FileIDs coincide between two different runs. +TEST_F(SourceManagerTest, ResetsIncludeLocMap) { + auto ParseFile = [&] { + TrivialModuleLoader ModLoader; + HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr, + Diags, LangOpts, &*Target); + Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts, + SourceMgr, HeaderInfo, ModLoader, + /*IILookup =*/nullptr, + /*OwnsHeaderSearch =*/false); + PP.Initialize(*Target); + PP.EnterMainSourceFile(); + PP.LexTokensUntilEOF(); + EXPECT_FALSE(Diags.hasErrorOccurred()); + }; + + auto Buf = llvm::MemoryBuffer::getMemBuffer(""); + FileEntryRef HeaderFile = + FileMgr.getVirtualFileRef("/foo.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(HeaderFile, std::move(Buf)); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileEntryRef BarFile = + FileMgr.getVirtualFileRef("/bar.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(BarFile, std::move(Buf)); + SourceMgr.createFileID(BarFile, {}, clang::SrcMgr::C_User); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileID MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + auto FooFID = SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User); + auto IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + EXPECT_EQ(IncFID, MFID); + + // Clean up source-manager state before we start next parse. + SourceMgr.clearIDTables(); + + // Set up a new main file. + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp( + // silly comment 42 + #include "/bar.h")cpp"); + MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + // Make sure foo.h got the same file-id in both runs. + EXPECT_EQ(FooFID, + SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User)); + auto BarFID = SourceMgr.getOrCreateFileID(BarFile, clang::SrcMgr::C_User); + IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + // Check that includer is bar.h during this run. + EXPECT_EQ(IncFID, BarFID); +} + TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { const char *header = "#define FM(x,y) x\n"; |