1 //===-- SymbolInfoTests.cpp -----------------------*- C++ -*--------------===//
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
7 //===----------------------------------------------------------------------===//
8 #include "Annotations.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
20 using ::testing::UnorderedElementsAreArray
;
22 // Partial SymbolDetails with the rest filled in at testing time.
23 struct ExpectedSymbolDetails
{
25 std::string Container
;
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
41 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl"}}},
43 R
"cpp( // Simple function reference - definition
49 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "def", "def"}}},
51 R
"cpp( // Simple function reference - decl and def
58 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl", "def"}}},
60 R
"cpp( // Simple class reference - decl and def
61 @interface $decl[[Foo]]
63 @implementation $def[[Foo]]
65 void doSomething(F^oo *obj) {}
67 {ExpectedSymbolDetails
{"Foo", "", "c:objc(cs)Foo", "decl",
70 R
"cpp( // Simple method reference - decl and def
75 - (void)$def[[fo^o]] {}
78 {ExpectedSymbolDetails
{"foo", "Foo::", "c:objc(cs)Foo(im)foo",
81 R
"cpp( // Function in namespace reference
89 {ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@F@foo#",
92 R
"cpp( // Function in different namespace reference
102 {ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@F@foo#",
105 R
"cpp( // Function in global namespace reference
115 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl"}}},
117 R
"cpp( // Function in anonymous namespace reference
127 {ExpectedSymbolDetails
{"foo", "(anonymous)",
128 "c:TestTU.cpp@aN@F@foo#", "decl"}}},
130 R
"cpp( // Function reference - ADL
133 void $decl[[foo]](const BarType&);
142 {ExpectedSymbolDetails
{
143 "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#",
146 R
"cpp( // Global value reference
153 {ExpectedSymbolDetails
{"value", "", "c:@value", "def", "def"}}},
155 R
"cpp( // Local value reference
156 void foo() { int $def[[aaa]]; int bbb = aa^a; }
158 {ExpectedSymbolDetails
{"aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa",
161 R
"cpp( // Function param
162 void bar(int $def[[aaa]]) {
166 {ExpectedSymbolDetails
{
167 "aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa", "def", "def"}}},
169 R
"cpp( // Lambda capture
177 {ExpectedSymbolDetails
{"ii", "foo", "c:TestTU.cpp@54@F@foo#@ii",
180 R
"cpp( // Macro reference
181 #define MACRO 5\nint i = MAC^RO;
183 {ExpectedSymbolDetails
{"MACRO", "",
184 "c:TestTU.cpp@38@macro@MACRO"}}},
186 R
"cpp( // Macro reference
187 #define MACRO 5\nint i = MACRO^;
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) {}
197 using ::$decl[[fo^o]];
200 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "def", "def"},
201 ExpectedSymbolDetails
{"foo", "", "c:@F@foo#b#", "def_bool",
203 ExpectedSymbolDetails
{"foo", "", "c:@F@foo#I#", "def_int",
205 ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@UD@foo",
208 R
"cpp( // Multiple symbols returned - implicit conversion
213 void func_baz1(bar) {}
219 {ExpectedSymbolDetails
{"ff", "func_baz2",
220 "c:TestTU.cpp@218@F@func_baz2#@ff", "def",
223 R
"cpp( // Type reference - declaration
227 {ExpectedSymbolDetails
{"foo", "", "c:@S@foo", "decl"}}},
229 R
"cpp( // Type reference - definition
230 struct $def[[foo]] {};
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 {};
242 {ExpectedSymbolDetails
{"foo", "", "c:@S@foo", "def", "def"}}},
244 R
"cpp( // Template parameter reference - type param
245 template<class $def[[TT]]> struct bar {
249 {ExpectedSymbolDetails
{"TT", "bar::", "c:TestTU.cpp@65", "def",
252 R
"cpp( // Template parameter reference - type param
253 template<int $def[[NN]]> struct bar {
257 {ExpectedSymbolDetails
{"NN", "bar::", "c:TestTU.cpp@65", "def",
260 R
"cpp( // Class member reference - objec
269 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@FI@aa", "def",
272 R
"cpp( // Class member reference - pointer
280 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@FI@aa", "def",
283 R
"cpp( // Class method reference - objec
292 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@F@aa#", "def",
295 R
"cpp( // Class method reference - pointer
303 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@F@aa#", "def",
307 typedef int $decl[[foo]];
312 {ExpectedSymbolDetails
{"foo", "", "c:TestTU.cpp@T@foo", "decl"}}},
315 using $decl[[foo]] = int;
320 {ExpectedSymbolDetails
{"foo", "", "c:@foo", "decl"}}},
322 R
"cpp( // Namespace reference
323 namespace $decl[[foo]] {}
324 using namespace fo^o;
326 {ExpectedSymbolDetails
{"foo", "", "c:@N@foo", "decl"}}},
328 R
"cpp( // Enum value reference
329 enum foo { $def[[bar]], baz };
334 {ExpectedSymbolDetails
{"bar", "foo", "c:@E@foo@bar", "def",
337 R
"cpp( // Enum class value reference
338 enum class foo { $def[[bar]], baz };
343 {ExpectedSymbolDetails
{"bar", "foo::", "c:@E@foo@bar", "def",
346 R
"cpp( // Parameters in declarations
347 void foo(int $def[[ba^r]]);
349 {ExpectedSymbolDetails
{
350 "bar", "foo", "c:TestTU.cpp@50@F@foo#I#@bar", "def", "def"}}},
352 R
"cpp( // Type inference with auto keyword
354 foo getfoo() { return foo{}; }
359 {/* not implemented */}},
368 {/* not implemented */}},
371 for (const auto &T
: TestInputExpectedOutput
) {
372 Annotations
TestInput(T
.first
);
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
;
382 Decl
= Location
{URIForFile::canonicalize(testPath(TU
.Filename
), ""),
383 TestInput
.range(Sym
.DeclMarker
)};
385 Def
= Location
{URIForFile::canonicalize(testPath(TU
.Filename
), ""),
386 TestInput
.range(Sym
.DefMarker
)};
388 {Sym
.Name
, Sym
.Container
, Sym
.USR
, SymbolID(Sym
.USR
), Decl
, Def
});
391 EXPECT_THAT(getSymbolInfo(AST
, TestInput
.point()),
392 UnorderedElementsAreArray(Expected
))
398 } // namespace clangd