[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