diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -303,8 +303,8 @@ bit field. - Introduced the new ``CXIndex`` constructor function - ``clang_createIndexWithOptions``, which allows overriding precompiled preamble - storage path. + ``clang_createIndexWithOptions``, which allows storing precompiled preambles + in memory or overriding precompiled preamble storage path. - Deprecated two functions ``clang_CXIndex_setGlobalOptions`` and ``clang_CXIndex_setInvocationEmissionPathOption`` in favor of the new diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -372,13 +372,19 @@ * \see clang_createIndex() */ unsigned DisplayDiagnostics : 1; - unsigned /*Reserved*/ : 14; + /** + * Store PCH in memory. If zero, PCH are stored in temporary files. + */ + unsigned StorePreamblesInMemory : 1; + unsigned /*Reserved*/ : 13; /** * The path to a directory, in which to store temporary PCH files. If null or * empty, the default system temporary directory is used. These PCH files are * deleted on clean exit but stay on disk if the program crashes or is killed. * + * This option is ignored if \a StorePreamblesInMemory is non-zero. + * * Libclang does not create the directory at the specified path in the file * system. Therefore it must exist, or storing PCH files will fail. */ diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -119,6 +119,7 @@ std::shared_ptr PPOpts; IntrusiveRefCntPtr Reader; bool HadModuleLoaderFatalFailure = false; + bool StorePreamblesInMemory = false; struct ASTWriterData; std::unique_ptr WriterData; @@ -803,9 +804,12 @@ /// /// \param ResourceFilesPath - The path to the compiler resource files. /// + /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false, + /// PCH are stored in temporary files. + /// /// \param PreambleStoragePath - The path to a directory, in which to create /// temporary PCH files. If empty, the default system temporary directory is - /// used. + /// used. This parameter is ignored if \p StorePreamblesInMemory is true. /// /// \param ModuleFormat - If provided, uses the specific module format. /// @@ -825,6 +829,7 @@ const char **ArgBegin, const char **ArgEnd, std::shared_ptr PCHContainerOps, IntrusiveRefCntPtr Diags, StringRef ResourceFilesPath, + bool StorePreamblesInMemory = false, StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false, CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, ArrayRef RemappedFiles = std::nullopt, diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1397,7 +1397,7 @@ llvm::ErrorOr NewPreamble = PrecompiledPreamble::Build( PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS, - PCHContainerOps, /*StoreInMemory=*/false, PreambleStoragePath, + PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath, Callbacks); PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = @@ -1742,13 +1742,13 @@ const char **ArgBegin, const char **ArgEnd, std::shared_ptr PCHContainerOps, IntrusiveRefCntPtr Diags, StringRef ResourceFilesPath, - StringRef PreambleStoragePath, bool OnlyLocalDecls, - CaptureDiagsKind CaptureDiagnostics, ArrayRef RemappedFiles, - bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses, - TranslationUnitKind TUKind, bool CacheCodeCompletionResults, - bool IncludeBriefCommentsInCodeCompletion, bool AllowPCHWithCompilerErrors, - SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse, - bool UserFilesAreVolatile, bool ForSerialization, + bool StorePreamblesInMemory, StringRef PreambleStoragePath, + bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, + ArrayRef RemappedFiles, bool RemappedFilesKeepOriginalName, + unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind, + bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, + bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies, + bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization, bool RetainExcludedConditionalBlocks, std::optional ModuleFormat, std::unique_ptr *ErrAST, IntrusiveRefCntPtr VFS) { @@ -1803,6 +1803,7 @@ VFS = llvm::vfs::getRealFileSystem(); VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS); AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); + AST->StorePreamblesInMemory = StorePreamblesInMemory; AST->PreambleStoragePath = PreambleStoragePath; AST->ModuleCache = new InMemoryModuleCache; AST->OnlyLocalDecls = OnlyLocalDecls; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3742,6 +3742,7 @@ options->ExcludeDeclarationsFromPCH, options->DisplayDiagnostics, options->ThreadBackgroundPriorityForIndexing, options->ThreadBackgroundPriorityForEditing); + CIdxr->setStorePreamblesInMemory(options->StorePreamblesInMemory); CIdxr->setPreambleStoragePath(options->PreambleStoragePath); CIdxr->setInvocationEmissionPath(options->InvocationEmissionPath); return CIdxr; @@ -3956,8 +3957,9 @@ std::unique_ptr Unit(ASTUnit::LoadFromCommandLine( Args->data(), Args->data() + Args->size(), CXXIdx->getPCHContainerOperations(), Diags, - CXXIdx->getClangResourcesPath(), CXXIdx->getPreambleStoragePath(), - CXXIdx->getOnlyLocalDecls(), CaptureDiagnostics, *RemappedFiles.get(), + CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(), + CXXIdx->getPreambleStoragePath(), CXXIdx->getOnlyLocalDecls(), + CaptureDiagnostics, *RemappedFiles.get(), /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses, TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion, /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse, diff --git a/clang/tools/libclang/CIndexer.h b/clang/tools/libclang/CIndexer.h --- a/clang/tools/libclang/CIndexer.h +++ b/clang/tools/libclang/CIndexer.h @@ -34,6 +34,7 @@ class CIndexer { bool OnlyLocalDecls; bool DisplayDiagnostics; + bool StorePreamblesInMemory = false; unsigned Options; // CXGlobalOptFlags. std::string ResourcesPath; @@ -78,6 +79,11 @@ StringRef getClangToolchainPath(); + void setStorePreamblesInMemory(bool StoreInMemory) { + StorePreamblesInMemory = StoreInMemory; + } + bool getStorePreamblesInMemory() const { return StorePreamblesInMemory; } + void setPreambleStoragePath(StringRef Str) { PreambleStoragePath = Str.str(); } diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp --- a/clang/unittests/Frontend/ASTUnitTest.cpp +++ b/clang/unittests/Frontend/ASTUnitTest.cpp @@ -167,7 +167,7 @@ std::unique_ptr ErrUnit; ASTUnit *AST = ASTUnit::LoadFromCommandLine( - &Args[0], &Args[4], PCHContainerOps, Diags, "", "", false, + &Args[0], &Args[4], PCHContainerOps, Diags, "", false, "", false, CaptureDiagsKind::All, std::nullopt, true, 0, TU_Complete, false, false, false, SkipFunctionBodiesScope::None, false, true, false, false, std::nullopt, &ErrUnit, nullptr); diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp --- a/clang/unittests/libclang/LibclangTest.cpp +++ b/clang/unittests/libclang/LibclangTest.cpp @@ -479,6 +479,7 @@ }; class LibclangSetPreambleStoragePathTest : public LibclangPreambleStorageTest { + virtual bool StorePreamblesInMemory() { return false; } virtual const char *PreambleStoragePath() = 0; protected: @@ -487,6 +488,7 @@ CXIndexOptions Opts{}; Opts.Size = sizeof(CXIndexOptions); + Opts.StorePreamblesInMemory = StorePreamblesInMemory(); Opts.PreambleStoragePath = PreambleStoragePath(); Index = clang_createIndexWithOptions(&Opts); ASSERT_TRUE(Index); @@ -506,6 +508,19 @@ const char *PreambleStoragePath() override { return PreambleDir.c_str(); } }; +class LibclangStoreInMemoryNullPreambleStoragePathTest + : public LibclangNullPreambleStoragePathTest { + bool StorePreamblesInMemory() override { return true; } +}; +class LibclangStoreInMemoryEmptyPreambleStoragePathTest + : public LibclangEmptyPreambleStoragePathTest { + bool StorePreamblesInMemory() override { return true; } +}; +class LibclangStoreInMemoryPreambleDirPreambleStoragePathTest + : public LibclangPreambleDirPreambleStoragePathTest { + bool StorePreamblesInMemory() override { return true; } +}; + TEST_F(LibclangNotOverriddenPreambleStoragePathTest, CountPreambles) { CountPreamblesInPreambleDir(0); } @@ -518,6 +533,16 @@ TEST_F(LibclangPreambleDirPreambleStoragePathTest, CountPreambles) { CountPreamblesInPreambleDir(1); } +TEST_F(LibclangStoreInMemoryNullPreambleStoragePathTest, CountPreambles) { + CountPreamblesInPreambleDir(0); +} +TEST_F(LibclangStoreInMemoryEmptyPreambleStoragePathTest, CountPreambles) { + CountPreamblesInPreambleDir(0); +} +TEST_F(LibclangStoreInMemoryPreambleDirPreambleStoragePathTest, + CountPreambles) { + CountPreamblesInPreambleDir(0); +} TEST_F(LibclangParseTest, AllSkippedRanges) { std::string Header = "header.h", Main = "main.cpp";