diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h --- a/clang-tools-extra/clangd/Compiler.h +++ b/clang-tools-extra/clangd/Compiler.h @@ -52,8 +52,8 @@ /// Builds compiler invocation that could be used to build AST or preamble. std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs, - clang::DiagnosticConsumer &D); +buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, + std::vector *CC1Args = nullptr); /// Creates a compiler instance, configured so that: /// - Contents of the parsed file are remapped to \p MainFile. diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -42,7 +42,8 @@ std::unique_ptr buildCompilerInvocation(const ParseInputs &Inputs, - clang::DiagnosticConsumer &D) { + clang::DiagnosticConsumer &D, + std::vector *CC1Args) { std::vector ArgStrs; for (const auto &S : Inputs.CompileCommand.CommandLine) ArgStrs.push_back(S.c_str()); @@ -57,7 +58,7 @@ CompilerInstance::createDiagnostics(new DiagnosticOptions, &D, false); std::unique_ptr CI = createInvocationFromCommandLine( ArgStrs, CommandLineDiagsEngine, Inputs.FS, - /*ShouldRecoverOnErrors=*/true); + /*ShouldRecoverOnErrors=*/true, CC1Args); if (!CI) return nullptr; // createInvocationFromCommandLine sets DisableFree. diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -407,8 +407,12 @@ llvm::join(Inputs.CompileCommand.CommandLine, " ")); // Rebuild the preamble and the AST. StoreDiags CompilerInvocationDiagConsumer; + std::vector CC1Args; std::unique_ptr Invocation = buildCompilerInvocation(Inputs, CompilerInvocationDiagConsumer); + // Log cc1 args even (especially!) if creating invocation failed. + if (!CC1Args.empty()) + vlog("cc1 args: {0}", llvm::join(CC1Args, " ")); std::vector CompilerInvocationDiags = CompilerInvocationDiagConsumer.take(); if (!Invocation) { diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -217,14 +217,18 @@ /// non-null (and possibly incorrect) CompilerInvocation if any errors were /// encountered. When this flag is false, always return null on errors. /// -/// \return A CompilerInvocation, or 0 if none was built for the given +/// \param CC1Args - if non-null, will be populated with the args to cc1 +/// expanded from \p Args. May be set even if nullptr is returned. +/// +/// \return A CompilerInvocation, or nullptr if none was built for the given /// argument vector. std::unique_ptr createInvocationFromCommandLine( ArrayRef Args, IntrusiveRefCntPtr Diags = IntrusiveRefCntPtr(), IntrusiveRefCntPtr VFS = nullptr, - bool ShouldRecoverOnErrors = false); + bool ShouldRecoverOnErrors = false, + std::vector *CC1Args = nullptr); /// Return the value of the last argument as an integer, or a default. If Diags /// is non-null, emits an error if the argument is given, but non-integral. diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp --- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -26,7 +26,8 @@ std::unique_ptr clang::createInvocationFromCommandLine( ArrayRef ArgList, IntrusiveRefCntPtr Diags, - IntrusiveRefCntPtr VFS, bool ShouldRecoverOnErorrs) { + IntrusiveRefCntPtr VFS, bool ShouldRecoverOnErorrs, + std::vector *CC1Args) { if (!Diags.get()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. @@ -89,6 +90,8 @@ } const ArgStringList &CCArgs = Cmd.getArguments(); + if (CC1Args) + *CC1Args = {CCArgs.begin(), CCArgs.end()}; auto CI = std::make_unique(); if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags) && !ShouldRecoverOnErorrs)