[TableGen] Fix validateOperandClass for non Phyical Reg (#118146)
[llvm-project.git] / clang-tools-extra / clangd / unittests / SymbolInfoTests.cpp
blob6c91f3783a6220af8500f894f3667213dca064e3
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 "ParsedAST.h"
10 #include "TestTU.h"
11 #include "XRefs.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 #include <optional>
16 namespace clang {
17 namespace clangd {
18 namespace {
20 using ::testing::UnorderedElementsAreArray;
22 // Partial SymbolDetails with the rest filled in at testing time.
23 struct ExpectedSymbolDetails {
24 std::string Name;
25 std::string Container;
26 std::string USR;
27 const char *DeclMarker = nullptr;
28 const char *DefMarker = nullptr;
31 TEST(SymbolInfoTests, All) {
32 std::pair<const char *, std::vector<ExpectedSymbolDetails>>
33 TestInputExpectedOutput[] = {
35 R"cpp( // Simple function reference - declaration
36 void $decl[[foo]]();
37 int bar() {
38 fo^o();
40 )cpp",
41 {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},
43 R"cpp( // Simple function reference - definition
44 void $def[[foo]]() {}
45 int bar() {
46 fo^o();
48 )cpp",
49 {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"}}},
51 R"cpp( // Simple function reference - decl and def
52 void $decl[[foo]]();
53 void $def[[foo]]() {}
54 int bar() {
55 fo^o();
57 )cpp",
58 {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl", "def"}}},
60 R"cpp( // Simple class reference - decl and def
61 @interface $decl[[Foo]]
62 @end
63 @implementation $def[[Foo]]
64 @end
65 void doSomething(F^oo *obj) {}
66 )cpp",
67 {ExpectedSymbolDetails{"Foo", "", "c:objc(cs)Foo", "decl",
68 "def"}}},
70 R"cpp( // Simple method reference - decl and def
71 @interface Foo
72 - (void)$decl[[foo]];
73 @end
74 @implementation Foo
75 - (void)$def[[fo^o]] {}
76 @end
77 )cpp",
78 {ExpectedSymbolDetails{"foo", "Foo::", "c:objc(cs)Foo(im)foo",
79 "decl", "def"}}},
81 R"cpp( // Function in namespace reference
82 namespace bar {
83 void $decl[[foo]]();
84 int baz() {
85 fo^o();
88 )cpp",
89 {ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",
90 "decl"}}},
92 R"cpp( // Function in different namespace reference
93 namespace bar {
94 void $decl[[foo]]();
96 namespace barbar {
97 int baz() {
98 bar::fo^o();
101 )cpp",
102 {ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",
103 "decl"}}},
105 R"cpp( // Function in global namespace reference
106 void $decl[[foo]]();
107 namespace Nbar {
108 namespace Nbaz {
109 int baz() {
110 ::fo^o();
114 )cpp",
115 {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},
117 R"cpp( // Function in anonymous namespace reference
118 namespace {
119 void $decl[[foo]]();
121 namespace barbar {
122 int baz() {
123 fo^o();
126 )cpp",
127 {ExpectedSymbolDetails{"foo", "(anonymous)",
128 "c:TestTU.cpp@aN@F@foo#", "decl"}}},
130 R"cpp( // Function reference - ADL
131 namespace bar {
132 struct BarType {};
133 void $decl[[foo]](const BarType&);
135 namespace barbar {
136 int baz() {
137 bar::BarType b;
138 fo^o(b);
141 )cpp",
142 {ExpectedSymbolDetails{
143 "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#",
144 "decl"}}},
146 R"cpp( // Global value reference
147 int $def[[value]];
148 void foo(int) { }
149 void bar() {
150 foo(val^ue);
152 )cpp",
153 {ExpectedSymbolDetails{"value", "", "c:@value", "def", "def"}}},
155 R"cpp( // Local value reference
156 void foo() { int $def[[aaa]]; int bbb = aa^a; }
157 )cpp",
158 {ExpectedSymbolDetails{"aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa",
159 "def", "def"}}},
161 R"cpp( // Function param
162 void bar(int $def[[aaa]]) {
163 int bbb = a^aa;
165 )cpp",
166 {ExpectedSymbolDetails{
167 "aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa", "def", "def"}}},
169 R"cpp( // Lambda capture
170 void foo() {
171 int $def[[ii]];
172 auto lam = [ii]() {
173 return i^i;
176 )cpp",
177 {ExpectedSymbolDetails{"ii", "foo", "c:TestTU.cpp@54@F@foo#@ii",
178 "def", "def"}}},
180 R"cpp( // Macro reference
181 #define MACRO 5\nint i = MAC^RO;
182 )cpp",
183 {ExpectedSymbolDetails{"MACRO", "",
184 "c:TestTU.cpp@38@macro@MACRO"}}},
186 R"cpp( // Macro reference
187 #define MACRO 5\nint i = MACRO^;
188 )cpp",
189 {ExpectedSymbolDetails{"MACRO", "",
190 "c:TestTU.cpp@38@macro@MACRO"}}},
192 R"cpp( // Multiple symbols returned - using overloaded function name
193 void $def[[foo]]() {}
194 void $def_bool[[foo]](bool) {}
195 void $def_int[[foo]](int) {}
196 namespace bar {
197 using ::$decl[[fo^o]];
199 )cpp",
200 {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"},
201 ExpectedSymbolDetails{"foo", "", "c:@F@foo#b#", "def_bool",
202 "def_bool"},
203 ExpectedSymbolDetails{"foo", "", "c:@F@foo#I#", "def_int",
204 "def_int"},
205 ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@UD@foo",
206 "decl"}}},
208 R"cpp( // Multiple symbols returned - implicit conversion
209 struct foo {};
210 struct bar {
211 bar(const foo&) {}
213 void func_baz1(bar) {}
214 void func_baz2() {
215 foo $def[[ff]];
216 func_baz1(f^f);
218 )cpp",
219 {ExpectedSymbolDetails{"ff", "func_baz2",
220 "c:TestTU.cpp@218@F@func_baz2#@ff", "def",
221 "def"}}},
223 R"cpp( // Type reference - declaration
224 struct $decl[[foo]];
225 void bar(fo^o*);
226 )cpp",
227 {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "decl"}}},
229 R"cpp( // Type reference - definition
230 struct $def[[foo]] {};
231 void bar(fo^o*);
232 )cpp",
233 {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},
235 R"cpp( // Type Reference - template argument
236 struct $def[[foo]] {};
237 template<class T> struct bar {};
238 void baz() {
239 bar<fo^o> b;
241 )cpp",
242 {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},
244 R"cpp( // Template parameter reference - type param
245 template<class $def[[TT]]> struct bar {
246 T^T t;
248 )cpp",
249 {ExpectedSymbolDetails{"TT", "bar::", "c:TestTU.cpp@65", "def",
250 "def"}}},
252 R"cpp( // Template parameter reference - type param
253 template<int $def[[NN]]> struct bar {
254 int a = N^N;
256 )cpp",
257 {ExpectedSymbolDetails{"NN", "bar::", "c:TestTU.cpp@65", "def",
258 "def"}}},
260 R"cpp( // Class member reference - objec
261 struct foo {
262 int $def[[aa]];
264 void bar() {
265 foo f;
266 f.a^a;
268 )cpp",
269 {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",
270 "def"}}},
272 R"cpp( // Class member reference - pointer
273 struct foo {
274 int $def[[aa]];
276 void bar() {
277 &foo::a^a;
279 )cpp",
280 {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",
281 "def"}}},
283 R"cpp( // Class method reference - objec
284 struct foo {
285 void $def[[aa]]() {}
287 void bar() {
288 foo f;
289 f.a^a();
291 )cpp",
292 {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",
293 "def"}}},
295 R"cpp( // Class method reference - pointer
296 struct foo {
297 void $def[[aa]]() {}
299 void bar() {
300 &foo::a^a;
302 )cpp",
303 {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",
304 "def"}}},
306 R"cpp( // Typedef
307 typedef int $decl[[foo]];
308 void bar() {
309 fo^o a;
311 )cpp",
312 {ExpectedSymbolDetails{"foo", "", "c:TestTU.cpp@T@foo", "decl"}}},
314 R"cpp( // Type alias
315 using $decl[[foo]] = int;
316 void bar() {
317 fo^o a;
319 )cpp",
320 {ExpectedSymbolDetails{"foo", "", "c:@foo", "decl"}}},
322 R"cpp( // Namespace reference
323 namespace $decl[[foo]] {}
324 using namespace fo^o;
325 )cpp",
326 {ExpectedSymbolDetails{"foo", "", "c:@N@foo", "decl"}}},
328 R"cpp( // Enum value reference
329 enum foo { $def[[bar]], baz };
330 void f() {
331 foo fff = ba^r;
333 )cpp",
334 {ExpectedSymbolDetails{"bar", "foo", "c:@E@foo@bar", "def",
335 "def"}}},
337 R"cpp( // Enum class value reference
338 enum class foo { $def[[bar]], baz };
339 void f() {
340 foo fff = foo::ba^r;
342 )cpp",
343 {ExpectedSymbolDetails{"bar", "foo::", "c:@E@foo@bar", "def",
344 "def"}}},
346 R"cpp( // Parameters in declarations
347 void foo(int $def[[ba^r]]);
348 )cpp",
349 {ExpectedSymbolDetails{
350 "bar", "foo", "c:TestTU.cpp@50@F@foo#I#@bar", "def", "def"}}},
352 R"cpp( // Type inference with auto keyword
353 struct foo {};
354 foo getfoo() { return foo{}; }
355 void f() {
356 au^to a = getfoo();
358 )cpp",
359 {/* not implemented */}},
361 R"cpp( // decltype
362 struct foo {};
363 void f() {
364 foo f;
365 declt^ype(f);
367 )cpp",
368 {/* not implemented */}},
371 for (const auto &T : TestInputExpectedOutput) {
372 Annotations TestInput(T.first);
373 TestTU TU;
374 TU.Code = std::string(TestInput.code());
375 TU.ExtraArgs.push_back("-xobjective-c++");
376 auto AST = TU.build();
378 std::vector<SymbolDetails> Expected;
379 for (const auto &Sym : T.second) {
380 std::optional<Location> Decl, Def;
381 if (Sym.DeclMarker)
382 Decl = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),
383 TestInput.range(Sym.DeclMarker)};
384 if (Sym.DefMarker)
385 Def = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),
386 TestInput.range(Sym.DefMarker)};
387 Expected.push_back(
388 {Sym.Name, Sym.Container, Sym.USR, SymbolID(Sym.USR), Decl, Def});
391 EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),
392 UnorderedElementsAreArray(Expected))
393 << T.first;
397 } // namespace
398 } // namespace clangd
399 } // namespace clang