[clang-tools-extra] 41e2422 - [clangd] Unify compiler invocation creation
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 30 06:23:20 PDT 2021
Author: Kadir Cetinkaya
Date: 2021-07-30T15:22:51+02:00
New Revision: 41e24222861fb5394ab4c7e892a7d7f2914b533e
URL: https://github.com/llvm/llvm-project/commit/41e24222861fb5394ab4c7e892a7d7f2914b533e
DIFF: https://github.com/llvm/llvm-project/commit/41e24222861fb5394ab4c7e892a7d7f2914b533e.diff
LOG: [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
Added:
clang-tools-extra/clangd/test/indexer.test
Modified:
clang-tools-extra/clangd/CompileCommands.h
clang-tools-extra/clangd/Compiler.cpp
clang-tools-extra/clangd/Compiler.h
clang-tools-extra/clangd/indexer/IndexerMain.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/CompileCommands.h b/clang-tools-extra/clangd/CompileCommands.h
index 50c1a3571ec42..c6b338297385f 100644
--- a/clang-tools-extra/clangd/CompileCommands.h
+++ b/clang-tools-extra/clangd/CompileCommands.h
@@ -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;
diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp
index f2fb4489f105a..44a1b1a77db56 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -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;
}
diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h
index 0351069683155..b46765f6813ad 100644
--- a/clang-tools-extra/clangd/Compiler.h
+++ b/clang-tools-extra/clangd/Compiler.h
@@ -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,
diff --git a/clang-tools-extra/clangd/indexer/IndexerMain.cpp b/clang-tools-extra/clangd/indexer/IndexerMain.cpp
index 533334fcc1f28..2b3de014f8f7b 100644
--- a/clang-tools-extra/clangd/indexer/IndexerMain.cpp
+++ b/clang-tools-extra/clangd/indexer/IndexerMain.cpp
@@ -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 @@ class IndexActionFactory : public tooling::FrontendActionFactory {
/*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));
}
diff --git a/clang-tools-extra/clangd/test/indexer.test b/clang-tools-extra/clangd/test/indexer.test
new file mode 100644
index 0000000000000..2f01f6c557a7d
--- /dev/null
+++ b/clang-tools-extra/clangd/test/indexer.test
@@ -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
More information about the cfe-commits
mailing list