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