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::Eq;
42 using ::testing::IsEmpty;
43 using ::testing::Matcher;
44 using ::testing::UnorderedElementsAreArray;
45 
46 MATCHER_P2(FileRange, File, Range, "") {
47   return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg;
48 }
49 
50 // Extracts ranges from an annotated example, and constructs a matcher for a
51 // highlight set. Ranges should be named $read/$write as appropriate.
52 Matcher<const std::vector<DocumentHighlight> &>
HighlightsFrom(const Annotations & Test)53 HighlightsFrom(const Annotations &Test) {
54   std::vector<DocumentHighlight> Expected;
55   auto Add = [&](const Range &R, DocumentHighlightKind K) {
56     Expected.emplace_back();
57     Expected.back().range = R;
58     Expected.back().kind = K;
59   };
60   for (const auto &Range : Test.ranges())
61     Add(Range, DocumentHighlightKind::Text);
62   for (const auto &Range : Test.ranges("read"))
63     Add(Range, DocumentHighlightKind::Read);
64   for (const auto &Range : Test.ranges("write"))
65     Add(Range, DocumentHighlightKind::Write);
66   return UnorderedElementsAreArray(Expected);
67 }
68 
TEST(HighlightsTest,All)69 TEST(HighlightsTest, All) {
70   const char *Tests[] = {
71       R"cpp(// Local variable
72         int main() {
73           int [[bonjour]];
74           $write[[^bonjour]] = 2;
75           int test1 = $read[[bonjour]];
76         }
77       )cpp",
78 
79       R"cpp(// Struct
80         namespace ns1 {
81         struct [[MyClass]] {
82           static void foo([[MyClass]]*) {}
83         };
84         } // namespace ns1
85         int main() {
86           ns1::[[My^Class]]* Params;
87         }
88       )cpp",
89 
90       R"cpp(// Function
91         int [[^foo]](int) {}
92         int main() {
93           [[foo]]([[foo]](42));
94           auto *X = &[[foo]];
95         }
96       )cpp",
97 
98       R"cpp(// Function parameter in decl
99         void foo(int [[^bar]]);
100       )cpp",
101       R"cpp(// Not touching any identifiers.
102         struct Foo {
103           [[~]]Foo() {};
104         };
105         void foo() {
106           Foo f;
107           f.[[^~]]Foo();
108         }
109       )cpp",
110   };
111   for (const char *Test : Tests) {
112     Annotations T(Test);
113     auto AST = TestTU::withCode(T.code()).build();
114     EXPECT_THAT(findDocumentHighlights(AST, T.point()), HighlightsFrom(T))
115         << Test;
116   }
117 }
118 
TEST(HighlightsTest,ControlFlow)119 TEST(HighlightsTest, ControlFlow) {
120   const char *Tests[] = {
121       R"cpp(
122         // Highlight same-function returns.
123         int fib(unsigned n) {
124           if (n <= 1) [[ret^urn]] 1;
125           [[return]] fib(n - 1) + fib(n - 2);
126 
127           // Returns from other functions not highlighted.
128           auto Lambda = [] { return; };
129           class LocalClass { void x() { return; } };
130         }
131       )cpp",
132 
133       R"cpp(
134         #define FAIL() return false
135         #define DO(x) { x; }
136         bool foo(int n) {
137           if (n < 0) [[FAIL]]();
138           DO([[re^turn]] true)
139         }
140       )cpp",
141 
142       R"cpp(
143         // Highlight loop control flow
144         int magic() {
145           int counter = 0;
146           [[^for]] (char c : "fruit loops!") {
147             if (c == ' ') [[continue]];
148             counter += c;
149             if (c == '!') [[break]];
150             if (c == '?') [[return]] -1;
151           }
152           return counter;
153         }
154       )cpp",
155 
156       R"cpp(
157         // Highlight loop and same-loop control flow
158         void nonsense() {
159           [[while]] (true) {
160             if (false) [[bre^ak]];
161             switch (1) break;
162             [[continue]];
163           }
164         }
165       )cpp",
166 
167       R"cpp(
168         // Highlight switch for break (but not other breaks).
169         void describe(unsigned n) {
170           [[switch]](n) {
171           case 0:
172             break;
173           [[default]]:
174             [[^break]];
175           }
176         }
177       )cpp",
178 
179       R"cpp(
180         // Highlight case and exits for switch-break (but not other cases).
181         void describe(unsigned n) {
182           [[switch]](n) {
183           case 0:
184             break;
185           [[case]] 1:
186           [[default]]:
187             [[return]];
188             [[^break]];
189           }
190         }
191       )cpp",
192 
193       R"cpp(
194         // Highlight exits and switch for case
195         void describe(unsigned n) {
196           [[switch]](n) {
197           case 0:
198             break;
199           [[case]] 1:
200           [[d^efault]]:
201             [[return]];
202             [[break]];
203           }
204         }
205       )cpp",
206 
207       R"cpp(
208         // Highlight nothing for switch.
209         void describe(unsigned n) {
210           s^witch(n) {
211           case 0:
212             break;
213           case 1:
214           default:
215             return;
216             break;
217           }
218         }
219       )cpp",
220 
221       R"cpp(
222         // FIXME: match exception type against catch blocks
223         int catchy() {
224           try {                     // wrong: highlight try with matching catch
225             try {                   // correct: has no matching catch
226               [[thr^ow]] "oh no!";
227             } catch (int) { }       // correct: catch doesn't match type
228             [[return]] -1;          // correct: exits the matching catch
229           } catch (const char*) { } // wrong: highlight matching catch
230           [[return]] 42;            // wrong: throw doesn't exit function
231         }
232       )cpp",
233 
234       R"cpp(
235         // Loop highlights goto exiting the loop, but not jumping within it.
236         void jumpy() {
237           [[wh^ile]](1) {
238             up:
239             if (0) [[goto]] out;
240             goto up;
241           }
242           out: return;
243         }
244       )cpp",
245   };
246   for (const char *Test : Tests) {
247     Annotations T(Test);
248     auto TU = TestTU::withCode(T.code());
249     TU.ExtraArgs.push_back("-fexceptions"); // FIXME: stop testing on PS4.
250     auto AST = TU.build();
251     EXPECT_THAT(findDocumentHighlights(AST, T.point()), HighlightsFrom(T))
252         << Test;
253   }
254 }
255 
256 MATCHER_P3(Sym, Name, Decl, DefOrNone, "") {
257   llvm::Optional<Range> Def = DefOrNone;
258   if (Name != arg.Name) {
259     *result_listener << "Name is " << arg.Name;
260     return false;
261   }
262   if (Decl != arg.PreferredDeclaration.range) {
263     *result_listener << "Declaration is "
264                      << llvm::to_string(arg.PreferredDeclaration);
265     return false;
266   }
267   if (Def && !arg.Definition) {
268     *result_listener << "Has no definition";
269     return false;
270   }
271   if (Def && arg.Definition->range != *Def) {
272     *result_listener << "Definition is " << llvm::to_string(arg.Definition);
273     return false;
274   }
275   return true;
276 }
Sym(std::string Name,Range Decl)277 ::testing::Matcher<LocatedSymbol> Sym(std::string Name, Range Decl) {
278   return Sym(Name, Decl, llvm::None);
279 }
280 MATCHER_P(Sym, Name, "") { return arg.Name == Name; }
281 
282 MATCHER_P(RangeIs, R, "") { return arg.range == R; }
283 
TEST(LocateSymbol,WithIndex)284 TEST(LocateSymbol, WithIndex) {
285   Annotations SymbolHeader(R"cpp(
286         class $forward[[Forward]];
287         class $foo[[Foo]] {};
288 
289         void $f1[[f1]]();
290 
291         inline void $f2[[f2]]() {}
292       )cpp");
293   Annotations SymbolCpp(R"cpp(
294       class $forward[[forward]] {};
295       void  $f1[[f1]]() {}
296     )cpp");
297 
298   TestTU TU;
299   TU.Code = std::string(SymbolCpp.code());
300   TU.HeaderCode = std::string(SymbolHeader.code());
301   auto Index = TU.index();
302   auto LocateWithIndex = [&Index](const Annotations &Main) {
303     auto AST = TestTU::withCode(Main.code()).build();
304     return clangd::locateSymbolAt(AST, Main.point(), Index.get());
305   };
306 
307   Annotations Test(R"cpp(// only declaration in AST.
308         void [[f1]]();
309         int main() {
310           ^f1();
311         }
312       )cpp");
313   EXPECT_THAT(LocateWithIndex(Test),
314               ElementsAre(Sym("f1", Test.range(), SymbolCpp.range("f1"))));
315 
316   Test = Annotations(R"cpp(// definition in AST.
317         void [[f1]]() {}
318         int main() {
319           ^f1();
320         }
321       )cpp");
322   EXPECT_THAT(LocateWithIndex(Test),
323               ElementsAre(Sym("f1", SymbolHeader.range("f1"), Test.range())));
324 
325   Test = Annotations(R"cpp(// forward declaration in AST.
326         class [[Foo]];
327         F^oo* create();
328       )cpp");
329   EXPECT_THAT(LocateWithIndex(Test),
330               ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range("foo"))));
331 
332   Test = Annotations(R"cpp(// definition in AST.
333         class [[Forward]] {};
334         F^orward create();
335       )cpp");
336   EXPECT_THAT(
337       LocateWithIndex(Test),
338       ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range())));
339 }
340 
TEST(LocateSymbol,WithIndexPreferredLocation)341 TEST(LocateSymbol, WithIndexPreferredLocation) {
342   Annotations SymbolHeader(R"cpp(
343         class $p[[Proto]] {};
344         void $f[[func]]() {};
345       )cpp");
346   TestTU TU;
347   TU.HeaderCode = std::string(SymbolHeader.code());
348   TU.HeaderFilename = "x.proto"; // Prefer locations in codegen files.
349   auto Index = TU.index();
350 
351   Annotations Test(R"cpp(// only declaration in AST.
352         // Shift to make range different.
353         class Proto;
354         void func() {}
355         P$p^roto* create() {
356           fu$f^nc();
357           return nullptr;
358         }
359       )cpp");
360 
361   auto AST = TestTU::withCode(Test.code()).build();
362   {
363     auto Locs = clangd::locateSymbolAt(AST, Test.point("p"), Index.get());
364     auto CodeGenLoc = SymbolHeader.range("p");
365     EXPECT_THAT(Locs, ElementsAre(Sym("Proto", CodeGenLoc, CodeGenLoc)));
366   }
367   {
368     auto Locs = clangd::locateSymbolAt(AST, Test.point("f"), Index.get());
369     auto CodeGenLoc = SymbolHeader.range("f");
370     EXPECT_THAT(Locs, ElementsAre(Sym("func", CodeGenLoc, CodeGenLoc)));
371   }
372 }
373 
TEST(LocateSymbol,All)374 TEST(LocateSymbol, All) {
375   // Ranges in tests:
376   //   $decl is the declaration location (if absent, no symbol is located)
377   //   $def is the definition location (if absent, symbol has no definition)
378   //   unnamed range becomes both $decl and $def.
379   const char *Tests[] = {
380       R"cpp(// Local variable
381         int main() {
382           int [[bonjour]];
383           ^bonjour = 2;
384           int test1 = bonjour;
385         }
386       )cpp",
387 
388       R"cpp(// Struct
389         namespace ns1 {
390         struct [[MyClass]] {};
391         } // namespace ns1
392         int main() {
393           ns1::My^Class* Params;
394         }
395       )cpp",
396 
397       R"cpp(// Function definition via pointer
398         void [[foo]](int) {}
399         int main() {
400           auto *X = &^foo;
401         }
402       )cpp",
403 
404       R"cpp(// Function declaration via call
405         int $decl[[foo]](int);
406         int main() {
407           return ^foo(42);
408         }
409       )cpp",
410 
411       R"cpp(// Field
412         struct Foo { int [[x]]; };
413         int main() {
414           Foo bar;
415           (void)bar.^x;
416         }
417       )cpp",
418 
419       R"cpp(// Field, member initializer
420         struct Foo {
421           int [[x]];
422           Foo() : ^x(0) {}
423         };
424       )cpp",
425 
426       R"cpp(// Field, field designator
427         struct Foo { int [[x]]; };
428         int main() {
429           Foo bar = { .^x = 2 };
430         }
431       )cpp",
432 
433       R"cpp(// Method call
434         struct Foo { int $decl[[x]](); };
435         int main() {
436           Foo bar;
437           bar.^x();
438         }
439       )cpp",
440 
441       R"cpp(// Typedef
442         typedef int $decl[[Foo]];
443         int main() {
444           ^Foo bar;
445         }
446       )cpp",
447 
448       R"cpp(// Template type parameter
449         template <typename [[T]]>
450         void foo() { ^T t; }
451       )cpp",
452 
453       R"cpp(// Template template type parameter
454         template <template<typename> class [[T]]>
455         void foo() { ^T<int> t; }
456       )cpp",
457 
458       R"cpp(// Namespace
459         namespace $decl[[ns]] {
460         struct Foo { static void bar(); };
461         } // namespace ns
462         int main() { ^ns::Foo::bar(); }
463       )cpp",
464 
465       R"cpp(// Macro
466        class TTT { public: int a; };
467        #define [[FF]](S) if (int b = S.a) {}
468        void f() {
469          TTT t;
470          F^F(t);
471        }
472       )cpp",
473 
474       R"cpp(// Macro argument
475        int [[i]];
476        #define ADDRESSOF(X) &X;
477        int *j = ADDRESSOF(^i);
478       )cpp",
479       R"cpp(// Macro argument appearing multiple times in expansion
480         #define VALIDATE_TYPE(x) (void)x;
481         #define ASSERT(expr)       \
482           do {                     \
483             VALIDATE_TYPE(expr);   \
484             if (!expr);            \
485           } while (false)
486         bool [[waldo]]() { return true; }
487         void foo() {
488           ASSERT(wa^ldo());
489         }
490       )cpp",
491       R"cpp(// Symbol concatenated inside macro (not supported)
492        int *pi;
493        #define POINTER(X) p ## X;
494        int x = *POINTER(^i);
495       )cpp",
496 
497       R"cpp(// Forward class declaration
498         class $decl[[Foo]];
499         class $def[[Foo]] {};
500         F^oo* foo();
501       )cpp",
502 
503       R"cpp(// Function declaration
504         void $decl[[foo]]();
505         void g() { f^oo(); }
506         void $def[[foo]]() {}
507       )cpp",
508 
509       R"cpp(
510         #define FF(name) class name##_Test {};
511         [[FF]](my);
512         void f() { my^_Test a; }
513       )cpp",
514 
515       R"cpp(
516          #define FF() class [[Test]] {};
517          FF();
518          void f() { T^est a; }
519       )cpp",
520 
521       R"cpp(// explicit template specialization
522         template <typename T>
523         struct Foo { void bar() {} };
524 
525         template <>
526         struct [[Foo]]<int> { void bar() {} };
527 
528         void foo() {
529           Foo<char> abc;
530           Fo^o<int> b;
531         }
532       )cpp",
533 
534       R"cpp(// implicit template specialization
535         template <typename T>
536         struct [[Foo]] { void bar() {} };
537         template <>
538         struct Foo<int> { void bar() {} };
539         void foo() {
540           Fo^o<char> abc;
541           Foo<int> b;
542         }
543       )cpp",
544 
545       R"cpp(// partial template specialization
546         template <typename T>
547         struct Foo { void bar() {} };
548         template <typename T>
549         struct [[Foo]]<T*> { void bar() {} };
550         ^Foo<int*> x;
551       )cpp",
552 
553       R"cpp(// function template specializations
554         template <class T>
555         void foo(T) {}
556         template <>
557         void [[foo]](int) {}
558         void bar() {
559           fo^o(10);
560         }
561       )cpp",
562 
563       R"cpp(// variable template decls
564         template <class T>
565         T var = T();
566 
567         template <>
568         double [[var]]<int> = 10;
569 
570         double y = va^r<int>;
571       )cpp",
572 
573       R"cpp(// No implicit constructors
574         struct X {
575           X(X&& x) = default;
576         };
577         X $decl[[makeX]]();
578         void foo() {
579           auto x = m^akeX();
580         }
581       )cpp",
582 
583       R"cpp(
584         struct X {
585           X& $decl[[operator]]++();
586         };
587         void foo(X& x) {
588           +^+x;
589         }
590       )cpp",
591 
592       R"cpp(
593         struct S1 { void f(); };
594         struct S2 { S1 * $decl[[operator]]->(); };
595         void test(S2 s2) {
596           s2-^>f();
597         }
598       )cpp",
599 
600       R"cpp(// Declaration of explicit template specialization
601         template <typename T>
602         struct $decl[[Foo]] {};
603 
604         template <>
605         struct Fo^o<int> {};
606       )cpp",
607 
608       R"cpp(// Declaration of partial template specialization
609         template <typename T>
610         struct $decl[[Foo]] {};
611 
612         template <typename T>
613         struct Fo^o<T*> {};
614       )cpp",
615 
616       R"cpp(// Override specifier jumps to overridden method
617         class Y { virtual void $decl[[a]]() = 0; };
618         class X : Y { void a() ^override {} };
619       )cpp",
620 
621       R"cpp(// Final specifier jumps to overridden method
622         class Y { virtual void $decl[[a]]() = 0; };
623         class X : Y { void a() ^final {} };
624       )cpp",
625 
626       R"cpp(// Heuristic resolution of dependent method
627         template <typename T>
628         struct S {
629           void [[bar]]() {}
630         };
631 
632         template <typename T>
633         void foo(S<T> arg) {
634           arg.ba^r();
635         }
636       )cpp",
637 
638       R"cpp(// Heuristic resolution of dependent method via this->
639         template <typename T>
640         struct S {
641           void [[foo]]() {
642             this->fo^o();
643           }
644         };
645       )cpp",
646 
647       R"cpp(// Heuristic resolution of dependent static method
648         template <typename T>
649         struct S {
650           static void [[bar]]() {}
651         };
652 
653         template <typename T>
654         void foo() {
655           S<T>::ba^r();
656         }
657       )cpp",
658 
659       R"cpp(// Heuristic resolution of dependent method
660             // invoked via smart pointer
661         template <typename> struct S { void [[foo]]() {} };
662         template <typename T> struct unique_ptr {
663           T* operator->();
664         };
665         template <typename T>
666         void test(unique_ptr<S<T>>& V) {
667           V->fo^o();
668         }
669       )cpp",
670 
671       R"cpp(// Heuristic resolution of dependent enumerator
672         template <typename T>
673         struct Foo {
674           enum class E { [[A]], B };
675           E e = E::A^;
676         };
677       )cpp"};
678   for (const char *Test : Tests) {
679     Annotations T(Test);
680     llvm::Optional<Range> WantDecl;
681     llvm::Optional<Range> WantDef;
682     if (!T.ranges().empty())
683       WantDecl = WantDef = T.range();
684     if (!T.ranges("decl").empty())
685       WantDecl = T.range("decl");
686     if (!T.ranges("def").empty())
687       WantDef = T.range("def");
688 
689     TestTU TU;
690     TU.Code = std::string(T.code());
691 
692     // FIXME: Auto-completion in a template requires disabling delayed template
693     // parsing.
694     TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
695 
696     auto AST = TU.build();
697     auto Results = locateSymbolAt(AST, T.point());
698 
699     if (!WantDecl) {
700       EXPECT_THAT(Results, IsEmpty()) << Test;
701     } else {
702       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
703       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
704       llvm::Optional<Range> GotDef;
705       if (Results[0].Definition)
706         GotDef = Results[0].Definition->range;
707       EXPECT_EQ(WantDef, GotDef) << Test;
708     }
709   }
710 }
711 
712 // LocateSymbol test cases that produce warnings.
713 // These are separated out from All so that in All we can assert
714 // that there are no diagnostics.
TEST(LocateSymbol,Warnings)715 TEST(LocateSymbol, Warnings) {
716   const char *Tests[] = {
717       R"cpp(// Field, GNU old-style field designator
718         struct Foo { int [[x]]; };
719         int main() {
720           Foo bar = { ^x : 1 };
721         }
722       )cpp",
723 
724       R"cpp(// Macro
725         #define MACRO 0
726         #define [[MACRO]] 1
727         int main() { return ^MACRO; }
728         #define MACRO 2
729         #undef macro
730       )cpp",
731   };
732 
733   for (const char *Test : Tests) {
734     Annotations T(Test);
735     llvm::Optional<Range> WantDecl;
736     llvm::Optional<Range> WantDef;
737     if (!T.ranges().empty())
738       WantDecl = WantDef = T.range();
739     if (!T.ranges("decl").empty())
740       WantDecl = T.range("decl");
741     if (!T.ranges("def").empty())
742       WantDef = T.range("def");
743 
744     TestTU TU;
745     TU.Code = std::string(T.code());
746 
747     auto AST = TU.build();
748     auto Results = locateSymbolAt(AST, T.point());
749 
750     if (!WantDecl) {
751       EXPECT_THAT(Results, IsEmpty()) << Test;
752     } else {
753       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
754       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
755       llvm::Optional<Range> GotDef;
756       if (Results[0].Definition)
757         GotDef = Results[0].Definition->range;
758       EXPECT_EQ(WantDef, GotDef) << Test;
759     }
760   }
761 }
762 
TEST(LocateSymbol,TextualSmoke)763 TEST(LocateSymbol, TextualSmoke) {
764   auto T = Annotations(
765       R"cpp(
766         struct [[MyClass]] {};
767         // Comment mentioning M^yClass
768       )cpp");
769 
770   auto TU = TestTU::withCode(T.code());
771   auto AST = TU.build();
772   auto Index = TU.index();
773   EXPECT_THAT(locateSymbolAt(AST, T.point(), Index.get()),
774               ElementsAre(Sym("MyClass", T.range())));
775 }
776 
TEST(LocateSymbol,Textual)777 TEST(LocateSymbol, Textual) {
778   const char *Tests[] = {
779       R"cpp(// Comment
780         struct [[MyClass]] {};
781         // Comment mentioning M^yClass
782       )cpp",
783       R"cpp(// String
784         struct MyClass {};
785         // Not triggered for string literal tokens.
786         const char* s = "String literal mentioning M^yClass";
787       )cpp",
788       R"cpp(// Ifdef'ed out code
789         struct [[MyClass]] {};
790         #ifdef WALDO
791           M^yClass var;
792         #endif
793       )cpp",
794       R"cpp(// Macro definition
795         struct [[MyClass]] {};
796         #define DECLARE_MYCLASS_OBJ(name) M^yClass name;
797       )cpp",
798       R"cpp(// Invalid code
799         /*error-ok*/
800         int myFunction(int);
801         // Not triggered for token which survived preprocessing.
802         int var = m^yFunction();
803       )cpp"};
804 
805   for (const char *Test : Tests) {
806     Annotations T(Test);
807     llvm::Optional<Range> WantDecl;
808     if (!T.ranges().empty())
809       WantDecl = T.range();
810 
811     auto TU = TestTU::withCode(T.code());
812 
813     auto AST = TU.build();
814     auto Index = TU.index();
815     auto Word = SpelledWord::touching(
816         cantFail(sourceLocationInMainFile(AST.getSourceManager(), T.point())),
817         AST.getTokens(), AST.getLangOpts());
818     if (!Word) {
819       ADD_FAILURE() << "No word touching point!" << Test;
820       continue;
821     }
822     auto Results = locateSymbolTextually(*Word, AST, Index.get(),
823                                          testPath(TU.Filename), ASTNodeKind());
824 
825     if (!WantDecl) {
826       EXPECT_THAT(Results, IsEmpty()) << Test;
827     } else {
828       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
829       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
830     }
831   }
832 } // namespace
833 
TEST(LocateSymbol,Ambiguous)834 TEST(LocateSymbol, Ambiguous) {
835   auto T = Annotations(R"cpp(
836     struct Foo {
837       Foo();
838       Foo(Foo&&);
839       $ConstructorLoc[[Foo]](const char*);
840     };
841 
842     Foo f();
843 
844     void g(Foo foo);
845 
846     void call() {
847       const char* str = "123";
848       Foo a = $1^str;
849       Foo b = Foo($2^str);
850       Foo c = $3^f();
851       $4^g($5^f());
852       g($6^str);
853       Foo ab$7^c;
854       Foo ab$8^cd("asdf");
855       Foo foox = Fo$9^o("asdf");
856       Foo abcde$10^("asdf");
857       Foo foox2 = Foo$11^("asdf");
858     }
859 
860     template <typename T>
861     struct S {
862       void $NonstaticOverload1[[bar]](int);
863       void $NonstaticOverload2[[bar]](float);
864 
865       static void $StaticOverload1[[baz]](int);
866       static void $StaticOverload2[[baz]](float);
867     };
868 
869     template <typename T, typename U>
870     void dependent_call(S<T> s, U u) {
871       s.ba$12^r(u);
872       S<T>::ba$13^z(u);
873     }
874   )cpp");
875   auto TU = TestTU::withCode(T.code());
876   // FIXME: Go-to-definition in a template requires disabling delayed template
877   // parsing.
878   TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
879   auto AST = TU.build();
880   // Ordered assertions are deliberate: we expect a predictable order.
881   EXPECT_THAT(locateSymbolAt(AST, T.point("1")), ElementsAre(Sym("str")));
882   EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str")));
883   EXPECT_THAT(locateSymbolAt(AST, T.point("3")), ElementsAre(Sym("f")));
884   EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g")));
885   EXPECT_THAT(locateSymbolAt(AST, T.point("5")), ElementsAre(Sym("f")));
886   EXPECT_THAT(locateSymbolAt(AST, T.point("6")), ElementsAre(Sym("str")));
887   // FIXME: Target the constructor as well.
888   EXPECT_THAT(locateSymbolAt(AST, T.point("7")), ElementsAre(Sym("abc")));
889   // FIXME: Target the constructor as well.
890   EXPECT_THAT(locateSymbolAt(AST, T.point("8")), ElementsAre(Sym("abcd")));
891   // FIXME: Target the constructor as well.
892   EXPECT_THAT(locateSymbolAt(AST, T.point("9")), ElementsAre(Sym("Foo")));
893   EXPECT_THAT(locateSymbolAt(AST, T.point("10")),
894               ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
895   EXPECT_THAT(locateSymbolAt(AST, T.point("11")),
896               ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
897   // These assertions are unordered because the order comes from
898   // CXXRecordDecl::lookupDependentName() which doesn't appear to provide
899   // an order guarantee.
900   EXPECT_THAT(locateSymbolAt(AST, T.point("12")),
901               UnorderedElementsAre(Sym("bar", T.range("NonstaticOverload1")),
902                                    Sym("bar", T.range("NonstaticOverload2"))));
903   EXPECT_THAT(locateSymbolAt(AST, T.point("13")),
904               UnorderedElementsAre(Sym("baz", T.range("StaticOverload1")),
905                                    Sym("baz", T.range("StaticOverload2"))));
906 }
907 
TEST(LocateSymbol,TextualDependent)908 TEST(LocateSymbol, TextualDependent) {
909   // Put the declarations in the header to make sure we are
910   // finding them via the index heuristic and not the
911   // nearby-ident heuristic.
912   Annotations Header(R"cpp(
913         struct Foo {
914           void $FooLoc[[uniqueMethodName]]();
915         };
916         struct Bar {
917           void $BarLoc[[uniqueMethodName]]();
918         };
919         )cpp");
920   Annotations Source(R"cpp(
921         template <typename T>
922         void f(T t) {
923           t.u^niqueMethodName();
924         }
925       )cpp");
926   TestTU TU;
927   TU.Code = std::string(Source.code());
928   TU.HeaderCode = std::string(Header.code());
929   auto AST = TU.build();
930   auto Index = TU.index();
931   // Need to use locateSymbolAt() since we are testing an
932   // interaction between locateASTReferent() and
933   // locateSymbolNamedTextuallyAt().
934   auto Results = locateSymbolAt(AST, Source.point(), Index.get());
935   EXPECT_THAT(Results, UnorderedElementsAre(
936                            Sym("uniqueMethodName", Header.range("FooLoc")),
937                            Sym("uniqueMethodName", Header.range("BarLoc"))));
938 }
939 
TEST(LocateSymbol,TemplateTypedefs)940 TEST(LocateSymbol, TemplateTypedefs) {
941   auto T = Annotations(R"cpp(
942     template <class T> struct function {};
943     template <class T> using callback = function<T()>;
944 
945     c^allback<int> foo;
946   )cpp");
947   auto AST = TestTU::withCode(T.code()).build();
948   EXPECT_THAT(locateSymbolAt(AST, T.point()), ElementsAre(Sym("callback")));
949 }
950 
TEST(LocateSymbol,RelPathsInCompileCommand)951 TEST(LocateSymbol, RelPathsInCompileCommand) {
952   // The source is in "/clangd-test/src".
953   // We build in "/clangd-test/build".
954 
955   Annotations SourceAnnotations(R"cpp(
956 #include "header_in_preamble.h"
957 int [[foo]];
958 #include "header_not_in_preamble.h"
959 int baz = f$p1^oo + bar_pre$p2^amble + bar_not_pre$p3^amble;
960 )cpp");
961 
962   Annotations HeaderInPreambleAnnotations(R"cpp(
963 int [[bar_preamble]];
964 )cpp");
965 
966   Annotations HeaderNotInPreambleAnnotations(R"cpp(
967 int [[bar_not_preamble]];
968 )cpp");
969 
970   // Make the compilation paths appear as ../src/foo.cpp in the compile
971   // commands.
972   SmallString<32> RelPathPrefix("..");
973   llvm::sys::path::append(RelPathPrefix, "src");
974   std::string BuildDir = testPath("build");
975   MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
976 
977   MockFS FS;
978   ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
979 
980   // Fill the filesystem.
981   auto FooCpp = testPath("src/foo.cpp");
982   FS.Files[FooCpp] = "";
983   auto HeaderInPreambleH = testPath("src/header_in_preamble.h");
984   FS.Files[HeaderInPreambleH] = std::string(HeaderInPreambleAnnotations.code());
985   auto HeaderNotInPreambleH = testPath("src/header_not_in_preamble.h");
986   FS.Files[HeaderNotInPreambleH] =
987       std::string(HeaderNotInPreambleAnnotations.code());
988 
989   runAddDocument(Server, FooCpp, SourceAnnotations.code());
990 
991   // Go to a definition in main source file.
992   auto Locations =
993       runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p1"));
994   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
995   EXPECT_THAT(*Locations, ElementsAre(Sym("foo", SourceAnnotations.range())));
996 
997   // Go to a definition in header_in_preamble.h.
998   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p2"));
999   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
1000   EXPECT_THAT(
1001       *Locations,
1002       ElementsAre(Sym("bar_preamble", HeaderInPreambleAnnotations.range())));
1003 
1004   // Go to a definition in header_not_in_preamble.h.
1005   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p3"));
1006   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
1007   EXPECT_THAT(*Locations,
1008               ElementsAre(Sym("bar_not_preamble",
1009                               HeaderNotInPreambleAnnotations.range())));
1010 }
1011 
TEST(GoToInclude,All)1012 TEST(GoToInclude, All) {
1013   MockFS FS;
1014   MockCompilationDatabase CDB;
1015   ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
1016 
1017   auto FooCpp = testPath("foo.cpp");
1018   const char *SourceContents = R"cpp(
1019   #include ^"$2^foo.h$3^"
1020   #include "$4^invalid.h"
1021   int b = a;
1022   // test
1023   int foo;
1024   #in$5^clude "$6^foo.h"$7^
1025   )cpp";
1026   Annotations SourceAnnotations(SourceContents);
1027   FS.Files[FooCpp] = std::string(SourceAnnotations.code());
1028   auto FooH = testPath("foo.h");
1029 
1030   const char *HeaderContents = R"cpp([[]]#pragma once
1031                                      int a;
1032                                      )cpp";
1033   Annotations HeaderAnnotations(HeaderContents);
1034   FS.Files[FooH] = std::string(HeaderAnnotations.code());
1035 
1036   Server.addDocument(FooH, HeaderAnnotations.code());
1037   Server.addDocument(FooCpp, SourceAnnotations.code());
1038 
1039   // Test include in preamble.
1040   auto Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point());
1041   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1042   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1043 
1044   // Test include in preamble, last char.
1045   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("2"));
1046   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1047   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1048 
1049   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("3"));
1050   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1051   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1052 
1053   // Test include outside of preamble.
1054   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("6"));
1055   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1056   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1057 
1058   // Test a few positions that do not result in Locations.
1059   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("4"));
1060   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1061   EXPECT_THAT(*Locations, IsEmpty());
1062 
1063   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("5"));
1064   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1065   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1066 
1067   Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("7"));
1068   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1069   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1070 
1071   // Objective C #import directive.
1072   Annotations ObjC(R"objc(
1073   #import "^foo.h"
1074   )objc");
1075   auto FooM = testPath("foo.m");
1076   FS.Files[FooM] = std::string(ObjC.code());
1077 
1078   Server.addDocument(FooM, ObjC.code());
1079   Locations = runLocateSymbolAt(Server, FooM, ObjC.point());
1080   ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1081   EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1082 }
1083 
TEST(LocateSymbol,WithPreamble)1084 TEST(LocateSymbol, WithPreamble) {
1085   // Test stragety: AST should always use the latest preamble instead of last
1086   // good preamble.
1087   MockFS FS;
1088   MockCompilationDatabase CDB;
1089   ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
1090 
1091   auto FooCpp = testPath("foo.cpp");
1092   // The trigger locations must be the same.
1093   Annotations FooWithHeader(R"cpp(#include "fo^o.h")cpp");
1094   Annotations FooWithoutHeader(R"cpp(double    [[fo^o]]();)cpp");
1095 
1096   FS.Files[FooCpp] = std::string(FooWithHeader.code());
1097 
1098   auto FooH = testPath("foo.h");
1099   Annotations FooHeader(R"cpp([[]])cpp");
1100   FS.Files[FooH] = std::string(FooHeader.code());
1101 
1102   runAddDocument(Server, FooCpp, FooWithHeader.code());
1103   // LocateSymbol goes to a #include file: the result comes from the preamble.
1104   EXPECT_THAT(
1105       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithHeader.point())),
1106       ElementsAre(Sym("foo.h", FooHeader.range())));
1107 
1108   // Only preamble is built, and no AST is built in this request.
1109   Server.addDocument(FooCpp, FooWithoutHeader.code(), "null",
1110                      WantDiagnostics::No);
1111   // We build AST here, and it should use the latest preamble rather than the
1112   // stale one.
1113   EXPECT_THAT(
1114       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
1115       ElementsAre(Sym("foo", FooWithoutHeader.range())));
1116 
1117   // Reset test environment.
1118   runAddDocument(Server, FooCpp, FooWithHeader.code());
1119   // Both preamble and AST are built in this request.
1120   Server.addDocument(FooCpp, FooWithoutHeader.code(), "null",
1121                      WantDiagnostics::Yes);
1122   // Use the AST being built in above request.
1123   EXPECT_THAT(
1124       cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
1125       ElementsAre(Sym("foo", FooWithoutHeader.range())));
1126 }
1127 
TEST(LocateSymbol,NearbyTokenSmoke)1128 TEST(LocateSymbol, NearbyTokenSmoke) {
1129   auto T = Annotations(R"cpp(
1130     // prints e^rr and crashes
1131     void die(const char* [[err]]);
1132   )cpp");
1133   auto AST = TestTU::withCode(T.code()).build();
1134   // We don't pass an index, so can't hit index-based fallback.
1135   EXPECT_THAT(locateSymbolAt(AST, T.point()),
1136               ElementsAre(Sym("err", T.range())));
1137 }
1138 
TEST(LocateSymbol,NearbyIdentifier)1139 TEST(LocateSymbol, NearbyIdentifier) {
1140   const char *Tests[] = {
1141       R"cpp(
1142       // regular identifiers (won't trigger)
1143       int hello;
1144       int y = he^llo;
1145     )cpp",
1146       R"cpp(
1147       // disabled preprocessor sections
1148       int [[hello]];
1149       #if 0
1150       int y = ^hello;
1151       #endif
1152     )cpp",
1153       R"cpp(
1154       // comments
1155       // he^llo, world
1156       int [[hello]];
1157     )cpp",
1158       R"cpp(
1159       // not triggered by string literals
1160       int hello;
1161       const char* greeting = "h^ello, world";
1162     )cpp",
1163 
1164       R"cpp(
1165       // can refer to macro invocations
1166       #define INT int
1167       [[INT]] x;
1168       // I^NT
1169     )cpp",
1170 
1171       R"cpp(
1172       // can refer to macro invocations (even if they expand to nothing)
1173       #define EMPTY
1174       [[EMPTY]] int x;
1175       // E^MPTY
1176     )cpp",
1177 
1178       R"cpp(
1179       // prefer nearest occurrence, backwards is worse than forwards
1180       int hello;
1181       int x = hello;
1182       // h^ello
1183       int y = [[hello]];
1184       int z = hello;
1185     )cpp",
1186 
1187       R"cpp(
1188       // short identifiers find near results
1189       int [[hi]];
1190       // h^i
1191     )cpp",
1192       R"cpp(
1193       // short identifiers don't find far results
1194       int hi;
1195 
1196 
1197 
1198       // h^i
1199     )cpp",
1200   };
1201   for (const char *Test : Tests) {
1202     Annotations T(Test);
1203     auto AST = TestTU::withCode(T.code()).build();
1204     const auto &SM = AST.getSourceManager();
1205     llvm::Optional<Range> Nearby;
1206     auto Word =
1207         SpelledWord::touching(cantFail(sourceLocationInMainFile(SM, T.point())),
1208                               AST.getTokens(), AST.getLangOpts());
1209     if (!Word) {
1210       ADD_FAILURE() << "No word at point! " << Test;
1211       continue;
1212     }
1213     if (const auto *Tok = findNearbyIdentifier(*Word, AST.getTokens()))
1214       Nearby = halfOpenToRange(SM, CharSourceRange::getCharRange(
1215                                        Tok->location(), Tok->endLocation()));
1216     if (T.ranges().empty())
1217       EXPECT_THAT(Nearby, Eq(llvm::None)) << Test;
1218     else
1219       EXPECT_EQ(Nearby, T.range()) << Test;
1220   }
1221 }
1222 
TEST(FindReferences,WithinAST)1223 TEST(FindReferences, WithinAST) {
1224   const char *Tests[] = {
1225       R"cpp(// Local variable
1226         int main() {
1227           int [[foo]];
1228           [[^foo]] = 2;
1229           int test1 = [[foo]];
1230         }
1231       )cpp",
1232 
1233       R"cpp(// Struct
1234         namespace ns1 {
1235         struct [[Foo]] {};
1236         } // namespace ns1
1237         int main() {
1238           ns1::[[Fo^o]]* Params;
1239         }
1240       )cpp",
1241 
1242       R"cpp(// Forward declaration
1243         class [[Foo]];
1244         class [[Foo]] {};
1245         int main() {
1246           [[Fo^o]] foo;
1247         }
1248       )cpp",
1249 
1250       R"cpp(// Function
1251         int [[foo]](int) {}
1252         int main() {
1253           auto *X = &[[^foo]];
1254           [[foo]](42);
1255         }
1256       )cpp",
1257 
1258       R"cpp(// Field
1259         struct Foo {
1260           int [[foo]];
1261           Foo() : [[foo]](0) {}
1262         };
1263         int main() {
1264           Foo f;
1265           f.[[f^oo]] = 1;
1266         }
1267       )cpp",
1268 
1269       R"cpp(// Method call
1270         struct Foo { int [[foo]](); };
1271         int Foo::[[foo]]() {}
1272         int main() {
1273           Foo f;
1274           f.[[^foo]]();
1275         }
1276       )cpp",
1277 
1278       R"cpp(// Constructor
1279         struct Foo {
1280           [[F^oo]](int);
1281         };
1282         void foo() {
1283           Foo f = [[Foo]](42);
1284         }
1285       )cpp",
1286 
1287       R"cpp(// Typedef
1288         typedef int [[Foo]];
1289         int main() {
1290           [[^Foo]] bar;
1291         }
1292       )cpp",
1293 
1294       R"cpp(// Namespace
1295         namespace [[ns]] {
1296         struct Foo {};
1297         } // namespace ns
1298         int main() { [[^ns]]::Foo foo; }
1299       )cpp",
1300 
1301       R"cpp(// Macros
1302         #define TYPE(X) X
1303         #define FOO Foo
1304         #define CAT(X, Y) X##Y
1305         class [[Fo^o]] {};
1306         void test() {
1307           TYPE([[Foo]]) foo;
1308           [[FOO]] foo2;
1309           TYPE(TYPE([[Foo]])) foo3;
1310           [[CAT]](Fo, o) foo4;
1311         }
1312       )cpp",
1313 
1314       R"cpp(// Macros
1315         #define [[MA^CRO]](X) (X+1)
1316         void test() {
1317           int x = [[MACRO]]([[MACRO]](1));
1318         }
1319       )cpp",
1320 
1321       R"cpp(
1322         int [[v^ar]] = 0;
1323         void foo(int s = [[var]]);
1324       )cpp",
1325 
1326       R"cpp(
1327        template <typename T>
1328        class [[Fo^o]] {};
1329        void func([[Foo]]<int>);
1330       )cpp",
1331 
1332       R"cpp(
1333        template <typename T>
1334        class [[Foo]] {};
1335        void func([[Fo^o]]<int>);
1336       )cpp",
1337       R"cpp(// Not touching any identifiers.
1338         struct Foo {
1339           [[~]]Foo() {};
1340         };
1341         void foo() {
1342           Foo f;
1343           f.[[^~]]Foo();
1344         }
1345       )cpp",
1346   };
1347   for (const char *Test : Tests) {
1348     Annotations T(Test);
1349     auto AST = TestTU::withCode(T.code()).build();
1350     std::vector<Matcher<Location>> ExpectedLocations;
1351     for (const auto &R : T.ranges())
1352       ExpectedLocations.push_back(RangeIs(R));
1353     EXPECT_THAT(findReferences(AST, T.point(), 0).References,
1354                 ElementsAreArray(ExpectedLocations))
1355         << Test;
1356   }
1357 }
1358 
TEST(FindReferences,MainFileReferencesOnly)1359 TEST(FindReferences, MainFileReferencesOnly) {
1360   llvm::StringRef Test =
1361       R"cpp(
1362         void test() {
1363           int [[fo^o]] = 1;
1364           // refs not from main file should not be included.
1365           #include "foo.inc"
1366         })cpp";
1367 
1368   Annotations Code(Test);
1369   auto TU = TestTU::withCode(Code.code());
1370   TU.AdditionalFiles["foo.inc"] = R"cpp(
1371       foo = 3;
1372     )cpp";
1373   auto AST = TU.build();
1374 
1375   std::vector<Matcher<Location>> ExpectedLocations;
1376   for (const auto &R : Code.ranges())
1377     ExpectedLocations.push_back(RangeIs(R));
1378   EXPECT_THAT(findReferences(AST, Code.point(), 0).References,
1379               ElementsAreArray(ExpectedLocations))
1380       << Test;
1381 }
1382 
TEST(FindReferences,ExplicitSymbols)1383 TEST(FindReferences, ExplicitSymbols) {
1384   const char *Tests[] = {
1385       R"cpp(
1386       struct Foo { Foo* [[self]]() const; };
1387       void f() {
1388         Foo foo;
1389         if (Foo* T = foo.[[^self]]()) {} // Foo member call expr.
1390       }
1391       )cpp",
1392 
1393       R"cpp(
1394       struct Foo { Foo(int); };
1395       Foo f() {
1396         int [[b]];
1397         return [[^b]]; // Foo constructor expr.
1398       }
1399       )cpp",
1400 
1401       R"cpp(
1402       struct Foo {};
1403       void g(Foo);
1404       Foo [[f]]();
1405       void call() {
1406         g([[^f]]());  // Foo constructor expr.
1407       }
1408       )cpp",
1409 
1410       R"cpp(
1411       void [[foo]](int);
1412       void [[foo]](double);
1413 
1414       namespace ns {
1415       using ::[[fo^o]];
1416       }
1417       )cpp",
1418 
1419       R"cpp(
1420       struct X {
1421         operator bool();
1422       };
1423 
1424       int test() {
1425         X [[a]];
1426         [[a]].operator bool();
1427         if ([[a^]]) {} // ignore implicit conversion-operator AST node
1428       }
1429     )cpp",
1430   };
1431   for (const char *Test : Tests) {
1432     Annotations T(Test);
1433     auto AST = TestTU::withCode(T.code()).build();
1434     std::vector<Matcher<Location>> ExpectedLocations;
1435     for (const auto &R : T.ranges())
1436       ExpectedLocations.push_back(RangeIs(R));
1437     ASSERT_THAT(ExpectedLocations, Not(IsEmpty()));
1438     EXPECT_THAT(findReferences(AST, T.point(), 0).References,
1439                 ElementsAreArray(ExpectedLocations))
1440         << Test;
1441   }
1442 }
1443 
TEST(FindReferences,NeedsIndexForSymbols)1444 TEST(FindReferences, NeedsIndexForSymbols) {
1445   const char *Header = "int foo();";
1446   Annotations Main("int main() { [[f^oo]](); }");
1447   TestTU TU;
1448   TU.Code = std::string(Main.code());
1449   TU.HeaderCode = Header;
1450   auto AST = TU.build();
1451 
1452   // References in main file are returned without index.
1453   EXPECT_THAT(
1454       findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
1455       ElementsAre(RangeIs(Main.range())));
1456   Annotations IndexedMain(R"cpp(
1457     int main() { [[f^oo]](); }
1458   )cpp");
1459 
1460   // References from indexed files are included.
1461   TestTU IndexedTU;
1462   IndexedTU.Code = std::string(IndexedMain.code());
1463   IndexedTU.Filename = "Indexed.cpp";
1464   IndexedTU.HeaderCode = Header;
1465   EXPECT_THAT(
1466       findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
1467       ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
1468   auto LimitRefs =
1469       findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
1470   EXPECT_EQ(1u, LimitRefs.References.size());
1471   EXPECT_TRUE(LimitRefs.HasMore);
1472 
1473   // Avoid indexed results for the main file. Use AST for the mainfile.
1474   TU.Code = ("\n\n" + Main.code()).str();
1475   EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()).References,
1476               ElementsAre(RangeIs(Main.range())));
1477 }
1478 
TEST(FindReferences,NeedsIndexForMacro)1479 TEST(FindReferences, NeedsIndexForMacro) {
1480   const char *Header = "#define MACRO(X) (X+1)";
1481   Annotations Main(R"cpp(
1482     int main() {
1483       int a = [[MA^CRO]](1);
1484     }
1485   )cpp");
1486   TestTU TU;
1487   TU.Code = std::string(Main.code());
1488   TU.HeaderCode = Header;
1489   auto AST = TU.build();
1490 
1491   // References in main file are returned without index.
1492   EXPECT_THAT(
1493       findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
1494       ElementsAre(RangeIs(Main.range())));
1495 
1496   Annotations IndexedMain(R"cpp(
1497     int indexed_main() {
1498       int a = [[MACRO]](1);
1499     }
1500   )cpp");
1501 
1502   // References from indexed files are included.
1503   TestTU IndexedTU;
1504   IndexedTU.Code = std::string(IndexedMain.code());
1505   IndexedTU.Filename = "Indexed.cpp";
1506   IndexedTU.HeaderCode = Header;
1507   EXPECT_THAT(
1508       findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
1509       ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
1510   auto LimitRefs =
1511       findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
1512   EXPECT_EQ(1u, LimitRefs.References.size());
1513   EXPECT_TRUE(LimitRefs.HasMore);
1514 }
1515 
TEST(FindReferences,NoQueryForLocalSymbols)1516 TEST(FindReferences, NoQueryForLocalSymbols) {
1517   struct RecordingIndex : public MemIndex {
1518     mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
1519     bool refs(const RefsRequest &Req,
1520               llvm::function_ref<void(const Ref &)>) const override {
1521       RefIDs = Req.IDs;
1522       return false;
1523     }
1524   };
1525 
1526   struct Test {
1527     StringRef AnnotatedCode;
1528     bool WantQuery;
1529   } Tests[] = {
1530       {"int ^x;", true},
1531       // For now we don't assume header structure which would allow skipping.
1532       {"namespace { int ^x; }", true},
1533       {"static int ^x;", true},
1534       // Anything in a function certainly can't be referenced though.
1535       {"void foo() { int ^x; }", false},
1536       {"void foo() { struct ^x{}; }", false},
1537       {"auto lambda = []{ int ^x; };", false},
1538   };
1539   for (Test T : Tests) {
1540     Annotations File(T.AnnotatedCode);
1541     RecordingIndex Rec;
1542     auto AST = TestTU::withCode(File.code()).build();
1543     findReferences(AST, File.point(), 0, &Rec);
1544     if (T.WantQuery)
1545       EXPECT_NE(Rec.RefIDs, None) << T.AnnotatedCode;
1546     else
1547       EXPECT_EQ(Rec.RefIDs, None) << T.AnnotatedCode;
1548   }
1549 }
1550 
TEST(GetNonLocalDeclRefs,All)1551 TEST(GetNonLocalDeclRefs, All) {
1552   struct Case {
1553     llvm::StringRef AnnotatedCode;
1554     std::vector<std::string> ExpectedDecls;
1555   } Cases[] = {
1556       {
1557           // VarDecl and ParamVarDecl
1558           R"cpp(
1559             void bar();
1560             void ^foo(int baz) {
1561               int x = 10;
1562               bar();
1563             })cpp",
1564           {"bar"},
1565       },
1566       {
1567           // Method from class
1568           R"cpp(
1569             class Foo { public: void foo(); };
1570             class Bar {
1571               void foo();
1572               void bar();
1573             };
1574             void Bar::^foo() {
1575               Foo f;
1576               bar();
1577               f.foo();
1578             })cpp",
1579           {"Bar", "Bar::bar", "Foo", "Foo::foo"},
1580       },
1581       {
1582           // Local types
1583           R"cpp(
1584             void ^foo() {
1585               class Foo { public: void foo() {} };
1586               class Bar { public: void bar() {} };
1587               Foo f;
1588               Bar b;
1589               b.bar();
1590               f.foo();
1591             })cpp",
1592           {},
1593       },
1594       {
1595           // Template params
1596           R"cpp(
1597             template <typename T, template<typename> class Q>
1598             void ^foo() {
1599               T x;
1600               Q<T> y;
1601             })cpp",
1602           {},
1603       },
1604   };
1605   for (const Case &C : Cases) {
1606     Annotations File(C.AnnotatedCode);
1607     auto AST = TestTU::withCode(File.code()).build();
1608     SourceLocation SL = llvm::cantFail(
1609         sourceLocationInMainFile(AST.getSourceManager(), File.point()));
1610 
1611     const FunctionDecl *FD =
1612         llvm::dyn_cast<FunctionDecl>(&findDecl(AST, [SL](const NamedDecl &ND) {
1613           return ND.getLocation() == SL && llvm::isa<FunctionDecl>(ND);
1614         }));
1615     ASSERT_NE(FD, nullptr);
1616 
1617     auto NonLocalDeclRefs = getNonLocalDeclRefs(AST, FD);
1618     std::vector<std::string> Names;
1619     for (const Decl *D : NonLocalDeclRefs) {
1620       if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
1621         Names.push_back(ND->getQualifiedNameAsString());
1622     }
1623     EXPECT_THAT(Names, UnorderedElementsAreArray(C.ExpectedDecls))
1624         << File.code();
1625   }
1626 }
1627 
TEST(DocumentLinks,All)1628 TEST(DocumentLinks, All) {
1629   Annotations MainCpp(R"cpp(
1630       #/*comments*/include /*comments*/ $foo[["foo.h"]] //more comments
1631       int end_of_preamble = 0;
1632       #include $bar[[<bar.h>]]
1633     )cpp");
1634 
1635   TestTU TU;
1636   TU.Code = std::string(MainCpp.code());
1637   TU.AdditionalFiles = {{"foo.h", ""}, {"bar.h", ""}};
1638   TU.ExtraArgs = {"-isystem."};
1639   auto AST = TU.build();
1640 
1641   EXPECT_THAT(
1642       clangd::getDocumentLinks(AST),
1643       ElementsAre(
1644           DocumentLink({MainCpp.range("foo"),
1645                         URIForFile::canonicalize(testPath("foo.h"), "")}),
1646           DocumentLink({MainCpp.range("bar"),
1647                         URIForFile::canonicalize(testPath("bar.h"), "")})));
1648 }
1649 
1650 } // namespace
1651 } // namespace clangd
1652 } // namespace clang
1653