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/Support/Annotations.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include <initializer_list>
37 PrintedDecl(
const NamedDecl *D, DeclRelationSet
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(
" {"));
51 bool operator==(
const PrintedDecl &L,
const PrintedDecl &R) {
52 return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);
54 llvm::raw_ostream &
operator<<(llvm::raw_ostream &
OS,
const PrintedDecl &D) {
55 return OS << D.Name <<
" Rel=" << D.Relations;
64 class TargetDeclTest :
public ::testing::Test {
73 std::vector<PrintedDecl> assertNodeAndPrintDecls(
const char *NodeType) {
74 llvm::Annotations A(
Code);
77 auto AST = TU.build();
80 AST.getASTContext(),
AST.getTokens(), R.Begin, R.End);
83 ADD_FAILURE() <<
"No node selected!\n" <<
Code;
86 EXPECT_EQ(N->kind(), NodeType) << Selection;
88 std::vector<PrintedDecl> ActualDecls;
90 ActualDecls.emplace_back(
Entry.first,
Entry.second);
97 #define EXPECT_DECLS(NodeType, ...) \
98 EXPECT_THAT(assertNodeAndPrintDecls(NodeType), \
99 ::testing::UnorderedElementsAreArray( \
100 std::vector<PrintedDecl>({__VA_ARGS__}))) \
102 using ExpectedDecls = std::vector<PrintedDecl>;
104 TEST_F(TargetDeclTest, Exprs) {
112 struct S { S operator+(S) const; };
113 auto X = S() [[+]] S();
125 void operator()(int n);
132 EXPECT_DECLS("CXXOperatorCallExpr",
"void operator()(int n)");
151 TEST_F(TargetDeclTest, Recovery) {
153 // error-ok: testing behavior on broken code
158 EXPECT_DECLS("UnresolvedLookupExpr",
"int f()",
"int f(int, int)");
161 TEST_F(TargetDeclTest, RecoveryType) {
163 // error-ok: testing behavior on broken code
164 struct S { int member; };
167 // No overload matches, but we have recovery-expr with the correct type.
168 overloaded().[[member]];
174 TEST_F(TargetDeclTest, UsingDecl) {
206 int x = Y().[[foo]]();
212 TEST_F(TargetDeclTest, ConstructorInitList) {
230 TEST_F(TargetDeclTest, DesignatedInit) {
234 struct Y { int b; struct X c[2]; };
235 struct Y y = { .c[0].[[a]] = 1 };
240 TEST_F(TargetDeclTest, NestedNameSpecifier) {
242 namespace a { namespace b { int c; } }
248 namespace a { struct X { enum { y }; }; }
254 template <typename T>
260 namespace a { int x; }
268 TEST_F(TargetDeclTest, Types) {
283 namespace ns { struct S{}; }
292 Flags = {
"-fno-delayed-template-parsing"};
295 void foo() { [[T]] x; }
302 Flags = {
"-fno-delayed-template-parsing"};
304 template<template<typename> class T>
305 void foo() { [[T<int>]] x; }
307 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> class T");
325 template <typename... E>
327 static const int size = sizeof...([[E]]);
333 template <typename T>
341 TEST_F(TargetDeclTest, ClassTemplate) {
343 // Implicit specialization.
344 template<int x> class Foo{};
352 template<typename T> class Foo {};
353 // The "Foo<int>" SpecializationDecl is incomplete, there is no
354 // instantiation happening.
355 void func([[Foo<int>]] *);
362 // Explicit specialization.
363 template<int x> class Foo{};
364 template<> class Foo<42>{};
367 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template<> class Foo<42>");
370 // Partial specialization.
371 template<typename T> class Foo{};
372 template<typename T> class Foo<T*>{};
380 // Class template argument deduction
381 template <typename T>
389 Flags.push_back("-std=c++17");
394 TEST_F(TargetDeclTest, Concept) {
396 template <typename T>
397 concept Fooable = requires (T t) { t.foo(); };
399 template <typename T> requires [[Fooable]]<T>
404 Flags.push_back("-std=c++20");
406 "ConceptSpecializationExpr",
409 {
"template <typename T> concept Fooable = requires (T t) { t.foo(); };"});
412 TEST_F(TargetDeclTest, FunctionTemplate) {
414 // Implicit specialization.
415 template<typename T> bool foo(T) { return false; };
416 bool x = [[foo]](42);
423 // Explicit specialization.
424 template<typename T> bool foo(T) { return false; };
425 template<> bool foo<int>(int) { return false; };
426 bool x = [[foo]](42);
428 EXPECT_DECLS("DeclRefExpr",
"template<> bool foo<int>(int)");
431 TEST_F(TargetDeclTest, VariableTemplate) {
434 // Implicit specialization.
435 template<typename T> int foo;
436 int x = [[foo]]<char>;
442 // Explicit specialization.
443 template<typename T> int foo;
444 template <> bool foo<char>;
445 int x = [[foo]]<char>;
450 // Partial specialization.
451 template<typename T> int foo;
452 template<typename T> bool foo<T*>;
453 bool x = [[foo]]<char*>;
459 TEST_F(TargetDeclTest, TypeAliasTemplate) {
461 template<typename T, int X> class SmallVector {};
462 template<typename U> using TinyVector = SmallVector<U, 1>;
463 [[TinyVector<int>]] X;
466 {
"template<> class SmallVector<int, 1>",
469 {
"using TinyVector = SmallVector<U, 1>",
473 TEST_F(TargetDeclTest, MemberOfTemplate) {
475 template <typename T> struct Foo {
478 int y = Foo<int>().[[x]](42);
484 template <typename T> struct Foo {
485 template <typename U>
488 int y = Foo<char>().[[x]]('c', 42);
495 TEST_F(TargetDeclTest, Lambda) {
497 void foo(int x = 42) {
498 auto l = [ [[x]] ]{ return x + 1; };
506 void foo(int x = 42) {
507 auto l = [x]{ return [[x]] + 1; };
514 auto l = [x = 1]{ return [[x]] + 1; };
521 TEST_F(TargetDeclTest, OverloadExpr) {
524 Flags = {
"-fno-delayed-template-parsing"};
535 EXPECT_DECLS("UnresolvedLookupExpr",
"void func(int *)",
"void func(char *)");
548 EXPECT_DECLS("UnresolvedMemberExpr",
"void func(int *)",
"void func(char *)");
551 TEST_F(TargetDeclTest, ObjC) {
552 Flags = {
"-xobjective-c"};
564 @interface Foo { @public int bar; }
581 EXPECT_DECLS("ObjCPropertyRefExpr",
"- (void)setX:(int)x");
585 @property(retain) I* x;
586 @property(retain) I* y;
593 "@property(atomic, retain, readwrite) I *x");
599 return [[@protocol(Foo)]];
607 void test([[Foo]] *p);
614 void test([[id<Foo>]] p);
622 void test(C<[[Foo]]> *p);
628 class FindExplicitReferencesTest :
public ::testing::Test {
638 AllRefs annotateReferencesInFoo(llvm::StringRef
Code) {
640 TU.Code = std::string(
Code);
644 TU.ExtraArgs.push_back(
"-fno-delayed-template-parsing");
645 TU.ExtraArgs.push_back(
"-std=c++20");
646 TU.ExtraArgs.push_back(
"-xobjective-c++");
648 auto AST = TU.build();
650 if (
auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
651 TestDecl = T->getTemplatedDecl();
653 std::vector<ReferenceLoc>
Refs;
654 if (
const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
656 Refs.push_back(std::move(R));
658 else if (
const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
661 if (R.Targets.size() == 1 && R.Targets.front() == NS)
663 Refs.push_back(std::move(R));
666 ADD_FAILURE() <<
"Failed to find ::foo decl for test";
668 auto &SM =
AST.getSourceManager();
669 llvm::sort(
Refs, [&](
const ReferenceLoc &L,
const ReferenceLoc &R) {
670 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
674 unsigned NextCodeChar = 0;
675 for (
unsigned I = 0; I <
Refs.size(); ++I) {
678 SourceLocation
Pos = R.NameLoc;
679 assert(
Pos.isValid());
681 Pos = SM.getExpansionLoc(
Pos);
682 assert(
Pos.isFileID());
687 if (
File == SM.getMainFileID()) {
689 assert(NextCodeChar <=
Offset);
699 for (
unsigned I = 0; I <
Refs.size(); ++I)
706 TEST_F(FindExplicitReferencesTest, All) {
707 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
712 void foo(int param) {
713 $0^global = $1^param + $2^func();
716 "0: targets = {global}\n"
717 "1: targets = {param}\n"
718 "2: targets = {func}\n"},
726 "1: targets = {X::a}\n"},
728 // error-ok: testing with broken code
731 return $0^bar() + $1^bar(42);
734 "0: targets = {bar}\n"
735 "1: targets = {bar}\n"},
739 namespace alias = ns;
741 using namespace $0^ns;
742 using namespace $1^alias;
745 "0: targets = {ns}\n"
746 "1: targets = {alias}\n"},
749 namespace ns { int global; }
751 using $0^ns::$1^global;
754 "0: targets = {ns}\n"
755 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
758 struct Struct { int a; };
763 static_cast<$4^Struct*>(0);
766 "0: targets = {Struct}\n"
767 "1: targets = {x}, decl\n"
768 "2: targets = {Typedef}\n"
769 "3: targets = {y}, decl\n"
770 "4: targets = {Struct}\n"},
773 namespace a { namespace b { struct S { typedef int type; }; } }
775 $0^a::$1^b::$2^S $3^x;
776 using namespace $4^a::$5^b;
781 "1: targets = {a::b}, qualifier = 'a::'\n"
782 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
783 "3: targets = {x}, decl\n"
785 "5: targets = {a::b}, qualifier = 'a::'\n"
786 "6: targets = {a::b::S}\n"
787 "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
788 "8: targets = {y}, decl\n"},
791 $0^ten: // PRINT "HELLO WORLD!"
795 "0: targets = {ten}, decl\n"
796 "1: targets = {ten}\n"},
799 template <class T> struct vector { using value_type = T; };
800 template <> struct vector<bool> { using value_type = bool; };
802 $0^vector<int> $1^vi;
803 $2^vector<bool> $3^vb;
806 "0: targets = {vector<int>}\n"
807 "1: targets = {vi}, decl\n"
808 "2: targets = {vector<bool>}\n"
809 "3: targets = {vb}, decl\n"},
812 template <class T> struct vector { using value_type = T; };
813 template <> struct vector<bool> { using value_type = bool; };
814 template <class T> using valias = vector<T>;
816 $0^valias<int> $1^vi;
817 $2^valias<bool> $3^vb;
820 "0: targets = {valias}\n"
821 "1: targets = {vi}, decl\n"
822 "2: targets = {valias}\n"
823 "3: targets = {vb}, decl\n"},
827 template <typename $0^T>
834 "0: targets = {foo::Bar::T}, decl\n"
835 "1: targets = {foo::Bar}, decl\n"
836 "2: targets = {foo::Bar}\n"
837 "3: targets = {foo::Bar::f}, decl\n"
838 "4: targets = {foo::Bar}\n"},
841 struct X { void func(int); };
850 "1: targets = {Y::func}\n"},
853 namespace ns { void bar(int); }
860 "0: targets = {bar}\n"},
866 void foo(int a, int b) {
871 "1: targets = {b}\n"},
880 for (int $0^x : $1^vector()) {
885 "0: targets = {x}, decl\n"
886 "1: targets = {vector}\n"
887 "2: targets = {x}\n"},
892 #ifndef EXPENSIVE_CHECKS
894 namespace ns1 { void func(char*); }
895 namespace ns2 { void func(int*); }
904 "0: targets = {ns1::func, ns2::func}\n"
905 "1: targets = {t}\n"},
920 "1: targets = {X::func, X::func}\n"
921 "2: targets = {t}\n"},
931 $0^S<$1^T>::$2^value;
936 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
950 "1: targets = {S::value}\n"},
955 static_cast<$0^T>(0);
963 "3: targets = {t}, decl\n"},
971 "0: targets = {x}, decl\n"
972 "1: targets = {I}\n"},
975 template <class T> struct vector {};
977 template <template<class> class TT, template<class> class ...TP>
985 "0: targets = {TT}\n"
986 "1: targets = {x}, decl\n"
987 "2: targets = {foo}\n"
988 "3: targets = {TT}\n"
989 "4: targets = {foo}\n"
990 "5: targets = {vector}\n"
991 "6: targets = {foo}\n"
992 "7: targets = {TP}\n"},
996 template <int(*)()> struct wrapper {};
998 template <int(*FuncParam)()>
1000 $0^wrapper<$1^func> $2^w;
1004 "0: targets = {wrapper<&func>}\n"
1005 "1: targets = {func}\n"
1006 "2: targets = {w}, decl\n"
1007 "3: targets = {FuncParam}\n"},
1013 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1015 enum $5^E { $6^ABC };
1017 using $8^INT2 = int;
1018 namespace $9^NS = $10^ns;
1021 "0: targets = {Foo}, decl\n"
1022 "1: targets = {foo()::Foo::Foo}, decl\n"
1023 "2: targets = {Foo}\n"
1024 "3: targets = {foo()::Foo::field}, decl\n"
1025 "4: targets = {Var}, decl\n"
1026 "5: targets = {E}, decl\n"
1027 "6: targets = {foo()::ABC}, decl\n"
1028 "7: targets = {INT}, decl\n"
1029 "8: targets = {INT2}, decl\n"
1030 "9: targets = {NS}, decl\n"
1031 "10: targets = {ns}\n"},
1038 // FIXME: This should have only one reference to Bar.
1039 $2^operator $3^$4^Bar();
1043 $7^f.$8^operator $9^Bar();
1046 "0: targets = {Bar}, decl\n"
1047 "1: targets = {Foo}, decl\n"
1048 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1049 "3: targets = {Bar}\n"
1050 "4: targets = {Bar}\n"
1051 "5: targets = {Foo}\n"
1052 "6: targets = {f}, decl\n"
1053 "7: targets = {f}\n"
1054 "8: targets = {foo()::Foo::operator Bar}\n"
1055 "9: targets = {Bar}\n"},
1063 void $2^destructMe() {
1069 $6^f.~ /*...*/ $7^Foo();
1072 "0: targets = {Foo}, decl\n"
1075 "1: targets = {Foo}\n"
1076 "2: targets = {foo()::Foo::destructMe}, decl\n"
1077 "3: targets = {Foo}\n"
1078 "4: targets = {Foo}\n"
1079 "5: targets = {f}, decl\n"
1080 "6: targets = {f}\n"
1081 "7: targets = {Foo}\n"},
1086 // member initializer
1092 class $4^Derived : public $5^Base {
1094 $8^Derived() : $9^Base() {}
1096 // delegating initializer
1099 $12^Foo(): $13^Foo(111) {}
1103 "0: targets = {X}, decl\n"
1104 "1: targets = {foo()::X::abc}, decl\n"
1105 "2: targets = {foo()::X::X}, decl\n"
1106 "3: targets = {foo()::X::abc}\n"
1107 "4: targets = {Derived}, decl\n"
1108 "5: targets = {Base}\n"
1109 "6: targets = {Base}\n"
1110 "7: targets = {foo()::Derived::B}, decl\n"
1111 "8: targets = {foo()::Derived::Derived}, decl\n"
1112 "9: targets = {Base}\n"
1113 "10: targets = {Foo}, decl\n"
1114 "11: targets = {foo()::Foo::Foo}, decl\n"
1115 "12: targets = {foo()::Foo::Foo}, decl\n"
1116 "13: targets = {Foo}\n"},
1122 int (*$1^fptr)(int $2^a, int) = nullptr;
1125 "0: targets = {x}, decl\n"
1126 "1: targets = {fptr}, decl\n"
1127 "2: targets = {a}, decl\n"},
1131 namespace ns { struct Type {}; }
1132 namespace alias = ns;
1133 namespace rec_alias = alias;
1136 $0^ns::$1^Type $2^a;
1137 $3^alias::$4^Type $5^b;
1138 $6^rec_alias::$7^Type $8^c;
1141 "0: targets = {ns}\n"
1142 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1143 "2: targets = {a}, decl\n"
1144 "3: targets = {alias}\n"
1145 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1146 "5: targets = {b}, decl\n"
1147 "6: targets = {rec_alias}\n"
1148 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1149 "8: targets = {c}, decl\n"},
1153 template <typename... E>
1155 constexpr int $0^size = sizeof...($1^E);
1158 "0: targets = {size}, decl\n"
1159 "1: targets = {E}\n"},
1163 template <typename T>
1171 "0: targets = {Test}\n"
1172 "1: targets = {a}, decl\n"},
1176 template <typename $0^T>
1180 "0: targets = {foo::Bar::T}, decl\n"
1181 "1: targets = {foo::Bar}, decl\n"},
1185 template <typename $0^T>
1189 "0: targets = {T}, decl\n"
1190 "1: targets = {foo::func}, decl\n"},
1194 template <typename $0^T>
1198 "0: targets = {foo::T}, decl\n"
1199 "1: targets = {foo::T}\n"
1200 "2: targets = {foo::x}, decl\n"},
1203 template<typename T> class vector {};
1205 template <typename $0^T>
1206 using $1^V = $2^vector<$3^T>;
1209 "0: targets = {foo::T}, decl\n"
1210 "1: targets = {foo::V}, decl\n"
1211 "2: targets = {vector}\n"
1212 "3: targets = {foo::T}\n"},
1216 template <typename T>
1217 concept Drawable = requires (T t) { t.draw(); };
1220 template <typename $0^T> requires $1^Drawable<$2^T>
1221 void $3^bar($4^T $5^t) {
1226 "0: targets = {T}, decl\n"
1227 "1: targets = {Drawable}\n"
1228 "2: targets = {T}\n"
1229 "3: targets = {foo::bar}, decl\n"
1230 "4: targets = {T}\n"
1231 "5: targets = {t}, decl\n"
1232 "6: targets = {t}\n"
1233 "7: targets = {}\n"},
1238 @property(retain) I* x;
1239 @property(retain) I* y;
1246 "0: targets = {f}\n"
1247 "1: targets = {I::x}\n"
1248 "2: targets = {I::y}\n"},
1261 "0: targets = {f}\n"
1262 "1: targets = {I::x}\n"
1263 "2: targets = {I::setY:}\n"},
1270 $2^Foo $3^f { .$4^Bar = 42 };
1273 "0: targets = {Foo}, decl\n"
1274 "1: targets = {foo()::Foo::Bar}, decl\n"
1275 "2: targets = {Foo}\n"
1276 "3: targets = {f}, decl\n"
1277 "4: targets = {foo()::Foo::Bar}\n"},
1286 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
1289 "0: targets = {Baz}, decl\n"
1290 "1: targets = {foo()::Baz::Field}, decl\n"
1291 "2: targets = {Bar}, decl\n"
1292 "3: targets = {Baz}\n"
1293 "4: targets = {foo()::Bar::Foo}, decl\n"
1294 "5: targets = {Bar}\n"
1295 "6: targets = {bar}, decl\n"
1296 "7: targets = {foo()::Bar::Foo}\n"
1297 "8: targets = {foo()::Baz::Field}\n"},
1299 template<typename T>
1301 template<typename T>
1303 $0^crash({.$1^x = $2^T()});
1306 "0: targets = {crash}\n"
1308 "2: targets = {T}\n"
1312 template <template <typename> typename T>
1315 template <typename $0^T>
1316 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
1319 "0: targets = {foo::Derive::T}, decl\n"
1320 "1: targets = {foo::Derive}, decl\n"
1321 "2: targets = {Base}\n"
1322 "3: targets = {foo::Derive::T}\n"
1323 "4: targets = {}, qualifier = 'T::'\n"},
1326 for (
const auto &C : Cases) {
1327 llvm::StringRef ExpectedCode = C.first;
1328 llvm::StringRef ExpectedRefs = C.second;
1331 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
1332 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
1333 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;