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>
35 PrintedDecl(
const char *Name, DeclRelationSet Relations = {})
36 :
Name(Name), Relations(Relations) {}
37 PrintedDecl(
const NamedDecl *D, DeclRelationSet Relations = {})
38 : Relations(Relations) {
40 llvm::raw_string_ostream
OS(S);
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(
" {"));
49 DeclRelationSet Relations;
51bool operator==(
const PrintedDecl &L,
const PrintedDecl &R) {
52 return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);
54llvm::raw_ostream &
operator<<(llvm::raw_ostream &
OS,
const PrintedDecl &D) {
55 return OS << D.Name <<
" Rel=" << D.Relations;
64class TargetDeclTest :
public ::testing::Test {
73 std::vector<PrintedDecl> assertNodeAndPrintDecls(
const char *NodeType) {
74 llvm::Annotations A(
Code);
77 auto AST = TU.build();
78 llvm::Annotations::Range R = A.range();
80 AST.getASTContext(),
AST.getTokens(), R.Begin, R.End);
81 const SelectionTree::Node *N = Selection.commonAncestor();
83 ADD_FAILURE() <<
"No node selected!\n" <<
Code;
86 EXPECT_EQ(N->kind(), NodeType) << Selection;
88 std::vector<PrintedDecl> ActualDecls;
89 for (
const auto &
Entry :
91 ActualDecls.emplace_back(
Entry.first,
Entry.second);
98#define EXPECT_DECLS(NodeType, ...) \
99 EXPECT_THAT(assertNodeAndPrintDecls(NodeType), \
100 ::testing::UnorderedElementsAreArray( \
101 std::vector<PrintedDecl>({__VA_ARGS__}))) \
103using ExpectedDecls = std::vector<PrintedDecl>;
105TEST_F(TargetDeclTest, Exprs) {
113 struct S { S operator+(S) const; };
114 auto X = S() [[+]] S();
126 void operator()(int n);
133 EXPECT_DECLS("CXXOperatorCallExpr",
"void operator()(int n)");
152TEST_F(TargetDeclTest, RecoveryForC) {
153 Flags = {
"-xc",
"-Xclang",
"-frecovery-ast"};
155 // error-ok: testing behavior on broken code
163TEST_F(TargetDeclTest, Recovery) {
165 // error-ok: testing behavior on broken code
170 EXPECT_DECLS("UnresolvedLookupExpr",
"int f()",
"int f(int, int)");
173TEST_F(TargetDeclTest, RecoveryType) {
175 // error-ok: testing behavior on broken code
176 struct S { int member; };
179 // No overload matches, but we have recovery-expr with the correct type.
180 overloaded().[[member]];
186TEST_F(TargetDeclTest, UsingDecl) {
196 EXPECT_DECLS(
"DeclRefExpr", {
"using foo::f", Rel::Alias}, {
"int f(int)"});
206 EXPECT_DECLS(
"UsingDecl", {
"using foo::f", Rel::Alias}, {
"int f(int)"},
216 int x = Y().[[foo]]();
218 EXPECT_DECLS("MemberExpr", {
"using X::foo", Rel::Alias}, {
"int foo()"});
221 template <typename T>
225 template <typename T>
226 struct Derived : Base<T> {
227 using Base<T>::[[waldo]];
230 EXPECT_DECLS("UnresolvedUsingValueDecl", {
"using Base<T>::waldo", Rel::Alias},
235 template<typename T> class S {};
243 EXPECT_DECLS("TemplateSpecializationTypeLoc", {
"using ns::S", Rel::Alias},
244 {
"template <typename T> class S"},
245 {
"class S", Rel::TemplatePattern});
249 template<typename T> class S {};
253 template <template <typename> class T> class X {};
256 EXPECT_DECLS("TemplateArgumentLoc", {
"using ns::S", Rel::Alias},
257 {
"template <typename T> class S"});
261 template<typename T> class S { public: S(T); };
267 Flags.push_back("-std=c++17");
269 {
"using ns::S", Rel::Alias}, {
"template <typename T> class S"},
270 {
"class S", Rel::TemplatePattern});
274 class Foo { public: class foo {}; };
275 template <class T> class A : public Foo<T> {
276 using typename Foo<T>::foo;
281 {
"using typename Foo<T>::foo", Rel::Alias});
284 Flags.push_back(
"-std=c++20");
286 namespace ns { enum class A { X }; }
287 [[using enum ns::A]];
292 namespace ns { enum class A { X }; }
299TEST_F(TargetDeclTest, BaseSpecifier) {
302 struct Y : [[private]] X {};
307 struct Y : [[private X]] {};
312 struct Y : private [[X]] {};
317TEST_F(TargetDeclTest, ConstructorInitList) {
335TEST_F(TargetDeclTest, DesignatedInit) {
339 struct Y { int b; struct X c[2]; };
340 struct Y y = { .c[0].[[a]] = 1 };
345TEST_F(TargetDeclTest, NestedNameSpecifier) {
347 namespace a { namespace b { int c; } }
353 namespace a { struct X { enum { y }; }; }
359 template <typename T>
365 namespace a { int x; }
369 EXPECT_DECLS("NestedNameSpecifierLoc", {
"namespace b = a", Rel::Alias},
370 {
"namespace a", Rel::Underlying});
373TEST_F(TargetDeclTest, Types) {
385 EXPECT_DECLS("TypedefTypeLoc", {
"typedef S X", Rel::Alias},
386 {
"struct S", Rel::Underlying});
388 namespace ns { struct S{}; }
392 EXPECT_DECLS("TypedefTypeLoc", {
"typedef ns::S X", Rel::Alias},
393 {
"struct S", Rel::Underlying});
397 void foo() { [[T]] x; }
403 template<template<typename> class T>
404 void foo() { [[T<int>]] x; }
406 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> class T");
410 template<template<typename> class ...T>
415 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename> class ...T"});
423 EXPECT_DECLS("DecltypeTypeLoc", {
"struct S", Rel::Underlying});
433 template <typename... E>
435 static const int size = sizeof...([[E]]);
441 template <typename T>
449TEST_F(TargetDeclTest, ClassTemplate) {
451 // Implicit specialization.
452 template<int x> class Foo{};
456 {
"template<> class Foo<42>", Rel::TemplateInstantiation},
457 {
"class Foo", Rel::TemplatePattern});
460 template<typename T> class Foo {};
461 // The "Foo<int>" SpecializationDecl is incomplete, there is no
462 // instantiation happening.
463 void func([[Foo<int>]] *);
466 {
"class Foo", Rel::TemplatePattern},
467 {
"template<> class Foo<int>", Rel::TemplateInstantiation});
470 // Explicit specialization.
471 template<int x> class Foo{};
472 template<> class Foo<42>{};
475 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template<> class Foo<42>");
478 // Partial specialization.
479 template<typename T> class Foo{};
480 template<typename T> class Foo<T*>{};
484 {
"template<> class Foo<int *>", Rel::TemplateInstantiation},
485 {
"template <typename T> class Foo<T *>", Rel::TemplatePattern});
488 // Template template argument.
489 template<typename T> struct Vector {};
490 template <template <typename> class Container>
494 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename T> struct Vector"});
496 Flags.push_back(
"-std=c++17");
499 // Class template argument deduction
500 template <typename T>
509 {
"struct Test", Rel::TemplatePattern});
513 template <typename T>
515 template <typename I>
518 template <typename I>
519 [[Test]](I, I) -> Test<typename I::type>;
521 EXPECT_DECLS("CXXDeductionGuideDecl", {
"template <typename T> struct Test"});
525 Flags.push_back(
"-std=c++20");
531 template <typename T>
532 concept Fooable = requires (T t) { t.foo(); };
534 template <typename T> requires [[Fooable]]<T>
541 {
"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
545 template <typename T>
546 concept Fooable = true;
548 template <typename T>
549 void foo() requires [[Fooable]]<T>;
552 {
"template <typename T> concept Fooable = true"});
556 template <typename T>
557 concept Fooable = true;
559 template <[[Fooable]] T>
563 {
"template <typename T> concept Fooable = true"});
567 template <typename T, typename U>
568 concept Fooable = true;
570 template <[[Fooable]]<int> T>
574 {
"template <typename T, typename U> concept Fooable = true"});
577TEST_F(TargetDeclTest, Coroutine) {
578 Flags.push_back(
"-std=c++20");
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;
592 struct awaitable_frame {
593 awaitable get_return_object();
595 void unhandled_exception();
598 bool await_ready() const noexcept;
599 void await_suspend(std::coroutine_handle<void>) noexcept;
600 void await_resume() const noexcept;
602 result_t initial_suspend() noexcept;
603 result_t final_suspend() noexcept;
604 result_t await_transform(executor) noexcept;
609 struct coroutine_traits<awaitable> {
610 typedef awaitable_frame promise_type;
615 co_await [[executor]]();
621TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
622 Flags.push_back(
"-std=c++20");
626 struct strong_ordering {
628 constexpr operator int() const { return n; }
629 static const strong_ordering equal, greater, less;
631 constexpr strong_ordering strong_ordering::equal = {0};
632 constexpr strong_ordering strong_ordering::greater = {1};
633 constexpr strong_ordering strong_ordering::less = {-1};
639 auto operator<=>(const Foo&) const = default;
642 bool x = (Foo(1) [[!=]] Foo(2));
645 {
"std::strong_ordering operator<=>(const Foo &) const = default",
646 Rel::TemplatePattern},
647 {
"bool operator==(const Foo &) const noexcept = default",
648 Rel::TemplateInstantiation});
651TEST_F(TargetDeclTest, FunctionTemplate) {
653 // Implicit specialization.
654 template<typename T> bool foo(T) { return false; };
655 bool x = [[foo]](42);
658 {
"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
659 {
"bool foo(T)", Rel::TemplatePattern});
662 // Explicit specialization.
663 template<typename T> bool foo(T) { return false; };
664 template<> bool foo<int>(int) { return false; };
665 bool x = [[foo]](42);
667 EXPECT_DECLS("DeclRefExpr",
"template<> bool foo<int>(int)");
670TEST_F(TargetDeclTest, VariableTemplate) {
673 // Implicit specialization.
674 template<typename T> int foo;
675 int x = [[foo]]<char>;
677 EXPECT_DECLS("DeclRefExpr", {
"int foo", Rel::TemplateInstantiation},
678 {
"int foo", Rel::TemplatePattern});
681 // Explicit specialization.
682 template<typename T> int foo;
683 template <> bool foo<char>;
684 int x = [[foo]]<char>;
689 // Partial specialization.
690 template<typename T> int foo;
691 template<typename T> bool foo<T*>;
692 bool x = [[foo]]<char*>;
694 EXPECT_DECLS("DeclRefExpr", {
"bool foo", Rel::TemplateInstantiation},
695 {
"bool foo", Rel::TemplatePattern});
698TEST_F(TargetDeclTest, TypeAliasTemplate) {
700 template<typename T, int X> class SmallVector {};
701 template<typename U> using TinyVector = SmallVector<U, 1>;
702 [[TinyVector<int>]] X;
705 {
"template<> class SmallVector<int, 1>",
706 Rel::TemplateInstantiation | Rel::Underlying},
707 {
"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
708 {
"using TinyVector = SmallVector<U, 1>",
709 Rel::Alias | Rel::TemplatePattern});
712TEST_F(TargetDeclTest, BuiltinTemplates) {
714 template <class T, T... Index> struct integer_sequence {};
715 [[__make_integer_seq]]<integer_sequence, int, 3> X;
718 "TemplateSpecializationTypeLoc",
719 {
"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
720 {
"template<> struct integer_sequence<int, <0, 1, 2>>",
721 Rel::TemplateInstantiation | Rel::Underlying});
725 template <class T, T... Index> struct integer_sequence;
727 template <class T, int N>
728 using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
733 template <int N, class... Pack>
734 using type_pack_element = [[__type_pack_element]]<N, Pack...>;
739TEST_F(TargetDeclTest, MemberOfTemplate) {
741 template <typename T> struct Foo {
744 int y = Foo<int>().[[x]](42);
746 EXPECT_DECLS("MemberExpr", {
"int x(int)", Rel::TemplateInstantiation},
747 {
"int x(T)", Rel::TemplatePattern});
750 template <typename T> struct Foo {
751 template <typename U>
754 int y = Foo<char>().[[x]]('c', 42);
757 {
"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
758 {
"int x(T, U)", Rel::TemplatePattern});
761TEST_F(TargetDeclTest, Lambda) {
763 void foo(int x = 42) {
764 auto l = [ [[x]] ]{ return x + 1; };
772 void foo(int x = 42) {
773 auto l = [x]{ return [[x]] + 1; };
780 auto l = [x = 1]{ return [[x]] + 1; };
787TEST_F(TargetDeclTest, OverloadExpr) {
788 Flags.push_back(
"--target=x86_64-pc-linux-gnu");
799 EXPECT_DECLS("UnresolvedLookupExpr",
"void func(int *)",
"void func(char *)");
812 EXPECT_DECLS("UnresolvedMemberExpr",
"void func(int *)",
"void func(char *)");
816 static void *operator new(unsigned long);
818 auto* k = [[new]] X();
820 EXPECT_DECLS("CXXNewExpr",
"static void *operator new(unsigned long)");
822 void *operator new(unsigned long);
823 auto* k = [[new]] int();
825 EXPECT_DECLS("CXXNewExpr",
"void *operator new(unsigned long)");
829 static void operator delete(void *) noexcept;
835 EXPECT_DECLS("CXXDeleteExpr",
"static void operator delete(void *) noexcept");
837 void operator delete(void *) noexcept;
842 EXPECT_DECLS("CXXDeleteExpr",
"void operator delete(void *) noexcept");
845TEST_F(TargetDeclTest, DependentExprs) {
848 struct A { void foo() {} };
849 template <typename T>
857 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void foo()");
867 template <typename T>
871 this->c.getA().[[foo]]();
875 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void foo()");
886 template <typename T>
890 this->c.fptr().[[foo]]();
894 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void foo()");
901 template <typename T> struct Foo {
908 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"int aaaa");
914 template <typename T> T convert() const;
916 template <typename T>
918 Foo::k(T()).template [[convert]]<T>();
922 "template <typename T> T convert() const");
925 template <typename T>
929 template <typename T>
930 using Wally = Waldo<T>;
931 template <typename T>
932 void foo(Wally<T> w) {
936 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
939 template <typename T>
943 template <typename T>
945 using Type = Waldo<T>;
947 template <typename T>
948 void foo(typename MetaWaldo<T>::Type w) {
952 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
958 template <typename T>
961 struct S : Wally<int> {
962 void Foo() { this->[[find]](); }
965 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
968TEST_F(TargetDeclTest, DependentTypes) {
972 struct A { struct B {}; };
974 template <typename T>
975 void foo(typename A<T>::[[B]]);
982 struct A { struct B { struct C {}; }; };
984 template <typename T>
985 void foo(typename A<T>::[[B]]::C);
993 struct A { struct B { struct C {}; }; };
995 template <typename T>
996 void foo(typename A<T>::B::[[C]]);
1004 template <typename> struct B {};
1007 template <typename T>
1008 void foo(typename A<T>::template [[B]]<int>);
1011 "template <typename> struct B");
1018 typedef typename waldo<N - 1>::type::[[next]] type;
1030 using type = typename odd<N - 1>::type::next;
1035 using type = typename even<N - 1>::type::[[next]];
1041TEST_F(TargetDeclTest, TypedefCascade) {
1047 using type = C::type;
1050 using type = B::type;
1055 {
"using type = int", Rel::Alias | Rel::Underlying},
1056 {
"using type = C::type", Rel::Alias | Rel::Underlying},
1057 {
"using type = B::type", Rel::Alias});
1060TEST_F(TargetDeclTest, RecursiveTemplate) {
1061 Flags.push_back(
"-std=c++20");
1064 template <typename T>
1065 concept Leaf = false;
1067 template <typename Tree>
1068 struct descend_left {
1069 using type = typename descend_left<typename Tree::left>::[[type]];
1072 template <Leaf Tree>
1073 struct descend_left<Tree> {
1074 using type = typename Tree::value;
1078 {
"using type = typename descend_left<typename Tree::left>::type",
1079 Rel::Alias | Rel::Underlying});
1082TEST_F(TargetDeclTest, ObjC) {
1083 Flags = {
"-xobjective-c"};
1095 @interface Foo { @public int bar; }
1106 -(void) setX:(int)x;
1112 EXPECT_DECLS("ObjCPropertyRefExpr",
"- (void)setX:(int)x");
1116 @property(retain) I* x;
1117 @property(retain) I* y;
1124 "@property(atomic, retain, readwrite) I *x");
1129 @interface Interface
1130 @property(retain) [[MYObject]] *x;
1133 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject");
1136 @interface MYObject2
1138 @interface Interface
1139 @property(retain, nonnull) [[MYObject2]] *x;
1142 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject2");
1148 return [[@protocol(Foo)]];
1156 void test([[Foo]] *p);
1158 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1160 Code = R
"cpp(// Don't consider implicit interface as the target.
1161 @implementation [[Implicit]]
1164 EXPECT_DECLS("ObjCImplementationDecl",
"@implementation Implicit");
1169 @implementation [[Foo]]
1172 EXPECT_DECLS("ObjCImplementationDecl",
"@interface Foo");
1177 @interface Foo (Ext)
1179 @implementation [[Foo]] (Ext)
1182 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1187 @interface Foo (Ext)
1189 @implementation Foo ([[Ext]])
1192 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1195 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1203 void test([[C]]<Foo> *p);
1211 void test(C<[[Foo]]> *p);
1221 void test(C<[[Foo]], Bar> *p);
1231 void test(C<Foo, [[Bar]]> *p);
1237 + (id)sharedInstance;
1240 + (id)sharedInstance { return 0; }
1243 id value = [[Foo]].sharedInstance;
1246 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1250 + (id)sharedInstance;
1253 + (id)sharedInstance { return 0; }
1256 id value = Foo.[[sharedInstance]];
1259 EXPECT_DECLS("ObjCPropertyRefExpr",
"+ (id)sharedInstance");
1263 + ([[id]])sharedInstance;
1270 + ([[instancetype]])sharedInstance;
1276class FindExplicitReferencesTest :
public ::testing::Test {
1283 TestTU newTU(llvm::StringRef
Code) {
1285 TU.Code = std::string(
Code);
1289 TU.ExtraArgs.push_back(
"-std=c++20");
1290 TU.ExtraArgs.push_back(
"-xobjective-c++");
1295 AllRefs annotatedReferences(llvm::StringRef
Code, ParsedAST &
AST,
1296 std::vector<ReferenceLoc> Refs) {
1297 auto &SM =
AST.getSourceManager();
1298 llvm::stable_sort(Refs, [&](
const ReferenceLoc &L,
const ReferenceLoc &R) {
1299 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1303 unsigned NextCodeChar = 0;
1304 for (
unsigned I = 0; I < Refs.size(); ++I) {
1307 SourceLocation
Pos = R.NameLoc;
1308 assert(
Pos.isValid());
1309 if (
Pos.isMacroID())
1310 Pos = SM.getExpansionLoc(
Pos);
1311 assert(
Pos.isFileID());
1316 if (
File == SM.getMainFileID()) {
1318 assert(NextCodeChar <=
Offset);
1328 for (
unsigned I = 0; I < Refs.size(); ++I)
1337 AllRefs annotateAllReferences(llvm::StringRef
Code) {
1338 TestTU TU = newTU(
Code);
1339 auto AST = TU.build();
1341 std::vector<ReferenceLoc> Refs;
1342 for (
auto *TopLevel :
AST.getLocalTopLevelDecls())
1344 TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1345 AST.getHeuristicResolver());
1346 return annotatedReferences(
Code,
AST, std::move(Refs));
1352 AllRefs annotateReferencesInFoo(llvm::StringRef
Code) {
1353 TestTU TU = newTU(
Code);
1354 auto AST = TU.build();
1356 if (
auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1357 TestDecl = T->getTemplatedDecl();
1359 std::vector<ReferenceLoc> Refs;
1360 if (
const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1363 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1364 AST.getHeuristicResolver());
1365 else if (
const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1368 [&Refs, &NS](ReferenceLoc R) {
1370 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1372 Refs.push_back(std::move(R));
1374 AST.getHeuristicResolver());
1375 else if (
const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))
1377 OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1378 AST.getHeuristicResolver());
1380 ADD_FAILURE() <<
"Failed to find ::foo decl for test";
1382 return annotatedReferences(
Code,
AST, std::move(Refs));
1386TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
1387 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
1392 void foo(int param) {
1393 $0^global = $1^param + $2^func();
1396 "0: targets = {global}\n"
1397 "1: targets = {param}\n"
1398 "2: targets = {func}\n"},
1400 struct X { int a; };
1405 "0: targets = {x}\n"
1406 "1: targets = {X::a}\n"},
1408 // error-ok: testing with broken code
1411 return $0^bar() + $1^bar(42);
1414 "0: targets = {bar}\n"
1415 "1: targets = {bar}\n"},
1419 namespace alias = ns;
1421 using namespace $0^ns;
1422 using namespace $1^alias;
1425 "0: targets = {ns}\n"
1426 "1: targets = {alias}\n"},
1429 namespace ns { int global; }
1431 using $0^ns::$1^global;
1434 "0: targets = {ns}\n"
1435 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1438 namespace ns { enum class A {}; }
1440 using enum $0^ns::$1^A;
1443 "0: targets = {ns}\n"
1444 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1447 struct Struct { int a; };
1448 using Typedef = int;
1452 static_cast<$4^Struct*>(0);
1455 "0: targets = {Struct}\n"
1456 "1: targets = {x}, decl\n"
1457 "2: targets = {Typedef}\n"
1458 "3: targets = {y}, decl\n"
1459 "4: targets = {Struct}\n"},
1462 namespace a { namespace b { struct S { typedef int type; }; } }
1464 $0^a::$1^b::$2^S $3^x;
1465 using namespace $4^a::$5^b;
1469 "0: targets = {a}\n"
1470 "1: targets = {a::b}, qualifier = 'a::'\n"
1471 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1472 "3: targets = {x}, decl\n"
1473 "4: targets = {a}\n"
1474 "5: targets = {a::b}, qualifier = 'a::'\n"
1475 "6: targets = {a::b::S}\n"
1476 "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
1477 "8: targets = {y}, decl\n"},
1480 $0^ten: // PRINT "HELLO WORLD!"
1484 "0: targets = {ten}, decl\n"
1485 "1: targets = {ten}\n"},
1488 template <class T> struct vector { using value_type = T; };
1489 template <> struct vector<bool> { using value_type = bool; };
1491 $0^vector<int> $1^vi;
1492 $2^vector<bool> $3^vb;
1495 "0: targets = {vector<int>}\n"
1496 "1: targets = {vi}, decl\n"
1497 "2: targets = {vector<bool>}\n"
1498 "3: targets = {vb}, decl\n"},
1501 template <class T> struct vector { using value_type = T; };
1502 template <> struct vector<bool> { using value_type = bool; };
1503 template <class T> using valias = vector<T>;
1505 $0^valias<int> $1^vi;
1506 $2^valias<bool> $3^vb;
1509 "0: targets = {valias}\n"
1510 "1: targets = {vi}, decl\n"
1511 "2: targets = {valias}\n"
1512 "3: targets = {vb}, decl\n"},
1516 template <typename $0^T>
1523 "0: targets = {foo::Bar::T}, decl\n"
1524 "1: targets = {foo::Bar}, decl\n"
1525 "2: targets = {foo::Bar}\n"
1526 "3: targets = {foo::Bar::f}, decl\n"
1527 "4: targets = {foo::Bar}\n"},
1530 struct X { void func(int); };
1538 "0: targets = {y}\n"
1539 "1: targets = {Y::func}\n"},
1542 namespace ns { void bar(int); }
1549 "0: targets = {bar}\n"},
1555 void foo(int a, int b) {
1559 "0: targets = {a}\n"
1560 "1: targets = {b}\n"},
1569 for (int $0^x : $1^vector()) {
1574 "0: targets = {x}, decl\n"
1575 "1: targets = {vector}\n"
1576 "2: targets = {x}\n"},
1579 namespace ns1 { void func(char*); }
1580 namespace ns2 { void func(int*); }
1581 using namespace ns1;
1582 using namespace ns2;
1589 "0: targets = {ns1::func, ns2::func}\n"
1590 "1: targets = {t}\n"},
1599 void foo(X x, T t) {
1603 "0: targets = {x}\n"
1604 "1: targets = {X::func, X::func}\n"
1605 "2: targets = {t}\n"},
1615 $0^S<$1^T>::$2^value;
1618 "0: targets = {S}\n"
1619 "1: targets = {T}\n"
1620 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1633 "0: targets = {t}\n"
1634 "1: targets = {S::value}\n"},
1639 static_cast<$0^T>(0);
1644 "0: targets = {T}\n"
1645 "1: targets = {T}\n"
1646 "2: targets = {T}\n"
1647 "3: targets = {t}, decl\n"},
1655 "0: targets = {x}, decl\n"
1656 "1: targets = {I}\n"},
1659 template <class T> struct vector {};
1661 template <template<class> class TT, template<class> class ...TP>
1665 $4^foo<$5^vector>();
1669 "0: targets = {TT}\n"
1670 "1: targets = {x}, decl\n"
1671 "2: targets = {foo}\n"
1672 "3: targets = {TT}\n"
1673 "4: targets = {foo}\n"
1674 "5: targets = {vector}\n"
1675 "6: targets = {foo}\n"
1676 "7: targets = {TP}\n"},
1680 template <int(*)()> struct wrapper {};
1682 template <int(*FuncParam)()>
1684 $0^wrapper<$1^func> $2^w;
1688 "0: targets = {wrapper<&func>}\n"
1689 "1: targets = {func}\n"
1690 "2: targets = {w}, decl\n"
1691 "3: targets = {FuncParam}\n"},
1697 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1699 enum $5^E { $6^ABC };
1701 using $8^INT2 = int;
1702 namespace $9^NS = $10^ns;
1705 "0: targets = {Foo}, decl\n"
1706 "1: targets = {foo()::Foo::Foo}, decl\n"
1707 "2: targets = {Foo}\n"
1708 "3: targets = {foo()::Foo::field}, decl\n"
1709 "4: targets = {Var}, decl\n"
1710 "5: targets = {E}, decl\n"
1711 "6: targets = {foo()::ABC}, decl\n"
1712 "7: targets = {INT}, decl\n"
1713 "8: targets = {INT2}, decl\n"
1714 "9: targets = {NS}, decl\n"
1715 "10: targets = {ns}\n"},
1722 // FIXME: This should have only one reference to Bar.
1723 $2^operator $3^$4^Bar();
1727 $7^f.$8^operator $9^Bar();
1730 "0: targets = {Bar}, decl\n"
1731 "1: targets = {Foo}, decl\n"
1732 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1733 "3: targets = {Bar}\n"
1734 "4: targets = {Bar}\n"
1735 "5: targets = {Foo}\n"
1736 "6: targets = {f}, decl\n"
1737 "7: targets = {f}\n"
1738 "8: targets = {foo()::Foo::operator Bar}\n"
1739 "9: targets = {Bar}\n"},
1747 void $2^destructMe() {
1753 $6^f.~ /*...*/ $7^Foo();
1756 "0: targets = {Foo}, decl\n"
1759 "1: targets = {Foo}\n"
1760 "2: targets = {foo()::Foo::destructMe}, decl\n"
1761 "3: targets = {Foo}\n"
1762 "4: targets = {Foo}\n"
1763 "5: targets = {f}, decl\n"
1764 "6: targets = {f}\n"
1765 "7: targets = {Foo}\n"},
1770 // member initializer
1776 class $4^Derived : public $5^Base {
1778 $8^Derived() : $9^Base() {}
1780 // delegating initializer
1783 $12^Foo(): $13^Foo(111) {}
1787 "0: targets = {X}, decl\n"
1788 "1: targets = {foo()::X::abc}, decl\n"
1789 "2: targets = {foo()::X::X}, decl\n"
1790 "3: targets = {foo()::X::abc}\n"
1791 "4: targets = {Derived}, decl\n"
1792 "5: targets = {Base}\n"
1793 "6: targets = {Base}\n"
1794 "7: targets = {foo()::Derived::B}, decl\n"
1795 "8: targets = {foo()::Derived::Derived}, decl\n"
1796 "9: targets = {Base}\n"
1797 "10: targets = {Foo}, decl\n"
1798 "11: targets = {foo()::Foo::Foo}, decl\n"
1799 "12: targets = {foo()::Foo::Foo}, decl\n"
1800 "13: targets = {Foo}\n"},
1806 int (*$2^fptr)(int $3^a, int) = nullptr;
1809 "0: targets = {(unnamed)}\n"
1810 "1: targets = {x}, decl\n"
1811 "2: targets = {fptr}, decl\n"
1812 "3: targets = {a}, decl\n"},
1816 namespace ns { struct Type {}; }
1817 namespace alias = ns;
1818 namespace rec_alias = alias;
1821 $0^ns::$1^Type $2^a;
1822 $3^alias::$4^Type $5^b;
1823 $6^rec_alias::$7^Type $8^c;
1826 "0: targets = {ns}\n"
1827 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1828 "2: targets = {a}, decl\n"
1829 "3: targets = {alias}\n"
1830 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1831 "5: targets = {b}, decl\n"
1832 "6: targets = {rec_alias}\n"
1833 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1834 "8: targets = {c}, decl\n"},
1838 template <typename... E>
1840 constexpr int $0^size = sizeof...($1^E);
1843 "0: targets = {size}, decl\n"
1844 "1: targets = {E}\n"},
1848 template <typename T>
1856 "0: targets = {Test}\n"
1857 "1: targets = {a}, decl\n"},
1861 template <typename $0^T>
1865 "0: targets = {foo::Bar::T}, decl\n"
1866 "1: targets = {foo::Bar}, decl\n"},
1870 template <typename $0^T>
1874 "0: targets = {T}, decl\n"
1875 "1: targets = {foo::func}, decl\n"},
1879 template <typename $0^T>
1883 "0: targets = {foo::T}, decl\n"
1884 "1: targets = {foo::T}\n"
1885 "2: targets = {foo::x}, decl\n"},
1888 template<typename T> class vector {};
1890 template <typename $0^T>
1891 using $1^V = $2^vector<$3^T>;
1894 "0: targets = {foo::T}, decl\n"
1895 "1: targets = {foo::V}, decl\n"
1896 "2: targets = {vector}\n"
1897 "3: targets = {foo::T}\n"},
1901 template <typename T>
1902 concept Drawable = requires (T t) { t.draw(); };
1905 template <typename $0^T> requires $1^Drawable<$2^T>
1906 void $3^bar($4^T $5^t) {
1911 "0: targets = {T}, decl\n"
1912 "1: targets = {Drawable}\n"
1913 "2: targets = {T}\n"
1914 "3: targets = {foo::bar}, decl\n"
1915 "4: targets = {T}\n"
1916 "5: targets = {t}, decl\n"
1917 "6: targets = {t}\n"
1918 "7: targets = {}\n"},
1932 "0: targets = {f}\n"
1933 "1: targets = {I::_z}\n"},
1938 @property(retain) I* x;
1939 @property(retain) I* y;
1946 "0: targets = {f}\n"
1947 "1: targets = {I::x}\n"
1948 "2: targets = {I::y}\n"},
1961 "0: targets = {f}\n"
1962 "1: targets = {I::x}\n"
1963 "2: targets = {I::setY:}\n"},
1968 @property(class) I *x;
1973 $2^local = $3^I.$4^x;
1976 "0: targets = {I}\n"
1977 "1: targets = {I::setX:}\n"
1978 "2: targets = {local}\n"
1979 "3: targets = {I}\n"
1980 "4: targets = {I::x}\n"},
1991 $2^local = $3^I.$4^x;
1994 "0: targets = {I}\n"
1995 "1: targets = {I::setX:}\n"
1996 "2: targets = {local}\n"
1997 "3: targets = {I}\n"
1998 "4: targets = {I::x}\n"},
2002 -(void) a:(int)x b:(int)y;
2008 "0: targets = {i}\n"
2009 "1: targets = {I::a:b:}\n"},
2020 "0: targets = {I}\n"
2021 "1: targets = {P}\n"
2022 "2: targets = {x}, decl\n"},
2030 $2^Foo $3^f { .$4^Bar = 42 };
2033 "0: targets = {Foo}, decl\n"
2034 "1: targets = {foo()::Foo::Bar}, decl\n"
2035 "2: targets = {Foo}\n"
2036 "3: targets = {f}, decl\n"
2037 "4: targets = {foo()::Foo::Bar}\n"},
2046 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
2049 "0: targets = {Baz}, decl\n"
2050 "1: targets = {foo()::Baz::Field}, decl\n"
2051 "2: targets = {Bar}, decl\n"
2052 "3: targets = {Baz}\n"
2053 "4: targets = {foo()::Bar::Foo}, decl\n"
2054 "5: targets = {Bar}\n"
2055 "6: targets = {bar}, decl\n"
2056 "7: targets = {foo()::Bar::Foo}\n"
2057 "8: targets = {foo()::Baz::Field}\n"},
2059 template<typename T>
2061 template<typename T>
2063 $0^crash({.$1^x = $2^T()});
2066 "0: targets = {crash}\n"
2068 "2: targets = {T}\n"},
2071 template <template <typename> typename T>
2074 template <typename $0^T>
2075 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
2078 "0: targets = {foo::Derive::T}, decl\n"
2079 "1: targets = {foo::Derive}, decl\n"
2080 "2: targets = {Base}\n"
2081 "3: targets = {foo::Derive::T}\n"
2082 "4: targets = {}, qualifier = 'T::'\n"},
2086 template <typename $0^T>
2088 template <typename $2^I>
2091 template <typename $5^I>
2092 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
2095 "0: targets = {T}, decl\n"
2096 "1: targets = {foo::Test}, decl\n"
2097 "2: targets = {I}, decl\n"
2098 "3: targets = {foo::Test::Test<T>}, decl\n"
2099 "4: targets = {I}\n"
2100 "5: targets = {I}, decl\n"
2101 "6: targets = {foo::Test}\n"
2102 "7: targets = {I}\n"
2103 "8: targets = {foo::Test}\n"
2104 "9: targets = {I}\n"
2105 "10: targets = {}, qualifier = 'I::'\n"}};
2107 for (
const auto &
C : Cases) {
2108 llvm::StringRef ExpectedCode =
C.first;
2109 llvm::StringRef ExpectedRefs =
C.second;
2112 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
2113 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2114 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2118TEST_F(FindExplicitReferencesTest, AllRefs) {
2119 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
2121 @interface $0^MyClass
2123 @implementation $1^$2^MyClass
2126 "0: targets = {MyClass}, decl\n"
2127 "1: targets = {MyClass}\n"
2128 "2: targets = {MyClass}, decl\n"},
2130 @interface $0^MyClass
2132 @interface $1^MyClass ($2^Category)
2134 @implementation $3^MyClass ($4^$5^Category)
2137 "0: targets = {MyClass}, decl\n"
2138 "1: targets = {MyClass}\n"
2139 "2: targets = {Category}, decl\n"
2140 "3: targets = {MyClass}\n"
2141 "4: targets = {Category}\n"
2142 "5: targets = {Category}, decl\n"}};
2144 for (
const auto &
C : Cases) {
2145 llvm::StringRef ExpectedCode =
C.first;
2146 llvm::StringRef ExpectedRefs =
C.second;
2148 auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());
2149 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2150 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
llvm::SmallString< 256U > Name
#define EXPECT_DECLS(NodeType,...)
std::string AnnotatedCode
std::string DumpedReferences
llvm::raw_string_ostream OS
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
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)
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static TestTU withCode(llvm::StringRef Code)