[clang][modules] Introduce new ModuleCache
interface (#131193)
This PR adds new `ModuleCache` interface to Clang's implicitly-built modules machinery. The main motivation for this change is to create a second implementation that uses a more efficient kind of `llvm::AdvisoryLock` during dependency scanning. In addition to the lock abstraction, the `ModuleCache` interface also manages the existing `InMemoryModuleCache` instance. I found that compared to keeping these separate/independent, the code is a bit simpler now, since these are two tightly coupled concepts. I can envision a more efficient implementation of the `InMemoryModuleCache` for the single-process case too, which will be much easier to implement with the current setup. This is not intended to be a functional change.
This commit is contained in:
parent
d0a0de50f7
commit
c84d8e8f1c
@ -12,7 +12,7 @@
|
|||||||
#include "clang/Frontend/FrontendAction.h"
|
#include "clang/Frontend/FrontendAction.h"
|
||||||
#include "clang/Frontend/FrontendActions.h"
|
#include "clang/Frontend/FrontendActions.h"
|
||||||
#include "clang/Serialization/ASTReader.h"
|
#include "clang/Serialization/ASTReader.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "llvm/ADT/ScopeExit.h"
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
@ -206,9 +206,9 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,
|
|||||||
Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts,
|
Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts,
|
||||||
SourceMgr, HeaderInfo, ModuleLoader);
|
SourceMgr, HeaderInfo, ModuleLoader);
|
||||||
|
|
||||||
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache = new InMemoryModuleCache;
|
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
|
||||||
PCHContainerOperations PCHOperations;
|
PCHContainerOperations PCHOperations;
|
||||||
ASTReader Reader(PP, *ModuleCache, /*ASTContext=*/nullptr,
|
ASTReader Reader(PP, *ModCache, /*ASTContext=*/nullptr,
|
||||||
PCHOperations.getRawReader(), {});
|
PCHOperations.getRawReader(), {});
|
||||||
|
|
||||||
// We don't need any listener here. By default it will use a validator
|
// We don't need any listener here. By default it will use a validator
|
||||||
|
@ -70,7 +70,7 @@ class FileManager;
|
|||||||
class FrontendAction;
|
class FrontendAction;
|
||||||
class HeaderSearch;
|
class HeaderSearch;
|
||||||
class InputKind;
|
class InputKind;
|
||||||
class InMemoryModuleCache;
|
class ModuleCache;
|
||||||
class PCHContainerOperations;
|
class PCHContainerOperations;
|
||||||
class PCHContainerReader;
|
class PCHContainerReader;
|
||||||
class Preprocessor;
|
class Preprocessor;
|
||||||
@ -110,7 +110,7 @@ private:
|
|||||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
|
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
|
||||||
IntrusiveRefCntPtr<FileManager> FileMgr;
|
IntrusiveRefCntPtr<FileManager> FileMgr;
|
||||||
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
||||||
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
|
IntrusiveRefCntPtr<ModuleCache> ModCache;
|
||||||
std::unique_ptr<HeaderSearch> HeaderInfo;
|
std::unique_ptr<HeaderSearch> HeaderInfo;
|
||||||
IntrusiveRefCntPtr<TargetInfo> Target;
|
IntrusiveRefCntPtr<TargetInfo> Target;
|
||||||
std::shared_ptr<Preprocessor> PP;
|
std::shared_ptr<Preprocessor> PP;
|
||||||
|
@ -51,8 +51,8 @@ class DiagnosticsEngine;
|
|||||||
class DiagnosticConsumer;
|
class DiagnosticConsumer;
|
||||||
class FileManager;
|
class FileManager;
|
||||||
class FrontendAction;
|
class FrontendAction;
|
||||||
class InMemoryModuleCache;
|
|
||||||
class Module;
|
class Module;
|
||||||
|
class ModuleCache;
|
||||||
class Preprocessor;
|
class Preprocessor;
|
||||||
class Sema;
|
class Sema;
|
||||||
class SourceManager;
|
class SourceManager;
|
||||||
@ -97,7 +97,7 @@ class CompilerInstance : public ModuleLoader {
|
|||||||
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
||||||
|
|
||||||
/// The cache of PCM files.
|
/// The cache of PCM files.
|
||||||
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
|
IntrusiveRefCntPtr<ModuleCache> ModCache;
|
||||||
|
|
||||||
/// The preprocessor.
|
/// The preprocessor.
|
||||||
std::shared_ptr<Preprocessor> PP;
|
std::shared_ptr<Preprocessor> PP;
|
||||||
@ -209,7 +209,7 @@ public:
|
|||||||
explicit CompilerInstance(
|
explicit CompilerInstance(
|
||||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
|
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
|
||||||
std::make_shared<PCHContainerOperations>(),
|
std::make_shared<PCHContainerOperations>(),
|
||||||
InMemoryModuleCache *SharedModuleCache = nullptr);
|
ModuleCache *ModCache = nullptr);
|
||||||
~CompilerInstance() override;
|
~CompilerInstance() override;
|
||||||
|
|
||||||
/// @name High-Level Operations
|
/// @name High-Level Operations
|
||||||
@ -746,9 +746,8 @@ public:
|
|||||||
static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
|
static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
|
||||||
StringRef Path, StringRef Sysroot,
|
StringRef Path, StringRef Sysroot,
|
||||||
DisableValidationForModuleKind DisableValidation,
|
DisableValidationForModuleKind DisableValidation,
|
||||||
bool AllowPCHWithCompilerErrors, Preprocessor &PP,
|
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
|
||||||
InMemoryModuleCache &ModuleCache, ASTContext &Context,
|
ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
|
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
|
||||||
void *DeserializationListener, bool OwnDeserializationListener,
|
void *DeserializationListener, bool OwnDeserializationListener,
|
||||||
@ -896,7 +895,7 @@ public:
|
|||||||
|
|
||||||
void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
|
void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
|
||||||
|
|
||||||
InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
|
ModuleCache &getModuleCache() const { return *ModCache; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
@ -89,7 +89,7 @@ struct HeaderFileInfo;
|
|||||||
class HeaderSearchOptions;
|
class HeaderSearchOptions;
|
||||||
class LangOptions;
|
class LangOptions;
|
||||||
class MacroInfo;
|
class MacroInfo;
|
||||||
class InMemoryModuleCache;
|
class ModuleCache;
|
||||||
class NamedDecl;
|
class NamedDecl;
|
||||||
class NamespaceDecl;
|
class NamespaceDecl;
|
||||||
class ObjCCategoryDecl;
|
class ObjCCategoryDecl;
|
||||||
@ -1742,8 +1742,8 @@ public:
|
|||||||
///
|
///
|
||||||
/// \param ReadTimer If non-null, a timer used to track the time spent
|
/// \param ReadTimer If non-null, a timer used to track the time spent
|
||||||
/// deserializing.
|
/// deserializing.
|
||||||
ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
ASTReader(Preprocessor &PP, ModuleCache &ModCache, ASTContext *Context,
|
||||||
ASTContext *Context, const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr,
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
StringRef isysroot = "",
|
StringRef isysroot = "",
|
||||||
DisableValidationForModuleKind DisableValidationKind =
|
DisableValidationForModuleKind DisableValidationKind =
|
||||||
@ -1954,8 +1954,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \returns true if an error occurred, false otherwise.
|
/// \returns true if an error occurred, false otherwise.
|
||||||
static bool readASTFileControlBlock(
|
static bool readASTFileControlBlock(
|
||||||
StringRef Filename, FileManager &FileMgr,
|
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
|
||||||
const InMemoryModuleCache &ModuleCache,
|
|
||||||
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
|
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
|
||||||
ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
|
ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
|
||||||
unsigned ClientLoadCapabilities = ARR_ConfigurationMismatch |
|
unsigned ClientLoadCapabilities = ARR_ConfigurationMismatch |
|
||||||
@ -1964,7 +1963,7 @@ public:
|
|||||||
/// Determine whether the given AST file is acceptable to load into a
|
/// Determine whether the given AST file is acceptable to load into a
|
||||||
/// translation unit with the given language and target options.
|
/// translation unit with the given language and target options.
|
||||||
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
|
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
|
||||||
const InMemoryModuleCache &ModuleCache,
|
const ModuleCache &ModCache,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr,
|
||||||
const LangOptions &LangOpts,
|
const LangOptions &LangOpts,
|
||||||
const TargetOptions &TargetOpts,
|
const TargetOptions &TargetOpts,
|
||||||
|
@ -60,7 +60,7 @@ class LangOptions;
|
|||||||
class MacroDefinitionRecord;
|
class MacroDefinitionRecord;
|
||||||
class MacroInfo;
|
class MacroInfo;
|
||||||
class Module;
|
class Module;
|
||||||
class InMemoryModuleCache;
|
class ModuleCache;
|
||||||
class ModuleFileExtension;
|
class ModuleFileExtension;
|
||||||
class ModuleFileExtensionWriter;
|
class ModuleFileExtensionWriter;
|
||||||
class NamedDecl;
|
class NamedDecl;
|
||||||
@ -117,7 +117,7 @@ private:
|
|||||||
const SmallVectorImpl<char> &Buffer;
|
const SmallVectorImpl<char> &Buffer;
|
||||||
|
|
||||||
/// The PCM manager which manages memory buffers for pcm files.
|
/// The PCM manager which manages memory buffers for pcm files.
|
||||||
InMemoryModuleCache &ModuleCache;
|
ModuleCache &ModCache;
|
||||||
|
|
||||||
/// The preprocessor we're writing.
|
/// The preprocessor we're writing.
|
||||||
Preprocessor *PP = nullptr;
|
Preprocessor *PP = nullptr;
|
||||||
@ -682,7 +682,7 @@ public:
|
|||||||
/// Create a new precompiled header writer that outputs to
|
/// Create a new precompiled header writer that outputs to
|
||||||
/// the given bitstream.
|
/// the given bitstream.
|
||||||
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
|
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
|
||||||
InMemoryModuleCache &ModuleCache,
|
ModuleCache &ModCache,
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
bool IncludeTimestamps = true, bool BuildingImplicitModule = false,
|
bool IncludeTimestamps = true, bool BuildingImplicitModule = false,
|
||||||
bool GeneratingReducedBMI = false);
|
bool GeneratingReducedBMI = false);
|
||||||
@ -986,9 +986,8 @@ protected:
|
|||||||
virtual Module *getEmittingModule(ASTContext &Ctx);
|
virtual Module *getEmittingModule(ASTContext &Ctx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PCHGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
PCHGenerator(Preprocessor &PP, ModuleCache &ModCache, StringRef OutputFile,
|
||||||
StringRef OutputFile, StringRef isysroot,
|
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
|
||||||
std::shared_ptr<PCHBuffer> Buffer,
|
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
|
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
|
||||||
bool BuildingImplicitModule = false,
|
bool BuildingImplicitModule = false,
|
||||||
@ -1010,14 +1009,14 @@ class CXX20ModulesGenerator : public PCHGenerator {
|
|||||||
protected:
|
protected:
|
||||||
virtual Module *getEmittingModule(ASTContext &Ctx) override;
|
virtual Module *getEmittingModule(ASTContext &Ctx) override;
|
||||||
|
|
||||||
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
|
||||||
StringRef OutputFile, bool GeneratingReducedBMI,
|
StringRef OutputFile, bool GeneratingReducedBMI,
|
||||||
bool AllowASTWithErrors);
|
bool AllowASTWithErrors);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
|
||||||
StringRef OutputFile, bool AllowASTWithErrors = false)
|
StringRef OutputFile, bool AllowASTWithErrors = false)
|
||||||
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
|
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
|
||||||
/*GeneratingReducedBMI=*/false,
|
/*GeneratingReducedBMI=*/false,
|
||||||
AllowASTWithErrors) {}
|
AllowASTWithErrors) {}
|
||||||
|
|
||||||
@ -1028,9 +1027,9 @@ class ReducedBMIGenerator : public CXX20ModulesGenerator {
|
|||||||
void anchor() override;
|
void anchor() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
ReducedBMIGenerator(Preprocessor &PP, ModuleCache &ModCache,
|
||||||
StringRef OutputFile, bool AllowASTWithErrors = false)
|
StringRef OutputFile, bool AllowASTWithErrors = false)
|
||||||
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
|
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
|
||||||
/*GeneratingReducedBMI=*/true,
|
/*GeneratingReducedBMI=*/true,
|
||||||
AllowASTWithErrors) {}
|
AllowASTWithErrors) {}
|
||||||
};
|
};
|
||||||
|
50
clang/include/clang/Serialization/ModuleCache.h
Normal file
50
clang/include/clang/Serialization/ModuleCache.h
Normal file
@ -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
|
@ -37,7 +37,7 @@ class FileEntry;
|
|||||||
class FileManager;
|
class FileManager;
|
||||||
class GlobalModuleIndex;
|
class GlobalModuleIndex;
|
||||||
class HeaderSearch;
|
class HeaderSearch;
|
||||||
class InMemoryModuleCache;
|
class ModuleCache;
|
||||||
class PCHContainerReader;
|
class PCHContainerReader;
|
||||||
|
|
||||||
namespace serialization {
|
namespace serialization {
|
||||||
@ -65,7 +65,7 @@ class ModuleManager {
|
|||||||
FileManager &FileMgr;
|
FileManager &FileMgr;
|
||||||
|
|
||||||
/// Cache of PCM files.
|
/// Cache of PCM files.
|
||||||
IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
|
IntrusiveRefCntPtr<ModuleCache> ModCache;
|
||||||
|
|
||||||
/// Knows how to unwrap module containers.
|
/// Knows how to unwrap module containers.
|
||||||
const PCHContainerReader &PCHContainerRdr;
|
const PCHContainerReader &PCHContainerRdr;
|
||||||
@ -133,9 +133,9 @@ public:
|
|||||||
SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
|
SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
|
||||||
using ModuleOffset = std::pair<uint32_t, StringRef>;
|
using ModuleOffset = std::pair<uint32_t, StringRef>;
|
||||||
|
|
||||||
explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache,
|
ModuleManager(FileManager &FileMgr, ModuleCache &ModCache,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr,
|
||||||
const HeaderSearch &HeaderSearchInfo);
|
const HeaderSearch &HeaderSearchInfo);
|
||||||
|
|
||||||
/// Forward iterator to traverse all loaded modules.
|
/// Forward iterator to traverse all loaded modules.
|
||||||
ModuleIterator begin() { return Chain.begin(); }
|
ModuleIterator begin() { return Chain.begin(); }
|
||||||
@ -306,7 +306,7 @@ public:
|
|||||||
/// View the graphviz representation of the module graph.
|
/// View the graphviz representation of the module graph.
|
||||||
void viewGraph();
|
void viewGraph();
|
||||||
|
|
||||||
InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
|
ModuleCache &getModuleCache() const { return *ModCache; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace serialization
|
} // namespace serialization
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
#include "clang/Serialization/ASTReader.h"
|
#include "clang/Serialization/ASTReader.h"
|
||||||
#include "clang/Serialization/ASTWriter.h"
|
#include "clang/Serialization/ASTWriter.h"
|
||||||
#include "clang/Serialization/ContinuousRangeMap.h"
|
#include "clang/Serialization/ContinuousRangeMap.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "clang/Serialization/ModuleFile.h"
|
#include "clang/Serialization/ModuleFile.h"
|
||||||
#include "clang/Serialization/PCHContainerOperations.h"
|
#include "clang/Serialization/PCHContainerOperations.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
@ -219,8 +219,8 @@ struct ASTUnit::ASTWriterData {
|
|||||||
llvm::BitstreamWriter Stream;
|
llvm::BitstreamWriter Stream;
|
||||||
ASTWriter Writer;
|
ASTWriter Writer;
|
||||||
|
|
||||||
ASTWriterData(InMemoryModuleCache &ModuleCache)
|
ASTWriterData(ModuleCache &ModCache)
|
||||||
: Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
|
: Stream(Buffer), Writer(Stream, Buffer, ModCache, {}) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ASTUnit::clearFileLevelDecls() {
|
void ASTUnit::clearFileLevelDecls() {
|
||||||
@ -829,7 +829,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
|
|||||||
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
|
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
|
||||||
AST->getFileManager(),
|
AST->getFileManager(),
|
||||||
UserFilesAreVolatile);
|
UserFilesAreVolatile);
|
||||||
AST->ModuleCache = new InMemoryModuleCache;
|
AST->ModCache = createCrossProcessModuleCache();
|
||||||
AST->HSOpts = HSOpts ? HSOpts : std::make_shared<HeaderSearchOptions>();
|
AST->HSOpts = HSOpts ? HSOpts : std::make_shared<HeaderSearchOptions>();
|
||||||
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
|
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
|
||||||
AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
|
AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
|
||||||
@ -861,8 +861,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
|
|||||||
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
|
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
|
||||||
disableValid = DisableValidationForModuleKind::All;
|
disableValid = DisableValidationForModuleKind::All;
|
||||||
AST->Reader = new ASTReader(
|
AST->Reader = new ASTReader(
|
||||||
PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
|
PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"",
|
||||||
/*isysroot=*/"",
|
|
||||||
/*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
|
/*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
|
||||||
|
|
||||||
unsigned Counter = 0;
|
unsigned Counter = 0;
|
||||||
@ -1546,7 +1545,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
|
|||||||
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
||||||
AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
|
AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
|
||||||
UserFilesAreVolatile);
|
UserFilesAreVolatile);
|
||||||
AST->ModuleCache = new InMemoryModuleCache;
|
AST->ModCache = createCrossProcessModuleCache();
|
||||||
|
|
||||||
return AST;
|
return AST;
|
||||||
}
|
}
|
||||||
@ -1833,7 +1832,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
|
|||||||
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
|
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
|
||||||
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
||||||
AST->PreambleStoragePath = PreambleStoragePath;
|
AST->PreambleStoragePath = PreambleStoragePath;
|
||||||
AST->ModuleCache = new InMemoryModuleCache;
|
AST->ModCache = createCrossProcessModuleCache();
|
||||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||||
AST->CaptureDiagnostics = CaptureDiagnostics;
|
AST->CaptureDiagnostics = CaptureDiagnostics;
|
||||||
AST->TUKind = TUKind;
|
AST->TUKind = TUKind;
|
||||||
@ -1844,7 +1843,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
|
|||||||
AST->Invocation = CI;
|
AST->Invocation = CI;
|
||||||
AST->SkipFunctionBodies = SkipFunctionBodies;
|
AST->SkipFunctionBodies = SkipFunctionBodies;
|
||||||
if (ForSerialization)
|
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.
|
// Zero out now to ease cleanup during crash recovery.
|
||||||
CI = nullptr;
|
CI = nullptr;
|
||||||
Diags = nullptr;
|
Diags = nullptr;
|
||||||
@ -2379,8 +2378,8 @@ bool ASTUnit::serialize(raw_ostream &OS) {
|
|||||||
|
|
||||||
SmallString<128> Buffer;
|
SmallString<128> Buffer;
|
||||||
llvm::BitstreamWriter Stream(Buffer);
|
llvm::BitstreamWriter Stream(Buffer);
|
||||||
InMemoryModuleCache ModuleCache;
|
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
|
||||||
ASTWriter Writer(Stream, Buffer, ModuleCache, {});
|
ASTWriter Writer(Stream, Buffer, *ModCache, {});
|
||||||
return serializeUnit(Writer, Buffer, getSema(), OS);
|
return serializeUnit(Writer, Buffer, getSema(), OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,16 +39,17 @@
|
|||||||
#include "clang/Serialization/ASTReader.h"
|
#include "clang/Serialization/ASTReader.h"
|
||||||
#include "clang/Serialization/GlobalModuleIndex.h"
|
#include "clang/Serialization/GlobalModuleIndex.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/ScopeExit.h"
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Config/llvm-config.h"
|
#include "llvm/Config/llvm-config.h"
|
||||||
|
#include "llvm/Support/AdvisoryLock.h"
|
||||||
#include "llvm/Support/BuryPointer.h"
|
#include "llvm/Support/BuryPointer.h"
|
||||||
#include "llvm/Support/CrashRecoveryContext.h"
|
#include "llvm/Support/CrashRecoveryContext.h"
|
||||||
#include "llvm/Support/Errc.h"
|
#include "llvm/Support/Errc.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/LockFileManager.h"
|
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
#include "llvm/Support/Program.h"
|
#include "llvm/Support/Program.h"
|
||||||
@ -66,11 +67,10 @@ using namespace clang;
|
|||||||
|
|
||||||
CompilerInstance::CompilerInstance(
|
CompilerInstance::CompilerInstance(
|
||||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||||
InMemoryModuleCache *SharedModuleCache)
|
ModuleCache *ModCache)
|
||||||
: ModuleLoader(/* BuildingModule = */ SharedModuleCache),
|
: ModuleLoader(/*BuildingModule=*/ModCache),
|
||||||
Invocation(new CompilerInvocation()),
|
Invocation(new CompilerInvocation()),
|
||||||
ModuleCache(SharedModuleCache ? SharedModuleCache
|
ModCache(ModCache ? ModCache : createCrossProcessModuleCache()),
|
||||||
: new InMemoryModuleCache),
|
|
||||||
ThePCHContainerOperations(std::move(PCHContainerOps)) {}
|
ThePCHContainerOperations(std::move(PCHContainerOps)) {}
|
||||||
|
|
||||||
CompilerInstance::~CompilerInstance() {
|
CompilerInstance::~CompilerInstance() {
|
||||||
@ -205,7 +205,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const {
|
|||||||
return TheASTReader;
|
return TheASTReader;
|
||||||
}
|
}
|
||||||
void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) {
|
void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) {
|
||||||
assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&
|
assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
|
||||||
"Expected ASTReader to use the same PCM cache");
|
"Expected ASTReader to use the same PCM cache");
|
||||||
TheASTReader = std::move(Reader);
|
TheASTReader = std::move(Reader);
|
||||||
}
|
}
|
||||||
@ -625,9 +625,8 @@ void CompilerInstance::createPCHExternalASTSource(
|
|||||||
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
|
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
|
||||||
StringRef Path, StringRef Sysroot,
|
StringRef Path, StringRef Sysroot,
|
||||||
DisableValidationForModuleKind DisableValidation,
|
DisableValidationForModuleKind DisableValidation,
|
||||||
bool AllowPCHWithCompilerErrors, Preprocessor &PP,
|
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
|
||||||
InMemoryModuleCache &ModuleCache, ASTContext &Context,
|
ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
|
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
|
||||||
void *DeserializationListener, bool OwnDeserializationListener,
|
void *DeserializationListener, bool OwnDeserializationListener,
|
||||||
@ -635,7 +634,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
|
|||||||
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
|
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
|
||||||
|
|
||||||
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
|
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
|
||||||
PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
|
PP, ModCache, &Context, PCHContainerRdr, Extensions,
|
||||||
Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,
|
Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,
|
||||||
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
|
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
|
||||||
HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent,
|
HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent,
|
||||||
@ -1166,7 +1165,8 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
|
|||||||
|
|
||||||
// Never compile a module that's already finalized - this would cause the
|
// Never compile a module that's already finalized - this would cause the
|
||||||
// existing module to be freed, causing crashes if it is later referenced
|
// existing module to be freed, causing crashes if it is later referenced
|
||||||
if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) {
|
if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal(
|
||||||
|
ModuleFileName)) {
|
||||||
ImportingInstance.getDiagnostics().Report(
|
ImportingInstance.getDiagnostics().Report(
|
||||||
ImportLoc, diag::err_module_rebuild_finalized)
|
ImportLoc, diag::err_module_rebuild_finalized)
|
||||||
<< ModuleName;
|
<< ModuleName;
|
||||||
@ -1477,15 +1477,13 @@ static bool compileModuleAndReadASTBehindLock(
|
|||||||
Diags.Report(ModuleNameLoc, diag::remark_module_lock)
|
Diags.Report(ModuleNameLoc, diag::remark_module_lock)
|
||||||
<< ModuleFileName << Module->Name;
|
<< ModuleFileName << Module->Name;
|
||||||
|
|
||||||
// FIXME: have LockFileManager return an error_code so that we can
|
auto &ModuleCache = ImportingInstance.getModuleCache();
|
||||||
// avoid the mkdir when the directory already exists.
|
ModuleCache.prepareForGetLock(ModuleFileName);
|
||||||
StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
|
|
||||||
llvm::sys::fs::create_directories(Dir);
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
llvm::LockFileManager Lock(ModuleFileName);
|
auto Lock = ModuleCache.getLock(ModuleFileName);
|
||||||
bool Owned;
|
bool Owned;
|
||||||
if (llvm::Error Err = Lock.tryLock().moveInto(Owned)) {
|
if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
|
||||||
// ModuleCache takes care of correctness and locks are only necessary for
|
// ModuleCache takes care of correctness and locks are only necessary for
|
||||||
// performance. Fallback to building the module in case of any lock
|
// performance. Fallback to building the module in case of any lock
|
||||||
// related errors.
|
// related errors.
|
||||||
@ -1502,19 +1500,19 @@ static bool compileModuleAndReadASTBehindLock(
|
|||||||
|
|
||||||
// Someone else is responsible for building the module. Wait for them to
|
// Someone else is responsible for building the module. Wait for them to
|
||||||
// finish.
|
// finish.
|
||||||
switch (Lock.waitForUnlockFor(std::chrono::seconds(90))) {
|
switch (Lock->waitForUnlockFor(std::chrono::seconds(90))) {
|
||||||
case llvm::WaitForUnlockResult::Success:
|
case llvm::WaitForUnlockResult::Success:
|
||||||
break; // The interesting case.
|
break; // The interesting case.
|
||||||
case llvm::WaitForUnlockResult::OwnerDied:
|
case llvm::WaitForUnlockResult::OwnerDied:
|
||||||
continue; // try again to get the lock.
|
continue; // try again to get the lock.
|
||||||
case llvm::WaitForUnlockResult::Timeout:
|
case llvm::WaitForUnlockResult::Timeout:
|
||||||
// Since ModuleCache takes care of correctness, we try waiting for
|
// Since the InMemoryModuleCache takes care of correctness, we try waiting
|
||||||
// another process to complete the build so clang does not do it done
|
// for someone else to complete the build so that it does not happen
|
||||||
// twice. If case of timeout, build it ourselves.
|
// twice. In case of timeout, build it ourselves.
|
||||||
Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
|
Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
|
||||||
<< Module->Name;
|
<< Module->Name;
|
||||||
// Clear the lock file so that future invocations can make progress.
|
// Clear the lock file so that future invocations can make progress.
|
||||||
Lock.unsafeMaybeUnlock();
|
Lock->unsafeMaybeUnlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,10 +292,9 @@ private:
|
|||||||
class PrecompilePreambleConsumer : public PCHGenerator {
|
class PrecompilePreambleConsumer : public PCHGenerator {
|
||||||
public:
|
public:
|
||||||
PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
|
PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
|
||||||
InMemoryModuleCache &ModuleCache,
|
ModuleCache &ModCache, StringRef isysroot,
|
||||||
StringRef isysroot,
|
|
||||||
std::shared_ptr<PCHBuffer> Buffer)
|
std::shared_ptr<PCHBuffer> Buffer)
|
||||||
: PCHGenerator(PP, ModuleCache, "", isysroot, std::move(Buffer),
|
: PCHGenerator(PP, ModCache, "", isysroot, std::move(Buffer),
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
|
ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
|
||||||
/*AllowASTWithErrors=*/true),
|
/*AllowASTWithErrors=*/true),
|
||||||
Action(Action) {}
|
Action(Action) {}
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
#include "clang/Serialization/ContinuousRangeMap.h"
|
#include "clang/Serialization/ContinuousRangeMap.h"
|
||||||
#include "clang/Serialization/GlobalModuleIndex.h"
|
#include "clang/Serialization/GlobalModuleIndex.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "clang/Serialization/ModuleFile.h"
|
#include "clang/Serialization/ModuleFile.h"
|
||||||
#include "clang/Serialization/ModuleFileExtension.h"
|
#include "clang/Serialization/ModuleFileExtension.h"
|
||||||
#include "clang/Serialization/ModuleManager.h"
|
#include "clang/Serialization/ModuleManager.h"
|
||||||
@ -3318,9 +3319,12 @@ ASTReader::ReadControlBlock(ModuleFile &F,
|
|||||||
StoredSignature, Capabilities);
|
StoredSignature, Capabilities);
|
||||||
|
|
||||||
// If we diagnosed a problem, produce a backtrace.
|
// If we diagnosed a problem, produce a backtrace.
|
||||||
bool recompilingFinalized =
|
bool recompilingFinalized = Result == OutOfDate &&
|
||||||
Result == OutOfDate && (Capabilities & ARR_OutOfDate) &&
|
(Capabilities & ARR_OutOfDate) &&
|
||||||
getModuleManager().getModuleCache().isPCMFinal(F.FileName);
|
getModuleManager()
|
||||||
|
.getModuleCache()
|
||||||
|
.getInMemoryModuleCache()
|
||||||
|
.isPCMFinal(F.FileName);
|
||||||
if (isDiagnosedResult(Result, Capabilities) || recompilingFinalized)
|
if (isDiagnosedResult(Result, Capabilities) || recompilingFinalized)
|
||||||
Diag(diag::note_module_file_imported_by)
|
Diag(diag::note_module_file_imported_by)
|
||||||
<< F.FileName << !F.ModuleName.empty() << F.ModuleName;
|
<< F.FileName << !F.ModuleName.empty() << F.ModuleName;
|
||||||
@ -5006,7 +5010,7 @@ ASTReader::ReadASTCore(StringRef FileName,
|
|||||||
|
|
||||||
bool ShouldFinalizePCM = false;
|
bool ShouldFinalizePCM = false;
|
||||||
auto FinalizeOrDropPCM = llvm::make_scope_exit([&]() {
|
auto FinalizeOrDropPCM = llvm::make_scope_exit([&]() {
|
||||||
auto &MC = getModuleManager().getModuleCache();
|
auto &MC = getModuleManager().getModuleCache().getInMemoryModuleCache();
|
||||||
if (ShouldFinalizePCM)
|
if (ShouldFinalizePCM)
|
||||||
MC.finalizePCM(FileName);
|
MC.finalizePCM(FileName);
|
||||||
else
|
else
|
||||||
@ -5143,7 +5147,8 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
|
|||||||
// validation will fail during the as-system import since the PCM on disk
|
// validation will fail during the as-system import since the PCM on disk
|
||||||
// doesn't guarantee that -Werror was respected. However, the -Werror
|
// doesn't guarantee that -Werror was respected. However, the -Werror
|
||||||
// flags were checked during the initial as-user import.
|
// flags were checked during the initial as-user import.
|
||||||
if (getModuleManager().getModuleCache().isPCMFinal(F.FileName)) {
|
if (getModuleManager().getModuleCache().getInMemoryModuleCache().isPCMFinal(
|
||||||
|
F.FileName)) {
|
||||||
Diag(diag::warn_module_system_bit_conflict) << F.FileName;
|
Diag(diag::warn_module_system_bit_conflict) << F.FileName;
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
@ -5651,14 +5656,14 @@ namespace {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool ASTReader::readASTFileControlBlock(
|
bool ASTReader::readASTFileControlBlock(
|
||||||
StringRef Filename, FileManager &FileMgr,
|
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
|
||||||
const InMemoryModuleCache &ModuleCache,
|
|
||||||
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
|
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
|
||||||
ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
|
ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
|
||||||
unsigned ClientLoadCapabilities) {
|
unsigned ClientLoadCapabilities) {
|
||||||
// Open the AST file.
|
// Open the AST file.
|
||||||
std::unique_ptr<llvm::MemoryBuffer> OwnedBuffer;
|
std::unique_ptr<llvm::MemoryBuffer> OwnedBuffer;
|
||||||
llvm::MemoryBuffer *Buffer = ModuleCache.lookupPCM(Filename);
|
llvm::MemoryBuffer *Buffer =
|
||||||
|
ModCache.getInMemoryModuleCache().lookupPCM(Filename);
|
||||||
if (!Buffer) {
|
if (!Buffer) {
|
||||||
// FIXME: We should add the pcm to the InMemoryModuleCache if it could be
|
// FIXME: We should add the pcm to the InMemoryModuleCache if it could be
|
||||||
// read again later, but we do not have the context here to determine if it
|
// read again later, but we do not have the context here to determine if it
|
||||||
@ -5947,19 +5952,15 @@ bool ASTReader::readASTFileControlBlock(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
|
bool ASTReader::isAcceptableASTFile(
|
||||||
const InMemoryModuleCache &ModuleCache,
|
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts,
|
||||||
const LangOptions &LangOpts,
|
const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts,
|
||||||
const TargetOptions &TargetOpts,
|
StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches) {
|
||||||
const PreprocessorOptions &PPOpts,
|
|
||||||
StringRef ExistingModuleCachePath,
|
|
||||||
bool RequireStrictOptionMatches) {
|
|
||||||
SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
|
SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
|
||||||
ExistingModuleCachePath, FileMgr,
|
ExistingModuleCachePath, FileMgr,
|
||||||
RequireStrictOptionMatches);
|
RequireStrictOptionMatches);
|
||||||
return !readASTFileControlBlock(Filename, FileMgr, ModuleCache,
|
return !readASTFileControlBlock(Filename, FileMgr, ModCache, PCHContainerRdr,
|
||||||
PCHContainerRdr,
|
|
||||||
/*FindModuleFileExtensions=*/false, validator,
|
/*FindModuleFileExtensions=*/false, validator,
|
||||||
/*ValidateDiagnosticOptions=*/true);
|
/*ValidateDiagnosticOptions=*/true);
|
||||||
}
|
}
|
||||||
@ -6496,7 +6497,10 @@ ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
|
|||||||
bool ASTReader::canRecoverFromOutOfDate(StringRef ModuleFileName,
|
bool ASTReader::canRecoverFromOutOfDate(StringRef ModuleFileName,
|
||||||
unsigned int ClientLoadCapabilities) {
|
unsigned int ClientLoadCapabilities) {
|
||||||
return ClientLoadCapabilities & ARR_OutOfDate &&
|
return ClientLoadCapabilities & ARR_OutOfDate &&
|
||||||
!getModuleManager().getModuleCache().isPCMFinal(ModuleFileName);
|
!getModuleManager()
|
||||||
|
.getModuleCache()
|
||||||
|
.getInMemoryModuleCache()
|
||||||
|
.isPCMFinal(ModuleFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::iterator_range<ASTReader::ModuleDeclIterator>
|
llvm::iterator_range<ASTReader::ModuleDeclIterator>
|
||||||
@ -10862,7 +10866,7 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache,
|
||||||
ASTContext *Context,
|
ASTContext *Context,
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr,
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
@ -10878,7 +10882,7 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
|
|||||||
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
|
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
|
||||||
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()),
|
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()),
|
||||||
StackHandler(Diags), PP(PP), ContextObj(Context),
|
StackHandler(Diags), PP(PP), ContextObj(Context),
|
||||||
ModuleMgr(PP.getFileManager(), ModuleCache, PCHContainerRdr,
|
ModuleMgr(PP.getFileManager(), ModCache, PCHContainerRdr,
|
||||||
PP.getHeaderSearchInfo()),
|
PP.getHeaderSearchInfo()),
|
||||||
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
|
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
|
||||||
DisableValidationKind(DisableValidationKind),
|
DisableValidationKind(DisableValidationKind),
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
#include "clang/Serialization/ASTReader.h"
|
#include "clang/Serialization/ASTReader.h"
|
||||||
#include "clang/Serialization/ASTRecordWriter.h"
|
#include "clang/Serialization/ASTRecordWriter.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "clang/Serialization/ModuleFile.h"
|
#include "clang/Serialization/ModuleFile.h"
|
||||||
#include "clang/Serialization/ModuleFileExtension.h"
|
#include "clang/Serialization/ModuleFileExtension.h"
|
||||||
#include "clang/Serialization/SerializationDiagnostic.h"
|
#include "clang/Serialization/SerializationDiagnostic.h"
|
||||||
@ -5326,12 +5327,11 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
|
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
|
||||||
SmallVectorImpl<char> &Buffer,
|
SmallVectorImpl<char> &Buffer, ModuleCache &ModCache,
|
||||||
InMemoryModuleCache &ModuleCache,
|
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
bool IncludeTimestamps, bool BuildingImplicitModule,
|
bool IncludeTimestamps, bool BuildingImplicitModule,
|
||||||
bool GeneratingReducedBMI)
|
bool GeneratingReducedBMI)
|
||||||
: Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
|
: Stream(Stream), Buffer(Buffer), ModCache(ModCache),
|
||||||
IncludeTimestamps(IncludeTimestamps),
|
IncludeTimestamps(IncludeTimestamps),
|
||||||
BuildingImplicitModule(BuildingImplicitModule),
|
BuildingImplicitModule(BuildingImplicitModule),
|
||||||
GeneratingReducedBMI(GeneratingReducedBMI) {
|
GeneratingReducedBMI(GeneratingReducedBMI) {
|
||||||
@ -5389,9 +5389,9 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
|
|||||||
|
|
||||||
if (ShouldCacheASTInMemory) {
|
if (ShouldCacheASTInMemory) {
|
||||||
// Construct MemoryBuffer and update buffer manager.
|
// Construct MemoryBuffer and update buffer manager.
|
||||||
ModuleCache.addBuiltPCM(OutputFile,
|
ModCache.getInMemoryModuleCache().addBuiltPCM(
|
||||||
llvm::MemoryBuffer::getMemBufferCopy(
|
OutputFile, llvm::MemoryBuffer::getMemBufferCopy(
|
||||||
StringRef(Buffer.begin(), Buffer.size())));
|
StringRef(Buffer.begin(), Buffer.size())));
|
||||||
}
|
}
|
||||||
return Signature;
|
return Signature;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ add_clang_library(clangSerialization
|
|||||||
GeneratePCH.cpp
|
GeneratePCH.cpp
|
||||||
GlobalModuleIndex.cpp
|
GlobalModuleIndex.cpp
|
||||||
InMemoryModuleCache.cpp
|
InMemoryModuleCache.cpp
|
||||||
|
ModuleCache.cpp
|
||||||
ModuleFile.cpp
|
ModuleFile.cpp
|
||||||
ModuleFileExtension.cpp
|
ModuleFileExtension.cpp
|
||||||
ModuleManager.cpp
|
ModuleManager.cpp
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
PCHGenerator::PCHGenerator(
|
PCHGenerator::PCHGenerator(
|
||||||
Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef OutputFile,
|
Preprocessor &PP, ModuleCache &ModCache, StringRef OutputFile,
|
||||||
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
|
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
|
||||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||||
bool AllowASTWithErrors, bool IncludeTimestamps,
|
bool AllowASTWithErrors, bool IncludeTimestamps,
|
||||||
@ -31,7 +31,7 @@ PCHGenerator::PCHGenerator(
|
|||||||
bool GeneratingReducedBMI)
|
bool GeneratingReducedBMI)
|
||||||
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
|
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
|
||||||
Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
|
Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
|
||||||
Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
|
Writer(Stream, this->Buffer->Data, ModCache, Extensions,
|
||||||
IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
|
IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
|
||||||
AllowASTWithErrors(AllowASTWithErrors),
|
AllowASTWithErrors(AllowASTWithErrors),
|
||||||
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
|
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
|
||||||
@ -100,12 +100,12 @@ ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
|
|||||||
void PCHGenerator::anchor() {}
|
void PCHGenerator::anchor() {}
|
||||||
|
|
||||||
CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,
|
CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,
|
||||||
InMemoryModuleCache &ModuleCache,
|
ModuleCache &ModCache,
|
||||||
StringRef OutputFile,
|
StringRef OutputFile,
|
||||||
bool GeneratingReducedBMI,
|
bool GeneratingReducedBMI,
|
||||||
bool AllowASTWithErrors)
|
bool AllowASTWithErrors)
|
||||||
: PCHGenerator(
|
: PCHGenerator(
|
||||||
PP, ModuleCache, OutputFile, llvm::StringRef(),
|
PP, ModCache, OutputFile, llvm::StringRef(),
|
||||||
std::make_shared<PCHBuffer>(),
|
std::make_shared<PCHBuffer>(),
|
||||||
/*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
|
/*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
|
||||||
AllowASTWithErrors, /*IncludeTimestamps=*/false,
|
AllowASTWithErrors, /*IncludeTimestamps=*/false,
|
||||||
|
44
clang/lib/Serialization/ModuleCache.cpp
Normal file
44
clang/lib/Serialization/ModuleCache.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
|
|
||||||
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "llvm/Support/LockFileManager.h"
|
||||||
|
#include "llvm/Support/Path.h"
|
||||||
|
|
||||||
|
using namespace clang;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class CrossProcessModuleCache : public ModuleCache {
|
||||||
|
InMemoryModuleCache InMemory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void prepareForGetLock(StringRef ModuleFilename) override {
|
||||||
|
// FIXME: Do this in LockFileManager and only if the directory doesn't
|
||||||
|
// exist.
|
||||||
|
StringRef Dir = llvm::sys::path::parent_path(ModuleFilename);
|
||||||
|
llvm::sys::fs::create_directories(Dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<llvm::AdvisoryLock>
|
||||||
|
getLock(StringRef ModuleFilename) override {
|
||||||
|
return std::make_unique<llvm::LockFileManager>(ModuleFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
|
||||||
|
const InMemoryModuleCache &getInMemoryModuleCache() const override {
|
||||||
|
return InMemory;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
IntrusiveRefCntPtr<ModuleCache> clang::createCrossProcessModuleCache() {
|
||||||
|
return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>();
|
||||||
|
}
|
@ -18,6 +18,7 @@
|
|||||||
#include "clang/Lex/ModuleMap.h"
|
#include "clang/Lex/ModuleMap.h"
|
||||||
#include "clang/Serialization/GlobalModuleIndex.h"
|
#include "clang/Serialization/GlobalModuleIndex.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "clang/Serialization/ModuleFile.h"
|
#include "clang/Serialization/ModuleFile.h"
|
||||||
#include "clang/Serialization/PCHContainerOperations.h"
|
#include "clang/Serialization/PCHContainerOperations.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
@ -182,17 +183,20 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
|
|||||||
// Load the contents of the module
|
// Load the contents of the module
|
||||||
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
|
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
|
||||||
// The buffer was already provided for us.
|
// The buffer was already provided for us.
|
||||||
NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer));
|
NewModule->Buffer = &getModuleCache().getInMemoryModuleCache().addBuiltPCM(
|
||||||
|
FileName, std::move(Buffer));
|
||||||
// Since the cached buffer is reused, it is safe to close the file
|
// Since the cached buffer is reused, it is safe to close the file
|
||||||
// descriptor that was opened while stat()ing the PCM in
|
// descriptor that was opened while stat()ing the PCM in
|
||||||
// lookupModuleFile() above, it won't be needed any longer.
|
// lookupModuleFile() above, it won't be needed any longer.
|
||||||
Entry->closeFile();
|
Entry->closeFile();
|
||||||
} else if (llvm::MemoryBuffer *Buffer =
|
} else if (llvm::MemoryBuffer *Buffer =
|
||||||
getModuleCache().lookupPCM(FileName)) {
|
getModuleCache().getInMemoryModuleCache().lookupPCM(
|
||||||
|
FileName)) {
|
||||||
NewModule->Buffer = Buffer;
|
NewModule->Buffer = Buffer;
|
||||||
// As above, the file descriptor is no longer needed.
|
// As above, the file descriptor is no longer needed.
|
||||||
Entry->closeFile();
|
Entry->closeFile();
|
||||||
} else if (getModuleCache().shouldBuildPCM(FileName)) {
|
} else if (getModuleCache().getInMemoryModuleCache().shouldBuildPCM(
|
||||||
|
FileName)) {
|
||||||
// Report that the module is out of date, since we tried (and failed) to
|
// Report that the module is out of date, since we tried (and failed) to
|
||||||
// import it earlier.
|
// import it earlier.
|
||||||
Entry->closeFile();
|
Entry->closeFile();
|
||||||
@ -213,7 +217,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
|
|||||||
return Missing;
|
return Missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewModule->Buffer = &getModuleCache().addPCM(FileName, std::move(*Buf));
|
NewModule->Buffer = &getModuleCache().getInMemoryModuleCache().addPCM(
|
||||||
|
FileName, std::move(*Buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the stream.
|
// Initialize the stream.
|
||||||
@ -324,12 +329,11 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
|
|||||||
ModulesInCommonWithGlobalIndex.push_back(MF);
|
ModulesInCommonWithGlobalIndex.push_back(MF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleManager::ModuleManager(FileManager &FileMgr,
|
ModuleManager::ModuleManager(FileManager &FileMgr, ModuleCache &ModCache,
|
||||||
InMemoryModuleCache &ModuleCache,
|
|
||||||
const PCHContainerReader &PCHContainerRdr,
|
const PCHContainerReader &PCHContainerRdr,
|
||||||
const HeaderSearch &HeaderSearchInfo)
|
const HeaderSearch &HeaderSearchInfo)
|
||||||
: FileMgr(FileMgr), ModuleCache(&ModuleCache),
|
: FileMgr(FileMgr), ModCache(&ModCache), PCHContainerRdr(PCHContainerRdr),
|
||||||
PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {}
|
HeaderSearchInfo(HeaderSearchInfo) {}
|
||||||
|
|
||||||
void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
|
void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
|
||||||
llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
|
llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "clang/Lex/PreprocessorOptions.h"
|
#include "clang/Lex/PreprocessorOptions.h"
|
||||||
#include "clang/Sema/Sema.h"
|
#include "clang/Sema/Sema.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||||
|
#include "clang/Serialization/ModuleCache.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/ToolOutputFile.h"
|
#include "llvm/Support/ToolOutputFile.h"
|
||||||
#include "llvm/Support/VirtualFileSystem.h"
|
#include "llvm/Support/VirtualFileSystem.h"
|
||||||
@ -287,10 +288,12 @@ TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
|
|||||||
// Check whether the PCH was cached.
|
// Check whether the PCH was cached.
|
||||||
if (ShouldCache)
|
if (ShouldCache)
|
||||||
EXPECT_EQ(InMemoryModuleCache::Final,
|
EXPECT_EQ(InMemoryModuleCache::Final,
|
||||||
Compiler.getModuleCache().getPCMState(PCHFilename));
|
Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
|
||||||
|
PCHFilename));
|
||||||
else
|
else
|
||||||
EXPECT_EQ(InMemoryModuleCache::Unknown,
|
EXPECT_EQ(InMemoryModuleCache::Unknown,
|
||||||
Compiler.getModuleCache().getPCMState(PCHFilename));
|
Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
|
||||||
|
PCHFilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "clang/Basic/TargetOptions.h"
|
#include "clang/Basic/TargetOptions.h"
|
||||||
#include "clang/Lex/HeaderSearchOptions.h"
|
#include "clang/Lex/HeaderSearchOptions.h"
|
||||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user