From fb2398d0c43405a6b654c80560e38fb3ccd134b9 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 17 Jul 2015 01:19:54 +0000 Subject: [PATCH] Make the clang module container format selectable from the command line. - introduces a new cc1 option -fmodule-format=[raw,obj] with 'raw' being the default - supports arbitrary module container formats that libclang is agnostic to - adds the format to the module hash to avoid collisions - splits the old PCHContainerOperations into PCHContainerWriter and a PCHContainerReader. Thanks to Richard Smith for reviewing this patch! llvm-svn: 242499 --- clang/include/clang/Basic/DiagnosticCommonKinds.td | 2 + .../CodeGen/ObjectFilePCHContainerOperations.h | 24 ++++---- clang/include/clang/Driver/CC1Options.td | 3 + clang/include/clang/Frontend/ASTUnit.h | 4 +- clang/include/clang/Frontend/CompilerInstance.h | 32 +++++++++- .../clang/Frontend/PCHContainerOperations.h | 72 ++++++++++++++++++---- clang/include/clang/Frontend/Utils.h | 4 +- clang/include/clang/Lex/HeaderSearchOptions.h | 21 ++++--- clang/include/clang/Serialization/ASTReader.h | 10 +-- .../clang/Serialization/GlobalModuleIndex.h | 3 +- clang/include/clang/Serialization/ModuleManager.h | 8 +-- clang/include/clang/Tooling/Refactoring.h | 2 +- clang/include/clang/Tooling/Tooling.h | 12 ++-- clang/lib/ARCMigrate/ARCMT.cpp | 10 +-- clang/lib/Basic/FileManager.cpp | 4 +- .../CodeGen/ObjectFilePCHContainerOperations.cpp | 4 +- clang/lib/Frontend/ASTMerge.cpp | 2 +- clang/lib/Frontend/ASTUnit.cpp | 6 +- clang/lib/Frontend/ChainedIncludesSource.cpp | 2 +- clang/lib/Frontend/CompilerInstance.cpp | 16 ++--- clang/lib/Frontend/CompilerInvocation.cpp | 2 + clang/lib/Frontend/FrontendAction.cpp | 6 +- clang/lib/Frontend/FrontendActions.cpp | 8 +-- clang/lib/Frontend/InitPreprocessor.cpp | 8 +-- clang/lib/Frontend/PCHContainerOperations.cpp | 31 ++++++---- clang/lib/Lex/HeaderSearch.cpp | 4 +- clang/lib/Serialization/ASTReader.cpp | 20 +++--- clang/lib/Serialization/GlobalModuleIndex.cpp | 12 ++-- clang/lib/Serialization/ModuleManager.cpp | 6 +- clang/test/Modules/pch_container.m | 11 ++-- clang/tools/arcmt-test/arcmt-test.cpp | 6 +- clang/tools/clang-check/CMakeLists.txt | 1 - clang/tools/clang-check/ClangCheck.cpp | 3 +- clang/tools/driver/cc1_main.cpp | 8 ++- clang/tools/libclang/CIndex.cpp | 8 +-- clang/tools/libclang/CIndexer.h | 2 +- clang/tools/libclang/CMakeLists.txt | 1 - clang/unittests/ASTMatchers/ASTMatchersTest.h | 2 +- 38 files changed, 240 insertions(+), 140 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index ff42683..fc3ca62 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -195,6 +195,8 @@ def err_unable_to_make_temp : Error< // Modules def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">; +def err_module_format_unhandled : Error< + "no handler registered for module format '%0'">; // TransformActions // TODO: Use a custom category name to distinguish rewriter errors. diff --git a/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index 4540efb..e82aab7 100644 --- a/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -14,30 +14,32 @@ namespace clang { -/// \brief A PCHContainerOperations implementation that uses LLVM to +/// A PCHContainerWriter implementation that uses LLVM to /// wraps Clang modules inside a COFF, ELF, or Mach-O container. -class ObjectFilePCHContainerOperations - : public PCHContainerOperations { - /// \brief Return an ASTConsumer that can be chained with a +class ObjectFilePCHContainerWriter : public PCHContainerWriter { + StringRef getFormat() const override { return "obj"; } + + /// Return an ASTConsumer that can be chained with a /// PCHGenerator that produces a wrapper file format /// that also contains full debug info for the module. - std::unique_ptr - CreatePCHContainerGenerator( + std::unique_ptr CreatePCHContainerGenerator( DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, const PreprocessorOptions &PPO, const TargetOptions &TO, const LangOptions &LO, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr Buffer) const override; +}; + +/// A PCHContainerReader implementation that uses LLVM to +/// wraps Clang modules inside a COFF, ELF, or Mach-O container. +class ObjectFilePCHContainerReader : public PCHContainerReader { + StringRef getFormat() const override { return "obj"; } - /// \brief Initialize an llvm::BitstreamReader with the serialized + /// Initialize an llvm::BitstreamReader with the serialized /// AST inside the PCH container Buffer. void ExtractPCH(llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const override; - - }; - } - #endif diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 60cc6ec..d2f0d05 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -369,6 +369,9 @@ def fmodules_local_submodule_visibility : Flag<["-"], "fmodules-local-submodule-visibility">, HelpText<"Enforce name visibility rules across submodules of the same " "top-level module.">; +def fmodule_format_EQ : Joined<["-"], "fmodule-format=">, + HelpText<"Select the container format for clang modules and PCH. " + "Supported options are 'raw' and 'obj'.">; def fno_modules_hide_internal_linkage : Flag<["-"], "fno-modules-hide-internal-linkage">, HelpText<"Make all declarations visible to redeclaration lookup, " diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 2d38352..fa4bcf2 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -57,6 +57,7 @@ class FileManager; class HeaderSearch; class Preprocessor; class PCHContainerOperations; +class PCHContainerReader; class SourceManager; class TargetInfo; class ASTFrontendAction; @@ -725,8 +726,7 @@ public: /// /// \returns - The initialized ASTUnit or null if the AST failed to load. static std::unique_ptr LoadFromASTFile( - const std::string &Filename, - std::shared_ptr PCHContainerOps, + const std::string &Filename, const PCHContainerReader &PCHContainerRdr, IntrusiveRefCntPtr Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false, ArrayRef RemappedFiles = None, diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 2f3e1b6..45e5ed1 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -183,7 +183,7 @@ class CompilerInstance : public ModuleLoader { public: explicit CompilerInstance( std::shared_ptr PCHContainerOps = - std::make_shared(), + std::make_shared(), bool BuildingModule = false); ~CompilerInstance() override; @@ -508,6 +508,34 @@ public: return ThePCHContainerOperations; } + /// Return the appropriate PCHContainerWriter depending on the + /// current CodeGenOptions. + const PCHContainerWriter &getPCHContainerWriter() const { + assert(Invocation && "cannot determine module format without invocation"); + StringRef Format = getHeaderSearchOpts().ModuleFormat; + auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format); + if (!Writer) { + if (Diagnostics) + Diagnostics->Report(diag::err_module_format_unhandled) << Format; + llvm::report_fatal_error("unknown module format"); + } + return *Writer; + } + + /// Return the appropriate PCHContainerReader depending on the + /// current CodeGenOptions. + const PCHContainerReader &getPCHContainerReader() const { + assert(Invocation && "cannot determine module format without invocation"); + StringRef Format = getHeaderSearchOpts().ModuleFormat; + auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format); + if (!Reader) { + if (Diagnostics) + Diagnostics->Report(diag::err_module_format_unhandled) << Format; + llvm::report_fatal_error("unknown module format"); + } + return *Reader; + } + /// } /// @name Code Completion /// { @@ -621,7 +649,7 @@ public: static IntrusiveRefCntPtr createPCHExternalASTSource( StringRef Path, StringRef Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex); diff --git a/clang/include/clang/Frontend/PCHContainerOperations.h b/clang/include/clang/Frontend/PCHContainerOperations.h index 949ee63..868ea68 100644 --- a/clang/include/clang/Frontend/PCHContainerOperations.h +++ b/clang/include/clang/Frontend/PCHContainerOperations.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/MemoryBuffer.h" #include @@ -19,6 +20,8 @@ class raw_pwrite_stream; class BitstreamReader; } +using llvm::StringRef; + namespace clang { class ASTConsumer; @@ -33,14 +36,16 @@ struct PCHBuffer { bool IsComplete; llvm::SmallVector Data; }; + +/// This abstract interface provides operations for creating +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerWriter { +public: + virtual ~PCHContainerWriter() = 0; + virtual StringRef getFormat() const = 0; -/// \brief This abstract interface provides operations for creating -/// and unwrapping containers for serialized ASTs (precompiled headers -/// and clang modules). -class PCHContainerOperations { -public: - virtual ~PCHContainerOperations(); - /// \brief Return an ASTConsumer that can be chained with a + /// Return an ASTConsumer that can be chained with a /// PCHGenerator that produces a wrapper file format containing a /// serialized AST bitstream. virtual std::unique_ptr CreatePCHContainerGenerator( @@ -49,16 +54,28 @@ public: const LangOptions &LO, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr Buffer) const = 0; +}; - /// \brief Initialize an llvm::BitstreamReader with the serialized AST inside +/// This abstract interface provides operations for unwrapping +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerReader { +public: + virtual ~PCHContainerReader() = 0; + /// Equivalent to the format passed to -fmodule-format= + virtual StringRef getFormat() const = 0; + + /// Initialize an llvm::BitstreamReader with the serialized AST inside /// the PCH container Buffer. virtual void ExtractPCH(llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const = 0; }; -/// \brief Implements a raw pass-through PCH container. -class RawPCHContainerOperations : public PCHContainerOperations { - /// \brief Return an ASTConsumer that can be chained with a +/// Implements write operations for a raw pass-through PCH container. +class RawPCHContainerWriter : public PCHContainerWriter { + StringRef getFormat() const override { return "raw"; } + + /// Return an ASTConsumer that can be chained with a /// PCHGenerator that writes the module to a flat file. std::unique_ptr CreatePCHContainerGenerator( DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, @@ -66,11 +83,42 @@ class RawPCHContainerOperations : public PCHContainerOperations { const LangOptions &LO, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr Buffer) const override; +}; - /// \brief Initialize an llvm::BitstreamReader with Buffer. +/// Implements read operations for a raw pass-through PCH container. +class RawPCHContainerReader : public PCHContainerReader { + StringRef getFormat() const override { return "raw"; } + + /// Initialize an llvm::BitstreamReader with Buffer. void ExtractPCH(llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const override; }; + +/// A registry of PCHContainerWriter and -Reader objects for different formats. +class PCHContainerOperations { + llvm::StringMap> Writers; + llvm::StringMap> Readers; +public: + /// Automatically registers a RawPCHContainerWriter and + /// RawPCHContainerReader. + PCHContainerOperations(); + void registerWriter(std::unique_ptr Writer) { + Writers[Writer->getFormat()] = std::move(Writer); + } + void registerReader(std::unique_ptr Reader) { + Readers[Reader->getFormat()] = std::move(Reader); + } + const PCHContainerWriter *getWriterOrNull(StringRef Format) { + return Writers[Format].get(); + } + const PCHContainerReader *getReaderOrNull(StringRef Format) { + return Readers[Format].get(); + } + const PCHContainerReader &getRawReader() { + return *getReaderOrNull("raw"); + } +}; + } #endif diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h index 6399653..aa567b4 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -45,7 +45,7 @@ class HeaderSearch; class HeaderSearchOptions; class IdentifierTable; class LangOptions; -class PCHContainerOperations; +class PCHContainerReader; class Preprocessor; class PreprocessorOptions; class PreprocessorOutputOptions; @@ -63,7 +63,7 @@ void ApplyHeaderSearchOptions(HeaderSearch &HS, /// InitializePreprocessor - Initialize the preprocessor getting it and the /// environment ready to process a single file. void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts); /// DoPrintPreprocessedInput - Implement -E mode. diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index c9c3260..12f0447 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -92,6 +92,9 @@ public: /// \brief The directory used for a user build. std::string ModuleUserBuildPath; + /// The module/pch container format. + std::string ModuleFormat; + /// \brief Whether we should disable the use of the hash string within the /// module cache. /// @@ -167,16 +170,14 @@ public: public: HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), DisableModuleHash(0), ImplicitModuleMaps(0), - ModuleMapFileHomeIsCwd(0), - ModuleCachePruneInterval(7*24*60*60), - ModuleCachePruneAfter(31*24*60*60), - BuildSessionTimestamp(0), - UseBuiltinIncludes(true), - UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), - UseLibcxx(false), Verbose(false), - ModulesValidateOncePerBuildSession(false), - ModulesValidateSystemHeaders(false) {} + : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0), + ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0), + ModuleCachePruneInterval(7 * 24 * 60 * 60), + ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0), + UseBuiltinIncludes(true), UseStandardSystemIncludes(true), + UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), + ModulesValidateOncePerBuildSession(false), + ModulesValidateSystemHeaders(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 9377dfa..840655e 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -362,7 +362,7 @@ private: SourceManager &SourceMgr; FileManager &FileMgr; - const PCHContainerOperations &PCHContainerOps; + const PCHContainerReader &PCHContainerRdr; DiagnosticsEngine &Diags; /// \brief The semantic analysis object that will be processing the @@ -1289,7 +1289,7 @@ public: /// \param ReadTimer If non-null, a timer used to track the time spent /// deserializing. ASTReader(Preprocessor &PP, ASTContext &Context, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, bool AllowConfigurationMismatch = false, @@ -1458,7 +1458,7 @@ public: /// the AST file, without actually loading the AST file. static std::string getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, DiagnosticsEngine &Diags); /// \brief Read the control block for the named AST file. @@ -1466,13 +1466,13 @@ public: /// \returns true if an error occurred, false otherwise. static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, ASTReaderListener &Listener); /// \brief 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 PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, diff --git a/clang/include/clang/Serialization/GlobalModuleIndex.h b/clang/include/clang/Serialization/GlobalModuleIndex.h index 7e20510..ba4f7e2 100644 --- a/clang/include/clang/Serialization/GlobalModuleIndex.h +++ b/clang/include/clang/Serialization/GlobalModuleIndex.h @@ -198,10 +198,9 @@ public: /// \param Path The path to the directory containing module files, into /// which the global index will be written. static ErrorCode writeIndex(FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, StringRef Path); }; - } #endif diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index ea4b57f..ab39aef 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -24,7 +24,7 @@ namespace clang { class GlobalModuleIndex; class ModuleMap; -class PCHContainerOperations; +class PCHContainerReader; namespace serialization { @@ -52,7 +52,7 @@ class ModuleManager { FileManager &FileMgr; /// \brief Knows how to unwrap module containers. - const PCHContainerOperations &PCHContainerOps; + const PCHContainerReader &PCHContainerRdr; /// \brief A lookup of in-memory (virtual file) buffers llvm::DenseMap> @@ -118,9 +118,9 @@ public: typedef std::pair ModuleOffset; explicit ModuleManager(FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps); + const PCHContainerReader &PCHContainerRdr); ~ModuleManager(); - + /// \brief Forward iterator to traverse all loaded modules. This is reverse /// source-order. ModuleIterator begin() { return Chain.begin(); } diff --git a/clang/include/clang/Tooling/Refactoring.h b/clang/include/clang/Tooling/Refactoring.h index 944fd41..54deff6 100644 --- a/clang/include/clang/Tooling/Refactoring.h +++ b/clang/include/clang/Tooling/Refactoring.h @@ -40,7 +40,7 @@ public: RefactoringTool(const CompilationDatabase &Compilations, ArrayRef SourcePaths, std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); /// \brief Returns the set of replacements to which replacements should /// be added during the run of the tool. diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index fb887e1..92e9065 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -150,7 +150,7 @@ inline std::unique_ptr newFrontendActionFactory( bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, const Twine &FileName = "input.cc", std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); /// The first part of the pair is the filename, the second part the /// file-content. @@ -171,7 +171,7 @@ bool runToolOnCodeWithArgs( clang::FrontendAction *ToolAction, const Twine &Code, const std::vector &Args, const Twine &FileName = "input.cc", std::shared_ptr PCHContainerOps = - std::make_shared(), + std::make_shared(), const FileContentMappings &VirtualMappedFiles = FileContentMappings()); /// \brief Builds an AST for 'Code'. @@ -185,7 +185,7 @@ bool runToolOnCodeWithArgs( std::unique_ptr buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc", std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); /// \brief Builds an AST for 'Code' with additional flags. /// @@ -200,7 +200,7 @@ std::unique_ptr buildASTFromCodeWithArgs( const Twine &Code, const std::vector &Args, const Twine &FileName = "input.cc", std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); /// \brief Utility to run a FrontendAction in a single clang invocation. class ToolInvocation { @@ -219,7 +219,7 @@ public: ToolInvocation(std::vector CommandLine, FrontendAction *FAction, FileManager *Files, std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); /// \brief Create a tool invocation. /// @@ -288,7 +288,7 @@ class ClangTool { ClangTool(const CompilationDatabase &Compilations, ArrayRef SourcePaths, std::shared_ptr PCHContainerOps = - std::make_shared()); + std::make_shared()); ~ClangTool(); diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp index f33ad21..e328842 100644 --- a/clang/lib/ARCMigrate/ARCMT.cpp +++ b/clang/lib/ARCMigrate/ARCMT.cpp @@ -167,7 +167,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) { static CompilerInvocation * createInvocationForMigration(CompilerInvocation &origCI, - const PCHContainerOperations &PCHContainerOps) { + const PCHContainerReader &PCHContainerRdr) { std::unique_ptr CInvok; CInvok.reset(new CompilerInvocation(origCI)); PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); @@ -180,7 +180,7 @@ createInvocationForMigration(CompilerInvocation &origCI, new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), new IgnoringDiagConsumer())); std::string OriginalFile = ASTReader::getOriginalSourceFile( - PPOpts.ImplicitPCHInclude, FileMgr, PCHContainerOps, *Diags); + PPOpts.ImplicitPCHInclude, FileMgr, PCHContainerRdr, *Diags); if (!OriginalFile.empty()) PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile); PPOpts.ImplicitPCHInclude.clear(); @@ -247,7 +247,8 @@ bool arcmt::checkForManualIssues( assert(!transforms.empty()); std::unique_ptr CInvok; - CInvok.reset(createInvocationForMigration(origCI, *PCHContainerOps)); + CInvok.reset( + createInvocationForMigration(origCI, PCHContainerOps->getRawReader())); CInvok->getFrontendOpts().Inputs.clear(); CInvok->getFrontendOpts().Inputs.push_back(Input); @@ -517,7 +518,8 @@ MigrationProcess::MigrationProcess( bool MigrationProcess::applyTransform(TransformFn trans, RewriteListener *listener) { std::unique_ptr CInvok; - CInvok.reset(createInvocationForMigration(OrigCI, *PCHContainerOps)); + CInvok.reset( + createInvocationForMigration(OrigCI, PCHContainerOps->getRawReader())); CInvok->getDiagnosticOpts().IgnoreWarnings = true; Remapper.applyMappings(CInvok->getPreprocessorOpts()); diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 1a636ae..d492744 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -587,4 +587,6 @@ void FileManager::PrintStats() const { //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups; } -PCHContainerOperations::~PCHContainerOperations() {} +// Virtual destructors for abstract base classes that need live in Basic. +PCHContainerWriter::~PCHContainerWriter() {} +PCHContainerReader::~PCHContainerReader() {} diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index 8f04e06..9c9b123 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -156,7 +156,7 @@ public: } // namespace std::unique_ptr -ObjectFilePCHContainerOperations::CreatePCHContainerGenerator( +ObjectFilePCHContainerWriter::CreatePCHContainerGenerator( DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, const PreprocessorOptions &PPO, const TargetOptions &TO, const LangOptions &LO, const std::string &MainFileName, @@ -166,7 +166,7 @@ ObjectFilePCHContainerOperations::CreatePCHContainerGenerator( Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer); } -void ObjectFilePCHContainerOperations::ExtractPCH( +void ObjectFilePCHContainerReader::ExtractPCH( llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) { auto *Obj = OF.get().get(); diff --git a/clang/lib/Frontend/ASTMerge.cpp b/clang/lib/Frontend/ASTMerge.cpp index f6f1551..762c7a5 100644 --- a/clang/lib/Frontend/ASTMerge.cpp +++ b/clang/lib/Frontend/ASTMerge.cpp @@ -46,7 +46,7 @@ void ASTMergeAction::ExecuteAction() { *CI.getDiagnostics().getClient()), /*ShouldOwnClient=*/true)); std::unique_ptr Unit = - ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerOperations(), + ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(), false); if (!Unit) diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 57c97d0..1bb5c3f 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -650,7 +650,7 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr Diags, std::unique_ptr ASTUnit::LoadFromASTFile( const std::string &Filename, - std::shared_ptr PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, IntrusiveRefCntPtr Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, ArrayRef RemappedFiles, bool CaptureDiagnostics, @@ -676,7 +676,7 @@ std::unique_ptr ASTUnit::LoadFromASTFile( AST->getFileManager(), UserFilesAreVolatile); AST->HSOpts = new HeaderSearchOptions(); - + AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat(); AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, AST->getSourceManager(), AST->getDiagnostics(), @@ -708,7 +708,7 @@ std::unique_ptr ASTUnit::LoadFromASTFile( bool disableValid = false; if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = true; - AST->Reader = new ASTReader(PP, Context, *PCHContainerOps, + AST->Reader = new ASTReader(PP, Context, PCHContainerRdr, /*isysroot=*/"", /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors); diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index be30d43..cc0504b 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -81,7 +81,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile, Preprocessor &PP = CI.getPreprocessor(); std::unique_ptr Reader; Reader.reset(new ASTReader(PP, CI.getASTContext(), - *CI.getPCHContainerOperations(), + CI.getPCHContainerReader(), /*isysroot=*/"", /*DisableValidation=*/true)); for (unsigned ti = 0; ti < bufNames.size(); ++ti) { StringRef sr(bufNames[ti]); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index ff041a8..c33b150 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -322,7 +322,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { PP->getFileManager(), PPOpts); // Predefine macros and configure the preprocessor. - InitializePreprocessor(*PP, PPOpts, *getPCHContainerOperations(), + InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), getFrontendOpts()); // Initialize the header search object. @@ -399,7 +399,7 @@ void CompilerInstance::createPCHExternalASTSource( ModuleManager = createPCHExternalASTSource( Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), - *getPCHContainerOperations(), DeserializationListener, + getPCHContainerReader(), DeserializationListener, OwnDeserializationListener, Preamble, getFrontendOpts().UseGlobalModuleIndex); } @@ -407,13 +407,13 @@ void CompilerInstance::createPCHExternalASTSource( IntrusiveRefCntPtr CompilerInstance::createPCHExternalASTSource( StringRef Path, StringRef Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex) { HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); IntrusiveRefCntPtr Reader(new ASTReader( - PP, Context, PCHContainerOps, Sysroot.empty() ? "" : Sysroot.data(), + PP, Context, PCHContainerRdr, Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation, AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); @@ -1244,7 +1244,7 @@ void CompilerInstance::createModuleManager() { ReadTimer = llvm::make_unique("Reading modules", *FrontendTimerGroup); ModuleManager = new ASTReader( - getPreprocessor(), *Context, *getPCHContainerOperations(), + getPreprocessor(), *Context, getPCHContainerReader(), Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, /*AllowASTWithCompilerErrors=*/false, /*AllowConfigurationMismatch=*/false, @@ -1296,7 +1296,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { ModuleFileStack.push_back(FileName); ModuleNameStack.push_back(StringRef()); if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), - *CI.getPCHContainerOperations(), + CI.getPCHContainerReader(), *this)) { CI.getDiagnostics().Report( SourceLocation(), CI.getFileManager().getBufferForFile(FileName) @@ -1667,7 +1667,7 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( llvm::sys::fs::create_directories( getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); GlobalModuleIndex::writeIndex( - getFileManager(), *getPCHContainerOperations(), + getFileManager(), getPCHContainerReader(), getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); ModuleManager->resetForReload(); ModuleManager->loadGlobalIndex(); @@ -1695,7 +1695,7 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( } if (RecreateIndex) { GlobalModuleIndex::writeIndex( - getFileManager(), *getPCHContainerOperations(), + getFileManager(), getPCHContainerReader(), getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); ModuleManager->resetForReload(); ModuleManager->loadGlobalIndex(); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6f13faf..f325144 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1112,6 +1112,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0); Opts.ModulesValidateSystemHeaders = Args.hasArg(OPT_fmodules_validate_system_headers); + if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ)) + Opts.ModuleFormat = A->getValue(); for (const Arg *A : Args.filtered(OPT_fmodules_ignore_macro)) { StringRef MacroDef = A->getValue(); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index db9dd3b..3e0f7a1 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -191,7 +191,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, IntrusiveRefCntPtr Diags(&CI.getDiagnostics()); std::unique_ptr AST = - ASTUnit::LoadFromASTFile(InputFile, CI.getPCHContainerOperations(), + ASTUnit::LoadFromASTFile(InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts()); if (!AST) @@ -273,7 +273,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. if (ASTReader::isAcceptableASTFile( - Dir->path(), FileMgr, *CI.getPCHContainerOperations(), + Dir->path(), FileMgr, CI.getPCHContainerReader(), CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), SpecificModuleCachePath)) { PPOpts.ImplicitPCHInclude = Dir->path(); @@ -443,7 +443,7 @@ bool FrontendAction::Execute() { if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && CI.hasPreprocessor()) { GlobalModuleIndex::writeIndex( - CI.getFileManager(), *CI.getPCHContainerOperations(), + CI.getFileManager(), CI.getPCHContainerReader(), CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); } diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 4997764..40277bd 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -93,7 +93,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { Consumers.push_back(llvm::make_unique( CI.getPreprocessor(), OutputFile, nullptr, Sysroot, Buffer)); Consumers.push_back( - CI.getPCHContainerOperations()->CreatePCHContainerGenerator( + CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI.getDiagnostics(), CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(), InFile, OutputFile, OS, Buffer)); @@ -139,7 +139,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, Consumers.push_back(llvm::make_unique( CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer)); Consumers.push_back( - CI.getPCHContainerOperations()->CreatePCHContainerGenerator( + CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI.getDiagnostics(), CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(), InFile, OutputFile, OS, Buffer)); @@ -415,7 +415,7 @@ void VerifyPCHAction::ExecuteAction() { bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; std::unique_ptr Reader(new ASTReader( - CI.getPreprocessor(), CI.getASTContext(), *CI.getPCHContainerOperations(), + CI.getPreprocessor(), CI.getASTContext(), CI.getPCHContainerReader(), Sysroot.empty() ? "" : Sysroot.c_str(), /*DisableValidation*/ false, /*AllowPCHWithCompilerErrors*/ false, @@ -578,7 +578,7 @@ void DumpModuleInfoAction::ExecuteAction() { DumpModuleInfoListener Listener(Out); ASTReader::readASTFileControlBlock( getCurrentFile(), getCompilerInstance().getFileManager(), - *getCompilerInstance().getPCHContainerOperations(), Listener); + getCompilerInstance().getPCHContainerReader(), Listener); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 025c8b9..0791494 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -97,11 +97,11 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP, /// \brief Add an implicit \#include using the original file used to generate /// a PCH file. static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, StringRef ImplicitIncludePCH) { std::string OriginalFile = ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(), - PCHContainerOps, PP.getDiagnostics()); + PCHContainerRdr, PP.getDiagnostics()); if (OriginalFile.empty()) return; @@ -902,7 +902,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, /// void clang::InitializePreprocessor( Preprocessor &PP, const PreprocessorOptions &InitOpts, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts) { const LangOptions &LangOpts = PP.getLangOpts(); std::string PredefineBuffer; @@ -962,7 +962,7 @@ void clang::InitializePreprocessor( // Process -include-pch/-include-pth directives. if (!InitOpts.ImplicitPCHInclude.empty()) - AddImplicitIncludePCH(Builder, PP, PCHContainerOps, + AddImplicitIncludePCH(Builder, PP, PCHContainerRdr, InitOpts.ImplicitPCHInclude); if (!InitOpts.ImplicitPTHInclude.empty()) AddImplicitIncludePTH(Builder, PP, InitOpts.ImplicitPTHInclude); diff --git a/clang/lib/Frontend/PCHContainerOperations.cpp b/clang/lib/Frontend/PCHContainerOperations.cpp index c749bb5..cde3ba1 100644 --- a/clang/lib/Frontend/PCHContainerOperations.cpp +++ b/clang/lib/Frontend/PCHContainerOperations.cpp @@ -21,21 +21,22 @@ using namespace clang; namespace { /// \brief A PCHContainerGenerator that writes out the PCH to a flat file. -class PCHContainerGenerator : public ASTConsumer { +class RawPCHContainerGenerator : public ASTConsumer { std::shared_ptr Buffer; raw_pwrite_stream *OS; public: - PCHContainerGenerator(DiagnosticsEngine &Diags, - const HeaderSearchOptions &HSO, - const PreprocessorOptions &PPO, const TargetOptions &TO, - const LangOptions &LO, const std::string &MainFileName, - const std::string &OutputFileName, - llvm::raw_pwrite_stream *OS, - std::shared_ptr Buffer) + RawPCHContainerGenerator(DiagnosticsEngine &Diags, + const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, + const TargetOptions &TO, const LangOptions &LO, + const std::string &MainFileName, + const std::string &OutputFileName, + llvm::raw_pwrite_stream *OS, + std::shared_ptr Buffer) : Buffer(Buffer), OS(OS) {} - virtual ~PCHContainerGenerator() {} + virtual ~RawPCHContainerGenerator() {} void HandleTranslationUnit(ASTContext &Ctx) override { if (Buffer->IsComplete) { @@ -50,19 +51,23 @@ public: }; } -std::unique_ptr -RawPCHContainerOperations::CreatePCHContainerGenerator( +std::unique_ptr RawPCHContainerWriter::CreatePCHContainerGenerator( DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, const PreprocessorOptions &PPO, const TargetOptions &TO, const LangOptions &LO, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr Buffer) const { - return llvm::make_unique( + return llvm::make_unique( Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer); } -void RawPCHContainerOperations::ExtractPCH( +void RawPCHContainerReader::ExtractPCH( llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { StreamFile.init((const unsigned char *)Buffer.getBufferStart(), (const unsigned char *)Buffer.getBufferEnd()); } + +PCHContainerOperations::PCHContainerOperations() { + registerWriter(llvm::make_unique()); + registerReader(llvm::make_unique()); +} diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index b805990..983dc18 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -14,6 +14,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Frontend/PCHContainerOperations.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderMap.h" #include "clang/Lex/HeaderSearchOptions.h" @@ -151,7 +152,8 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, auto FileName = llvm::sys::path::filename(ModuleMapPath); llvm::hash_code Hash = - llvm::hash_combine(DirName.lower(), FileName.lower()); + llvm::hash_combine(DirName.lower(), FileName.lower(), + HSOpts->ModuleFormat); SmallString<128> HashStr; llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3045629..9fbf55b 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3601,7 +3601,7 @@ ASTReader::ReadASTCore(StringRef FileName, ModuleFile &F = *M; BitstreamCursor &Stream = F.Stream; - PCHContainerOps.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile); + PCHContainerRdr.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile); Stream.init(&F.StreamFile); F.SizeInBits = F.Buffer->getBufferSize() * 8; @@ -3872,7 +3872,7 @@ static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){ /// file. std::string ASTReader::getOriginalSourceFile( const std::string &ASTFileName, FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, DiagnosticsEngine &Diags) { + const PCHContainerReader &PCHContainerRdr, DiagnosticsEngine &Diags) { // Open the AST file. auto Buffer = FileMgr.getBufferForFile(ASTFileName); if (!Buffer) { @@ -3883,7 +3883,7 @@ std::string ASTReader::getOriginalSourceFile( // Initialize the stream llvm::BitstreamReader StreamFile; - PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); + PCHContainerRdr.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); BitstreamCursor Stream(StreamFile); // Sniff for the signature. @@ -3967,7 +3967,7 @@ namespace { bool ASTReader::readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, ASTReaderListener &Listener) { // Open the AST file. // FIXME: This allows use of the VFS; we do not allow use of the @@ -3979,7 +3979,7 @@ bool ASTReader::readASTFileControlBlock( // Initialize the stream llvm::BitstreamReader StreamFile; - PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); + PCHContainerRdr.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile); BitstreamCursor Stream(StreamFile); // Sniff for the signature. @@ -4160,12 +4160,12 @@ bool ASTReader::readASTFileControlBlock( bool ASTReader::isAcceptableASTFile( StringRef Filename, FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, const LangOptions &LangOpts, + const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, std::string ExistingModuleCachePath) { SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, ExistingModuleCachePath, FileMgr); - return !readASTFileControlBlock(Filename, FileMgr, PCHContainerOps, + return !readASTFileControlBlock(Filename, FileMgr, PCHContainerRdr, validator); } @@ -8472,7 +8472,7 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { } ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, StringRef isysroot, bool DisableValidation, bool AllowASTWithCompilerErrors, bool AllowConfigurationMismatch, bool ValidateSystemInputs, @@ -8480,9 +8480,9 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, std::unique_ptr ReadTimer) : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr), OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()), - FileMgr(PP.getFileManager()), PCHContainerOps(PCHContainerOps), + FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context), - Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerOps), + Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerRdr), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 2c7da3e8..17c7914 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -385,7 +385,7 @@ namespace { /// \brief Builder that generates the global module index file. class GlobalModuleIndexBuilder { FileManager &FileMgr; - const PCHContainerOperations &PCHContainerOps; + const PCHContainerReader &PCHContainerRdr; /// \brief Mapping from files to module file information. typedef llvm::MapVector ModuleFilesMap; @@ -419,8 +419,8 @@ namespace { public: explicit GlobalModuleIndexBuilder( - FileManager &FileMgr, const PCHContainerOperations &PCHContainerOps) - : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps) {} + FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr) + : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr) {} /// \brief Load the contents of the given module file into the builder. /// @@ -505,7 +505,7 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Initialize the input stream llvm::BitstreamReader InStreamFile; - PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile); + PCHContainerRdr.ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile); llvm::BitstreamCursor InStream(InStreamFile); // Sniff for the signature. @@ -768,7 +768,7 @@ void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) { GlobalModuleIndex::ErrorCode GlobalModuleIndex::writeIndex(FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps, + const PCHContainerReader &PCHContainerRdr, StringRef Path) { llvm::SmallString<128> IndexPath; IndexPath += Path; @@ -792,7 +792,7 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, } // The module index builder. - GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerOps); + GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerRdr); // Load each of the module files. std::error_code EC; diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index 03d8ed0..2716194 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -139,7 +139,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, } // Initialize the stream. - PCHContainerOps.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile); + PCHContainerRdr.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile); } if (ExpectedSignature) { @@ -290,8 +290,8 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) { } ModuleManager::ModuleManager(FileManager &FileMgr, - const PCHContainerOperations &PCHContainerOps) - : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps), GlobalIndex(), + const PCHContainerReader &PCHContainerRdr) + : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr), GlobalIndex(), FirstVisitState(nullptr) {} ModuleManager::~ModuleManager() { diff --git a/clang/test/Modules/pch_container.m b/clang/test/Modules/pch_container.m index 095245b..95ef3ed 100644 --- a/clang/test/Modules/pch_container.m +++ b/clang/test/Modules/pch_container.m @@ -1,9 +1,11 @@ @import DependsOnModule; // REQUIRES: x86-registered-target -// RUN: rm -rf %t-MachO %t-ELF %t-ELF_SPLIT %t-COFF -// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-MachO -F %S/Inputs %s -// RUN: %clang_cc1 -triple=x86_64-linux-elf -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF -F %S/Inputs %s -// RUN: %clang_cc1 -triple=x86_64-windows-coff -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-COFF -F %S/Inputs %s +// RUN: rm -rf %t-MachO %t-ELF %t-ELF_SPLIT %t-COFF %t-raw +// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-MachO -F %S/Inputs %s +// RUN: %clang_cc1 -triple=x86_64-linux-elf -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF -F %S/Inputs %s +// RUN: %clang_cc1 -triple=x86_64-windows-coff -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-COFF -F %S/Inputs %s +// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fmodule-format=raw -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-raw -F %S/Inputs %s + // RUN: llvm-objdump -section-headers %t-MachO/DependsOnModule.pcm %t-ELF/DependsOnModule.pcm %t-COFF/DependsOnModule.pcm | FileCheck %s // CHECK: file format Mach-O 64-bit x86-64 @@ -13,5 +15,6 @@ // CHECK: file format COFF-x86-64 // CHECK: clangast {{[0-9a-f]+}} {{[0-9a-f]+}} +// RUN: not llvm-objdump -section-headers %t-raw/DependsOnModule.pcm // RUN: %clang_cc1 -split-dwarf-file t-split.dwo -triple=x86_64-linux-elf -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF_SPLIT -F %S/Inputs %s -o %t-split.o diff --git a/clang/tools/arcmt-test/arcmt-test.cpp b/clang/tools/arcmt-test/arcmt-test.cpp index c269e01..7c8e46a 100644 --- a/clang/tools/arcmt-test/arcmt-test.cpp +++ b/clang/tools/arcmt-test/arcmt-test.cpp @@ -132,7 +132,7 @@ static bool checkForMigration(StringRef resourcesPath, return false; arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0], - std::make_shared(), + std::make_shared(), Diags->getClient()); return Diags->getClient()->getNumErrors() > 0; } @@ -171,8 +171,8 @@ static bool performTransformations(StringRef resourcesPath, if (!origCI.getLangOpts()->ObjC1) return false; - MigrationProcess migration( - origCI, std::make_shared(), DiagClient); + MigrationProcess migration(origCI, std::make_shared(), + DiagClient); std::vector transforms = arcmt::getAllTransformations(origCI.getLangOpts()->getGC(), diff --git a/clang/tools/clang-check/CMakeLists.txt b/clang/tools/clang-check/CMakeLists.txt index d1572cb..04151a8 100644 --- a/clang/tools/clang-check/CMakeLists.txt +++ b/clang/tools/clang-check/CMakeLists.txt @@ -11,7 +11,6 @@ add_clang_executable(clang-check target_link_libraries(clang-check clangAST clangBasic - clangCodeGen clangDriver clangFrontend clangRewriteFrontend diff --git a/clang/tools/clang-check/ClangCheck.cpp b/clang/tools/clang-check/ClangCheck.cpp index 2682e0f..a9934c9 100644 --- a/clang/tools/clang-check/ClangCheck.cpp +++ b/clang/tools/clang-check/ClangCheck.cpp @@ -160,8 +160,7 @@ int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory); ClangTool Tool(OptionsParser.getCompilations(), - OptionsParser.getSourcePathList(), - std::make_shared()); + OptionsParser.getSourcePathList()); // Clear adjusters because -fsyntax-only is inserted by the default chain. Tool.clearArgumentsAdjusters(); diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp index 65f845d..8240561 100644 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -65,10 +65,14 @@ void initializePollyPasses(llvm::PassRegistry &Registry); #endif int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { - std::unique_ptr Clang(new CompilerInstance( - std::make_shared())); + std::unique_ptr Clang(new CompilerInstance()); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); + // Register the support for object-file-wrapped Clang modules. + auto PCHOps = Clang->getPCHContainerOperations(); + PCHOps->registerWriter(llvm::make_unique()); + PCHOps->registerReader(llvm::make_unique()); + // Initialize targets first, so that --version shows registered targets. llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 6e48bab..8225a6c 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2884,8 +2884,8 @@ CXIndex clang_createIndex(int excludeDeclarationsFromPCH, llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); - CIndexer *CIdxr = - new CIndexer(std::make_shared()); + CIndexer *CIdxr = new CIndexer(); + if (excludeDeclarationsFromPCH) CIdxr->setOnlyLocalDecls(); if (displayDiagnostics) @@ -2954,8 +2954,8 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx, IntrusiveRefCntPtr Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); std::unique_ptr AU = ASTUnit::LoadFromASTFile( - ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts, - CXXIdx->getOnlyLocalDecls(), None, + ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags, + FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None, /*CaptureDiagnostics=*/true, /*AllowPCHWithCompilerErrors=*/true, /*UserFilesAreVolatile=*/true); diff --git a/clang/tools/libclang/CIndexer.h b/clang/tools/libclang/CIndexer.h index 8a306cd..bf55301 100644 --- a/clang/tools/libclang/CIndexer.h +++ b/clang/tools/libclang/CIndexer.h @@ -44,7 +44,7 @@ class CIndexer { public: CIndexer(std::shared_ptr PCHContainerOps = - std::make_shared()) + std::make_shared()) : OnlyLocalDecls(false), DisplayDiagnostics(false), Options(CXGlobalOpt_None), PCHContainerOps(PCHContainerOps) {} diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index fb29209..06db70e 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -40,7 +40,6 @@ set(SOURCES set(LIBS clangAST clangBasic - clangCodeGen clangFrontend clangIndex clangLex diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h index d79a317..403a305 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.h +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h @@ -80,7 +80,7 @@ testing::AssertionResult matchesConditionally( Args.push_back("-frtti"); Args.push_back("-fexceptions"); if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, Filename, - std::make_shared(), + std::make_shared(), VirtualMappedFiles)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } -- 2.7.4