1 //===-- XRefsTests.cpp  ---------------------------*- C++ -*--------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "Annotations.h"
9 #include "Compiler.h"
10 #include "Matchers.h"
11 #include "ParsedAST.h"
12 #include "Protocol.h"
13 #include "SourceCode.h"
14 #include "SyncAPI.h"
15 #include "TestFS.h"
16 #include "TestIndex.h"
17 #include "TestTU.h"
18 #include "XRefs.h"
19 #include "index/FileIndex.h"
20 #include "index/MemIndex.h"
21 #include "index/SymbolCollector.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "clang/Index/IndexingAction.h"
25 #include "llvm/ADT/None.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Error.h"
29 #include "llvm/Support/Path.h"
30 #include "llvm/Support/ScopedPrinter.h"
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
33 #include <string>
34 #include <vector>
35 
36 namespace clang {
37 namespace clangd {
38 namespace {
39 
40 using ::testing::ElementsAre;
41 using ::testing::IsEmpty;
42 using ::testing::Matcher;
43 using ::testing::UnorderedElementsAreArray;
44 
45 class IgnoreDiagnostics : public DiagnosticsConsumer {
onDiagnosticsReady(PathRef File,std::vector<Diag> Diagnostics)46   void onDiagnosticsReady(PathRef File,
47                           std::vector<Diag> Diagnostics) override {}
48 };
49 
50 MATCHER_P2(FileRange, File, Range, "") {
51   return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg;
52 }
53 
54 // Extracts ranges from an annotated example, and constructs a matcher for a
55 // highlight set. Ranges should be named $read/$write as appropriate.
56 Matcher<const std::vector<DocumentHighlight> &>
HighlightsFrom(const Annotations & Test)57 HighlightsFrom(const Annotations &Test) {
58   std::vector<DocumentHighlight> Expected;
59   auto Add = [&](const Range &R, DocumentHighlightKind K) {
60     Expected.emplace_back();
61     Expected.back().range = R;
62     Expected.back().kind = K;
63   };
64   for (const auto &Range : Test.ranges())
65     Add(Range, DocumentHighlightKind::Text);
66   for (const auto &Range : Test.ranges("read"))
67     Add(Range, DocumentHighlightKind::Read);
68   for (const auto &Range : Test.ranges("write"))
69     Add(Range, DocumentHighlightKind::Write);
70   return UnorderedElementsAreArray(Expected);
71 }
72 
TEST(HighlightsTest,All)73 TEST(HighlightsTest, All) {
74   const char *Tests[] = {
75       R"cpp(// Local variable
76         int main() {
77           int [[bonjour]];
78           $write[[^bonjour]] = 2;
79           int test1 = $read[[bonjour]];
80         }
81       )cpp",
82 
83       R"cpp(// Struct
84         namespace ns1 {
85         struct [[MyClass]] {
86           static void foo([[MyClass]]*) {}
87         };
88         } // namespace ns1
89         int main() {
90           ns1::[[My^Class]]* Params;
91         }
92       )cpp",
93 
94       R"cpp(// Function
95         int [[^foo]](int) {}
96         int main() {
97           [[foo]]([[foo]](42));
98           auto *X = &[[foo]];
99         }
100       )cpp",
101 
102       R"cpp(// Function parameter in decl
103         void foo(int [[^bar]]);
104       )cpp",
105   };
106   for (const char *Test : Tests) {
107     Annotations T(Test);
108     auto AST = TestTU::withCode(T.code()).build();
109     EXPECT_THAT(findDocumentHighlights(AST, T.point()), HighlightsFrom(T))
110         << Test;
111   }
112 }
113 
114 MATCHER_P3(Sym, Name, Decl, DefOrNone, "") {
115   llvm::Optional<Range> Def = DefOrNone;
116   if (Name != arg.Name) {
117     *result_listener << "Name is " << arg.Name;
118     return false;
119   }
120   if (Decl != arg.PreferredDeclaration.range) {
121     *result_listener << "Declaration is "
122                      << llvm::to_string(arg.PreferredDeclaration);
123     return false;
124   }
125   if (Def && !arg.Definition) {
126     *result_listener << "Has no definition";
127     return false;
128   }
129   if (Def && arg.Definition->range != *Def) {
130     *result_listener << "Definition is " << llvm::to_string(arg.Definition);
131     return false;
132   }
133   return true;
134 }
Sym(std::string Name,Range Decl)135 ::testing::Matcher<LocatedSymbol> Sym(std::string Name, Range Decl) {
136   return Sym(Name, Decl, llvm::None);
137 }
138 MATCHER_P(Sym, Name, "") { return arg.Name == Name; }
139 
140 MATCHER_P(RangeIs, R, "") { return arg.range == R; }
141 
TEST(LocateSymbol,WithIndex)142 TEST(LocateSymbol, WithIndex) {
143   Annotations SymbolHeader(R"cpp(
144         class $forward[[Forward]];
145         class $foo[[Foo]] {};
146 
147         void $f1[[f1]]();
148 
149         inline void $f2[[f2]]() {}
150       )cpp");
151   Annotations SymbolCpp(R"cpp(
152       class $forward[[forward]] {};
153       void  $f1[[f1]]() {}
154     )cpp");
155 
156   TestTU TU;
157   TU.Code = SymbolCpp.code();
158   TU.HeaderCode = SymbolHeader.code();
159   auto Index = TU.index();
160   auto LocateWithIndex = [&Index](const Annotations &Main) {
161     auto AST = TestTU::withCode(Main.code()).build();
162     return clangd::locateSymbolAt(AST, Main.point(), Index.get());
163   };
164 
165   Annotations Test(R"cpp(// only declaration in AST.
166         void [[f1]]();
167         int main() {
168           ^f1();
169         }
170       )cpp");
171   EXPECT_THAT(LocateWithIndex(Test),
172               ElementsAre(Sym("f1", Test.range(), SymbolCpp.range("f1"))));
173 
174   Test = Annotations(R"cpp(// definition in AST.
175         void [[f1]]() {}
176         int main() {
177           ^f1();
178         }
179       )cpp");
180   EXPECT_THAT(LocateWithIndex(Test),
181               ElementsAre(Sym("f1", SymbolHeader.range("f1"), Test.range())));
182 
183   Test = Annotations(R"cpp(// forward declaration in AST.
184         class [[Foo]];
185         F^oo* create();
186       )cpp");
187   EXPECT_THAT(LocateWithIndex(Test),
188               ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range("foo"))));
189 
190   Test = Annotations(R"cpp(// definition in AST.
191         class [[Forward]] {};
192         F^orward create();
193       )cpp");
194   EXPECT_THAT(
195       LocateWithIndex(Test),
196       ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range())));
197 }
198 
TEST(LocateSymbol,WithIndexPreferredLocation)199 TEST(LocateSymbol, WithIndexPreferredLocation) {
200   Annotations SymbolHeader(R"cpp(
201         class $p[[Proto]] {};
202         void $f[[func]]() {};
203       )cpp");
204   TestTU TU;
205   TU.HeaderCode = SymbolHeader.code();
206   TU.HeaderFilename = "x.proto"; // Prefer locations in codegen files.
207   auto Index = TU.index();
208 
209   Annotations Test(R"cpp(// only declaration in AST.
210         // Shift to make range different.
211         class Proto;
212         void func() {}
213         P$p^roto* create() {
214           fu$f^nc();
215           return nullptr;
216         }
217       )cpp");
218 
219   auto AST = TestTU::withCode(Test.code()).build();
220   {
221     auto Locs = clangd::locateSymbolAt(AST, Test.point("p"), Index.get());
222     auto CodeGenLoc = SymbolHeader.range("p");
223     EXPECT_THAT(Locs, ElementsAre(Sym("Proto", CodeGenLoc, CodeGenLoc)));
224   }
225   {
226     auto Locs = clangd::locateSymbolAt(AST, Test.point("f"), Index.get());
227     auto CodeGenLoc = SymbolHeader.range("f");
228     EXPECT_THAT(Locs, ElementsAre(Sym("func", CodeGenLoc, CodeGenLoc)));
229   }
230 }
231 
TEST(LocateSymbol,All)232 TEST(LocateSymbol, All) {
233   // Ranges in tests:
234   //   $decl is the declaration location (if absent, no symbol is located)
235   //   $def is the definition location (if absent, symbol has no definition)
236   //   unnamed range becomes both $decl and $def.
237   const char *Tests[] = {
238       R"cpp(// Local variable
239         int main() {
240           int [[bonjour]];
241           ^bonjour = 2;
242           int test1 = bonjour;
243         }
244       )cpp",
245 
246       R"cpp(// Struct
247         namespace ns1 {
248         struct [[MyClass]] {};
249         } // namespace ns1
250         int main() {
251           ns1::My^Class* Params;
252         }
253       )cpp",
254 
255       R"cpp(// Function definition via pointer
256         void [[foo]](int) {}
257         int main() {
258           auto *X = &^foo;
259         }
260       )cpp",
261 
262       R"cpp(// Function declaration via call
263         int $decl[[foo]](int);
264         int main() {
265           return ^foo(42);
266         }
267       )cpp",
268 
269       R"cpp(// Field
270         struct Foo { int [[x]]; };
271         int main() {
272           Foo bar;
273           (void)bar.^x;
274         }
275       )cpp",
276 
277       R"cpp(// Field, member initializer
278         struct Foo {
279           int [[x]];
280           Foo() : ^x(0) {}
281         };
282       )cpp",
283 
284       R"cpp(// Field, field designator
285         struct Foo { int [[x]]; };
286         int main() {
287           Foo bar = { .^x = 2 };
288         }
289       )cpp",
290 
291       R"cpp(// Method call
292         struct Foo { int $decl[[x]](); };
293         int main() {
294           Foo bar;
295           bar.^x();
296         }
297       )cpp",
298 
299       R"cpp(// Typedef
300         typedef int $decl[[Foo]];
301         int main() {
302           ^Foo bar;
303         }
304       )cpp",
305 
306       R"cpp(// Template type parameter
307         template <typename [[T]]>
308         void foo() { ^T t; }
309       )cpp",
310 
311       R"cpp(// Template template type parameter
312         template <template<typename> class [[T]]>
313         void foo() { ^T<int> t; }
314       )cpp",
315 
316       R"cpp(// Namespace
317         namespace $decl[[ns]] {
318         struct Foo { static void bar(); };
319         } // namespace ns
320         int main() { ^ns::Foo::bar(); }
321       )cpp",
322 
323       R"cpp(// Macro
324        class TTT { public: int a; };
325        #define [[FF]](S) if (int b = S.a) {}
326        void f() {
327          TTT t;
328          F^F(t);
329        }
330       )cpp",
331 
332       R"cpp(// Macro argument
333        int [[i]];
334        #define ADDRESSOF(X) &X;
335        int *j = ADDRESSOF(^i);
336       )cpp",
337 
338       R"cpp(// Symbol concatenated inside macro (not supported)
339        int *pi;
340        #define POINTER(X) p ## X;
341        int i = *POINTER(^i);
342       )cpp",
343 
344       R"cpp(// Forward class declaration
345         class Foo;
346         class [[Foo]] {};
347         F^oo* foo();
348       )cpp",
349 
350       R"cpp(// Function declaration
351         void foo();
352         void g() { f^oo(); }
353         void [[foo]]() {}
354       )cpp",
355 
356       R"cpp(
357         #define FF(name) class name##_Test {};
358         [[FF]](my);
359         void f() { my^_Test a; }
360       )cpp",
361 
362       R"cpp(
363          #define FF() class [[Test]] {};
364          FF();
365          void f() { T^est a; }
366       )cpp",
367 
368       R"cpp(// explicit template specialization
369         template <typename T>
370         struct Foo { void bar() {} };
371 
372         template <>
373         struct [[Foo]]<int> { void bar() {} };
374 
375         void foo() {
376           Foo<char> abc;
377           Fo^o<int> b;
378         }
379       )cpp",
380 
381       R"cpp(// implicit template specialization
382         template <typename T>
383         struct [[Foo]] { void bar() {} };
384         template <>
385         struct Foo<int> { void bar() {} };
386         void foo() {
387           Fo^o<char> abc;
388           Foo<int> b;
389         }
390       )cpp",
391 
392       R"cpp(// partial template specialization
393         template <typename T>
394         struct Foo { void bar() {} };
395         template <typename T>
396         struct [[Foo]]<T*> { void bar() {} };
397         ^Foo<int*> x;
398       )cpp",
399 
400       R"cpp(// function template specializations
401         template <class T>
402         void foo(T) {}
403         template <>
404         void [[foo]](int) {}
405         void bar() {
406           fo^o(10);
407         }
408       )cpp",
409 
410       R"cpp(// variable template decls
411         template <class T>
412         T var = T();
413 
414         template <>
415         double [[var]]<int> = 10;
416 
417         double y = va^r<int>;
418       )cpp",
419 
420       R"cpp(// No implicit constructors
421         struct X {
422           X(X&& x) = default;
423         };
424         X $decl[[makeX]]();
425         void foo() {
426           auto x = m^akeX();
427         }
428       )cpp",
429 
430       R"cpp(
431         struct X {
432           X& $decl[[operator]]++();
433         };
434         void foo(X& x) {
435           +^+x;
436         }
437       )cpp",
438 
439       R"cpp(// Declaration of explicit template specialization
440         template <typename T>
441         struct $decl[[Foo]] {};
442 
443         template <>
444         struct Fo^o<int> {};
445       )cpp",
446 
447       R"cpp(// Declaration of partial template specialization
448         template <typename T>
449         struct $decl[[Foo]] {};
450 
451         template <typename T>
452         struct Fo^o<T*> {};
453       )cpp",
454 
455       R"cpp(// Heuristic resolution of dependent method
456         template <typename T>
457         struct S {
458           void [[bar]]() {}
459         };
460 
461         template <typename T>
462         void foo(S<T> arg) {
463           arg.ba^r();
464         }
465       )cpp",
466 
467       R"cpp(// Heuristic resolution of dependent method via this->
468         template <typename T>
469         struct S {
470           void [[foo]]() {
471             this->fo^o();
472           }
473         };
474       )cpp",
475 
476       R"cpp(// Heuristic resolution of dependent static method
477         template <typename T>
478         struct S {
479           static void [[bar]]() {}
480         };
481 
482         template <typename T>
483         void foo() {
484           S<T>::ba^r();
485         }
486       )cpp",
487 
488       R"cpp(// Heuristic resolution of dependent method
489             // invoked via smart pointer
490         template <typename> struct S { void [[foo]]() {} };
491         template <typename T> struct unique_ptr {
492           T* operator->();
493         };
494         template <typename T>
495         void test(unique_ptr<S<T>>& V) {
496           V->fo^o();
497         }
498       )cpp"};
499   for (const char *Test : Tests) {
500     Annotations T(Test);
501     llvm::Optional<Range> WantDecl;
502     llvm::Optional<Range> WantDef;
503     if (!T.ranges().empty())
504       WantDecl = WantDef = T.range();
505     if (!T.ranges("decl").empty())
506       WantDecl = T.range("decl");
507     if (!T.ranges("def").empty())
508       WantDef = T.range("def");
509 
510     TestTU TU;
511     TU.Code = T.code();
512 
513     // FIXME: Auto-completion in a template requires disabling delayed template
514     // parsing.
515     TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
516 
517     auto AST = TU.build();
518     for (auto &D : AST.getDiagnostics())
519       ADD_FAILURE() << D;
520     ASSERT_TRUE(AST.getDiagnostics().empty()) << Test;
521 
522     auto Results = locateSymbolAt(AST, T.point());
523 
524     if (!WantDecl) {
525       EXPECT_THAT(Results, IsEmpty()) << Test;
526     } else {
527       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
528       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
529       llvm::Optional<Range> GotDef;
530       if (Results[0].Definition)
531         GotDef = Results[0].Definition->range;
532       EXPECT_EQ(WantDef, GotDef) << Test;
533     }
534   }
535 }
536 
537 // LocateSymbol test cases that produce warnings.
538 // These are separated out from All so that in All we can assert
539 // that there are no diagnostics.
TEST(LocateSymbol,Warnings)540 TEST(LocateSymbol, Warnings) {
541   const char *Tests[] = {
542       R"cpp(// Field, GNU old-style field designator
543         struct Foo { int [[x]]; };
544         int main() {
545           Foo bar = { ^x : 1 };
546         }
547       )cpp",
548 
549       R"cpp(// Macro
550         #define MACRO 0
551         #define [[MACRO]] 1
552         int main() { return ^MACRO; }
553         #define MACRO 2
554         #undef macro
555       )cpp",
556   };
557 
558   for (const char *Test : Tests) {
559     Annotations T(Test);
560     llvm::Optional<Range> WantDecl;
561     llvm::Optional<Range> WantDef;
562     if (!T.ranges().empty())
563       WantDecl = WantDef = T.range();
564     if (!T.ranges("decl").empty())
565       WantDecl = T.range("decl");
566     if (!T.ranges("def").empty())
567       WantDef = T.range("def");
568 
569     TestTU TU;
570     TU.Code = T.code();
571 
572     auto AST = TU.build();
573     auto Results = locateSymbolAt(AST, T.point());
574 
575     if (!WantDecl) {
576       EXPECT_THAT(Results, IsEmpty()) << Test;
577     } else {
578       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
579       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
580       llvm::Optional<Range> GotDef;
581       if (Results[0].Definition)
582         GotDef = Results[0].Definition->range;
583       EXPECT_EQ(WantDef, GotDef) << Test;
584     }
585   }
586 }
587 
TEST(LocateSymbol,Ambiguous)588 TEST(LocateSymbol, Ambiguous) {
589   auto T = Annotations(R"cpp(
590     struct Foo {
591       Foo();
592       Foo(Foo&&);
593       $ConstructorLoc[[Foo]](const char*);
594     };
595 
596     Foo f();
597 
598     void g(Foo foo);
599 
600     void call() {
601       const char* str = "123";
602       Foo a = $1^str;
603       Foo b = Foo($2^str);
604       Foo c = $3^f();
605       $4^g($5^f());
606       g($6^str);
607       Foo ab$7^c;
608       Foo ab$8^cd("asdf");
609       Foo foox = Fo$9^o("asdf");
610       Foo abcde$10^("asdf");
611       Foo foox2 = Foo$11^("asdf");
612     }
613 
614     template <typename T>
615     struct S {
616       void $NonstaticOverload1[[bar]](int);
617       void $NonstaticOverload2[[bar]](float);
618 
619       static void $StaticOverload1[[baz]](int);
620       static void $StaticOverload2[[baz]](float);
621     };
622 
623     template <typename T, typename U>
624     void dependent_call(S<T> s, U u) {
625       s.ba$12^r(u);
626       S<T>::ba$13^z(u);
627     }
628   )cpp");
629   auto TU = TestTU::withCode(T.code());
630   // FIXME: Go-to-definition in a template requires disabling delayed template
631   // parsing.
632   TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
633   auto AST = TU.build();
634   // Ordered assertions are deliberate: we expect a predictable order.
635   EXPECT_THAT(locateSymbolAt(AST, T.point("1")), ElementsAre(Sym("str")));
636   EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str")));
637   EXPECT_THAT(locateSymbolAt(AST, T.point("3")), ElementsAre(Sym("f")));
638   EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g")));
639   EXPECT_THAT(locateSymbolAt(AST, T.point("5")), ElementsAre(Sym("f")));
640   EXPECT_THAT(locateSymbolAt(AST, T.point("6")), ElementsAre(Sym("str")));
641   // FIXME: Target the constructor as well.
642   EXPECT_THAT(locateSymbolAt(AST, T.point("7")), ElementsAre(Sym("abc")));
643   // FIXME: Target the constructor as well.
644   EXPECT_THAT(locateSymbolAt(AST, T.point("8")), ElementsAre(Sym("abcd")));
645   // FIXME: Target the constructor as well.
646   EXPECT_THAT(locateSymbolAt(AST, T.point("9")), ElementsAre(Sym("Foo")));
647   EXPECT_THAT(locateSymbolAt(AST, T.point("10")),
648               ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
649   EXPECT_THAT(locateSymbolAt(AST, T.point("11")),
650               ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
651   // These assertions are unordered because the order comes from
652   // CXXRecordDecl::lookupDependentName() which doesn't appear to provide
653   // an order guarantee.
654   EXPECT_THAT(locateSymbolAt(AST, T.point("12")),
655               UnorderedElementsAre(Sym("bar", T.range("NonstaticOverload1")),
656                                    Sym("bar", T.range("NonstaticOverload2"))));
657   EXPECT_THAT(locateSymbolAt(AST, T.point("13")),
658               UnorderedElementsAre(Sym("baz", T.range("StaticOverload1")),
659                                    Sym("baz", T.range("StaticOverload2"))));
660 }
661 
TEST(LocateSymbol,TemplateTypedefs)662 TEST(LocateSymbol, TemplateTypedefs) {
663   auto T = Annotations(R"cpp(
664     template <class T> struct function {};
665     template <class T> using callback = function<T()>;
666 
667     c^allback<int> foo;
668   )cpp");
669   auto AST = TestTU::withCode(T.code()).build();
670   EXPECT_THAT(locateSymbolAt(AST, T.point()), ElementsAre(Sym("callback")));
671 }
672 
TEST(LocateSymbol,RelPathsInCompileCommand)673 TEST(LocateSymbol, RelPathsInCompileCommand) {
674   // The source is in "/clangd-test/src".
675   // We build in "/clangd-test/build".
676 
677   Annotations SourceAnnotations(R"cpp(
678 #include "header_in_preamble.h"
679 int [[foo]];
680 #include "header_not_in_preamble.h"
681 int baz = f$p1^oo + bar_pre$p2^amble + bar_not_pre$p3^amble;
682 )cpp");
683 
684   Annotations HeaderInPreambleAnnotations(R"cpp(
685 int [[bar_preamble]];
686 )cpp");
687 
688   Annotations HeaderNotInPreambleAnnotations(R"cpp(
689 int [[bar_not_preamble]];
690 )cpp");
691 
692   // Make the compilation paths appear as ../src/foo.cpp in the compile
693   // commands.
694   SmallString<32> RelPathPrefix("..");
695   llvm::sys::path::append(RelPathPrefix, "src");
696   std::string BuildDir = testPath("build");
697   MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
698 
699   IgnoreDiagnostics DiagConsumer;
700   MockFSProvider FS;
701   ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
702 
703   // Fill the filesystem.
704   auto FooCpp = testPath("src/foo.cpp");
705   FS.Files[FooCpp] = "";
706   auto HeaderInPreambleH = testPath("src/header_in_preamble.h");
707   FS.Files[HeaderInPreambleH] = HeaderInPreambleAnnotations.code();
708   auto HeaderNotInPreambleH = testPath("src/header_not_in_preamble.h");
709   FS.Files[HeaderNotInPreambleH] = HeaderNotInPreambleAnnotations.code();
710 
711   runAddDocument(Server, FooCpp, SourceAnnotations.code());
712 
713   // Go to a definition in main source file.
714   auto Locations =
715       runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p1"));
716   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
717   EXPECT_THAT(*Locations, ElementsAre(Sym("foo", SourceAnnotations.range())));
718 
719   // Go to a definition in header_in_preamble.h.
720   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p2"));
721   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
722   EXPECT_THAT(
723       *Locations,
724       ElementsAre(Sym("bar_preamble", HeaderInPreambleAnnotations.range())));
725 
726   // Go to a definition in header_not_in_preamble.h.
727   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p3"));
728   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
729   EXPECT_THAT(*Locations,
730               ElementsAre(Sym("bar_not_preamble",
731                               HeaderNotInPreambleAnnotations.range())));
732 }
733 
TEST(GoToInclude,All)734 TEST(GoToInclude, All) {
735   MockFSProvider FS;
736   IgnoreDiagnostics DiagConsumer;
737   MockCompilationDatabase CDB;
738   ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
739 
740   auto FooCpp = testPath("foo.cpp");
741   const char *SourceContents = R"cpp(
742   #include ^"$2^foo.h$3^"
743   #include "$4^invalid.h"
744   int b = a;
745   // test
746   int foo;
747   #in$5^clude "$6^foo.h"$7^
748   )cpp";
749   Annotations SourceAnnotations(SourceContents);
750   FS.Files[FooCpp] = SourceAnnotations.code();
751   auto FooH = testPath("foo.h");
752 
753   const char *HeaderContents = R"cpp([[]]#pragma once
754                                      int a;
755                                      )cpp";
756   Annotations HeaderAnnotations(HeaderContents);
757   FS.Files[FooH] = HeaderAnnotations.code();
758 
759   Server.addDocument(FooH, HeaderAnnotations.code());
760   Server.addDocument(FooCpp, SourceAnnotations.code());
761 
762   // Test include in preamble.
763   auto Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point());
764   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
765   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
766 
767   // Test include in preamble, last char.
768   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("2"));
769   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
770   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
771 
772   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("3"));
773   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
774   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
775 
776   // Test include outside of preamble.
777   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("6"));
778   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
779   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
780 
781   // Test a few positions that do not result in Locations.
782   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("4"));
783   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
784   EXPECT_THAT(*Locations, IsEmpty());
785 
786   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("5"));
787   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
788   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
789 
790   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("7"));
791   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
792   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
793 
794   // Objective C #import directive.
795   Annotations ObjC(R"objc(
796   #import "^foo.h"
797   )objc");
798   auto FooM = testPath("foo.m");
799   FS.Files[FooM] = ObjC.code();
800 
801   Server.addDocument(FooM, ObjC.code());
802   Locations = runLocateSymbolAt(Server, FooM, ObjC.point());
803   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
804   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
805 }
806 
TEST(LocateSymbol,WithPreamble)807 TEST(LocateSymbol, WithPreamble) {
808   // Test stragety: AST should always use the latest preamble instead of last
809   // good preamble.
810   MockFSProvider FS;
811   IgnoreDiagnostics DiagConsumer;
812   MockCompilationDatabase CDB;
813   ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
814 
815   auto FooCpp = testPath("foo.cpp");
816   // The trigger locations must be the same.
817   Annotations FooWithHeader(R"cpp(#include "fo^o.h")cpp");
818   Annotations FooWithoutHeader(R"cpp(double    [[fo^o]]();)cpp");
819 
820   FS.Files[FooCpp] = FooWithHeader.code();
821 
822   auto FooH = testPath("foo.h");
823   Annotations FooHeader(R"cpp([[]])cpp");
824   FS.Files[FooH] = FooHeader.code();
825 
826   runAddDocument(Server, FooCpp, FooWithHeader.code());
827   // LocateSymbol goes to a #include file: the result comes from the preamble.
828   EXPECT_THAT(
829       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithHeader.point())),
830       ElementsAre(Sym("foo.h", FooHeader.range())));
831 
832   // Only preamble is built, and no AST is built in this request.
833   Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::No);
834   // We build AST here, and it should use the latest preamble rather than the
835   // stale one.
836   EXPECT_THAT(
837       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
838       ElementsAre(Sym("foo", FooWithoutHeader.range())));
839 
840   // Reset test environment.
841   runAddDocument(Server, FooCpp, FooWithHeader.code());
842   // Both preamble and AST are built in this request.
843   Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::Yes);
844   // Use the AST being built in above request.
845   EXPECT_THAT(
846       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
847       ElementsAre(Sym("foo", FooWithoutHeader.range())));
848 }
849 
TEST(FindReferences,WithinAST)850 TEST(FindReferences, WithinAST) {
851   const char *Tests[] = {
852       R"cpp(// Local variable
853         int main() {
854           int [[foo]];
855           [[^foo]] = 2;
856           int test1 = [[foo]];
857         }
858       )cpp",
859 
860       R"cpp(// Struct
861         namespace ns1 {
862         struct [[Foo]] {};
863         } // namespace ns1
864         int main() {
865           ns1::[[Fo^o]]* Params;
866         }
867       )cpp",
868 
869       R"cpp(// Forward declaration
870         class [[Foo]];
871         class [[Foo]] {}
872         int main() {
873           [[Fo^o]] foo;
874         }
875       )cpp",
876 
877       R"cpp(// Function
878         int [[foo]](int) {}
879         int main() {
880           auto *X = &[[^foo]];
881           [[foo]](42)
882         }
883       )cpp",
884 
885       R"cpp(// Field
886         struct Foo {
887           int [[foo]];
888           Foo() : [[foo]](0) {}
889         };
890         int main() {
891           Foo f;
892           f.[[f^oo]] = 1;
893         }
894       )cpp",
895 
896       R"cpp(// Method call
897         struct Foo { int [[foo]](); };
898         int Foo::[[foo]]() {}
899         int main() {
900           Foo f;
901           f.[[^foo]]();
902         }
903       )cpp",
904 
905       R"cpp(// Constructor
906         struct Foo {
907           [[F^oo]](int);
908         };
909         void foo() {
910           Foo f = [[Foo]](42);
911         }
912       )cpp",
913 
914       R"cpp(// Typedef
915         typedef int [[Foo]];
916         int main() {
917           [[^Foo]] bar;
918         }
919       )cpp",
920 
921       R"cpp(// Namespace
922         namespace [[ns]] {
923         struct Foo {};
924         } // namespace ns
925         int main() { [[^ns]]::Foo foo; }
926       )cpp",
927 
928       R"cpp(// Macros
929         #define TYPE(X) X
930         #define FOO Foo
931         #define CAT(X, Y) X##Y
932         class [[Fo^o]] {};
933         void test() {
934           TYPE([[Foo]]) foo;
935           [[FOO]] foo2;
936           TYPE(TYPE([[Foo]])) foo3;
937           [[CAT]](Fo, o) foo4;
938         }
939       )cpp",
940 
941       R"cpp(// Macros
942         #define [[MA^CRO]](X) (X+1)
943         void test() {
944           int x = [[MACRO]]([[MACRO]](1));
945         }
946       )cpp",
947   };
948   for (const char *Test : Tests) {
949     Annotations T(Test);
950     auto AST = TestTU::withCode(T.code()).build();
951     std::vector<Matcher<Location>> ExpectedLocations;
952     for (const auto &R : T.ranges())
953       ExpectedLocations.push_back(RangeIs(R));
954     EXPECT_THAT(findReferences(AST, T.point(), 0).References,
955                 ElementsAreArray(ExpectedLocations))
956         << Test;
957   }
958 }
959 
TEST(FindReferences,ExplicitSymbols)960 TEST(FindReferences, ExplicitSymbols) {
961   const char *Tests[] = {
962       R"cpp(
963       struct Foo { Foo* [[self]]() const; };
964       void f() {
965         Foo foo;
966         if (Foo* T = foo.[[^self]]()) {} // Foo member call expr.
967       }
968       )cpp",
969 
970       R"cpp(
971       struct Foo { Foo(int); };
972       Foo f() {
973         int [[b]];
974         return [[^b]]; // Foo constructor expr.
975       }
976       )cpp",
977 
978       R"cpp(
979       struct Foo {};
980       void g(Foo);
981       Foo [[f]]();
982       void call() {
983         g([[^f]]());  // Foo constructor expr.
984       }
985       )cpp",
986 
987       R"cpp(
988       void [[foo]](int);
989       void [[foo]](double);
990 
991       namespace ns {
992       using ::[[fo^o]];
993       }
994       )cpp",
995 
996       R"cpp(
997       struct X {
998         operator bool();
999       };
1000 
1001       int test() {
1002         X [[a]];
1003         [[a]].operator bool();
1004         if ([[a^]]) {} // ignore implicit conversion-operator AST node
1005       }
1006     )cpp",
1007   };
1008   for (const char *Test : Tests) {
1009     Annotations T(Test);
1010     auto AST = TestTU::withCode(T.code()).build();
1011     std::vector<Matcher<Location>> ExpectedLocations;
1012     for (const auto &R : T.ranges())
1013       ExpectedLocations.push_back(RangeIs(R));
1014     ASSERT_THAT(ExpectedLocations, Not(IsEmpty()));
1015     EXPECT_THAT(findReferences(AST, T.point(), 0).References,
1016                 ElementsAreArray(ExpectedLocations))
1017         << Test;
1018   }
1019 }
1020 
TEST(FindReferences,NeedsIndexForSymbols)1021 TEST(FindReferences, NeedsIndexForSymbols) {
1022   const char *Header = "int foo();";
1023   Annotations Main("int main() { [[f^oo]](); }");
1024   TestTU TU;
1025   TU.Code = Main.code();
1026   TU.HeaderCode = Header;
1027   auto AST = TU.build();
1028 
1029   // References in main file are returned without index.
1030   EXPECT_THAT(
1031       findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
1032       ElementsAre(RangeIs(Main.range())));
1033   Annotations IndexedMain(R"cpp(
1034     int main() { [[f^oo]](); }
1035   )cpp");
1036 
1037   // References from indexed files are included.
1038   TestTU IndexedTU;
1039   IndexedTU.Code = IndexedMain.code();
1040   IndexedTU.Filename = "Indexed.cpp";
1041   IndexedTU.HeaderCode = Header;
1042   EXPECT_THAT(
1043       findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
1044       ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
1045   auto LimitRefs =
1046       findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
1047   EXPECT_EQ(1u, LimitRefs.References.size());
1048   EXPECT_TRUE(LimitRefs.HasMore);
1049 
1050   // Avoid indexed results for the main file. Use AST for the mainfile.
1051   TU.Code = ("\n\n" + Main.code()).str();
1052   EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()).References,
1053               ElementsAre(RangeIs(Main.range())));
1054 }
1055 
TEST(FindReferences,NeedsIndexForMacro)1056 TEST(FindReferences, NeedsIndexForMacro) {
1057   const char *Header = "#define MACRO(X) (X+1)";
1058   Annotations Main(R"cpp(
1059     int main() {
1060       int a = [[MA^CRO]](1);
1061     }
1062   )cpp");
1063   TestTU TU;
1064   TU.Code = Main.code();
1065   TU.HeaderCode = Header;
1066   auto AST = TU.build();
1067 
1068   // References in main file are returned without index.
1069   EXPECT_THAT(
1070       findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
1071       ElementsAre(RangeIs(Main.range())));
1072 
1073   Annotations IndexedMain(R"cpp(
1074     int indexed_main() {
1075       int a = [[MACRO]](1);
1076     }
1077   )cpp");
1078 
1079   // References from indexed files are included.
1080   TestTU IndexedTU;
1081   IndexedTU.Code = IndexedMain.code();
1082   IndexedTU.Filename = "Indexed.cpp";
1083   IndexedTU.HeaderCode = Header;
1084   EXPECT_THAT(
1085       findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
1086       ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
1087   auto LimitRefs =
1088       findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
1089   EXPECT_EQ(1u, LimitRefs.References.size());
1090   EXPECT_TRUE(LimitRefs.HasMore);
1091 }
1092 
TEST(FindReferences,NoQueryForLocalSymbols)1093 TEST(FindReferences, NoQueryForLocalSymbols) {
1094   struct RecordingIndex : public MemIndex {
1095     mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
1096     bool refs(const RefsRequest &Req,
1097               llvm::function_ref<void(const Ref &)>) const override {
1098       RefIDs = Req.IDs;
1099       return false;
1100     }
1101   };
1102 
1103   struct Test {
1104     StringRef AnnotatedCode;
1105     bool WantQuery;
1106   } Tests[] = {
1107       {"int ^x;", true},
1108       // For now we don't assume header structure which would allow skipping.
1109       {"namespace { int ^x; }", true},
1110       {"static int ^x;", true},
1111       // Anything in a function certainly can't be referenced though.
1112       {"void foo() { int ^x; }", false},
1113       {"void foo() { struct ^x{}; }", false},
1114       {"auto lambda = []{ int ^x; };", false},
1115   };
1116   for (Test T : Tests) {
1117     Annotations File(T.AnnotatedCode);
1118     RecordingIndex Rec;
1119     auto AST = TestTU::withCode(File.code()).build();
1120     findReferences(AST, File.point(), 0, &Rec);
1121     if (T.WantQuery)
1122       EXPECT_NE(Rec.RefIDs, None) << T.AnnotatedCode;
1123     else
1124       EXPECT_EQ(Rec.RefIDs, None) << T.AnnotatedCode;
1125   }
1126 }
1127 
TEST(GetNonLocalDeclRefs,All)1128 TEST(GetNonLocalDeclRefs, All) {
1129   struct Case {
1130     llvm::StringRef AnnotatedCode;
1131     std::vector<llvm::StringRef> ExpectedDecls;
1132   } Cases[] = {
1133       {
1134           // VarDecl and ParamVarDecl
1135           R"cpp(
1136             void bar();
1137             void ^foo(int baz) {
1138               int x = 10;
1139               bar();
1140             })cpp",
1141           {"bar"},
1142       },
1143       {
1144           // Method from class
1145           R"cpp(
1146             class Foo { public: void foo(); };
1147             class Bar {
1148               void foo();
1149               void bar();
1150             };
1151             void Bar::^foo() {
1152               Foo f;
1153               bar();
1154               f.foo();
1155             })cpp",
1156           {"Bar", "Bar::bar", "Foo", "Foo::foo"},
1157       },
1158       {
1159           // Local types
1160           R"cpp(
1161             void ^foo() {
1162               class Foo { public: void foo() {} };
1163               class Bar { public: void bar() {} };
1164               Foo f;
1165               Bar b;
1166               b.bar();
1167               f.foo();
1168             })cpp",
1169           {},
1170       },
1171       {
1172           // Template params
1173           R"cpp(
1174             template <typename T, template<typename> class Q>
1175             void ^foo() {
1176               T x;
1177               Q<T> y;
1178             })cpp",
1179           {},
1180       },
1181   };
1182   for (const Case &C : Cases) {
1183     Annotations File(C.AnnotatedCode);
1184     auto AST = TestTU::withCode(File.code()).build();
1185     ASSERT_TRUE(AST.getDiagnostics().empty())
1186         << AST.getDiagnostics().begin()->Message;
1187     SourceLocation SL = llvm::cantFail(
1188         sourceLocationInMainFile(AST.getSourceManager(), File.point()));
1189 
1190     const FunctionDecl *FD =
1191         llvm::dyn_cast<FunctionDecl>(&findDecl(AST, [SL](const NamedDecl &ND) {
1192           return ND.getLocation() == SL && llvm::isa<FunctionDecl>(ND);
1193         }));
1194     ASSERT_NE(FD, nullptr);
1195 
1196     auto NonLocalDeclRefs = getNonLocalDeclRefs(AST, FD);
1197     std::vector<std::string> Names;
1198     for (const Decl *D : NonLocalDeclRefs) {
1199       if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
1200         Names.push_back(ND->getQualifiedNameAsString());
1201     }
1202     EXPECT_THAT(Names, UnorderedElementsAreArray(C.ExpectedDecls))
1203         << File.code();
1204   }
1205 }
1206 
TEST(DocumentLinks,All)1207 TEST(DocumentLinks, All) {
1208   Annotations MainCpp(R"cpp(
1209       #include $foo[["foo.h"]]
1210       int end_of_preamble = 0;
1211       #include $bar[["bar.h"]]
1212     )cpp");
1213 
1214   TestTU TU;
1215   TU.Code = MainCpp.code();
1216   TU.AdditionalFiles = {{"foo.h", ""}, {"bar.h", ""}};
1217   auto AST = TU.build();
1218 
1219   EXPECT_THAT(
1220       clangd::getDocumentLinks(AST),
1221       ElementsAre(
1222           DocumentLink({MainCpp.range("foo"),
1223                         URIForFile::canonicalize(testPath("foo.h"), "")}),
1224           DocumentLink({MainCpp.range("bar"),
1225                         URIForFile::canonicalize(testPath("bar.h"), "")})));
1226 }
1227 
1228 } // namespace
1229 } // namespace clangd
1230 } // namespace clang
1231