Index: clangd/ClangdUnit.h =================================================================== --- clangd/ClangdUnit.h +++ clangd/ClangdUnit.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H -#include "../clang-tidy/ClangTidyOptions.h" +#include "Compiler.h" #include "Diagnostics.h" #include "FS.h" #include "Function.h" @@ -60,14 +60,6 @@ std::unique_ptr StatCache; }; -/// Information required to run clang, e.g. to parse AST or do code completion. -struct ParseInputs { - tooling::CompileCommand CompileCommand; - IntrusiveRefCntPtr FS; - std::string Contents; - tidy::ClangTidyOptions ClangTidyOpts; -}; - /// Stores and provides access to parsed AST. class ParsedAST { public: @@ -137,10 +129,6 @@ using PreambleParsedCallback = std::function)>; -/// Builds compiler invocation that could be used to build AST or preamble. -std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs); - /// Rebuild the preamble for the new inputs unless the old one can be reused. /// If \p OldPreamble can be reused, it is returned unchanged. /// If \p OldPreamble is null, always builds the preamble. Index: clangd/ClangdUnit.cpp =================================================================== --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -418,34 +418,6 @@ assert(this->Action); } -std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs) { - std::vector ArgStrs; - for (const auto &S : Inputs.CompileCommand.CommandLine) - ArgStrs.push_back(S.c_str()); - - if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { - log("Couldn't set working directory when creating compiler invocation."); - // We proceed anyway, our lit-tests rely on results for non-existing working - // dirs. - } - - // FIXME(ibiryukov): store diagnostics from CommandLine when we start - // reporting them. - IgnoreDiagnostics IgnoreDiagnostics; - llvm::IntrusiveRefCntPtr CommandLineDiagsEngine = - CompilerInstance::createDiagnostics(new DiagnosticOptions, - &IgnoreDiagnostics, false); - std::unique_ptr CI = createInvocationFromCommandLine( - ArgStrs, CommandLineDiagsEngine, Inputs.FS); - if (!CI) - return nullptr; - // createInvocationFromCommandLine sets DisableFree. - CI->getFrontendOpts().DisableFree = false; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; - return CI; -} - std::shared_ptr buildPreamble(PathRef FileName, CompilerInvocation &CI, std::shared_ptr OldPreamble, Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -1016,33 +1016,17 @@ const SemaCompleteInput &Input, IncludeStructure *Includes = nullptr) { trace::Span Tracer("Sema completion"); - std::vector ArgStrs; - for (const auto &S : Input.Command.CommandLine) - ArgStrs.push_back(S.c_str()); - - if (Input.VFS->setCurrentWorkingDirectory(Input.Command.Directory)) { - log("Couldn't set working directory"); - // We run parsing anyway, our lit-tests rely on results for non-existing - // working dirs. - } - llvm::IntrusiveRefCntPtr VFS = Input.VFS; if (Input.Preamble && Input.Preamble->StatCache) VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); - IgnoreDiagnostics DummyDiagsConsumer; - auto CI = createInvocationFromCommandLine( - ArgStrs, - CompilerInstance::createDiagnostics(new DiagnosticOptions, - &DummyDiagsConsumer, false), - VFS); + auto CI = + buildCompilerInvocation(ParseInputs{Input.Command, VFS, Input.Contents}); if (!CI) { elog("Couldn't create CompilerInvocation"); return false; } auto &FrontendOpts = CI->getFrontendOpts(); - FrontendOpts.DisableFree = false; FrontendOpts.SkipFunctionBodies = true; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; // Disable typo correction in Sema. CI->getLangOpts()->SpellChecking = false; // Setup code completion. @@ -1072,6 +1056,7 @@ *Offset; // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise // the remapped buffers do not get freed. + IgnoreDiagnostics DummyDiagsConsumer; auto Clang = prepareCompilerInstance( std::move(CI), (Input.Preamble && !CompletingInPreamble) ? &Input.Preamble->Preamble Index: clangd/Compiler.h =================================================================== --- clangd/Compiler.h +++ clangd/Compiler.h @@ -15,9 +15,11 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H +#include "../clang-tidy/ClangTidyOptions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" +#include "clang/Tooling/CompilationDatabase.h" namespace clang { namespace clangd { @@ -31,6 +33,18 @@ const clang::Diagnostic &Info) override; }; +/// Information required to run clang, e.g. to parse AST or do code completion. +struct ParseInputs { + tooling::CompileCommand CompileCommand; + IntrusiveRefCntPtr FS; + std::string Contents; + tidy::ClangTidyOptions ClangTidyOpts; +}; + +/// Builds compiler invocation that could be used to build AST or preamble. +std::unique_ptr +buildCompilerInvocation(const ParseInputs &Inputs); + /// Creates a compiler instance, configured so that: /// - Contents of the parsed file are remapped to \p MainFile. /// - Preamble is overriden to use PCH passed to this function. It means the Index: clangd/Compiler.cpp =================================================================== --- clangd/Compiler.cpp +++ clangd/Compiler.cpp @@ -39,6 +39,34 @@ IgnoreDiagnostics::log(DiagLevel, Info); } +std::unique_ptr +buildCompilerInvocation(const ParseInputs &Inputs) { + std::vector ArgStrs; + for (const auto &S : Inputs.CompileCommand.CommandLine) + ArgStrs.push_back(S.c_str()); + + if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { + log("Couldn't set working directory when creating compiler invocation."); + // We proceed anyway, our lit-tests rely on results for non-existing working + // dirs. + } + + // FIXME(ibiryukov): store diagnostics from CommandLine when we start + // reporting them. + IgnoreDiagnostics IgnoreDiagnostics; + llvm::IntrusiveRefCntPtr CommandLineDiagsEngine = + CompilerInstance::createDiagnostics(new DiagnosticOptions, + &IgnoreDiagnostics, false); + std::unique_ptr CI = createInvocationFromCommandLine( + ArgStrs, CommandLineDiagsEngine, Inputs.FS); + if (!CI) + return nullptr; + // createInvocationFromCommandLine sets DisableFree. + CI->getFrontendOpts().DisableFree = false; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; + return CI; +} + std::unique_ptr prepareCompilerInstance(std::unique_ptr CI, const PrecompiledPreamble *Preamble,