clang-tools 24.0.0git
FindTargetTests.cpp
Go to the documentation of this file.
1//===-- FindTargetTests.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 "FindTarget.h"
9
10#include "Selection.h"
11#include "TestTU.h"
12#include "clang/AST/Decl.h"
13#include "clang/AST/DeclObjC.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/Basic/SourceLocation.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/Testing/Annotations/Annotations.h"
20#include "gmock/gmock.h"
21#include "gtest/gtest.h"
22#include <initializer_list>
23
24namespace clang {
25namespace clangd {
26namespace {
27
28// A referenced Decl together with its DeclRelationSet, for assertions.
29//
30// There's no great way to assert on the "content" of a Decl in the general case
31// that's both expressive and unambiguous (e.g. clearly distinguishes between
32// templated decls and their specializations).
33//
34// We use the result of pretty-printing the decl, with the {body} truncated.
35struct PrintedDecl {
36 PrintedDecl(const char *Name, DeclRelationSet Relations = {})
37 : Name(Name), Relations(Relations) {}
38 PrintedDecl(const NamedDecl *D, DeclRelationSet Relations = {})
39 : Relations(Relations) {
40 std::string S;
41 llvm::raw_string_ostream OS(S);
42 D->print(OS);
43 llvm::StringRef FirstLine =
44 llvm::StringRef(OS.str()).take_until([](char C) { return C == '\n'; });
45 FirstLine = FirstLine.rtrim(" {");
46 Name = std::string(FirstLine.rtrim(" {"));
47 }
48
49 std::string Name;
50 DeclRelationSet Relations;
51};
52bool operator==(const PrintedDecl &L, const PrintedDecl &R) {
53 return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);
54}
55llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PrintedDecl &D) {
56 return OS << D.Name << " Rel=" << D.Relations;
57}
58
59// The test cases in for targetDecl() take the form
60// - a piece of code (Code = "...")
61// - Code should have a single AST node marked as a [[range]]
62// - an EXPECT_DECLS() assertion that verify the type of node selected, and
63// all the decls that targetDecl() considers it to reference
64// Despite the name, these cases actually test allTargetDecls() for brevity.
65class TargetDeclTest : public ::testing::Test {
66protected:
67 using Rel = DeclRelation;
68 std::string Code;
69 std::vector<std::string> Flags;
70
71 // Asserts that `Code` has a marked selection of a node `NodeType`,
72 // and returns allTargetDecls() as PrintedDecl structs.
73 // Use via EXPECT_DECLS().
74 std::vector<PrintedDecl> assertNodeAndPrintDecls(const char *NodeType) {
75 llvm::Annotations A(Code);
76 auto TU = TestTU::withCode(A.code());
77 TU.ExtraArgs = Flags;
78 auto AST = TU.build();
79 llvm::Annotations::Range R = A.range();
80 auto Selection = SelectionTree::createRight(
81 AST.getASTContext(), AST.getTokens(), R.Begin, R.End);
82 const SelectionTree::Node *N = Selection.commonAncestor();
83 if (!N) {
84 ADD_FAILURE() << "No node selected!\n" << Code;
85 return {};
86 }
87 EXPECT_EQ(N->kind(), NodeType) << Selection;
88
89 std::vector<PrintedDecl> ActualDecls;
90 for (const auto &Entry :
91 allTargetDecls(N->ASTNode, AST.getHeuristicResolver()))
92 ActualDecls.emplace_back(Entry.first, Entry.second);
93 return ActualDecls;
94 }
95};
96
97// This is a macro to preserve line numbers in assertion failures.
98// It takes the expected decls as varargs to work around comma-in-macro issues.
99#define EXPECT_DECLS(NodeType, ...) \
100 EXPECT_THAT(assertNodeAndPrintDecls(NodeType), \
101 ::testing::UnorderedElementsAreArray( \
102 std::vector<PrintedDecl>({__VA_ARGS__}))) \
103 << Code
104using ExpectedDecls = std::vector<PrintedDecl>;
105
106TEST_F(TargetDeclTest, Exprs) {
107 Code = R"cpp(
108 int f();
109 int x = [[f]]();
110 )cpp";
111 EXPECT_DECLS("DeclRefExpr", "int f()");
112
113 Code = R"cpp(
114 struct S { S operator+(S) const; };
115 auto X = S() [[+]] S();
116 )cpp";
117 EXPECT_DECLS("DeclRefExpr", "S operator+(S) const");
118
119 Code = R"cpp(
120 int foo();
121 int s = foo[[()]];
122 )cpp";
123 EXPECT_DECLS("CallExpr", "int foo()");
124
125 Code = R"cpp(
126 struct X {
127 void operator()(int n);
128 };
129 void test() {
130 X x;
131 x[[(123)]];
132 }
133 )cpp";
134 EXPECT_DECLS("CXXOperatorCallExpr", "void operator()(int n)");
135
136 Code = R"cpp(
137 void test() {
138 goto [[label]];
139 label:
140 return;
141 }
142 )cpp";
143 EXPECT_DECLS("GotoStmt", "label:");
144 Code = R"cpp(
145 void test() {
146 [[label]]:
147 return;
148 }
149 )cpp";
150 EXPECT_DECLS("LabelStmt", "label:");
151}
152
153TEST_F(TargetDeclTest, RecoveryForC) {
154 Flags = {"-xc", "-Xclang", "-frecovery-ast"};
155 Code = R"cpp(
156 // error-ok: testing behavior on broken code
157 // int f();
158 int f(int);
159 int x = [[f]]();
160 )cpp";
161 EXPECT_DECLS("DeclRefExpr", "int f(int)");
162}
163
164TEST_F(TargetDeclTest, Recovery) {
165 Code = R"cpp(
166 // error-ok: testing behavior on broken code
167 int f();
168 int f(int, int);
169 int x = [[f]](42);
170 )cpp";
171 EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)");
172}
173
174TEST_F(TargetDeclTest, RecoveryType) {
175 Code = R"cpp(
176 // error-ok: testing behavior on broken code
177 struct S { int member; };
178 S overloaded(int);
179 void foo() {
180 // No overload matches, but we have recovery-expr with the correct type.
181 overloaded().[[member]];
182 }
183 )cpp";
184 EXPECT_DECLS("MemberExpr", "int member");
185}
186
187TEST_F(TargetDeclTest, UsingDecl) {
188 Code = R"cpp(
189 namespace foo {
190 int f(int);
191 int f(char);
192 }
193 using foo::f;
194 int x = [[f]](42);
195 )cpp";
196 // f(char) is not referenced!
197 EXPECT_DECLS("DeclRefExpr", {"using foo::f", Rel::Alias}, {"int f(int)"});
198
199 Code = R"cpp(
200 namespace foo {
201 int f(int);
202 int f(char);
203 }
204 [[using foo::f]];
205 )cpp";
206 // All overloads are referenced.
207 EXPECT_DECLS("UsingDecl", {"using foo::f", Rel::Alias}, {"int f(int)"},
208 {"int f(char)"});
209
210 Code = R"cpp(
211 struct X {
212 int foo();
213 };
214 struct Y : X {
215 using X::foo;
216 };
217 int x = Y().[[foo]]();
218 )cpp";
219 EXPECT_DECLS("MemberExpr", {"using X::foo", Rel::Alias}, {"int foo()"});
220
221 Code = R"cpp(
222 template <typename T>
223 struct Base {
224 void waldo() {}
225 };
226 template <typename T>
227 struct Derived : Base<T> {
228 using Base<T>::[[waldo]];
229 };
230 )cpp";
231 EXPECT_DECLS("UnresolvedUsingValueDecl", {"using Base<T>::waldo", Rel::Alias},
232 {"void waldo()"});
233
234 Code = R"cpp(
235 namespace ns {
236 template<typename T> class S {};
237 }
238
239 using ns::S;
240
241 template<typename T>
242 using A = [[S]]<T>;
243 )cpp";
244 EXPECT_DECLS("TemplateSpecializationTypeLoc", {"using ns::S", Rel::Alias},
245 {"template <typename T> class S"},
246 {"class S", Rel::TemplatePattern});
247
248 Code = R"cpp(
249 namespace ns {
250 template<typename T> class S {};
251 }
252
253 using ns::S;
254 template <template <typename> class T> class X {};
255 using B = X<[[S]]>;
256 )cpp";
257 EXPECT_DECLS("TemplateArgumentLoc", {"using ns::S", Rel::Alias},
258 {"template <typename T> class S"});
259
260 Code = R"cpp(
261 namespace ns {
262 template<typename T> class S { public: S(T); };
263 }
264
265 using ns::S;
266 [[S]] s(123);
267 )cpp";
268 Flags.push_back("-std=c++17"); // For CTAD feature.
269 EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
270 {"using ns::S", Rel::Alias}, {"template <typename T> class S"},
271 {"class S", Rel::TemplatePattern});
272
273 Code = R"cpp(
274 template<typename T>
275 class Foo { public: class foo {}; };
276 template <class T> class A : public Foo<T> {
277 using typename Foo<T>::foo;
278 [[foo]] abc;
279 };
280 )cpp";
281 EXPECT_DECLS("UnresolvedUsingTypeLoc",
282 {"using typename Foo<T>::foo", Rel::Alias});
283
284 // Using enum.
285 Flags.push_back("-std=c++20");
286 Code = R"cpp(
287 namespace ns { enum class A { X }; }
288 [[using enum ns::A]];
289 )cpp";
290 EXPECT_DECLS("UsingEnumDecl", "enum class A : int");
291
292 Code = R"cpp(
293 namespace ns { enum class A { X }; }
294 using enum ns::A;
295 auto m = [[X]];
296 )cpp";
297 EXPECT_DECLS("DeclRefExpr", "X");
298}
299
300TEST_F(TargetDeclTest, BaseSpecifier) {
301 Code = R"cpp(
302 struct X {};
303 struct Y : [[private]] X {};
304 )cpp";
305 EXPECT_DECLS("CXXBaseSpecifier", "struct X");
306 Code = R"cpp(
307 struct X {};
308 struct Y : [[private X]] {};
309 )cpp";
310 EXPECT_DECLS("CXXBaseSpecifier", "struct X");
311 Code = R"cpp(
312 struct X {};
313 struct Y : private [[X]] {};
314 )cpp";
315 EXPECT_DECLS("RecordTypeLoc", "struct X");
316}
317
318TEST_F(TargetDeclTest, ConstructorInitList) {
319 Code = R"cpp(
320 struct X {
321 int a;
322 X() : [[a]](42) {}
323 };
324 )cpp";
325 EXPECT_DECLS("CXXCtorInitializer", "int a");
326
327 Code = R"cpp(
328 struct X {
329 X() : [[X]](1) {}
330 X(int);
331 };
332 )cpp";
333 EXPECT_DECLS("RecordTypeLoc", "struct X");
334}
335
336TEST_F(TargetDeclTest, DesignatedInit) {
337 Flags = {"-xc"}; // array designators are a C99 extension.
338 Code = R"c(
339 struct X { int a; };
340 struct Y { int b; struct X c[2]; };
341 struct Y y = { .c[0].[[a]] = 1 };
342 )c";
343 EXPECT_DECLS("DesignatedInitExpr", "int a");
344}
345
346TEST_F(TargetDeclTest, OffsetOf) {
347 Code = R"cpp(
348 struct Foo { int bar; };
349 int x = __builtin_offsetof(Foo, [[bar]]);
350 )cpp";
351 EXPECT_DECLS("OffsetOfNode", "int bar");
352
353 Code = R"cpp(
354 struct Inner { int c; };
355 struct Outer { Inner b; };
356 int x = __builtin_offsetof(Outer, [[b]].c);
357 )cpp";
358 EXPECT_DECLS("OffsetOfNode", "Inner b");
359
360 Code = R"cpp(
361 struct Inner { int c; };
362 struct Outer { Inner b; };
363 int x = __builtin_offsetof(Outer, b.[[c]]);
364 )cpp";
365 EXPECT_DECLS("OffsetOfNode", "int c");
366
367 // Selection that spans multiple components doesn't match any single
368 // OffsetOfNode.
369 Code = R"cpp(
370 struct Inner { int c; };
371 struct Outer { Inner b; };
372 int x = __builtin_offsetof(Outer, [[b.c]]);
373 )cpp";
374 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
375
376 Code = R"cpp(
377 struct Inner { int c; };
378 struct Outer { Inner b; };
379 int x = __builtin_offsetof(Outer, [[b.]]c);
380 )cpp";
381 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
382
383 Code = R"cpp(
384 struct Inner { int c; };
385 struct Outer { Inner b; };
386 int x = __builtin_offsetof(Outer, b[[.c]]);
387 )cpp";
388 EXPECT_DECLS("OffsetOfNode", "int c");
389
390 Code = R"cpp(
391 struct Foo { int bar; };
392 int x = __builtin_[[offsetof]](Foo, bar);
393 )cpp";
394 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
395
396 // Base-class component: the implicit Base node has no source range, so
397 // the cursor on `x` resolves precisely to the inherited field.
398 Code = R"cpp(
399 struct B { int x; };
400 struct D : B {};
401 int o = __builtin_offsetof(D, [[x]]);
402 )cpp";
403 EXPECT_DECLS("OffsetOfNode", "int x");
404
405 // Dependent-type identifier component: no resolvable decl, but must not
406 // crash and must not produce spurious targets.
407 Code = R"cpp(
408 template <typename T> int f() { return __builtin_offsetof(T, [[x]]); }
409 )cpp";
410 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfNode"), ::testing::IsEmpty());
411
412 // C-style offsetof macro form resolves the same as __builtin_offsetof.
413 Code = R"cpp(
414 #define offsetof(t, m) __builtin_offsetof(t, m)
415 struct Foo { int bar; };
416 int x = offsetof(Foo, [[bar]]);
417 )cpp";
418 EXPECT_DECLS("OffsetOfNode", "int bar");
419
420 // Array-index expression in an offsetof designator should still resolve as
421 // the expression, not as the enclosing OffsetOfNode.
422 Code = R"cpp(
423 struct Foo { int bar[4]; };
424 int i;
425 int x = __builtin_offsetof(Foo, bar[ [[i]] ]);
426 )cpp";
427 EXPECT_DECLS("DeclRefExpr", "int i");
428}
429
430TEST_F(TargetDeclTest, NestedNameSpecifier) {
431 Code = R"cpp(
432 namespace a { namespace b { int c; } }
433 int x = a::[[b::]]c;
434 )cpp";
435 EXPECT_DECLS("NestedNameSpecifierLoc", "namespace b");
436
437 Code = R"cpp(
438 namespace a { struct X { enum { y }; }; }
439 int x = a::[[X::]]y;
440 )cpp";
441 EXPECT_DECLS("NestedNameSpecifierLoc", "struct X");
442
443 Code = R"cpp(
444 template <typename T>
445 int x = [[T::]]y;
446 )cpp";
447 EXPECT_DECLS("NestedNameSpecifierLoc", "typename T");
448
449 Code = R"cpp(
450 namespace a { int x; }
451 namespace b = a;
452 int y = [[b]]::x;
453 )cpp";
454 EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},
455 {"namespace a", Rel::Underlying});
456}
457
458TEST_F(TargetDeclTest, Types) {
459 Code = R"cpp(
460 struct X{};
461 [[X]] x;
462 )cpp";
463 EXPECT_DECLS("RecordTypeLoc", "struct X");
464
465 Code = R"cpp(
466 struct S{};
467 typedef S X;
468 [[X]] x;
469 )cpp";
470 EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},
471 {"struct S", Rel::Underlying});
472 Code = R"cpp(
473 namespace ns { struct S{}; }
474 typedef ns::S X;
475 [[X]] x;
476 )cpp";
477 EXPECT_DECLS("TypedefTypeLoc", {"typedef ns::S X", Rel::Alias},
478 {"struct S", Rel::Underlying});
479
480 Code = R"cpp(
481 template<class T>
482 void foo() { [[T]] x; }
483 )cpp";
484 EXPECT_DECLS("TemplateTypeParmTypeLoc", "class T");
485 Flags.clear();
486
487 Code = R"cpp(
488 template<template<typename> class T>
489 void foo() { [[T<int>]] x; }
490 )cpp";
491 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class T");
492 Flags.clear();
493
494 Code = R"cpp(
495 template<template<typename> class ...T>
496 class C {
497 C<[[T...]]> foo;
498 };
499 )cpp";
500 EXPECT_DECLS("TemplateArgumentLoc", {"template <typename> class ...T"});
501 Flags.clear();
502
503 Code = R"cpp(
504 struct S{};
505 S X;
506 [[decltype]](X) Y;
507 )cpp";
508 EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});
509
510 Code = R"cpp(
511 struct S{};
512 [[auto]] X = S{};
513 )cpp";
514 // FIXME: deduced type missing in AST. https://llvm.org/PR42914
515 EXPECT_DECLS("AutoTypeLoc", );
516
517 Code = R"cpp(
518 template <typename... E>
519 struct S {
520 static const int size = sizeof...([[E]]);
521 };
522 )cpp";
523 EXPECT_DECLS("SizeOfPackExpr", "typename ...E");
524
525 Code = R"cpp(
526 template <typename T>
527 class Foo {
528 void f([[Foo]] x);
529 };
530 )cpp";
531 EXPECT_DECLS("InjectedClassNameTypeLoc", "class Foo");
532}
533
534TEST_F(TargetDeclTest, ClassTemplate) {
535 Code = R"cpp(
536 // Implicit specialization.
537 template<int x> class Foo{};
538 [[Foo<42>]] B;
539 )cpp";
540 EXPECT_DECLS("TemplateSpecializationTypeLoc",
541 {"template<> class Foo<42>", Rel::TemplateInstantiation},
542 {"class Foo", Rel::TemplatePattern});
543
544 Code = R"cpp(
545 template<typename T> class Foo {};
546 // The "Foo<int>" SpecializationDecl is incomplete, there is no
547 // instantiation happening.
548 void func([[Foo<int>]] *);
549 )cpp";
550 EXPECT_DECLS("TemplateSpecializationTypeLoc",
551 {"class Foo", Rel::TemplatePattern},
552 {"template<> class Foo<int>", Rel::TemplateInstantiation});
553
554 Code = R"cpp(
555 // Explicit specialization.
556 template<int x> class Foo{};
557 template<> class Foo<42>{};
558 [[Foo<42>]] B;
559 )cpp";
560 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template<> class Foo<42>");
561
562 Code = R"cpp(
563 // Partial specialization.
564 template<typename T> class Foo{};
565 template<typename T> class Foo<T*>{};
566 [[Foo<int*>]] B;
567 )cpp";
568 EXPECT_DECLS("TemplateSpecializationTypeLoc",
569 {"template<> class Foo<int *>", Rel::TemplateInstantiation},
570 {"template <typename T> class Foo<T *>", Rel::TemplatePattern});
571
572 Code = R"cpp(
573 // Template template argument.
574 template<typename T> struct Vector {};
575 template <template <typename> class Container>
576 struct A {};
577 A<[[Vector]]> a;
578 )cpp";
579 EXPECT_DECLS("TemplateArgumentLoc", {"template <typename T> struct Vector"});
580
581 Flags.push_back("-std=c++17"); // for CTAD tests
582
583 Code = R"cpp(
584 // Class template argument deduction
585 template <typename T>
586 struct Test {
587 Test(T);
588 };
589 void foo() {
590 [[Test]] a(5);
591 }
592 )cpp";
593 EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
594 {"struct Test", Rel::TemplatePattern});
595
596 Code = R"cpp(
597 // Deduced specialization of a template template parameter
598 template <template<typename> class X>
599 void foo() {
600 [[X]] a;
601 }
602 )cpp";
603 EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
604 "template <typename> class X");
605
606 Code = R"cpp(
607 // Deduction guide
608 template <typename T>
609 struct Test {
610 template <typename I>
611 Test(I, I);
612 };
613 template <typename I>
614 [[Test]](I, I) -> Test<typename I::type>;
615 )cpp";
616 EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"});
617}
618
619TEST_F(TargetDeclTest, Concept) {
620 Flags.push_back("-std=c++20");
621
622 // FIXME: Should we truncate the pretty-printed form of a concept decl
623 // somewhere?
624
625 Code = R"cpp(
626 template <typename T>
627 concept Fooable = requires (T t) { t.foo(); };
628
629 template <typename T> requires [[Fooable]]<T>
630 void bar(T t) {
631 t.foo();
632 }
633 )cpp";
635 "ConceptReference",
636 {"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
637
638 // trailing requires clause
639 Code = R"cpp(
640 template <typename T>
641 concept Fooable = true;
642
643 template <typename T>
644 void foo() requires [[Fooable]]<T>;
645 )cpp";
646 EXPECT_DECLS("ConceptReference",
647 {"template <typename T> concept Fooable = true"});
648
649 // constrained-parameter
650 Code = R"cpp(
651 template <typename T>
652 concept Fooable = true;
653
654 template <[[Fooable]] T>
655 void bar(T t);
656 )cpp";
657 EXPECT_DECLS("ConceptReference",
658 {"template <typename T> concept Fooable = true"});
659
660 // partial-concept-id
661 Code = R"cpp(
662 template <typename T, typename U>
663 concept Fooable = true;
664
665 template <[[Fooable]]<int> T>
666 void bar(T t);
667 )cpp";
668 EXPECT_DECLS("ConceptReference",
669 {"template <typename T, typename U> concept Fooable = true"});
670}
671
672TEST_F(TargetDeclTest, PackIndexing) {
673 Flags.push_back("-std=c++2d");
674
675 Code = R"cpp(
676 // Deduced specialization of an indexed template template parameter pack
677 template <template <typename> class... X>
678 void foo() {
679 [[X]]...[0] a(1);
680 }
681 )cpp";
682 EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
683 "template <typename> class ...X");
684
685 Code = R"cpp(
686 // Specialization of an indexed template template parameter pack
687 template <template <typename> class... X>
688 void foo() {
689 [[X]]...[0]<int> x;
690 }
691 )cpp";
692 EXPECT_DECLS("TemplateSpecializationTypeLoc",
693 "template <typename> class ...X");
694
695 Code = R"cpp(
696 // Indexed type template parameter pack
697 template <typename... X>
698 void foo() {
699 [[X]]...[0] x;
700 }
701 )cpp";
702 EXPECT_DECLS("TemplateTypeParmTypeLoc", "typename ...X");
703}
704
705TEST_F(TargetDeclTest, PackIndexedConcept) {
706 Flags.push_back("-std=c++2d");
707
708 // constrained-parameter
709 Code = R"cpp(
710 template <template <class> concept... CC>
711 struct S {
712 template <[[CC]]...[0] T>
713 void bar(T t);
714 };
715 )cpp";
716 EXPECT_DECLS("ConceptReference", {"template <class> concept ...CC"});
717
718 // constrained placeholder type
719 Code = R"cpp(
720 template <template <class> concept... CC>
721 void bar([[CC]]...[0] auto t);
722 )cpp";
723 EXPECT_DECLS("ConceptReference", {"template <class> concept ...CC"});
724}
725
726TEST_F(TargetDeclTest, Coroutine) {
727 Flags.push_back("-std=c++20");
728
729 Code = R"cpp(
730 namespace std {
731 template <typename, typename...> struct coroutine_traits;
732 template <typename> struct coroutine_handle {
733 template <typename U>
734 coroutine_handle(coroutine_handle<U>&&) noexcept;
735 static coroutine_handle from_address(void* __addr) noexcept;
736 };
737 } // namespace std
738
739 struct executor {};
740 struct awaitable {};
741 struct awaitable_frame {
742 awaitable get_return_object();
743 void return_void();
744 void unhandled_exception();
745 struct result_t {
746 ~result_t();
747 bool await_ready() const noexcept;
748 void await_suspend(std::coroutine_handle<void>) noexcept;
749 void await_resume() const noexcept;
750 };
751 result_t initial_suspend() noexcept;
752 result_t final_suspend() noexcept;
753 result_t await_transform(executor) noexcept;
754 };
755
756 namespace std {
757 template <>
758 struct coroutine_traits<awaitable> {
759 typedef awaitable_frame promise_type;
760 };
761 } // namespace std
762
763 awaitable foo() {
764 co_await [[executor]]();
765 }
766 )cpp";
767 EXPECT_DECLS("RecordTypeLoc", "struct executor");
768}
769
770TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
771 Flags.push_back("-std=c++20");
772
773 Code = R"cpp(
774 namespace std {
775 struct strong_ordering {
776 int n;
777 constexpr operator int() const { return n; }
778 static const strong_ordering equal, greater, less;
779 };
780 constexpr strong_ordering strong_ordering::equal = {0};
781 constexpr strong_ordering strong_ordering::greater = {1};
782 constexpr strong_ordering strong_ordering::less = {-1};
783 }
784
785 struct Foo
786 {
787 int x;
788 auto operator<=>(const Foo&) const = default;
789 };
790
791 bool x = (Foo(1) [[!=]] Foo(2));
792 )cpp";
793 EXPECT_DECLS("CXXRewrittenBinaryOperator",
794 {"std::strong_ordering operator<=>(const Foo &) const = default",
795 Rel::TemplatePattern},
796 {"bool operator==(const Foo &) const noexcept = default",
797 Rel::TemplateInstantiation});
798}
799
800TEST_F(TargetDeclTest, FunctionTemplate) {
801 Code = R"cpp(
802 // Implicit specialization.
803 template<typename T> bool foo(T) { return false; };
804 bool x = [[foo]](42);
805 )cpp";
806 EXPECT_DECLS("DeclRefExpr",
807 {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
808 {"bool foo(T)", Rel::TemplatePattern});
809
810 Code = R"cpp(
811 // Explicit specialization.
812 template<typename T> bool foo(T) { return false; };
813 template<> bool foo<int>(int) { return false; };
814 bool x = [[foo]](42);
815 )cpp";
816 EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");
817}
818
819TEST_F(TargetDeclTest, VariableTemplate) {
820 // Pretty-printer doesn't do a very good job of variable templates :-(
821 Code = R"cpp(
822 // Implicit specialization.
823 template<typename T> int foo;
824 int x = [[foo]]<char>;
825 )cpp";
826 EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},
827 {"int foo", Rel::TemplatePattern});
828
829 Code = R"cpp(
830 // Explicit specialization.
831 template<typename T> int foo;
832 template <> bool foo<char>;
833 int x = [[foo]]<char>;
834 )cpp";
835 EXPECT_DECLS("DeclRefExpr", "bool foo");
836
837 Code = R"cpp(
838 // Partial specialization.
839 template<typename T> int foo;
840 template<typename T> bool foo<T*>;
841 bool x = [[foo]]<char*>;
842 )cpp";
843 EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},
844 {"bool foo", Rel::TemplatePattern});
845}
846
847TEST_F(TargetDeclTest, TypeAliasTemplate) {
848 Code = R"cpp(
849 template<typename T, int X> class SmallVector {};
850 template<typename U> using TinyVector = SmallVector<U, 1>;
851 [[TinyVector<int>]] X;
852 )cpp";
853 EXPECT_DECLS("TemplateSpecializationTypeLoc",
854 {"template<> class SmallVector<int, 1>",
855 Rel::TemplateInstantiation | Rel::Underlying},
856 {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
857 {"using TinyVector = SmallVector<U, 1>",
858 Rel::Alias | Rel::TemplatePattern});
859}
860
861TEST_F(TargetDeclTest, BuiltinTemplates) {
862 Code = R"cpp(
863 template <class T, T... Index> struct integer_sequence {};
864 [[__make_integer_seq]]<integer_sequence, int, 3> X;
865 )cpp";
867 "TemplateSpecializationTypeLoc",
868 {"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
869 {"template<> struct integer_sequence<int, <0, 1, 2>>",
870 Rel::TemplateInstantiation | Rel::Underlying});
871
872 // Dependent context.
873 Code = R"cpp(
874 template <class T, T... Index> struct integer_sequence;
875
876 template <class T, int N>
877 using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
878 )cpp";
879 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
880
881 Code = R"cpp(
882 template <int N, class... Pack>
883 using type_pack_element = [[__type_pack_element]]<N, Pack...>;
884 )cpp";
885 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
886
887 Code = R"cpp(
888 template <template <class...> class Templ, class... Types>
889 using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;
890 )cpp";
891 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
892
893 Code = R"cpp(
894 template <template <class...> class Templ, class... Types>
895 using sort_types = Templ<[[__builtin_sort_pack]]<Types...>...>;
896 )cpp";
897 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
898}
899
900TEST_F(TargetDeclTest, MemberOfTemplate) {
901 Code = R"cpp(
902 template <typename T> struct Foo {
903 int x(T);
904 };
905 int y = Foo<int>().[[x]](42);
906 )cpp";
907 EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},
908 {"int x(T)", Rel::TemplatePattern});
909
910 Code = R"cpp(
911 template <typename T> struct Foo {
912 template <typename U>
913 int x(T, U);
914 };
915 int y = Foo<char>().[[x]]('c', 42);
916 )cpp";
917 EXPECT_DECLS("MemberExpr",
918 {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
919 {"int x(T, U)", Rel::TemplatePattern});
920}
921
922TEST_F(TargetDeclTest, Lambda) {
923 Code = R"cpp(
924 void foo(int x = 42) {
925 auto l = [ [[x]] ]{ return x + 1; };
926 };
927 )cpp";
928 EXPECT_DECLS("DeclRefExpr", "int x = 42");
929
930 // It seems like this should refer to another var, with the outer param being
931 // an underlying decl. But it doesn't seem to exist.
932 Code = R"cpp(
933 void foo(int x = 42) {
934 auto l = [x]{ return [[x]] + 1; };
935 };
936 )cpp";
937 EXPECT_DECLS("DeclRefExpr", "int x = 42");
938
939 Code = R"cpp(
940 void foo() {
941 auto l = [x = 1]{ return [[x]] + 1; };
942 };
943 )cpp";
944 // FIXME: why both auto and int?
945 EXPECT_DECLS("DeclRefExpr", "auto int x = 1");
946}
947
948TEST_F(TargetDeclTest, OverloadExpr) {
949 Flags.push_back("--target=x86_64-pc-linux-gnu");
950
951 Code = R"cpp(
952 void func(int*);
953 void func(char*);
954
955 template <class T>
956 void foo(T t) {
957 [[func]](t);
958 };
959 )cpp";
960 EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");
961
962 Code = R"cpp(
963 struct X {
964 void func(int*);
965 void func(char*);
966 };
967
968 template <class T>
969 void foo(X x, T t) {
970 x.[[func]](t);
971 };
972 )cpp";
973 EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");
974
975 Code = R"cpp(
976 struct X {
977 static void *operator new(unsigned long);
978 };
979 auto* k = [[new]] X();
980 )cpp";
981 EXPECT_DECLS("CXXNewExpr", "static void *operator new(unsigned long)");
982 Code = R"cpp(
983 void *operator new(unsigned long);
984 auto* k = [[new]] int();
985 )cpp";
986 EXPECT_DECLS("CXXNewExpr", "void *operator new(unsigned long)");
987
988 Code = R"cpp(
989 struct X {
990 static void operator delete(void *) noexcept;
991 };
992 void k(X* x) {
993 [[delete]] x;
994 }
995 )cpp";
996 EXPECT_DECLS("CXXDeleteExpr", "static void operator delete(void *) noexcept");
997 Code = R"cpp(
998 void operator delete(void *) noexcept;
999 void k(int* x) {
1000 [[delete]] x;
1001 }
1002 )cpp";
1003 // Sized deallocation is enabled by default in C++14 onwards.
1004 EXPECT_DECLS("CXXDeleteExpr",
1005 "void operator delete(void *, __size_t) noexcept");
1006}
1007
1008TEST_F(TargetDeclTest, DependentExprs) {
1009 Flags.push_back("--std=c++20");
1010
1011 // Heuristic resolution of method of dependent field
1012 Code = R"cpp(
1013 struct A { void foo() {} };
1014 template <typename T>
1015 struct B {
1016 A a;
1017 void bar() {
1018 this->a.[[foo]]();
1019 }
1020 };
1021 )cpp";
1022 EXPECT_DECLS("MemberExpr", "void foo()");
1023
1024 // Similar to above but base expression involves a function call.
1025 Code = R"cpp(
1026 struct A {
1027 void foo() {}
1028 };
1029 struct B {
1030 A getA();
1031 };
1032 template <typename T>
1033 struct C {
1034 B c;
1035 void bar() {
1036 this->c.getA().[[foo]]();
1037 }
1038 };
1039 )cpp";
1040 EXPECT_DECLS("MemberExpr", "void foo()");
1041
1042 // Similar to above but uses a function pointer.
1043 Code = R"cpp(
1044 struct A {
1045 void foo() {}
1046 };
1047 struct B {
1048 using FPtr = A(*)();
1049 FPtr fptr;
1050 };
1051 template <typename T>
1052 struct C {
1053 B c;
1054 void bar() {
1055 this->c.fptr().[[foo]]();
1056 }
1057 };
1058 )cpp";
1059 EXPECT_DECLS("MemberExpr", "void foo()");
1060
1061 // Base expression involves a member access into this.
1062 Code = R"cpp(
1063 struct Bar {
1064 int aaaa;
1065 };
1066 template <typename T> struct Foo {
1067 Bar func(int);
1068 void test() {
1069 func(1).[[aaaa]];
1070 }
1071 };
1072 )cpp";
1073 EXPECT_DECLS("CXXDependentScopeMemberExpr", "int aaaa");
1074
1075 Code = R"cpp(
1076 class Foo {
1077 public:
1078 static Foo k(int);
1079 template <typename T> T convert() const;
1080 };
1081 template <typename T>
1082 void test() {
1083 Foo::k(T()).template [[convert]]<T>();
1084 }
1085 )cpp";
1086 EXPECT_DECLS("CXXDependentScopeMemberExpr",
1087 "template <typename T> T convert() const");
1088
1089 Code = R"cpp(
1090 template <typename T>
1091 struct Waldo {
1092 void find();
1093 };
1094 template <typename T>
1095 using Wally = Waldo<T>;
1096 template <typename T>
1097 void foo(Wally<T> w) {
1098 w.[[find]]();
1099 }
1100 )cpp";
1101 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
1102
1103 Code = R"cpp(
1104 template <typename T>
1105 struct Waldo {
1106 void find();
1107 };
1108 template <typename T>
1109 struct MetaWaldo {
1110 using Type = Waldo<T>;
1111 };
1112 template <typename T>
1113 void foo(typename MetaWaldo<T>::Type w) {
1114 w.[[find]]();
1115 }
1116 )cpp";
1117 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
1118
1119 Code = R"cpp(
1120 struct Waldo {
1121 void find();
1122 };
1123 template <typename T>
1124 using Wally = Waldo;
1125 template <typename>
1126 struct S : Wally<int> {
1127 void Foo() { this->[[find]](); }
1128 };
1129 )cpp";
1130 EXPECT_DECLS("MemberExpr", "void find()");
1131
1132 // Base expression is the type of a non-type template parameter
1133 // which is deduced using CTAD.
1134 Code = R"cpp(
1135 template <int N>
1136 struct Waldo {
1137 const int found = N;
1138 };
1139
1140 template <Waldo W>
1141 int test() {
1142 return W.[[found]];
1143 }
1144 )cpp";
1145 EXPECT_DECLS("CXXDependentScopeMemberExpr", "const int found = N");
1146}
1147
1148TEST_F(TargetDeclTest, DependentTypes) {
1149 // Heuristic resolution of dependent type name
1150 Code = R"cpp(
1151 template <typename>
1152 struct A { struct B {}; };
1153
1154 template <typename T>
1155 void foo(typename A<T>::[[B]]);
1156 )cpp";
1157 EXPECT_DECLS("DependentNameTypeLoc", "struct B");
1158
1159 // Heuristic resolution of dependent type name within a NestedNameSpecifierLoc
1160 Code = R"cpp(
1161 template <typename>
1162 struct A { struct B { struct C {}; }; };
1163
1164 template <typename T>
1165 void foo(typename A<T>::[[B]]::C);
1166 )cpp";
1167 EXPECT_DECLS("DependentNameTypeLoc", "struct B");
1168
1169 // Heuristic resolution of dependent type name whose qualifier is also
1170 // dependent
1171 Code = R"cpp(
1172 template <typename>
1173 struct A { struct B { struct C {}; }; };
1174
1175 template <typename T>
1176 void foo(typename A<T>::B::[[C]]);
1177 )cpp";
1178 EXPECT_DECLS("DependentNameTypeLoc", "struct C");
1179
1180 // Heuristic resolution of dependent template name
1181 Code = R"cpp(
1182 template <typename>
1183 struct A {
1184 template <typename> struct B {};
1185 };
1186
1187 template <typename T>
1188 void foo(typename A<T>::template [[B]]<int>);
1189 )cpp";
1190 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");
1191
1192 // Dependent name with recursive definition. We don't expect a
1193 // result, but we shouldn't get into a stack overflow either.
1194 Code = R"cpp(
1195 template <int N>
1196 struct waldo {
1197 typedef typename waldo<N - 1>::type::[[next]] type;
1198 };
1199 )cpp";
1200 EXPECT_DECLS("DependentNameTypeLoc", );
1201
1202 // Similar to above but using mutually recursive templates.
1203 Code = R"cpp(
1204 template <int N>
1205 struct odd;
1206
1207 template <int N>
1208 struct even {
1209 using type = typename odd<N - 1>::type::next;
1210 };
1211
1212 template <int N>
1213 struct odd {
1214 using type = typename even<N - 1>::type::[[next]];
1215 };
1216 )cpp";
1217 EXPECT_DECLS("DependentNameTypeLoc", );
1218}
1219
1220TEST_F(TargetDeclTest, TypedefCascade) {
1221 Code = R"cpp(
1222 struct C {
1223 using type = int;
1224 };
1225 struct B {
1226 using type = C::type;
1227 };
1228 struct A {
1229 using type = B::type;
1230 };
1231 A::[[type]] waldo;
1232 )cpp";
1233 EXPECT_DECLS("TypedefTypeLoc",
1234 {"using type = int", Rel::Alias | Rel::Underlying},
1235 {"using type = C::type", Rel::Alias | Rel::Underlying},
1236 {"using type = B::type", Rel::Alias});
1237}
1238
1239TEST_F(TargetDeclTest, RecursiveTemplate) {
1240 Flags.push_back("-std=c++20"); // the test case uses concepts
1241
1242 Code = R"cpp(
1243 template <typename T>
1244 concept Leaf = false;
1245
1246 template <typename Tree>
1247 struct descend_left {
1248 using type = typename descend_left<typename Tree::left>::[[type]];
1249 };
1250
1251 template <Leaf Tree>
1252 struct descend_left<Tree> {
1253 using type = typename Tree::value;
1254 };
1255 )cpp";
1256 EXPECT_DECLS("DependentNameTypeLoc",
1257 {"using type = typename descend_left<typename Tree::left>::type",
1258 Rel::Alias | Rel::Underlying});
1259}
1260
1261TEST_F(TargetDeclTest, ObjC) {
1262 Flags = {"-xobjective-c"};
1263 Code = R"cpp(
1264 @interface Foo {}
1265 -(void)bar;
1266 @end
1267 void test(Foo *f) {
1268 [f [[bar]] ];
1269 }
1270 )cpp";
1271 EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");
1272
1273 Code = R"cpp(
1274 @interface Foo { @public int bar; }
1275 @end
1276 int test(Foo *f) {
1277 return [[f->bar]];
1278 }
1279 )cpp";
1280 EXPECT_DECLS("ObjCIvarRefExpr", "int bar");
1281
1282 Code = R"cpp(
1283 @interface Foo {}
1284 -(int) x;
1285 -(void) setX:(int)x;
1286 @end
1287 void test(Foo *f) {
1288 [[f.x]] = 42;
1289 }
1290 )cpp";
1291 EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");
1292
1293 Code = R"cpp(
1294 @interface I {}
1295 @property(retain) I* x;
1296 @property(retain) I* y;
1297 @end
1298 void test(I *f) {
1299 [[f.x]].y = 0;
1300 }
1301 )cpp";
1302 EXPECT_DECLS("ObjCPropertyRefExpr",
1303 "@property(atomic, retain, readwrite) I *x");
1304
1305 Code = R"cpp(
1306 @interface MYObject
1307 @end
1308 @interface Interface
1309 @property(retain) [[MYObject]] *x;
1310 @end
1311 )cpp";
1312 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject");
1313
1314 Code = R"cpp(
1315 @interface MYObject2
1316 @end
1317 @interface Interface
1318 @property(retain, nonnull) [[MYObject2]] *x;
1319 @end
1320 )cpp";
1321 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject2");
1322
1323 Code = R"cpp(
1324 @protocol Foo
1325 @end
1326 id test() {
1327 return [[@protocol(Foo)]];
1328 }
1329 )cpp";
1330 EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");
1331
1332 Code = R"cpp(
1333 @interface Foo
1334 @end
1335 void test([[Foo]] *p);
1336 )cpp";
1337 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1338
1339 Code = R"cpp(// Don't consider implicit interface as the target.
1340 @implementation [[Implicit]]
1341 @end
1342 )cpp";
1343 EXPECT_DECLS("ObjCImplementationDecl", "@implementation Implicit");
1344
1345 Code = R"cpp(
1346 @interface Foo
1347 @end
1348 @implementation [[Foo]]
1349 @end
1350 )cpp";
1351 EXPECT_DECLS("ObjCImplementationDecl", "@interface Foo");
1352
1353 Code = R"cpp(
1354 @interface Foo
1355 @end
1356 @interface Foo (Ext)
1357 @end
1358 @implementation [[Foo]] (Ext)
1359 @end
1360 )cpp";
1361 EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");
1362
1363 Code = R"cpp(
1364 @interface Foo
1365 @end
1366 @interface Foo (Ext)
1367 @end
1368 @implementation Foo ([[Ext]])
1369 @end
1370 )cpp";
1371 EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");
1372
1373 Code = R"cpp(
1374 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1375 )cpp";
1376 EXPECT_DECLS("ParmVarDecl", "id p");
1377
1378 Code = R"cpp(
1379 @class C;
1380 @protocol Foo
1381 @end
1382 void test([[C]]<Foo> *p);
1383 )cpp";
1384 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@class C;");
1385
1386 Code = R"cpp(
1387 @class C;
1388 @protocol Foo
1389 @end
1390 void test(C<[[Foo]]> *p);
1391 )cpp";
1392 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1393
1394 Code = R"cpp(
1395 @class C;
1396 @protocol Foo
1397 @end
1398 @protocol Bar
1399 @end
1400 void test(C<[[Foo]], Bar> *p);
1401 )cpp";
1402 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1403
1404 Code = R"cpp(
1405 @class C;
1406 @protocol Foo
1407 @end
1408 @protocol Bar
1409 @end
1410 void test(C<Foo, [[Bar]]> *p);
1411 )cpp";
1412 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Bar");
1413
1414 Code = R"cpp(
1415 @interface Foo
1416 + (id)sharedInstance;
1417 @end
1418 @implementation Foo
1419 + (id)sharedInstance { return 0; }
1420 @end
1421 void test() {
1422 id value = [[Foo]].sharedInstance;
1423 }
1424 )cpp";
1425 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1426
1427 Code = R"cpp(
1428 @interface Foo
1429 + (id)sharedInstance;
1430 @end
1431 @implementation Foo
1432 + (id)sharedInstance { return 0; }
1433 @end
1434 void test() {
1435 id value = Foo.[[sharedInstance]];
1436 }
1437 )cpp";
1438 EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
1439
1440 Code = R"cpp(
1441 @interface Foo
1442 + ([[id]])sharedInstance;
1443 @end
1444 )cpp";
1445 EXPECT_DECLS("TypedefTypeLoc", );
1446
1447 Code = R"cpp(
1448 @interface Foo
1449 + ([[instancetype]])sharedInstance;
1450 @end
1451 )cpp";
1452 EXPECT_DECLS("TypedefTypeLoc", );
1453}
1454
1455class FindExplicitReferencesTest : public ::testing::Test {
1456protected:
1457 struct AllRefs {
1458 std::string AnnotatedCode;
1459 std::string DumpedReferences;
1460 };
1461
1462 TestTU newTU(llvm::StringRef Code) {
1463 TestTU TU;
1464 TU.Code = std::string(Code);
1465
1466 // FIXME: Auto-completion in a template requires disabling delayed template
1467 // parsing.
1468 TU.ExtraArgs.push_back("-std=c++20");
1469 TU.ExtraArgs.push_back("-xobjective-c++");
1470
1471 return TU;
1472 }
1473
1474 AllRefs annotatedReferences(llvm::StringRef Code, ParsedAST &AST,
1475 std::vector<ReferenceLoc> Refs) {
1476 auto &SM = AST.getSourceManager();
1477 llvm::stable_sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
1478 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1479 });
1480
1481 std::string AnnotatedCode;
1482 unsigned NextCodeChar = 0;
1483 for (unsigned I = 0; I < Refs.size(); ++I) {
1484 auto &R = Refs[I];
1485
1486 SourceLocation Pos = R.NameLoc;
1487 assert(Pos.isValid());
1488 if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.
1489 Pos = SM.getExpansionLoc(Pos);
1490 assert(Pos.isFileID());
1491
1492 FileID File;
1493 unsigned Offset;
1494 std::tie(File, Offset) = SM.getDecomposedLoc(Pos);
1495 if (File == SM.getMainFileID()) {
1496 // Print the reference in a source code.
1497 assert(NextCodeChar <= Offset);
1498 AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
1499 AnnotatedCode += "$" + std::to_string(I) + "^";
1500
1501 NextCodeChar = Offset;
1502 }
1503 }
1504 AnnotatedCode += Code.substr(NextCodeChar);
1505
1506 std::string DumpedReferences;
1507 for (unsigned I = 0; I < Refs.size(); ++I)
1508 DumpedReferences += std::string(llvm::formatv("{0}: {1}\n", I, Refs[I]));
1509
1510 return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
1511 }
1512
1513 /// Parses \p Code, and annotates its body with results of
1514 /// findExplicitReferences on all top level decls.
1515 /// See actual tests for examples of annotation format.
1516 AllRefs annotateAllReferences(llvm::StringRef Code) {
1517 TestTU TU = newTU(Code);
1518 auto AST = TU.build();
1519
1520 std::vector<ReferenceLoc> Refs;
1521 for (auto *TopLevel : AST.getLocalTopLevelDecls())
1523 TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1524 AST.getHeuristicResolver());
1525 return annotatedReferences(Code, AST, std::move(Refs));
1526 }
1527
1528 /// Parses \p Code, finds function or namespace '::foo' and annotates its body
1529 /// with results of findExplicitReferences.
1530 /// See actual tests for examples of annotation format.
1531 AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
1532 TestTU TU = newTU(Code);
1533 auto AST = TU.build();
1534 auto *TestDecl = &findDecl(AST, "foo");
1535 if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1536 TestDecl = T->getTemplatedDecl();
1537
1538 std::vector<ReferenceLoc> Refs;
1539 if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1541 Func->getBody(),
1542 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1543 AST.getHeuristicResolver());
1544 else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1546 NS,
1547 [&Refs, &NS](ReferenceLoc R) {
1548 // Avoid adding the namespace foo decl to the results.
1549 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1550 return;
1551 Refs.push_back(std::move(R));
1552 },
1553 AST.getHeuristicResolver());
1554 else if (const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))
1556 OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1557 AST.getHeuristicResolver());
1558 else
1559 ADD_FAILURE() << "Failed to find ::foo decl for test";
1560
1561 return annotatedReferences(Code, AST, std::move(Refs));
1562 }
1563};
1564
1565TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
1566 std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
1567 {// Simple expressions.
1568 {R"cpp(
1569 int global;
1570 int func();
1571 void foo(int param) {
1572 $0^global = $1^param + $2^func();
1573 }
1574 )cpp",
1575 "0: targets = {global}\n"
1576 "1: targets = {param}\n"
1577 "2: targets = {func}\n"},
1578 {R"cpp(
1579 struct X { int a; };
1580 void foo(X x) {
1581 $0^x.$1^a = 10;
1582 }
1583 )cpp",
1584 "0: targets = {x}\n"
1585 "1: targets = {X::a}\n"},
1586 {R"cpp(
1587 // error-ok: testing with broken code
1588 int bar();
1589 int foo() {
1590 return $0^bar() + $1^bar(42);
1591 }
1592 )cpp",
1593 "0: targets = {bar}\n"
1594 "1: targets = {bar}\n"},
1595 // Namespaces and aliases.
1596 {R"cpp(
1597 namespace ns {}
1598 namespace alias = ns;
1599 void foo() {
1600 using namespace $0^ns;
1601 using namespace $1^alias;
1602 }
1603 )cpp",
1604 "0: targets = {ns}\n"
1605 "1: targets = {alias}\n"},
1606 // Using declarations.
1607 {R"cpp(
1608 namespace ns { int global; }
1609 void foo() {
1610 using $0^ns::$1^global;
1611 }
1612 )cpp",
1613 "0: targets = {ns}\n"
1614 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1615 // Using enum declarations.
1616 {R"cpp(
1617 namespace ns { enum class A {}; }
1618 void foo() {
1619 using enum $0^ns::$1^A;
1620 }
1621 )cpp",
1622 "0: targets = {ns}\n"
1623 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1624 // Simple types.
1625 {R"cpp(
1626 struct Struct { int a; };
1627 using Typedef = int;
1628 void foo() {
1629 $0^Struct $1^x;
1630 $2^Typedef $3^y;
1631 static_cast<$4^Struct*>(0);
1632 }
1633 )cpp",
1634 "0: targets = {Struct}\n"
1635 "1: targets = {x}, decl\n"
1636 "2: targets = {Typedef}\n"
1637 "3: targets = {y}, decl\n"
1638 "4: targets = {Struct}\n"},
1639 // Name qualifiers.
1640 {R"cpp(
1641 namespace a { namespace b { struct S { typedef int type; }; } }
1642 void foo() {
1643 $0^a::$1^b::$2^S $3^x;
1644 using namespace $4^a::$5^b;
1645 $6^S::$7^type $8^y;
1646 }
1647 )cpp",
1648 "0: targets = {a}\n"
1649 "1: targets = {a::b}, qualifier = 'a::'\n"
1650 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1651 "3: targets = {x}, decl\n"
1652 "4: targets = {a}\n"
1653 "5: targets = {a::b}, qualifier = 'a::'\n"
1654 "6: targets = {a::b::S}\n"
1655 "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
1656 "8: targets = {y}, decl\n"},
1657 {R"cpp(
1658 void foo() {
1659 $0^ten: // PRINT "HELLO WORLD!"
1660 goto $1^ten;
1661 }
1662 )cpp",
1663 "0: targets = {ten}, decl\n"
1664 "1: targets = {ten}\n"},
1665 // Simple templates.
1666 {R"cpp(
1667 template <class T> struct vector { using value_type = T; };
1668 template <> struct vector<bool> { using value_type = bool; };
1669 void foo() {
1670 $0^vector<int> $1^vi;
1671 $2^vector<bool> $3^vb;
1672 }
1673 )cpp",
1674 "0: targets = {vector<int>}\n"
1675 "1: targets = {vi}, decl\n"
1676 "2: targets = {vector<bool>}\n"
1677 "3: targets = {vb}, decl\n"},
1678 // Template type aliases.
1679 {R"cpp(
1680 template <class T> struct vector { using value_type = T; };
1681 template <> struct vector<bool> { using value_type = bool; };
1682 template <class T> using valias = vector<T>;
1683 void foo() {
1684 $0^valias<int> $1^vi;
1685 $2^valias<bool> $3^vb;
1686 }
1687 )cpp",
1688 "0: targets = {valias}\n"
1689 "1: targets = {vi}, decl\n"
1690 "2: targets = {valias}\n"
1691 "3: targets = {vb}, decl\n"},
1692 // Injected class name.
1693 {R"cpp(
1694 namespace foo {
1695 template <typename $0^T>
1696 class $1^Bar {
1697 ~$2^Bar();
1698 void $3^f($4^Bar);
1699 };
1700 }
1701 )cpp",
1702 "0: targets = {foo::Bar::T}, decl\n"
1703 "1: targets = {foo::Bar}, decl\n"
1704 "2: targets = {foo::Bar}\n"
1705 "3: targets = {foo::Bar::f}, decl\n"
1706 "4: targets = {foo::Bar}\n"},
1707 // MemberExpr should know their using declaration.
1708 {R"cpp(
1709 struct X { void func(int); };
1710 struct Y : X {
1711 using X::func;
1712 };
1713 void foo(Y y) {
1714 $0^y.$1^func(1);
1715 }
1716 )cpp",
1717 "0: targets = {y}\n"
1718 "1: targets = {Y::func}\n"},
1719 // DeclRefExpr should know their using declaration.
1720 {R"cpp(
1721 namespace ns { void bar(int); }
1722 using ns::bar;
1723
1724 void foo() {
1725 $0^bar(10);
1726 }
1727 )cpp",
1728 "0: targets = {bar}\n"},
1729 // References from a macro.
1730 {R"cpp(
1731 #define FOO a
1732 #define BAR b
1733
1734 void foo(int a, int b) {
1735 $0^FOO+$1^BAR;
1736 }
1737 )cpp",
1738 "0: targets = {a}\n"
1739 "1: targets = {b}\n"},
1740 // No references from implicit nodes.
1741 {R"cpp(
1742 struct vector {
1743 int *begin();
1744 int *end();
1745 };
1746
1747 void foo() {
1748 for (int $0^x : $1^vector()) {
1749 $2^x = 10;
1750 }
1751 }
1752 )cpp",
1753 "0: targets = {x}, decl\n"
1754 "1: targets = {vector}\n"
1755 "2: targets = {x}\n"},
1756 // Handle UnresolvedLookupExpr.
1757 {R"cpp(
1758 namespace ns1 { void func(char*); }
1759 namespace ns2 { void func(int*); }
1760 using namespace ns1;
1761 using namespace ns2;
1762
1763 template <class T>
1764 void foo(T t) {
1765 $0^func($1^t);
1766 }
1767 )cpp",
1768 "0: targets = {ns1::func, ns2::func}\n"
1769 "1: targets = {t}\n"},
1770 // Handle UnresolvedMemberExpr.
1771 {R"cpp(
1772 struct X {
1773 void func(char*);
1774 void func(int*);
1775 };
1776
1777 template <class T>
1778 void foo(X x, T t) {
1779 $0^x.$1^func($2^t);
1780 }
1781 )cpp",
1782 "0: targets = {x}\n"
1783 "1: targets = {X::func, X::func}\n"
1784 "2: targets = {t}\n"},
1785 // Handle DependentScopeDeclRefExpr.
1786 {R"cpp(
1787 template <class T>
1788 struct S {
1789 static int value;
1790 };
1791
1792 template <class T>
1793 void foo() {
1794 $0^S<$1^T>::$2^value;
1795 }
1796 )cpp",
1797 "0: targets = {S}\n"
1798 "1: targets = {T}\n"
1799 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1800 // Handle CXXDependentScopeMemberExpr.
1801 {R"cpp(
1802 template <class T>
1803 struct S {
1804 int value;
1805 };
1806
1807 template <class T>
1808 void foo(S<T> t) {
1809 $0^t.$1^value;
1810 }
1811 )cpp",
1812 "0: targets = {t}\n"
1813 "1: targets = {S::value}\n"},
1814 // Type template parameters.
1815 {R"cpp(
1816 template <class T>
1817 void foo() {
1818 static_cast<$0^T>(0);
1819 $1^T();
1820 $2^T $3^t;
1821 }
1822 )cpp",
1823 "0: targets = {T}\n"
1824 "1: targets = {T}\n"
1825 "2: targets = {T}\n"
1826 "3: targets = {t}, decl\n"},
1827 // Non-type template parameters.
1828 {R"cpp(
1829 template <int I>
1830 void foo() {
1831 int $0^x = $1^I;
1832 }
1833 )cpp",
1834 "0: targets = {x}, decl\n"
1835 "1: targets = {I}\n"},
1836 // Template template parameters.
1837 {R"cpp(
1838 template <class T> struct vector {};
1839
1840 template <template<class> class TT, template<class> class ...TP>
1841 void foo() {
1842 $0^TT<int> $1^x;
1843 $2^foo<$3^TT>();
1844 $4^foo<$5^vector>();
1845 $6^foo<$7^TP...>();
1846 }
1847 )cpp",
1848 "0: targets = {TT}\n"
1849 "1: targets = {x}, decl\n"
1850 "2: targets = {foo}\n"
1851 "3: targets = {TT}\n"
1852 "4: targets = {foo}\n"
1853 "5: targets = {vector}\n"
1854 "6: targets = {foo}\n"
1855 "7: targets = {TP}\n"},
1856 // Non-type template parameters with declarations.
1857 {R"cpp(
1858 int func();
1859 template <int(*)()> struct wrapper {};
1860
1861 template <int(*FuncParam)()>
1862 void foo() {
1863 $0^wrapper<$1^func> $2^w;
1864 $3^FuncParam();
1865 }
1866 )cpp",
1867 "0: targets = {wrapper<&func>}\n"
1868 "1: targets = {func}\n"
1869 "2: targets = {w}, decl\n"
1870 "3: targets = {FuncParam}\n"},
1871 // declaration references.
1872 {R"cpp(
1873 namespace ns {}
1874 class S {};
1875 void foo() {
1876 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1877 int $4^Var;
1878 enum $5^E { $6^ABC };
1879 typedef int $7^INT;
1880 using $8^INT2 = int;
1881 namespace $9^NS = $10^ns;
1882 }
1883 )cpp",
1884 "0: targets = {Foo}, decl\n"
1885 "1: targets = {foo()::Foo::Foo}, decl\n"
1886 "2: targets = {Foo}\n"
1887 "3: targets = {foo()::Foo::field}, decl\n"
1888 "4: targets = {Var}, decl\n"
1889 "5: targets = {E}, decl\n"
1890 "6: targets = {foo()::ABC}, decl\n"
1891 "7: targets = {INT}, decl\n"
1892 "8: targets = {INT2}, decl\n"
1893 "9: targets = {NS}, decl\n"
1894 "10: targets = {ns}\n"},
1895 // User-defined conversion operator.
1896 {R"cpp(
1897 void foo() {
1898 class $0^Bar {};
1899 class $1^Foo {
1900 public:
1901 // FIXME: This should have only one reference to Bar.
1902 $2^operator $3^$4^Bar();
1903 };
1904
1905 $5^Foo $6^f;
1906 $7^f.$8^operator $9^Bar();
1907 }
1908 )cpp",
1909 "0: targets = {Bar}, decl\n"
1910 "1: targets = {Foo}, decl\n"
1911 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1912 "3: targets = {Bar}\n"
1913 "4: targets = {Bar}\n"
1914 "5: targets = {Foo}\n"
1915 "6: targets = {f}, decl\n"
1916 "7: targets = {f}\n"
1917 "8: targets = {foo()::Foo::operator Bar}\n"
1918 "9: targets = {Bar}\n"},
1919 // Destructor.
1920 {R"cpp(
1921 void foo() {
1922 class $0^Foo {
1923 public:
1924 ~$1^Foo() {}
1925
1926 void $2^destructMe() {
1927 this->~$3^Foo();
1928 }
1929 };
1930
1931 $4^Foo $5^f;
1932 $6^f.~ /*...*/ $7^Foo();
1933 }
1934 )cpp",
1935 "0: targets = {Foo}, decl\n"
1936 // FIXME: It's better to target destructor's FunctionDecl instead of
1937 // the type itself (similar to constructor).
1938 "1: targets = {Foo}\n"
1939 "2: targets = {foo()::Foo::destructMe}, decl\n"
1940 "3: targets = {Foo}\n"
1941 "4: targets = {Foo}\n"
1942 "5: targets = {f}, decl\n"
1943 "6: targets = {f}\n"
1944 "7: targets = {Foo}\n"},
1945 // cxx constructor initializer.
1946 {R"cpp(
1947 class Base {};
1948 void foo() {
1949 // member initializer
1950 class $0^X {
1951 int $1^abc;
1952 $2^X(): $3^abc() {}
1953 };
1954 // base initializer
1955 class $4^Derived : public $5^Base {
1956 $6^Base $7^B;
1957 $8^Derived() : $9^Base() {}
1958 };
1959 // delegating initializer
1960 class $10^Foo {
1961 $11^Foo(int);
1962 $12^Foo(): $13^Foo(111) {}
1963 };
1964 }
1965 )cpp",
1966 "0: targets = {X}, decl\n"
1967 "1: targets = {foo()::X::abc}, decl\n"
1968 "2: targets = {foo()::X::X}, decl\n"
1969 "3: targets = {foo()::X::abc}\n"
1970 "4: targets = {Derived}, decl\n"
1971 "5: targets = {Base}\n"
1972 "6: targets = {Base}\n"
1973 "7: targets = {foo()::Derived::B}, decl\n"
1974 "8: targets = {foo()::Derived::Derived}, decl\n"
1975 "9: targets = {Base}\n"
1976 "10: targets = {Foo}, decl\n"
1977 "11: targets = {foo()::Foo::Foo}, decl\n"
1978 "12: targets = {foo()::Foo::Foo}, decl\n"
1979 "13: targets = {Foo}\n"},
1980 // Anonymous entities should not be reported.
1981 {
1982 R"cpp(
1983 void foo() {
1984 $0^class {} $1^x;
1985 int (*$2^fptr)(int $3^a, int) = nullptr;
1986 }
1987 )cpp",
1988 "0: targets = {(unnamed class)}\n"
1989 "1: targets = {x}, decl\n"
1990 "2: targets = {fptr}, decl\n"
1991 "3: targets = {a}, decl\n"},
1992 // Namespace aliases should be handled properly.
1993 {
1994 R"cpp(
1995 namespace ns { struct Type {}; }
1996 namespace alias = ns;
1997 namespace rec_alias = alias;
1998
1999 void foo() {
2000 $0^ns::$1^Type $2^a;
2001 $3^alias::$4^Type $5^b;
2002 $6^rec_alias::$7^Type $8^c;
2003 }
2004 )cpp",
2005 "0: targets = {ns}\n"
2006 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
2007 "2: targets = {a}, decl\n"
2008 "3: targets = {alias}\n"
2009 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
2010 "5: targets = {b}, decl\n"
2011 "6: targets = {rec_alias}\n"
2012 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
2013 "8: targets = {c}, decl\n"},
2014 // Handle SizeOfPackExpr.
2015 {
2016 R"cpp(
2017 template <typename... E>
2018 void foo() {
2019 constexpr int $0^size = sizeof...($1^E);
2020 };
2021 )cpp",
2022 "0: targets = {size}, decl\n"
2023 "1: targets = {E}\n"},
2024 // Class template argument deduction
2025 {
2026 R"cpp(
2027 template <typename T>
2028 struct Test {
2029 Test(T);
2030 };
2031 void foo() {
2032 $0^Test $1^a(5);
2033 }
2034 )cpp",
2035 "0: targets = {Test}\n"
2036 "1: targets = {a}, decl\n"},
2037 // Templates
2038 {R"cpp(
2039 namespace foo {
2040 template <typename $0^T>
2041 class $1^Bar {};
2042 }
2043 )cpp",
2044 "0: targets = {foo::Bar::T}, decl\n"
2045 "1: targets = {foo::Bar}, decl\n"},
2046 // Templates
2047 {R"cpp(
2048 namespace foo {
2049 template <typename $0^T>
2050 void $1^func();
2051 }
2052 )cpp",
2053 "0: targets = {T}, decl\n"
2054 "1: targets = {foo::func}, decl\n"},
2055 // Templates
2056 {R"cpp(
2057 namespace foo {
2058 template <typename $0^T>
2059 $1^T $2^x;
2060 }
2061 )cpp",
2062 "0: targets = {foo::T}, decl\n"
2063 "1: targets = {foo::T}\n"
2064 "2: targets = {foo::x}, decl\n"},
2065 // Templates
2066 {R"cpp(
2067 template<typename T> class vector {};
2068 namespace foo {
2069 template <typename $0^T>
2070 using $1^V = $2^vector<$3^T>;
2071 }
2072 )cpp",
2073 "0: targets = {foo::T}, decl\n"
2074 "1: targets = {foo::V}, decl\n"
2075 "2: targets = {vector}\n"
2076 "3: targets = {foo::T}\n"},
2077 // Concept
2078 {
2079 R"cpp(
2080 template <typename T>
2081 concept Drawable = requires (T t) { t.draw(); };
2082
2083 namespace foo {
2084 template <typename $0^T> requires $1^Drawable<$2^T>
2085 void $3^bar($4^T $5^t) {
2086 $6^t.$7^draw();
2087 }
2088 }
2089 )cpp",
2090 "0: targets = {T}, decl\n"
2091 "1: targets = {Drawable}\n"
2092 "2: targets = {T}\n"
2093 "3: targets = {foo::bar}, decl\n"
2094 "4: targets = {T}\n"
2095 "5: targets = {t}, decl\n"
2096 "6: targets = {t}\n"
2097 "7: targets = {}\n"},
2098 // Objective-C: instance variables
2099 {
2100 R"cpp(
2101 @interface I {
2102 @public
2103 I *_z;
2104 }
2105 @end
2106 I *f;
2107 void foo() {
2108 $0^f->$1^_z = 0;
2109 }
2110 )cpp",
2111 "0: targets = {f}\n"
2112 "1: targets = {I::_z}\n"},
2113 // Objective-C: properties
2114 {
2115 R"cpp(
2116 @interface I {}
2117 @property(retain) I* x;
2118 @property(retain) I* y;
2119 @end
2120 I *f;
2121 void foo() {
2122 $0^f.$1^x.$2^y = 0;
2123 }
2124 )cpp",
2125 "0: targets = {f}\n"
2126 "1: targets = {I::x}\n"
2127 "2: targets = {I::y}\n"},
2128 // Objective-C: implicit properties
2129 {
2130 R"cpp(
2131 @interface I {}
2132 -(I*)x;
2133 -(void)setY:(I*)y;
2134 @end
2135 I *f;
2136 void foo() {
2137 $0^f.$1^x.$2^y = 0;
2138 }
2139 )cpp",
2140 "0: targets = {f}\n"
2141 "1: targets = {I::x}\n"
2142 "2: targets = {I::setY:}\n"},
2143 // Objective-C: class properties
2144 {
2145 R"cpp(
2146 @interface I {}
2147 @property(class) I *x;
2148 @end
2149 id local;
2150 void foo() {
2151 $0^I.$1^x = 0;
2152 $2^local = $3^I.$4^x;
2153 }
2154 )cpp",
2155 "0: targets = {I}\n"
2156 "1: targets = {I::setX:}\n"
2157 "2: targets = {local}\n"
2158 "3: targets = {I}\n"
2159 "4: targets = {I::x}\n"},
2160 // Objective-C: implicit class properties
2161 {
2162 R"cpp(
2163 @interface I {}
2164 +(I*)x;
2165 +(void)setX:(I*)x;
2166 @end
2167 id local;
2168 void foo() {
2169 $0^I.$1^x = 0;
2170 $2^local = $3^I.$4^x;
2171 }
2172 )cpp",
2173 "0: targets = {I}\n"
2174 "1: targets = {I::setX:}\n"
2175 "2: targets = {local}\n"
2176 "3: targets = {I}\n"
2177 "4: targets = {I::x}\n"},
2178 {// Objective-C: methods
2179 R"cpp(
2180 @interface I
2181 -(void) a:(int)x b:(int)y;
2182 @end
2183 void foo(I *i) {
2184 [$0^i $1^a:1 b:2];
2185 }
2186 )cpp",
2187 "0: targets = {i}\n"
2188 "1: targets = {I::a:b:}\n"},
2189 {// Objective-C: protocols
2190 R"cpp(
2191 @interface I
2192 @end
2193 @protocol P
2194 @end
2195 void foo() {
2196 $0^I<$1^P> *$2^x;
2197 }
2198 )cpp",
2199 "0: targets = {I}\n"
2200 "1: targets = {P}\n"
2201 "2: targets = {x}, decl\n"},
2202
2203 // Designated initializers.
2204 {R"cpp(
2205 void foo() {
2206 struct $0^Foo {
2207 int $1^Bar;
2208 };
2209 $2^Foo $3^f { .$4^Bar = 42 };
2210 }
2211 )cpp",
2212 "0: targets = {Foo}, decl\n"
2213 "1: targets = {foo()::Foo::Bar}, decl\n"
2214 "2: targets = {Foo}\n"
2215 "3: targets = {f}, decl\n"
2216 "4: targets = {foo()::Foo::Bar}\n"},
2217 {R"cpp(
2218 void foo() {
2219 struct $0^Baz {
2220 int $1^Field;
2221 };
2222 struct $2^Bar {
2223 $3^Baz $4^Foo;
2224 };
2225 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
2226 }
2227 )cpp",
2228 "0: targets = {Baz}, decl\n"
2229 "1: targets = {foo()::Baz::Field}, decl\n"
2230 "2: targets = {Bar}, decl\n"
2231 "3: targets = {Baz}\n"
2232 "4: targets = {foo()::Bar::Foo}, decl\n"
2233 "5: targets = {Bar}\n"
2234 "6: targets = {bar}, decl\n"
2235 "7: targets = {foo()::Bar::Foo}\n"
2236 "8: targets = {foo()::Baz::Field}\n"},
2237 // offsetof
2238 {R"cpp(
2239 void foo() {
2240 struct $0^Foo { int $1^bar; };
2241 int $2^x = __builtin_offsetof($3^Foo, $4^bar);
2242 }
2243 )cpp",
2244 "0: targets = {Foo}, decl\n"
2245 "1: targets = {foo()::Foo::bar}, decl\n"
2246 "2: targets = {x}, decl\n"
2247 "3: targets = {Foo}\n"
2248 "4: targets = {foo()::Foo::bar}\n"},
2249 // offsetof with a nested field designator -- each component must
2250 // resolve to its own source position, not a shared one.
2251 {R"cpp(
2252 void foo() {
2253 struct $0^A {
2254 $1^struct { int $2^c; } $3^B;
2255 };
2256 int $4^x = __builtin_offsetof($5^A, $6^B.$7^c);
2257 }
2258 )cpp",
2259 "0: targets = {A}, decl\n"
2260 "1: targets = {foo()::A::(unnamed struct)}\n"
2261 "2: targets = {foo()::A::(unnamed struct)::c}, decl\n"
2262 "3: targets = {foo()::A::B}, decl\n"
2263 "4: targets = {x}, decl\n"
2264 "5: targets = {A}\n"
2265 "6: targets = {foo()::A::B}\n"
2266 "7: targets = {foo()::A::(unnamed struct)::c}\n"},
2267 // offsetof with an array-subscript component -- array indices are not
2268 // emitted as offsetof references (the subscript expression is still
2269 // visited independently).
2270 {R"cpp(
2271 void foo() {
2272 struct $0^A { int $1^arr[4]; };
2273 int $2^i = 0;
2274 int $3^x = __builtin_offsetof($4^A, $5^arr[$6^i]);
2275 }
2276 )cpp",
2277 "0: targets = {A}, decl\n"
2278 "1: targets = {foo()::A::arr}, decl\n"
2279 "2: targets = {i}, decl\n"
2280 "3: targets = {x}, decl\n"
2281 "4: targets = {A}\n"
2282 "5: targets = {foo()::A::arr}\n"
2283 "6: targets = {i}\n"},
2284 {R"cpp(
2285 template<typename T>
2286 void crash(T);
2287 template<typename T>
2288 void foo() {
2289 $0^crash({.$1^x = $2^T()});
2290 }
2291 )cpp",
2292 "0: targets = {crash}\n"
2293 "1: targets = {}\n"
2294 "2: targets = {T}\n"},
2295 // unknown template name should not crash.
2296 {R"cpp(
2297 template <template <typename> typename T>
2298 struct Base {};
2299 namespace foo {
2300 template <typename $0^T>
2301 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
2302 }
2303 )cpp",
2304 "0: targets = {foo::Derive::T}, decl\n"
2305 "1: targets = {foo::Derive}, decl\n"
2306 "2: targets = {Base}\n"
2307 "3: targets = {foo::Derive::T}\n"
2308 "4: targets = {}, qualifier = 'T::'\n"},
2309 // deduction guide
2310 {R"cpp(
2311 namespace foo {
2312 template <typename $0^T>
2313 struct $1^Test {
2314 template <typename $2^I>
2315 $3^Test($4^I);
2316 };
2317 template <typename $5^I>
2318 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
2319 }
2320 )cpp",
2321 "0: targets = {T}, decl\n"
2322 "1: targets = {foo::Test}, decl\n"
2323 "2: targets = {I}, decl\n"
2324 "3: targets = {foo::Test::Test<T>}, decl\n"
2325 "4: targets = {I}\n"
2326 "5: targets = {I}, decl\n"
2327 "6: targets = {foo::Test}\n"
2328 "7: targets = {I}\n"
2329 "8: targets = {foo::Test}\n"
2330 "9: targets = {I}\n"
2331 "10: targets = {}, qualifier = 'I::'\n"}};
2332
2333 for (const auto &C : Cases) {
2334 llvm::StringRef ExpectedCode = C.first;
2335 llvm::StringRef ExpectedRefs = C.second;
2336
2337 auto Actual =
2338 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
2339 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2340 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2341 }
2342}
2343
2344TEST_F(FindExplicitReferencesTest, AllRefs) {
2345 std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
2346 {{R"cpp(
2347 @interface $0^MyClass
2348 @end
2349 @implementation $1^$2^MyClass
2350 @end
2351 )cpp",
2352 "0: targets = {MyClass}, decl\n"
2353 "1: targets = {MyClass}\n"
2354 "2: targets = {MyClass}, decl\n"},
2355 {R"cpp(
2356 @interface $0^MyClass
2357 @end
2358 @interface $1^MyClass ($2^Category)
2359 @end
2360 @implementation $3^MyClass ($4^$5^Category)
2361 @end
2362 )cpp",
2363 "0: targets = {MyClass}, decl\n"
2364 "1: targets = {MyClass}\n"
2365 "2: targets = {Category}, decl\n"
2366 "3: targets = {MyClass}\n"
2367 "4: targets = {Category}\n"
2368 "5: targets = {Category}, decl\n"}};
2369
2370 for (const auto &C : Cases) {
2371 llvm::StringRef ExpectedCode = C.first;
2372 llvm::StringRef ExpectedRefs = C.second;
2373
2374 auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());
2375 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2376 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2377 }
2378}
2379
2380} // namespace
2381} // namespace clangd
2382} // namespace clang
#define EXPECT_DECLS(NodeType,...)
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:44
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition TestTU.cpp:220
llvm::SmallVector< std::pair< const NamedDecl *, DeclRelationSet >, 1 > allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver)
Similar to targetDecl(), however instead of applying a filter, all possible decls are returned along ...
void findExplicitReferences(const Stmt *S, llvm::function_ref< void(ReferenceLoc)> Out, const HeuristicResolver *Resolver)
Recursively traverse S and report all references explicitly written in the code.
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition Headers.cpp:356
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static TestTU withCode(llvm::StringRef Code)
Definition TestTU.h:36