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 {
68 std::vector<std::string> Flags;
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, OffsetOf) {
347 struct Foo { int bar; };
348 int x = __builtin_offsetof(Foo, [[bar]]);
353 struct Inner { int c; };
354 struct Outer { Inner b; };
355 int x = __builtin_offsetof(Outer, [[b]].c);
360 struct Inner { int c; };
361 struct Outer { Inner b; };
362 int x = __builtin_offsetof(Outer, b.[[c]]);
369 struct Inner { int c; };
370 struct Outer { Inner b; };
371 int x = __builtin_offsetof(Outer, [[b.c]]);
373 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
376 struct Inner { int c; };
377 struct Outer { Inner b; };
378 int x = __builtin_offsetof(Outer, [[b.]]c);
380 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
383 struct Inner { int c; };
384 struct Outer { Inner b; };
385 int x = __builtin_offsetof(Outer, b[[.c]]);
390 struct Foo { int bar; };
391 int x = __builtin_[[offsetof]](Foo, bar);
393 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
400 int o = __builtin_offsetof(D, [[x]]);
407 template <typename T> int f() { return __builtin_offsetof(T, [[x]]); }
409 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfNode"), ::testing::IsEmpty());
413 #define offsetof(t, m) __builtin_offsetof(t, m)
414 struct Foo { int bar; };
415 int x = offsetof(Foo, [[bar]]);
422 struct Foo { int bar[4]; };
424 int x = __builtin_offsetof(Foo, bar[ [[i]] ]);
429TEST_F(TargetDeclTest, NestedNameSpecifier) {
431 namespace a { namespace b { int c; } }
437 namespace a { struct X { enum { y }; }; }
443 template <typename T>
449 namespace a { int x; }
453 EXPECT_DECLS("NestedNameSpecifierLoc", {
"namespace b = a", Rel::Alias},
454 {
"namespace a", Rel::Underlying});
457TEST_F(TargetDeclTest, Types) {
469 EXPECT_DECLS("TypedefTypeLoc", {
"typedef S X", Rel::Alias},
470 {
"struct S", Rel::Underlying});
472 namespace ns { struct S{}; }
476 EXPECT_DECLS("TypedefTypeLoc", {
"typedef ns::S X", Rel::Alias},
477 {
"struct S", Rel::Underlying});
481 void foo() { [[T]] x; }
487 template<template<typename> class T>
488 void foo() { [[T<int>]] x; }
490 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> class T");
494 template<template<typename> class ...T>
499 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename> class ...T"});
507 EXPECT_DECLS("DecltypeTypeLoc", {
"struct S", Rel::Underlying});
517 template <typename... E>
519 static const int size = sizeof...([[E]]);
525 template <typename T>
533TEST_F(TargetDeclTest, ClassTemplate) {
535 // Implicit specialization.
536 template<int x> class Foo{};
540 {
"template<> class Foo<42>", Rel::TemplateInstantiation},
541 {
"class Foo", Rel::TemplatePattern});
544 template<typename T> class Foo {};
545 // The "Foo<int>" SpecializationDecl is incomplete, there is no
546 // instantiation happening.
547 void func([[Foo<int>]] *);
550 {
"class Foo", Rel::TemplatePattern},
551 {
"template<> class Foo<int>", Rel::TemplateInstantiation});
554 // Explicit specialization.
555 template<int x> class Foo{};
556 template<> class Foo<42>{};
559 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template<> class Foo<42>");
562 // Partial specialization.
563 template<typename T> class Foo{};
564 template<typename T> class Foo<T*>{};
568 {
"template<> class Foo<int *>", Rel::TemplateInstantiation},
569 {
"template <typename T> class Foo<T *>", Rel::TemplatePattern});
572 // Template template argument.
573 template<typename T> struct Vector {};
574 template <template <typename> class Container>
578 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename T> struct Vector"});
580 Flags.push_back(
"-std=c++17");
583 // Class template argument deduction
584 template <typename T>
593 {
"struct Test", Rel::TemplatePattern});
597 template <typename T>
599 template <typename I>
602 template <typename I>
603 [[Test]](I, I) -> Test<typename I::type>;
605 EXPECT_DECLS("CXXDeductionGuideDecl", {
"template <typename T> struct Test"});
609 Flags.push_back(
"-std=c++20");
615 template <typename T>
616 concept Fooable = requires (T t) { t.foo(); };
618 template <typename T> requires [[Fooable]]<T>
625 {
"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
629 template <typename T>
630 concept Fooable = true;
632 template <typename T>
633 void foo() requires [[Fooable]]<T>;
636 {
"template <typename T> concept Fooable = true"});
640 template <typename T>
641 concept Fooable = true;
643 template <[[Fooable]] T>
647 {
"template <typename T> concept Fooable = true"});
651 template <typename T, typename U>
652 concept Fooable = true;
654 template <[[Fooable]]<int> T>
658 {
"template <typename T, typename U> concept Fooable = true"});
661TEST_F(TargetDeclTest, Coroutine) {
662 Flags.push_back(
"-std=c++20");
666 template <typename, typename...> struct coroutine_traits;
667 template <typename> struct coroutine_handle {
668 template <typename U>
669 coroutine_handle(coroutine_handle<U>&&) noexcept;
670 static coroutine_handle from_address(void* __addr) noexcept;
676 struct awaitable_frame {
677 awaitable get_return_object();
679 void unhandled_exception();
682 bool await_ready() const noexcept;
683 void await_suspend(std::coroutine_handle<void>) noexcept;
684 void await_resume() const noexcept;
686 result_t initial_suspend() noexcept;
687 result_t final_suspend() noexcept;
688 result_t await_transform(executor) noexcept;
693 struct coroutine_traits<awaitable> {
694 typedef awaitable_frame promise_type;
699 co_await [[executor]]();
705TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
706 Flags.push_back(
"-std=c++20");
710 struct strong_ordering {
712 constexpr operator int() const { return n; }
713 static const strong_ordering equal, greater, less;
715 constexpr strong_ordering strong_ordering::equal = {0};
716 constexpr strong_ordering strong_ordering::greater = {1};
717 constexpr strong_ordering strong_ordering::less = {-1};
723 auto operator<=>(const Foo&) const = default;
726 bool x = (Foo(1) [[!=]] Foo(2));
729 {
"bool operator==(const Foo &) const noexcept = default"});
732TEST_F(TargetDeclTest, FunctionTemplate) {
734 // Implicit specialization.
735 template<typename T> bool foo(T) { return false; };
736 bool x = [[foo]](42);
739 {
"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
740 {
"bool foo(T)", Rel::TemplatePattern});
743 // Explicit specialization.
744 template<typename T> bool foo(T) { return false; };
745 template<> bool foo<int>(int) { return false; };
746 bool x = [[foo]](42);
748 EXPECT_DECLS("DeclRefExpr",
"template<> bool foo<int>(int)");
751TEST_F(TargetDeclTest, VariableTemplate) {
754 // Implicit specialization.
755 template<typename T> int foo;
756 int x = [[foo]]<char>;
758 EXPECT_DECLS("DeclRefExpr", {
"int foo", Rel::TemplateInstantiation},
759 {
"int foo", Rel::TemplatePattern});
762 // Explicit specialization.
763 template<typename T> int foo;
764 template <> bool foo<char>;
765 int x = [[foo]]<char>;
770 // Partial specialization.
771 template<typename T> int foo;
772 template<typename T> bool foo<T*>;
773 bool x = [[foo]]<char*>;
775 EXPECT_DECLS("DeclRefExpr", {
"bool foo", Rel::TemplateInstantiation},
776 {
"bool foo", Rel::TemplatePattern});
779TEST_F(TargetDeclTest, TypeAliasTemplate) {
781 template<typename T, int X> class SmallVector {};
782 template<typename U> using TinyVector = SmallVector<U, 1>;
783 [[TinyVector<int>]] X;
786 {
"template<> class SmallVector<int, 1>",
787 Rel::TemplateInstantiation | Rel::Underlying},
788 {
"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
789 {
"using TinyVector = SmallVector<U, 1>",
790 Rel::Alias | Rel::TemplatePattern});
793TEST_F(TargetDeclTest, BuiltinTemplates) {
795 template <class T, T... Index> struct integer_sequence {};
796 [[__make_integer_seq]]<integer_sequence, int, 3> X;
799 "TemplateSpecializationTypeLoc",
800 {
"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
801 {
"template<> struct integer_sequence<int, <0, 1, 2>>",
802 Rel::TemplateInstantiation | Rel::Underlying});
806 template <class T, T... Index> struct integer_sequence;
808 template <class T, int N>
809 using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
814 template <int N, class... Pack>
815 using type_pack_element = [[__type_pack_element]]<N, Pack...>;
820 template <template <class...> class Templ, class... Types>
821 using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;
826TEST_F(TargetDeclTest, MemberOfTemplate) {
828 template <typename T> struct Foo {
831 int y = Foo<int>().[[x]](42);
833 EXPECT_DECLS("MemberExpr", {
"int x(int)", Rel::TemplateInstantiation},
834 {
"int x(T)", Rel::TemplatePattern});
837 template <typename T> struct Foo {
838 template <typename U>
841 int y = Foo<char>().[[x]]('c', 42);
844 {
"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
845 {
"int x(T, U)", Rel::TemplatePattern});
848TEST_F(TargetDeclTest, Lambda) {
850 void foo(int x = 42) {
851 auto l = [ [[x]] ]{ return x + 1; };
859 void foo(int x = 42) {
860 auto l = [x]{ return [[x]] + 1; };
867 auto l = [x = 1]{ return [[x]] + 1; };
874TEST_F(TargetDeclTest, OverloadExpr) {
875 Flags.push_back(
"--target=x86_64-pc-linux-gnu");
886 EXPECT_DECLS("UnresolvedLookupExpr",
"void func(int *)",
"void func(char *)");
899 EXPECT_DECLS("UnresolvedMemberExpr",
"void func(int *)",
"void func(char *)");
903 static void *operator new(unsigned long);
905 auto* k = [[new]] X();
907 EXPECT_DECLS("CXXNewExpr",
"static void *operator new(unsigned long)");
909 void *operator new(unsigned long);
910 auto* k = [[new]] int();
912 EXPECT_DECLS("CXXNewExpr",
"void *operator new(unsigned long)");
916 static void operator delete(void *) noexcept;
922 EXPECT_DECLS("CXXDeleteExpr",
"static void operator delete(void *) noexcept");
924 void operator delete(void *) noexcept;
931 "void operator delete(void *, __size_t) noexcept");
934TEST_F(TargetDeclTest, DependentExprs) {
935 Flags.push_back(
"--std=c++20");
939 struct A { void foo() {} };
940 template <typename T>
958 template <typename T>
962 this->c.getA().[[foo]]();
977 template <typename T>
981 this->c.fptr().[[foo]]();
992 template <typename T> struct Foo {
999 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"int aaaa");
1005 template <typename T> T convert() const;
1007 template <typename T>
1009 Foo::k(T()).template [[convert]]<T>();
1013 "template <typename T> T convert() const");
1016 template <typename T>
1020 template <typename T>
1021 using Wally = Waldo<T>;
1022 template <typename T>
1023 void foo(Wally<T> w) {
1027 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
1030 template <typename T>
1034 template <typename T>
1036 using Type = Waldo<T>;
1038 template <typename T>
1039 void foo(typename MetaWaldo<T>::Type w) {
1043 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
1049 template <typename T>
1050 using Wally = Waldo;
1052 struct S : Wally<int> {
1053 void Foo() { this->[[find]](); }
1063 const int found = N;
1071 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"const int found = N");
1074TEST_F(TargetDeclTest, DependentTypes) {
1078 struct A { struct B {}; };
1080 template <typename T>
1081 void foo(typename A<T>::[[B]]);
1088 struct A { struct B { struct C {}; }; };
1090 template <typename T>
1091 void foo(typename A<T>::[[B]]::C);
1099 struct A { struct B { struct C {}; }; };
1101 template <typename T>
1102 void foo(typename A<T>::B::[[C]]);
1110 template <typename> struct B {};
1113 template <typename T>
1114 void foo(typename A<T>::template [[B]]<int>);
1116 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> struct B");
1123 typedef typename waldo<N - 1>::type::[[next]] type;
1135 using type = typename odd<N - 1>::type::next;
1140 using type = typename even<N - 1>::type::[[next]];
1146TEST_F(TargetDeclTest, TypedefCascade) {
1152 using type = C::type;
1155 using type = B::type;
1160 {
"using type = int", Rel::Alias | Rel::Underlying},
1161 {
"using type = C::type", Rel::Alias | Rel::Underlying},
1162 {
"using type = B::type", Rel::Alias});
1165TEST_F(TargetDeclTest, RecursiveTemplate) {
1166 Flags.push_back(
"-std=c++20");
1169 template <typename T>
1170 concept Leaf = false;
1172 template <typename Tree>
1173 struct descend_left {
1174 using type = typename descend_left<typename Tree::left>::[[type]];
1177 template <Leaf Tree>
1178 struct descend_left<Tree> {
1179 using type = typename Tree::value;
1183 {
"using type = typename descend_left<typename Tree::left>::type",
1184 Rel::Alias | Rel::Underlying});
1187TEST_F(TargetDeclTest, ObjC) {
1188 Flags = {
"-xobjective-c"};
1200 @interface Foo { @public int bar; }
1211 -(void) setX:(int)x;
1217 EXPECT_DECLS("ObjCPropertyRefExpr",
"- (void)setX:(int)x");
1221 @property(retain) I* x;
1222 @property(retain) I* y;
1229 "@property(atomic, retain, readwrite) I *x");
1234 @interface Interface
1235 @property(retain) [[MYObject]] *x;
1238 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject");
1241 @interface MYObject2
1243 @interface Interface
1244 @property(retain, nonnull) [[MYObject2]] *x;
1247 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject2");
1253 return [[@protocol(Foo)]];
1261 void test([[Foo]] *p);
1263 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1265 Code = R
"cpp(// Don't consider implicit interface as the target.
1266 @implementation [[Implicit]]
1269 EXPECT_DECLS("ObjCImplementationDecl",
"@implementation Implicit");
1274 @implementation [[Foo]]
1277 EXPECT_DECLS("ObjCImplementationDecl",
"@interface Foo");
1282 @interface Foo (Ext)
1284 @implementation [[Foo]] (Ext)
1287 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1292 @interface Foo (Ext)
1294 @implementation Foo ([[Ext]])
1297 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1300 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1308 void test([[C]]<Foo> *p);
1316 void test(C<[[Foo]]> *p);
1326 void test(C<[[Foo]], Bar> *p);
1336 void test(C<Foo, [[Bar]]> *p);
1342 + (id)sharedInstance;
1345 + (id)sharedInstance { return 0; }
1348 id value = [[Foo]].sharedInstance;
1351 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1355 + (id)sharedInstance;
1358 + (id)sharedInstance { return 0; }
1361 id value = Foo.[[sharedInstance]];
1364 EXPECT_DECLS("ObjCPropertyRefExpr",
"+ (id)sharedInstance");
1368 + ([[id]])sharedInstance;
1375 + ([[instancetype]])sharedInstance;
1381class FindExplicitReferencesTest :
public ::testing::Test {
1384 std::string AnnotatedCode;
1385 std::string DumpedReferences;
1388 TestTU newTU(llvm::StringRef Code) {
1390 TU.Code = std::string(Code);
1394 TU.ExtraArgs.push_back(
"-std=c++20");
1395 TU.ExtraArgs.push_back(
"-xobjective-c++");
1400 AllRefs annotatedReferences(llvm::StringRef Code, ParsedAST &
AST,
1401 std::vector<ReferenceLoc> Refs) {
1402 auto &SM =
AST.getSourceManager();
1403 llvm::stable_sort(Refs, [&](
const ReferenceLoc &L,
const ReferenceLoc &R) {
1404 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1407 std::string AnnotatedCode;
1408 unsigned NextCodeChar = 0;
1409 for (
unsigned I = 0; I < Refs.size(); ++I) {
1412 SourceLocation Pos = R.NameLoc;
1413 assert(Pos.isValid());
1414 if (Pos.isMacroID())
1415 Pos = SM.getExpansionLoc(Pos);
1416 assert(Pos.isFileID());
1420 std::tie(
File, Offset) = SM.getDecomposedLoc(Pos);
1421 if (
File == SM.getMainFileID()) {
1423 assert(NextCodeChar <= Offset);
1424 AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
1425 AnnotatedCode +=
"$" + std::to_string(I) +
"^";
1427 NextCodeChar = Offset;
1430 AnnotatedCode += Code.substr(NextCodeChar);
1432 std::string DumpedReferences;
1433 for (
unsigned I = 0; I < Refs.size(); ++I)
1434 DumpedReferences += std::string(llvm::formatv(
"{0}: {1}\n", I, Refs[I]));
1436 return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
1442 AllRefs annotateAllReferences(llvm::StringRef Code) {
1443 TestTU TU = newTU(Code);
1444 auto AST = TU.build();
1446 std::vector<ReferenceLoc> Refs;
1447 for (
auto *TopLevel :
AST.getLocalTopLevelDecls())
1449 TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1450 AST.getHeuristicResolver());
1451 return annotatedReferences(Code,
AST, std::move(Refs));
1457 AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
1458 TestTU TU = newTU(Code);
1459 auto AST = TU.build();
1461 if (
auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1462 TestDecl =
T->getTemplatedDecl();
1464 std::vector<ReferenceLoc> Refs;
1465 if (
const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1468 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1469 AST.getHeuristicResolver());
1470 else if (
const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1473 [&Refs, &NS](ReferenceLoc R) {
1475 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1477 Refs.push_back(std::move(R));
1479 AST.getHeuristicResolver());
1480 else if (
const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))
1482 OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1483 AST.getHeuristicResolver());
1485 ADD_FAILURE() <<
"Failed to find ::foo decl for test";
1487 return annotatedReferences(Code,
AST, std::move(Refs));
1491TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
1492 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
1497 void foo(int param) {
1498 $0^global = $1^param + $2^func();
1501 "0: targets = {global}\n"
1502 "1: targets = {param}\n"
1503 "2: targets = {func}\n"},
1505 struct X { int a; };
1510 "0: targets = {x}\n"
1511 "1: targets = {X::a}\n"},
1513 // error-ok: testing with broken code
1516 return $0^bar() + $1^bar(42);
1519 "0: targets = {bar}\n"
1520 "1: targets = {bar}\n"},
1524 namespace alias = ns;
1526 using namespace $0^ns;
1527 using namespace $1^alias;
1530 "0: targets = {ns}\n"
1531 "1: targets = {alias}\n"},
1534 namespace ns { int global; }
1536 using $0^ns::$1^global;
1539 "0: targets = {ns}\n"
1540 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1543 namespace ns { enum class A {}; }
1545 using enum $0^ns::$1^A;
1548 "0: targets = {ns}\n"
1549 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1552 struct Struct { int a; };
1553 using Typedef = int;
1557 static_cast<$4^Struct*>(0);
1560 "0: targets = {Struct}\n"
1561 "1: targets = {x}, decl\n"
1562 "2: targets = {Typedef}\n"
1563 "3: targets = {y}, decl\n"
1564 "4: targets = {Struct}\n"},
1567 namespace a { namespace b { struct S { typedef int type; }; } }
1569 $0^a::$1^b::$2^S $3^x;
1570 using namespace $4^a::$5^b;
1574 "0: targets = {a}\n"
1575 "1: targets = {a::b}, qualifier = 'a::'\n"
1576 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1577 "3: targets = {x}, decl\n"
1578 "4: targets = {a}\n"
1579 "5: targets = {a::b}, qualifier = 'a::'\n"
1580 "6: targets = {a::b::S}\n"
1581 "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
1582 "8: targets = {y}, decl\n"},
1585 $0^ten: // PRINT "HELLO WORLD!"
1589 "0: targets = {ten}, decl\n"
1590 "1: targets = {ten}\n"},
1593 template <class T> struct vector { using value_type = T; };
1594 template <> struct vector<bool> { using value_type = bool; };
1596 $0^vector<int> $1^vi;
1597 $2^vector<bool> $3^vb;
1600 "0: targets = {vector<int>}\n"
1601 "1: targets = {vi}, decl\n"
1602 "2: targets = {vector<bool>}\n"
1603 "3: targets = {vb}, decl\n"},
1606 template <class T> struct vector { using value_type = T; };
1607 template <> struct vector<bool> { using value_type = bool; };
1608 template <class T> using valias = vector<T>;
1610 $0^valias<int> $1^vi;
1611 $2^valias<bool> $3^vb;
1614 "0: targets = {valias}\n"
1615 "1: targets = {vi}, decl\n"
1616 "2: targets = {valias}\n"
1617 "3: targets = {vb}, decl\n"},
1621 template <typename $0^T>
1628 "0: targets = {foo::Bar::T}, decl\n"
1629 "1: targets = {foo::Bar}, decl\n"
1630 "2: targets = {foo::Bar}\n"
1631 "3: targets = {foo::Bar::f}, decl\n"
1632 "4: targets = {foo::Bar}\n"},
1635 struct X { void func(int); };
1643 "0: targets = {y}\n"
1644 "1: targets = {Y::func}\n"},
1647 namespace ns { void bar(int); }
1654 "0: targets = {bar}\n"},
1660 void foo(int a, int b) {
1664 "0: targets = {a}\n"
1665 "1: targets = {b}\n"},
1674 for (int $0^x : $1^vector()) {
1679 "0: targets = {x}, decl\n"
1680 "1: targets = {vector}\n"
1681 "2: targets = {x}\n"},
1684 namespace ns1 { void func(char*); }
1685 namespace ns2 { void func(int*); }
1686 using namespace ns1;
1687 using namespace ns2;
1694 "0: targets = {ns1::func, ns2::func}\n"
1695 "1: targets = {t}\n"},
1704 void foo(X x, T t) {
1708 "0: targets = {x}\n"
1709 "1: targets = {X::func, X::func}\n"
1710 "2: targets = {t}\n"},
1720 $0^S<$1^T>::$2^value;
1723 "0: targets = {S}\n"
1724 "1: targets = {T}\n"
1725 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1738 "0: targets = {t}\n"
1739 "1: targets = {S::value}\n"},
1744 static_cast<$0^T>(0);
1749 "0: targets = {T}\n"
1750 "1: targets = {T}\n"
1751 "2: targets = {T}\n"
1752 "3: targets = {t}, decl\n"},
1760 "0: targets = {x}, decl\n"
1761 "1: targets = {I}\n"},
1764 template <class T> struct vector {};
1766 template <template<class> class TT, template<class> class ...TP>
1770 $4^foo<$5^vector>();
1774 "0: targets = {TT}\n"
1775 "1: targets = {x}, decl\n"
1776 "2: targets = {foo}\n"
1777 "3: targets = {TT}\n"
1778 "4: targets = {foo}\n"
1779 "5: targets = {vector}\n"
1780 "6: targets = {foo}\n"
1781 "7: targets = {TP}\n"},
1785 template <int(*)()> struct wrapper {};
1787 template <int(*FuncParam)()>
1789 $0^wrapper<$1^func> $2^w;
1793 "0: targets = {wrapper<&func>}\n"
1794 "1: targets = {func}\n"
1795 "2: targets = {w}, decl\n"
1796 "3: targets = {FuncParam}\n"},
1802 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1804 enum $5^E { $6^ABC };
1806 using $8^INT2 = int;
1807 namespace $9^NS = $10^ns;
1810 "0: targets = {Foo}, decl\n"
1811 "1: targets = {foo()::Foo::Foo}, decl\n"
1812 "2: targets = {Foo}\n"
1813 "3: targets = {foo()::Foo::field}, decl\n"
1814 "4: targets = {Var}, decl\n"
1815 "5: targets = {E}, decl\n"
1816 "6: targets = {foo()::ABC}, decl\n"
1817 "7: targets = {INT}, decl\n"
1818 "8: targets = {INT2}, decl\n"
1819 "9: targets = {NS}, decl\n"
1820 "10: targets = {ns}\n"},
1827 // FIXME: This should have only one reference to Bar.
1828 $2^operator $3^$4^Bar();
1832 $7^f.$8^operator $9^Bar();
1835 "0: targets = {Bar}, decl\n"
1836 "1: targets = {Foo}, decl\n"
1837 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1838 "3: targets = {Bar}\n"
1839 "4: targets = {Bar}\n"
1840 "5: targets = {Foo}\n"
1841 "6: targets = {f}, decl\n"
1842 "7: targets = {f}\n"
1843 "8: targets = {foo()::Foo::operator Bar}\n"
1844 "9: targets = {Bar}\n"},
1852 void $2^destructMe() {
1858 $6^f.~ /*...*/ $7^Foo();
1861 "0: targets = {Foo}, decl\n"
1864 "1: targets = {Foo}\n"
1865 "2: targets = {foo()::Foo::destructMe}, decl\n"
1866 "3: targets = {Foo}\n"
1867 "4: targets = {Foo}\n"
1868 "5: targets = {f}, decl\n"
1869 "6: targets = {f}\n"
1870 "7: targets = {Foo}\n"},
1875 // member initializer
1881 class $4^Derived : public $5^Base {
1883 $8^Derived() : $9^Base() {}
1885 // delegating initializer
1888 $12^Foo(): $13^Foo(111) {}
1892 "0: targets = {X}, decl\n"
1893 "1: targets = {foo()::X::abc}, decl\n"
1894 "2: targets = {foo()::X::X}, decl\n"
1895 "3: targets = {foo()::X::abc}\n"
1896 "4: targets = {Derived}, decl\n"
1897 "5: targets = {Base}\n"
1898 "6: targets = {Base}\n"
1899 "7: targets = {foo()::Derived::B}, decl\n"
1900 "8: targets = {foo()::Derived::Derived}, decl\n"
1901 "9: targets = {Base}\n"
1902 "10: targets = {Foo}, decl\n"
1903 "11: targets = {foo()::Foo::Foo}, decl\n"
1904 "12: targets = {foo()::Foo::Foo}, decl\n"
1905 "13: targets = {Foo}\n"},
1911 int (*$2^fptr)(int $3^a, int) = nullptr;
1914 "0: targets = {(unnamed class)}\n"
1915 "1: targets = {x}, decl\n"
1916 "2: targets = {fptr}, decl\n"
1917 "3: targets = {a}, decl\n"},
1921 namespace ns { struct Type {}; }
1922 namespace alias = ns;
1923 namespace rec_alias = alias;
1926 $0^ns::$1^Type $2^a;
1927 $3^alias::$4^Type $5^b;
1928 $6^rec_alias::$7^Type $8^c;
1931 "0: targets = {ns}\n"
1932 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1933 "2: targets = {a}, decl\n"
1934 "3: targets = {alias}\n"
1935 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1936 "5: targets = {b}, decl\n"
1937 "6: targets = {rec_alias}\n"
1938 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1939 "8: targets = {c}, decl\n"},
1943 template <typename... E>
1945 constexpr int $0^size = sizeof...($1^E);
1948 "0: targets = {size}, decl\n"
1949 "1: targets = {E}\n"},
1953 template <typename T>
1961 "0: targets = {Test}\n"
1962 "1: targets = {a}, decl\n"},
1966 template <typename $0^T>
1970 "0: targets = {foo::Bar::T}, decl\n"
1971 "1: targets = {foo::Bar}, decl\n"},
1975 template <typename $0^T>
1979 "0: targets = {T}, decl\n"
1980 "1: targets = {foo::func}, decl\n"},
1984 template <typename $0^T>
1988 "0: targets = {foo::T}, decl\n"
1989 "1: targets = {foo::T}\n"
1990 "2: targets = {foo::x}, decl\n"},
1993 template<typename T> class vector {};
1995 template <typename $0^T>
1996 using $1^V = $2^vector<$3^T>;
1999 "0: targets = {foo::T}, decl\n"
2000 "1: targets = {foo::V}, decl\n"
2001 "2: targets = {vector}\n"
2002 "3: targets = {foo::T}\n"},
2006 template <typename T>
2007 concept Drawable = requires (T t) { t.draw(); };
2010 template <typename $0^T> requires $1^Drawable<$2^T>
2011 void $3^bar($4^T $5^t) {
2016 "0: targets = {T}, decl\n"
2017 "1: targets = {Drawable}\n"
2018 "2: targets = {T}\n"
2019 "3: targets = {foo::bar}, decl\n"
2020 "4: targets = {T}\n"
2021 "5: targets = {t}, decl\n"
2022 "6: targets = {t}\n"
2023 "7: targets = {}\n"},
2037 "0: targets = {f}\n"
2038 "1: targets = {I::_z}\n"},
2043 @property(retain) I* x;
2044 @property(retain) I* y;
2051 "0: targets = {f}\n"
2052 "1: targets = {I::x}\n"
2053 "2: targets = {I::y}\n"},
2066 "0: targets = {f}\n"
2067 "1: targets = {I::x}\n"
2068 "2: targets = {I::setY:}\n"},
2073 @property(class) I *x;
2078 $2^local = $3^I.$4^x;
2081 "0: targets = {I}\n"
2082 "1: targets = {I::setX:}\n"
2083 "2: targets = {local}\n"
2084 "3: targets = {I}\n"
2085 "4: targets = {I::x}\n"},
2096 $2^local = $3^I.$4^x;
2099 "0: targets = {I}\n"
2100 "1: targets = {I::setX:}\n"
2101 "2: targets = {local}\n"
2102 "3: targets = {I}\n"
2103 "4: targets = {I::x}\n"},
2107 -(void) a:(int)x b:(int)y;
2113 "0: targets = {i}\n"
2114 "1: targets = {I::a:b:}\n"},
2125 "0: targets = {I}\n"
2126 "1: targets = {P}\n"
2127 "2: targets = {x}, decl\n"},
2135 $2^Foo $3^f { .$4^Bar = 42 };
2138 "0: targets = {Foo}, decl\n"
2139 "1: targets = {foo()::Foo::Bar}, decl\n"
2140 "2: targets = {Foo}\n"
2141 "3: targets = {f}, decl\n"
2142 "4: targets = {foo()::Foo::Bar}\n"},
2151 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
2154 "0: targets = {Baz}, decl\n"
2155 "1: targets = {foo()::Baz::Field}, decl\n"
2156 "2: targets = {Bar}, decl\n"
2157 "3: targets = {Baz}\n"
2158 "4: targets = {foo()::Bar::Foo}, decl\n"
2159 "5: targets = {Bar}\n"
2160 "6: targets = {bar}, decl\n"
2161 "7: targets = {foo()::Bar::Foo}\n"
2162 "8: targets = {foo()::Baz::Field}\n"},
2166 struct $0^Foo { int $1^bar; };
2167 int $2^x = __builtin_offsetof($3^Foo, $4^bar);
2170 "0: targets = {Foo}, decl\n"
2171 "1: targets = {foo()::Foo::bar}, decl\n"
2172 "2: targets = {x}, decl\n"
2173 "3: targets = {Foo}\n"
2174 "4: targets = {foo()::Foo::bar}\n"},
2180 $1^struct { int $2^c; } $3^B;
2182 int $4^x = __builtin_offsetof($5^A, $6^B.$7^c);
2185 "0: targets = {A}, decl\n"
2186 "1: targets = {foo()::A::(unnamed struct)}\n"
2187 "2: targets = {foo()::A::(unnamed struct)::c}, decl\n"
2188 "3: targets = {foo()::A::B}, decl\n"
2189 "4: targets = {x}, decl\n"
2190 "5: targets = {A}\n"
2191 "6: targets = {foo()::A::B}\n"
2192 "7: targets = {foo()::A::(unnamed struct)::c}\n"},
2198 struct $0^A { int $1^arr[4]; };
2200 int $3^x = __builtin_offsetof($4^A, $5^arr[$6^i]);
2203 "0: targets = {A}, decl\n"
2204 "1: targets = {foo()::A::arr}, decl\n"
2205 "2: targets = {i}, decl\n"
2206 "3: targets = {x}, decl\n"
2207 "4: targets = {A}\n"
2208 "5: targets = {foo()::A::arr}\n"
2209 "6: targets = {i}\n"},
2211 template<typename T>
2213 template<typename T>
2215 $0^crash({.$1^x = $2^T()});
2218 "0: targets = {crash}\n"
2220 "2: targets = {T}\n"},
2223 template <template <typename> typename T>
2226 template <typename $0^T>
2227 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
2230 "0: targets = {foo::Derive::T}, decl\n"
2231 "1: targets = {foo::Derive}, decl\n"
2232 "2: targets = {Base}\n"
2233 "3: targets = {foo::Derive::T}\n"
2234 "4: targets = {}, qualifier = 'T::'\n"},
2238 template <typename $0^T>
2240 template <typename $2^I>
2243 template <typename $5^I>
2244 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
2247 "0: targets = {T}, decl\n"
2248 "1: targets = {foo::Test}, decl\n"
2249 "2: targets = {I}, decl\n"
2250 "3: targets = {foo::Test::Test<T>}, decl\n"
2251 "4: targets = {I}\n"
2252 "5: targets = {I}, decl\n"
2253 "6: targets = {foo::Test}\n"
2254 "7: targets = {I}\n"
2255 "8: targets = {foo::Test}\n"
2256 "9: targets = {I}\n"
2257 "10: targets = {}, qualifier = 'I::'\n"}};
2259 for (
const auto &C : Cases) {
2260 llvm::StringRef ExpectedCode =
C.first;
2261 llvm::StringRef ExpectedRefs =
C.second;
2264 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
2265 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2266 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2270TEST_F(FindExplicitReferencesTest, AllRefs) {
2271 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
2273 @interface $0^MyClass
2275 @implementation $1^$2^MyClass
2278 "0: targets = {MyClass}, decl\n"
2279 "1: targets = {MyClass}\n"
2280 "2: targets = {MyClass}, decl\n"},
2282 @interface $0^MyClass
2284 @interface $1^MyClass ($2^Category)
2286 @implementation $3^MyClass ($4^$5^Category)
2289 "0: targets = {MyClass}, decl\n"
2290 "1: targets = {MyClass}\n"
2291 "2: targets = {Category}, decl\n"
2292 "3: targets = {MyClass}\n"
2293 "4: targets = {Category}\n"
2294 "5: targets = {Category}, decl\n"}};
2296 for (
const auto &C : Cases) {
2297 llvm::StringRef ExpectedCode =
C.first;
2298 llvm::StringRef ExpectedRefs =
C.second;
2300 auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());
2301 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2302 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
#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.
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)