clang-tools 17.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, NestedNameSpecifier) {
346 Code = R"cpp(
347 namespace a { namespace b { int c; } }
348 int x = a::[[b::]]c;
349 )cpp";
350 EXPECT_DECLS("NestedNameSpecifierLoc", "namespace b");
351
352 Code = R"cpp(
353 namespace a { struct X { enum { y }; }; }
354 int x = a::[[X::]]y;
355 )cpp";
356 EXPECT_DECLS("NestedNameSpecifierLoc", "struct X");
357
358 Code = R"cpp(
359 template <typename T>
360 int x = [[T::]]y;
361 )cpp";
362 EXPECT_DECLS("NestedNameSpecifierLoc", "typename T");
363
364 Code = R"cpp(
365 namespace a { int x; }
366 namespace b = a;
367 int y = [[b]]::x;
368 )cpp";
369 EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},
370 {"namespace a", Rel::Underlying});
371}
372
373TEST_F(TargetDeclTest, Types) {
374 Code = R"cpp(
375 struct X{};
376 [[X]] x;
377 )cpp";
378 EXPECT_DECLS("RecordTypeLoc", "struct X");
379
380 Code = R"cpp(
381 struct S{};
382 typedef S X;
383 [[X]] x;
384 )cpp";
385 EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},
386 {"struct S", Rel::Underlying});
387 Code = R"cpp(
388 namespace ns { struct S{}; }
389 typedef ns::S X;
390 [[X]] x;
391 )cpp";
392 EXPECT_DECLS("TypedefTypeLoc", {"typedef ns::S X", Rel::Alias},
393 {"struct S", Rel::Underlying});
394
395 Code = R"cpp(
396 template<class T>
397 void foo() { [[T]] x; }
398 )cpp";
399 EXPECT_DECLS("TemplateTypeParmTypeLoc", "class T");
400 Flags.clear();
401
402 Code = R"cpp(
403 template<template<typename> class T>
404 void foo() { [[T<int>]] x; }
405 )cpp";
406 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class T");
407 Flags.clear();
408
409 Code = R"cpp(
410 template<template<typename> class ...T>
411 class C {
412 C<[[T...]]> foo;
413 };
414 )cpp";
415 EXPECT_DECLS("TemplateArgumentLoc", {"template <typename> class ...T"});
416 Flags.clear();
417
418 Code = R"cpp(
419 struct S{};
420 S X;
421 [[decltype]](X) Y;
422 )cpp";
423 EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});
424
425 Code = R"cpp(
426 struct S{};
427 [[auto]] X = S{};
428 )cpp";
429 // FIXME: deduced type missing in AST. https://llvm.org/PR42914
430 EXPECT_DECLS("AutoTypeLoc");
431
432 Code = R"cpp(
433 template <typename... E>
434 struct S {
435 static const int size = sizeof...([[E]]);
436 };
437 )cpp";
438 EXPECT_DECLS("SizeOfPackExpr", "typename ...E");
439
440 Code = R"cpp(
441 template <typename T>
442 class Foo {
443 void f([[Foo]] x);
444 };
445 )cpp";
446 EXPECT_DECLS("InjectedClassNameTypeLoc", "class Foo");
447}
448
449TEST_F(TargetDeclTest, ClassTemplate) {
450 Code = R"cpp(
451 // Implicit specialization.
452 template<int x> class Foo{};
453 [[Foo<42>]] B;
454 )cpp";
455 EXPECT_DECLS("TemplateSpecializationTypeLoc",
456 {"template<> class Foo<42>", Rel::TemplateInstantiation},
457 {"class Foo", Rel::TemplatePattern});
458
459 Code = R"cpp(
460 template<typename T> class Foo {};
461 // The "Foo<int>" SpecializationDecl is incomplete, there is no
462 // instantiation happening.
463 void func([[Foo<int>]] *);
464 )cpp";
465 EXPECT_DECLS("TemplateSpecializationTypeLoc",
466 {"class Foo", Rel::TemplatePattern},
467 {"template<> class Foo<int>", Rel::TemplateInstantiation});
468
469 Code = R"cpp(
470 // Explicit specialization.
471 template<int x> class Foo{};
472 template<> class Foo<42>{};
473 [[Foo<42>]] B;
474 )cpp";
475 EXPECT_DECLS("TemplateSpecializationTypeLoc", "template<> class Foo<42>");
476
477 Code = R"cpp(
478 // Partial specialization.
479 template<typename T> class Foo{};
480 template<typename T> class Foo<T*>{};
481 [[Foo<int*>]] B;
482 )cpp";
483 EXPECT_DECLS("TemplateSpecializationTypeLoc",
484 {"template<> class Foo<int *>", Rel::TemplateInstantiation},
485 {"template <typename T> class Foo<T *>", Rel::TemplatePattern});
486
487 Code = R"cpp(
488 // Template template argument.
489 template<typename T> struct Vector {};
490 template <template <typename> class Container>
491 struct A {};
492 A<[[Vector]]> a;
493 )cpp";
494 EXPECT_DECLS("TemplateArgumentLoc", {"template <typename T> struct Vector"});
495
496 Flags.push_back("-std=c++17"); // for CTAD tests
497
498 Code = R"cpp(
499 // Class template argument deduction
500 template <typename T>
501 struct Test {
502 Test(T);
503 };
504 void foo() {
505 [[Test]] a(5);
506 }
507 )cpp";
508 EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
509 {"struct Test", Rel::TemplatePattern});
510
511 Code = R"cpp(
512 // Deduction guide
513 template <typename T>
514 struct Test {
515 template <typename I>
516 Test(I, I);
517 };
518 template <typename I>
519 [[Test]](I, I) -> Test<typename I::type>;
520 )cpp";
521 EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"});
522}
523
524TEST_F(TargetDeclTest, Concept) {
525 Flags.push_back("-std=c++20");
526
527 // FIXME: Should we truncate the pretty-printed form of a concept decl
528 // somewhere?
529
530 Code = R"cpp(
531 template <typename T>
532 concept Fooable = requires (T t) { t.foo(); };
533
534 template <typename T> requires [[Fooable]]<T>
535 void bar(T t) {
536 t.foo();
537 }
538 )cpp";
540 "ConceptSpecializationExpr",
541 {"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
542
543 // trailing requires clause
544 Code = R"cpp(
545 template <typename T>
546 concept Fooable = true;
547
548 template <typename T>
549 void foo() requires [[Fooable]]<T>;
550 )cpp";
551 EXPECT_DECLS("ConceptSpecializationExpr",
552 {"template <typename T> concept Fooable = true"});
553
554 // constrained-parameter
555 Code = R"cpp(
556 template <typename T>
557 concept Fooable = true;
558
559 template <[[Fooable]] T>
560 void bar(T t);
561 )cpp";
562 EXPECT_DECLS("ConceptSpecializationExpr",
563 {"template <typename T> concept Fooable = true"});
564
565 // partial-concept-id
566 Code = R"cpp(
567 template <typename T, typename U>
568 concept Fooable = true;
569
570 template <[[Fooable]]<int> T>
571 void bar(T t);
572 )cpp";
573 EXPECT_DECLS("ConceptSpecializationExpr",
574 {"template <typename T, typename U> concept Fooable = true"});
575}
576
577TEST_F(TargetDeclTest, Coroutine) {
578 Flags.push_back("-std=c++20");
579
580 Code = R"cpp(
581 namespace std {
582 template <typename, typename...> struct coroutine_traits;
583 template <typename> struct coroutine_handle {
584 template <typename U>
585 coroutine_handle(coroutine_handle<U>&&) noexcept;
586 static coroutine_handle from_address(void* __addr) noexcept;
587 };
588 } // namespace std
589
590 struct executor {};
591 struct awaitable {};
592 struct awaitable_frame {
593 awaitable get_return_object();
594 void return_void();
595 void unhandled_exception();
596 struct result_t {
597 ~result_t();
598 bool await_ready() const noexcept;
599 void await_suspend(std::coroutine_handle<void>) noexcept;
600 void await_resume() const noexcept;
601 };
602 result_t initial_suspend() noexcept;
603 result_t final_suspend() noexcept;
604 result_t await_transform(executor) noexcept;
605 };
606
607 namespace std {
608 template <>
609 struct coroutine_traits<awaitable> {
610 typedef awaitable_frame promise_type;
611 };
612 } // namespace std
613
614 awaitable foo() {
615 co_await [[executor]]();
616 }
617 )cpp";
618 EXPECT_DECLS("RecordTypeLoc", "struct executor");
619}
620
621TEST_F(TargetDeclTest, FunctionTemplate) {
622 Code = R"cpp(
623 // Implicit specialization.
624 template<typename T> bool foo(T) { return false; };
625 bool x = [[foo]](42);
626 )cpp";
627 EXPECT_DECLS("DeclRefExpr",
628 {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
629 {"bool foo(T)", Rel::TemplatePattern});
630
631 Code = R"cpp(
632 // Explicit specialization.
633 template<typename T> bool foo(T) { return false; };
634 template<> bool foo<int>(int) { return false; };
635 bool x = [[foo]](42);
636 )cpp";
637 EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");
638}
639
640TEST_F(TargetDeclTest, VariableTemplate) {
641 // Pretty-printer doesn't do a very good job of variable templates :-(
642 Code = R"cpp(
643 // Implicit specialization.
644 template<typename T> int foo;
645 int x = [[foo]]<char>;
646 )cpp";
647 EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},
648 {"int foo", Rel::TemplatePattern});
649
650 Code = R"cpp(
651 // Explicit specialization.
652 template<typename T> int foo;
653 template <> bool foo<char>;
654 int x = [[foo]]<char>;
655 )cpp";
656 EXPECT_DECLS("DeclRefExpr", "bool foo");
657
658 Code = R"cpp(
659 // Partial specialization.
660 template<typename T> int foo;
661 template<typename T> bool foo<T*>;
662 bool x = [[foo]]<char*>;
663 )cpp";
664 EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},
665 {"bool foo", Rel::TemplatePattern});
666}
667
668TEST_F(TargetDeclTest, TypeAliasTemplate) {
669 Code = R"cpp(
670 template<typename T, int X> class SmallVector {};
671 template<typename U> using TinyVector = SmallVector<U, 1>;
672 [[TinyVector<int>]] X;
673 )cpp";
674 EXPECT_DECLS("TemplateSpecializationTypeLoc",
675 {"template<> class SmallVector<int, 1>",
676 Rel::TemplateInstantiation | Rel::Underlying},
677 {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
678 {"using TinyVector = SmallVector<U, 1>",
679 Rel::Alias | Rel::TemplatePattern});
680}
681
682TEST_F(TargetDeclTest, MemberOfTemplate) {
683 Code = R"cpp(
684 template <typename T> struct Foo {
685 int x(T);
686 };
687 int y = Foo<int>().[[x]](42);
688 )cpp";
689 EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},
690 {"int x(T)", Rel::TemplatePattern});
691
692 Code = R"cpp(
693 template <typename T> struct Foo {
694 template <typename U>
695 int x(T, U);
696 };
697 int y = Foo<char>().[[x]]('c', 42);
698 )cpp";
699 EXPECT_DECLS("MemberExpr",
700 {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
701 {"int x(T, U)", Rel::TemplatePattern});
702}
703
704TEST_F(TargetDeclTest, Lambda) {
705 Code = R"cpp(
706 void foo(int x = 42) {
707 auto l = [ [[x]] ]{ return x + 1; };
708 };
709 )cpp";
710 EXPECT_DECLS("DeclRefExpr", "int x = 42");
711
712 // It seems like this should refer to another var, with the outer param being
713 // an underlying decl. But it doesn't seem to exist.
714 Code = R"cpp(
715 void foo(int x = 42) {
716 auto l = [x]{ return [[x]] + 1; };
717 };
718 )cpp";
719 EXPECT_DECLS("DeclRefExpr", "int x = 42");
720
721 Code = R"cpp(
722 void foo() {
723 auto l = [x = 1]{ return [[x]] + 1; };
724 };
725 )cpp";
726 // FIXME: why both auto and int?
727 EXPECT_DECLS("DeclRefExpr", "auto int x = 1");
728}
729
730TEST_F(TargetDeclTest, OverloadExpr) {
731 Flags.push_back("--target=x86_64-pc-linux-gnu");
732
733 Code = R"cpp(
734 void func(int*);
735 void func(char*);
736
737 template <class T>
738 void foo(T t) {
739 [[func]](t);
740 };
741 )cpp";
742 EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");
743
744 Code = R"cpp(
745 struct X {
746 void func(int*);
747 void func(char*);
748 };
749
750 template <class T>
751 void foo(X x, T t) {
752 x.[[func]](t);
753 };
754 )cpp";
755 EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");
756
757 Code = R"cpp(
758 struct X {
759 static void *operator new(unsigned long);
760 };
761 auto* k = [[new]] X();
762 )cpp";
763 EXPECT_DECLS("CXXNewExpr", "static void *operator new(unsigned long)");
764 Code = R"cpp(
765 void *operator new(unsigned long);
766 auto* k = [[new]] int();
767 )cpp";
768 EXPECT_DECLS("CXXNewExpr", "void *operator new(unsigned long)");
769
770 Code = R"cpp(
771 struct X {
772 static void operator delete(void *) noexcept;
773 };
774 void k(X* x) {
775 [[delete]] x;
776 }
777 )cpp";
778 EXPECT_DECLS("CXXDeleteExpr", "static void operator delete(void *) noexcept");
779 Code = R"cpp(
780 void operator delete(void *) noexcept;
781 void k(int* x) {
782 [[delete]] x;
783 }
784 )cpp";
785 EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept");
786}
787
788TEST_F(TargetDeclTest, DependentExprs) {
789 // Heuristic resolution of method of dependent field
790 Code = R"cpp(
791 struct A { void foo() {} };
792 template <typename T>
793 struct B {
794 A a;
795 void bar() {
796 this->a.[[foo]]();
797 }
798 };
799 )cpp";
800 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
801
802 // Similar to above but base expression involves a function call.
803 Code = R"cpp(
804 struct A {
805 void foo() {}
806 };
807 struct B {
808 A getA();
809 };
810 template <typename T>
811 struct C {
812 B c;
813 void bar() {
814 this->c.getA().[[foo]]();
815 }
816 };
817 )cpp";
818 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
819
820 // Similar to above but uses a function pointer.
821 Code = R"cpp(
822 struct A {
823 void foo() {}
824 };
825 struct B {
826 using FPtr = A(*)();
827 FPtr fptr;
828 };
829 template <typename T>
830 struct C {
831 B c;
832 void bar() {
833 this->c.fptr().[[foo]]();
834 }
835 };
836 )cpp";
837 EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
838
839 // Base expression involves a member access into this.
840 Code = R"cpp(
841 struct Bar {
842 int aaaa;
843 };
844 template <typename T> struct Foo {
845 Bar func(int);
846 void test() {
847 func(1).[[aaaa]];
848 }
849 };
850 )cpp";
851 EXPECT_DECLS("CXXDependentScopeMemberExpr", "int aaaa");
852
853 Code = R"cpp(
854 class Foo {
855 public:
856 static Foo k(int);
857 template <typename T> T convert() const;
858 };
859 template <typename T>
860 void test() {
861 Foo::k(T()).template [[convert]]<T>();
862 }
863 )cpp";
864 EXPECT_DECLS("CXXDependentScopeMemberExpr",
865 "template <typename T> T convert() const");
866}
867
868TEST_F(TargetDeclTest, DependentTypes) {
869 // Heuristic resolution of dependent type name
870 Code = R"cpp(
871 template <typename>
872 struct A { struct B {}; };
873
874 template <typename T>
875 void foo(typename A<T>::[[B]]);
876 )cpp";
877 EXPECT_DECLS("DependentNameTypeLoc", "struct B");
878
879 // Heuristic resolution of dependent type name which doesn't get a TypeLoc
880 Code = R"cpp(
881 template <typename>
882 struct A { struct B { struct C {}; }; };
883
884 template <typename T>
885 void foo(typename A<T>::[[B]]::C);
886 )cpp";
887 EXPECT_DECLS("NestedNameSpecifierLoc", "struct B");
888
889 // Heuristic resolution of dependent type name whose qualifier is also
890 // dependent
891 Code = R"cpp(
892 template <typename>
893 struct A { struct B { struct C {}; }; };
894
895 template <typename T>
896 void foo(typename A<T>::B::[[C]]);
897 )cpp";
898 EXPECT_DECLS("DependentNameTypeLoc", "struct C");
899
900 // Heuristic resolution of dependent template name
901 Code = R"cpp(
902 template <typename>
903 struct A {
904 template <typename> struct B {};
905 };
906
907 template <typename T>
908 void foo(typename A<T>::template [[B]]<int>);
909 )cpp";
910 EXPECT_DECLS("DependentTemplateSpecializationTypeLoc",
911 "template <typename> struct B");
912}
913
914TEST_F(TargetDeclTest, TypedefCascade) {
915 Code = R"cpp(
916 struct C {
917 using type = int;
918 };
919 struct B {
920 using type = C::type;
921 };
922 struct A {
923 using type = B::type;
924 };
925 A::[[type]] waldo;
926 )cpp";
927 EXPECT_DECLS("TypedefTypeLoc",
928 {"using type = int", Rel::Alias | Rel::Underlying},
929 {"using type = C::type", Rel::Alias | Rel::Underlying},
930 {"using type = B::type", Rel::Alias});
931}
932
933TEST_F(TargetDeclTest, RecursiveTemplate) {
934 Flags.push_back("-std=c++20"); // the test case uses concepts
935
936 Code = R"cpp(
937 template <typename T>
938 concept Leaf = false;
939
940 template <typename Tree>
941 struct descend_left {
942 using type = typename descend_left<typename Tree::left>::[[type]];
943 };
944
945 template <Leaf Tree>
946 struct descend_left<Tree> {
947 using type = typename Tree::value;
948 };
949 )cpp";
950 EXPECT_DECLS("DependentNameTypeLoc",
951 {"using type = typename descend_left<typename Tree::left>::type",
952 Rel::Alias | Rel::Underlying});
953}
954
955TEST_F(TargetDeclTest, ObjC) {
956 Flags = {"-xobjective-c"};
957 Code = R"cpp(
958 @interface Foo {}
959 -(void)bar;
960 @end
961 void test(Foo *f) {
962 [f [[bar]] ];
963 }
964 )cpp";
965 EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");
966
967 Code = R"cpp(
968 @interface Foo { @public int bar; }
969 @end
970 int test(Foo *f) {
971 return [[f->bar]];
972 }
973 )cpp";
974 EXPECT_DECLS("ObjCIvarRefExpr", "int bar");
975
976 Code = R"cpp(
977 @interface Foo {}
978 -(int) x;
979 -(void) setX:(int)x;
980 @end
981 void test(Foo *f) {
982 [[f.x]] = 42;
983 }
984 )cpp";
985 EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");
986
987 Code = R"cpp(
988 @interface I {}
989 @property(retain) I* x;
990 @property(retain) I* y;
991 @end
992 void test(I *f) {
993 [[f.x]].y = 0;
994 }
995 )cpp";
996 EXPECT_DECLS("ObjCPropertyRefExpr",
997 "@property(atomic, retain, readwrite) I *x");
998
999 Code = R"cpp(
1000 @interface MYObject
1001 @end
1002 @interface Interface
1003 @property(retain) [[MYObject]] *x;
1004 @end
1005 )cpp";
1006 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject");
1007
1008 Code = R"cpp(
1009 @interface MYObject2
1010 @end
1011 @interface Interface
1012 @property(retain, nonnull) [[MYObject2]] *x;
1013 @end
1014 )cpp";
1015 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject2");
1016
1017 Code = R"cpp(
1018 @protocol Foo
1019 @end
1020 id test() {
1021 return [[@protocol(Foo)]];
1022 }
1023 )cpp";
1024 EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");
1025
1026 Code = R"cpp(
1027 @interface Foo
1028 @end
1029 void test([[Foo]] *p);
1030 )cpp";
1031 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1032
1033 Code = R"cpp(// Don't consider implicit interface as the target.
1034 @implementation [[Implicit]]
1035 @end
1036 )cpp";
1037 EXPECT_DECLS("ObjCImplementationDecl", "@implementation Implicit");
1038
1039 Code = R"cpp(
1040 @interface Foo
1041 @end
1042 @implementation [[Foo]]
1043 @end
1044 )cpp";
1045 EXPECT_DECLS("ObjCImplementationDecl", "@interface Foo");
1046
1047 Code = R"cpp(
1048 @interface Foo
1049 @end
1050 @interface Foo (Ext)
1051 @end
1052 @implementation [[Foo]] (Ext)
1053 @end
1054 )cpp";
1055 EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");
1056
1057 Code = R"cpp(
1058 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1059 )cpp";
1060 EXPECT_DECLS("ParmVarDecl", "id p");
1061
1062 Code = R"cpp(
1063 @class C;
1064 @protocol Foo
1065 @end
1066 void test([[C]]<Foo> *p);
1067 )cpp";
1068 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@class C;");
1069
1070 Code = R"cpp(
1071 @class C;
1072 @protocol Foo
1073 @end
1074 void test(C<[[Foo]]> *p);
1075 )cpp";
1076 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1077
1078 Code = R"cpp(
1079 @class C;
1080 @protocol Foo
1081 @end
1082 @protocol Bar
1083 @end
1084 void test(C<[[Foo]], Bar> *p);
1085 )cpp";
1086 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");
1087
1088 Code = R"cpp(
1089 @class C;
1090 @protocol Foo
1091 @end
1092 @protocol Bar
1093 @end
1094 void test(C<Foo, [[Bar]]> *p);
1095 )cpp";
1096 EXPECT_DECLS("ObjCProtocolLoc", "@protocol Bar");
1097
1098 Code = R"cpp(
1099 @interface Foo
1100 + (id)sharedInstance;
1101 @end
1102 @implementation Foo
1103 + (id)sharedInstance { return 0; }
1104 @end
1105 void test() {
1106 id value = [[Foo]].sharedInstance;
1107 }
1108 )cpp";
1109 EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
1110
1111 Code = R"cpp(
1112 @interface Foo
1113 + (id)sharedInstance;
1114 @end
1115 @implementation Foo
1116 + (id)sharedInstance { return 0; }
1117 @end
1118 void test() {
1119 id value = Foo.[[sharedInstance]];
1120 }
1121 )cpp";
1122 EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
1123
1124 Code = R"cpp(
1125 @interface Foo
1126 + ([[id]])sharedInstance;
1127 @end
1128 )cpp";
1129 EXPECT_DECLS("TypedefTypeLoc");
1130
1131 Code = R"cpp(
1132 @interface Foo
1133 + ([[instancetype]])sharedInstance;
1134 @end
1135 )cpp";
1136 EXPECT_DECLS("TypedefTypeLoc");
1137}
1138
1139class FindExplicitReferencesTest : public ::testing::Test {
1140protected:
1141 struct AllRefs {
1142 std::string AnnotatedCode;
1143 std::string DumpedReferences;
1144 };
1145
1146 /// Parses \p Code, finds function or namespace '::foo' and annotates its body
1147 /// with results of findExplicitReferences.
1148 /// See actual tests for examples of annotation format.
1149 AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
1150 TestTU TU;
1151 TU.Code = std::string(Code);
1152
1153 // FIXME: Auto-completion in a template requires disabling delayed template
1154 // parsing.
1155 TU.ExtraArgs.push_back("-std=c++20");
1156 TU.ExtraArgs.push_back("-xobjective-c++");
1157
1158 auto AST = TU.build();
1159 auto *TestDecl = &findDecl(AST, "foo");
1160 if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1161 TestDecl = T->getTemplatedDecl();
1162
1163 std::vector<ReferenceLoc> Refs;
1164 if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1166 Func->getBody(),
1167 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1168 AST.getHeuristicResolver());
1169 else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1171 NS,
1172 [&Refs, &NS](ReferenceLoc R) {
1173 // Avoid adding the namespace foo decl to the results.
1174 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1175 return;
1176 Refs.push_back(std::move(R));
1177 },
1178 AST.getHeuristicResolver());
1179 else
1180 ADD_FAILURE() << "Failed to find ::foo decl for test";
1181
1182 auto &SM = AST.getSourceManager();
1183 llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
1184 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1185 });
1186
1187 std::string AnnotatedCode;
1188 unsigned NextCodeChar = 0;
1189 for (unsigned I = 0; I < Refs.size(); ++I) {
1190 auto &R = Refs[I];
1191
1192 SourceLocation Pos = R.NameLoc;
1193 assert(Pos.isValid());
1194 if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.
1195 Pos = SM.getExpansionLoc(Pos);
1196 assert(Pos.isFileID());
1197
1198 FileID File;
1199 unsigned Offset;
1200 std::tie(File, Offset) = SM.getDecomposedLoc(Pos);
1201 if (File == SM.getMainFileID()) {
1202 // Print the reference in a source code.
1203 assert(NextCodeChar <= Offset);
1204 AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
1205 AnnotatedCode += "$" + std::to_string(I) + "^";
1206
1207 NextCodeChar = Offset;
1208 }
1209 }
1210 AnnotatedCode += Code.substr(NextCodeChar);
1211
1212 std::string DumpedReferences;
1213 for (unsigned I = 0; I < Refs.size(); ++I)
1214 DumpedReferences += std::string(llvm::formatv("{0}: {1}\n", I, Refs[I]));
1215
1216 return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
1217 }
1218};
1219
1220TEST_F(FindExplicitReferencesTest, All) {
1221 std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
1222 {// Simple expressions.
1223 {R"cpp(
1224 int global;
1225 int func();
1226 void foo(int param) {
1227 $0^global = $1^param + $2^func();
1228 }
1229 )cpp",
1230 "0: targets = {global}\n"
1231 "1: targets = {param}\n"
1232 "2: targets = {func}\n"},
1233 {R"cpp(
1234 struct X { int a; };
1235 void foo(X x) {
1236 $0^x.$1^a = 10;
1237 }
1238 )cpp",
1239 "0: targets = {x}\n"
1240 "1: targets = {X::a}\n"},
1241 {R"cpp(
1242 // error-ok: testing with broken code
1243 int bar();
1244 int foo() {
1245 return $0^bar() + $1^bar(42);
1246 }
1247 )cpp",
1248 "0: targets = {bar}\n"
1249 "1: targets = {bar}\n"},
1250 // Namespaces and aliases.
1251 {R"cpp(
1252 namespace ns {}
1253 namespace alias = ns;
1254 void foo() {
1255 using namespace $0^ns;
1256 using namespace $1^alias;
1257 }
1258 )cpp",
1259 "0: targets = {ns}\n"
1260 "1: targets = {alias}\n"},
1261 // Using declarations.
1262 {R"cpp(
1263 namespace ns { int global; }
1264 void foo() {
1265 using $0^ns::$1^global;
1266 }
1267 )cpp",
1268 "0: targets = {ns}\n"
1269 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1270 // Using enum declarations.
1271 {R"cpp(
1272 namespace ns { enum class A {}; }
1273 void foo() {
1274 using enum $0^ns::$1^A;
1275 }
1276 )cpp",
1277 "0: targets = {ns}\n"
1278 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1279 // Simple types.
1280 {R"cpp(
1281 struct Struct { int a; };
1282 using Typedef = int;
1283 void foo() {
1284 $0^Struct $1^x;
1285 $2^Typedef $3^y;
1286 static_cast<$4^Struct*>(0);
1287 }
1288 )cpp",
1289 "0: targets = {Struct}\n"
1290 "1: targets = {x}, decl\n"
1291 "2: targets = {Typedef}\n"
1292 "3: targets = {y}, decl\n"
1293 "4: targets = {Struct}\n"},
1294 // Name qualifiers.
1295 {R"cpp(
1296 namespace a { namespace b { struct S { typedef int type; }; } }
1297 void foo() {
1298 $0^a::$1^b::$2^S $3^x;
1299 using namespace $4^a::$5^b;
1300 $6^S::$7^type $8^y;
1301 }
1302 )cpp",
1303 "0: targets = {a}\n"
1304 "1: targets = {a::b}, qualifier = 'a::'\n"
1305 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1306 "3: targets = {x}, decl\n"
1307 "4: targets = {a}\n"
1308 "5: targets = {a::b}, qualifier = 'a::'\n"
1309 "6: targets = {a::b::S}\n"
1310 "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
1311 "8: targets = {y}, decl\n"},
1312 {R"cpp(
1313 void foo() {
1314 $0^ten: // PRINT "HELLO WORLD!"
1315 goto $1^ten;
1316 }
1317 )cpp",
1318 "0: targets = {ten}, decl\n"
1319 "1: targets = {ten}\n"},
1320 // Simple templates.
1321 {R"cpp(
1322 template <class T> struct vector { using value_type = T; };
1323 template <> struct vector<bool> { using value_type = bool; };
1324 void foo() {
1325 $0^vector<int> $1^vi;
1326 $2^vector<bool> $3^vb;
1327 }
1328 )cpp",
1329 "0: targets = {vector<int>}\n"
1330 "1: targets = {vi}, decl\n"
1331 "2: targets = {vector<bool>}\n"
1332 "3: targets = {vb}, decl\n"},
1333 // Template type aliases.
1334 {R"cpp(
1335 template <class T> struct vector { using value_type = T; };
1336 template <> struct vector<bool> { using value_type = bool; };
1337 template <class T> using valias = vector<T>;
1338 void foo() {
1339 $0^valias<int> $1^vi;
1340 $2^valias<bool> $3^vb;
1341 }
1342 )cpp",
1343 "0: targets = {valias}\n"
1344 "1: targets = {vi}, decl\n"
1345 "2: targets = {valias}\n"
1346 "3: targets = {vb}, decl\n"},
1347 // Injected class name.
1348 {R"cpp(
1349 namespace foo {
1350 template <typename $0^T>
1351 class $1^Bar {
1352 ~$2^Bar();
1353 void $3^f($4^Bar);
1354 };
1355 }
1356 )cpp",
1357 "0: targets = {foo::Bar::T}, decl\n"
1358 "1: targets = {foo::Bar}, decl\n"
1359 "2: targets = {foo::Bar}\n"
1360 "3: targets = {foo::Bar::f}, decl\n"
1361 "4: targets = {foo::Bar}\n"},
1362 // MemberExpr should know their using declaration.
1363 {R"cpp(
1364 struct X { void func(int); };
1365 struct Y : X {
1366 using X::func;
1367 };
1368 void foo(Y y) {
1369 $0^y.$1^func(1);
1370 }
1371 )cpp",
1372 "0: targets = {y}\n"
1373 "1: targets = {Y::func}\n"},
1374 // DeclRefExpr should know their using declaration.
1375 {R"cpp(
1376 namespace ns { void bar(int); }
1377 using ns::bar;
1378
1379 void foo() {
1380 $0^bar(10);
1381 }
1382 )cpp",
1383 "0: targets = {bar}\n"},
1384 // References from a macro.
1385 {R"cpp(
1386 #define FOO a
1387 #define BAR b
1388
1389 void foo(int a, int b) {
1390 $0^FOO+$1^BAR;
1391 }
1392 )cpp",
1393 "0: targets = {a}\n"
1394 "1: targets = {b}\n"},
1395 // No references from implicit nodes.
1396 {R"cpp(
1397 struct vector {
1398 int *begin();
1399 int *end();
1400 };
1401
1402 void foo() {
1403 for (int $0^x : $1^vector()) {
1404 $2^x = 10;
1405 }
1406 }
1407 )cpp",
1408 "0: targets = {x}, decl\n"
1409 "1: targets = {vector}\n"
1410 "2: targets = {x}\n"},
1411 // Handle UnresolvedLookupExpr.
1412 {R"cpp(
1413 namespace ns1 { void func(char*); }
1414 namespace ns2 { void func(int*); }
1415 using namespace ns1;
1416 using namespace ns2;
1417
1418 template <class T>
1419 void foo(T t) {
1420 $0^func($1^t);
1421 }
1422 )cpp",
1423 "0: targets = {ns1::func, ns2::func}\n"
1424 "1: targets = {t}\n"},
1425 // Handle UnresolvedMemberExpr.
1426 {R"cpp(
1427 struct X {
1428 void func(char*);
1429 void func(int*);
1430 };
1431
1432 template <class T>
1433 void foo(X x, T t) {
1434 $0^x.$1^func($2^t);
1435 }
1436 )cpp",
1437 "0: targets = {x}\n"
1438 "1: targets = {X::func, X::func}\n"
1439 "2: targets = {t}\n"},
1440 // Handle DependentScopeDeclRefExpr.
1441 {R"cpp(
1442 template <class T>
1443 struct S {
1444 static int value;
1445 };
1446
1447 template <class T>
1448 void foo() {
1449 $0^S<$1^T>::$2^value;
1450 }
1451 )cpp",
1452 "0: targets = {S}\n"
1453 "1: targets = {T}\n"
1454 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1455 // Handle CXXDependentScopeMemberExpr.
1456 {R"cpp(
1457 template <class T>
1458 struct S {
1459 int value;
1460 };
1461
1462 template <class T>
1463 void foo(S<T> t) {
1464 $0^t.$1^value;
1465 }
1466 )cpp",
1467 "0: targets = {t}\n"
1468 "1: targets = {S::value}\n"},
1469 // Type template parameters.
1470 {R"cpp(
1471 template <class T>
1472 void foo() {
1473 static_cast<$0^T>(0);
1474 $1^T();
1475 $2^T $3^t;
1476 }
1477 )cpp",
1478 "0: targets = {T}\n"
1479 "1: targets = {T}\n"
1480 "2: targets = {T}\n"
1481 "3: targets = {t}, decl\n"},
1482 // Non-type template parameters.
1483 {R"cpp(
1484 template <int I>
1485 void foo() {
1486 int $0^x = $1^I;
1487 }
1488 )cpp",
1489 "0: targets = {x}, decl\n"
1490 "1: targets = {I}\n"},
1491 // Template template parameters.
1492 {R"cpp(
1493 template <class T> struct vector {};
1494
1495 template <template<class> class TT, template<class> class ...TP>
1496 void foo() {
1497 $0^TT<int> $1^x;
1498 $2^foo<$3^TT>();
1499 $4^foo<$5^vector>();
1500 $6^foo<$7^TP...>();
1501 }
1502 )cpp",
1503 "0: targets = {TT}\n"
1504 "1: targets = {x}, decl\n"
1505 "2: targets = {foo}\n"
1506 "3: targets = {TT}\n"
1507 "4: targets = {foo}\n"
1508 "5: targets = {vector}\n"
1509 "6: targets = {foo}\n"
1510 "7: targets = {TP}\n"},
1511 // Non-type template parameters with declarations.
1512 {R"cpp(
1513 int func();
1514 template <int(*)()> struct wrapper {};
1515
1516 template <int(*FuncParam)()>
1517 void foo() {
1518 $0^wrapper<$1^func> $2^w;
1519 $3^FuncParam();
1520 }
1521 )cpp",
1522 "0: targets = {wrapper<&func>}\n"
1523 "1: targets = {func}\n"
1524 "2: targets = {w}, decl\n"
1525 "3: targets = {FuncParam}\n"},
1526 // declaration references.
1527 {R"cpp(
1528 namespace ns {}
1529 class S {};
1530 void foo() {
1531 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1532 int $4^Var;
1533 enum $5^E { $6^ABC };
1534 typedef int $7^INT;
1535 using $8^INT2 = int;
1536 namespace $9^NS = $10^ns;
1537 }
1538 )cpp",
1539 "0: targets = {Foo}, decl\n"
1540 "1: targets = {foo()::Foo::Foo}, decl\n"
1541 "2: targets = {Foo}\n"
1542 "3: targets = {foo()::Foo::field}, decl\n"
1543 "4: targets = {Var}, decl\n"
1544 "5: targets = {E}, decl\n"
1545 "6: targets = {foo()::ABC}, decl\n"
1546 "7: targets = {INT}, decl\n"
1547 "8: targets = {INT2}, decl\n"
1548 "9: targets = {NS}, decl\n"
1549 "10: targets = {ns}\n"},
1550 // User-defined conversion operator.
1551 {R"cpp(
1552 void foo() {
1553 class $0^Bar {};
1554 class $1^Foo {
1555 public:
1556 // FIXME: This should have only one reference to Bar.
1557 $2^operator $3^$4^Bar();
1558 };
1559
1560 $5^Foo $6^f;
1561 $7^f.$8^operator $9^Bar();
1562 }
1563 )cpp",
1564 "0: targets = {Bar}, decl\n"
1565 "1: targets = {Foo}, decl\n"
1566 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1567 "3: targets = {Bar}\n"
1568 "4: targets = {Bar}\n"
1569 "5: targets = {Foo}\n"
1570 "6: targets = {f}, decl\n"
1571 "7: targets = {f}\n"
1572 "8: targets = {foo()::Foo::operator Bar}\n"
1573 "9: targets = {Bar}\n"},
1574 // Destructor.
1575 {R"cpp(
1576 void foo() {
1577 class $0^Foo {
1578 public:
1579 ~$1^Foo() {}
1580
1581 void $2^destructMe() {
1582 this->~$3^Foo();
1583 }
1584 };
1585
1586 $4^Foo $5^f;
1587 $6^f.~ /*...*/ $7^Foo();
1588 }
1589 )cpp",
1590 "0: targets = {Foo}, decl\n"
1591 // FIXME: It's better to target destructor's FunctionDecl instead of
1592 // the type itself (similar to constructor).
1593 "1: targets = {Foo}\n"
1594 "2: targets = {foo()::Foo::destructMe}, decl\n"
1595 "3: targets = {Foo}\n"
1596 "4: targets = {Foo}\n"
1597 "5: targets = {f}, decl\n"
1598 "6: targets = {f}\n"
1599 "7: targets = {Foo}\n"},
1600 // cxx constructor initializer.
1601 {R"cpp(
1602 class Base {};
1603 void foo() {
1604 // member initializer
1605 class $0^X {
1606 int $1^abc;
1607 $2^X(): $3^abc() {}
1608 };
1609 // base initializer
1610 class $4^Derived : public $5^Base {
1611 $6^Base $7^B;
1612 $8^Derived() : $9^Base() {}
1613 };
1614 // delegating initializer
1615 class $10^Foo {
1616 $11^Foo(int);
1617 $12^Foo(): $13^Foo(111) {}
1618 };
1619 }
1620 )cpp",
1621 "0: targets = {X}, decl\n"
1622 "1: targets = {foo()::X::abc}, decl\n"
1623 "2: targets = {foo()::X::X}, decl\n"
1624 "3: targets = {foo()::X::abc}\n"
1625 "4: targets = {Derived}, decl\n"
1626 "5: targets = {Base}\n"
1627 "6: targets = {Base}\n"
1628 "7: targets = {foo()::Derived::B}, decl\n"
1629 "8: targets = {foo()::Derived::Derived}, decl\n"
1630 "9: targets = {Base}\n"
1631 "10: targets = {Foo}, decl\n"
1632 "11: targets = {foo()::Foo::Foo}, decl\n"
1633 "12: targets = {foo()::Foo::Foo}, decl\n"
1634 "13: targets = {Foo}\n"},
1635 // Anonymous entities should not be reported.
1636 {
1637 R"cpp(
1638 void foo() {
1639 $0^class {} $1^x;
1640 int (*$2^fptr)(int $3^a, int) = nullptr;
1641 }
1642 )cpp",
1643 "0: targets = {(unnamed)}\n"
1644 "1: targets = {x}, decl\n"
1645 "2: targets = {fptr}, decl\n"
1646 "3: targets = {a}, decl\n"},
1647 // Namespace aliases should be handled properly.
1648 {
1649 R"cpp(
1650 namespace ns { struct Type {}; }
1651 namespace alias = ns;
1652 namespace rec_alias = alias;
1653
1654 void foo() {
1655 $0^ns::$1^Type $2^a;
1656 $3^alias::$4^Type $5^b;
1657 $6^rec_alias::$7^Type $8^c;
1658 }
1659 )cpp",
1660 "0: targets = {ns}\n"
1661 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1662 "2: targets = {a}, decl\n"
1663 "3: targets = {alias}\n"
1664 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1665 "5: targets = {b}, decl\n"
1666 "6: targets = {rec_alias}\n"
1667 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1668 "8: targets = {c}, decl\n"},
1669 // Handle SizeOfPackExpr.
1670 {
1671 R"cpp(
1672 template <typename... E>
1673 void foo() {
1674 constexpr int $0^size = sizeof...($1^E);
1675 };
1676 )cpp",
1677 "0: targets = {size}, decl\n"
1678 "1: targets = {E}\n"},
1679 // Class template argument deduction
1680 {
1681 R"cpp(
1682 template <typename T>
1683 struct Test {
1684 Test(T);
1685 };
1686 void foo() {
1687 $0^Test $1^a(5);
1688 }
1689 )cpp",
1690 "0: targets = {Test}\n"
1691 "1: targets = {a}, decl\n"},
1692 // Templates
1693 {R"cpp(
1694 namespace foo {
1695 template <typename $0^T>
1696 class $1^Bar {};
1697 }
1698 )cpp",
1699 "0: targets = {foo::Bar::T}, decl\n"
1700 "1: targets = {foo::Bar}, decl\n"},
1701 // Templates
1702 {R"cpp(
1703 namespace foo {
1704 template <typename $0^T>
1705 void $1^func();
1706 }
1707 )cpp",
1708 "0: targets = {T}, decl\n"
1709 "1: targets = {foo::func}, decl\n"},
1710 // Templates
1711 {R"cpp(
1712 namespace foo {
1713 template <typename $0^T>
1714 $1^T $2^x;
1715 }
1716 )cpp",
1717 "0: targets = {foo::T}, decl\n"
1718 "1: targets = {foo::T}\n"
1719 "2: targets = {foo::x}, decl\n"},
1720 // Templates
1721 {R"cpp(
1722 template<typename T> class vector {};
1723 namespace foo {
1724 template <typename $0^T>
1725 using $1^V = $2^vector<$3^T>;
1726 }
1727 )cpp",
1728 "0: targets = {foo::T}, decl\n"
1729 "1: targets = {foo::V}, decl\n"
1730 "2: targets = {vector}\n"
1731 "3: targets = {foo::T}\n"},
1732 // Concept
1733 {
1734 R"cpp(
1735 template <typename T>
1736 concept Drawable = requires (T t) { t.draw(); };
1737
1738 namespace foo {
1739 template <typename $0^T> requires $1^Drawable<$2^T>
1740 void $3^bar($4^T $5^t) {
1741 $6^t.$7^draw();
1742 }
1743 }
1744 )cpp",
1745 "0: targets = {T}, decl\n"
1746 "1: targets = {Drawable}\n"
1747 "2: targets = {T}\n"
1748 "3: targets = {foo::bar}, decl\n"
1749 "4: targets = {T}\n"
1750 "5: targets = {t}, decl\n"
1751 "6: targets = {t}\n"
1752 "7: targets = {}\n"},
1753 // Objective-C: instance variables
1754 {
1755 R"cpp(
1756 @interface I {
1757 @public
1758 I *_z;
1759 }
1760 @end
1761 I *f;
1762 void foo() {
1763 $0^f->$1^_z = 0;
1764 }
1765 )cpp",
1766 "0: targets = {f}\n"
1767 "1: targets = {I::_z}\n"},
1768 // Objective-C: properties
1769 {
1770 R"cpp(
1771 @interface I {}
1772 @property(retain) I* x;
1773 @property(retain) I* y;
1774 @end
1775 I *f;
1776 void foo() {
1777 $0^f.$1^x.$2^y = 0;
1778 }
1779 )cpp",
1780 "0: targets = {f}\n"
1781 "1: targets = {I::x}\n"
1782 "2: targets = {I::y}\n"},
1783 // Objective-C: implicit properties
1784 {
1785 R"cpp(
1786 @interface I {}
1787 -(I*)x;
1788 -(void)setY:(I*)y;
1789 @end
1790 I *f;
1791 void foo() {
1792 $0^f.$1^x.$2^y = 0;
1793 }
1794 )cpp",
1795 "0: targets = {f}\n"
1796 "1: targets = {I::x}\n"
1797 "2: targets = {I::setY:}\n"},
1798 // Objective-C: class properties
1799 {
1800 R"cpp(
1801 @interface I {}
1802 @property(class) I *x;
1803 @end
1804 id local;
1805 void foo() {
1806 $0^I.$1^x = 0;
1807 $2^local = $3^I.$4^x;
1808 }
1809 )cpp",
1810 "0: targets = {I}\n"
1811 "1: targets = {I::setX:}\n"
1812 "2: targets = {local}\n"
1813 "3: targets = {I}\n"
1814 "4: targets = {I::x}\n"},
1815 // Objective-C: implicit class properties
1816 {
1817 R"cpp(
1818 @interface I {}
1819 +(I*)x;
1820 +(void)setX:(I*)x;
1821 @end
1822 id local;
1823 void foo() {
1824 $0^I.$1^x = 0;
1825 $2^local = $3^I.$4^x;
1826 }
1827 )cpp",
1828 "0: targets = {I}\n"
1829 "1: targets = {I::setX:}\n"
1830 "2: targets = {local}\n"
1831 "3: targets = {I}\n"
1832 "4: targets = {I::x}\n"},
1833 {// Objective-C: methods
1834 R"cpp(
1835 @interface I
1836 -(void) a:(int)x b:(int)y;
1837 @end
1838 void foo(I *i) {
1839 [$0^i $1^a:1 b:2];
1840 }
1841 )cpp",
1842 "0: targets = {i}\n"
1843 "1: targets = {I::a:b:}\n"},
1844 {// Objective-C: protocols
1845 R"cpp(
1846 @interface I
1847 @end
1848 @protocol P
1849 @end
1850 void foo() {
1851 $0^I<$1^P> *$2^x;
1852 }
1853 )cpp",
1854 "0: targets = {I}\n"
1855 "1: targets = {P}\n"
1856 "2: targets = {x}, decl\n"},
1857
1858 // Designated initializers.
1859 {R"cpp(
1860 void foo() {
1861 struct $0^Foo {
1862 int $1^Bar;
1863 };
1864 $2^Foo $3^f { .$4^Bar = 42 };
1865 }
1866 )cpp",
1867 "0: targets = {Foo}, decl\n"
1868 "1: targets = {foo()::Foo::Bar}, decl\n"
1869 "2: targets = {Foo}\n"
1870 "3: targets = {f}, decl\n"
1871 "4: targets = {foo()::Foo::Bar}\n"},
1872 {R"cpp(
1873 void foo() {
1874 struct $0^Baz {
1875 int $1^Field;
1876 };
1877 struct $2^Bar {
1878 $3^Baz $4^Foo;
1879 };
1880 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
1881 }
1882 )cpp",
1883 "0: targets = {Baz}, decl\n"
1884 "1: targets = {foo()::Baz::Field}, decl\n"
1885 "2: targets = {Bar}, decl\n"
1886 "3: targets = {Baz}\n"
1887 "4: targets = {foo()::Bar::Foo}, decl\n"
1888 "5: targets = {Bar}\n"
1889 "6: targets = {bar}, decl\n"
1890 "7: targets = {foo()::Bar::Foo}\n"
1891 "8: targets = {foo()::Baz::Field}\n"},
1892 {R"cpp(
1893 template<typename T>
1894 void crash(T);
1895 template<typename T>
1896 void foo() {
1897 $0^crash({.$1^x = $2^T()});
1898 }
1899 )cpp",
1900 "0: targets = {crash}\n"
1901 "1: targets = {}\n"
1902 "2: targets = {T}\n"},
1903 // unknown template name should not crash.
1904 {R"cpp(
1905 template <template <typename> typename T>
1906 struct Base {};
1907 namespace foo {
1908 template <typename $0^T>
1909 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
1910 }
1911 )cpp",
1912 "0: targets = {foo::Derive::T}, decl\n"
1913 "1: targets = {foo::Derive}, decl\n"
1914 "2: targets = {Base}\n"
1915 "3: targets = {foo::Derive::T}\n"
1916 "4: targets = {}, qualifier = 'T::'\n"},
1917 // deduction guide
1918 {R"cpp(
1919 namespace foo {
1920 template <typename $0^T>
1921 struct $1^Test {
1922 template <typename $2^I>
1923 $3^Test($4^I);
1924 };
1925 template <typename $5^I>
1926 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
1927 }
1928 )cpp",
1929 "0: targets = {T}, decl\n"
1930 "1: targets = {foo::Test}, decl\n"
1931 "2: targets = {I}, decl\n"
1932 "3: targets = {foo::Test::Test<T>}, decl\n"
1933 "4: targets = {I}\n"
1934 "5: targets = {I}, decl\n"
1935 "6: targets = {foo::Test}\n"
1936 "7: targets = {I}\n"
1937 "8: targets = {foo::Test}\n"
1938 "9: targets = {I}\n"
1939 "10: targets = {}, qualifier = 'I::'\n"}};
1940
1941 for (const auto &C : Cases) {
1942 llvm::StringRef ExpectedCode = C.first;
1943 llvm::StringRef ExpectedRefs = C.second;
1944
1945 auto Actual =
1946 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
1947 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
1948 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
1949 }
1950}
1951
1952} // namespace
1953} // namespace clangd
1954} // namespace clang
size_t Offset
#define EXPECT_DECLS(NodeType,...)
std::string Code
std::string AnnotatedCode
std::string DumpedReferences
const Criteria C
Token Name
size_t Pos
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
Definition: Selection.cpp:1060
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:221
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 ...
Definition: FindTarget.cpp:536
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:316
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