Dmitry.Kozhevnikov updated this revision to Diff 160837.
Dmitry.Kozhevnikov added a comment.

Add a unit test which explicitly builds preamble/AST


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50455

Files:
  clangd/ClangdUnit.cpp
  clangd/Compiler.cpp
  test/clangd/missing-includes.test
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===================================================================
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -15,6 +15,8 @@
 #include "TestFS.h"
 #include "URI.h"
 #include "clang/Config/config.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Errc.h"
@@ -37,6 +39,7 @@
 using ::testing::Eq;
 using ::testing::Field;
 using ::testing::Gt;
+using ::testing::HasSubstr;
 using ::testing::IsEmpty;
 using ::testing::Pair;
 using ::testing::UnorderedElementsAre;
@@ -963,6 +966,53 @@
                                        Field(&CodeCompletion::Name, "baz")));
 }
 
+TEST(DiagnosticsTest, RecoverAfterFatalError) {
+  auto FooCpp = testPath("foo.cpp");
+
+  ParseInputs PI;
+  PI.CompileCommand.Directory = testRoot();
+  PI.CompileCommand.Filename = FooCpp;
+  PI.CompileCommand.CommandLine = {"clang", "-xc++", FooCpp};
+
+  llvm::StringMap<std::string> Files;
+  Files[FooCpp] = "";
+  PI.FS = buildTestFS(Files);
+
+  PI.Contents = R"cpp(
+    #include "preamble1"
+    #include "preamble2"
+    // end of the preamble
+    int x;
+    #include "main1"
+    #include "main2"
+  )cpp";
+
+  auto PreambleCI = buildCompilerInvocation(PI);
+
+  auto Preamble = buildPreamble(
+      FooCpp, *PreambleCI, /*OldPreamble=*/nullptr, tooling::CompileCommand(),
+      PI, std::make_shared<PCHContainerOperations>(), /*StoreInMemory=*/true,
+      /*PreambleCallback=*/nullptr);
+  ASSERT_TRUE(Preamble) << "Failed to build preamble";
+
+  ASSERT_EQ(Preamble->Diags.size(), 2u);
+  EXPECT_THAT(Preamble->Diags[0].Message, HasSubstr("preamble1"));
+  EXPECT_THAT(Preamble->Diags[1].Message, HasSubstr("preamble2"));
+
+  auto MainFileCI = buildCompilerInvocation(PI);
+  auto AST =
+      ParsedAST::build(std::move(MainFileCI), Preamble,
+                       llvm::MemoryBuffer::getMemBufferCopy(PI.Contents),
+                       std::make_shared<PCHContainerOperations>(), PI.FS);
+  ASSERT_TRUE(AST.hasValue()) << "Failed to build AST";
+
+  ASSERT_EQ(AST->getDiagnostics().size(), 4u);
+  EXPECT_THAT(AST->getDiagnostics()[0].Message, HasSubstr("preamble1"));
+  EXPECT_THAT(AST->getDiagnostics()[1].Message, HasSubstr("preamble2"));
+  EXPECT_THAT(AST->getDiagnostics()[2].Message, HasSubstr("main1"));
+  EXPECT_THAT(AST->getDiagnostics()[3].Message, HasSubstr("main2"));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: test/clangd/missing-includes.test
===================================================================
--- /dev/null
+++ test/clangd/missing-includes.test
@@ -0,0 +1,13 @@
+# RUN: clangd -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"#include <a>\n#include <b>\nint x;\n#include <c>\n#include <d>\n"}}}
+# CHECK:  "method": "textDocument/publishDiagnostics",
+# CHECK:  "message": "'a' file not found",
+# CHECK:  "message": "'b' file not found",
+# CHECK:  "message": "'c' file not found",
+# CHECK:  "message": "'d' file not found",
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/Compiler.cpp
===================================================================
--- clangd/Compiler.cpp
+++ clangd/Compiler.cpp
@@ -63,6 +63,7 @@
   auto Clang = llvm::make_unique<CompilerInstance>(PCHs);
   Clang->setInvocation(std::move(CI));
   Clang->createDiagnostics(&DiagsClient, false);
+  Clang->getDiagnostics().setSuppressAfterFatalError(false);
 
   if (auto VFSWithRemapping = createVFSFromCompilerInvocation(
           Clang->getInvocation(), Clang->getDiagnostics(), VFS))
Index: clangd/ClangdUnit.cpp
===================================================================
--- clangd/ClangdUnit.cpp
+++ clangd/ClangdUnit.cpp
@@ -328,6 +328,8 @@
   // to read back. We rely on dynamic index for the comments instead.
   CI.getPreprocessorOpts().WriteCommentListToPCH = false;
 
+  PreambleDiagsEngine->setSuppressAfterFatalError(false);
+
   CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
   if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
     log("Couldn't set working directory when building the preamble.");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to