clang-tools  11.0.0git
FindTargetTests.cpp
Go to the documentation of this file.
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-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 = std::string(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<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 : allTargetDecls(N->ASTNode))
90  ActualDecls.emplace_back(Entry.first, Entry.second);
91  return ActualDecls;
92  }
93 };
94 
95 // This is a macro to preserve line numbers in assertion failures.
96 // It takes the expected decls as varargs to work around comma-in-macro issues.
97 #define EXPECT_DECLS(NodeType, ...) \
98  EXPECT_THAT(assertNodeAndPrintDecls(NodeType), \
99  ::testing::UnorderedElementsAreArray( \
100  std::vector<PrintedDecl>({__VA_ARGS__}))) \
101  << Code
102 using ExpectedDecls = std::vector<PrintedDecl>;
103 
104 TEST_F(TargetDeclTest, Exprs) {
105  Code = R"cpp(
106  int f();
107  int x = [[f]]();
108  )cpp";
109  EXPECT_DECLS("DeclRefExpr", "int f()");
110 
111  Code = R"cpp(
112  struct S { S operator+(S) const; };
113  auto X = S() [[+]] S();
114  )cpp";
115  EXPECT_DECLS("DeclRefExpr", "S operator+(S) const");
116 
117  Code = R"cpp(
118  int foo();
119  int s = foo[[()]];
120  )cpp";
121  EXPECT_DECLS("CallExpr", "int foo()");
122 
123  Code = R"cpp(
124  struct X {
125  void operator()(int n);
126  };
127  void test() {
128  X x;
129  x[[(123)]];
130  }
131  )cpp";
132  EXPECT_DECLS("CXXOperatorCallExpr", "void operator()(int n)");
133 
134  Code = R"cpp(
135  void test() {
136  goto [[label]];
137  label:
138  return;
139  }
140  )cpp";
141  EXPECT_DECLS("GotoStmt", "label:");
142  Code = R"cpp(
143  void test() {
144  [[label]]:
145  return;
146  }
147  )cpp";
148  EXPECT_DECLS("LabelStmt", "label:");
149 }
150 
151 TEST_F(TargetDeclTest, Recovery) {
152  Code = R"cpp(
153  // error-ok: testing behavior on broken code
154  int f();
155  int f(int, int);
156  int x = [[f]](42);
157  )cpp";
158  EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)");
159 }
160 
161 TEST_F(TargetDeclTest, RecoveryType) {
162  Code = R"cpp(
163  // error-ok: testing behavior on broken code
164  struct S { int member; };
165  S overloaded(int);
166  void foo() {
167  // No overload matches, but we have recovery-expr with the correct type.
168  overloaded().[[member]];
169  }
170  )cpp";
171  EXPECT_DECLS("MemberExpr", "int member");
172 }
173 
174 TEST_F(TargetDeclTest, UsingDecl) {
175  Code = R"cpp(
176  namespace foo {
177  int f(int);
178  int f(char);
179  }
180  using foo::f;
181  int x = [[f]](42);
182  )cpp";
183  // f(char) is not referenced!
184  EXPECT_DECLS("DeclRefExpr", {"using foo::f", Rel::Alias},
185  {"int f(int)", Rel::Underlying});
186 
187  Code = R"cpp(
188  namespace foo {
189  int f(int);
190  int f(char);
191  }
192  [[using foo::f]];
193  )cpp";
194  // All overloads are referenced.
195  EXPECT_DECLS("UsingDecl", {"using foo::f", Rel::Alias},
196  {"int f(int)", Rel::Underlying},
197  {"int f(char)", Rel::Underlying});
198 
199  Code = R"cpp(
200  struct X {
201  int foo();
202  };
203  struct Y : X {
204  using X::foo;
205  };
206  int x = Y().[[foo]]();
207  )cpp";
208  EXPECT_DECLS("MemberExpr", {"using X::foo", Rel::Alias},
209  {"int foo()", Rel::Underlying});
210 }
211 
212 TEST_F(TargetDeclTest, ConstructorInitList) {
213  Code = R"cpp(
214  struct X {
215  int a;
216  X() : [[a]](42) {}
217  };
218  )cpp";
219  EXPECT_DECLS("CXXCtorInitializer", "int a");
220 
221  Code = R"cpp(
222  struct X {
223  X() : [[X]](1) {}
224  X(int);
225  };
226  )cpp";
227  EXPECT_DECLS("RecordTypeLoc", "struct X");
228 }
229 
230 TEST_F(TargetDeclTest, DesignatedInit) {
231  Flags = {"-xc"}; // array designators are a C99 extension.
232  Code = R"c(
233  struct X { int a; };
234  struct Y { int b; struct X c[2]; };
235  struct Y y = { .c[0].[[a]] = 1 };
236  )c";
237  EXPECT_DECLS("DesignatedInitExpr", "int a");
238 }
239 
240 TEST_F(TargetDeclTest, NestedNameSpecifier) {
241  Code = R"cpp(
242  namespace a { namespace b { int c; } }
243  int x = a::[[b::]]c;
244  )cpp";
245  EXPECT_DECLS("NestedNameSpecifierLoc", "namespace b");
246 
247  Code = R"cpp(
248  namespace a { struct X { enum { y }; }; }
249  int x = a::[[X::]]y;
250  )cpp";
251  EXPECT_DECLS("NestedNameSpecifierLoc", "struct X");
252 
253  Code = R"cpp(
254  template <typename T>
255  int x = [[T::]]y;
256  )cpp";
257  EXPECT_DECLS("NestedNameSpecifierLoc", "typename T");
258 
259  Code = R"cpp(
260  namespace a { int x; }
261  namespace b = a;
262  int y = [[b]]::x;
263  )cpp";
264  EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},
265  {"namespace a", Rel::Underlying});
266 }
267 
268 TEST_F(TargetDeclTest, Types) {
269  Code = R"cpp(
270  struct X{};
271  [[X]] x;
272  )cpp";
273  EXPECT_DECLS("RecordTypeLoc", "struct X");
274 
275  Code = R"cpp(
276  struct S{};
277  typedef S X;
278  [[X]] x;
279  )cpp";
280  EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},
281  {"struct S", Rel::Underlying});
282  Code = R"cpp(
283  namespace ns { struct S{}; }
284  typedef ns::S X;
285  [[X]] x;
286  )cpp";
287  EXPECT_DECLS("TypedefTypeLoc", {"typedef ns::S X", Rel::Alias},
288  {"struct S", Rel::Underlying});
289 
290  // FIXME: Auto-completion in a template requires disabling delayed template
291  // parsing.
292  Flags = {"-fno-delayed-template-parsing"};
293  Code = R"cpp(
294  template<class T>
295  void foo() { [[T]] x; }
296  )cpp";
297  EXPECT_DECLS("TemplateTypeParmTypeLoc", "class T");
298  Flags.clear();
299 
300  // FIXME: Auto-completion in a template requires disabling delayed template
301  // parsing.
302  Flags = {"-fno-delayed-template-parsing"};
303  Code = R"cpp(
304  template<template<typename> class T>
305  void foo() { [[T<int>]] x; }
306  )cpp";
307  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class T");
308  Flags.clear();
309 
310  Code = R"cpp(
311  struct S{};
312  S X;
313  [[decltype]](X) Y;
314  )cpp";
315  EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});
316 
317  Code = R"cpp(
318  struct S{};
319  [[auto]] X = S{};
320  )cpp";
321  // FIXME: deduced type missing in AST. https://llvm.org/PR42914
322  EXPECT_DECLS("AutoTypeLoc");
323 
324  Code = R"cpp(
325  template <typename... E>
326  struct S {
327  static const int size = sizeof...([[E]]);
328  };
329  )cpp";
330  EXPECT_DECLS("SizeOfPackExpr", "typename ...E");
331 
332  Code = R"cpp(
333  template <typename T>
334  class Foo {
335  void f([[Foo]] x);
336  };
337  )cpp";
338  EXPECT_DECLS("InjectedClassNameTypeLoc", "class Foo");
339 }
340 
341 TEST_F(TargetDeclTest, ClassTemplate) {
342  Code = R"cpp(
343  // Implicit specialization.
344  template<int x> class Foo{};
345  [[Foo<42>]] B;
346  )cpp";
347  EXPECT_DECLS("TemplateSpecializationTypeLoc",
348  {"template<> class Foo<42>", Rel::TemplateInstantiation},
349  {"class Foo", Rel::TemplatePattern});
350 
351  Code = R"cpp(
352  template<typename T> class Foo {};
353  // The "Foo<int>" SpecializationDecl is incomplete, there is no
354  // instantiation happening.
355  void func([[Foo<int>]] *);
356  )cpp";
357  EXPECT_DECLS("TemplateSpecializationTypeLoc",
358  {"class Foo", Rel::TemplatePattern},
359  {"template<> class Foo<int>", Rel::TemplateInstantiation});
360 
361  Code = R"cpp(
362  // Explicit specialization.
363  template<int x> class Foo{};
364  template<> class Foo<42>{};
365  [[Foo<42>]] B;
366  )cpp";
367  EXPECT_DECLS("TemplateSpecializationTypeLoc", "template<> class Foo<42>");
368 
369  Code = R"cpp(
370  // Partial specialization.
371  template<typename T> class Foo{};
372  template<typename T> class Foo<T*>{};
373  [[Foo<int*>]] B;
374  )cpp";
375  EXPECT_DECLS("TemplateSpecializationTypeLoc",
376  {"template<> class Foo<int *>", Rel::TemplateInstantiation},
377  {"template <typename T> class Foo<T *>", Rel::TemplatePattern});
378 
379  Code = R"cpp(
380  // Class template argument deduction
381  template <typename T>
382  struct Test {
383  Test(T);
384  };
385  void foo() {
386  [[Test]] a(5);
387  }
388  )cpp";
389  Flags.push_back("-std=c++17");
390  EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
391  {"struct Test", Rel::TemplatePattern});
392 }
393 
394 TEST_F(TargetDeclTest, Concept) {
395  Code = R"cpp(
396  template <typename T>
397  concept Fooable = requires (T t) { t.foo(); };
398 
399  template <typename T> requires [[Fooable]]<T>
400  void bar(T t) {
401  t.foo();
402  }
403  )cpp";
404  Flags.push_back("-std=c++20");
405  EXPECT_DECLS(
406  "ConceptSpecializationExpr",
407  // FIXME: Should we truncate the pretty-printed form of a concept decl
408  // somewhere?
409  {"template <typename T> concept Fooable = requires (T t) { t.foo(); };"});
410 }
411 
412 TEST_F(TargetDeclTest, FunctionTemplate) {
413  Code = R"cpp(
414  // Implicit specialization.
415  template<typename T> bool foo(T) { return false; };
416  bool x = [[foo]](42);
417  )cpp";
418  EXPECT_DECLS("DeclRefExpr",
419  {"template<> bool foo<int>(int)", Rel::TemplateInstantiation},
420  {"bool foo(T)", Rel::TemplatePattern});
421 
422  Code = R"cpp(
423  // Explicit specialization.
424  template<typename T> bool foo(T) { return false; };
425  template<> bool foo<int>(int) { return false; };
426  bool x = [[foo]](42);
427  )cpp";
428  EXPECT_DECLS("DeclRefExpr", "template<> bool foo<int>(int)");
429 }
430 
431 TEST_F(TargetDeclTest, VariableTemplate) {
432  // Pretty-printer doesn't do a very good job of variable templates :-(
433  Code = R"cpp(
434  // Implicit specialization.
435  template<typename T> int foo;
436  int x = [[foo]]<char>;
437  )cpp";
438  EXPECT_DECLS("DeclRefExpr", {"int foo", Rel::TemplateInstantiation},
439  {"int foo", Rel::TemplatePattern});
440 
441  Code = R"cpp(
442  // Explicit specialization.
443  template<typename T> int foo;
444  template <> bool foo<char>;
445  int x = [[foo]]<char>;
446  )cpp";
447  EXPECT_DECLS("DeclRefExpr", "bool foo");
448 
449  Code = R"cpp(
450  // Partial specialization.
451  template<typename T> int foo;
452  template<typename T> bool foo<T*>;
453  bool x = [[foo]]<char*>;
454  )cpp";
455  EXPECT_DECLS("DeclRefExpr", {"bool foo", Rel::TemplateInstantiation},
456  {"bool foo", Rel::TemplatePattern});
457 }
458 
459 TEST_F(TargetDeclTest, TypeAliasTemplate) {
460  Code = R"cpp(
461  template<typename T, int X> class SmallVector {};
462  template<typename U> using TinyVector = SmallVector<U, 1>;
463  [[TinyVector<int>]] X;
464  )cpp";
465  EXPECT_DECLS("TemplateSpecializationTypeLoc",
466  {"template<> class SmallVector<int, 1>",
468  {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
469  {"using TinyVector = SmallVector<U, 1>",
471 }
472 
473 TEST_F(TargetDeclTest, MemberOfTemplate) {
474  Code = R"cpp(
475  template <typename T> struct Foo {
476  int x(T);
477  };
478  int y = Foo<int>().[[x]](42);
479  )cpp";
480  EXPECT_DECLS("MemberExpr", {"int x(int)", Rel::TemplateInstantiation},
481  {"int x(T)", Rel::TemplatePattern});
482 
483  Code = R"cpp(
484  template <typename T> struct Foo {
485  template <typename U>
486  int x(T, U);
487  };
488  int y = Foo<char>().[[x]]('c', 42);
489  )cpp";
490  EXPECT_DECLS("MemberExpr",
491  {"template<> int x<int>(char, int)", Rel::TemplateInstantiation},
492  {"int x(T, U)", Rel::TemplatePattern});
493 }
494 
495 TEST_F(TargetDeclTest, Lambda) {
496  Code = R"cpp(
497  void foo(int x = 42) {
498  auto l = [ [[x]] ]{ return x + 1; };
499  };
500  )cpp";
501  EXPECT_DECLS("DeclRefExpr", "int x = 42");
502 
503  // It seems like this should refer to another var, with the outer param being
504  // an underlying decl. But it doesn't seem to exist.
505  Code = R"cpp(
506  void foo(int x = 42) {
507  auto l = [x]{ return [[x]] + 1; };
508  };
509  )cpp";
510  EXPECT_DECLS("DeclRefExpr", "int x = 42");
511 
512  Code = R"cpp(
513  void foo() {
514  auto l = [x = 1]{ return [[x]] + 1; };
515  };
516  )cpp";
517  // FIXME: why both auto and int?
518  EXPECT_DECLS("DeclRefExpr", "auto int x = 1");
519 }
520 
521 TEST_F(TargetDeclTest, OverloadExpr) {
522  // FIXME: Auto-completion in a template requires disabling delayed template
523  // parsing.
524  Flags = {"-fno-delayed-template-parsing"};
525 
526  Code = R"cpp(
527  void func(int*);
528  void func(char*);
529 
530  template <class T>
531  void foo(T t) {
532  [[func]](t);
533  };
534  )cpp";
535  EXPECT_DECLS("UnresolvedLookupExpr", "void func(int *)", "void func(char *)");
536 
537  Code = R"cpp(
538  struct X {
539  void func(int*);
540  void func(char*);
541  };
542 
543  template <class T>
544  void foo(X x, T t) {
545  x.[[func]](t);
546  };
547  )cpp";
548  EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)");
549 }
550 
551 TEST_F(TargetDeclTest, ObjC) {
552  Flags = {"-xobjective-c"};
553  Code = R"cpp(
554  @interface Foo {}
555  -(void)bar;
556  @end
557  void test(Foo *f) {
558  [f [[bar]] ];
559  }
560  )cpp";
561  EXPECT_DECLS("ObjCMessageExpr", "- (void)bar");
562 
563  Code = R"cpp(
564  @interface Foo { @public int bar; }
565  @end
566  int test(Foo *f) {
567  return [[f->bar]];
568  }
569  )cpp";
570  EXPECT_DECLS("ObjCIvarRefExpr", "int bar");
571 
572  Code = R"cpp(
573  @interface Foo {}
574  -(int) x;
575  -(void) setX:(int)x;
576  @end
577  void test(Foo *f) {
578  [[f.x]] = 42;
579  }
580  )cpp";
581  EXPECT_DECLS("ObjCPropertyRefExpr", "- (void)setX:(int)x");
582 
583  Code = R"cpp(
584  @interface I {}
585  @property(retain) I* x;
586  @property(retain) I* y;
587  @end
588  void test(I *f) {
589  [[f.x]].y = 0;
590  }
591  )cpp";
592  EXPECT_DECLS("ObjCPropertyRefExpr",
593  "@property(atomic, retain, readwrite) I *x");
594 
595  Code = R"cpp(
596  @protocol Foo
597  @end
598  id test() {
599  return [[@protocol(Foo)]];
600  }
601  )cpp";
602  EXPECT_DECLS("ObjCProtocolExpr", "@protocol Foo");
603 
604  Code = R"cpp(
605  @interface Foo
606  @end
607  void test([[Foo]] *p);
608  )cpp";
609  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
610 
611  Code = R"cpp(
612  @protocol Foo
613  @end
614  void test([[id<Foo>]] p);
615  )cpp";
616  EXPECT_DECLS("ObjCObjectTypeLoc", "@protocol Foo");
617 
618  Code = R"cpp(
619  @class C;
620  @protocol Foo
621  @end
622  void test(C<[[Foo]]> *p);
623  )cpp";
624  // FIXME: there's no AST node corresponding to 'Foo', so we're stuck.
625  EXPECT_DECLS("ObjCObjectTypeLoc");
626 }
627 
628 class FindExplicitReferencesTest : public ::testing::Test {
629 protected:
630  struct AllRefs {
631  std::string AnnotatedCode;
632  std::string DumpedReferences;
633  };
634 
635  /// Parses \p Code, finds function or namespace '::foo' and annotates its body
636  /// with results of findExplicitReferences.
637  /// See actual tests for examples of annotation format.
638  AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
639  TestTU TU;
640  TU.Code = std::string(Code);
641 
642  // FIXME: Auto-completion in a template requires disabling delayed template
643  // parsing.
644  TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
645  TU.ExtraArgs.push_back("-std=c++20");
646  TU.ExtraArgs.push_back("-xobjective-c++");
647 
648  auto AST = TU.build();
649  auto *TestDecl = &findDecl(AST, "foo");
650  if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
651  TestDecl = T->getTemplatedDecl();
652 
653  std::vector<ReferenceLoc> Refs;
654  if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
655  findExplicitReferences(Func->getBody(), [&Refs](ReferenceLoc R) {
656  Refs.push_back(std::move(R));
657  });
658  else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
659  findExplicitReferences(NS, [&Refs, &NS](ReferenceLoc R) {
660  // Avoid adding the namespace foo decl to the results.
661  if (R.Targets.size() == 1 && R.Targets.front() == NS)
662  return;
663  Refs.push_back(std::move(R));
664  });
665  else
666  ADD_FAILURE() << "Failed to find ::foo decl for test";
667 
668  auto &SM = AST.getSourceManager();
669  llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
670  return SM.isBeforeInTranslationUnit(L.NameLoc, R.NameLoc);
671  });
672 
673  std::string AnnotatedCode;
674  unsigned NextCodeChar = 0;
675  for (unsigned I = 0; I < Refs.size(); ++I) {
676  auto &R = Refs[I];
677 
678  SourceLocation Pos = R.NameLoc;
679  assert(Pos.isValid());
680  if (Pos.isMacroID()) // FIXME: figure out how to show macro locations.
681  Pos = SM.getExpansionLoc(Pos);
682  assert(Pos.isFileID());
683 
684  FileID File;
685  unsigned Offset;
686  std::tie(File, Offset) = SM.getDecomposedLoc(Pos);
687  if (File == SM.getMainFileID()) {
688  // Print the reference in a source code.
689  assert(NextCodeChar <= Offset);
690  AnnotatedCode += Code.substr(NextCodeChar, Offset - NextCodeChar);
691  AnnotatedCode += "$" + std::to_string(I) + "^";
692 
693  NextCodeChar = Offset;
694  }
695  }
696  AnnotatedCode += Code.substr(NextCodeChar);
697 
698  std::string DumpedReferences;
699  for (unsigned I = 0; I < Refs.size(); ++I)
700  DumpedReferences += std::string(llvm::formatv("{0}: {1}\n", I, Refs[I]));
701 
702  return AllRefs{std::move(AnnotatedCode), std::move(DumpedReferences)};
703  }
704 };
705 
706 TEST_F(FindExplicitReferencesTest, All) {
707  std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] =
708  {// Simple expressions.
709  {R"cpp(
710  int global;
711  int func();
712  void foo(int param) {
713  $0^global = $1^param + $2^func();
714  }
715  )cpp",
716  "0: targets = {global}\n"
717  "1: targets = {param}\n"
718  "2: targets = {func}\n"},
719  {R"cpp(
720  struct X { int a; };
721  void foo(X x) {
722  $0^x.$1^a = 10;
723  }
724  )cpp",
725  "0: targets = {x}\n"
726  "1: targets = {X::a}\n"},
727  {R"cpp(
728  // error-ok: testing with broken code
729  int bar();
730  int foo() {
731  return $0^bar() + $1^bar(42);
732  }
733  )cpp",
734  "0: targets = {bar}\n"
735  "1: targets = {bar}\n"},
736  // Namespaces and aliases.
737  {R"cpp(
738  namespace ns {}
739  namespace alias = ns;
740  void foo() {
741  using namespace $0^ns;
742  using namespace $1^alias;
743  }
744  )cpp",
745  "0: targets = {ns}\n"
746  "1: targets = {alias}\n"},
747  // Using declarations.
748  {R"cpp(
749  namespace ns { int global; }
750  void foo() {
751  using $0^ns::$1^global;
752  }
753  )cpp",
754  "0: targets = {ns}\n"
755  "1: targets = {ns::global}, qualifier = 'ns::'\n"},
756  // Simple types.
757  {R"cpp(
758  struct Struct { int a; };
759  using Typedef = int;
760  void foo() {
761  $0^Struct $1^x;
762  $2^Typedef $3^y;
763  static_cast<$4^Struct*>(0);
764  }
765  )cpp",
766  "0: targets = {Struct}\n"
767  "1: targets = {x}, decl\n"
768  "2: targets = {Typedef}\n"
769  "3: targets = {y}, decl\n"
770  "4: targets = {Struct}\n"},
771  // Name qualifiers.
772  {R"cpp(
773  namespace a { namespace b { struct S { typedef int type; }; } }
774  void foo() {
775  $0^a::$1^b::$2^S $3^x;
776  using namespace $4^a::$5^b;
777  $6^S::$7^type $8^y;
778  }
779  )cpp",
780  "0: targets = {a}\n"
781  "1: targets = {a::b}, qualifier = 'a::'\n"
782  "2: targets = {a::b::S}, qualifier = 'a::b::'\n"
783  "3: targets = {x}, decl\n"
784  "4: targets = {a}\n"
785  "5: targets = {a::b}, qualifier = 'a::'\n"
786  "6: targets = {a::b::S}\n"
787  "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
788  "8: targets = {y}, decl\n"},
789  {R"cpp(
790  void foo() {
791  $0^ten: // PRINT "HELLO WORLD!"
792  goto $1^ten;
793  }
794  )cpp",
795  "0: targets = {ten}, decl\n"
796  "1: targets = {ten}\n"},
797  // Simple templates.
798  {R"cpp(
799  template <class T> struct vector { using value_type = T; };
800  template <> struct vector<bool> { using value_type = bool; };
801  void foo() {
802  $0^vector<int> $1^vi;
803  $2^vector<bool> $3^vb;
804  }
805  )cpp",
806  "0: targets = {vector<int>}\n"
807  "1: targets = {vi}, decl\n"
808  "2: targets = {vector<bool>}\n"
809  "3: targets = {vb}, decl\n"},
810  // Template type aliases.
811  {R"cpp(
812  template <class T> struct vector { using value_type = T; };
813  template <> struct vector<bool> { using value_type = bool; };
814  template <class T> using valias = vector<T>;
815  void foo() {
816  $0^valias<int> $1^vi;
817  $2^valias<bool> $3^vb;
818  }
819  )cpp",
820  "0: targets = {valias}\n"
821  "1: targets = {vi}, decl\n"
822  "2: targets = {valias}\n"
823  "3: targets = {vb}, decl\n"},
824  // Injected class name.
825  {R"cpp(
826  namespace foo {
827  template <typename $0^T>
828  class $1^Bar {
829  ~$2^Bar();
830  void $3^f($4^Bar);
831  };
832  }
833  )cpp",
834  "0: targets = {foo::Bar::T}, decl\n"
835  "1: targets = {foo::Bar}, decl\n"
836  "2: targets = {foo::Bar}\n"
837  "3: targets = {foo::Bar::f}, decl\n"
838  "4: targets = {foo::Bar}\n"},
839  // MemberExpr should know their using declaration.
840  {R"cpp(
841  struct X { void func(int); };
842  struct Y : X {
843  using X::func;
844  };
845  void foo(Y y) {
846  $0^y.$1^func(1);
847  }
848  )cpp",
849  "0: targets = {y}\n"
850  "1: targets = {Y::func}\n"},
851  // DeclRefExpr should know their using declaration.
852  {R"cpp(
853  namespace ns { void bar(int); }
854  using ns::bar;
855 
856  void foo() {
857  $0^bar(10);
858  }
859  )cpp",
860  "0: targets = {bar}\n"},
861  // References from a macro.
862  {R"cpp(
863  #define FOO a
864  #define BAR b
865 
866  void foo(int a, int b) {
867  $0^FOO+$1^BAR;
868  }
869  )cpp",
870  "0: targets = {a}\n"
871  "1: targets = {b}\n"},
872  // No references from implicit nodes.
873  {R"cpp(
874  struct vector {
875  int *begin();
876  int *end();
877  };
878 
879  void foo() {
880  for (int $0^x : $1^vector()) {
881  $2^x = 10;
882  }
883  }
884  )cpp",
885  "0: targets = {x}, decl\n"
886  "1: targets = {vector}\n"
887  "2: targets = {x}\n"},
888 // Handle UnresolvedLookupExpr.
889 // FIXME
890 // This case fails when expensive checks are enabled.
891 // Seems like the order of ns1::func and ns2::func isn't defined.
892 #ifndef EXPENSIVE_CHECKS
893  {R"cpp(
894  namespace ns1 { void func(char*); }
895  namespace ns2 { void func(int*); }
896  using namespace ns1;
897  using namespace ns2;
898 
899  template <class T>
900  void foo(T t) {
901  $0^func($1^t);
902  }
903  )cpp",
904  "0: targets = {ns1::func, ns2::func}\n"
905  "1: targets = {t}\n"},
906 #endif
907  // Handle UnresolvedMemberExpr.
908  {R"cpp(
909  struct X {
910  void func(char*);
911  void func(int*);
912  };
913 
914  template <class T>
915  void foo(X x, T t) {
916  $0^x.$1^func($2^t);
917  }
918  )cpp",
919  "0: targets = {x}\n"
920  "1: targets = {X::func, X::func}\n"
921  "2: targets = {t}\n"},
922  // Handle DependentScopeDeclRefExpr.
923  {R"cpp(
924  template <class T>
925  struct S {
926  static int value;
927  };
928 
929  template <class T>
930  void foo() {
931  $0^S<$1^T>::$2^value;
932  }
933  )cpp",
934  "0: targets = {S}\n"
935  "1: targets = {T}\n"
936  "2: targets = {S::value}, qualifier = 'S<T>::'\n"},
937  // Handle CXXDependentScopeMemberExpr.
938  {R"cpp(
939  template <class T>
940  struct S {
941  int value;
942  };
943 
944  template <class T>
945  void foo(S<T> t) {
946  $0^t.$1^value;
947  }
948  )cpp",
949  "0: targets = {t}\n"
950  "1: targets = {S::value}\n"},
951  // Type template parameters.
952  {R"cpp(
953  template <class T>
954  void foo() {
955  static_cast<$0^T>(0);
956  $1^T();
957  $2^T $3^t;
958  }
959  )cpp",
960  "0: targets = {T}\n"
961  "1: targets = {T}\n"
962  "2: targets = {T}\n"
963  "3: targets = {t}, decl\n"},
964  // Non-type template parameters.
965  {R"cpp(
966  template <int I>
967  void foo() {
968  int $0^x = $1^I;
969  }
970  )cpp",
971  "0: targets = {x}, decl\n"
972  "1: targets = {I}\n"},
973  // Template template parameters.
974  {R"cpp(
975  template <class T> struct vector {};
976 
977  template <template<class> class TT, template<class> class ...TP>
978  void foo() {
979  $0^TT<int> $1^x;
980  $2^foo<$3^TT>();
981  $4^foo<$5^vector>();
982  $6^foo<$7^TP...>();
983  }
984  )cpp",
985  "0: targets = {TT}\n"
986  "1: targets = {x}, decl\n"
987  "2: targets = {foo}\n"
988  "3: targets = {TT}\n"
989  "4: targets = {foo}\n"
990  "5: targets = {vector}\n"
991  "6: targets = {foo}\n"
992  "7: targets = {TP}\n"},
993  // Non-type template parameters with declarations.
994  {R"cpp(
995  int func();
996  template <int(*)()> struct wrapper {};
997 
998  template <int(*FuncParam)()>
999  void foo() {
1000  $0^wrapper<$1^func> $2^w;
1001  $3^FuncParam();
1002  }
1003  )cpp",
1004  "0: targets = {wrapper<&func>}\n"
1005  "1: targets = {func}\n"
1006  "2: targets = {w}, decl\n"
1007  "3: targets = {FuncParam}\n"},
1008  // declaration references.
1009  {R"cpp(
1010  namespace ns {}
1011  class S {};
1012  void foo() {
1013  class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
1014  int $4^Var;
1015  enum $5^E { $6^ABC };
1016  typedef int $7^INT;
1017  using $8^INT2 = int;
1018  namespace $9^NS = $10^ns;
1019  }
1020  )cpp",
1021  "0: targets = {Foo}, decl\n"
1022  "1: targets = {foo()::Foo::Foo}, decl\n"
1023  "2: targets = {Foo}\n"
1024  "3: targets = {foo()::Foo::field}, decl\n"
1025  "4: targets = {Var}, decl\n"
1026  "5: targets = {E}, decl\n"
1027  "6: targets = {foo()::ABC}, decl\n"
1028  "7: targets = {INT}, decl\n"
1029  "8: targets = {INT2}, decl\n"
1030  "9: targets = {NS}, decl\n"
1031  "10: targets = {ns}\n"},
1032  // User-defined conversion operator.
1033  {R"cpp(
1034  void foo() {
1035  class $0^Bar {};
1036  class $1^Foo {
1037  public:
1038  // FIXME: This should have only one reference to Bar.
1039  $2^operator $3^$4^Bar();
1040  };
1041 
1042  $5^Foo $6^f;
1043  $7^f.$8^operator $9^Bar();
1044  }
1045  )cpp",
1046  "0: targets = {Bar}, decl\n"
1047  "1: targets = {Foo}, decl\n"
1048  "2: targets = {foo()::Foo::operator Bar}, decl\n"
1049  "3: targets = {Bar}\n"
1050  "4: targets = {Bar}\n"
1051  "5: targets = {Foo}\n"
1052  "6: targets = {f}, decl\n"
1053  "7: targets = {f}\n"
1054  "8: targets = {foo()::Foo::operator Bar}\n"
1055  "9: targets = {Bar}\n"},
1056  // Destructor.
1057  {R"cpp(
1058  void foo() {
1059  class $0^Foo {
1060  public:
1061  ~$1^Foo() {}
1062 
1063  void $2^destructMe() {
1064  this->~$3^Foo();
1065  }
1066  };
1067 
1068  $4^Foo $5^f;
1069  $6^f.~ /*...*/ $7^Foo();
1070  }
1071  )cpp",
1072  "0: targets = {Foo}, decl\n"
1073  // FIXME: It's better to target destructor's FunctionDecl instead of
1074  // the type itself (similar to constructor).
1075  "1: targets = {Foo}\n"
1076  "2: targets = {foo()::Foo::destructMe}, decl\n"
1077  "3: targets = {Foo}\n"
1078  "4: targets = {Foo}\n"
1079  "5: targets = {f}, decl\n"
1080  "6: targets = {f}\n"
1081  "7: targets = {Foo}\n"},
1082  // cxx constructor initializer.
1083  {R"cpp(
1084  class Base {};
1085  void foo() {
1086  // member initializer
1087  class $0^X {
1088  int $1^abc;
1089  $2^X(): $3^abc() {}
1090  };
1091  // base initializer
1092  class $4^Derived : public $5^Base {
1093  $6^Base $7^B;
1094  $8^Derived() : $9^Base() {}
1095  };
1096  // delegating initializer
1097  class $10^Foo {
1098  $11^Foo(int);
1099  $12^Foo(): $13^Foo(111) {}
1100  };
1101  }
1102  )cpp",
1103  "0: targets = {X}, decl\n"
1104  "1: targets = {foo()::X::abc}, decl\n"
1105  "2: targets = {foo()::X::X}, decl\n"
1106  "3: targets = {foo()::X::abc}\n"
1107  "4: targets = {Derived}, decl\n"
1108  "5: targets = {Base}\n"
1109  "6: targets = {Base}\n"
1110  "7: targets = {foo()::Derived::B}, decl\n"
1111  "8: targets = {foo()::Derived::Derived}, decl\n"
1112  "9: targets = {Base}\n"
1113  "10: targets = {Foo}, decl\n"
1114  "11: targets = {foo()::Foo::Foo}, decl\n"
1115  "12: targets = {foo()::Foo::Foo}, decl\n"
1116  "13: targets = {Foo}\n"},
1117  // Anonymous entities should not be reported.
1118  {
1119  R"cpp(
1120  void foo() {
1121  class {} $0^x;
1122  int (*$1^fptr)(int $2^a, int) = nullptr;
1123  }
1124  )cpp",
1125  "0: targets = {x}, decl\n"
1126  "1: targets = {fptr}, decl\n"
1127  "2: targets = {a}, decl\n"},
1128  // Namespace aliases should be handled properly.
1129  {
1130  R"cpp(
1131  namespace ns { struct Type {}; }
1132  namespace alias = ns;
1133  namespace rec_alias = alias;
1134 
1135  void foo() {
1136  $0^ns::$1^Type $2^a;
1137  $3^alias::$4^Type $5^b;
1138  $6^rec_alias::$7^Type $8^c;
1139  }
1140  )cpp",
1141  "0: targets = {ns}\n"
1142  "1: targets = {ns::Type}, qualifier = 'ns::'\n"
1143  "2: targets = {a}, decl\n"
1144  "3: targets = {alias}\n"
1145  "4: targets = {ns::Type}, qualifier = 'alias::'\n"
1146  "5: targets = {b}, decl\n"
1147  "6: targets = {rec_alias}\n"
1148  "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n"
1149  "8: targets = {c}, decl\n"},
1150  // Handle SizeOfPackExpr.
1151  {
1152  R"cpp(
1153  template <typename... E>
1154  void foo() {
1155  constexpr int $0^size = sizeof...($1^E);
1156  };
1157  )cpp",
1158  "0: targets = {size}, decl\n"
1159  "1: targets = {E}\n"},
1160  // Class template argument deduction
1161  {
1162  R"cpp(
1163  template <typename T>
1164  struct Test {
1165  Test(T);
1166  };
1167  void foo() {
1168  $0^Test $1^a(5);
1169  }
1170  )cpp",
1171  "0: targets = {Test}\n"
1172  "1: targets = {a}, decl\n"},
1173  // Templates
1174  {R"cpp(
1175  namespace foo {
1176  template <typename $0^T>
1177  class $1^Bar {};
1178  }
1179  )cpp",
1180  "0: targets = {foo::Bar::T}, decl\n"
1181  "1: targets = {foo::Bar}, decl\n"},
1182  // Templates
1183  {R"cpp(
1184  namespace foo {
1185  template <typename $0^T>
1186  void $1^func();
1187  }
1188  )cpp",
1189  "0: targets = {T}, decl\n"
1190  "1: targets = {foo::func}, decl\n"},
1191  // Templates
1192  {R"cpp(
1193  namespace foo {
1194  template <typename $0^T>
1195  $1^T $2^x;
1196  }
1197  )cpp",
1198  "0: targets = {foo::T}, decl\n"
1199  "1: targets = {foo::T}\n"
1200  "2: targets = {foo::x}, decl\n"},
1201  // Templates
1202  {R"cpp(
1203  template<typename T> class vector {};
1204  namespace foo {
1205  template <typename $0^T>
1206  using $1^V = $2^vector<$3^T>;
1207  }
1208  )cpp",
1209  "0: targets = {foo::T}, decl\n"
1210  "1: targets = {foo::V}, decl\n"
1211  "2: targets = {vector}\n"
1212  "3: targets = {foo::T}\n"},
1213  // Concept
1214  {
1215  R"cpp(
1216  template <typename T>
1217  concept Drawable = requires (T t) { t.draw(); };
1218 
1219  namespace foo {
1220  template <typename $0^T> requires $1^Drawable<$2^T>
1221  void $3^bar($4^T $5^t) {
1222  $6^t.$7^draw();
1223  }
1224  }
1225  )cpp",
1226  "0: targets = {T}, decl\n"
1227  "1: targets = {Drawable}\n"
1228  "2: targets = {T}\n"
1229  "3: targets = {foo::bar}, decl\n"
1230  "4: targets = {T}\n"
1231  "5: targets = {t}, decl\n"
1232  "6: targets = {t}\n"
1233  "7: targets = {}\n"},
1234  // Objective-C: properties
1235  {
1236  R"cpp(
1237  @interface I {}
1238  @property(retain) I* x;
1239  @property(retain) I* y;
1240  @end
1241  I *f;
1242  void foo() {
1243  $0^f.$1^x.$2^y = 0;
1244  }
1245  )cpp",
1246  "0: targets = {f}\n"
1247  "1: targets = {I::x}\n"
1248  "2: targets = {I::y}\n"},
1249  // Objective-C: implicit properties
1250  {
1251  R"cpp(
1252  @interface I {}
1253  -(I*)x;
1254  -(void)setY:(I*)y;
1255  @end
1256  I *f;
1257  void foo() {
1258  $0^f.$1^x.$2^y = 0;
1259  }
1260  )cpp",
1261  "0: targets = {f}\n"
1262  "1: targets = {I::x}\n"
1263  "2: targets = {I::setY:}\n"},
1264  // Designated initializers.
1265  {R"cpp(
1266  void foo() {
1267  struct $0^Foo {
1268  int $1^Bar;
1269  };
1270  $2^Foo $3^f { .$4^Bar = 42 };
1271  }
1272  )cpp",
1273  "0: targets = {Foo}, decl\n"
1274  "1: targets = {foo()::Foo::Bar}, decl\n"
1275  "2: targets = {Foo}\n"
1276  "3: targets = {f}, decl\n"
1277  "4: targets = {foo()::Foo::Bar}\n"},
1278  {R"cpp(
1279  void foo() {
1280  struct $0^Baz {
1281  int $1^Field;
1282  };
1283  struct $2^Bar {
1284  $3^Baz $4^Foo;
1285  };
1286  $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
1287  }
1288  )cpp",
1289  "0: targets = {Baz}, decl\n"
1290  "1: targets = {foo()::Baz::Field}, decl\n"
1291  "2: targets = {Bar}, decl\n"
1292  "3: targets = {Baz}\n"
1293  "4: targets = {foo()::Bar::Foo}, decl\n"
1294  "5: targets = {Bar}\n"
1295  "6: targets = {bar}, decl\n"
1296  "7: targets = {foo()::Bar::Foo}\n"
1297  "8: targets = {foo()::Baz::Field}\n"},
1298  {R"cpp(
1299  template<typename T>
1300  void crash(T);
1301  template<typename T>
1302  void foo() {
1303  $0^crash({.$1^x = $2^T()});
1304  }
1305  )cpp",
1306  "0: targets = {crash}\n"
1307  "1: targets = {}\n"
1308  "2: targets = {T}\n"
1309  },
1310  // unknown template name should not crash.
1311  {R"cpp(
1312  template <template <typename> typename T>
1313  struct Base {};
1314  namespace foo {
1315  template <typename $0^T>
1316  struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
1317  }
1318  )cpp",
1319  "0: targets = {foo::Derive::T}, decl\n"
1320  "1: targets = {foo::Derive}, decl\n"
1321  "2: targets = {Base}\n"
1322  "3: targets = {foo::Derive::T}\n"
1323  "4: targets = {}, qualifier = 'T::'\n"},
1324  };
1325 
1326  for (const auto &C : Cases) {
1327  llvm::StringRef ExpectedCode = C.first;
1328  llvm::StringRef ExpectedRefs = C.second;
1329 
1330  auto Actual =
1331  annotateReferencesInFoo(llvm::Annotations(ExpectedCode).code());
1332  EXPECT_EQ(ExpectedCode, Actual.AnnotatedCode);
1333  EXPECT_EQ(ExpectedRefs, Actual.DumpedReferences) << ExpectedCode;
1334  }
1335 }
1336 
1337 } // namespace
1338 } // namespace clangd
1339 } // namespace clang
std::string Code
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:522
std::string Name
std::string DumpedReferences
This is the pattern the template specialization was instantiated from.
#define EXPECT_DECLS(NodeType,...)
This declaration is an alias that was referred to.
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
This is the template instantiation that was referred to.
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:162
std::vector< std::string > Flags
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
Definition: Selection.cpp:784
Position Pos
Definition: SourceCode.cpp:649
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:35
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:994
This is the underlying declaration for an alias, decltype etc.
DeclRelationSet Relations
CharSourceRange Range
SourceRange for the file name.
const Node * commonAncestor() const
Definition: Selection.cpp:814
RefSlab Refs
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition: Headers.cpp:273
std::string AnnotatedCode
std::vector< std::string > ExtraArgs
Definition: TestTU.h:59
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:165