clang-tools  11.0.0
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  void foo() {
142  int ii;
143  auto lam = [ii]() {
144  return i^i;
145  };
146  }
147  )cpp",
148  {CreateExpectedSymbolDetails("ii", "foo",
149  "c:TestTU.cpp@54@F@foo#@ii")}},
150  {
151  R"cpp( // Macro reference
152  #define MACRO 5\nint i = MAC^RO;
153  )cpp",
154  {CreateExpectedSymbolDetails("MACRO", "",
155  "c:TestTU.cpp@38@macro@MACRO")}},
156  {
157  R"cpp( // Macro reference
158  #define MACRO 5\nint i = MACRO^;
159  )cpp",
160  {CreateExpectedSymbolDetails("MACRO", "",
161  "c:TestTU.cpp@38@macro@MACRO")}},
162  {
163  R"cpp( // Multiple symbols returned - using overloaded function name
164  void foo() {}
165  void foo(bool) {}
166  void foo(int) {}
167  namespace bar {
168  using ::fo^o;
169  }
170  )cpp",
171  {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
172  CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
173  CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"),
174  CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}},
175  {
176  R"cpp( // Multiple symbols returned - implicit conversion
177  struct foo {};
178  struct bar {
179  bar(const foo&) {}
180  };
181  void func_baz1(bar) {}
182  void func_baz2() {
183  foo ff;
184  func_baz1(f^f);
185  }
186  )cpp",
187  {CreateExpectedSymbolDetails(
188  "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff")}},
189  {
190  R"cpp( // Type reference - declaration
191  struct foo;
192  void bar(fo^o*);
193  )cpp",
194  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
195  {
196  R"cpp( // Type reference - definition
197  struct foo {};
198  void bar(fo^o*);
199  )cpp",
200  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
201  {
202  R"cpp( // Type Reference - template argument
203  struct foo {};
204  template<class T> struct bar {};
205  void baz() {
206  bar<fo^o> b;
207  }
208  )cpp",
209  {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
210  {
211  R"cpp( // Template parameter reference - type param
212  template<class TT> struct bar {
213  T^T t;
214  };
215  )cpp",
216  {CreateExpectedSymbolDetails("TT", "bar::", "c:TestTU.cpp@65")}},
217  {
218  R"cpp( // Template parameter reference - type param
219  template<int NN> struct bar {
220  int a = N^N;
221  };
222  )cpp",
223  {CreateExpectedSymbolDetails("NN", "bar::", "c:TestTU.cpp@65")}},
224  {
225  R"cpp( // Class member reference - objec
226  struct foo {
227  int aa;
228  };
229  void bar() {
230  foo f;
231  f.a^a;
232  }
233  )cpp",
234  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
235  {
236  R"cpp( // Class member reference - pointer
237  struct foo {
238  int aa;
239  };
240  void bar() {
241  &foo::a^a;
242  }
243  )cpp",
244  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
245  {
246  R"cpp( // Class method reference - objec
247  struct foo {
248  void aa() {}
249  };
250  void bar() {
251  foo f;
252  f.a^a();
253  }
254  )cpp",
255  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
256  {
257  R"cpp( // Class method reference - pointer
258  struct foo {
259  void aa() {}
260  };
261  void bar() {
262  &foo::a^a;
263  }
264  )cpp",
265  {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
266  {
267  R"cpp( // Typedef
268  typedef int foo;
269  void bar() {
270  fo^o a;
271  }
272  )cpp",
273  {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@T@foo")}},
274  {
275  R"cpp( // Type alias
276  using foo = int;
277  void bar() {
278  fo^o a;
279  }
280  )cpp",
281  {CreateExpectedSymbolDetails("foo", "", "c:@foo")}},
282  {
283  R"cpp( // Namespace reference
284  namespace foo {}
285  using namespace fo^o;
286  )cpp",
287  {CreateExpectedSymbolDetails("foo", "", "c:@N@foo")}},
288  {
289  R"cpp( // Enum value reference
290  enum foo { bar, baz };
291  void f() {
292  foo fff = ba^r;
293  }
294  )cpp",
295  {CreateExpectedSymbolDetails("bar", "foo", "c:@E@foo@bar")}},
296  {
297  R"cpp( // Enum class value reference
298  enum class foo { bar, baz };
299  void f() {
300  foo fff = foo::ba^r;
301  }
302  )cpp",
303  {CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}},
304  {
305  R"cpp( // Parameters in declarations
306  void foo(int ba^r);
307  )cpp",
308  {CreateExpectedSymbolDetails("bar", "foo",
309  "c:TestTU.cpp@50@F@foo#I#@bar")}},
310  {
311  R"cpp( // Type inference with auto keyword
312  struct foo {};
313  foo getfoo() { return foo{}; }
314  void f() {
315  au^to a = getfoo();
316  }
317  )cpp",
318  {/* not implemented */}},
319  {
320  R"cpp( // decltype
321  struct foo {};
322  void f() {
323  foo f;
324  declt^ype(f);
325  }
326  )cpp",
327  {/* not implemented */}},
328  };
329 
330  for (const auto &T : TestInputExpectedOutput) {
331  Annotations TestInput(T.first);
332  auto AST = TestTU::withCode(TestInput.code()).build();
333 
334  EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),
335  UnorderedElementsAreArray(T.second))
336  << T.first;
337  }
338 }
339 
340 } // namespace
341 } // namespace clangd
342 } // namespace clang
XRefs.h
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:704
TestTU.h
lit.name
name
Definition: test/lit.cfg.py:6
clang::clangd::getSymbolInfo
std::vector< SymbolDetails > getSymbolInfo(ParsedAST &AST, Position Pos)
Get info about symbols at Pos.
Definition: XRefs.cpp:1123
TestFS.h
SyncAPI.h
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:30
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:35
FileIndex.h
Annotations.h
Compiler.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
SymbolCollector.h
Matchers.h
ParsedAST.h