ilya-biryukov updated this revision to Diff 217335.
ilya-biryukov marked 2 inline comments as done.
ilya-biryukov added a comment.

- Start a paragrah with \returns instead of putting it in the middle


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66731/new/

https://reviews.llvm.org/D66731

Files:
  clang-tools-extra/clangd/Compiler.cpp
  clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp
  clang/include/clang/Frontend/CompilerInvocation.h
  clang/include/clang/Frontend/Utils.h
  clang/lib/Frontend/CreateInvocationFromCommandLine.cpp

Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
===================================================================
--- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -24,14 +24,9 @@
 using namespace clang;
 using namespace llvm::opt;
 
-/// createInvocationFromCommandLine - Construct a compiler invocation object for
-/// a command line argument vector.
-///
-/// \return A CompilerInvocation, or 0 if none was built for the given
-/// argument vector.
 std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
     ArrayRef<const char *> ArgList, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
+    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool ShouldRecoverOnErorrs) {
   if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
@@ -95,11 +90,10 @@
 
   const ArgStringList &CCArgs = Cmd.getArguments();
   auto CI = std::make_unique<CompilerInvocation>();
-  if (!CompilerInvocation::CreateFromArgs(*CI,
-                                     const_cast<const char **>(CCArgs.data()),
-                                     const_cast<const char **>(CCArgs.data()) +
-                                     CCArgs.size(),
-                                     *Diags))
+  if (!CompilerInvocation::CreateFromArgs(
+          *CI, const_cast<const char **>(CCArgs.data()),
+          const_cast<const char **>(CCArgs.data()) + CCArgs.size(), *Diags) &&
+      !ShouldRecoverOnErorrs)
     return nullptr;
   return CI;
 }
Index: clang/include/clang/Frontend/Utils.h
===================================================================
--- clang/include/clang/Frontend/Utils.h
+++ clang/include/clang/Frontend/Utils.h
@@ -213,13 +213,18 @@
 /// createInvocationFromCommandLine - Construct a compiler invocation object for
 /// a command line argument vector.
 ///
+/// \param ShouldRecoverOnErrors - whether we should attempt to return a
+/// 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
 /// argument vector.
 std::unique_ptr<CompilerInvocation> createInvocationFromCommandLine(
     ArrayRef<const char *> Args,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
         IntrusiveRefCntPtr<DiagnosticsEngine>(),
-    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
+    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr,
+    bool ShouldRecoverOnErrors = false);
 
 /// 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.
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -147,6 +147,11 @@
   /// Create a compiler invocation from a list of input options.
   /// \returns true on success.
   ///
+  /// \returns false if an error was encountered while parsing the arguments
+  /// and attempts to recover and continue parsing the rest of the arguments.
+  /// The recovery is best-effort and only guarantees that \p Res will end up in
+  /// one of the vaild-to-access (albeit arbitrary) states.
+  ///
   /// \param [out] Res - The resulting invocation.
   /// \param ArgBegin - The first element in the argument vector.
   /// \param ArgEnd - The last element in the argument vector.
Index: clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp
@@ -9,7 +9,9 @@
 #include "AST.h"
 #include "Annotations.h"
 #include "ClangdUnit.h"
+#include "Compiler.h"
 #include "SourceCode.h"
+#include "TestFS.h"
 #include "TestTU.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/TokenKinds.h"
@@ -244,6 +246,20 @@
   EXPECT_EQ(T.expandedTokens().drop_back().back().text(SM), "}");
 }
 
+TEST(ClangdUnitTest, CanBuildInvocationWithUnknownArgs) {
+  // Unknown flags should not prevent a build of compiler invocation.
+  ParseInputs Inputs;
+  Inputs.FS = buildTestFS({{testPath("foo.cpp"), "void test() {}"}});
+  Inputs.CompileCommand.CommandLine = {"clang", "-fsome-unknown-flag",
+                                       testPath("foo.cpp")};
+  EXPECT_NE(buildCompilerInvocation(Inputs), nullptr);
+
+  // Unknown forwarded to -cc1 should not a failure either.
+  Inputs.CompileCommand.CommandLine = {
+      "clang", "-Xclang", "-fsome-unknown-flag", testPath("foo.cpp")};
+  EXPECT_NE(buildCompilerInvocation(Inputs), nullptr);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/Compiler.cpp
===================================================================
--- clang-tools-extra/clangd/Compiler.cpp
+++ clang-tools-extra/clangd/Compiler.cpp
@@ -59,7 +59,8 @@
       CompilerInstance::createDiagnostics(new DiagnosticOptions,
                                           &IgnoreDiagnostics, false);
   std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine(
-      ArgStrs, CommandLineDiagsEngine, Inputs.FS);
+      ArgStrs, CommandLineDiagsEngine, Inputs.FS,
+      /*ShouldRecoverOnErrors=*/true);
   if (!CI)
     return nullptr;
   // createInvocationFromCommandLine sets DisableFree.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to