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