[clangd] Don't treat top-level decls as "local" if they are from the preamble.
authorSam McCall <sam.mccall@gmail.com>
Fri, 9 Nov 2018 15:35:00 +0000 (15:35 +0000)
committerSam McCall <sam.mccall@gmail.com>
Fri, 9 Nov 2018 15:35:00 +0000 (15:35 +0000)
Summary:
These get passed to HandleTopLevelDecl() if they happen to have been
deserialized for any reason. We don't want to treat them as part of the
main file.

Reviewers: ilya-biryukov

Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Differential Revision: https://reviews.llvm.org/D54303

llvm-svn: 346503

clang-tools-extra/clangd/ClangdUnit.cpp
clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp

index 7fdae21849eea9e3d39f4c7bf7c1b3d5ef27d16b..eadd891826b46d1c0838b2faae3faf015a490018 100644 (file)
@@ -57,6 +57,9 @@ public:
 
   bool HandleTopLevelDecl(DeclGroupRef DG) override {
     for (Decl *D : DG) {
+      if (D->isFromASTFile())
+        continue;
+
       // ObjCMethodDecl are not actually top-level decls.
       if (isa<ObjCMethodDecl>(D))
         continue;
index c4171e16b335ce6baedc514ff211f43a21a62522..d7961da2ac56c4eb2511f1d94527651ef8c8688b 100644 (file)
@@ -257,6 +257,28 @@ Bar* bar;
   }
 }
 
+MATCHER_P(DeclNamed, Name, "") {
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
+    if (ND->getName() == Name)
+      return true;
+  if (auto *Stream = result_listener->stream()) {
+    llvm::raw_os_ostream OS(*Stream);
+    arg->dump(OS);
+  }
+  return false;
+}
+
+TEST(ClangdUnitTest, TopLevelDecls) {
+  TestTU TU;
+  TU.HeaderCode = R"(
+    int header1();
+    int header2;
+  )";
+  TU.Code = "int main();";
+  auto AST = TU.build();
+  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang