forked from OSchip/llvm-project
[clangd] Unify compiler invocation creation
Background-indexing is fine, because it uses GlobalCompilationDatabase to fetch the compile commands (hence uses CommandMangler), and creates invocation through buildCompilerInvocation. Depends on D106639. Differential Revision: https://reviews.llvm.org/D106669
This commit is contained in:
parent
6569b7f902
commit
41e2422286
|
@ -26,10 +26,6 @@ namespace clangd {
|
|||
// - forcing the use of clangd's builtin headers rather than clang's
|
||||
// - resolving argv0 as cc1 expects
|
||||
// - injecting -isysroot flags on mac as the system clang does
|
||||
// FIXME: This is currently not used in all code paths that create invocations.
|
||||
// Make use of these adjusters and buildCompilerInvocation in clangd-indexer as
|
||||
// well. It should be possible to hook it up by overriding RunInvocation in
|
||||
// FrontendActionFactory.
|
||||
struct CommandMangler {
|
||||
// Absolute path to clang.
|
||||
llvm::Optional<std::string> ClangPath;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Compiler.h"
|
||||
#include "support/Logger.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Serialization/PCHContainerOperations.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
@ -41,6 +42,44 @@ void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
|
|||
IgnoreDiagnostics::log(DiagLevel, Info);
|
||||
}
|
||||
|
||||
void disableUnsupportedOptions(CompilerInvocation &CI) {
|
||||
// Disable "clang -verify" diagnostics, they are rarely useful in clangd, and
|
||||
// our compiler invocation set-up doesn't seem to work with it (leading
|
||||
// assertions in VerifyDiagnosticConsumer).
|
||||
CI.getDiagnosticOpts().VerifyDiagnostics = false;
|
||||
CI.getDiagnosticOpts().ShowColors = false;
|
||||
|
||||
// Disable any dependency outputting, we don't want to generate files or write
|
||||
// to stdout/stderr.
|
||||
CI.getDependencyOutputOpts().ShowIncludesDest = ShowIncludesDestination::None;
|
||||
CI.getDependencyOutputOpts().OutputFile.clear();
|
||||
CI.getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
|
||||
CI.getDependencyOutputOpts().DOTOutputFile.clear();
|
||||
CI.getDependencyOutputOpts().ModuleDependencyOutputDir.clear();
|
||||
|
||||
// Disable any pch generation/usage operations. Since serialized preamble
|
||||
// format is unstable, using an incompatible one might result in unexpected
|
||||
// behaviours, including crashes.
|
||||
CI.getPreprocessorOpts().ImplicitPCHInclude.clear();
|
||||
CI.getPreprocessorOpts().PrecompiledPreambleBytes = {0, false};
|
||||
CI.getPreprocessorOpts().PCHThroughHeader.clear();
|
||||
CI.getPreprocessorOpts().PCHWithHdrStop = false;
|
||||
CI.getPreprocessorOpts().PCHWithHdrStopCreate = false;
|
||||
// Don't crash on `#pragma clang __debug parser_crash`
|
||||
CI.getPreprocessorOpts().DisablePragmaDebugCrash = true;
|
||||
|
||||
// Always default to raw container format as clangd doesn't registry any other
|
||||
// and clang dies when faced with unknown formats.
|
||||
CI.getHeaderSearchOpts().ModuleFormat =
|
||||
PCHContainerOperations().getRawReader().getFormat().str();
|
||||
|
||||
CI.getFrontendOpts().Plugins.clear();
|
||||
CI.getFrontendOpts().AddPluginActions.clear();
|
||||
CI.getFrontendOpts().PluginArgs.clear();
|
||||
CI.getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
|
||||
CI.getFrontendOpts().ActionName.clear();
|
||||
}
|
||||
|
||||
std::unique_ptr<CompilerInvocation>
|
||||
buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
|
||||
std::vector<std::string> *CC1Args) {
|
||||
|
@ -60,43 +99,8 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
|
|||
CI->getFrontendOpts().DisableFree = false;
|
||||
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
|
||||
CI->getLangOpts()->RetainCommentsFromSystemHeaders = true;
|
||||
// Disable "clang -verify" diagnostics, they are rarely useful in clangd, and
|
||||
// our compiler invocation set-up doesn't seem to work with it (leading
|
||||
// assertions in VerifyDiagnosticConsumer).
|
||||
CI->getDiagnosticOpts().VerifyDiagnostics = false;
|
||||
CI->getDiagnosticOpts().ShowColors = false;
|
||||
|
||||
// Disable any dependency outputting, we don't want to generate files or write
|
||||
// to stdout/stderr.
|
||||
CI->getDependencyOutputOpts().ShowIncludesDest =
|
||||
ShowIncludesDestination::None;
|
||||
CI->getDependencyOutputOpts().OutputFile.clear();
|
||||
CI->getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
|
||||
CI->getDependencyOutputOpts().DOTOutputFile.clear();
|
||||
CI->getDependencyOutputOpts().ModuleDependencyOutputDir.clear();
|
||||
|
||||
// Disable any pch generation/usage operations. Since serialized preamble
|
||||
// format is unstable, using an incompatible one might result in unexpected
|
||||
// behaviours, including crashes.
|
||||
CI->getPreprocessorOpts().ImplicitPCHInclude.clear();
|
||||
CI->getPreprocessorOpts().PrecompiledPreambleBytes = {0, false};
|
||||
CI->getPreprocessorOpts().PCHThroughHeader.clear();
|
||||
CI->getPreprocessorOpts().PCHWithHdrStop = false;
|
||||
CI->getPreprocessorOpts().PCHWithHdrStopCreate = false;
|
||||
// Don't crash on `#pragma clang __debug parser_crash`
|
||||
CI->getPreprocessorOpts().DisablePragmaDebugCrash = true;
|
||||
|
||||
// Always default to raw container format as clangd doesn't registry any other
|
||||
// and clang dies when faced with unknown formats.
|
||||
CI->getHeaderSearchOpts().ModuleFormat =
|
||||
PCHContainerOperations().getRawReader().getFormat().str();
|
||||
|
||||
CI->getFrontendOpts().Plugins.clear();
|
||||
CI->getFrontendOpts().AddPluginActions.clear();
|
||||
CI->getFrontendOpts().PluginArgs.clear();
|
||||
CI->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
|
||||
CI->getFrontendOpts().ActionName.clear();
|
||||
|
||||
disableUnsupportedOptions(*CI);
|
||||
return CI;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,12 @@ struct ParseInputs {
|
|||
FeatureModuleSet *FeatureModules = nullptr;
|
||||
};
|
||||
|
||||
/// Clears \p CI from options that are not supported by clangd, like codegen or
|
||||
/// plugins. This should be combined with CommandMangler::adjust, which provides
|
||||
/// similar functionality for options that needs to be stripped from compile
|
||||
/// flags.
|
||||
void disableUnsupportedOptions(CompilerInvocation &CI);
|
||||
|
||||
/// Builds compiler invocation that could be used to build AST or preamble.
|
||||
std::unique_ptr<CompilerInvocation>
|
||||
buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CompileCommands.h"
|
||||
#include "Compiler.h"
|
||||
#include "index/IndexAction.h"
|
||||
#include "index/Merge.h"
|
||||
#include "index/Ref.h"
|
||||
|
@ -23,6 +25,7 @@
|
|||
#include "clang/Tooling/Tooling.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
@ -82,6 +85,15 @@ public:
|
|||
/*IncludeGraphCallback=*/nullptr);
|
||||
}
|
||||
|
||||
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
|
||||
FileManager *Files,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
DiagnosticConsumer *DiagConsumer) override {
|
||||
disableUnsupportedOptions(*Invocation);
|
||||
return tooling::FrontendActionFactory::runInvocation(
|
||||
std::move(Invocation), Files, std::move(PCHContainerOps), DiagConsumer);
|
||||
}
|
||||
|
||||
// Awkward: we write the result in the destructor, because the executor
|
||||
// takes ownership so it's the easiest way to get our data back out.
|
||||
~IndexActionFactory() {
|
||||
|
@ -135,7 +147,8 @@ int main(int argc, const char **argv) {
|
|||
clang::clangd::IndexFileIn Data;
|
||||
auto Err = Executor->get()->execute(
|
||||
std::make_unique<clang::clangd::IndexActionFactory>(Data),
|
||||
clang::tooling::getStripPluginsAdjuster());
|
||||
clang::tooling::ArgumentsAdjuster(
|
||||
clang::clangd::CommandMangler::detect()));
|
||||
if (Err) {
|
||||
clang::clangd::elog("{0}", std::move(Err));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# RUN: rm -rf %t.cpp
|
||||
# RUN: touch %t.cpp
|
||||
#
|
||||
# Make sure compile flags are adjusted for clangd. `--save-temps` creates a
|
||||
# `.ii` file and `-verify` triggers extra diagnostics generation. Clangd should
|
||||
# strip those.
|
||||
# RUN: clangd-indexer %t.cpp -- -Xclang -verify --save-temps -- 2>&1 | FileCheck %s
|
||||
# CHECK-NOT: error: no expected directives found: consider use of 'expected-no-diagnostics'
|
||||
# RUN: not ls %t.ii
|
Loading…
Reference in New Issue