mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 15:06:10 +00:00
[clangd] Fold buildAST into ParsedAST::build. NFCI
This commit is contained in:
parent
910fff1c1d
commit
6880c4dfa3
@ -239,13 +239,22 @@ void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
llvm::Optional<ParsedAST>
|
llvm::Optional<ParsedAST>
|
||||||
ParsedAST::build(llvm::StringRef Version,
|
ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
|
||||||
std::unique_ptr<clang::CompilerInvocation> CI,
|
std::unique_ptr<clang::CompilerInvocation> CI,
|
||||||
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
||||||
std::shared_ptr<const PreambleData> Preamble,
|
std::shared_ptr<const PreambleData> Preamble) {
|
||||||
std::unique_ptr<llvm::MemoryBuffer> Buffer,
|
trace::Span Tracer("BuildAST");
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
|
SPAN_ATTACH(Tracer, "File", Filename);
|
||||||
const SymbolIndex *Index, const ParseOptions &Opts) {
|
|
||||||
|
auto VFS = Inputs.FS;
|
||||||
|
if (Preamble && Preamble->StatCache)
|
||||||
|
VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
|
||||||
|
if (VFS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
|
||||||
|
log("Couldn't set working directory when building the preamble.");
|
||||||
|
// We proceed anyway, our lit-tests rely on results for non-existing working
|
||||||
|
// dirs.
|
||||||
|
}
|
||||||
|
|
||||||
assert(CI);
|
assert(CI);
|
||||||
// Command-line parsing sets DisableFree to true by default, but we don't want
|
// Command-line parsing sets DisableFree to true by default, but we don't want
|
||||||
// to leak memory in clangd.
|
// to leak memory in clangd.
|
||||||
@ -255,18 +264,17 @@ ParsedAST::build(llvm::StringRef Version,
|
|||||||
|
|
||||||
// Recovery expression currently only works for C++.
|
// Recovery expression currently only works for C++.
|
||||||
if (CI->getLangOpts()->CPlusPlus)
|
if (CI->getLangOpts()->CPlusPlus)
|
||||||
CI->getLangOpts()->RecoveryAST = Opts.BuildRecoveryAST;
|
CI->getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST;
|
||||||
// This is on-by-default in windows to allow parsing SDK headers, but it
|
// This is on-by-default in windows to allow parsing SDK headers, but it
|
||||||
// breaks many features. Disable it for the main-file (not preamble).
|
// breaks many features. Disable it for the main-file (not preamble).
|
||||||
CI->getLangOpts()->DelayedTemplateParsing = false;
|
CI->getLangOpts()->DelayedTemplateParsing = false;
|
||||||
|
|
||||||
StoreDiags ASTDiags;
|
StoreDiags ASTDiags;
|
||||||
std::string Content = std::string(Buffer->getBuffer());
|
|
||||||
std::string Filename =
|
|
||||||
std::string(Buffer->getBufferIdentifier()); // Absolute.
|
|
||||||
|
|
||||||
auto Clang = prepareCompilerInstance(std::move(CI), PreamblePCH,
|
auto Clang = prepareCompilerInstance(
|
||||||
std::move(Buffer), VFS, ASTDiags);
|
std::move(CI), PreamblePCH,
|
||||||
|
llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, Filename), VFS,
|
||||||
|
ASTDiags);
|
||||||
if (!Clang)
|
if (!Clang)
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
@ -290,12 +298,12 @@ ParsedAST::build(llvm::StringRef Version,
|
|||||||
{
|
{
|
||||||
trace::Span Tracer("ClangTidyInit");
|
trace::Span Tracer("ClangTidyInit");
|
||||||
dlog("ClangTidy configuration for file {0}: {1}", Filename,
|
dlog("ClangTidy configuration for file {0}: {1}", Filename,
|
||||||
tidy::configurationAsText(Opts.ClangTidyOpts));
|
tidy::configurationAsText(Inputs.Opts.ClangTidyOpts));
|
||||||
tidy::ClangTidyCheckFactories CTFactories;
|
tidy::ClangTidyCheckFactories CTFactories;
|
||||||
for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
|
for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
|
||||||
E.instantiate()->addCheckFactories(CTFactories);
|
E.instantiate()->addCheckFactories(CTFactories);
|
||||||
CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
|
CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
|
||||||
tidy::ClangTidyGlobalOptions(), Opts.ClangTidyOpts));
|
tidy::ClangTidyGlobalOptions(), Inputs.Opts.ClangTidyOpts));
|
||||||
CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
|
CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
|
||||||
CTContext->setASTContext(&Clang->getASTContext());
|
CTContext->setASTContext(&Clang->getASTContext());
|
||||||
CTContext->setCurrentFile(Filename);
|
CTContext->setCurrentFile(Filename);
|
||||||
@ -345,16 +353,17 @@ ParsedAST::build(llvm::StringRef Version,
|
|||||||
// (e.g. incomplete type) and attach include insertion fixes to diagnostics.
|
// (e.g. incomplete type) and attach include insertion fixes to diagnostics.
|
||||||
llvm::Optional<IncludeFixer> FixIncludes;
|
llvm::Optional<IncludeFixer> FixIncludes;
|
||||||
auto BuildDir = VFS->getCurrentWorkingDirectory();
|
auto BuildDir = VFS->getCurrentWorkingDirectory();
|
||||||
if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) {
|
if (Inputs.Opts.SuggestMissingIncludes && Inputs.Index &&
|
||||||
auto Style = getFormatStyleForFile(Filename, Content, VFS.get());
|
!BuildDir.getError()) {
|
||||||
|
auto Style = getFormatStyleForFile(Filename, Inputs.Contents, VFS.get());
|
||||||
auto Inserter = std::make_shared<IncludeInserter>(
|
auto Inserter = std::make_shared<IncludeInserter>(
|
||||||
Filename, Content, Style, BuildDir.get(),
|
Filename, Inputs.Contents, Style, BuildDir.get(),
|
||||||
&Clang->getPreprocessor().getHeaderSearchInfo());
|
&Clang->getPreprocessor().getHeaderSearchInfo());
|
||||||
if (Preamble) {
|
if (Preamble) {
|
||||||
for (const auto &Inc : Preamble->Includes.MainFileIncludes)
|
for (const auto &Inc : Preamble->Includes.MainFileIncludes)
|
||||||
Inserter->addExisting(Inc);
|
Inserter->addExisting(Inc);
|
||||||
}
|
}
|
||||||
FixIncludes.emplace(Filename, Inserter, *Index,
|
FixIncludes.emplace(Filename, Inserter, *Inputs.Index,
|
||||||
/*IndexRequestLimit=*/5);
|
/*IndexRequestLimit=*/5);
|
||||||
ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
|
ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
|
||||||
const clang::Diagnostic &Info) {
|
const clang::Diagnostic &Info) {
|
||||||
@ -434,7 +443,7 @@ ParsedAST::build(llvm::StringRef Version,
|
|||||||
std::vector<Diag> D = ASTDiags.take(CTContext.getPointer());
|
std::vector<Diag> D = ASTDiags.take(CTContext.getPointer());
|
||||||
Diags.insert(Diags.end(), D.begin(), D.end());
|
Diags.insert(Diags.end(), D.begin(), D.end());
|
||||||
}
|
}
|
||||||
return ParsedAST(Version, std::move(Preamble), std::move(Clang),
|
return ParsedAST(Inputs.Version, std::move(Preamble), std::move(Clang),
|
||||||
std::move(Action), std::move(Tokens), std::move(Macros),
|
std::move(Action), std::move(Tokens), std::move(Macros),
|
||||||
std::move(ParsedDecls), std::move(Diags),
|
std::move(ParsedDecls), std::move(Diags),
|
||||||
std::move(Includes), std::move(CanonIncludes));
|
std::move(Includes), std::move(CanonIncludes));
|
||||||
@ -536,28 +545,5 @@ ParsedAST::ParsedAST(llvm::StringRef Version,
|
|||||||
assert(this->Action);
|
assert(this->Action);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Optional<ParsedAST>
|
|
||||||
buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
|
|
||||||
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
|
||||||
const ParseInputs &Inputs,
|
|
||||||
std::shared_ptr<const PreambleData> Preamble) {
|
|
||||||
trace::Span Tracer("BuildAST");
|
|
||||||
SPAN_ATTACH(Tracer, "File", FileName);
|
|
||||||
|
|
||||||
auto VFS = Inputs.FS;
|
|
||||||
if (Preamble && Preamble->StatCache)
|
|
||||||
VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
|
|
||||||
if (VFS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
|
|
||||||
log("Couldn't set working directory when building the preamble.");
|
|
||||||
// We proceed anyway, our lit-tests rely on results for non-existing working
|
|
||||||
// dirs.
|
|
||||||
}
|
|
||||||
|
|
||||||
return ParsedAST::build(
|
|
||||||
Inputs.Version, std::move(Invocation), CompilerInvocationDiags, Preamble,
|
|
||||||
llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, FileName),
|
|
||||||
std::move(VFS), Inputs.Index, Inputs.Opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace clangd
|
} // namespace clangd
|
||||||
} // namespace clang
|
} // namespace clang
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// - capturing diagnostics for later access
|
// - capturing diagnostics for later access
|
||||||
// - running clang-tidy checks checks
|
// - running clang-tidy checks checks
|
||||||
//
|
//
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
|
||||||
@ -45,15 +44,14 @@ class SymbolIndex;
|
|||||||
/// Stores and provides access to parsed AST.
|
/// Stores and provides access to parsed AST.
|
||||||
class ParsedAST {
|
class ParsedAST {
|
||||||
public:
|
public:
|
||||||
/// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
|
/// Attempts to run Clang and store the parsed AST.
|
||||||
/// it is reused during parsing.
|
/// If \p Preamble is non-null it is reused during parsing.
|
||||||
|
/// This function does not check if preamble is valid to reuse.
|
||||||
static llvm::Optional<ParsedAST>
|
static llvm::Optional<ParsedAST>
|
||||||
build(llvm::StringRef Version, std::unique_ptr<clang::CompilerInvocation> CI,
|
build(llvm::StringRef Filename, const ParseInputs &Inputs,
|
||||||
|
std::unique_ptr<clang::CompilerInvocation> CI,
|
||||||
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
||||||
std::shared_ptr<const PreambleData> Preamble,
|
std::shared_ptr<const PreambleData> Preamble);
|
||||||
std::unique_ptr<llvm::MemoryBuffer> Buffer,
|
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
|
|
||||||
const SymbolIndex *Index, const ParseOptions &Opts);
|
|
||||||
|
|
||||||
ParsedAST(ParsedAST &&Other);
|
ParsedAST(ParsedAST &&Other);
|
||||||
ParsedAST &operator=(ParsedAST &&Other);
|
ParsedAST &operator=(ParsedAST &&Other);
|
||||||
@ -141,15 +139,6 @@ private:
|
|||||||
CanonicalIncludes CanonIncludes;
|
CanonicalIncludes CanonIncludes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build an AST from provided user inputs. This function does not check if
|
|
||||||
/// preamble can be reused, as this function expects that \p Preamble is the
|
|
||||||
/// result of calling buildPreamble.
|
|
||||||
llvm::Optional<ParsedAST>
|
|
||||||
buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
|
|
||||||
llvm::ArrayRef<Diag> CompilerInvocationDiags,
|
|
||||||
const ParseInputs &Inputs,
|
|
||||||
std::shared_ptr<const PreambleData> Preamble);
|
|
||||||
|
|
||||||
/// For testing/debugging purposes. Note that this method deserializes all
|
/// For testing/debugging purposes. Note that this method deserializes all
|
||||||
/// unserialized Decls, so use with care.
|
/// unserialized Decls, so use with care.
|
||||||
void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS);
|
void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS);
|
||||||
|
@ -665,8 +665,8 @@ void ASTWorker::runWithAST(
|
|||||||
// return a compatible preamble as ASTWorker::update blocks.
|
// return a compatible preamble as ASTWorker::update blocks.
|
||||||
llvm::Optional<ParsedAST> NewAST;
|
llvm::Optional<ParsedAST> NewAST;
|
||||||
if (Invocation) {
|
if (Invocation) {
|
||||||
NewAST = buildAST(FileName, std::move(Invocation),
|
NewAST = ParsedAST::build(FileName, FileInputs, std::move(Invocation),
|
||||||
CompilerInvocationDiagConsumer.take(), FileInputs,
|
CompilerInvocationDiagConsumer.take(),
|
||||||
getPossiblyStalePreamble());
|
getPossiblyStalePreamble());
|
||||||
++ASTBuildCount;
|
++ASTBuildCount;
|
||||||
}
|
}
|
||||||
@ -804,8 +804,8 @@ void ASTWorker::generateDiagnostics(
|
|||||||
llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
|
llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
|
||||||
if (!AST || !InputsAreLatest) {
|
if (!AST || !InputsAreLatest) {
|
||||||
auto RebuildStartTime = DebouncePolicy::clock::now();
|
auto RebuildStartTime = DebouncePolicy::clock::now();
|
||||||
llvm::Optional<ParsedAST> NewAST = buildAST(
|
llvm::Optional<ParsedAST> NewAST = ParsedAST::build(
|
||||||
FileName, std::move(Invocation), CIDiags, Inputs, LatestPreamble);
|
FileName, Inputs, std::move(Invocation), CIDiags, LatestPreamble);
|
||||||
auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
|
auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
|
||||||
++ASTBuildCount;
|
++ASTBuildCount;
|
||||||
// Try to record the AST-build time, to inform future update debouncing.
|
// Try to record the AST-build time, to inform future update debouncing.
|
||||||
|
@ -73,8 +73,8 @@ ParsedAST TestTU::build() const {
|
|||||||
auto Preamble =
|
auto Preamble =
|
||||||
buildPreamble(testPath(Filename), *CI, Inputs,
|
buildPreamble(testPath(Filename), *CI, Inputs,
|
||||||
/*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
|
/*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
|
||||||
auto AST = buildAST(testPath(Filename), std::move(CI), Diags.take(), Inputs,
|
auto AST = ParsedAST::build(testPath(Filename), Inputs, std::move(CI),
|
||||||
Preamble);
|
Diags.take(), Preamble);
|
||||||
if (!AST.hasValue()) {
|
if (!AST.hasValue()) {
|
||||||
ADD_FAILURE() << "Failed to build code:\n" << Code;
|
ADD_FAILURE() << "Failed to build code:\n" << Code;
|
||||||
llvm_unreachable("Failed to build TestTU!");
|
llvm_unreachable("Failed to build TestTU!");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user