clang-tools  10.0.0git
SymbolInfoTests.cpp
Go to the documentation of this file.
1 //===-- SymbolInfoTests.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 "Annotations.h"
9 #include "Compiler.h"
10 #include "Matchers.h"
11 #include "ParsedAST.h"
12 #include "SyncAPI.h"
13 #include "TestFS.h"
14 #include "TestTU.h"
15 #include "XRefs.h"
16 #include "index/FileIndex.h"
17 #include "index/SymbolCollector.h"
18 #include "clang/Index/IndexingAction.h"
19 #include "llvm/Support/Path.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 
23 namespace clang {
24 namespace clangd {
25 namespace {
26 
27 using ::testing::UnorderedElementsAreArray;
28 
29 auto CreateExpectedSymbolDetails = [](const std::string &name,
30  const std::string &container,
31  const std::string &USR) {
32  return SymbolDetails{name, container, USR, SymbolID(USR)};
33 };
34 
35 TEST(SymbolInfoTests, All) {
36  std::pair<const char *, std::vector<SymbolDetails>>
37  TestInputExpectedOutput[] = {
38  {
39  R"cpp( // Simple function reference - declaration
40  void foo();
41  int bar() {
42  fo^o();
43  }
44  )cpp",
45  {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
46  {
47  R"cpp( // Simple function reference - definition
48  void foo() {}
49  int bar() {
50  fo^o();
51  }
52  )cpp",
53  {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
54  {
55  R"cpp( // Function in namespace reference
56  namespace bar {
57  void foo();
58  int baz() {
59  fo^o();
60  }
61  }
62  )cpp",
63  {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
64  {
65  R"cpp( // Function in different namespace reference
66  namespace bar {
67  void foo();
68  }
69  namespace barbar {
70  int baz() {
71  bar::fo^o();
72  }
73  }
74  )cpp",
75  {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
76  {
77  R"cpp( // Function in global namespace reference
78  void foo();
79  namespace Nbar {
80  namespace Nbaz {
81  int baz() {
82  ::fo^o();
83  }
84  }
85  }
86  )cpp",
87  {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
88  {
89  R"cpp( // Function in anonymous namespace reference
90  namespace {
91  void foo();
92  }
93  namespace barbar {
94  int baz() {
95  fo^o();
96  }
97  }
98  )cpp",
99  {CreateExpectedSymbolDetails("foo", "(anonymous)",
100  "c:TestTU.cpp@aN@F@foo#")}},
101  {
102  R"cpp( // Function reference - ADL
103  namespace bar {
104  struct BarType {};
105  void foo(const BarType&);
106  }
107  namespace barbar {
108  int baz() {
109  bar::BarType b;
110  fo^o(b);
111  }
112  }
113  )cpp",
114  {CreateExpectedSymbolDetails(
115  "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#")}},
116  {
117  R"cpp( // Global value reference
118  int value;
119  void foo(int) { }
120  void bar() {
121  foo(val^ue);
122  }
123  )cpp",
124  {CreateExpectedSymbolDetails("value", "", "c:@value")}},
125  {
126  R"cpp( // Local value reference
127  void foo() { int aaa; int bbb = aa^a; }
128  )cpp",
129  {CreateExpectedSymbolDetails("aaa", "foo",
130  "c:TestTU.cpp@49@F@foo#@aaa")}},
131  {
132  R"cpp( // Function param
133  void bar(int aaa) {
134  int bbb = a^aa;
135  }
136  )cpp",
137  {CreateExpectedSymbolDetails("aaa", "bar",
138  "c:TestTU.cpp@38@F@bar#I#@aaa")}},
139  {
140  R"cpp( // Lambda capture
141  int ii;
142  auto lam = [ii]() {
143  return i^i;
144  };
145  )cpp",
146  {CreateExpectedSymbolDetails("ii", "", "c:@ii")}},
147  {
148  R"cpp( // Macro reference
149  #define MACRO 5\nint i = MAC^RO;
150  )cpp",
151  {CreateExpectedSymbolDetails("MACRO", "",
152  "c:TestTU.cpp@38@macro@MACRO")}},
153  {
154  R"cpp( // Macro reference
155  #define MACRO 5\nint i = MACRO^;
156  )cpp",
157  {CreateExpectedSymbolDetails("MACRO", "",
158  "c:TestTU.cpp@38@macro@MACRO")}},
159  {
160  R"cpp( // Multiple symbols returned - using overloaded function name
161  void foo() {}
162  void foo(bool) {}
163  void foo(int) {}
164  namespace bar {
165  using ::fo^o;
166  }
167  )cpp",
168  {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
169  CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
170  CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"),
171  CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}},
172  {
173  R"cpp( // Multiple symbols returned - implicit conversion
174  struct foo {};
175  struct bar {
176  bar(const foo&) {}
177  };
178  void func_baz1(bar) {}
179  void func_baz2() {
180  foo ff;
181  func_baz1(f^f);
182  }
183  )cpp",
184  {CreateExpectedSymbolDetails(
185  "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff")}},
186  {
187  R"cpp( // Type reference - declaration
188  struct foo;
189  void bar(fo^o*);
190  )cpp",
191  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
192  {
193  R"cpp( // Type reference - definition
194  struct foo {};
195  void bar(fo^o*);
196  )cpp",
197  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
198  {
199  R"cpp( // Type Reference - template argumen
200  struct foo {};
201  template<class T> struct bar {};
202  void baz() {
203  bar<fo^o> b;
204  }
205  )cpp",
206  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
207  {
208  R"cpp( // Template parameter reference - type param
209  template<class TT> struct bar {
210  T^T t;
211  };
212  )cpp",
213  {CreateExpectedSymbolDetails("TT", "bar::", "c:TestTU.cpp@65")}},
214  {
215  R"cpp( // Template parameter reference - type param
216  template<int NN> struct bar {
217  int a = N^N;
218  };
219  )cpp",
220  {CreateExpectedSymbolDetails("NN", "bar::", "c:TestTU.cpp@65")}},
221  {
222  R"cpp( // Class member reference - objec
223  struct foo {
224  int aa;
225  };
226  void bar() {
227  foo f;
228  f.a^a;
229  }
230  )cpp",
231  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
232  {
233  R"cpp( // Class member reference - pointer
234  struct foo {
235  int aa;
236  };
237  void bar() {
238  &foo::a^a;
239  }
240  )cpp",
241  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
242  {
243  R"cpp( // Class method reference - objec
244  struct foo {
245  void aa() {}
246  };
247  void bar() {
248  foo f;
249  f.a^a();
250  }
251  )cpp",
252  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
253  {
254  R"cpp( // Class method reference - pointer
255  struct foo {
256  void aa() {}
257  };
258  void bar() {
259  &foo::a^a;
260  }
261  )cpp",
262  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
263  {
264  R"cpp( // Typedef
265  typedef int foo;
266  void bar() {
267  fo^o a;
268  }
269  )cpp",
270  {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@T@foo")}},
271  {
272  R"cpp( // Type alias
273  using foo = int;
274  void bar() {
275  fo^o a;
276  }
277  )cpp",
278  {CreateExpectedSymbolDetails("foo", "", "c:@foo")}},
279  {
280  R"cpp( // Namespace reference
281  namespace foo {}
282  using namespace fo^o;
283  )cpp",
284  {CreateExpectedSymbolDetails("foo", "", "c:@N@foo")}},
285  {
286  R"cpp( // Enum value reference
287  enum foo { bar, baz };
288  void f() {
289  foo fff = ba^r;
290  }
291  )cpp",
292  {CreateExpectedSymbolDetails("bar", "foo", "c:@E@foo@bar")}},
293  {
294  R"cpp( // Enum class value reference
295  enum class foo { bar, baz };
296  void f() {
297  foo fff = foo::ba^r;
298  }
299  )cpp",
300  {CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}},
301  {
302  R"cpp( // Parameters in declarations
303  void foo(int ba^r);
304  )cpp",
305  {CreateExpectedSymbolDetails("bar", "foo",
306  "c:TestTU.cpp@50@F@foo#I#@bar")}},
307  {
308  R"cpp( // Type inference with auto keyword
309  struct foo {};
310  foo getfoo() { return foo{}; }
311  void f() {
312  au^to a = getfoo();
313  }
314  )cpp",
315  {/* not implemented */}},
316  {
317  R"cpp( // decltype
318  struct foo {};
319  void f() {
320  foo f;
321  declt^ype(f);
322  }
323  )cpp",
324  {/* not implemented */}},
325  };
326 
327  for (const auto &T : TestInputExpectedOutput) {
328  Annotations TestInput(T.first);
329  auto AST = TestTU::withCode(TestInput.code()).build();
330 
331  EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),
332  UnorderedElementsAreArray(T.second))
333  << T.first;
334  }
335 }
336 
337 } // namespace
338 } // namespace clangd
339 } // namespace clang
std::vector< SymbolDetails > getSymbolInfo(ParsedAST &AST, Position Pos)
Get info about symbols at Pos.
Definition: XRefs.cpp:519
TEST(BackgroundQueueTest, Priority)
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::array< uint8_t, 20 > SymbolID