[clang] a2a93f0 - [clang] Cleanup IncludeLocMap (#106241)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 30 02:57:40 PDT 2024
Author: kadir çetinkaya
Date: 2024-08-30T11:57:37+02:00
New Revision: a2a93f02930e20930d5ef38464ca9c99eb00ff23
URL: https://github.com/llvm/llvm-project/commit/a2a93f02930e20930d5ef38464ca9c99eb00ff23
DIFF: https://github.com/llvm/llvm-project/commit/a2a93f02930e20930d5ef38464ca9c99eb00ff23.diff
LOG: [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.
Added:
Modified:
clang/lib/Basic/SourceManager.cpp
clang/unittests/Basic/SourceManagerTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index b0256a8ce9ed04..d6ec26af80aadd 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -350,6 +350,7 @@ void SourceManager::clearIDTables() {
LastLineNoContentCache = nullptr;
LastFileIDLookup = FileID();
+ IncludedLocMap.clear();
if (LineTable)
LineTable->clear();
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp
index 45840f5188cdcd..0f2476bd8b0612 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
diff erent 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";
More information about the cfe-commits
mailing list