12#include "clang/AST/Decl.h"
13#include "clang/AST/DeclObjC.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/Basic/SourceLocation.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/Testing/Annotations/Annotations.h"
20#include "gmock/gmock.h"
21#include "gtest/gtest.h"
22#include <initializer_list>
36 PrintedDecl(
const char *Name, DeclRelationSet Relations = {})
37 : Name(Name), Relations(Relations) {}
38 PrintedDecl(
const NamedDecl *D, DeclRelationSet Relations = {})
39 : Relations(Relations) {
41 llvm::raw_string_ostream OS(S);
43 llvm::StringRef FirstLine =
44 llvm::StringRef(OS.str()).take_until([](
char C) {
return C ==
'\n'; });
45 FirstLine = FirstLine.rtrim(
" {");
46 Name = std::string(FirstLine.rtrim(
" {"));
50 DeclRelationSet Relations;
52bool operator==(
const PrintedDecl &L,
const PrintedDecl &R) {
53 return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);
55llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS,
const PrintedDecl &D) {
56 return OS <<
D.Name <<
" Rel=" <<
D.Relations;
65class TargetDeclTest :
public ::testing::Test {
69 std::vector<std::string> Flags;
74 std::vector<PrintedDecl> assertNodeAndPrintDecls(
const char *NodeType) {
75 llvm::Annotations
A(Code);
78 auto AST = TU.build();
79 llvm::Annotations::Range R =
A.range();
81 AST.getASTContext(),
AST.getTokens(), R.Begin, R.End);
82 const SelectionTree::Node *N = Selection.commonAncestor();
84 ADD_FAILURE() <<
"No node selected!\n" << Code;
87 EXPECT_EQ(N->kind(), NodeType) << Selection;
89 std::vector<PrintedDecl> ActualDecls;
90 for (
const auto &Entry :
92 ActualDecls.emplace_back(Entry.first, Entry.second);
99#define EXPECT_DECLS(NodeType, ...) \
100 EXPECT_THAT(assertNodeAndPrintDecls(NodeType), \
101 ::testing::UnorderedElementsAreArray( \
102 std::vector<PrintedDecl>({__VA_ARGS__}))) \
104using ExpectedDecls = std::vector<PrintedDecl>;
106TEST_F(TargetDeclTest, Exprs) {
114 struct S { S operator+(S) const; };
115 auto X = S() [[+]] S();
127 void operator()(int n);
134 EXPECT_DECLS("CXXOperatorCallExpr",
"void operator()(int n)");
153TEST_F(TargetDeclTest, RecoveryForC) {
154 Flags = {
"-xc",
"-Xclang",
"-frecovery-ast"};
156 // error-ok: testing behavior on broken code
164TEST_F(TargetDeclTest, Recovery) {
166 // error-ok: testing behavior on broken code
171 EXPECT_DECLS("UnresolvedLookupExpr",
"int f()",
"int f(int, int)");
174TEST_F(TargetDeclTest, RecoveryType) {
176 // error-ok: testing behavior on broken code
177 struct S { int member; };
180 // No overload matches, but we have recovery-expr with the correct type.
181 overloaded().[[member]];
187TEST_F(TargetDeclTest, UsingDecl) {
197 EXPECT_DECLS(
"DeclRefExpr", {
"using foo::f", Rel::Alias}, {
"int f(int)"});
207 EXPECT_DECLS(
"UsingDecl", {
"using foo::f", Rel::Alias}, {
"int f(int)"},
217 int x = Y().[[foo]]();
219 EXPECT_DECLS("MemberExpr", {
"using X::foo", Rel::Alias}, {
"int foo()"});
222 template <typename T>
226 template <typename T>
227 struct Derived : Base<T> {
228 using Base<T>::[[waldo]];
231 EXPECT_DECLS("UnresolvedUsingValueDecl", {
"using Base<T>::waldo", Rel::Alias},
236 template<typename T> class S {};
244 EXPECT_DECLS("TemplateSpecializationTypeLoc", {
"using ns::S", Rel::Alias},
245 {
"template <typename T> class S"},
246 {
"class S", Rel::TemplatePattern});
250 template<typename T> class S {};
254 template <template <typename> class T> class X {};
257 EXPECT_DECLS("TemplateArgumentLoc", {
"using ns::S", Rel::Alias},
258 {
"template <typename T> class S"});
262 template<typename T> class S { public: S(T); };
268 Flags.push_back("-std=c++17");
270 {
"using ns::S", Rel::Alias}, {
"template <typename T> class S"},
271 {
"class S", Rel::TemplatePattern});
275 class Foo { public: class foo {}; };
276 template <class T> class A : public Foo<T> {
277 using typename Foo<T>::foo;
282 {
"using typename Foo<T>::foo", Rel::Alias});
285 Flags.push_back(
"-std=c++20");
287 namespace ns { enum class A { X }; }
288 [[using enum ns::A]];
293 namespace ns { enum class A { X }; }
300TEST_F(TargetDeclTest, BaseSpecifier) {
303 struct Y : [[private]] X {};
308 struct Y : [[private X]] {};
313 struct Y : private [[X]] {};
318TEST_F(TargetDeclTest, ConstructorInitList) {
336TEST_F(TargetDeclTest, DesignatedInit) {
340 struct Y { int b; struct X c[2]; };
341 struct Y y = { .c[0].[[a]] = 1 };
346TEST_F(TargetDeclTest, OffsetOf) {
348 struct Foo { int bar; };
349 int x = __builtin_offsetof(Foo, [[bar]]);
354 struct Inner { int c; };
355 struct Outer { Inner b; };
356 int x = __builtin_offsetof(Outer, [[b]].c);
361 struct Inner { int c; };
362 struct Outer { Inner b; };
363 int x = __builtin_offsetof(Outer, b.[[c]]);
370 struct Inner { int c; };
371 struct Outer { Inner b; };
372 int x = __builtin_offsetof(Outer, [[b.c]]);
374 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
377 struct Inner { int c; };
378 struct Outer { Inner b; };
379 int x = __builtin_offsetof(Outer, [[b.]]c);
381 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
384 struct Inner { int c; };
385 struct Outer { Inner b; };
386 int x = __builtin_offsetof(Outer, b[[.c]]);
391 struct Foo { int bar; };
392 int x = __builtin_[[offsetof]](Foo, bar);
394 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfExpr"), ::testing::IsEmpty());
401 int o = __builtin_offsetof(D, [[x]]);
408 template <typename T> int f() { return __builtin_offsetof(T, [[x]]); }
410 EXPECT_THAT(assertNodeAndPrintDecls("OffsetOfNode"), ::testing::IsEmpty());
414 #define offsetof(t, m) __builtin_offsetof(t, m)
415 struct Foo { int bar; };
416 int x = offsetof(Foo, [[bar]]);
423 struct Foo { int bar[4]; };
425 int x = __builtin_offsetof(Foo, bar[ [[i]] ]);
430TEST_F(TargetDeclTest, NestedNameSpecifier) {
432 namespace a { namespace b { int c; } }
438 namespace a { struct X { enum { y }; }; }
444 template <typename T>
450 namespace a { int x; }
454 EXPECT_DECLS("NestedNameSpecifierLoc", {
"namespace b = a", Rel::Alias},
455 {
"namespace a", Rel::Underlying});
458TEST_F(TargetDeclTest, Types) {
470 EXPECT_DECLS("TypedefTypeLoc", {
"typedef S X", Rel::Alias},
471 {
"struct S", Rel::Underlying});
473 namespace ns { struct S{}; }
477 EXPECT_DECLS("TypedefTypeLoc", {
"typedef ns::S X", Rel::Alias},
478 {
"struct S", Rel::Underlying});
482 void foo() { [[T]] x; }
488 template<template<typename> class T>
489 void foo() { [[T<int>]] x; }
491 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> class T");
495 template<template<typename> class ...T>
500 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename> class ...T"});
508 EXPECT_DECLS("DecltypeTypeLoc", {
"struct S", Rel::Underlying});
518 template <typename... E>
520 static const int size = sizeof...([[E]]);
526 template <typename T>
534TEST_F(TargetDeclTest, ClassTemplate) {
536 // Implicit specialization.
537 template<int x> class Foo{};
541 {
"template<> class Foo<42>", Rel::TemplateInstantiation},
542 {
"class Foo", Rel::TemplatePattern});
545 template<typename T> class Foo {};
546 // The "Foo<int>" SpecializationDecl is incomplete, there is no
547 // instantiation happening.
548 void func([[Foo<int>]] *);
551 {
"class Foo", Rel::TemplatePattern},
552 {
"template<> class Foo<int>", Rel::TemplateInstantiation});
555 // Explicit specialization.
556 template<int x> class Foo{};
557 template<> class Foo<42>{};
560 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template<> class Foo<42>");
563 // Partial specialization.
564 template<typename T> class Foo{};
565 template<typename T> class Foo<T*>{};
569 {
"template<> class Foo<int *>", Rel::TemplateInstantiation},
570 {
"template <typename T> class Foo<T *>", Rel::TemplatePattern});
573 // Template template argument.
574 template<typename T> struct Vector {};
575 template <template <typename> class Container>
579 EXPECT_DECLS("TemplateArgumentLoc", {
"template <typename T> struct Vector"});
581 Flags.push_back(
"-std=c++17");
584 // Class template argument deduction
585 template <typename T>
594 {
"struct Test", Rel::TemplatePattern});
597 // Deduced specialization of a template template parameter
598 template <template<typename> class X>
604 "template <typename> class X");
608 template <typename T>
610 template <typename I>
613 template <typename I>
614 [[Test]](I, I) -> Test<typename I::type>;
616 EXPECT_DECLS("CXXDeductionGuideDecl", {
"template <typename T> struct Test"});
620 Flags.push_back(
"-std=c++20");
626 template <typename T>
627 concept Fooable = requires (T t) { t.foo(); };
629 template <typename T> requires [[Fooable]]<T>
636 {
"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});
640 template <typename T>
641 concept Fooable = true;
643 template <typename T>
644 void foo() requires [[Fooable]]<T>;
647 {
"template <typename T> concept Fooable = true"});
651 template <typename T>
652 concept Fooable = true;
654 template <[[Fooable]] T>
658 {
"template <typename T> concept Fooable = true"});
662 template <typename T, typename U>
663 concept Fooable = true;
665 template <[[Fooable]]<int> T>
669 {
"template <typename T, typename U> concept Fooable = true"});
672TEST_F(TargetDeclTest, PackIndexing) {
673 Flags.push_back(
"-std=c++2d");
676 // Deduced specialization of an indexed template template parameter pack
677 template <template <typename> class... X>
683 "template <typename> class ...X");
686 // Specialization of an indexed template template parameter pack
687 template <template <typename> class... X>
693 "template <typename> class ...X");
696 // Indexed type template parameter pack
697 template <typename... X>
702 EXPECT_DECLS("TemplateTypeParmTypeLoc",
"typename ...X");
705TEST_F(TargetDeclTest, PackIndexedConcept) {
706 Flags.push_back(
"-std=c++2d");
710 template <template <class> concept... CC>
712 template <[[CC]]...[0] T>
716 EXPECT_DECLS("ConceptReference", {
"template <class> concept ...CC"});
720 template <template <class> concept... CC>
721 void bar([[CC]]...[0] auto t);
723 EXPECT_DECLS("ConceptReference", {
"template <class> concept ...CC"});
726TEST_F(TargetDeclTest, Coroutine) {
727 Flags.push_back(
"-std=c++20");
731 template <typename, typename...> struct coroutine_traits;
732 template <typename> struct coroutine_handle {
733 template <typename U>
734 coroutine_handle(coroutine_handle<U>&&) noexcept;
735 static coroutine_handle from_address(void* __addr) noexcept;
741 struct awaitable_frame {
742 awaitable get_return_object();
744 void unhandled_exception();
747 bool await_ready() const noexcept;
748 void await_suspend(std::coroutine_handle<void>) noexcept;
749 void await_resume() const noexcept;
751 result_t initial_suspend() noexcept;
752 result_t final_suspend() noexcept;
753 result_t await_transform(executor) noexcept;
758 struct coroutine_traits<awaitable> {
759 typedef awaitable_frame promise_type;
764 co_await [[executor]]();
770TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
771 Flags.push_back(
"-std=c++20");
775 struct strong_ordering {
777 constexpr operator int() const { return n; }
778 static const strong_ordering equal, greater, less;
780 constexpr strong_ordering strong_ordering::equal = {0};
781 constexpr strong_ordering strong_ordering::greater = {1};
782 constexpr strong_ordering strong_ordering::less = {-1};
788 auto operator<=>(const Foo&) const = default;
791 bool x = (Foo(1) [[!=]] Foo(2));
794 {
"std::strong_ordering operator<=>(const Foo &) const = default",
795 Rel::TemplatePattern},
796 {
"bool operator==(const Foo &) const noexcept = default",
797 Rel::TemplateInstantiation});
800TEST_F(TargetDeclTest, FunctionTemplate) {
802 // Implicit specialization.
803 template<typename T> bool foo(T) { return false; };
804 bool x = [[foo]](42);
807 {
"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
808 {
"bool foo(T)", Rel::TemplatePattern});
811 // Explicit specialization.
812 template<typename T> bool foo(T) { return false; };
813 template<> bool foo<int>(int) { return false; };
814 bool x = [[foo]](42);
816 EXPECT_DECLS("DeclRefExpr",
"template<> bool foo<int>(int)");
819TEST_F(TargetDeclTest, VariableTemplate) {
822 // Implicit specialization.
823 template<typename T> int foo;
824 int x = [[foo]]<char>;
826 EXPECT_DECLS("DeclRefExpr", {
"int foo", Rel::TemplateInstantiation},
827 {
"int foo", Rel::TemplatePattern});
830 // Explicit specialization.
831 template<typename T> int foo;
832 template <> bool foo<char>;
833 int x = [[foo]]<char>;
838 // Partial specialization.
839 template<typename T> int foo;
840 template<typename T> bool foo<T*>;
841 bool x = [[foo]]<char*>;
843 EXPECT_DECLS("DeclRefExpr", {
"bool foo", Rel::TemplateInstantiation},
844 {
"bool foo", Rel::TemplatePattern});
847TEST_F(TargetDeclTest, TypeAliasTemplate) {
849 template<typename T, int X> class SmallVector {};
850 template<typename U> using TinyVector = SmallVector<U, 1>;
851 [[TinyVector<int>]] X;
854 {
"template<> class SmallVector<int, 1>",
855 Rel::TemplateInstantiation | Rel::Underlying},
856 {
"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
857 {
"using TinyVector = SmallVector<U, 1>",
858 Rel::Alias | Rel::TemplatePattern});
861TEST_F(TargetDeclTest, BuiltinTemplates) {
863 template <class T, T... Index> struct integer_sequence {};
864 [[__make_integer_seq]]<integer_sequence, int, 3> X;
867 "TemplateSpecializationTypeLoc",
868 {
"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
869 {
"template<> struct integer_sequence<int, <0, 1, 2>>",
870 Rel::TemplateInstantiation | Rel::Underlying});
874 template <class T, T... Index> struct integer_sequence;
876 template <class T, int N>
877 using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
882 template <int N, class... Pack>
883 using type_pack_element = [[__type_pack_element]]<N, Pack...>;
888 template <template <class...> class Templ, class... Types>
889 using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;
894 template <template <class...> class Templ, class... Types>
895 using sort_types = Templ<[[__builtin_sort_pack]]<Types...>...>;
900TEST_F(TargetDeclTest, MemberOfTemplate) {
902 template <typename T> struct Foo {
905 int y = Foo<int>().[[x]](42);
907 EXPECT_DECLS("MemberExpr", {
"int x(int)", Rel::TemplateInstantiation},
908 {
"int x(T)", Rel::TemplatePattern});
911 template <typename T> struct Foo {
912 template <typename U>
915 int y = Foo<char>().[[x]]('c', 42);
918 {
"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
919 {
"int x(T, U)", Rel::TemplatePattern});
922TEST_F(TargetDeclTest, Lambda) {
924 void foo(int x = 42) {
925 auto l = [ [[x]] ]{ return x + 1; };
933 void foo(int x = 42) {
934 auto l = [x]{ return [[x]] + 1; };
941 auto l = [x = 1]{ return [[x]] + 1; };
948TEST_F(TargetDeclTest, OverloadExpr) {
949 Flags.push_back(
"--target=x86_64-pc-linux-gnu");
960 EXPECT_DECLS("UnresolvedLookupExpr",
"void func(int *)",
"void func(char *)");
973 EXPECT_DECLS("UnresolvedMemberExpr",
"void func(int *)",
"void func(char *)");
977 static void *operator new(unsigned long);
979 auto* k = [[new]] X();
981 EXPECT_DECLS("CXXNewExpr",
"static void *operator new(unsigned long)");
983 void *operator new(unsigned long);
984 auto* k = [[new]] int();
986 EXPECT_DECLS("CXXNewExpr",
"void *operator new(unsigned long)");
990 static void operator delete(void *) noexcept;
996 EXPECT_DECLS("CXXDeleteExpr",
"static void operator delete(void *) noexcept");
998 void operator delete(void *) noexcept;
1005 "void operator delete(void *, __size_t) noexcept");
1008TEST_F(TargetDeclTest, DependentExprs) {
1009 Flags.push_back(
"--std=c++20");
1013 struct A { void foo() {} };
1014 template <typename T>
1032 template <typename T>
1036 this->c.getA().[[foo]]();
1048 using FPtr = A(*)();
1051 template <typename T>
1055 this->c.fptr().[[foo]]();
1066 template <typename T> struct Foo {
1073 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"int aaaa");
1079 template <typename T> T convert() const;
1081 template <typename T>
1083 Foo::k(T()).template [[convert]]<T>();
1087 "template <typename T> T convert() const");
1090 template <typename T>
1094 template <typename T>
1095 using Wally = Waldo<T>;
1096 template <typename T>
1097 void foo(Wally<T> w) {
1101 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
1104 template <typename T>
1108 template <typename T>
1110 using Type = Waldo<T>;
1112 template <typename T>
1113 void foo(typename MetaWaldo<T>::Type w) {
1117 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"void find()");
1123 template <typename T>
1124 using Wally = Waldo;
1126 struct S : Wally<int> {
1127 void Foo() { this->[[find]](); }
1137 const int found = N;
1145 EXPECT_DECLS("CXXDependentScopeMemberExpr",
"const int found = N");
1148TEST_F(TargetDeclTest, DependentTypes) {
1152 struct A { struct B {}; };
1154 template <typename T>
1155 void foo(typename A<T>::[[B]]);
1162 struct A { struct B { struct C {}; }; };
1164 template <typename T>
1165 void foo(typename A<T>::[[B]]::C);
1173 struct A { struct B { struct C {}; }; };
1175 template <typename T>
1176 void foo(typename A<T>::B::[[C]]);
1184 template <typename> struct B {};
1187 template <typename T>
1188 void foo(typename A<T>::template [[B]]<int>);
1190 EXPECT_DECLS("TemplateSpecializationTypeLoc",
"template <typename> struct B");
1197 typedef typename waldo<N - 1>::type::[[next]] type;
1209 using type = typename odd<N - 1>::type::next;
1214 using type = typename even<N - 1>::type::[[next]];
1220TEST_F(TargetDeclTest, TypedefCascade) {
1226 using type = C::type;
1229 using type = B::type;
1234 {
"using type = int", Rel::Alias | Rel::Underlying},
1235 {
"using type = C::type", Rel::Alias | Rel::Underlying},
1236 {
"using type = B::type", Rel::Alias});
1239TEST_F(TargetDeclTest, RecursiveTemplate) {
1240 Flags.push_back(
"-std=c++20");
1243 template <typename T>
1244 concept Leaf = false;
1246 template <typename Tree>
1247 struct descend_left {
1248 using type = typename descend_left<typename Tree::left>::[[type]];
1251 template <Leaf Tree>
1252 struct descend_left<Tree> {
1253 using type = typename Tree::value;
1257 {
"using type = typename descend_left<typename Tree::left>::type",
1258 Rel::Alias | Rel::Underlying});
1261TEST_F(TargetDeclTest, ObjC) {
1262 Flags = {
"-xobjective-c"};
1274 @interface Foo { @public int bar; }
1285 -(void) setX:(int)x;
1291 EXPECT_DECLS("ObjCPropertyRefExpr",
"- (void)setX:(int)x");
1295 @property(retain) I* x;
1296 @property(retain) I* y;
1303 "@property(atomic, retain, readwrite) I *x");
1308 @interface Interface
1309 @property(retain) [[MYObject]] *x;
1312 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject");
1315 @interface MYObject2
1317 @interface Interface
1318 @property(retain, nonnull) [[MYObject2]] *x;
1321 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface MYObject2");
1327 return [[@protocol(Foo)]];
1335 void test([[Foo]] *p);
1337 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1339 Code = R
"cpp(// Don't consider implicit interface as the target.
1340 @implementation [[Implicit]]
1343 EXPECT_DECLS("ObjCImplementationDecl",
"@implementation Implicit");
1348 @implementation [[Foo]]
1351 EXPECT_DECLS("ObjCImplementationDecl",
"@interface Foo");
1356 @interface Foo (Ext)
1358 @implementation [[Foo]] (Ext)
1361 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1366 @interface Foo (Ext)
1368 @implementation Foo ([[Ext]])
1371 EXPECT_DECLS("ObjCCategoryImplDecl",
"@interface Foo(Ext)");
1374 void test(id</*error-ok*/[[InvalidProtocol]]> p);
1382 void test([[C]]<Foo> *p);
1390 void test(C<[[Foo]]> *p);
1400 void test(C<[[Foo]], Bar> *p);
1410 void test(C<Foo, [[Bar]]> *p);
1416 + (id)sharedInstance;
1419 + (id)sharedInstance { return 0; }
1422 id value = [[Foo]].sharedInstance;
1425 EXPECT_DECLS("ObjCInterfaceTypeLoc",
"@interface Foo");
1429 + (id)sharedInstance;
1432 + (id)sharedInstance { return 0; }
1435 id value = Foo.[[sharedInstance]];
1438 EXPECT_DECLS("ObjCPropertyRefExpr",
"+ (id)sharedInstance");
1442 + ([[id]])sharedInstance;
1449 + ([[instancetype]])sharedInstance;
1455class FindExplicitReferencesTest :
public ::testing::Test {
1458 std::string AnnotatedCode;
1459 std::string DumpedReferences;
1462 TestTU newTU(llvm::StringRef Code) {
1464 TU.Code = std::string(Code);
1468 TU.ExtraArgs.push_back(
"-std=c++20");
1469 TU.ExtraArgs.push_back(
"-xobjective-c++");
1474 AllRefs annotatedReferences(llvm::StringRef Code, ParsedAST &
AST,
1475 std::vector<ReferenceLoc> Refs) {
1476 auto &SM =
AST.getSourceManager();
1477 llvm::stable_sort(Refs, [&](
const ReferenceLoc &L,
const ReferenceLoc &R) {
1478 return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
1481 std::string AnnotatedCode;
1482 unsigned NextCodeChar = 0;
1483 for (
unsigned I = 0; I < Refs.size(); ++I) {
1486 SourceLocation Pos = R.NameLoc;
1487 assert(Pos.isValid());
1488 if (Pos.isMacroID())
1489 Pos = SM.getExpansionLoc(Pos);
1490 assert(Pos.isFileID());
1494 std::tie(
File, Offset) = SM.getDecomposedLoc(Pos);
1495 if (
File == SM.getMainFileID()) {
1497 assert(NextCodeChar <= Offset);
1498 AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
1499 AnnotatedCode +=
"$" + std::to_string(I) +
"^";
1501 NextCodeChar = Offset;
1504 AnnotatedCode += Code.substr(NextCodeChar);
1506 std::string DumpedReferences;
1507 for (
unsigned I = 0; I < Refs.size(); ++I)
1508 DumpedReferences += std::string(llvm::formatv(
"{0}: {1}\n", I, Refs[I]));
1510 return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
1516 AllRefs annotateAllReferences(llvm::StringRef Code) {
1517 TestTU TU = newTU(Code);
1518 auto AST = TU.build();
1520 std::vector<ReferenceLoc> Refs;
1521 for (
auto *TopLevel :
AST.getLocalTopLevelDecls())
1523 TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1524 AST.getHeuristicResolver());
1525 return annotatedReferences(Code,
AST, std::move(Refs));
1531 AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
1532 TestTU TU = newTU(Code);
1533 auto AST = TU.build();
1535 if (
auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
1536 TestDecl =
T->getTemplatedDecl();
1538 std::vector<ReferenceLoc> Refs;
1539 if (
const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
1542 [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1543 AST.getHeuristicResolver());
1544 else if (
const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
1547 [&Refs, &NS](ReferenceLoc R) {
1549 if (R.Targets.size() == 1 && R.Targets.front() == NS)
1551 Refs.push_back(std::move(R));
1553 AST.getHeuristicResolver());
1554 else if (
const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))
1556 OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },
1557 AST.getHeuristicResolver());
1559 ADD_FAILURE() <<
"Failed to find ::foo decl for test";
1561 return annotatedReferences(Code,
AST, std::move(Refs));
1565TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
1566 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
1571 void foo(int param) {
1572 $0^global = $1^param + $2^func();
1575 "0: targets = {global}\n"
1576 "1: targets = {param}\n"
1577 "2: targets = {func}\n"},
1579 struct X { int a; };
1584 "0: targets = {x}\n"
1585 "1: targets = {X::a}\n"},
1587 // error-ok: testing with broken code
1590 return $0^bar() + $1^bar(42);
1593 "0: targets = {bar}\n"
1594 "1: targets = {bar}\n"},
1598 namespace alias = ns;
1600 using namespace $0^ns;
1601 using namespace $1^alias;
1604 "0: targets = {ns}\n"
1605 "1: targets = {alias}\n"},
1608 namespace ns { int global; }
1610 using $0^ns::$1^global;
1613 "0: targets = {ns}\n"
1614 "1: targets = {ns::global}, qualifier = 'ns::'\n"},
1617 namespace ns { enum class A {}; }
1619 using enum $0^ns::$1^A;
1622 "0: targets = {ns}\n"
1623 "1: targets = {ns::A}, qualifier = 'ns::'\n"},
1626 struct Struct { int a; };
1627 using Typedef = int;
1631 static_cast<$4^Struct*>(0);
1634 "0: targets = {Struct}\n"
1635 "1: targets = {x}, decl\n"
1636 "2: targets = {Typedef}\n"
1637 "3: targets = {y}, decl\n"
1638 "4: targets = {Struct}\n"},
1641 namespace a { namespace b { struct S { typedef int type; }; } }
1643 $0^a::$1^b::$2^S $3^x;
1644 using namespace $4^a::$5^b;
1648 "0: targets = {a}\n"
1649 "1: targets = {a::b}, qualifier = 'a::'\n"
1650 "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
1651 "3: targets = {x}, decl\n"
1652 "4: targets = {a}\n"
1653 "5: targets = {a::b}, qualifier = 'a::'\n"
1654 "6: targets = {a::b::S}\n"
1655 "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
1656 "8: targets = {y}, decl\n"},
1659 $0^ten: // PRINT "HELLO WORLD!"
1663 "0: targets = {ten}, decl\n"
1664 "1: targets = {ten}\n"},
1667 template <class T> struct vector { using value_type = T; };
1668 template <> struct vector<bool> { using value_type = bool; };
1670 $0^vector<int> $1^vi;
1671 $2^vector<bool> $3^vb;
1674 "0: targets = {vector<int>}\n"
1675 "1: targets = {vi}, decl\n"
1676 "2: targets = {vector<bool>}\n"
1677 "3: targets = {vb}, decl\n"},
1680 template <class T> struct vector { using value_type = T; };
1681 template <> struct vector<bool> { using value_type = bool; };
1682 template <class T> using valias = vector<T>;
1684 $0^valias<int> $1^vi;
1685 $2^valias<bool> $3^vb;
1688 "0: targets = {valias}\n"
1689 "1: targets = {vi}, decl\n"
1690 "2: targets = {valias}\n"
1691 "3: targets = {vb}, decl\n"},
1695 template <typename $0^T>
1702 "0: targets = {foo::Bar::T}, decl\n"
1703 "1: targets = {foo::Bar}, decl\n"
1704 "2: targets = {foo::Bar}\n"
1705 "3: targets = {foo::Bar::f}, decl\n"
1706 "4: targets = {foo::Bar}\n"},
1709 struct X { void func(int); };
1717 "0: targets = {y}\n"
1718 "1: targets = {Y::func}\n"},
1721 namespace ns { void bar(int); }
1728 "0: targets = {bar}\n"},
1734 void foo(int a, int b) {
1738 "0: targets = {a}\n"
1739 "1: targets = {b}\n"},
1748 for (int $0^x : $1^vector()) {
1753 "0: targets = {x}, decl\n"
1754 "1: targets = {vector}\n"
1755 "2: targets = {x}\n"},
1758 namespace ns1 { void func(char*); }
1759 namespace ns2 { void func(int*); }
1760 using namespace ns1;
1761 using namespace ns2;
1768 "0: targets = {ns1::func, ns2::func}\n"
1769 "1: targets = {t}\n"},
1778 void foo(X x, T t) {
1782 "0: targets = {x}\n"
1783 "1: targets = {X::func, X::func}\n"
1784 "2: targets = {t}\n"},
1794 $0^S<$1^T>::$2^value;
1797 "0: targets = {S}\n"
1798 "1: targets = {T}\n"
1799 "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
1812 "0: targets = {t}\n"
1813 "1: targets = {S::value}\n"},
1818 static_cast<$0^T>(0);
1823 "0: targets = {T}\n"
1824 "1: targets = {T}\n"
1825 "2: targets = {T}\n"
1826 "3: targets = {t}, decl\n"},
1834 "0: targets = {x}, decl\n"
1835 "1: targets = {I}\n"},
1838 template <class T> struct vector {};
1840 template <template<class> class TT, template<class> class ...TP>
1844 $4^foo<$5^vector>();
1848 "0: targets = {TT}\n"
1849 "1: targets = {x}, decl\n"
1850 "2: targets = {foo}\n"
1851 "3: targets = {TT}\n"
1852 "4: targets = {foo}\n"
1853 "5: targets = {vector}\n"
1854 "6: targets = {foo}\n"
1855 "7: targets = {TP}\n"},
1859 template <int(*)()> struct wrapper {};
1861 template <int(*FuncParam)()>
1863 $0^wrapper<$1^func> $2^w;
1867 "0: targets = {wrapper<&func>}\n"
1868 "1: targets = {func}\n"
1869 "2: targets = {w}, decl\n"
1870 "3: targets = {FuncParam}\n"},
1876 class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1878 enum $5^E { $6^ABC };
1880 using $8^INT2 = int;
1881 namespace $9^NS = $10^ns;
1884 "0: targets = {Foo}, decl\n"
1885 "1: targets = {foo()::Foo::Foo}, decl\n"
1886 "2: targets = {Foo}\n"
1887 "3: targets = {foo()::Foo::field}, decl\n"
1888 "4: targets = {Var}, decl\n"
1889 "5: targets = {E}, decl\n"
1890 "6: targets = {foo()::ABC}, decl\n"
1891 "7: targets = {INT}, decl\n"
1892 "8: targets = {INT2}, decl\n"
1893 "9: targets = {NS}, decl\n"
1894 "10: targets = {ns}\n"},
1901 // FIXME: This should have only one reference to Bar.
1902 $2^operator $3^$4^Bar();
1906 $7^f.$8^operator $9^Bar();
1909 "0: targets = {Bar}, decl\n"
1910 "1: targets = {Foo}, decl\n"
1911 "2: targets = {foo()::Foo::operator Bar}, decl\n"
1912 "3: targets = {Bar}\n"
1913 "4: targets = {Bar}\n"
1914 "5: targets = {Foo}\n"
1915 "6: targets = {f}, decl\n"
1916 "7: targets = {f}\n"
1917 "8: targets = {foo()::Foo::operator Bar}\n"
1918 "9: targets = {Bar}\n"},
1926 void $2^destructMe() {
1932 $6^f.~ /*...*/ $7^Foo();
1935 "0: targets = {Foo}, decl\n"
1938 "1: targets = {Foo}\n"
1939 "2: targets = {foo()::Foo::destructMe}, decl\n"
1940 "3: targets = {Foo}\n"
1941 "4: targets = {Foo}\n"
1942 "5: targets = {f}, decl\n"
1943 "6: targets = {f}\n"
1944 "7: targets = {Foo}\n"},
1949 // member initializer
1955 class $4^Derived : public $5^Base {
1957 $8^Derived() : $9^Base() {}
1959 // delegating initializer
1962 $12^Foo(): $13^Foo(111) {}
1966 "0: targets = {X}, decl\n"
1967 "1: targets = {foo()::X::abc}, decl\n"
1968 "2: targets = {foo()::X::X}, decl\n"
1969 "3: targets = {foo()::X::abc}\n"
1970 "4: targets = {Derived}, decl\n"
1971 "5: targets = {Base}\n"
1972 "6: targets = {Base}\n"
1973 "7: targets = {foo()::Derived::B}, decl\n"
1974 "8: targets = {foo()::Derived::Derived}, decl\n"
1975 "9: targets = {Base}\n"
1976 "10: targets = {Foo}, decl\n"
1977 "11: targets = {foo()::Foo::Foo}, decl\n"
1978 "12: targets = {foo()::Foo::Foo}, decl\n"
1979 "13: targets = {Foo}\n"},
1985 int (*$2^fptr)(int $3^a, int) = nullptr;
1988 "0: targets = {(unnamed class)}\n"
1989 "1: targets = {x}, decl\n"
1990 "2: targets = {fptr}, decl\n"
1991 "3: targets = {a}, decl\n"},
1995 namespace ns { struct Type {}; }
1996 namespace alias = ns;
1997 namespace rec_alias = alias;
2000 $0^ns::$1^Type $2^a;
2001 $3^alias::$4^Type $5^b;
2002 $6^rec_alias::$7^Type $8^c;
2005 "0: targets = {ns}\n"
2006 "1: targets = {ns::Type}, qualifier = 'ns::'\n"
2007 "2: targets = {a}, decl\n"
2008 "3: targets = {alias}\n"
2009 "4: targets = {ns::Type}, qualifier = 'alias::'\n"
2010 "5: targets = {b}, decl\n"
2011 "6: targets = {rec_alias}\n"
2012 "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
2013 "8: targets = {c}, decl\n"},
2017 template <typename... E>
2019 constexpr int $0^size = sizeof...($1^E);
2022 "0: targets = {size}, decl\n"
2023 "1: targets = {E}\n"},
2027 template <typename T>
2035 "0: targets = {Test}\n"
2036 "1: targets = {a}, decl\n"},
2040 template <typename $0^T>
2044 "0: targets = {foo::Bar::T}, decl\n"
2045 "1: targets = {foo::Bar}, decl\n"},
2049 template <typename $0^T>
2053 "0: targets = {T}, decl\n"
2054 "1: targets = {foo::func}, decl\n"},
2058 template <typename $0^T>
2062 "0: targets = {foo::T}, decl\n"
2063 "1: targets = {foo::T}\n"
2064 "2: targets = {foo::x}, decl\n"},
2067 template<typename T> class vector {};
2069 template <typename $0^T>
2070 using $1^V = $2^vector<$3^T>;
2073 "0: targets = {foo::T}, decl\n"
2074 "1: targets = {foo::V}, decl\n"
2075 "2: targets = {vector}\n"
2076 "3: targets = {foo::T}\n"},
2080 template <typename T>
2081 concept Drawable = requires (T t) { t.draw(); };
2084 template <typename $0^T> requires $1^Drawable<$2^T>
2085 void $3^bar($4^T $5^t) {
2090 "0: targets = {T}, decl\n"
2091 "1: targets = {Drawable}\n"
2092 "2: targets = {T}\n"
2093 "3: targets = {foo::bar}, decl\n"
2094 "4: targets = {T}\n"
2095 "5: targets = {t}, decl\n"
2096 "6: targets = {t}\n"
2097 "7: targets = {}\n"},
2111 "0: targets = {f}\n"
2112 "1: targets = {I::_z}\n"},
2117 @property(retain) I* x;
2118 @property(retain) I* y;
2125 "0: targets = {f}\n"
2126 "1: targets = {I::x}\n"
2127 "2: targets = {I::y}\n"},
2140 "0: targets = {f}\n"
2141 "1: targets = {I::x}\n"
2142 "2: targets = {I::setY:}\n"},
2147 @property(class) I *x;
2152 $2^local = $3^I.$4^x;
2155 "0: targets = {I}\n"
2156 "1: targets = {I::setX:}\n"
2157 "2: targets = {local}\n"
2158 "3: targets = {I}\n"
2159 "4: targets = {I::x}\n"},
2170 $2^local = $3^I.$4^x;
2173 "0: targets = {I}\n"
2174 "1: targets = {I::setX:}\n"
2175 "2: targets = {local}\n"
2176 "3: targets = {I}\n"
2177 "4: targets = {I::x}\n"},
2181 -(void) a:(int)x b:(int)y;
2187 "0: targets = {i}\n"
2188 "1: targets = {I::a:b:}\n"},
2199 "0: targets = {I}\n"
2200 "1: targets = {P}\n"
2201 "2: targets = {x}, decl\n"},
2209 $2^Foo $3^f { .$4^Bar = 42 };
2212 "0: targets = {Foo}, decl\n"
2213 "1: targets = {foo()::Foo::Bar}, decl\n"
2214 "2: targets = {Foo}\n"
2215 "3: targets = {f}, decl\n"
2216 "4: targets = {foo()::Foo::Bar}\n"},
2225 $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
2228 "0: targets = {Baz}, decl\n"
2229 "1: targets = {foo()::Baz::Field}, decl\n"
2230 "2: targets = {Bar}, decl\n"
2231 "3: targets = {Baz}\n"
2232 "4: targets = {foo()::Bar::Foo}, decl\n"
2233 "5: targets = {Bar}\n"
2234 "6: targets = {bar}, decl\n"
2235 "7: targets = {foo()::Bar::Foo}\n"
2236 "8: targets = {foo()::Baz::Field}\n"},
2240 struct $0^Foo { int $1^bar; };
2241 int $2^x = __builtin_offsetof($3^Foo, $4^bar);
2244 "0: targets = {Foo}, decl\n"
2245 "1: targets = {foo()::Foo::bar}, decl\n"
2246 "2: targets = {x}, decl\n"
2247 "3: targets = {Foo}\n"
2248 "4: targets = {foo()::Foo::bar}\n"},
2254 $1^struct { int $2^c; } $3^B;
2256 int $4^x = __builtin_offsetof($5^A, $6^B.$7^c);
2259 "0: targets = {A}, decl\n"
2260 "1: targets = {foo()::A::(unnamed struct)}\n"
2261 "2: targets = {foo()::A::(unnamed struct)::c}, decl\n"
2262 "3: targets = {foo()::A::B}, decl\n"
2263 "4: targets = {x}, decl\n"
2264 "5: targets = {A}\n"
2265 "6: targets = {foo()::A::B}\n"
2266 "7: targets = {foo()::A::(unnamed struct)::c}\n"},
2272 struct $0^A { int $1^arr[4]; };
2274 int $3^x = __builtin_offsetof($4^A, $5^arr[$6^i]);
2277 "0: targets = {A}, decl\n"
2278 "1: targets = {foo()::A::arr}, decl\n"
2279 "2: targets = {i}, decl\n"
2280 "3: targets = {x}, decl\n"
2281 "4: targets = {A}\n"
2282 "5: targets = {foo()::A::arr}\n"
2283 "6: targets = {i}\n"},
2285 template<typename T>
2287 template<typename T>
2289 $0^crash({.$1^x = $2^T()});
2292 "0: targets = {crash}\n"
2294 "2: targets = {T}\n"},
2297 template <template <typename> typename T>
2300 template <typename $0^T>
2301 struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
2304 "0: targets = {foo::Derive::T}, decl\n"
2305 "1: targets = {foo::Derive}, decl\n"
2306 "2: targets = {Base}\n"
2307 "3: targets = {foo::Derive::T}\n"
2308 "4: targets = {}, qualifier = 'T::'\n"},
2312 template <typename $0^T>
2314 template <typename $2^I>
2317 template <typename $5^I>
2318 $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
2321 "0: targets = {T}, decl\n"
2322 "1: targets = {foo::Test}, decl\n"
2323 "2: targets = {I}, decl\n"
2324 "3: targets = {foo::Test::Test<T>}, decl\n"
2325 "4: targets = {I}\n"
2326 "5: targets = {I}, decl\n"
2327 "6: targets = {foo::Test}\n"
2328 "7: targets = {I}\n"
2329 "8: targets = {foo::Test}\n"
2330 "9: targets = {I}\n"
2331 "10: targets = {}, qualifier = 'I::'\n"}};
2333 for (
const auto &C : Cases) {
2334 llvm::StringRef ExpectedCode =
C.first;
2335 llvm::StringRef ExpectedRefs =
C.second;
2338 annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
2339 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2340 EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
2344TEST_F(FindExplicitReferencesTest, AllRefs) {
2345 std::pair< llvm::StringRef, llvm::StringRef> Cases[] =
2347 @interface $0^MyClass
2349 @implementation $1^$2^MyClass
2352 "0: targets = {MyClass}, decl\n"
2353 "1: targets = {MyClass}\n"
2354 "2: targets = {MyClass}, decl\n"},
2356 @interface $0^MyClass
2358 @interface $1^MyClass ($2^Category)
2360 @implementation $3^MyClass ($4^$5^Category)
2363 "0: targets = {MyClass}, decl\n"
2364 "1: targets = {MyClass}\n"
2365 "2: targets = {Category}, decl\n"
2366 "3: targets = {MyClass}\n"
2367 "4: targets = {Category}\n"
2368 "5: targets = {Category}, decl\n"}};
2370 for (
const auto &C : Cases) {
2371 llvm::StringRef ExpectedCode =
C.first;
2372 llvm::StringRef ExpectedRefs =
C.second;
2374 auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());
2375 EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
2376 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)