Skip to content

[clang][modules] Introduce new ModuleCache interface #131193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang-tools-extra/clangd/ModulesBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/ModuleCache.h"
#include "llvm/ADT/ScopeExit.h"
#include <queue>

Expand Down Expand Up @@ -206,9 +206,9 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,
Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts,
SourceMgr, HeaderInfo, ModuleLoader);

IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache = new InMemoryModuleCache;
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
PCHContainerOperations PCHOperations;
ASTReader Reader(PP, *ModuleCache, /*ASTContext=*/nullptr,
ASTReader Reader(PP, *ModCache, /*ASTContext=*/nullptr,
PCHOperations.getRawReader(), {});

// We don't need any listener here. By default it will use a validator
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Frontend/ASTUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class FileManager;
class FrontendAction;
class HeaderSearch;
class InputKind;
class InMemoryModuleCache;
class ModuleCache;
class PCHContainerOperations;
class PCHContainerReader;
class Preprocessor;
Expand Down Expand Up @@ -110,7 +110,7 @@ class ASTUnit {
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
IntrusiveRefCntPtr<FileManager> FileMgr;
IntrusiveRefCntPtr<SourceManager> SourceMgr;
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
IntrusiveRefCntPtr<ModuleCache> ModCache;
std::unique_ptr<HeaderSearch> HeaderInfo;
IntrusiveRefCntPtr<TargetInfo> Target;
std::shared_ptr<Preprocessor> PP;
Expand Down
13 changes: 6 additions & 7 deletions clang/include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class DiagnosticsEngine;
class DiagnosticConsumer;
class FileManager;
class FrontendAction;
class InMemoryModuleCache;
class Module;
class ModuleCache;
class Preprocessor;
class Sema;
class SourceManager;
Expand Down Expand Up @@ -97,7 +97,7 @@ class CompilerInstance : public ModuleLoader {
IntrusiveRefCntPtr<SourceManager> SourceMgr;

/// The cache of PCM files.
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
IntrusiveRefCntPtr<ModuleCache> ModCache;

/// The preprocessor.
std::shared_ptr<Preprocessor> PP;
Expand Down Expand Up @@ -209,7 +209,7 @@ class CompilerInstance : public ModuleLoader {
explicit CompilerInstance(
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>(),
InMemoryModuleCache *SharedModuleCache = nullptr);
ModuleCache *ModCache = nullptr);
~CompilerInstance() override;

/// @name High-Level Operations
Expand Down Expand Up @@ -746,9 +746,8 @@ class CompilerInstance : public ModuleLoader {
static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
StringRef Path, StringRef Sysroot,
DisableValidationForModuleKind DisableValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP,
InMemoryModuleCache &ModuleCache, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
void *DeserializationListener, bool OwnDeserializationListener,
Expand Down Expand Up @@ -896,7 +895,7 @@ class CompilerInstance : public ModuleLoader {

void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);

InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
ModuleCache &getModuleCache() const { return *ModCache; }
};

} // end namespace clang
Expand Down
11 changes: 5 additions & 6 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct HeaderFileInfo;
class HeaderSearchOptions;
class LangOptions;
class MacroInfo;
class InMemoryModuleCache;
class ModuleCache;
class NamedDecl;
class NamespaceDecl;
class ObjCCategoryDecl;
Expand Down Expand Up @@ -1742,8 +1742,8 @@ class ASTReader
///
/// \param ReadTimer If non-null, a timer used to track the time spent
/// deserializing.
ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
ASTContext *Context, const PCHContainerReader &PCHContainerRdr,
ASTReader(Preprocessor &PP, ModuleCache &ModCache, ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot = "",
DisableValidationForModuleKind DisableValidationKind =
Expand Down Expand Up @@ -1954,8 +1954,7 @@ class ASTReader
///
/// \returns true if an error occurred, false otherwise.
static bool readASTFileControlBlock(
StringRef Filename, FileManager &FileMgr,
const InMemoryModuleCache &ModuleCache,
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
unsigned ClientLoadCapabilities = ARR_ConfigurationMismatch |
Expand All @@ -1964,7 +1963,7 @@ class ASTReader
/// Determine whether the given AST file is acceptable to load into a
/// translation unit with the given language and target options.
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
const InMemoryModuleCache &ModuleCache,
const ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
Expand Down
21 changes: 10 additions & 11 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class LangOptions;
class MacroDefinitionRecord;
class MacroInfo;
class Module;
class InMemoryModuleCache;
class ModuleCache;
class ModuleFileExtension;
class ModuleFileExtensionWriter;
class NamedDecl;
Expand Down Expand Up @@ -117,7 +117,7 @@ class ASTWriter : public ASTDeserializationListener,
const SmallVectorImpl<char> &Buffer;

/// The PCM manager which manages memory buffers for pcm files.
InMemoryModuleCache &ModuleCache;
ModuleCache &ModCache;

/// The preprocessor we're writing.
Preprocessor *PP = nullptr;
Expand Down Expand Up @@ -682,7 +682,7 @@ class ASTWriter : public ASTDeserializationListener,
/// Create a new precompiled header writer that outputs to
/// the given bitstream.
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
InMemoryModuleCache &ModuleCache,
ModuleCache &ModCache,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool IncludeTimestamps = true, bool BuildingImplicitModule = false,
bool GeneratingReducedBMI = false);
Expand Down Expand Up @@ -986,9 +986,8 @@ class PCHGenerator : public SemaConsumer {
virtual Module *getEmittingModule(ASTContext &Ctx);

public:
PCHGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile, StringRef isysroot,
std::shared_ptr<PCHBuffer> Buffer,
PCHGenerator(Preprocessor &PP, ModuleCache &ModCache, StringRef OutputFile,
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
bool BuildingImplicitModule = false,
Expand All @@ -1010,14 +1009,14 @@ class CXX20ModulesGenerator : public PCHGenerator {
protected:
virtual Module *getEmittingModule(ASTContext &Ctx) override;

CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool GeneratingReducedBMI,
bool AllowASTWithErrors);

public:
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
/*GeneratingReducedBMI=*/false,
AllowASTWithErrors) {}

Expand All @@ -1028,9 +1027,9 @@ class ReducedBMIGenerator : public CXX20ModulesGenerator {
void anchor() override;

public:
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
ReducedBMIGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
/*GeneratingReducedBMI=*/true,
AllowASTWithErrors) {}
};
Expand Down
50 changes: 50 additions & 0 deletions clang/include/clang/Serialization/ModuleCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SERIALIZATION_MODULECACHE_H
#define LLVM_CLANG_SERIALIZATION_MODULECACHE_H

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"

namespace llvm {
class AdvisoryLock;
} // namespace llvm

namespace clang {
class InMemoryModuleCache;

/// The module cache used for compiling modules implicitly. This centralizes the
/// operations the compiler might want to perform on the cache.
class ModuleCache : public RefCountedBase<ModuleCache> {
public:
/// May perform any work that only needs to be performed once for multiple
/// calls \c getLock() with the same module filename.
virtual void prepareForGetLock(StringRef ModuleFilename) = 0;

/// Returns lock for the given module file. The lock is initially unlocked.
virtual std::unique_ptr<llvm::AdvisoryLock>
getLock(StringRef ModuleFilename) = 0;

/// Returns this process's view of the module cache.
virtual InMemoryModuleCache &getInMemoryModuleCache() = 0;
virtual const InMemoryModuleCache &getInMemoryModuleCache() const = 0;

// TODO: Virtualize writing/reading PCM files, timestamping, pruning, etc.

virtual ~ModuleCache() = default;
};

/// Creates new \c ModuleCache backed by a file system directory that may be
/// operated on by multiple processes. This instance must be used across all
/// \c CompilerInstance instances participating in building modules for single
/// translation unit in order to share the same \c InMemoryModuleCache.
IntrusiveRefCntPtr<ModuleCache> createCrossProcessModuleCache();
} // namespace clang

#endif
12 changes: 6 additions & 6 deletions clang/include/clang/Serialization/ModuleManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class FileEntry;
class FileManager;
class GlobalModuleIndex;
class HeaderSearch;
class InMemoryModuleCache;
class ModuleCache;
class PCHContainerReader;

namespace serialization {
Expand Down Expand Up @@ -65,7 +65,7 @@ class ModuleManager {
FileManager &FileMgr;

/// Cache of PCM files.
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
IntrusiveRefCntPtr<ModuleCache> ModCache;

/// Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
Expand Down Expand Up @@ -133,9 +133,9 @@ class ModuleManager {
SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
using ModuleOffset = std::pair<uint32_t, StringRef>;

explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch &HeaderSearchInfo);
ModuleManager(FileManager &FileMgr, ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch &HeaderSearchInfo);

/// Forward iterator to traverse all loaded modules.
ModuleIterator begin() { return Chain.begin(); }
Expand Down Expand Up @@ -306,7 +306,7 @@ class ModuleManager {
/// View the graphviz representation of the module graph.
void viewGraph();

InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
ModuleCache &getModuleCache() const { return *ModCache; }
};

} // namespace serialization
Expand Down
21 changes: 10 additions & 11 deletions clang/lib/Frontend/ASTUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/ModuleCache.h"
#include "clang/Serialization/ModuleFile.h"
#include "clang/Serialization/PCHContainerOperations.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -219,8 +219,8 @@ struct ASTUnit::ASTWriterData {
llvm::BitstreamWriter Stream;
ASTWriter Writer;

ASTWriterData(InMemoryModuleCache &ModuleCache)
: Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
ASTWriterData(ModuleCache &ModCache)
: Stream(Buffer), Writer(Stream, Buffer, ModCache, {}) {}
};

void ASTUnit::clearFileLevelDecls() {
Expand Down Expand Up @@ -829,7 +829,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
AST->getFileManager(),
UserFilesAreVolatile);
AST->ModuleCache = new InMemoryModuleCache;
AST->ModCache = createCrossProcessModuleCache();
AST->HSOpts = HSOpts ? HSOpts : std::make_shared<HeaderSearchOptions>();
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
Expand Down Expand Up @@ -861,8 +861,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = DisableValidationForModuleKind::All;
AST->Reader = new ASTReader(
PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
/*isysroot=*/"",
PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"",
/*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);

unsigned Counter = 0;
Expand Down Expand Up @@ -1546,7 +1545,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
AST->UserFilesAreVolatile = UserFilesAreVolatile;
AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
UserFilesAreVolatile);
AST->ModuleCache = new InMemoryModuleCache;
AST->ModCache = createCrossProcessModuleCache();

return AST;
}
Expand Down Expand Up @@ -1833,7 +1832,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
AST->StorePreamblesInMemory = StorePreamblesInMemory;
AST->PreambleStoragePath = PreambleStoragePath;
AST->ModuleCache = new InMemoryModuleCache;
AST->ModCache = createCrossProcessModuleCache();
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
Expand All @@ -1844,7 +1843,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
AST->Invocation = CI;
AST->SkipFunctionBodies = SkipFunctionBodies;
if (ForSerialization)
AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
AST->WriterData.reset(new ASTWriterData(*AST->ModCache));
// Zero out now to ease cleanup during crash recovery.
CI = nullptr;
Diags = nullptr;
Expand Down Expand Up @@ -2379,8 +2378,8 @@ bool ASTUnit::serialize(raw_ostream &OS) {

SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
InMemoryModuleCache ModuleCache;
ASTWriter Writer(Stream, Buffer, ModuleCache, {});
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
ASTWriter Writer(Stream, Buffer, *ModCache, {});
return serializeUnit(Writer, Buffer, getSema(), OS);
}

Expand Down
Loading
Loading