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 // Deduction guide
598 template <typename T>
599 struct Test {
600 template <typename I>
601 Test(I, I);
602 };
603 template <typename I>
604 [[Test]](I, I) -> Test<typename I::type>;
605 )cpp";
606 EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"});
607}
608
609TEST_F(TargetDeclTest, Concept) {
610 Flags.push_back("-std=c++20");
611
612 // FIXME: Should we truncate the pretty-printed form of a concept decl
613 // somewhere?
614
615 Code = R"cpp(
616 template <typename T>
617 concept Fooable = requires (T t) { t.foo(); };
618
619 template <typename T> requires [[Fooable]]<T>
620 void bar(T t) {
621 t.foo();
622 }
623 )cpp";
625 "ConceptReference",
626 {"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
627
628 // trailing requires clause
629 Code = R"cpp(
630 template <typename T>
631 concept Fooable = true;
632
633 template <typename T>
634 void foo() requires [[Fooable]]<T>;
635 )cpp";
636 EXPECT_DECLS("ConceptReference",
637 {"template <typename T> concept Fooable = true"});
638
639 // constrained-parameter
640 Code = R"cpp(
641 template <typename T>
642 concept Fooable = true;
643
644 template <[[Fooable]] T>
645 void bar(T t);
646 )cpp";
647 EXPECT_DECLS("ConceptReference",
648 {"template <typename T> concept Fooable = true"});
649
650 // partial-concept-id
651 Code = R"cpp(
652 template <typename T, typename U>
653 concept Fooable = true;
654
655 template <[[Fooable]]<int> T>
656 void bar(T t);
657 )cpp";
658 EXPECT_DECLS("ConceptReference",
659 {"template <typename T, typename U> concept Fooable = true"});
660}
661
662TEST_F(TargetDeclTest, PackIndexedConcept) {
663 Flags.push_back("-std=c++2d");
664
665 // constrained-parameter
666 Code = R"cpp(
667 template <template <class> concept... CC>
668 struct S {
669 template <[[CC]]...[0] T>
670 void bar(T t);
671 };
672 )cpp";
673 EXPECT_DECLS("ConceptReference", {"template <class> concept ...CC"});
674
675 // constrained placeholder type
676 Code = R"cpp(
677 template <template <class> concept... CC>
678 void bar([[CC]]...[0] auto t);
679 )cpp";
680 EXPECT_DECLS("ConceptReference", {"template <class> concept ...CC"});
681}
682
683TEST_F(TargetDeclTest, Coroutine) {
684 Flags.push_back("-std=c++20");
685
686 Code = R"cpp(
687 namespace std {
688 template <typename, typename...> struct coroutine_traits;
689 template <typename> struct coroutine_handle {
690 template <typename U>
691 coroutine_handle(coroutine_handle<U>&&) noexcept;
692 static coroutine_handle from_address(void* __addr) noexcept;
693 };
694 } // namespace std
695
696 struct executor {};
697 struct awaitable {};
698 struct awaitable_frame {
699 awaitable get_return_object();
700 void return_void();
701 void unhandled_exception();
702 struct result_t {
703 ~result_t();
704 bool await_ready() const noexcept;
705 void await_suspend(std::coroutine_handle<void>) noexcept;
706 void await_resume() const noexcept;
707 };
708 result_t initial_suspend() noexcept;
709 result_t final_suspend() noexcept;
710 result_t await_transform(executor) noexcept;
711 };
712
713 namespace std {
714 template <>
715 struct coroutine_traits<awaitable> {
716 typedef awaitable_frame promise_type;
717 };
718 } // namespace std
719
720 awaitable foo() {
721 co_await [[executor]]();
722 }
723 )cpp";
724 EXPECT_DECLS("RecordTypeLoc", "struct executor");
725}
726
727TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
728 Flags.push_back("-std=c++20");
729
730 Code = R"cpp(
731 namespace std {
732 struct strong_ordering {
733 int n;
734 constexpr operator int() const { return n; }
735 static const strong_ordering equal, greater, less;
736 };
737 constexpr strong_ordering strong_ordering::equal = {0};
738 constexpr strong_ordering strong_ordering::greater = {1};
739 constexpr strong_ordering strong_ordering::less = {-1};
740 }
741
742 struct Foo
743 {
744 int x;
745 auto operator<=>(const Foo&) const = default;
746 };
747
748 bool x = (Foo(1) [[!=]] Foo(2));
749 )cpp";
750 EXPECT_DECLS("CXXRewrittenBinaryOperator",
751 {"bool operator==(const Foo &) const noexcept = default"});
752}
753
754TEST_F(TargetDeclTest, FunctionTemplate) {
755 Code = R"cpp(
756 // Implicit specialization.
757 template<typename T> bool foo(T) { return false; };
758 bool x = [[foo]](42);
759 )cpp";
760 EXPECT_DECLS("DeclRefExpr",
761 {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
762 {"bool foo(T)", Rel::TemplatePattern});
763
764 Code = R"cpp(
765 // Explicit specialization.
766 template<typename T> bool foo(T) { return false; };
767 template<> bool foo<int>(int) { return false; };
768 bool x = [[foo]](42);
769 )cpp";
770 EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");
771}
772
773TEST_F(TargetDeclTest, VariableTemplate) {
774 // Pretty-printer doesn't do a very good job of variable templates :-(
775 Code = R"cpp(
776 // Implicit specialization.
777 template<typename T> int foo;
778 int x = [[foo]]<char>;
779 )cpp";
780 EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},
781 {"int foo", Rel::TemplatePattern});
782
783 Code = R"cpp(
784 // Explicit specialization.
785 template<typename T> int foo;
786 template <> bool foo<char>;
787 int x = [[foo]]<char>;
788 )cpp";
789 EXPECT_DECLS("DeclRefExpr", "bool foo");
790
791 Code = R"cpp(
792 // Partial specialization.
793 template<typename T> int foo;
794 template<typename T> bool foo<T*>;
795 bool x = [[foo]]<char*>;
796 )cpp";
797 EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},
798 {"bool foo", Rel::TemplatePattern});
799}
800
801TEST_F(TargetDeclTest, TypeAliasTemplate) {
802 Code = R"cpp(
803 template<typename T, int X> class SmallVector {};
804 template<typename U> using TinyVector = SmallVector<U, 1>;
805 [[TinyVector<int>]] X;
806 )cpp";
807 EXPECT_DECLS("TemplateSpecializationTypeLoc",
808 {"template<> class SmallVector<int, 1>",
809 Rel::TemplateInstantiation | Rel::Underlying},
810 {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
811 {"using TinyVector = SmallVector<U, 1>",
812 Rel::Alias | Rel::TemplatePattern});
813}
814
815TEST_F(TargetDeclTest, BuiltinTemplates) {
816 Code = R"cpp(
817 template <class T, T... Index> struct integer_sequence {};
818 [[__make_integer_seq]]<integer_sequence, int, 3> X;
819 )cpp";
821 "TemplateSpecializationTypeLoc",
822 {"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
823 {"template<> struct integer_sequence<int, <0, 1, 2>>",
824 Rel::TemplateInstantiation | Rel::Underlying});
825
826 // Dependent context.
827 Code = R"cpp(
828 template <class T, T... Index> struct integer_sequence;
829
830 template <class T, int N>
831 using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
832 )cpp";
833 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
834
835 Code = R"cpp(
836 template <int N, class... Pack>
837 using type_pack_element = [[__type_pack_element]]<N, Pack...>;
838 )cpp";
839 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
840
841 Code = R"cpp(
842 template <template <class...> class Templ, class... Types>
843 using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;
844 )cpp";
845 EXPECT_DECLS("TemplateSpecializationTypeLoc", );
846}
847
848TEST_F(TargetDeclTest, MemberOfTemplate) {
849 Code = R"cpp(
850 template <typename T> struct Foo {
851 int x(T);
852 };
853 int y = Foo<int>().[[x]](42);
854 )cpp";
855 EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},
856 {"int x(T)", Rel::TemplatePattern});
857
858 Code = R"cpp(
859 template <typename T> struct Foo {
860 template <typename U>
861 int x(T, U);
862 };
863 int y = Foo<char>().[[x]]('c', 42);
864 )cpp";
865 EXPECT_DECLS("MemberExpr",
866 {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
867 {"int x(T, U)", Rel::TemplatePattern});
868}
869
870TEST_F(TargetDeclTest, Lambda) {
871 Code = R"cpp(
872 void foo(int x = 42) {
873 auto l = [ [[x]] ]{ return x + 1; };
874 };
875 )cpp";
876 EXPECT_DECLS("DeclRefExpr", "int x = 42");
877
878 // It seems like this should refer to another var, with the outer param being
879 // an underlying decl. But it doesn't seem to exist.
880 Code = R"cpp(
881 void foo(int x = 42) {
882 auto l = [x]{ return [[x]] + 1; };
883 };
884 )cpp";
885 EXPECT_DECLS("DeclRefExpr", "int x = 42");
886
887 Code = R"cpp(
888 void foo() {
889 auto l = [x = 1]{ return [[x]] + 1; };
890 };
891 )cpp";
892 // FIXME: why both auto and int?
893 EXPECT_DECLS("DeclRefExpr", "auto int x = 1");
894}
895
896TEST_F(TargetDeclTest, OverloadExpr) {
897 Flags.push_back("--target=x86_64-pc-linux-gnu");
898
899 Code = R"cpp(
900 void func(int*);
901 void func(char*);
902
903 template <class T>
904 void foo(T t) {
905 [[func]](t);
906 };
907 )cpp";
908 EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");
909
910 Code = R"cpp(
911 struct X {
912 void func(int*);
913 void func(char*);
914 };
915
916 template <class T>
917 void foo(X x, T t) {
918 x.[[func]](t);
919 };
920 )cpp";
921 EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");
922
923 Code = R"cpp(
924 struct X {
925 static void *operator new(unsigned long);
926 };
927 auto* k = [[new]] X();
928 )cpp";
929 EXPECT_DECLS("CXXNewExpr", "static void *operator new(unsigned long)");
930 Code = R"cpp(
931 void *operator new(unsigned long);
932 auto* k = [[new]] int();
933 )cpp";
934 EXPECT_DECLS("CXXNewExpr", "void *operator new(unsigned long)");
935
936 Code = R"cpp(
937 struct X {
938 static void operator delete(void *) noexcept;
939 };
940 void k(X* x) {
941 [[delete]] x;
942 }
943 )cpp";
944 EXPECT_DECLS("CXXDeleteExpr", "static void operator delete(void *) noexcept");
945 Code = R"cpp(
946 void operator delete(void *) noexcept;
947 void k(int* x) {
948 [[delete]] x;
949 }
950 )cpp";
951 // Sized deallocation is enabled by default in C++14 onwards.
952 EXPECT_DECLS("CXXDeleteExpr",
953 "void operator delete(void *, __size_t) noexcept");
954}
955
956TEST_F(TargetDeclTest, DependentExprs) {
957 Flags.push_back("--std=c++20");
958
959 // Heuristic resolution of method of dependent field
960 Code = R"cpp(
961 struct A { void foo() {} };
962 template <typename T>
963 struct B {
964 A a;
965 void bar() {
966 this->a.[[foo]]();
967 }
968 };
969 )cpp";
970 EXPECT_DECLS("MemberExpr", "void foo()");
971
972 // Similar to above but base expression involves a function call.
973 Code = R"cpp(
974 struct A {
975 void foo() {}
976 };
977 struct B {
978 A getA();
979 };
980 template <typename T>
981 struct C {
982 B c;
983 void bar() {
984 this->c.getA().[[foo]]();
985 }
986 };
987 )cpp";
988 EXPECT_DECLS("MemberExpr", "void foo()");
989
990 // Similar to above but uses a function pointer.
991 Code = R"cpp(
992 struct A {
993 void foo() {}
994 };
995 struct B {
996 using FPtr = A(*)();
997 FPtr fptr;
998 };
999 template <typename T>
1000 struct C {
1001 B c;
1002 void bar() {
1003 this->c.fptr().[[foo]]();
1004 }
1005 };
1006 )cpp";
1007 EXPECT_DECLS("MemberExpr", "void foo()");
1008
1009 // Base expression involves a member access into this.
1010 Code = R"cpp(
1011 struct Bar {
1012 int aaaa;
1013 };
1014 template <typename T> struct Foo {
1015 Bar func(int);
1016 void test() {
1017 func(1).[[aaaa]];
1018 }
1019 };
1020 )cpp";
1021 EXPECT_DECLS("CXXDependentScopeMemberExpr", "int aaaa");
1022
1023 Code = R"cpp(
1024 class Foo {
1025 public:
1026 static Foo k(int);
1027 template <typename T> T convert() const;
1028 };
1029 template <typename T>
1030 void test() {
1031 Foo::k(T()).template [[convert]]<T>();
1032 }
1033 )cpp";
1034 EXPECT_DECLS("CXXDependentScopeMemberExpr",
1035 "template <typename T> T convert() const");
1036
1037 Code = R"cpp(
1038 template <typename T>
1039 struct Waldo {
1040 void find();
1041 };
1042 template <typename T>
1043 using Wally = Waldo<T>;
1044 template <typename T>
1045 void foo(Wally<T> w) {
1046 w.[[find]]();
1047 }
1048 )cpp";
1049 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
1050
1051 Code = R"cpp(
1052 template <typename T>
1053 struct Waldo {
1054 void find();
1055 };
1056 template <typename T>
1057 struct MetaWaldo {
1058 using Type = Waldo<T>;
1059 };
1060 template <typename T>
1061 void foo(typename MetaWaldo<T>::Type w) {
1062 w.[[find]]();
1063 }
1064 )cpp";
1065 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
1066
1067 Code = R"cpp(
1068 struct Waldo {
1069 void find();
1070 };
1071 template <typename T>
1072 using Wally = Waldo;
1073 template <typename>
1074 struct S : Wally<int> {
1075 void Foo() { this->[[find]](); }
1076 };
1077 )cpp";
1078 EXPECT_DECLS("MemberExpr", "void find()");
1079
1080 // Base expression is the type of a non-type template parameter
1081 // which is deduced using CTAD.
1082 Code = R"cpp(
1083 template <int N>
1084 struct Waldo {
1085 const int found = N;
1086 };
1087
1088 template <Waldo W>
1089 int test() {
1090 return W.[[found]];
1091 }
1092 )cpp";
1093 EXPECT_DECLS("CXXDependentScopeMemberExpr", "const int found = N");
1094}
1095
1096TEST_F(TargetDeclTest, DependentTypes) {
1097 // Heuristic resolution of dependent type name
1098 Code = R"cpp(
1099 template <typename>
1100 struct A { struct B {}; };
1101
1102 template <typename T>
1103 void foo(typename A<T>::[[B]]);
1104 )cpp";
1105 EXPECT_DECLS("DependentNameTypeLoc", "struct B");
1106
1107 // Heuristic resolution of dependent type name within a NestedNameSpecifierLoc
1108 Code = R"cpp(
1109 template <typename>
1110 struct A { struct B { struct C {}; }; };
1111
1112 template <typename T>
1113 void foo(typename A<T>::[[B]]::C);
1114 )cpp";
1115 EXPECT_DECLS("DependentNameTypeLoc", "struct B");
1116
1117 // Heuristic resolution of dependent type name whose qualifier is also
1118 // dependent
1119 Code = R"cpp(
1120 template <typename>
1121 struct A { struct B { struct C {}; }; };
1122
1123 template <typename T>
1124 void foo(typename A<T>::B::[[C]]);
1125 )cpp";
1126 EXPECT_DECLS("DependentNameTypeLoc", "struct C");
1127
1128 // Heuristic resolution of dependent template name
1129 Code = R"cpp(
1130 template <typename>
1131 struct A {
1132 template <typename> struct B {};
1133 };
1134
1135 template <typename T>
1136 void foo(typename A<T>::template [[B]]<int>);
1137 )cpp";
1138 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");
1139
1140 // Dependent name with recursive definition. We don't expect a
1141 // result, but we shouldn't get into a stack overflow either.
1142 Code = R"cpp(
1143 template <int N>
1144 struct waldo {
1145 typedef typename waldo<N - 1>::type::[[next]] type;
1146 };
1147 )cpp";
1148 EXPECT_DECLS("DependentNameTypeLoc", );
1149
1150 // Similar to above but using mutually recursive templates.
1151 Code = R"cpp(
1152 template <int N>
1153 struct odd;
1154
1155 template <int N>
1156 struct even {
1157 using type = typename odd<N - 1>::type::next;
1158 };
1159
1160 template <int N>
1161 struct odd {
1162 using type = typename even<N - 1>::type::[[next]];
1163 };
1164 )cpp";
1165 EXPECT_DECLS("DependentNameTypeLoc", );
1166}
1167
1168TEST_F(TargetDeclTest, TypedefCascade) {
1169 Code = R"cpp(
1170 struct C {
1171 using type = int;
1172 };
1173 struct B {
1174 using type = C::type;
1175 };
1176 struct A {
1177 using type = B::type;
1178 };
1179 A::[[type]] waldo;
1180 )cpp";
1181 EXPECT_DECLS("TypedefTypeLoc",
1182 {"using type = int", Rel::Alias | Rel::Underlying},
1183 {"using type = C::type", Rel::Alias | Rel::Underlying},
1184 {"using type = B::type", Rel::Alias});
1185}
1186
1187TEST_F(TargetDeclTest, RecursiveTemplate) {
1188 Flags.push_back("-std=c++20"); // the test case uses concepts
1189
1190 Code = R"cpp(
1191 template <typename T>
1192 concept Leaf = false;
1193
1194 template <typename Tree>
1195 struct descend_left {
1196 using type = typename descend_left<typename Tree::left>::[[type]];
1197 };
1198
1199 template <Leaf Tree>
1200 struct descend_left<Tree> {
1201 using type = typename Tree::value;
1202 };
1203 )cpp";
1204 EXPECT_DECLS("DependentNameTypeLoc",
1205 {"using type = typename descend_left<typename Tree::left>::type",
1206 Rel::Alias | Rel::Underlying});
1207}
1208
1209TEST_F(TargetDeclTest, ObjC) {
1210 Flags = {"-xobjective-c"};
1211 Code = R"cpp(
1212 @interface Foo {}
1213 -(void)bar;
1214 @end
1215 void test(Foo *f) {
1216 [f [[bar]] ];
1217 }
1218 )cpp";
1219 EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");
1220
1221 Code = R"cpp(
1222 @interface Foo { @public int bar; }
1223 @end
1224 int test(Foo *f) {
1225 return [[f->bar]];
1226 }
1227 )cpp";
1228 EXPECT_DECLS("ObjCIvarRefExpr", "int bar");
1229
1230 Code = R"cpp(
1231 @interface Foo {}
1232 -(int) x;
1233 -(void) setX:(int)x;
1234 @end
1235 void test(Foo *f) {
1236 [[f.x]] = 42;
1237 }
1238 )cpp";
1239 EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");
1240
1241 Code = R"cpp(
1242 @interface I {}
1243 @property(retain) I* x;
1244 @property(retain) I* y;
1245 @end
1246 void test(I *f) {
1247 [[f.x]].y = 0;
1248 }
1249 )cpp";
1250 EXPECT_DECLS("ObjCPropertyRefExpr",
1251 "@property(atomic, retain, readwrite) I *x");
1252
1253 Code = R"cpp(
1254 @interface MYObject
1255 @end
1256 @interface Interface
1257 @property(retain) [[MYObject]] *x;
1258 @end
1259 )cpp";
1260 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject");
1261
1262 Code = R"cpp(
1263 @interface MYObject2
1264 @end
1265 @interface Interface
1266 @property(retain, nonnull) [[MYObject2]] *x;
1267 @end
1268 )cpp";
1269 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject2");
1270
1271 Code = R"cpp(
1272 @protocol Foo
1273 @end
1274 id test() {
1275 return [[@protocol(Foo)]];
1276 }
1277 )cpp";
1278 EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");
1279
1280 Code = R"cpp(
1281 @interface Foo
1282 @end
1283 void test([[Foo]] *p);
1284 )cpp";
1285 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1286
1287 Code = R"cpp(// Don't consider implicit interface as the target.
1288 @implementation [[Implicit]]
1289 @end
1290 )cpp";
1291 EXPECT_DECLS("ObjCImplementationDecl", "@implementation Implicit");
1292
1293 Code = R"cpp(
1294 @interface Foo
1295 @end
1296 @implementation [[Foo]]
1297 @end
1298 )cpp";
1299 EXPECT_DECLS("ObjCImplementationDecl", "@interface Foo");
1300
1301 Code = R"cpp(
1302 @interface Foo
1303 @end
1304 @interface Foo (Ext)
1305 @end
1306 @implementation [[Foo]] (Ext)
1307 @end
1308 )cpp";
1309 EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");
1310
1311 Code = R"cpp(
1312 @interface Foo
1313 @end
1314 @interface Foo (Ext)
1315 @end
1316 @implementation Foo ([[Ext]])
1317 @end
1318 )cpp";
1319 EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");
1320
1321 Code = R"cpp(
1322 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1323 )cpp";
1324 EXPECT_DECLS("ParmVarDecl", "id p");
1325
1326 Code = R"cpp(
1327 @class C;
1328 @protocol Foo
1329 @end
1330 void test([[C]]<Foo> *p);
1331 )cpp";
1332 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@class C;");
1333
1334 Code = R"cpp(
1335 @class C;
1336 @protocol Foo
1337 @end
1338 void test(C<[[Foo]]> *p);
1339 )cpp";
1340 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1341
1342 Code = R"cpp(
1343 @class C;
1344 @protocol Foo
1345 @end
1346 @protocol Bar
1347 @end
1348 void test(C<[[Foo]], Bar> *p);
1349 )cpp";
1350 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1351
1352 Code = R"cpp(
1353 @class C;
1354 @protocol Foo
1355 @end
1356 @protocol Bar
1357 @end
1358 void test(C<Foo, [[Bar]]> *p);
1359 )cpp";
1360 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Bar");
1361
1362 Code = R"cpp(
1363 @interface Foo
1364 + (id)sharedInstance;
1365 @end
1366 @implementation Foo
1367 + (id)sharedInstance { return 0; }
1368 @end
1369 void test() {
1370 id value = [[Foo]].sharedInstance;
1371 }
1372 )cpp";
1373 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1374
1375 Code = R"cpp(
1376 @interface Foo
1377 + (id)sharedInstance;
1378 @end
1379 @implementation Foo
1380 + (id)sharedInstance { return 0; }
1381 @end
1382 void test() {
1383 id value = Foo.[[sharedInstance]];
1384 }
1385 )cpp";
1386 EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
1387
1388 Code = R"cpp(
1389 @interface Foo
1390 + ([[id]])sharedInstance;
1391 @end
1392 )cpp";
1393 EXPECT_DECLS("TypedefTypeLoc", );
1394
1395 Code = R"cpp(
1396 @interface Foo
1397 + ([[instancetype]])sharedInstance;
1398 @end
1399 )cpp";
1400 EXPECT_DECLS("TypedefTypeLoc", );
1401}
1402
1403class FindExplicitReferencesTest : public ::testing::Test {
1404protected:
1405 struct AllRefs {
1406 std::string AnnotatedCode;
1407 std::string DumpedReferences;
1408 };
1409
1410 TestTU newTU(llvm::StringRef Code) {
1411 TestTU TU;
1412 TU.Code = std::string(Code);
1413
1414 // FIXME: Auto-completion in a template requires disabling delayed template
1415 // parsing.
1416 TU.ExtraArgs.push_back("-std=c++20");
1417 TU.ExtraArgs.push_back("-xobjective-c++");
1418
1419 return TU;
1420 }
1421
1422 AllRefs annotatedReferences(llvm::StringRef Code, ParsedAST &AST,
1423 std::vector<ReferenceLoc> Refs) {
1424 auto &SM = AST.getSourceManager();
1425 llvm::stable_sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
1426 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1427 });
1428
1429 std::string AnnotatedCode;
1430 unsigned NextCodeChar = 0;
1431 for (unsigned I = 0; I < Refs.size(); ++I) {
1432 auto &R = Refs[I];
1433
1434 SourceLocation Pos = R.NameLoc;
1435 assert(Pos.isValid());
1436 if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.
1437 Pos = SM.getExpansionLoc(Pos);
1438 assert(Pos.isFileID());
1439
1440 FileID File;
1441 unsigned Offset;
1442 std::tie(File, Offset) = SM.getDecomposedLoc(Pos);
1443 if (File == SM.getMainFileID()) {
1444 // Print the reference in a source code.
1445 assert(NextCodeChar <= Offset);
1446 AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
1447 AnnotatedCode += "$" + std::to_string(I) + "^";
1448
1449 NextCodeChar = Offset;
1450 }
1451 }
1452 AnnotatedCode += Code.substr(NextCodeChar);
1453
1454 std::string DumpedReferences;
1455 for (unsigned I = 0; I < Refs.size(); ++I)
1456 DumpedReferences += std::string(llvm::formatv("{0}: {1}\n", I, Refs[I]));
1457
1458 return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
1459 }
1460
1461 /// Parses \p Code, and annotates its body with results of
1462 /// findExplicitReferences on all top level decls.
1463 /// See actual tests for examples of annotation format.
1464 AllRefs annotateAllReferences(llvm::StringRef Code) {
1465 TestTU TU = newTU(Code);
1466 auto AST = TU.build();
1467
1468 std::vector<ReferenceLoc> Refs;
1469 for (auto *TopLevel : AST.getLocalTopLevelDecls())
1471 TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1472 AST.getHeuristicResolver());
1473 return annotatedReferences(Code, AST, std::move(Refs));
1474 }
1475
1476 /// Parses \p Code, finds function or namespace '::foo' and annotates its body
1477 /// with results of findExplicitReferences.
1478 /// See actual tests for examples of annotation format.
1479 AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
1480 TestTU TU = newTU(Code);
1481 auto AST = TU.build();
1482 auto *TestDecl = &findDecl(AST, "foo");
1483 if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1484 TestDecl = T->getTemplatedDecl();
1485
1486 std::vector<ReferenceLoc> Refs;
1487 if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1489 Func->getBody(),
1490 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1491 AST.getHeuristicResolver());
1492 else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1494 NS,
1495 [&Refs, &NS](ReferenceLoc R) {
1496 // Avoid adding the namespace foo decl to the results.
1497 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1498 return;
1499 Refs.push_back(std::move(R));
1500 },
1501 AST.getHeuristicResolver());
1502 else if (const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))
1504 OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1505 AST.getHeuristicResolver());
1506 else
1507 ADD_FAILURE() << "Failed to find ::foo decl for test";
1508
1509 return annotatedReferences(Code, AST, std::move(Refs));
1510 }
1511};
1512
1513TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
1514 std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
1515 {// Simple expressions.
1516 {R"cpp(
1517 int global;
1518 int func();
1519 void foo(int param) {
1520 $0^global = $1^param + $2^func();
1521 }
1522 )cpp",
1523 "0: targets = {global}\n"
1524 "1: targets = {param}\n"
1525 "2: targets = {func}\n"},
1526 {R"cpp(
1527 struct X { int a; };
1528 void foo(X x) {
1529 $0^x.$1^a = 10;
1530 }
1531 )cpp",
1532 "0: targets = {x}\n"
1533 "1: targets = {X::a}\n"},
1534 {R"cpp(
1535 // error-ok: testing with broken code
1536 int bar();
1537 int foo() {
1538 return $0^bar() + $1^bar(42);
1539 }
1540 )cpp",
1541 "0: targets = {bar}\n"
1542 "1: targets = {bar}\n"},
1543 // Namespaces and aliases.
1544 {R"cpp(
1545 namespace ns {}
1546 namespace alias = ns;
1547 void foo() {
1548 using namespace $0^ns;
1549 using namespace $1^alias;
1550 }
1551 )cpp",
1552 "0: targets = {ns}\n"
1553 "1: targets = {alias}\n"},
1554 // Using declarations.
1555 {R"cpp(
1556 namespace ns { int global; }
1557 void foo() {
1558 using $0^ns::$1^global;
1559 }
1560 )cpp",
1561 "0: targets = {ns}\n"
1562 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1563 // Using enum declarations.
1564 {R"cpp(
1565 namespace ns { enum class A {}; }
1566 void foo() {
1567 using enum $0^ns::$1^A;
1568 }
1569 )cpp",
1570 "0: targets = {ns}\n"
1571 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1572 // Simple types.
1573 {R"cpp(
1574 struct Struct { int a; };
1575 using Typedef = int;
1576 void foo() {
1577 $0^Struct $1^x;
1578 $2^Typedef $3^y;
1579 static_cast<$4^Struct*>(0);
1580 }
1581 )cpp",
1582 "0: targets = {Struct}\n"
1583 "1: targets = {x}, decl\n"
1584 "2: targets = {Typedef}\n"
1585 "3: targets = {y}, decl\n"
1586 "4: targets = {Struct}\n"},
1587 // Name qualifiers.
1588 {R"cpp(
1589 namespace a { namespace b { struct S { typedef int type; }; } }
1590 void foo() {
1591 $0^a::$1^b::$2^S $3^x;
1592 using namespace $4^a::$5^b;
1593 $6^S::$7^type $8^y;
1594 }
1595 )cpp",
1596 "0: targets = {a}\n"
1597 "1: targets = {a::b}, qualifier = 'a::'\n"
1598 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1599 "3: targets = {x}, decl\n"
1600 "4: targets = {a}\n"
1601 "5: targets = {a::b}, qualifier = 'a::'\n"
1602 "6: targets = {a::b::S}\n"
1603 "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
1604 "8: targets = {y}, decl\n"},
1605 {R"cpp(
1606 void foo() {
1607 $0^ten: // PRINT "HELLO WORLD!"
1608 goto $1^ten;
1609 }
1610 )cpp",
1611 "0: targets = {ten}, decl\n"
1612 "1: targets = {ten}\n"},
1613 // Simple templates.
1614 {R"cpp(
1615 template <class T> struct vector { using value_type = T; };
1616 template <> struct vector<bool> { using value_type = bool; };
1617 void foo() {
1618 $0^vector<int> $1^vi;
1619 $2^vector<bool> $3^vb;
1620 }
1621 )cpp",
1622 "0: targets = {vector<int>}\n"
1623 "1: targets = {vi}, decl\n"
1624 "2: targets = {vector<bool>}\n"
1625 "3: targets = {vb}, decl\n"},
1626 // Template type aliases.
1627 {R"cpp(
1628 template <class T> struct vector { using value_type = T; };
1629 template <> struct vector<bool> { using value_type = bool; };
1630 template <class T> using valias = vector<T>;
1631 void foo() {
1632 $0^valias<int> $1^vi;
1633 $2^valias<bool> $3^vb;
1634 }
1635 )cpp",
1636 "0: targets = {valias}\n"
1637 "1: targets = {vi}, decl\n"
1638 "2: targets = {valias}\n"
1639 "3: targets = {vb}, decl\n"},
1640 // Injected class name.
1641 {R"cpp(
1642 namespace foo {
1643 template <typename $0^T>
1644 class $1^Bar {
1645 ~$2^Bar();
1646 void $3^f($4^Bar);
1647 };
1648 }
1649 )cpp",
1650 "0: targets = {foo::Bar::T}, decl\n"
1651 "1: targets = {foo::Bar}, decl\n"
1652 "2: targets = {foo::Bar}\n"
1653 "3: targets = {foo::Bar::f}, decl\n"
1654 "4: targets = {foo::Bar}\n"},
1655 // MemberExpr should know their using declaration.
1656 {R"cpp(
1657 struct X { void func(int); };
1658 struct Y : X {
1659 using X::func;
1660 };
1661 void foo(Y y) {
1662 $0^y.$1^func(1);
1663 }
1664 )cpp",
1665 "0: targets = {y}\n"
1666 "1: targets = {Y::func}\n"},
1667 // DeclRefExpr should know their using declaration.
1668 {R"cpp(
1669 namespace ns { void bar(int); }
1670 using ns::bar;
1671
1672 void foo() {
1673 $0^bar(10);
1674 }
1675 )cpp",
1676 "0: targets = {bar}\n"},
1677 // References from a macro.
1678 {R"cpp(
1679 #define FOO a
1680 #define BAR b
1681
1682 void foo(int a, int b) {
1683 $0^FOO+$1^BAR;
1684 }
1685 )cpp",
1686 "0: targets = {a}\n"
1687 "1: targets = {b}\n"},
1688 // No references from implicit nodes.
1689 {R"cpp(
1690 struct vector {
1691 int *begin();
1692 int *end();
1693 };
1694
1695 void foo() {
1696 for (int $0^x : $1^vector()) {
1697 $2^x = 10;
1698 }
1699 }
1700 )cpp",
1701 "0: targets = {x}, decl\n"
1702 "1: targets = {vector}\n"
1703 "2: targets = {x}\n"},
1704 // Handle UnresolvedLookupExpr.
1705 {R"cpp(
1706 namespace ns1 { void func(char*); }
1707 namespace ns2 { void func(int*); }
1708 using namespace ns1;
1709 using namespace ns2;
1710
1711 template <class T>
1712 void foo(T t) {
1713 $0^func($1^t);
1714 }
1715 )cpp",
1716 "0: targets = {ns1::func, ns2::func}\n"
1717 "1: targets = {t}\n"},
1718 // Handle UnresolvedMemberExpr.
1719 {R"cpp(
1720 struct X {
1721 void func(char*);
1722 void func(int*);
1723 };
1724
1725 template <class T>
1726 void foo(X x, T t) {
1727 $0^x.$1^func($2^t);
1728 }
1729 )cpp",
1730 "0: targets = {x}\n"
1731 "1: targets = {X::func, X::func}\n"
1732 "2: targets = {t}\n"},
1733 // Handle DependentScopeDeclRefExpr.
1734 {R"cpp(
1735 template <class T>
1736 struct S {
1737 static int value;
1738 };
1739
1740 template <class T>
1741 void foo() {
1742 $0^S<$1^T>::$2^value;
1743 }
1744 )cpp",
1745 "0: targets = {S}\n"
1746 "1: targets = {T}\n"
1747 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1748 // Handle CXXDependentScopeMemberExpr.
1749 {R"cpp(
1750 template <class T>
1751 struct S {
1752 int value;
1753 };
1754
1755 template <class T>
1756 void foo(S<T> t) {
1757 $0^t.$1^value;
1758 }
1759 )cpp",
1760 "0: targets = {t}\n"
1761 "1: targets = {S::value}\n"},
1762 // Type template parameters.
1763 {R"cpp(
1764 template <class T>
1765 void foo() {
1766 static_cast<$0^T>(0);
1767 $1^T();
1768 $2^T $3^t;
1769 }
1770 )cpp",
1771 "0: targets = {T}\n"
1772 "1: targets = {T}\n"
1773 "2: targets = {T}\n"
1774 "3: targets = {t}, decl\n"},
1775 // Non-type template parameters.
1776 {R"cpp(
1777 template <int I>
1778 void foo() {
1779 int $0^x = $1^I;
1780 }
1781 )cpp",
1782 "0: targets = {x}, decl\n"
1783 "1: targets = {I}\n"},
1784 // Template template parameters.
1785 {R"cpp(
1786 template <class T> struct vector {};
1787
1788 template <template<class> class TT, template<class> class ...TP>
1789 void foo() {
1790 $0^TT<int> $1^x;
1791 $2^foo<$3^TT>();
1792 $4^foo<$5^vector>();
1793 $6^foo<$7^TP...>();
1794 }
1795 )cpp",
1796 "0: targets = {TT}\n"
1797 "1: targets = {x}, decl\n"
1798 "2: targets = {foo}\n"
1799 "3: targets = {TT}\n"
1800 "4: targets = {foo}\n"
1801 "5: targets = {vector}\n"
1802 "6: targets = {foo}\n"
1803 "7: targets = {TP}\n"},
1804 // Non-type template parameters with declarations.
1805 {R"cpp(
1806 int func();
1807 template <int(*)()> struct wrapper {};
1808
1809 template <int(*FuncParam)()>
1810 void foo() {
1811 $0^wrapper<$1^func> $2^w;
1812 $3^FuncParam();
1813 }
1814 )cpp",
1815 "0: targets = {wrapper<&func>}\n"
1816 "1: targets = {func}\n"
1817 "2: targets = {w}, decl\n"
1818 "3: targets = {FuncParam}\n"},
1819 // declaration references.
1820 {R"cpp(
1821 namespace ns {}
1822 class S {};
1823 void foo() {
1824 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1825 int $4^Var;
1826 enum $5^E { $6^ABC };
1827 typedef int $7^INT;
1828 using $8^INT2 = int;
1829 namespace $9^NS = $10^ns;
1830 }
1831 )cpp",
1832 "0: targets = {Foo}, decl\n"
1833 "1: targets = {foo()::Foo::Foo}, decl\n"
1834 "2: targets = {Foo}\n"
1835 "3: targets = {foo()::Foo::field}, decl\n"
1836 "4: targets = {Var}, decl\n"
1837 "5: targets = {E}, decl\n"
1838 "6: targets = {foo()::ABC}, decl\n"
1839 "7: targets = {INT}, decl\n"
1840 "8: targets = {INT2}, decl\n"
1841 "9: targets = {NS}, decl\n"
1842 "10: targets = {ns}\n"},
1843 // User-defined conversion operator.
1844 {R"cpp(
1845 void foo() {
1846 class $0^Bar {};
1847 class $1^Foo {
1848 public:
1849 // FIXME: This should have only one reference to Bar.
1850 $2^operator $3^$4^Bar();
1851 };
1852
1853 $5^Foo $6^f;
1854 $7^f.$8^operator $9^Bar();
1855 }
1856 )cpp",
1857 "0: targets = {Bar}, decl\n"
1858 "1: targets = {Foo}, decl\n"
1859 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1860 "3: targets = {Bar}\n"
1861 "4: targets = {Bar}\n"
1862 "5: targets = {Foo}\n"
1863 "6: targets = {f}, decl\n"
1864 "7: targets = {f}\n"
1865 "8: targets = {foo()::Foo::operator Bar}\n"
1866 "9: targets = {Bar}\n"},
1867 // Destructor.
1868 {R"cpp(
1869 void foo() {
1870 class $0^Foo {
1871 public:
1872 ~$1^Foo() {}
1873
1874 void $2^destructMe() {
1875 this->~$3^Foo();
1876 }
1877 };
1878
1879 $4^Foo $5^f;
1880 $6^f.~ /*...*/ $7^Foo();
1881 }
1882 )cpp",
1883 "0: targets = {Foo}, decl\n"
1884 // FIXME: It's better to target destructor's FunctionDecl instead of
1885 // the type itself (similar to constructor).
1886 "1: targets = {Foo}\n"
1887 "2: targets = {foo()::Foo::destructMe}, decl\n"
1888 "3: targets = {Foo}\n"
1889 "4: targets = {Foo}\n"
1890 "5: targets = {f}, decl\n"
1891 "6: targets = {f}\n"
1892 "7: targets = {Foo}\n"},
1893 // cxx constructor initializer.
1894 {R"cpp(
1895 class Base {};
1896 void foo() {
1897 // member initializer
1898 class $0^X {
1899 int $1^abc;
1900 $2^X(): $3^abc() {}
1901 };
1902 // base initializer
1903 class $4^Derived : public $5^Base {
1904 $6^Base $7^B;
1905 $8^Derived() : $9^Base() {}
1906 };
1907 // delegating initializer
1908 class $10^Foo {
1909 $11^Foo(int);
1910 $12^Foo(): $13^Foo(111) {}
1911 };
1912 }
1913 )cpp",
1914 "0: targets = {X}, decl\n"
1915 "1: targets = {foo()::X::abc}, decl\n"
1916 "2: targets = {foo()::X::X}, decl\n"
1917 "3: targets = {foo()::X::abc}\n"
1918 "4: targets = {Derived}, decl\n"
1919 "5: targets = {Base}\n"
1920 "6: targets = {Base}\n"
1921 "7: targets = {foo()::Derived::B}, decl\n"
1922 "8: targets = {foo()::Derived::Derived}, decl\n"
1923 "9: targets = {Base}\n"
1924 "10: targets = {Foo}, decl\n"
1925 "11: targets = {foo()::Foo::Foo}, decl\n"
1926 "12: targets = {foo()::Foo::Foo}, decl\n"
1927 "13: targets = {Foo}\n"},
1928 // Anonymous entities should not be reported.
1929 {
1930 R"cpp(
1931 void foo() {
1932 $0^class {} $1^x;
1933 int (*$2^fptr)(int $3^a, int) = nullptr;
1934 }
1935 )cpp",
1936 "0: targets = {(unnamed class)}\n"
1937 "1: targets = {x}, decl\n"
1938 "2: targets = {fptr}, decl\n"
1939 "3: targets = {a}, decl\n"},
1940 // Namespace aliases should be handled properly.
1941 {
1942 R"cpp(
1943 namespace ns { struct Type {}; }
1944 namespace alias = ns;
1945 namespace rec_alias = alias;
1946
1947 void foo() {
1948 $0^ns::$1^Type $2^a;
1949 $3^alias::$4^Type $5^b;
1950 $6^rec_alias::$7^Type $8^c;
1951 }
1952 )cpp",
1953 "0: targets = {ns}\n"
1954 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1955 "2: targets = {a}, decl\n"
1956 "3: targets = {alias}\n"
1957 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1958 "5: targets = {b}, decl\n"
1959 "6: targets = {rec_alias}\n"
1960 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1961 "8: targets = {c}, decl\n"},
1962 // Handle SizeOfPackExpr.
1963 {
1964 R"cpp(
1965 template <typename... E>
1966 void foo() {
1967 constexpr int $0^size = sizeof...($1^E);
1968 };
1969 )cpp",
1970 "0: targets = {size}, decl\n"
1971 "1: targets = {E}\n"},
1972 // Class template argument deduction
1973 {
1974 R"cpp(
1975 template <typename T>
1976 struct Test {
1977 Test(T);
1978 };
1979 void foo() {
1980 $0^Test $1^a(5);
1981 }
1982 )cpp",
1983 "0: targets = {Test}\n"
1984 "1: targets = {a}, decl\n"},
1985 // Templates
1986 {R"cpp(
1987 namespace foo {
1988 template <typename $0^T>
1989 class $1^Bar {};
1990 }
1991 )cpp",
1992 "0: targets = {foo::Bar::T}, decl\n"
1993 "1: targets = {foo::Bar}, decl\n"},
1994 // Templates
1995 {R"cpp(
1996 namespace foo {
1997 template <typename $0^T>
1998 void $1^func();
1999 }
2000 )cpp",
2001 "0: targets = {T}, decl\n"
2002 "1: targets = {foo::func}, decl\n"},
2003 // Templates
2004 {R"cpp(
2005 namespace foo {
2006 template <typename $0^T>
2007 $1^T $2^x;
2008 }
2009 )cpp",
2010 "0: targets = {foo::T}, decl\n"
2011 "1: targets = {foo::T}\n"
2012 "2: targets = {foo::x}, decl\n"},
2013 // Templates
2014 {R"cpp(
2015 template<typename T> class vector {};
2016 namespace foo {
2017 template <typename $0^T>
2018 using $1^V = $2^vector<$3^T>;
2019 }
2020 )cpp",
2021 "0: targets = {foo::T}, decl\n"
2022 "1: targets = {foo::V}, decl\n"
2023 "2: targets = {vector}\n"
2024 "3: targets = {foo::T}\n"},
2025 // Concept
2026 {
2027 R"cpp(
2028 template <typename T>
2029 concept Drawable = requires (T t) { t.draw(); };
2030
2031 namespace foo {
2032 template <typename $0^T> requires $1^Drawable<$2^T>
2033 void $3^bar($4^T $5^t) {
2034 $6^t.$7^draw();
2035 }
2036 }
2037 )cpp",
2038 "0: targets = {T}, decl\n"
2039 "1: targets = {Drawable}\n"
2040 "2: targets = {T}\n"
2041 "3: targets = {foo::bar}, decl\n"
2042 "4: targets = {T}\n"
2043 "5: targets = {t}, decl\n"
2044 "6: targets = {t}\n"
2045 "7: targets = {}\n"},
2046 // Objective-C: instance variables
2047 {
2048 R"cpp(
2049 @interface I {
2050 @public
2051 I *_z;
2052 }
2053 @end
2054 I *f;
2055 void foo() {
2056 $0^f->$1^_z = 0;
2057 }
2058 )cpp",
2059 "0: targets = {f}\n"
2060 "1: targets = {I::_z}\n"},
2061 // Objective-C: properties
2062 {
2063 R"cpp(
2064 @interface I {}
2065 @property(retain) I* x;
2066 @property(retain) I* y;
2067 @end
2068 I *f;
2069 void foo() {
2070 $0^f.$1^x.$2^y = 0;
2071 }
2072 )cpp",
2073 "0: targets = {f}\n"
2074 "1: targets = {I::x}\n"
2075 "2: targets = {I::y}\n"},
2076 // Objective-C: implicit properties
2077 {
2078 R"cpp(
2079 @interface I {}
2080 -(I*)x;
2081 -(void)setY:(I*)y;
2082 @end
2083 I *f;
2084 void foo() {
2085 $0^f.$1^x.$2^y = 0;
2086 }
2087 )cpp",
2088 "0: targets = {f}\n"
2089 "1: targets = {I::x}\n"
2090 "2: targets = {I::setY:}\n"},
2091 // Objective-C: class properties
2092 {
2093 R"cpp(
2094 @interface I {}
2095 @property(class) I *x;
2096 @end
2097 id local;
2098 void foo() {
2099 $0^I.$1^x = 0;
2100 $2^local = $3^I.$4^x;
2101 }
2102 )cpp",
2103 "0: targets = {I}\n"
2104 "1: targets = {I::setX:}\n"
2105 "2: targets = {local}\n"
2106 "3: targets = {I}\n"
2107 "4: targets = {I::x}\n"},
2108 // Objective-C: implicit class properties
2109 {
2110 R"cpp(
2111 @interface I {}
2112 +(I*)x;
2113 +(void)setX:(I*)x;
2114 @end
2115 id local;
2116 void foo() {
2117 $0^I.$1^x = 0;
2118 $2^local = $3^I.$4^x;
2119 }
2120 )cpp",
2121 "0: targets = {I}\n"
2122 "1: targets = {I::setX:}\n"
2123 "2: targets = {local}\n"
2124 "3: targets = {I}\n"
2125 "4: targets = {I::x}\n"},
2126 {// Objective-C: methods
2127 R"cpp(
2128 @interface I
2129 -(void) a:(int)x b:(int)y;
2130 @end
2131 void foo(I *i) {
2132 [$0^i $1^a:1 b:2];
2133 }
2134 )cpp",
2135 "0: targets = {i}\n"
2136 "1: targets = {I::a:b:}\n"},
2137 {// Objective-C: protocols
2138 R"cpp(
2139 @interface I
2140 @end
2141 @protocol P
2142 @end
2143 void foo() {
2144 $0^I<$1^P> *$2^x;
2145 }
2146 )cpp",
2147 "0: targets = {I}\n"
2148 "1: targets = {P}\n"
2149 "2: targets = {x}, decl\n"},
2150
2151 // Designated initializers.
2152 {R"cpp(
2153 void foo() {
2154 struct $0^Foo {
2155 int $1^Bar;
2156 };
2157 $2^Foo $3^f { .$4^Bar = 42 };
2158 }
2159 )cpp",
2160 "0: targets = {Foo}, decl\n"
2161 "1: targets = {foo()::Foo::Bar}, decl\n"
2162 "2: targets = {Foo}\n"
2163 "3: targets = {f}, decl\n"
2164 "4: targets = {foo()::Foo::Bar}\n"},
2165 {R"cpp(
2166 void foo() {
2167 struct $0^Baz {
2168 int $1^Field;
2169 };
2170 struct $2^Bar {
2171 $3^Baz $4^Foo;
2172 };
2173 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
2174 }
2175 )cpp",
2176 "0: targets = {Baz}, decl\n"
2177 "1: targets = {foo()::Baz::Field}, decl\n"
2178 "2: targets = {Bar}, decl\n"
2179 "3: targets = {Baz}\n"
2180 "4: targets = {foo()::Bar::Foo}, decl\n"
2181 "5: targets = {Bar}\n"
2182 "6: targets = {bar}, decl\n"
2183 "7: targets = {foo()::Bar::Foo}\n"
2184 "8: targets = {foo()::Baz::Field}\n"},
2185 // offsetof
2186 {R"cpp(
2187 void foo() {
2188 struct $0^Foo { int $1^bar; };
2189 int $2^x = __builtin_offsetof($3^Foo, $4^bar);
2190 }
2191 )cpp",
2192 "0: targets = {Foo}, decl\n"
2193 "1: targets = {foo()::Foo::bar}, decl\n"
2194 "2: targets = {x}, decl\n"
2195 "3: targets = {Foo}\n"
2196 "4: targets = {foo()::Foo::bar}\n"},
2197 // offsetof with a nested field designator -- each component must
2198 // resolve to its own source position, not a shared one.
2199 {R"cpp(
2200 void foo() {
2201 struct $0^A {
2202 $1^struct { int $2^c; } $3^B;
2203 };
2204 int $4^x = __builtin_offsetof($5^A, $6^B.$7^c);
2205 }
2206 )cpp",
2207 "0: targets = {A}, decl\n"
2208 "1: targets = {foo()::A::(unnamed struct)}\n"
2209 "2: targets = {foo()::A::(unnamed struct)::c}, decl\n"
2210 "3: targets = {foo()::A::B}, decl\n"
2211 "4: targets = {x}, decl\n"
2212 "5: targets = {A}\n"
2213 "6: targets = {foo()::A::B}\n"
2214 "7: targets = {foo()::A::(unnamed struct)::c}\n"},
2215 // offsetof with an array-subscript component -- array indices are not
2216 // emitted as offsetof references (the subscript expression is still
2217 // visited independently).
2218 {R"cpp(
2219 void foo() {
2220 struct $0^A { int $1^arr[4]; };
2221 int $2^i = 0;
2222 int $3^x = __builtin_offsetof($4^A, $5^arr[$6^i]);
2223 }
2224 )cpp",
2225 "0: targets = {A}, decl\n"
2226 "1: targets = {foo()::A::arr}, decl\n"
2227 "2: targets = {i}, decl\n"
2228 "3: targets = {x}, decl\n"
2229 "4: targets = {A}\n"
2230 "5: targets = {foo()::A::arr}\n"
2231 "6: targets = {i}\n"},
2232 {R"cpp(
2233 template<typename T>
2234 void crash(T);
2235 template<typename T>
2236 void foo() {
2237 $0^crash({.$1^x = $2^T()});
2238 }
2239 )cpp",
2240 "0: targets = {crash}\n"
2241 "1: targets = {}\n"
2242 "2: targets = {T}\n"},
2243 // unknown template name should not crash.
2244 {R"cpp(
2245 template <template <typename> typename T>
2246 struct Base {};
2247 namespace foo {
2248 template <typename $0^T>
2249 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
2250 }
2251 )cpp",
2252 "0: targets = {foo::Derive::T}, decl\n"
2253 "1: targets = {foo::Derive}, decl\n"
2254 "2: targets = {Base}\n"
2255 "3: targets = {foo::Derive::T}\n"
2256 "4: targets = {}, qualifier = 'T::'\n"},
2257 // deduction guide
2258 {R"cpp(
2259 namespace foo {
2260 template <typename $0^T>
2261 struct $1^Test {
2262 template <typename $2^I>
2263 $3^Test($4^I);
2264 };
2265 template <typename $5^I>
2266 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
2267 }
2268 )cpp",
2269 "0: targets = {T}, decl\n"
2270 "1: targets = {foo::Test}, decl\n"
2271 "2: targets = {I}, decl\n"
2272 "3: targets = {foo::Test::Test<T>}, decl\n"
2273 "4: targets = {I}\n"
2274 "5: targets = {I}, decl\n"
2275 "6: targets = {foo::Test}\n"
2276 "7: targets = {I}\n"
2277 "8: targets = {foo::Test}\n"
2278 "9: targets = {I}\n"
2279 "10: targets = {}, qualifier = 'I::'\n"}};
2280
2281 for (const auto &C : Cases) {
2282 llvm::StringRef ExpectedCode = C.first;
2283 llvm::StringRef ExpectedRefs = C.second;
2284
2285 auto Actual =
2286 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
2287 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2288 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2289 }
2290}
2291
2292TEST_F(FindExplicitReferencesTest, AllRefs) {
2293 std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
2294 {{R"cpp(
2295 @interface $0^MyClass
2296 @end
2297 @implementation $1^$2^MyClass
2298 @end
2299 )cpp",
2300 "0: targets = {MyClass}, decl\n"
2301 "1: targets = {MyClass}\n"
2302 "2: targets = {MyClass}, decl\n"},
2303 {R"cpp(
2304 @interface $0^MyClass
2305 @end
2306 @interface $1^MyClass ($2^Category)
2307 @end
2308 @implementation $3^MyClass ($4^$5^Category)
2309 @end
2310 )cpp",
2311 "0: targets = {MyClass}, decl\n"
2312 "1: targets = {MyClass}\n"
2313 "2: targets = {Category}, decl\n"
2314 "3: targets = {MyClass}\n"
2315 "4: targets = {Category}\n"
2316 "5: targets = {Category}, decl\n"}};
2317
2318 for (const auto &C : Cases) {
2319 llvm::StringRef ExpectedCode = C.first;
2320 llvm::StringRef ExpectedRefs = C.second;
2321
2322 auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());
2323 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2324 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2325 }
2326}
2327
2328} // namespace
2329} // namespace clangd
2330} // 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