clang-tools  10.0.0git
FindTargetTests.cpp
Go to the documentation of this file.
1 //===-- FindSymbolsTests.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-exception
6 //
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/Support/Annotations.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include <initializer_list>
22 
23 namespace clang {
24 namespace clangd {
25 namespace {
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 case
30 // that's both expressive and unambiguous (e.g. clearly distinguishes between
31 // templated decls and their specializations).
32 //
33 // We use the result of pretty-printing the decl, with the {body} truncated.
34 struct 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 = FirstLine.rtrim(" {");
46  }
47 
48  std::string Name;
49  DeclRelationSet Relations;
50 };
51 bool operator==(const PrintedDecl &L, const PrintedDecl &R) {
52  return std::tie(L.Name, L.Relations) == std::tie(R.Name, R.Relations);
53 }
54 llvm::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 form
59 // - 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, and
62 // all the decls that targetDecl() considers it to reference
63 // Despite the name, these cases actually test allTargetDecls() for brevity.
64 class TargetDeclTest : public ::testing::Test {
65 protected:
66  using Rel = DeclRelation;
67  std::string Code;
68  std::vector<const char *> 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  EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty()) << Code;
79  llvm::Annotations::Range R = A.range();
80  SelectionTree Selection(AST.getASTContext(), AST.getTokens(), R.Begin,
81  R.End);
82  const SelectionTree::Node *N = Selection.commonAncestor();
83  if (!N) {
84  ADD_FAILURE() << "No node selected!\n" << Code;
85  return {};
86  }
87  EXPECT_EQ(N->kind(), NodeType) << Selection;
88 
89  std::vector<PrintedDecl> ActualDecls;
90  for (const auto &Entry : allTargetDecls(N->ASTNode))
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  << Code
103 using ExpectedDecls = std::vector<PrintedDecl>;
104 
105 TEST_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 
136 TEST_F(TargetDeclTest, UsingDecl) {
137  Code = R"cpp(
138  namespace foo {
139  int f(int);
140  int f(char);
141  }
142  using foo::f;
143  int x = [[f]](42);
144  )cpp";
145  // f(char) is not referenced!
146  EXPECT_DECLS("DeclRefExpr", {"using foo::f", Rel::Alias},
147  {"int f(int)", Rel::Underlying});
148 
149  Code = R"cpp(
150  namespace foo {
151  int f(int);
152  int f(char);
153  }
154  [[using foo::f]];
155  )cpp";
156  // All overloads are referenced.
157  EXPECT_DECLS("UsingDecl", {"using foo::f", Rel::Alias},
158  {"int f(int)", Rel::Underlying},
159  {"int f(char)", Rel::Underlying});
160 
161  Code = R"cpp(
162  struct X {
163  int foo();
164  };
165  struct Y : X {
166  using X::foo;
167  };
168  int x = Y().[[foo]]();
169  )cpp";
170  EXPECT_DECLS("MemberExpr", {"using X::foo", Rel::Alias},
171  {"int foo()", Rel::Underlying});
172 }
173 
174 TEST_F(TargetDeclTest, ConstructorInitList) {
175  Code = R"cpp(
176  struct X {
177  int a;
178  X() : [[a]](42) {}
179  };
180  )cpp";
181  EXPECT_DECLS("CXXCtorInitializer", "int a");
182 
183  Code = R"cpp(
184  struct X {
185  X() : [[X]](1) {}
186  X(int);
187  };
188  )cpp";
189  EXPECT_DECLS("RecordTypeLoc", "struct X");
190 }
191 
192 TEST_F(TargetDeclTest, DesignatedInit) {
193  Flags = {"-xc"}; // array designators are a C99 extension.
194  Code = R"c(
195  struct X { int a; };
196  struct Y { int b; struct X c[2]; };
197  struct Y y = { .c[0].[[a]] = 1 };
198  )c";
199  EXPECT_DECLS("DesignatedInitExpr", "int a");
200 }
201 
202 TEST_F(TargetDeclTest, NestedNameSpecifier) {
203  Code = R"cpp(
204  namespace a { namespace b { int c; } }
205  int x = a::[[b::]]c;
206  )cpp";
207  EXPECT_DECLS("NestedNameSpecifierLoc", "namespace b");
208 
209  Code = R"cpp(
210  namespace a { struct X { enum { y }; }; }
211  int x = a::[[X::]]y;
212  )cpp";
213  EXPECT_DECLS("NestedNameSpecifierLoc", "struct X");
214 
215  Code = R"cpp(
216  template <typename T>
217  int x = [[T::]]y;
218  )cpp";
219  // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently!
220  EXPECT_DECLS("NestedNameSpecifierLoc", "");
221 
222  Code = R"cpp(
223  namespace a { int x; }
224  namespace b = a;
225  int y = [[b]]::x;
226  )cpp";
227  EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},
228  {"namespace a", Rel::Underlying});
229 }
230 
231 TEST_F(TargetDeclTest, Types) {
232  Code = R"cpp(
233  struct X{};
234  [[X]] x;
235  )cpp";
236  EXPECT_DECLS("RecordTypeLoc", "struct X");
237 
238  Code = R"cpp(
239  struct S{};
240  typedef S X;
241  [[X]] x;
242  )cpp";
243  EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},
244  {"struct S", Rel::Underlying});
245 
246  // FIXME: Auto-completion in a template requires disabling delayed template
247  // parsing.
248  Flags = {"-fno-delayed-template-parsing"};
249  Code = R"cpp(
250  template<class T>
251  void foo() { [[T]] x; }
252  )cpp";
253  // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently!
254  EXPECT_DECLS("TemplateTypeParmTypeLoc", "");
255  Flags.clear();
256 
257  // FIXME: Auto-completion in a template requires disabling delayed template
258  // parsing.
259  Flags = {"-fno-delayed-template-parsing"};
260  Code = R"cpp(
261  template<template<typename> class T>
262  void foo() { [[T<int>]] x; }
263  )cpp";
264  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class T");
265  Flags.clear();
266 
267  Code = R"cpp(
268  struct S{};
269  S X;
270  [[decltype]](X) Y;
271  )cpp";
272  EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});
273 
274  Code = R"cpp(
275  struct S{};
276  [[auto]] X = S{};
277  )cpp";
278  // FIXME: deduced type missing in AST. https://llvm.org/PR42914
279  EXPECT_DECLS("AutoTypeLoc");
280 
281  Code = R"cpp(
282  template <typename... E>
283  struct S {
284  static const int size = sizeof...([[E]]);
285  };
286  )cpp";
287  // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently!
288  EXPECT_DECLS("SizeOfPackExpr", "");
289 }
290 
291 TEST_F(TargetDeclTest, ClassTemplate) {
292  Code = R"cpp(
293  // Implicit specialization.
294  template<int x> class Foo{};
295  [[Foo<42>]] B;
296  )cpp";
297  EXPECT_DECLS("TemplateSpecializationTypeLoc",
298  {"template<> class Foo<42>", Rel::TemplateInstantiation},
299  {"class Foo", Rel::TemplatePattern});
300 
301  Code = R"cpp(
302  // Explicit specialization.
303  template<int x> class Foo{};
304  template<> class Foo<42>{};
305  [[Foo<42>]] B;
306  )cpp";
307  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template<> class Foo<42>");
308 
309  Code = R"cpp(
310  // Partial specialization.
311  template<typename T> class Foo{};
312  template<typename T> class Foo<T*>{};
313  [[Foo<int*>]] B;
314  )cpp";
315  EXPECT_DECLS("TemplateSpecializationTypeLoc",
316  {"template<> class Foo<int *>", Rel::TemplateInstantiation},
317  {"template <typename T> class Foo<T *>", Rel::TemplatePattern});
318 
319  Code = R"cpp(
320  // Class template argument deduction
321  template <typename T>
322  struct Test {
323  Test(T);
324  };
325  void foo() {
326  [[Test]] a(5);
327  }
328  )cpp";
329  Flags.push_back("-std=c++17");
330  EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
331  {"struct Test", Rel::TemplatePattern});
332 }
333 
334 TEST_F(TargetDeclTest, FunctionTemplate) {
335  Code = R"cpp(
336  // Implicit specialization.
337  template<typename T> bool foo(T) { return false; };
338  bool x = [[foo]](42);
339  )cpp";
340  EXPECT_DECLS("DeclRefExpr",
341  {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
342  {"bool foo(T)", Rel::TemplatePattern});
343 
344  Code = R"cpp(
345  // Explicit specialization.
346  template<typename T> bool foo(T) { return false; };
347  template<> bool foo<int>(int) { return false; };
348  bool x = [[foo]](42);
349  )cpp";
350  EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");
351 }
352 
353 TEST_F(TargetDeclTest, VariableTemplate) {
354  // Pretty-printer doesn't do a very good job of variable templates :-(
355  Code = R"cpp(
356  // Implicit specialization.
357  template<typename T> int foo;
358  int x = [[foo]]<char>;
359  )cpp";
360  EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},
361  {"int foo", Rel::TemplatePattern});
362 
363  Code = R"cpp(
364  // Explicit specialization.
365  template<typename T> int foo;
366  template <> bool foo<char>;
367  int x = [[foo]]<char>;
368  )cpp";
369  EXPECT_DECLS("DeclRefExpr", "bool foo");
370 
371  Code = R"cpp(
372  // Partial specialization.
373  template<typename T> int foo;
374  template<typename T> bool foo<T*>;
375  bool x = [[foo]]<char*>;
376  )cpp";
377  EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},
378  {"bool foo", Rel::TemplatePattern});
379 }
380 
381 TEST_F(TargetDeclTest, TypeAliasTemplate) {
382  Code = R"cpp(
383  template<typename T, int X> class SmallVector {};
384  template<typename U> using TinyVector = SmallVector<U, 1>;
385  [[TinyVector<int>]] X;
386  )cpp";
387  EXPECT_DECLS("TemplateSpecializationTypeLoc",
388  {"template<> class SmallVector<int, 1>",
390  {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
391  {"using TinyVector = SmallVector<U, 1>",
393 }
394 
395 TEST_F(TargetDeclTest, MemberOfTemplate) {
396  Code = R"cpp(
397  template <typename T> struct Foo {
398  int x(T);
399  };
400  int y = Foo<int>().[[x]](42);
401  )cpp";
402  EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},
403  {"int x(T)", Rel::TemplatePattern});
404 
405  Code = R"cpp(
406  template <typename T> struct Foo {
407  template <typename U>
408  int x(T, U);
409  };
410  int y = Foo<char>().[[x]]('c', 42);
411  )cpp";
412  EXPECT_DECLS("MemberExpr",
413  {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
414  {"int x(T, U)", Rel::TemplatePattern});
415 }
416 
417 TEST_F(TargetDeclTest, Lambda) {
418  Code = R"cpp(
419  void foo(int x = 42) {
420  auto l = [ [[x]] ]{ return x + 1; };
421  };
422  )cpp";
423  EXPECT_DECLS("DeclRefExpr", "int x = 42");
424 
425  // It seems like this should refer to another var, with the outer param being
426  // an underlying decl. But it doesn't seem to exist.
427  Code = R"cpp(
428  void foo(int x = 42) {
429  auto l = [x]{ return [[x]] + 1; };
430  };
431  )cpp";
432  EXPECT_DECLS("DeclRefExpr", "int x = 42");
433 
434  Code = R"cpp(
435  void foo() {
436  auto l = [x = 1]{ return [[x]] + 1; };
437  };
438  )cpp";
439  // FIXME: why both auto and int?
440  EXPECT_DECLS("DeclRefExpr", "auto int x = 1");
441 }
442 
443 TEST_F(TargetDeclTest, OverloadExpr) {
444  // FIXME: Auto-completion in a template requires disabling delayed template
445  // parsing.
446  Flags = {"-fno-delayed-template-parsing"};
447 
448  Code = R"cpp(
449  void func(int*);
450  void func(char*);
451 
452  template <class T>
453  void foo(T t) {
454  [[func]](t);
455  };
456  )cpp";
457  EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");
458 
459  Code = R"cpp(
460  struct X {
461  void func(int*);
462  void func(char*);
463  };
464 
465  template <class T>
466  void foo(X x, T t) {
467  x.[[func]](t);
468  };
469  )cpp";
470  EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");
471 }
472 
473 TEST_F(TargetDeclTest, ObjC) {
474  Flags = {"-xobjective-c"};
475  Code = R"cpp(
476  @interface Foo {}
477  -(void)bar;
478  @end
479  void test(Foo *f) {
480  [f [[bar]] ];
481  }
482  )cpp";
483  EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");
484 
485  Code = R"cpp(
486  @interface Foo { @public int bar; }
487  @end
488  int test(Foo *f) {
489  return [[f->bar]];
490  }
491  )cpp";
492  EXPECT_DECLS("ObjCIvarRefExpr", "int bar");
493 
494  Code = R"cpp(
495  @interface Foo {}
496  -(int) x;
497  -(void) setX:(int)x;
498  @end
499  void test(Foo *f) {
500  [[f.x]] = 42;
501  }
502  )cpp";
503  EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");
504 
505  Code = R"cpp(
506  @interface I {}
507  @property(retain) I* x;
508  @property(retain) I* y;
509  @end
510  void test(I *f) {
511  [[f.x]].y = 0;
512  }
513  )cpp";
514  EXPECT_DECLS("OpaqueValueExpr", "@property(atomic, retain, readwrite) I *x");
515 
516  Code = R"cpp(
517  @protocol Foo
518  @end
519  id test() {
520  return [[@protocol(Foo)]];
521  }
522  )cpp";
523  EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");
524 
525  Code = R"cpp(
526  @interface Foo
527  @end
528  void test([[Foo]] *p);
529  )cpp";
530  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
531 
532  Code = R"cpp(
533  @protocol Foo
534  @end
535  void test([[id<Foo>]] p);
536  )cpp";
537  EXPECT_DECLS("ObjCObjectTypeLoc", "@protocol Foo");
538 
539  Code = R"cpp(
540  @class C;
541  @protocol Foo
542  @end
543  void test(C<[[Foo]]> *p);
544  )cpp";
545  // FIXME: there's no AST node corresponding to 'Foo', so we're stuck.
546  EXPECT_DECLS("ObjCObjectTypeLoc");
547 }
548 
549 class FindExplicitReferencesTest : public ::testing::Test {
550 protected:
551  struct AllRefs {
552  std::string AnnotatedCode;
553  std::string DumpedReferences;
554  };
555 
556  /// Parses \p Code, finds function '::foo' and annotates its body with results
557  /// of findExplicitReferecnces.
558  /// See actual tests for examples of annotation format.
559  AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
560  TestTU TU;
561  TU.Code = Code;
562 
563  // FIXME: Auto-completion in a template requires disabling delayed template
564  // parsing.
565  TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
566  TU.ExtraArgs.push_back("-std=c++17");
567 
568  auto AST = TU.build();
569  for (auto &D : AST.getDiagnostics()) {
570  if (D.Severity > DiagnosticsEngine::Warning)
571  ADD_FAILURE() << D << Code;
572  }
573 
574  auto *TestDecl = &findDecl(AST, "foo");
575  if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
576  TestDecl = T->getTemplatedDecl();
577  auto &Func = llvm::cast<FunctionDecl>(*TestDecl);
578 
579  std::vector<ReferenceLoc> Refs;
580  findExplicitReferences(Func.getBody(), [&Refs](ReferenceLoc R) {
581  Refs.push_back(std::move(R));
582  });
583 
584  auto &SM = AST.getSourceManager();
585  llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
586  return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
587  });
588 
589  std::string AnnotatedCode;
590  unsigned NextCodeChar = 0;
591  for (unsigned I = 0; I < Refs.size(); ++I) {
592  auto &R = Refs[I];
593 
594  SourceLocation Pos = R.NameLoc;
595  assert(Pos.isValid());
596  if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.
597  Pos = SM.getExpansionLoc(Pos);
598  assert(Pos.isFileID());
599 
600  FileID File;
601  unsigned Offset;
602  std::tie(File, Offset) = SM.getDecomposedLoc(Pos);
603  if (File == SM.getMainFileID()) {
604  // Print the reference in a source code.
605  assert(NextCodeChar <= Offset);
606  AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
607  AnnotatedCode += "$" + std::to_string(I) + "^";
608 
609  NextCodeChar = Offset;
610  }
611  }
612  AnnotatedCode += Code.substr(NextCodeChar);
613 
614  std::string DumpedReferences;
615  for (unsigned I = 0; I < Refs.size(); ++I)
616  DumpedReferences += llvm::formatv("{0}: {1}\n", I, Refs[I]);
617 
618  return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
619  }
620 };
621 
622 TEST_F(FindExplicitReferencesTest, All) {
623  std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
624  {// Simple expressions.
625  {R"cpp(
626  int global;
627  int func();
628  void foo(int param) {
629  $0^global = $1^param + $2^func();
630  }
631  )cpp",
632  "0: targets = {global}\n"
633  "1: targets = {param}\n"
634  "2: targets = {func}\n"},
635  {R"cpp(
636  struct X { int a; };
637  void foo(X x) {
638  $0^x.$1^a = 10;
639  }
640  )cpp",
641  "0: targets = {x}\n"
642  "1: targets = {X::a}\n"},
643  // Namespaces and aliases.
644  {R"cpp(
645  namespace ns {}
646  namespace alias = ns;
647  void foo() {
648  using namespace $0^ns;
649  using namespace $1^alias;
650  }
651  )cpp",
652  "0: targets = {ns}\n"
653  "1: targets = {alias}\n"},
654  // Using declarations.
655  {R"cpp(
656  namespace ns { int global; }
657  void foo() {
658  using $0^ns::$1^global;
659  }
660  )cpp",
661  "0: targets = {ns}\n"
662  "1: targets = {ns::global}, qualifier = 'ns::'\n"},
663  // Simple types.
664  {R"cpp(
665  struct Struct { int a; };
666  using Typedef = int;
667  void foo() {
668  $0^Struct $1^x;
669  $2^Typedef $3^y;
670  static_cast<$4^Struct*>(0);
671  }
672  )cpp",
673  "0: targets = {Struct}\n"
674  "1: targets = {x}, decl\n"
675  "2: targets = {Typedef}\n"
676  "3: targets = {y}, decl\n"
677  "4: targets = {Struct}\n"},
678  // Name qualifiers.
679  {R"cpp(
680  namespace a { namespace b { struct S { typedef int type; }; } }
681  void foo() {
682  $0^a::$1^b::$2^S $3^x;
683  using namespace $4^a::$5^b;
684  $6^S::$7^type $8^y;
685  }
686  )cpp",
687  "0: targets = {a}\n"
688  "1: targets = {a::b}, qualifier = 'a::'\n"
689  "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
690  "3: targets = {x}, decl\n"
691  "4: targets = {a}\n"
692  "5: targets = {a::b}, qualifier = 'a::'\n"
693  "6: targets = {a::b::S}\n"
694  "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
695  "8: targets = {y}, decl\n"},
696  // Simple templates.
697  {R"cpp(
698  template <class T> struct vector { using value_type = T; };
699  template <> struct vector<bool> { using value_type = bool; };
700  void foo() {
701  $0^vector<int> $1^vi;
702  $2^vector<bool> $3^vb;
703  }
704  )cpp",
705  "0: targets = {vector<int>}\n"
706  "1: targets = {vi}, decl\n"
707  "2: targets = {vector<bool>}\n"
708  "3: targets = {vb}, decl\n"},
709  // Template type aliases.
710  {R"cpp(
711  template <class T> struct vector { using value_type = T; };
712  template <> struct vector<bool> { using value_type = bool; };
713  template <class T> using valias = vector<T>;
714  void foo() {
715  $0^valias<int> $1^vi;
716  $2^valias<bool> $3^vb;
717  }
718  )cpp",
719  "0: targets = {valias}\n"
720  "1: targets = {vi}, decl\n"
721  "2: targets = {valias}\n"
722  "3: targets = {vb}, decl\n"},
723  // MemberExpr should know their using declaration.
724  {R"cpp(
725  struct X { void func(int); };
726  struct Y : X {
727  using X::func;
728  };
729  void foo(Y y) {
730  $0^y.$1^func(1);
731  }
732  )cpp",
733  "0: targets = {y}\n"
734  "1: targets = {Y::func}\n"},
735  // DeclRefExpr should know their using declaration.
736  {R"cpp(
737  namespace ns { void bar(int); }
738  using ns::bar;
739 
740  void foo() {
741  $0^bar(10);
742  }
743  )cpp",
744  "0: targets = {bar}\n"},
745  // References from a macro.
746  {R"cpp(
747  #define FOO a
748  #define BAR b
749 
750  void foo(int a, int b) {
751  $0^FOO+$1^BAR;
752  }
753  )cpp",
754  "0: targets = {a}\n"
755  "1: targets = {b}\n"},
756  // No references from implicit nodes.
757  {R"cpp(
758  struct vector {
759  int *begin();
760  int *end();
761  };
762 
763  void foo() {
764  for (int $0^x : $1^vector()) {
765  $2^x = 10;
766  }
767  }
768  )cpp",
769  "0: targets = {x}, decl\n"
770  "1: targets = {vector}\n"
771  "2: targets = {x}\n"},
772  // Handle UnresolvedLookupExpr.
773  {R"cpp(
774  namespace ns1 { void func(char*); }
775  namespace ns2 { void func(int*); }
776  using namespace ns1;
777  using namespace ns2;
778 
779  template <class T>
780  void foo(T t) {
781  $0^func($1^t);
782  }
783  )cpp",
784  "0: targets = {ns1::func, ns2::func}\n"
785  "1: targets = {t}\n"},
786  // Handle UnresolvedMemberExpr.
787  {R"cpp(
788  struct X {
789  void func(char*);
790  void func(int*);
791  };
792 
793  template <class T>
794  void foo(X x, T t) {
795  $0^x.$1^func($2^t);
796  }
797  )cpp",
798  "0: targets = {x}\n"
799  "1: targets = {X::func, X::func}\n"
800  "2: targets = {t}\n"},
801  // Type template parameters.
802  {R"cpp(
803  template <class T>
804  void foo() {
805  static_cast<$0^T>(0);
806  $1^T();
807  $2^T $3^t;
808  }
809  )cpp",
810  "0: targets = {T}\n"
811  "1: targets = {T}\n"
812  "2: targets = {T}\n"
813  "3: targets = {t}, decl\n"},
814  // Non-type template parameters.
815  {R"cpp(
816  template <int I>
817  void foo() {
818  int $0^x = $1^I;
819  }
820  )cpp",
821  "0: targets = {x}, decl\n"
822  "1: targets = {I}\n"},
823  // Template template parameters.
824  {R"cpp(
825  template <class T> struct vector {};
826 
827  template <template<class> class TT, template<class> class ...TP>
828  void foo() {
829  $0^TT<int> $1^x;
830  $2^foo<$3^TT>();
831  $4^foo<$5^vector>();
832  $6^foo<$7^TP...>();
833  }
834  )cpp",
835  "0: targets = {TT}\n"
836  "1: targets = {x}, decl\n"
837  "2: targets = {foo}\n"
838  "3: targets = {TT}\n"
839  "4: targets = {foo}\n"
840  "5: targets = {vector}\n"
841  "6: targets = {foo}\n"
842  "7: targets = {TP}\n"},
843  // Non-type template parameters with declarations.
844  {R"cpp(
845  int func();
846  template <int(*)()> struct wrapper {};
847 
848  template <int(*FuncParam)()>
849  void foo() {
850  $0^wrapper<$1^func> $2^w;
851  $3^FuncParam();
852  }
853  )cpp",
854  "0: targets = {wrapper<&func>}\n"
855  "1: targets = {func}\n"
856  "2: targets = {w}, decl\n"
857  "3: targets = {FuncParam}\n"},
858  // declaration references.
859  {R"cpp(
860  namespace ns {}
861  class S {};
862  void foo() {
863  class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
864  int $4^Var;
865  enum $5^E { $6^ABC };
866  typedef int $7^INT;
867  using $8^INT2 = int;
868  namespace $9^NS = $10^ns;
869  }
870  )cpp",
871  "0: targets = {Foo}, decl\n"
872  "1: targets = {foo()::Foo::Foo}, decl\n"
873  "2: targets = {Foo}\n"
874  "3: targets = {foo()::Foo::field}, decl\n"
875  "4: targets = {Var}, decl\n"
876  "5: targets = {E}, decl\n"
877  "6: targets = {foo()::ABC}, decl\n"
878  "7: targets = {INT}, decl\n"
879  "8: targets = {INT2}, decl\n"
880  "9: targets = {NS}, decl\n"
881  "10: targets = {ns}\n"},
882  // cxx constructor initializer.
883  {R"cpp(
884  class Base {};
885  void foo() {
886  // member initializer
887  class $0^X {
888  int $1^abc;
889  $2^X(): $3^abc() {}
890  };
891  // base initializer
892  class $4^Derived : public $5^Base {
893  $6^Base $7^B;
894  $8^Derived() : $9^Base() {}
895  };
896  // delegating initializer
897  class $10^Foo {
898  $11^Foo(int);
899  $12^Foo(): $13^Foo(111) {}
900  };
901  }
902  )cpp",
903  "0: targets = {X}, decl\n"
904  "1: targets = {foo()::X::abc}, decl\n"
905  "2: targets = {foo()::X::X}, decl\n"
906  "3: targets = {foo()::X::abc}\n"
907  "4: targets = {Derived}, decl\n"
908  "5: targets = {Base}\n"
909  "6: targets = {Base}\n"
910  "7: targets = {foo()::Derived::B}, decl\n"
911  "8: targets = {foo()::Derived::Derived}, decl\n"
912  "9: targets = {Base}\n"
913  "10: targets = {Foo}, decl\n"
914  "11: targets = {foo()::Foo::Foo}, decl\n"
915  "12: targets = {foo()::Foo::Foo}, decl\n"
916  "13: targets = {Foo}\n"},
917  // Anonymous entities should not be reported.
918  {
919  R"cpp(
920  void foo() {
921  class {} $0^x;
922  int (*$1^fptr)(int $2^a, int) = nullptr;
923  }
924  )cpp",
925  "0: targets = {x}, decl\n"
926  "1: targets = {fptr}, decl\n"
927  "2: targets = {a}, decl\n"},
928  // Namespace aliases should be handled properly.
929  {
930  R"cpp(
931  namespace ns { struct Type {}; }
932  namespace alias = ns;
933  namespace rec_alias = alias;
934 
935  void foo() {
936  $0^ns::$1^Type $2^a;
937  $3^alias::$4^Type $5^b;
938  $6^rec_alias::$7^Type $8^c;
939  }
940  )cpp",
941  "0: targets = {ns}\n"
942  "1: targets = {ns::Type}, qualifier = 'ns::'\n"
943  "2: targets = {a}, decl\n"
944  "3: targets = {alias}\n"
945  "4: targets = {ns::Type}, qualifier = 'alias::'\n"
946  "5: targets = {b}, decl\n"
947  "6: targets = {rec_alias}\n"
948  "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
949  "8: targets = {c}, decl\n"},
950  // Handle SizeOfPackExpr.
951  {
952  R"cpp(
953  template <typename... E>
954  void foo() {
955  constexpr int $0^size = sizeof...($1^E);
956  };
957  )cpp",
958  "0: targets = {size}, decl\n"
959  "1: targets = {E}\n"},
960  // Class template argument deduction
961  {
962  R"cpp(
963  template <typename T>
964  struct Test {
965  Test(T);
966  };
967  void foo() {
968  $0^Test $1^a(5);
969  }
970  )cpp",
971  "0: targets = {Test}\n"
972  "1: targets = {a}, decl\n"}};
973 
974  for (const auto &C : Cases) {
975  llvm::StringRef ExpectedCode = C.first;
976  llvm::StringRef ExpectedRefs = C.second;
977 
978  auto Actual =
979  annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
980  EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
981  EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
982  }
983 }
984 
985 } // namespace
986 } // namespace clangd
987 } // namespace clang
std::string Code
bool operator==(const HoverInfo::Param &LHS, const HoverInfo::Param &RHS)
Definition: Hover.h:78
llvm::SmallVector< std::pair< const NamedDecl *, DeclRelationSet >, 1 > allTargetDecls(const ast_type_traits::DynTypedNode &N)
Similar to targetDecl(), however instead of applying a filter, all possible decls are returned along ...
Definition: FindTarget.cpp:469
std::string Name
std::string DumpedReferences
This is the pattern the template specialization was instantiated from.
std::vector< const char * > Flags
#define EXPECT_DECLS(NodeType,...)
This declaration is an alias that was referred to.
std::vector< const char * > ExtraArgs
Definition: TestTU.h:57
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
This is the template instantiation that was referred to.
Position Pos
Definition: SourceCode.cpp:772
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
size_t Offset
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void findExplicitReferences(const Stmt *S, llvm::function_ref< void(ReferenceLoc)> Out)
Recursively traverse S and report all references explicitly written in the code.
Definition: FindTarget.cpp:850
This is the underlying declaration for an alias, decltype etc.
DeclRelationSet Relations
CharSourceRange Range
SourceRange for the file name.
RefSlab Refs
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
std::string AnnotatedCode
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:118