brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.7 KiB · dd26182 Raw
2178 lines · cpp
1//===-- FindTargetTests.cpp --------------------------*- C++ -*------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8#include "FindTarget.h"9 10#include "Selection.h"11#include "TestTU.h"12#include "clang/AST/Decl.h"13#include "clang/AST/DeclTemplate.h"14#include "clang/Basic/SourceLocation.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/Support/Casting.h"17#include "llvm/Support/raw_ostream.h"18#include "llvm/Testing/Annotations/Annotations.h"19#include "gmock/gmock.h"20#include "gtest/gtest.h"21#include <initializer_list>22 23namespace clang {24namespace clangd {25namespace {26 27// A referenced Decl together with its DeclRelationSet, for assertions.28//29// There's no great way to assert on the "content" of a Decl in the general case30// that's both expressive and unambiguous (e.g. clearly distinguishes between31// templated decls and their specializations).32//33// We use the result of pretty-printing the decl, with the {body} truncated.34struct PrintedDecl {35  PrintedDecl(const char *Name, DeclRelationSet Relations = {})36      : Name(Name), Relations(Relations) {}37  PrintedDecl(const NamedDecl *D, DeclRelationSet Relations = {})38      : Relations(Relations) {39    std::string S;40    llvm::raw_string_ostream OS(S);41    D->print(OS);42    llvm::StringRef FirstLine =43        llvm::StringRef(OS.str()).take_until([](char C) { return C == '\n'; });44    FirstLine = FirstLine.rtrim(" {");45    Name = std::string(FirstLine.rtrim(" {"));46  }47 48  std::string Name;49  DeclRelationSet Relations;50};51bool operator==(const PrintedDecl &L, const PrintedDecl &R) {52  return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);53}54llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PrintedDecl &D) {55  return OS << D.Name << " Rel=" << D.Relations;56}57 58// The test cases in for targetDecl() take the form59//  - a piece of code (Code = "...")60//  - Code should have a single AST node marked as a [[range]]61//  - an EXPECT_DECLS() assertion that verify the type of node selected, and62//    all the decls that targetDecl() considers it to reference63// Despite the name, these cases actually test allTargetDecls() for brevity.64class TargetDeclTest : public ::testing::Test {65protected:66  using Rel = DeclRelation;67  std::string Code;68  std::vector<std::string> Flags;69 70  // Asserts that `Code` has a marked selection of a node `NodeType`,71  // and returns allTargetDecls() as PrintedDecl structs.72  // Use via EXPECT_DECLS().73  std::vector<PrintedDecl> assertNodeAndPrintDecls(const char *NodeType) {74    llvm::Annotations A(Code);75    auto TU = TestTU::withCode(A.code());76    TU.ExtraArgs = Flags;77    auto AST = TU.build();78    llvm::Annotations::Range R = A.range();79    auto Selection = SelectionTree::createRight(80        AST.getASTContext(), AST.getTokens(), R.Begin, R.End);81    const SelectionTree::Node *N = Selection.commonAncestor();82    if (!N) {83      ADD_FAILURE() << "No node selected!\n" << Code;84      return {};85    }86    EXPECT_EQ(N->kind(), NodeType) << Selection;87 88    std::vector<PrintedDecl> ActualDecls;89    for (const auto &Entry :90         allTargetDecls(N->ASTNode, AST.getHeuristicResolver()))91      ActualDecls.emplace_back(Entry.first, Entry.second);92    return ActualDecls;93  }94};95 96// This is a macro to preserve line numbers in assertion failures.97// It takes the expected decls as varargs to work around comma-in-macro issues.98#define EXPECT_DECLS(NodeType, ...)                                            \99  EXPECT_THAT(assertNodeAndPrintDecls(NodeType),                               \100              ::testing::UnorderedElementsAreArray(                            \101                  std::vector<PrintedDecl>({__VA_ARGS__})))                    \102      << Code103using ExpectedDecls = std::vector<PrintedDecl>;104 105TEST_F(TargetDeclTest, Exprs) {106  Code = R"cpp(107    int f();108    int x = [[f]]();109  )cpp";110  EXPECT_DECLS("DeclRefExpr", "int f()");111 112  Code = R"cpp(113    struct S { S operator+(S) const; };114    auto X = S() [[+]] S();115  )cpp";116  EXPECT_DECLS("DeclRefExpr", "S operator+(S) const");117 118  Code = R"cpp(119    int foo();120    int s = foo[[()]];121  )cpp";122  EXPECT_DECLS("CallExpr", "int foo()");123 124  Code = R"cpp(125    struct X {126    void operator()(int n);127    };128    void test() {129      X x;130      x[[(123)]];131    }132  )cpp";133  EXPECT_DECLS("CXXOperatorCallExpr", "void operator()(int n)");134 135  Code = R"cpp(136    void test() {137      goto [[label]];138    label:139      return;140    }141  )cpp";142  EXPECT_DECLS("GotoStmt", "label:");143  Code = R"cpp(144    void test() {145    [[label]]:146      return;147    }148  )cpp";149  EXPECT_DECLS("LabelStmt", "label:");150}151 152TEST_F(TargetDeclTest, RecoveryForC) {153  Flags = {"-xc", "-Xclang", "-frecovery-ast"};154  Code = R"cpp(155    // error-ok: testing behavior on broken code156    // int f();157    int f(int);158    int x = [[f]]();159  )cpp";160  EXPECT_DECLS("DeclRefExpr", "int f(int)");161}162 163TEST_F(TargetDeclTest, Recovery) {164  Code = R"cpp(165    // error-ok: testing behavior on broken code166    int f();167    int f(int, int);168    int x = [[f]](42);169  )cpp";170  EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)");171}172 173TEST_F(TargetDeclTest, RecoveryType) {174  Code = R"cpp(175    // error-ok: testing behavior on broken code176    struct S { int member; };177    S overloaded(int);178    void foo() {179      // No overload matches, but we have recovery-expr with the correct type.180      overloaded().[[member]];181    }182  )cpp";183  EXPECT_DECLS("MemberExpr", "int member");184}185 186TEST_F(TargetDeclTest, UsingDecl) {187  Code = R"cpp(188    namespace foo {189      int f(int);190      int f(char);191    }192    using foo::f;193    int x = [[f]](42);194  )cpp";195  // f(char) is not referenced!196  EXPECT_DECLS("DeclRefExpr", {"using foo::f", Rel::Alias}, {"int f(int)"});197 198  Code = R"cpp(199    namespace foo {200      int f(int);201      int f(char);202    }203    [[using foo::f]];204  )cpp";205  // All overloads are referenced.206  EXPECT_DECLS("UsingDecl", {"using foo::f", Rel::Alias}, {"int f(int)"},207               {"int f(char)"});208 209  Code = R"cpp(210    struct X {211      int foo();212    };213    struct Y : X {214      using X::foo;215    };216    int x = Y().[[foo]]();217  )cpp";218  EXPECT_DECLS("MemberExpr", {"using X::foo", Rel::Alias}, {"int foo()"});219 220  Code = R"cpp(221      template <typename T>222      struct Base {223        void waldo() {}224      };225      template <typename T>226      struct Derived : Base<T> {227        using Base<T>::[[waldo]];228      };229    )cpp";230  EXPECT_DECLS("UnresolvedUsingValueDecl", {"using Base<T>::waldo", Rel::Alias},231               {"void waldo()"});232 233  Code = R"cpp(234    namespace ns {235    template<typename T> class S {};236    }237 238    using ns::S;239 240    template<typename T>241    using A = [[S]]<T>;242  )cpp";243  EXPECT_DECLS("TemplateSpecializationTypeLoc", {"using ns::S", Rel::Alias},244               {"template <typename T> class S"},245               {"class S", Rel::TemplatePattern});246 247  Code = R"cpp(248    namespace ns {249    template<typename T> class S {};250    }251 252    using ns::S;253    template <template <typename> class T> class X {};254    using B = X<[[S]]>;255  )cpp";256  EXPECT_DECLS("TemplateArgumentLoc", {"using ns::S", Rel::Alias},257               {"template <typename T> class S"});258 259  Code = R"cpp(260    namespace ns {261    template<typename T> class S { public: S(T); };262    }263 264    using ns::S;265    [[S]] s(123);266  )cpp";267  Flags.push_back("-std=c++17"); // For CTAD feature.268  EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",269               {"using ns::S", Rel::Alias}, {"template <typename T> class S"},270               {"class S", Rel::TemplatePattern});271 272  Code = R"cpp(273    template<typename T>274    class Foo { public: class foo {}; };275    template <class T> class A : public Foo<T> {276      using typename Foo<T>::foo;277      [[foo]] abc;278    };279  )cpp";280  EXPECT_DECLS("UnresolvedUsingTypeLoc",281               {"using typename Foo<T>::foo", Rel::Alias});282 283  // Using enum.284  Flags.push_back("-std=c++20");285  Code = R"cpp(286    namespace ns { enum class A { X }; }287    [[using enum ns::A]];288  )cpp";289  EXPECT_DECLS("UsingEnumDecl", "enum class A : int");290 291  Code = R"cpp(292    namespace ns { enum class A { X }; }293    using enum ns::A;294    auto m = [[X]];295  )cpp";296  EXPECT_DECLS("DeclRefExpr", "X");297}298 299TEST_F(TargetDeclTest, BaseSpecifier) {300  Code = R"cpp(301    struct X {};302    struct Y : [[private]] X {};303  )cpp";304  EXPECT_DECLS("CXXBaseSpecifier", "struct X");305  Code = R"cpp(306    struct X {};307    struct Y : [[private X]] {};308  )cpp";309  EXPECT_DECLS("CXXBaseSpecifier", "struct X");310  Code = R"cpp(311    struct X {};312    struct Y : private [[X]] {};313  )cpp";314  EXPECT_DECLS("RecordTypeLoc", "struct X");315}316 317TEST_F(TargetDeclTest, ConstructorInitList) {318  Code = R"cpp(319    struct X {320      int a;321      X() : [[a]](42) {}322    };323  )cpp";324  EXPECT_DECLS("CXXCtorInitializer", "int a");325 326  Code = R"cpp(327    struct X {328      X() : [[X]](1) {}329      X(int);330    };331  )cpp";332  EXPECT_DECLS("RecordTypeLoc", "struct X");333}334 335TEST_F(TargetDeclTest, DesignatedInit) {336  Flags = {"-xc"}; // array designators are a C99 extension.337  Code = R"c(338    struct X { int a; };339    struct Y { int b; struct X c[2]; };340    struct Y y = { .c[0].[[a]] = 1 };341  )c";342  EXPECT_DECLS("DesignatedInitExpr", "int a");343}344 345TEST_F(TargetDeclTest, NestedNameSpecifier) {346  Code = R"cpp(347    namespace a { namespace b { int c; } }348    int x = a::[[b::]]c;349  )cpp";350  EXPECT_DECLS("NestedNameSpecifierLoc", "namespace b");351 352  Code = R"cpp(353    namespace a { struct X { enum { y }; }; }354    int x = a::[[X::]]y;355  )cpp";356  EXPECT_DECLS("NestedNameSpecifierLoc", "struct X");357 358  Code = R"cpp(359    template <typename T>360    int x = [[T::]]y;361  )cpp";362  EXPECT_DECLS("NestedNameSpecifierLoc", "typename T");363 364  Code = R"cpp(365    namespace a { int x; }366    namespace b = a;367    int y = [[b]]::x;368  )cpp";369  EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},370               {"namespace a", Rel::Underlying});371}372 373TEST_F(TargetDeclTest, Types) {374  Code = R"cpp(375    struct X{};376    [[X]] x;377  )cpp";378  EXPECT_DECLS("RecordTypeLoc", "struct X");379 380  Code = R"cpp(381    struct S{};382    typedef S X;383    [[X]] x;384  )cpp";385  EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},386               {"struct S", Rel::Underlying});387  Code = R"cpp(388    namespace ns { struct S{}; }389    typedef ns::S X;390    [[X]] x;391  )cpp";392  EXPECT_DECLS("TypedefTypeLoc", {"typedef ns::S X", Rel::Alias},393               {"struct S", Rel::Underlying});394 395  Code = R"cpp(396    template<class T>397    void foo() { [[T]] x; }398  )cpp";399  EXPECT_DECLS("TemplateTypeParmTypeLoc", "class T");400  Flags.clear();401 402  Code = R"cpp(403    template<template<typename> class T>404    void foo() { [[T<int>]] x; }405  )cpp";406  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class T");407  Flags.clear();408 409  Code = R"cpp(410  template<template<typename> class ...T>411  class C {412    C<[[T...]]> foo;413    };414  )cpp";415  EXPECT_DECLS("TemplateArgumentLoc", {"template <typename> class ...T"});416  Flags.clear();417 418  Code = R"cpp(419    struct S{};420    S X;421    [[decltype]](X) Y;422  )cpp";423  EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});424 425  Code = R"cpp(426    struct S{};427    [[auto]] X = S{};428  )cpp";429  // FIXME: deduced type missing in AST. https://llvm.org/PR42914430  EXPECT_DECLS("AutoTypeLoc", );431 432  Code = R"cpp(433    template <typename... E>434    struct S {435      static const int size = sizeof...([[E]]);436    };437  )cpp";438  EXPECT_DECLS("SizeOfPackExpr", "typename ...E");439 440  Code = R"cpp(441    template <typename T>442    class Foo {443      void f([[Foo]] x);444    };445  )cpp";446  EXPECT_DECLS("InjectedClassNameTypeLoc", "class Foo");447}448 449TEST_F(TargetDeclTest, ClassTemplate) {450  Code = R"cpp(451    // Implicit specialization.452    template<int x> class Foo{};453    [[Foo<42>]] B;454  )cpp";455  EXPECT_DECLS("TemplateSpecializationTypeLoc",456               {"template<> class Foo<42>", Rel::TemplateInstantiation},457               {"class Foo", Rel::TemplatePattern});458 459  Code = R"cpp(460    template<typename T> class Foo {};461    // The "Foo<int>" SpecializationDecl is incomplete, there is no462    // instantiation happening.463    void func([[Foo<int>]] *);464  )cpp";465  EXPECT_DECLS("TemplateSpecializationTypeLoc",466               {"class Foo", Rel::TemplatePattern},467               {"template<> class Foo<int>", Rel::TemplateInstantiation});468 469  Code = R"cpp(470    // Explicit specialization.471    template<int x> class Foo{};472    template<> class Foo<42>{};473    [[Foo<42>]] B;474  )cpp";475  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template<> class Foo<42>");476 477  Code = R"cpp(478    // Partial specialization.479    template<typename T> class Foo{};480    template<typename T> class Foo<T*>{};481    [[Foo<int*>]] B;482  )cpp";483  EXPECT_DECLS("TemplateSpecializationTypeLoc",484               {"template<> class Foo<int *>", Rel::TemplateInstantiation},485               {"template <typename T> class Foo<T *>", Rel::TemplatePattern});486 487  Code = R"cpp(488    // Template template argument.489    template<typename T> struct Vector {};490    template <template <typename> class Container>491    struct A {};492    A<[[Vector]]> a;493  )cpp";494  EXPECT_DECLS("TemplateArgumentLoc", {"template <typename T> struct Vector"});495 496  Flags.push_back("-std=c++17"); // for CTAD tests497 498  Code = R"cpp(499    // Class template argument deduction500    template <typename T>501    struct Test {502      Test(T);503    };504    void foo() {505      [[Test]] a(5);506    }507  )cpp";508  EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",509               {"struct Test", Rel::TemplatePattern});510 511  Code = R"cpp(512    // Deduction guide513    template <typename T>514    struct Test {515      template <typename I>516      Test(I, I);517    };518    template <typename I>519    [[Test]](I, I) -> Test<typename I::type>;520  )cpp";521  EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"});522}523 524TEST_F(TargetDeclTest, Concept) {525  Flags.push_back("-std=c++20");526 527  // FIXME: Should we truncate the pretty-printed form of a concept decl528  // somewhere?529 530  Code = R"cpp(531    template <typename T>532    concept Fooable = requires (T t) { t.foo(); };533 534    template <typename T> requires [[Fooable]]<T>535    void bar(T t) {536      t.foo();537    }538  )cpp";539  EXPECT_DECLS(540      "ConceptReference",541      {"template <typename T> concept Fooable = requires (T t) { t.foo(); }"});542 543  // trailing requires clause544  Code = R"cpp(545      template <typename T>546      concept Fooable = true;547 548      template <typename T>549      void foo() requires [[Fooable]]<T>;550  )cpp";551  EXPECT_DECLS("ConceptReference",552               {"template <typename T> concept Fooable = true"});553 554  // constrained-parameter555  Code = R"cpp(556    template <typename T>557    concept Fooable = true;558 559    template <[[Fooable]] T>560    void bar(T t);561  )cpp";562  EXPECT_DECLS("ConceptReference",563               {"template <typename T> concept Fooable = true"});564 565  // partial-concept-id566  Code = R"cpp(567    template <typename T, typename U>568    concept Fooable = true;569 570    template <[[Fooable]]<int> T>571    void bar(T t);572  )cpp";573  EXPECT_DECLS("ConceptReference",574               {"template <typename T, typename U> concept Fooable = true"});575}576 577TEST_F(TargetDeclTest, Coroutine) {578  Flags.push_back("-std=c++20");579 580  Code = R"cpp(581    namespace std {582    template <typename, typename...> struct coroutine_traits;583    template <typename> struct coroutine_handle {584      template <typename U>585      coroutine_handle(coroutine_handle<U>&&) noexcept;586      static coroutine_handle from_address(void* __addr) noexcept;587    };588    } // namespace std589 590    struct executor {};591    struct awaitable {};592    struct awaitable_frame {593      awaitable get_return_object();594      void return_void();595      void unhandled_exception();596      struct result_t {597        ~result_t();598        bool await_ready() const noexcept;599        void await_suspend(std::coroutine_handle<void>) noexcept;600        void await_resume() const noexcept;601      };602      result_t initial_suspend() noexcept;603      result_t final_suspend() noexcept;604      result_t await_transform(executor) noexcept;605    };606 607    namespace std {608    template <>609    struct coroutine_traits<awaitable> {610      typedef awaitable_frame promise_type;611    };612    } // namespace std613 614    awaitable foo() {615      co_await [[executor]]();616    }617  )cpp";618  EXPECT_DECLS("RecordTypeLoc", "struct executor");619}620 621TEST_F(TargetDeclTest, RewrittenBinaryOperator) {622  Flags.push_back("-std=c++20");623 624  Code = R"cpp(625  namespace std {626    struct strong_ordering {627      int n;628      constexpr operator int() const { return n; }629      static const strong_ordering equal, greater, less;630    };631    constexpr strong_ordering strong_ordering::equal = {0};632    constexpr strong_ordering strong_ordering::greater = {1};633    constexpr strong_ordering strong_ordering::less = {-1};634    }635 636    struct Foo637    {638      int x;639      auto operator<=>(const Foo&) const = default;640    };641 642    bool x = (Foo(1) [[!=]] Foo(2));643  )cpp";644  EXPECT_DECLS("CXXRewrittenBinaryOperator",645               {"bool operator==(const Foo &) const noexcept = default"});646}647 648TEST_F(TargetDeclTest, FunctionTemplate) {649  Code = R"cpp(650    // Implicit specialization.651    template<typename T> bool foo(T) { return false; };652    bool x = [[foo]](42);653  )cpp";654  EXPECT_DECLS("DeclRefExpr",655               {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},656               {"bool foo(T)", Rel::TemplatePattern});657 658  Code = R"cpp(659    // Explicit specialization.660    template<typename T> bool foo(T) { return false; };661    template<> bool foo<int>(int) { return false; };662    bool x = [[foo]](42);663  )cpp";664  EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");665}666 667TEST_F(TargetDeclTest, VariableTemplate) {668  // Pretty-printer doesn't do a very good job of variable templates :-(669  Code = R"cpp(670    // Implicit specialization.671    template<typename T> int foo;672    int x = [[foo]]<char>;673  )cpp";674  EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},675               {"int foo", Rel::TemplatePattern});676 677  Code = R"cpp(678    // Explicit specialization.679    template<typename T> int foo;680    template <> bool foo<char>;681    int x = [[foo]]<char>;682  )cpp";683  EXPECT_DECLS("DeclRefExpr", "bool foo");684 685  Code = R"cpp(686    // Partial specialization.687    template<typename T> int foo;688    template<typename T> bool foo<T*>;689    bool x = [[foo]]<char*>;690  )cpp";691  EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},692               {"bool foo", Rel::TemplatePattern});693}694 695TEST_F(TargetDeclTest, TypeAliasTemplate) {696  Code = R"cpp(697    template<typename T, int X> class SmallVector {};698    template<typename U> using TinyVector = SmallVector<U, 1>;699    [[TinyVector<int>]] X;700  )cpp";701  EXPECT_DECLS("TemplateSpecializationTypeLoc",702               {"template<> class SmallVector<int, 1>",703                Rel::TemplateInstantiation | Rel::Underlying},704               {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},705               {"using TinyVector = SmallVector<U, 1>",706                Rel::Alias | Rel::TemplatePattern});707}708 709TEST_F(TargetDeclTest, BuiltinTemplates) {710  Code = R"cpp(711    template <class T, T... Index> struct integer_sequence {};712    [[__make_integer_seq]]<integer_sequence, int, 3> X;713  )cpp";714  EXPECT_DECLS(715      "TemplateSpecializationTypeLoc",716      {"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},717      {"template<> struct integer_sequence<int, <0, 1, 2>>",718       Rel::TemplateInstantiation | Rel::Underlying});719 720  // Dependent context.721  Code = R"cpp(722    template <class T, T... Index> struct integer_sequence;723 724    template <class T, int N>725    using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;726  )cpp";727  EXPECT_DECLS("TemplateSpecializationTypeLoc", );728 729  Code = R"cpp(730    template <int N, class... Pack>731    using type_pack_element = [[__type_pack_element]]<N, Pack...>;732  )cpp";733  EXPECT_DECLS("TemplateSpecializationTypeLoc", );734 735  Code = R"cpp(736    template <template <class...> class Templ, class... Types>737    using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;738  )cpp";739  EXPECT_DECLS("TemplateSpecializationTypeLoc", );740}741 742TEST_F(TargetDeclTest, MemberOfTemplate) {743  Code = R"cpp(744    template <typename T> struct Foo {745      int x(T);746    };747    int y = Foo<int>().[[x]](42);748  )cpp";749  EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},750               {"int x(T)", Rel::TemplatePattern});751 752  Code = R"cpp(753    template <typename T> struct Foo {754      template <typename U>755      int x(T, U);756    };757    int y = Foo<char>().[[x]]('c', 42);758  )cpp";759  EXPECT_DECLS("MemberExpr",760               {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},761               {"int x(T, U)", Rel::TemplatePattern});762}763 764TEST_F(TargetDeclTest, Lambda) {765  Code = R"cpp(766    void foo(int x = 42) {767      auto l = [ [[x]] ]{ return x + 1; };768    };769  )cpp";770  EXPECT_DECLS("DeclRefExpr", "int x = 42");771 772  // It seems like this should refer to another var, with the outer param being773  // an underlying decl. But it doesn't seem to exist.774  Code = R"cpp(775    void foo(int x = 42) {776      auto l = [x]{ return [[x]] + 1; };777    };778  )cpp";779  EXPECT_DECLS("DeclRefExpr", "int x = 42");780 781  Code = R"cpp(782    void foo() {783      auto l = [x = 1]{ return [[x]] + 1; };784    };785  )cpp";786  // FIXME: why both auto and int?787  EXPECT_DECLS("DeclRefExpr", "auto int x = 1");788}789 790TEST_F(TargetDeclTest, OverloadExpr) {791  Flags.push_back("--target=x86_64-pc-linux-gnu");792 793  Code = R"cpp(794    void func(int*);795    void func(char*);796 797    template <class T>798    void foo(T t) {799      [[func]](t);800    };801  )cpp";802  EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");803 804  Code = R"cpp(805    struct X {806      void func(int*);807      void func(char*);808    };809 810    template <class T>811    void foo(X x, T t) {812      x.[[func]](t);813    };814  )cpp";815  EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");816 817  Code = R"cpp(818    struct X {819      static void *operator new(unsigned long);820    };821    auto* k = [[new]] X();822  )cpp";823  EXPECT_DECLS("CXXNewExpr", "static void *operator new(unsigned long)");824  Code = R"cpp(825    void *operator new(unsigned long);826    auto* k = [[new]] int();827  )cpp";828  EXPECT_DECLS("CXXNewExpr", "void *operator new(unsigned long)");829 830  Code = R"cpp(831    struct X {832      static void operator delete(void *) noexcept;833    };834    void k(X* x) {835      [[delete]] x;836    }837  )cpp";838  EXPECT_DECLS("CXXDeleteExpr", "static void operator delete(void *) noexcept");839  Code = R"cpp(840    void operator delete(void *) noexcept;841    void k(int* x) {842      [[delete]] x;843    }844  )cpp";845  // Sized deallocation is enabled by default in C++14 onwards.846  EXPECT_DECLS("CXXDeleteExpr",847               "void operator delete(void *, __size_t) noexcept");848}849 850TEST_F(TargetDeclTest, DependentExprs) {851  Flags.push_back("--std=c++20");852 853  // Heuristic resolution of method of dependent field854  Code = R"cpp(855        struct A { void foo() {} };856        template <typename T>857        struct B {858          A a;859          void bar() {860            this->a.[[foo]]();861          }862        };863      )cpp";864  EXPECT_DECLS("MemberExpr", "void foo()");865 866  // Similar to above but base expression involves a function call.867  Code = R"cpp(868        struct A {869          void foo() {}870        };871        struct B {872          A getA();873        };874        template <typename T>875        struct C {876          B c;877          void bar() {878            this->c.getA().[[foo]]();879          }880        };881      )cpp";882  EXPECT_DECLS("MemberExpr", "void foo()");883 884  // Similar to above but uses a function pointer.885  Code = R"cpp(886        struct A {887          void foo() {}888        };889        struct B {890          using FPtr = A(*)();891          FPtr fptr;892        };893        template <typename T>894        struct C {895          B c;896          void bar() {897            this->c.fptr().[[foo]]();898          }899        };900      )cpp";901  EXPECT_DECLS("MemberExpr", "void foo()");902 903  // Base expression involves a member access into this.904  Code = R"cpp(905        struct Bar {906          int aaaa;907        };908        template <typename T> struct Foo {909          Bar func(int);910          void test() {911            func(1).[[aaaa]];912          }913        };914      )cpp";915  EXPECT_DECLS("CXXDependentScopeMemberExpr", "int aaaa");916 917  Code = R"cpp(918        class Foo {919        public:920          static Foo k(int);921          template <typename T> T convert() const;922        };923        template <typename T>924        void test() {925          Foo::k(T()).template [[convert]]<T>();926        }927      )cpp";928  EXPECT_DECLS("CXXDependentScopeMemberExpr",929               "template <typename T> T convert() const");930 931  Code = R"cpp(932        template <typename T>933        struct Waldo {934          void find();935        };936        template <typename T>937        using Wally = Waldo<T>;938        template <typename T>939        void foo(Wally<T> w) {940          w.[[find]]();941        }942  )cpp";943  EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");944 945  Code = R"cpp(946        template <typename T>947        struct Waldo {948          void find();949        };950        template <typename T>951        struct MetaWaldo {952          using Type = Waldo<T>;953        };954        template <typename T>955        void foo(typename MetaWaldo<T>::Type w) {956          w.[[find]]();957        }958  )cpp";959  EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");960 961  Code = R"cpp(962        struct Waldo {963          void find();964        };965        template <typename T>966        using Wally = Waldo;967        template <typename>968        struct S : Wally<int> {969          void Foo() { this->[[find]](); }970        };971  )cpp";972  EXPECT_DECLS("MemberExpr", "void find()");973 974  // Base expression is the type of a non-type template parameter975  // which is deduced using CTAD.976  Code = R"cpp(977        template <int N>978        struct Waldo {979          const int found = N;980        };981 982        template <Waldo W>983        int test() {984          return W.[[found]];985        }986  )cpp";987  EXPECT_DECLS("CXXDependentScopeMemberExpr", "const int found = N");988}989 990TEST_F(TargetDeclTest, DependentTypes) {991  // Heuristic resolution of dependent type name992  Code = R"cpp(993        template <typename>994        struct A { struct B {}; };995 996        template <typename T>997        void foo(typename A<T>::[[B]]);998      )cpp";999  EXPECT_DECLS("DependentNameTypeLoc", "struct B");1000 1001  // Heuristic resolution of dependent type name within a NestedNameSpecifierLoc1002  Code = R"cpp(1003        template <typename>1004        struct A { struct B { struct C {}; }; };1005 1006        template <typename T>1007        void foo(typename A<T>::[[B]]::C);1008      )cpp";1009  EXPECT_DECLS("DependentNameTypeLoc", "struct B");1010 1011  // Heuristic resolution of dependent type name whose qualifier is also1012  // dependent1013  Code = R"cpp(1014        template <typename>1015        struct A { struct B { struct C {}; }; };1016 1017        template <typename T>1018        void foo(typename A<T>::B::[[C]]);1019      )cpp";1020  EXPECT_DECLS("DependentNameTypeLoc", "struct C");1021 1022  // Heuristic resolution of dependent template name1023  Code = R"cpp(1024        template <typename>1025        struct A {1026          template <typename> struct B {};1027        };1028 1029        template <typename T>1030        void foo(typename A<T>::template [[B]]<int>);1031      )cpp";1032  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");1033 1034  // Dependent name with recursive definition. We don't expect a1035  // result, but we shouldn't get into a stack overflow either.1036  Code = R"cpp(1037        template <int N>1038        struct waldo {1039          typedef typename waldo<N - 1>::type::[[next]] type;1040        };1041  )cpp";1042  EXPECT_DECLS("DependentNameTypeLoc", );1043 1044  // Similar to above but using mutually recursive templates.1045  Code = R"cpp(1046        template <int N>1047        struct odd;1048 1049        template <int N>1050        struct even {1051          using type = typename odd<N - 1>::type::next;1052        };1053 1054        template <int N>1055        struct odd {1056          using type = typename even<N - 1>::type::[[next]];1057        };1058  )cpp";1059  EXPECT_DECLS("DependentNameTypeLoc", );1060}1061 1062TEST_F(TargetDeclTest, TypedefCascade) {1063  Code = R"cpp(1064        struct C {1065          using type = int;1066        };1067        struct B {1068          using type = C::type;1069        };1070        struct A {1071          using type = B::type;1072        };1073        A::[[type]] waldo;1074  )cpp";1075  EXPECT_DECLS("TypedefTypeLoc",1076               {"using type = int", Rel::Alias | Rel::Underlying},1077               {"using type = C::type", Rel::Alias | Rel::Underlying},1078               {"using type = B::type", Rel::Alias});1079}1080 1081TEST_F(TargetDeclTest, RecursiveTemplate) {1082  Flags.push_back("-std=c++20"); // the test case uses concepts1083 1084  Code = R"cpp(1085        template <typename T>1086        concept Leaf = false;1087 1088        template <typename Tree>1089        struct descend_left {1090          using type = typename descend_left<typename Tree::left>::[[type]];1091        };1092 1093        template <Leaf Tree>1094        struct descend_left<Tree> {1095          using type = typename Tree::value;1096        };1097  )cpp";1098  EXPECT_DECLS("DependentNameTypeLoc",1099               {"using type = typename descend_left<typename Tree::left>::type",1100                Rel::Alias | Rel::Underlying});1101}1102 1103TEST_F(TargetDeclTest, ObjC) {1104  Flags = {"-xobjective-c"};1105  Code = R"cpp(1106    @interface Foo {}1107    -(void)bar;1108    @end1109    void test(Foo *f) {1110      [f [[bar]] ];1111    }1112  )cpp";1113  EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");1114 1115  Code = R"cpp(1116    @interface Foo { @public int bar; }1117    @end1118    int test(Foo *f) {1119      return [[f->bar]];1120    }1121  )cpp";1122  EXPECT_DECLS("ObjCIvarRefExpr", "int bar");1123 1124  Code = R"cpp(1125    @interface Foo {}1126    -(int) x;1127    -(void) setX:(int)x;1128    @end1129    void test(Foo *f) {1130      [[f.x]] = 42;1131    }1132  )cpp";1133  EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");1134 1135  Code = R"cpp(1136    @interface I {}1137    @property(retain) I* x;1138    @property(retain) I* y;1139    @end1140    void test(I *f) {1141      [[f.x]].y = 0;1142    }1143  )cpp";1144  EXPECT_DECLS("ObjCPropertyRefExpr",1145               "@property(atomic, retain, readwrite) I *x");1146 1147  Code = R"cpp(1148    @interface MYObject1149    @end1150    @interface Interface1151    @property(retain) [[MYObject]] *x;1152    @end1153  )cpp";1154  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject");1155 1156  Code = R"cpp(1157    @interface MYObject21158    @end1159    @interface Interface1160    @property(retain, nonnull) [[MYObject2]] *x;1161    @end1162  )cpp";1163  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface MYObject2");1164 1165  Code = R"cpp(1166    @protocol Foo1167    @end1168    id test() {1169      return [[@protocol(Foo)]];1170    }1171  )cpp";1172  EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");1173 1174  Code = R"cpp(1175    @interface Foo1176    @end1177    void test([[Foo]] *p);1178  )cpp";1179  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");1180 1181  Code = R"cpp(// Don't consider implicit interface as the target.1182    @implementation [[Implicit]]1183    @end1184  )cpp";1185  EXPECT_DECLS("ObjCImplementationDecl", "@implementation Implicit");1186 1187  Code = R"cpp(1188    @interface Foo1189    @end1190    @implementation [[Foo]]1191    @end1192  )cpp";1193  EXPECT_DECLS("ObjCImplementationDecl", "@interface Foo");1194 1195  Code = R"cpp(1196    @interface Foo1197    @end1198    @interface Foo (Ext)1199    @end1200    @implementation [[Foo]] (Ext)1201    @end1202  )cpp";1203  EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");1204 1205  Code = R"cpp(1206    @interface Foo1207    @end1208    @interface Foo (Ext)1209    @end1210    @implementation Foo ([[Ext]])1211    @end1212  )cpp";1213  EXPECT_DECLS("ObjCCategoryImplDecl", "@interface Foo(Ext)");1214 1215  Code = R"cpp(1216    void test(id</*error-ok*/[[InvalidProtocol]]> p);1217  )cpp";1218  EXPECT_DECLS("ParmVarDecl", "id p");1219 1220  Code = R"cpp(1221    @class C;1222    @protocol Foo1223    @end1224    void test([[C]]<Foo> *p);1225  )cpp";1226  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@class C;");1227 1228  Code = R"cpp(1229    @class C;1230    @protocol Foo1231    @end1232    void test(C<[[Foo]]> *p);1233  )cpp";1234  EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");1235 1236  Code = R"cpp(1237    @class C;1238    @protocol Foo1239    @end1240    @protocol Bar1241    @end1242    void test(C<[[Foo]], Bar> *p);1243  )cpp";1244  EXPECT_DECLS("ObjCProtocolLoc", "@protocol Foo");1245 1246  Code = R"cpp(1247    @class C;1248    @protocol Foo1249    @end1250    @protocol Bar1251    @end1252    void test(C<Foo, [[Bar]]> *p);1253  )cpp";1254  EXPECT_DECLS("ObjCProtocolLoc", "@protocol Bar");1255 1256  Code = R"cpp(1257    @interface Foo1258    + (id)sharedInstance;1259    @end1260    @implementation Foo1261    + (id)sharedInstance { return 0; }1262    @end1263    void test() {1264      id value = [[Foo]].sharedInstance;1265    }1266  )cpp";1267  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");1268 1269  Code = R"cpp(1270    @interface Foo1271    + (id)sharedInstance;1272    @end1273    @implementation Foo1274    + (id)sharedInstance { return 0; }1275    @end1276    void test() {1277      id value = Foo.[[sharedInstance]];1278    }1279  )cpp";1280  EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");1281 1282  Code = R"cpp(1283    @interface Foo1284    + ([[id]])sharedInstance;1285    @end1286  )cpp";1287  EXPECT_DECLS("TypedefTypeLoc", );1288 1289  Code = R"cpp(1290    @interface Foo1291    + ([[instancetype]])sharedInstance;1292    @end1293  )cpp";1294  EXPECT_DECLS("TypedefTypeLoc", );1295}1296 1297class FindExplicitReferencesTest : public ::testing::Test {1298protected:1299  struct AllRefs {1300    std::string AnnotatedCode;1301    std::string DumpedReferences;1302  };1303 1304  TestTU newTU(llvm::StringRef Code) {1305    TestTU TU;1306    TU.Code = std::string(Code);1307 1308    // FIXME: Auto-completion in a template requires disabling delayed template1309    // parsing.1310    TU.ExtraArgs.push_back("-std=c++20");1311    TU.ExtraArgs.push_back("-xobjective-c++");1312 1313    return TU;1314  }1315 1316  AllRefs annotatedReferences(llvm::StringRef Code, ParsedAST &AST,1317                              std::vector<ReferenceLoc> Refs) {1318    auto &SM = AST.getSourceManager();1319    llvm::stable_sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {1320      return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);1321    });1322 1323    std::string AnnotatedCode;1324    unsigned NextCodeChar = 0;1325    for (unsigned I = 0; I < Refs.size(); ++I) {1326      auto &R = Refs[I];1327 1328      SourceLocation Pos = R.NameLoc;1329      assert(Pos.isValid());1330      if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.1331        Pos = SM.getExpansionLoc(Pos);1332      assert(Pos.isFileID());1333 1334      FileID File;1335      unsigned Offset;1336      std::tie(File, Offset) = SM.getDecomposedLoc(Pos);1337      if (File == SM.getMainFileID()) {1338        // Print the reference in a source code.1339        assert(NextCodeChar <= Offset);1340        AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);1341        AnnotatedCode += "$" + std::to_string(I) + "^";1342 1343        NextCodeChar = Offset;1344      }1345    }1346    AnnotatedCode += Code.substr(NextCodeChar);1347 1348    std::string DumpedReferences;1349    for (unsigned I = 0; I < Refs.size(); ++I)1350      DumpedReferences += std::string(llvm::formatv("{0}: {1}\n", I, Refs[I]));1351 1352    return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};1353  }1354 1355  /// Parses \p Code, and annotates its body with results of1356  /// findExplicitReferences on all top level decls.1357  /// See actual tests for examples of annotation format.1358  AllRefs annotateAllReferences(llvm::StringRef Code) {1359    TestTU TU = newTU(Code);1360    auto AST = TU.build();1361 1362    std::vector<ReferenceLoc> Refs;1363    for (auto *TopLevel : AST.getLocalTopLevelDecls())1364      findExplicitReferences(1365          TopLevel, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },1366          AST.getHeuristicResolver());1367    return annotatedReferences(Code, AST, std::move(Refs));1368  }1369 1370  /// Parses \p Code, finds function or namespace '::foo' and annotates its body1371  /// with results of findExplicitReferences.1372  /// See actual tests for examples of annotation format.1373  AllRefs annotateReferencesInFoo(llvm::StringRef Code) {1374    TestTU TU = newTU(Code);1375    auto AST = TU.build();1376    auto *TestDecl = &findDecl(AST, "foo");1377    if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))1378      TestDecl = T->getTemplatedDecl();1379 1380    std::vector<ReferenceLoc> Refs;1381    if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))1382      findExplicitReferences(1383          Func->getBody(),1384          [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },1385          AST.getHeuristicResolver());1386    else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))1387      findExplicitReferences(1388          NS,1389          [&Refs, &NS](ReferenceLoc R) {1390            // Avoid adding the namespace foo decl to the results.1391            if (R.Targets.size() == 1 && R.Targets.front() == NS)1392              return;1393            Refs.push_back(std::move(R));1394          },1395          AST.getHeuristicResolver());1396    else if (const auto *OC = llvm::dyn_cast<ObjCContainerDecl>(TestDecl))1397      findExplicitReferences(1398          OC, [&Refs](ReferenceLoc R) { Refs.push_back(std::move(R)); },1399          AST.getHeuristicResolver());1400    else1401      ADD_FAILURE() << "Failed to find ::foo decl for test";1402 1403    return annotatedReferences(Code, AST, std::move(Refs));1404  }1405};1406 1407TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {1408  std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =1409      {// Simple expressions.1410       {R"cpp(1411        int global;1412        int func();1413        void foo(int param) {1414          $0^global = $1^param + $2^func();1415        }1416        )cpp",1417        "0: targets = {global}\n"1418        "1: targets = {param}\n"1419        "2: targets = {func}\n"},1420       {R"cpp(1421        struct X { int a; };1422        void foo(X x) {1423          $0^x.$1^a = 10;1424        }1425        )cpp",1426        "0: targets = {x}\n"1427        "1: targets = {X::a}\n"},1428       {R"cpp(1429        // error-ok: testing with broken code1430        int bar();1431        int foo() {1432          return $0^bar() + $1^bar(42);1433        }1434        )cpp",1435        "0: targets = {bar}\n"1436        "1: targets = {bar}\n"},1437       // Namespaces and aliases.1438       {R"cpp(1439          namespace ns {}1440          namespace alias = ns;1441          void foo() {1442            using namespace $0^ns;1443            using namespace $1^alias;1444          }1445        )cpp",1446        "0: targets = {ns}\n"1447        "1: targets = {alias}\n"},1448       // Using declarations.1449       {R"cpp(1450          namespace ns { int global; }1451          void foo() {1452            using $0^ns::$1^global;1453          }1454        )cpp",1455        "0: targets = {ns}\n"1456        "1: targets = {ns::global}, qualifier = 'ns::'\n"},1457       // Using enum declarations.1458       {R"cpp(1459          namespace ns { enum class A {}; }1460          void foo() {1461            using enum $0^ns::$1^A;1462          }1463        )cpp",1464        "0: targets = {ns}\n"1465        "1: targets = {ns::A}, qualifier = 'ns::'\n"},1466       // Simple types.1467       {R"cpp(1468         struct Struct { int a; };1469         using Typedef = int;1470         void foo() {1471           $0^Struct $1^x;1472           $2^Typedef $3^y;1473           static_cast<$4^Struct*>(0);1474         }1475       )cpp",1476        "0: targets = {Struct}\n"1477        "1: targets = {x}, decl\n"1478        "2: targets = {Typedef}\n"1479        "3: targets = {y}, decl\n"1480        "4: targets = {Struct}\n"},1481       // Name qualifiers.1482       {R"cpp(1483         namespace a { namespace b { struct S { typedef int type; }; } }1484         void foo() {1485           $0^a::$1^b::$2^S $3^x;1486           using namespace $4^a::$5^b;1487           $6^S::$7^type $8^y;1488         }1489        )cpp",1490        "0: targets = {a}\n"1491        "1: targets = {a::b}, qualifier = 'a::'\n"1492        "2: targets = {a::b::S}, qualifier = 'a::b::'\n"1493        "3: targets = {x}, decl\n"1494        "4: targets = {a}\n"1495        "5: targets = {a::b}, qualifier = 'a::'\n"1496        "6: targets = {a::b::S}\n"1497        "7: targets = {a::b::S::type}, qualifier = 'S::'\n"1498        "8: targets = {y}, decl\n"},1499       {R"cpp(1500         void foo() {1501           $0^ten: // PRINT "HELLO WORLD!"1502           goto $1^ten;1503         }1504       )cpp",1505        "0: targets = {ten}, decl\n"1506        "1: targets = {ten}\n"},1507       // Simple templates.1508       {R"cpp(1509          template <class T> struct vector { using value_type = T; };1510          template <> struct vector<bool> { using value_type = bool; };1511          void foo() {1512            $0^vector<int> $1^vi;1513            $2^vector<bool> $3^vb;1514          }1515        )cpp",1516        "0: targets = {vector<int>}\n"1517        "1: targets = {vi}, decl\n"1518        "2: targets = {vector<bool>}\n"1519        "3: targets = {vb}, decl\n"},1520       // Template type aliases.1521       {R"cpp(1522            template <class T> struct vector { using value_type = T; };1523            template <> struct vector<bool> { using value_type = bool; };1524            template <class T> using valias = vector<T>;1525            void foo() {1526              $0^valias<int> $1^vi;1527              $2^valias<bool> $3^vb;1528            }1529          )cpp",1530        "0: targets = {valias}\n"1531        "1: targets = {vi}, decl\n"1532        "2: targets = {valias}\n"1533        "3: targets = {vb}, decl\n"},1534       // Injected class name.1535       {R"cpp(1536            namespace foo {1537              template <typename $0^T>1538              class $1^Bar {1539                ~$2^Bar();1540                void $3^f($4^Bar);1541              };1542            }1543          )cpp",1544        "0: targets = {foo::Bar::T}, decl\n"1545        "1: targets = {foo::Bar}, decl\n"1546        "2: targets = {foo::Bar}\n"1547        "3: targets = {foo::Bar::f}, decl\n"1548        "4: targets = {foo::Bar}\n"},1549       // MemberExpr should know their using declaration.1550       {R"cpp(1551            struct X { void func(int); };1552            struct Y : X {1553              using X::func;1554            };1555            void foo(Y y) {1556              $0^y.$1^func(1);1557            }1558        )cpp",1559        "0: targets = {y}\n"1560        "1: targets = {Y::func}\n"},1561       // DeclRefExpr should know their using declaration.1562       {R"cpp(1563            namespace ns { void bar(int); }1564            using ns::bar;1565 1566            void foo() {1567              $0^bar(10);1568            }1569        )cpp",1570        "0: targets = {bar}\n"},1571       // References from a macro.1572       {R"cpp(1573            #define FOO a1574            #define BAR b1575 1576            void foo(int a, int b) {1577              $0^FOO+$1^BAR;1578            }1579        )cpp",1580        "0: targets = {a}\n"1581        "1: targets = {b}\n"},1582       // No references from implicit nodes.1583       {R"cpp(1584            struct vector {1585              int *begin();1586              int *end();1587            };1588 1589            void foo() {1590              for (int $0^x : $1^vector()) {1591                $2^x = 10;1592              }1593            }1594        )cpp",1595        "0: targets = {x}, decl\n"1596        "1: targets = {vector}\n"1597        "2: targets = {x}\n"},1598       // Handle UnresolvedLookupExpr.1599       {R"cpp(1600            namespace ns1 { void func(char*); }1601            namespace ns2 { void func(int*); }1602            using namespace ns1;1603            using namespace ns2;1604 1605            template <class T>1606            void foo(T t) {1607              $0^func($1^t);1608            }1609        )cpp",1610        "0: targets = {ns1::func, ns2::func}\n"1611        "1: targets = {t}\n"},1612       // Handle UnresolvedMemberExpr.1613       {R"cpp(1614            struct X {1615              void func(char*);1616              void func(int*);1617            };1618 1619            template <class T>1620            void foo(X x, T t) {1621              $0^x.$1^func($2^t);1622            }1623        )cpp",1624        "0: targets = {x}\n"1625        "1: targets = {X::func, X::func}\n"1626        "2: targets = {t}\n"},1627       // Handle DependentScopeDeclRefExpr.1628       {R"cpp(1629            template <class T>1630            struct S {1631              static int value;1632            };1633 1634            template <class T>1635            void foo() {1636              $0^S<$1^T>::$2^value;1637            }1638       )cpp",1639        "0: targets = {S}\n"1640        "1: targets = {T}\n"1641        "2: targets = {S::value}, qualifier = 'S<T>::'\n"},1642       // Handle CXXDependentScopeMemberExpr.1643       {R"cpp(1644            template <class T>1645            struct S {1646              int value;1647            };1648 1649            template <class T>1650            void foo(S<T> t) {1651              $0^t.$1^value;1652            }1653       )cpp",1654        "0: targets = {t}\n"1655        "1: targets = {S::value}\n"},1656       // Type template parameters.1657       {R"cpp(1658            template <class T>1659            void foo() {1660              static_cast<$0^T>(0);1661              $1^T();1662              $2^T $3^t;1663            }1664        )cpp",1665        "0: targets = {T}\n"1666        "1: targets = {T}\n"1667        "2: targets = {T}\n"1668        "3: targets = {t}, decl\n"},1669       // Non-type template parameters.1670       {R"cpp(1671            template <int I>1672            void foo() {1673              int $0^x = $1^I;1674            }1675        )cpp",1676        "0: targets = {x}, decl\n"1677        "1: targets = {I}\n"},1678       // Template template parameters.1679       {R"cpp(1680            template <class T> struct vector {};1681 1682            template <template<class> class TT, template<class> class ...TP>1683            void foo() {1684              $0^TT<int> $1^x;1685              $2^foo<$3^TT>();1686              $4^foo<$5^vector>();1687              $6^foo<$7^TP...>();1688            }1689        )cpp",1690        "0: targets = {TT}\n"1691        "1: targets = {x}, decl\n"1692        "2: targets = {foo}\n"1693        "3: targets = {TT}\n"1694        "4: targets = {foo}\n"1695        "5: targets = {vector}\n"1696        "6: targets = {foo}\n"1697        "7: targets = {TP}\n"},1698       // Non-type template parameters with declarations.1699       {R"cpp(1700            int func();1701            template <int(*)()> struct wrapper {};1702 1703            template <int(*FuncParam)()>1704            void foo() {1705              $0^wrapper<$1^func> $2^w;1706              $3^FuncParam();1707            }1708        )cpp",1709        "0: targets = {wrapper<&func>}\n"1710        "1: targets = {func}\n"1711        "2: targets = {w}, decl\n"1712        "3: targets = {FuncParam}\n"},1713       // declaration references.1714       {R"cpp(1715             namespace ns {}1716             class S {};1717             void foo() {1718               class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };1719               int $4^Var;1720               enum $5^E { $6^ABC };1721               typedef int $7^INT;1722               using $8^INT2 = int;1723               namespace $9^NS = $10^ns;1724             }1725           )cpp",1726        "0: targets = {Foo}, decl\n"1727        "1: targets = {foo()::Foo::Foo}, decl\n"1728        "2: targets = {Foo}\n"1729        "3: targets = {foo()::Foo::field}, decl\n"1730        "4: targets = {Var}, decl\n"1731        "5: targets = {E}, decl\n"1732        "6: targets = {foo()::ABC}, decl\n"1733        "7: targets = {INT}, decl\n"1734        "8: targets = {INT2}, decl\n"1735        "9: targets = {NS}, decl\n"1736        "10: targets = {ns}\n"},1737       // User-defined conversion operator.1738       {R"cpp(1739            void foo() {1740               class $0^Bar {};1741               class $1^Foo {1742               public:1743                 // FIXME: This should have only one reference to Bar.1744                 $2^operator $3^$4^Bar();1745               };1746 1747               $5^Foo $6^f;1748               $7^f.$8^operator $9^Bar();1749            }1750        )cpp",1751        "0: targets = {Bar}, decl\n"1752        "1: targets = {Foo}, decl\n"1753        "2: targets = {foo()::Foo::operator Bar}, decl\n"1754        "3: targets = {Bar}\n"1755        "4: targets = {Bar}\n"1756        "5: targets = {Foo}\n"1757        "6: targets = {f}, decl\n"1758        "7: targets = {f}\n"1759        "8: targets = {foo()::Foo::operator Bar}\n"1760        "9: targets = {Bar}\n"},1761       // Destructor.1762       {R"cpp(1763             void foo() {1764               class $0^Foo {1765               public:1766                 ~$1^Foo() {}1767 1768                 void $2^destructMe() {1769                   this->~$3^Foo();1770                 }1771               };1772 1773               $4^Foo $5^f;1774               $6^f.~ /*...*/ $7^Foo();1775             }1776           )cpp",1777        "0: targets = {Foo}, decl\n"1778        // FIXME: It's better to target destructor's FunctionDecl instead of1779        // the type itself (similar to constructor).1780        "1: targets = {Foo}\n"1781        "2: targets = {foo()::Foo::destructMe}, decl\n"1782        "3: targets = {Foo}\n"1783        "4: targets = {Foo}\n"1784        "5: targets = {f}, decl\n"1785        "6: targets = {f}\n"1786        "7: targets = {Foo}\n"},1787       // cxx constructor initializer.1788       {R"cpp(1789             class Base {};1790             void foo() {1791               // member initializer1792               class $0^X {1793                 int $1^abc;1794                 $2^X(): $3^abc() {}1795               };1796               // base initializer1797               class $4^Derived : public $5^Base {1798                 $6^Base $7^B;1799                 $8^Derived() : $9^Base() {}1800               };1801               // delegating initializer1802               class $10^Foo {1803                 $11^Foo(int);1804                 $12^Foo(): $13^Foo(111) {}1805               };1806             }1807           )cpp",1808        "0: targets = {X}, decl\n"1809        "1: targets = {foo()::X::abc}, decl\n"1810        "2: targets = {foo()::X::X}, decl\n"1811        "3: targets = {foo()::X::abc}\n"1812        "4: targets = {Derived}, decl\n"1813        "5: targets = {Base}\n"1814        "6: targets = {Base}\n"1815        "7: targets = {foo()::Derived::B}, decl\n"1816        "8: targets = {foo()::Derived::Derived}, decl\n"1817        "9: targets = {Base}\n"1818        "10: targets = {Foo}, decl\n"1819        "11: targets = {foo()::Foo::Foo}, decl\n"1820        "12: targets = {foo()::Foo::Foo}, decl\n"1821        "13: targets = {Foo}\n"},1822       // Anonymous entities should not be reported.1823       {1824           R"cpp(1825             void foo() {1826              $0^class {} $1^x;1827              int (*$2^fptr)(int $3^a, int) = nullptr;1828             }1829           )cpp",1830           "0: targets = {(unnamed)}\n"1831           "1: targets = {x}, decl\n"1832           "2: targets = {fptr}, decl\n"1833           "3: targets = {a}, decl\n"},1834       // Namespace aliases should be handled properly.1835       {1836           R"cpp(1837                namespace ns { struct Type {}; }1838                namespace alias = ns;1839                namespace rec_alias = alias;1840 1841                void foo() {1842                  $0^ns::$1^Type $2^a;1843                  $3^alias::$4^Type $5^b;1844                  $6^rec_alias::$7^Type $8^c;1845                }1846           )cpp",1847           "0: targets = {ns}\n"1848           "1: targets = {ns::Type}, qualifier = 'ns::'\n"1849           "2: targets = {a}, decl\n"1850           "3: targets = {alias}\n"1851           "4: targets = {ns::Type}, qualifier = 'alias::'\n"1852           "5: targets = {b}, decl\n"1853           "6: targets = {rec_alias}\n"1854           "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"1855           "8: targets = {c}, decl\n"},1856       // Handle SizeOfPackExpr.1857       {1858           R"cpp(1859                template <typename... E>1860                void foo() {1861                  constexpr int $0^size = sizeof...($1^E);1862                };1863            )cpp",1864           "0: targets = {size}, decl\n"1865           "1: targets = {E}\n"},1866       // Class template argument deduction1867       {1868           R"cpp(1869                template <typename T>1870                struct Test {1871                Test(T);1872              };1873              void foo() {1874                $0^Test $1^a(5);1875              }1876            )cpp",1877           "0: targets = {Test}\n"1878           "1: targets = {a}, decl\n"},1879       // Templates1880       {R"cpp(1881            namespace foo {1882              template <typename $0^T>1883              class $1^Bar {};1884            }1885          )cpp",1886        "0: targets = {foo::Bar::T}, decl\n"1887        "1: targets = {foo::Bar}, decl\n"},1888       // Templates1889       {R"cpp(1890            namespace foo {1891              template <typename $0^T>1892              void $1^func();1893            }1894          )cpp",1895        "0: targets = {T}, decl\n"1896        "1: targets = {foo::func}, decl\n"},1897       // Templates1898       {R"cpp(1899            namespace foo {1900              template <typename $0^T>1901              $1^T $2^x;1902            }1903          )cpp",1904        "0: targets = {foo::T}, decl\n"1905        "1: targets = {foo::T}\n"1906        "2: targets = {foo::x}, decl\n"},1907       // Templates1908       {R"cpp(1909            template<typename T> class vector {};1910            namespace foo {1911              template <typename $0^T>1912              using $1^V = $2^vector<$3^T>;1913            }1914          )cpp",1915        "0: targets = {foo::T}, decl\n"1916        "1: targets = {foo::V}, decl\n"1917        "2: targets = {vector}\n"1918        "3: targets = {foo::T}\n"},1919       // Concept1920       {1921           R"cpp(1922              template <typename T>1923              concept Drawable = requires (T t) { t.draw(); };1924 1925              namespace foo {1926                template <typename $0^T> requires $1^Drawable<$2^T>1927                void $3^bar($4^T $5^t) {1928                  $6^t.$7^draw();1929                }1930              }1931          )cpp",1932           "0: targets = {T}, decl\n"1933           "1: targets = {Drawable}\n"1934           "2: targets = {T}\n"1935           "3: targets = {foo::bar}, decl\n"1936           "4: targets = {T}\n"1937           "5: targets = {t}, decl\n"1938           "6: targets = {t}\n"1939           "7: targets = {}\n"},1940       // Objective-C: instance variables1941       {1942           R"cpp(1943            @interface I {1944            @public1945              I *_z;1946            }1947            @end1948            I *f;1949            void foo() {1950              $0^f->$1^_z = 0;1951            }1952          )cpp",1953           "0: targets = {f}\n"1954           "1: targets = {I::_z}\n"},1955       // Objective-C: properties1956       {1957           R"cpp(1958            @interface I {}1959            @property(retain) I* x;1960            @property(retain) I* y;1961            @end1962            I *f;1963            void foo() {1964              $0^f.$1^x.$2^y = 0;1965            }1966          )cpp",1967           "0: targets = {f}\n"1968           "1: targets = {I::x}\n"1969           "2: targets = {I::y}\n"},1970       // Objective-C: implicit properties1971       {1972           R"cpp(1973            @interface I {}1974            -(I*)x;1975            -(void)setY:(I*)y;1976            @end1977            I *f;1978            void foo() {1979              $0^f.$1^x.$2^y = 0;1980            }1981          )cpp",1982           "0: targets = {f}\n"1983           "1: targets = {I::x}\n"1984           "2: targets = {I::setY:}\n"},1985       // Objective-C: class properties1986       {1987           R"cpp(1988            @interface I {}1989            @property(class) I *x;1990            @end1991            id local;1992            void foo() {1993              $0^I.$1^x = 0;1994              $2^local = $3^I.$4^x;1995            }1996          )cpp",1997           "0: targets = {I}\n"1998           "1: targets = {I::setX:}\n"1999           "2: targets = {local}\n"2000           "3: targets = {I}\n"2001           "4: targets = {I::x}\n"},2002       // Objective-C: implicit class properties2003       {2004           R"cpp(2005            @interface I {}2006            +(I*)x;2007            +(void)setX:(I*)x;2008            @end2009            id local;2010            void foo() {2011              $0^I.$1^x = 0;2012              $2^local = $3^I.$4^x;2013            }2014          )cpp",2015           "0: targets = {I}\n"2016           "1: targets = {I::setX:}\n"2017           "2: targets = {local}\n"2018           "3: targets = {I}\n"2019           "4: targets = {I::x}\n"},2020       {// Objective-C: methods2021        R"cpp(2022            @interface I2023              -(void) a:(int)x b:(int)y;2024            @end2025            void foo(I *i) {2026              [$0^i $1^a:1 b:2];2027            }2028          )cpp",2029        "0: targets = {i}\n"2030        "1: targets = {I::a:b:}\n"},2031       {// Objective-C: protocols2032        R"cpp(2033            @interface I2034            @end2035            @protocol P2036            @end2037            void foo() {2038              $0^I<$1^P> *$2^x;2039            }2040          )cpp",2041        "0: targets = {I}\n"2042        "1: targets = {P}\n"2043        "2: targets = {x}, decl\n"},2044 2045       // Designated initializers.2046       {R"cpp(2047            void foo() {2048              struct $0^Foo {2049                int $1^Bar;2050              };2051              $2^Foo $3^f { .$4^Bar = 42 };2052            }2053        )cpp",2054        "0: targets = {Foo}, decl\n"2055        "1: targets = {foo()::Foo::Bar}, decl\n"2056        "2: targets = {Foo}\n"2057        "3: targets = {f}, decl\n"2058        "4: targets = {foo()::Foo::Bar}\n"},2059       {R"cpp(2060            void foo() {2061              struct $0^Baz {2062                int $1^Field;2063              };2064              struct $2^Bar {2065                $3^Baz $4^Foo;2066              };2067              $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };2068            }2069        )cpp",2070        "0: targets = {Baz}, decl\n"2071        "1: targets = {foo()::Baz::Field}, decl\n"2072        "2: targets = {Bar}, decl\n"2073        "3: targets = {Baz}\n"2074        "4: targets = {foo()::Bar::Foo}, decl\n"2075        "5: targets = {Bar}\n"2076        "6: targets = {bar}, decl\n"2077        "7: targets = {foo()::Bar::Foo}\n"2078        "8: targets = {foo()::Baz::Field}\n"},2079       {R"cpp(2080           template<typename T>2081           void crash(T);2082           template<typename T>2083           void foo() {2084             $0^crash({.$1^x = $2^T()});2085           }2086        )cpp",2087        "0: targets = {crash}\n"2088        "1: targets = {}\n"2089        "2: targets = {T}\n"},2090       // unknown template name should not crash.2091       {R"cpp(2092        template <template <typename> typename T>2093        struct Base {};2094        namespace foo {2095        template <typename $0^T>2096        struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};2097        }2098      )cpp",2099        "0: targets = {foo::Derive::T}, decl\n"2100        "1: targets = {foo::Derive}, decl\n"2101        "2: targets = {Base}\n"2102        "3: targets = {foo::Derive::T}\n"2103        "4: targets = {}, qualifier = 'T::'\n"},2104       // deduction guide2105       {R"cpp(2106          namespace foo {2107            template <typename $0^T>2108            struct $1^Test {2109              template <typename $2^I>2110              $3^Test($4^I);2111            };2112            template <typename $5^I>2113            $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;2114          }2115        )cpp",2116        "0: targets = {T}, decl\n"2117        "1: targets = {foo::Test}, decl\n"2118        "2: targets = {I}, decl\n"2119        "3: targets = {foo::Test::Test<T>}, decl\n"2120        "4: targets = {I}\n"2121        "5: targets = {I}, decl\n"2122        "6: targets = {foo::Test}\n"2123        "7: targets = {I}\n"2124        "8: targets = {foo::Test}\n"2125        "9: targets = {I}\n"2126        "10: targets = {}, qualifier = 'I::'\n"}};2127 2128  for (const auto &C : Cases) {2129    llvm::StringRef ExpectedCode = C.first;2130    llvm::StringRef ExpectedRefs = C.second;2131 2132    auto Actual =2133        annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());2134    EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);2135    EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;2136  }2137}2138 2139TEST_F(FindExplicitReferencesTest, AllRefs) {2140  std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =2141      {{R"cpp(2142      @interface $0^MyClass2143      @end2144      @implementation $1^$2^MyClass2145      @end2146      )cpp",2147        "0: targets = {MyClass}, decl\n"2148        "1: targets = {MyClass}\n"2149        "2: targets = {MyClass}, decl\n"},2150       {R"cpp(2151      @interface $0^MyClass2152      @end2153      @interface $1^MyClass ($2^Category)2154      @end2155      @implementation $3^MyClass ($4^$5^Category)2156      @end2157      )cpp",2158        "0: targets = {MyClass}, decl\n"2159        "1: targets = {MyClass}\n"2160        "2: targets = {Category}, decl\n"2161        "3: targets = {MyClass}\n"2162        "4: targets = {Category}\n"2163        "5: targets = {Category}, decl\n"}};2164 2165  for (const auto &C : Cases) {2166    llvm::StringRef ExpectedCode = C.first;2167    llvm::StringRef ExpectedRefs = C.second;2168 2169    auto Actual = annotateAllReferences(llvm::Annotations(ExpectedCode).code());2170    EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);2171    EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;2172  }2173}2174 2175} // namespace2176} // namespace clangd2177} // namespace clang2178