[PATCH] D143418: [libclang] Add API to set preferred temp dir path
Igor Kushnir via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 6 09:51:32 PST 2023
vedgy created this revision.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
vedgy requested review of this revision.
Herald added subscribers: cfe-commits, ilya-biryukov.
Herald added projects: clang, clang-tools-extra.
TempPCHFile::create() calls llvm::sys::fs::createTemporaryFile() to
create a file named preamble-*.pch in a system temporary directory. This
commit allows to override the directory where these often many and large
preamble-*.pch files are stored. The added API is named generally to
store other temporary files created by libclang in the same overridden
preferred temporary directory, once such other files are discovered.
A libclang user passes a preferred temporary directory path to
clang_CXIndex_setPreferredTempDirPath(), which stores it in
CIndexer::PreferredTempDirPath. Whenever
clang_parseTranslationUnit_Impl() is called, it passes
CIndexer::PreferredTempDirPath to ASTUnit::LoadFromCommandLine(), which
stores this argument in ASTUnit::PreferredTempDirPath. Whenever
ASTUnit::getMainBufferWithPrecompiledPreamble() is called, it passes
ASTUnit::PreferredTempDirPath to PrecompiledPreamble::Build().
PrecompiledPreamble::Build() forwards the corresponding StoragePath
argument to TempPCHFile::create(). If StoragePath is not empty,
TempPCHFile::create() stores the preamble-*.pch file in the directory at
the specified path rather than in the system temporary directory.
The analysis below proves that this passing around of the
PreferredTempDirPath string is sufficient to guarantee that the libclang
user override is used in TempPCHFile::create(). The analysis ignores API
uses in test code.
TempPCHFile::create() is called only in PrecompiledPreamble::Build().
PrecompiledPreamble::Build() is called only in two places: one in
clangd, which is not used by libclang, and one in
ASTUnit::getMainBufferWithPrecompiledPreamble().
ASTUnit::getMainBufferWithPrecompiledPreamble() is called in 3 places:
1. ASTUnit::LoadFromCompilerInvocation() [analyzed below].
2. ASTUnit::Reparse(), which in turn is called only from
clang_reparseTranslationUnit_Impl(), which in turn is called only from
clang_reparseTranslationUnit(). clang_reparseTranslationUnit() is never
called in LLVM code, but is part of public libclang API. This function's
documentation requires its translation unit argument to have been built
with clang_createTranslationUnitFromSourceFile().
clang_createTranslationUnitFromSourceFile() delegates its work to
clang_parseTranslationUnit(), which delegates to
clang_parseTranslationUnit2(), which delegates to
clang_parseTranslationUnit2FullArgv(), which delegates to
clang_parseTranslationUnit_Impl(), which passes
CIndexer::PreferredTempDirPath to the ASTUnit it creates.
3. ASTUnit::CodeComplete() passes AllowRebuild = false to
ASTUnit::getMainBufferWithPrecompiledPreamble(), which makes it return
nullptr before calling PrecompiledPreamble::Build().
Both ASTUnit::LoadFromCompilerInvocation() overloads (one of which
delegates its work to another) call
ASTUnit::getMainBufferWithPrecompiledPreamble() only if their argument
PrecompilePreambleAfterNParses > 0. LoadFromCompilerInvocation() is
called in:
1. ASTBuilderAction::runInvocation() keeps the default parameter value
of PrecompilePreambleAfterNParses = 0, meaning that the preamble file is
never created from here.
2. ASTUnit::LoadFromCommandLine().
ASTUnit::LoadFromCommandLine() is called in two places:
1. CrossTranslationUnitContext::ASTLoader::loadFromSource() keeps the
default parameter value of PrecompilePreambleAfterNParses = 0, meaning
that the preamble file is never created from here.
2. clang_parseTranslationUnit_Impl(), which passes
CIndexer::PreferredTempDirPath to the ASTUnit it creates.
TempPCHFile::create() uses PreferredTempDirPath in the same way as
LibclangInvocationReporter() uses InvocationEmissionPath. The
documentation for clang_CXIndex_setInvocationEmissionPathOption() does
not specify ownership, encoding, relative vs absolute path or separator
requirements. So the new function's documentation doesn't either.
The added function clang_CXIndex_setPreferredTempDirPath() works as
expected in KDevelop:
https://invent.kde.org/kdevelop/kdevelop/-/merge_requests/283
Fixes: https://github.com/llvm/llvm-project/issues/51847
Depends on D143415 <https://reviews.llvm.org/D143415>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D143418
Files:
clang-tools-extra/clangd/Preamble.cpp
clang/docs/ReleaseNotes.rst
clang/include/clang-c/Index.h
clang/include/clang/Frontend/ASTUnit.h
clang/include/clang/Frontend/PrecompiledPreamble.h
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/PrecompiledPreamble.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CIndexer.h
clang/tools/libclang/libclang.map
clang/unittests/Frontend/ASTUnitTest.cpp
clang/unittests/libclang/LibclangTest.cpp
clang/unittests/libclang/TestUtils.h
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143418.495190.patch
Type: text/x-patch
Size: 18601 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230206/a4978ff4/attachment-0001.bin>
More information about the cfe-commits
mailing list