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"
19 using ::testing::UnorderedElementsAreArray
;
21 // Partial SymbolDetails with the rest filled in at testing time.
22 struct ExpectedSymbolDetails
{
24 std::string Container
;
26 const char *DeclMarker
= nullptr;
27 const char *DefMarker
= nullptr;
30 TEST(SymbolInfoTests
, All
) {
31 std::pair
<const char *, std::vector
<ExpectedSymbolDetails
>>
32 TestInputExpectedOutput
[] = {
34 R
"cpp( // Simple function reference - declaration
40 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl"}}},
42 R
"cpp( // Simple function reference - definition
48 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "def", "def"}}},
50 R
"cpp( // Simple function reference - decl and def
57 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl", "def"}}},
59 R
"cpp( // Simple class reference - decl and def
60 @interface $decl[[Foo]]
62 @implementation $def[[Foo]]
64 void doSomething(F^oo *obj) {}
66 {ExpectedSymbolDetails
{"Foo", "", "c:objc(cs)Foo", "decl",
69 R
"cpp( // Simple method reference - decl and def
74 - (void)$def[[fo^o]] {}
77 {ExpectedSymbolDetails
{"foo", "Foo::", "c:objc(cs)Foo(im)foo",
80 R
"cpp( // Function in namespace reference
88 {ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@F@foo#",
91 R
"cpp( // Function in different namespace reference
101 {ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@F@foo#",
104 R
"cpp( // Function in global namespace reference
114 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "decl"}}},
116 R
"cpp( // Function in anonymous namespace reference
126 {ExpectedSymbolDetails
{"foo", "(anonymous)",
127 "c:TestTU.cpp@aN@F@foo#", "decl"}}},
129 R
"cpp( // Function reference - ADL
132 void $decl[[foo]](const BarType&);
141 {ExpectedSymbolDetails
{
142 "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#",
145 R
"cpp( // Global value reference
152 {ExpectedSymbolDetails
{"value", "", "c:@value", "def", "def"}}},
154 R
"cpp( // Local value reference
155 void foo() { int $def[[aaa]]; int bbb = aa^a; }
157 {ExpectedSymbolDetails
{"aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa",
160 R
"cpp( // Function param
161 void bar(int $def[[aaa]]) {
165 {ExpectedSymbolDetails
{
166 "aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa", "def", "def"}}},
168 R
"cpp( // Lambda capture
176 {ExpectedSymbolDetails
{"ii", "foo", "c:TestTU.cpp@54@F@foo#@ii",
179 R
"cpp( // Macro reference
180 #define MACRO 5\nint i = MAC^RO;
182 {ExpectedSymbolDetails
{"MACRO", "",
183 "c:TestTU.cpp@38@macro@MACRO"}}},
185 R
"cpp( // Macro reference
186 #define MACRO 5\nint i = MACRO^;
188 {ExpectedSymbolDetails
{"MACRO", "",
189 "c:TestTU.cpp@38@macro@MACRO"}}},
191 R
"cpp( // Multiple symbols returned - using overloaded function name
192 void $def[[foo]]() {}
193 void $def_bool[[foo]](bool) {}
194 void $def_int[[foo]](int) {}
196 using ::$decl[[fo^o]];
199 {ExpectedSymbolDetails
{"foo", "", "c:@F@foo#", "def", "def"},
200 ExpectedSymbolDetails
{"foo", "", "c:@F@foo#b#", "def_bool",
202 ExpectedSymbolDetails
{"foo", "", "c:@F@foo#I#", "def_int",
204 ExpectedSymbolDetails
{"foo", "bar::", "c:@N@bar@UD@foo",
207 R
"cpp( // Multiple symbols returned - implicit conversion
212 void func_baz1(bar) {}
218 {ExpectedSymbolDetails
{"ff", "func_baz2",
219 "c:TestTU.cpp@218@F@func_baz2#@ff", "def",
222 R
"cpp( // Type reference - declaration
226 {ExpectedSymbolDetails
{"foo", "", "c:@S@foo", "decl"}}},
228 R
"cpp( // Type reference - definition
229 struct $def[[foo]] {};
232 {ExpectedSymbolDetails
{"foo", "", "c:@S@foo", "def", "def"}}},
234 R
"cpp( // Type Reference - template argument
235 struct $def[[foo]] {};
236 template<class T> struct bar {};
241 {ExpectedSymbolDetails
{"foo", "", "c:@S@foo", "def", "def"}}},
243 R
"cpp( // Template parameter reference - type param
244 template<class $def[[TT]]> struct bar {
248 {ExpectedSymbolDetails
{"TT", "bar::", "c:TestTU.cpp@65", "def",
251 R
"cpp( // Template parameter reference - type param
252 template<int $def[[NN]]> struct bar {
256 {ExpectedSymbolDetails
{"NN", "bar::", "c:TestTU.cpp@65", "def",
259 R
"cpp( // Class member reference - objec
268 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@FI@aa", "def",
271 R
"cpp( // Class member reference - pointer
279 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@FI@aa", "def",
282 R
"cpp( // Class method reference - objec
291 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@F@aa#", "def",
294 R
"cpp( // Class method reference - pointer
302 {ExpectedSymbolDetails
{"aa", "foo::", "c:@S@foo@F@aa#", "def",
306 typedef int $decl[[foo]];
311 {ExpectedSymbolDetails
{"foo", "", "c:TestTU.cpp@T@foo", "decl"}}},
314 using $decl[[foo]] = int;
319 {ExpectedSymbolDetails
{"foo", "", "c:@foo", "decl"}}},
321 R
"cpp( // Namespace reference
322 namespace $decl[[foo]] {}
323 using namespace fo^o;
325 {ExpectedSymbolDetails
{"foo", "", "c:@N@foo", "decl"}}},
327 R
"cpp( // Enum value reference
328 enum foo { $def[[bar]], baz };
333 {ExpectedSymbolDetails
{"bar", "foo", "c:@E@foo@bar", "def",
336 R
"cpp( // Enum class value reference
337 enum class foo { $def[[bar]], baz };
342 {ExpectedSymbolDetails
{"bar", "foo::", "c:@E@foo@bar", "def",
345 R
"cpp( // Parameters in declarations
346 void foo(int $def[[ba^r]]);
348 {ExpectedSymbolDetails
{
349 "bar", "foo", "c:TestTU.cpp@50@F@foo#I#@bar", "def", "def"}}},
351 R
"cpp( // Type inference with auto keyword
353 foo getfoo() { return foo{}; }
358 {/* not implemented */}},
367 {/* not implemented */}},
370 for (const auto &T
: TestInputExpectedOutput
) {
371 Annotations
TestInput(T
.first
);
373 TU
.Code
= std::string(TestInput
.code());
374 TU
.ExtraArgs
.push_back("-xobjective-c++");
375 auto AST
= TU
.build();
377 std::vector
<SymbolDetails
> Expected
;
378 for (const auto &Sym
: T
.second
) {
379 llvm::Optional
<Location
> Decl
, Def
;
381 Decl
= Location
{URIForFile::canonicalize(testPath(TU
.Filename
), ""),
382 TestInput
.range(Sym
.DeclMarker
)};
384 Def
= Location
{URIForFile::canonicalize(testPath(TU
.Filename
), ""),
385 TestInput
.range(Sym
.DefMarker
)};
387 {Sym
.Name
, Sym
.Container
, Sym
.USR
, SymbolID(Sym
.USR
), Decl
, Def
});
390 EXPECT_THAT(getSymbolInfo(AST
, TestInput
.point()),
391 UnorderedElementsAreArray(Expected
))
397 } // namespace clangd