diff options
Diffstat (limited to 'clang-tools-extra/clangd/unittests/XRefsTests.cpp')
-rw-r--r-- | clang-tools-extra/clangd/unittests/XRefsTests.cpp | 1339 |
1 files changed, 0 insertions, 1339 deletions
diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index 483f216ca66..b6115065d1b 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -603,1321 +603,6 @@ int [[bar_not_preamble]]; HeaderNotInPreambleAnnotations.range()))); } -TEST(Hover, Structured) { - struct { - const char *const Code; - const std::function<void(HoverInfo &)> ExpectedBuilder; - } Cases[] = { - // Global scope. - {R"cpp( - // Best foo ever. - void [[fo^o]]() {} - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "foo"; - HI.Kind = SymbolKind::Function; - HI.Documentation = "Best foo ever."; - HI.Definition = "void foo()"; - HI.ReturnType = "void"; - HI.Type = "void ()"; - HI.Parameters.emplace(); - }}, - // Inside namespace - {R"cpp( - namespace ns1 { namespace ns2 { - /// Best foo ever. - void [[fo^o]]() {} - }} - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = "ns1::ns2::"; - HI.Name = "foo"; - HI.Kind = SymbolKind::Function; - HI.Documentation = "Best foo ever."; - HI.Definition = "void foo()"; - HI.ReturnType = "void"; - HI.Type = "void ()"; - HI.Parameters.emplace(); - }}, - // Field - {R"cpp( - namespace ns1 { namespace ns2 { - struct Foo { - int [[b^ar]]; - }; - }} - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = "ns1::ns2::"; - HI.LocalScope = "Foo::"; - HI.Name = "bar"; - HI.Kind = SymbolKind::Field; - HI.Definition = "int bar"; - HI.Type = "int"; - }}, - // Local to class method. - {R"cpp( - namespace ns1 { namespace ns2 { - struct Foo { - void foo() { - int [[b^ar]]; - } - }; - }} - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = "ns1::ns2::"; - HI.LocalScope = "Foo::foo::"; - HI.Name = "bar"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "int bar"; - HI.Type = "int"; - }}, - // Anon namespace and local scope. - {R"cpp( - namespace ns1 { namespace { - struct { - int [[b^ar]]; - } T; - }} - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = "ns1::(anonymous)::"; - HI.LocalScope = "(anonymous struct)::"; - HI.Name = "bar"; - HI.Kind = SymbolKind::Field; - HI.Definition = "int bar"; - HI.Type = "int"; - }}, - // Variable with template type - {R"cpp( - template <typename T, class... Ts> class Foo { public: Foo(int); }; - Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5); - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "foo"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)"; - HI.Type = "Foo<int, char, bool>"; - }}, - // Implicit template instantiation - {R"cpp( - template <typename T> class vector{}; - [[vec^tor]]<int> foo; - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "vector"; - HI.Kind = SymbolKind::Class; - HI.Definition = "template <typename T> class vector {}"; - HI.TemplateParameters = { - {std::string("typename"), std::string("T"), llvm::None}, - }; - }}, - // Class template - {R"cpp( - template <template<typename, bool...> class C, - typename = char, - int = 0, - bool Q = false, - class... Ts> class Foo {}; - template <template<typename, bool...> class T> - [[F^oo]]<T> foo; - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "Foo"; - HI.Kind = SymbolKind::Class; - HI.Definition = - R"cpp(template <template <typename, bool...> class C, typename = char, int = 0, - bool Q = false, class... Ts> -class Foo {})cpp"; - HI.TemplateParameters = { - {std::string("template <typename, bool...> class"), - std::string("C"), llvm::None}, - {std::string("typename"), llvm::None, std::string("char")}, - {std::string("int"), llvm::None, std::string("0")}, - {std::string("bool"), std::string("Q"), std::string("false")}, - {std::string("class..."), std::string("Ts"), llvm::None}, - }; - }}, - // Function template - {R"cpp( - template <template<typename, bool...> class C, - typename = char, - int = 0, - bool Q = false, - class... Ts> void foo(); - template<typename, bool...> class Foo; - - void bar() { - [[fo^o]]<Foo>(); - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "foo"; - HI.Kind = SymbolKind::Function; - HI.Definition = - R"cpp(template <template <typename, bool...> class C, typename = char, int = 0, - bool Q = false, class... Ts> -void foo())cpp"; - HI.ReturnType = "void"; - HI.Type = "void ()"; - HI.Parameters.emplace(); - HI.TemplateParameters = { - {std::string("template <typename, bool...> class"), - std::string("C"), llvm::None}, - {std::string("typename"), llvm::None, std::string("char")}, - {std::string("int"), llvm::None, std::string("0")}, - {std::string("bool"), std::string("Q"), std::string("false")}, - {std::string("class..."), std::string("Ts"), llvm::None}, - }; - }}, - // Function decl - {R"cpp( - template<typename, bool...> class Foo {}; - Foo<bool, true, false> foo(int, bool T = false); - - void bar() { - [[fo^o]](3); - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "foo"; - HI.Kind = SymbolKind::Function; - HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)"; - HI.ReturnType = "Foo<bool, true, false>"; - HI.Type = "Foo<bool, true, false> (int, bool)"; - HI.Parameters = { - {std::string("int"), llvm::None, llvm::None}, - {std::string("bool"), std::string("T"), std::string("false")}, - }; - }}, - // Pointers to lambdas - {R"cpp( - void foo() { - auto lamb = [](int T, bool B) -> bool { return T && B; }; - auto *b = &lamb; - auto *[[^c]] = &b; - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.LocalScope = "foo::"; - HI.Name = "c"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "auto *c = &b"; - HI.Type = "class (lambda) **"; - HI.ReturnType = "bool"; - HI.Parameters = { - {std::string("int"), std::string("T"), llvm::None}, - {std::string("bool"), std::string("B"), llvm::None}, - }; - return HI; - }}, - // Lambda parameter with decltype reference - {R"cpp( - auto lamb = [](int T, bool B) -> bool { return T && B; }; - void foo(decltype(lamb)& bar) { - [[ba^r]](0, false); - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.LocalScope = "foo::"; - HI.Name = "bar"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "decltype(lamb) &bar"; - HI.Type = "decltype(lamb) &"; - HI.ReturnType = "bool"; - HI.Parameters = { - {std::string("int"), std::string("T"), llvm::None}, - {std::string("bool"), std::string("B"), llvm::None}, - }; - return HI; - }}, - // Lambda parameter with decltype - {R"cpp( - auto lamb = [](int T, bool B) -> bool { return T && B; }; - void foo(decltype(lamb) bar) { - [[ba^r]](0, false); - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.LocalScope = "foo::"; - HI.Name = "bar"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "decltype(lamb) bar"; - HI.Type = "class (lambda)"; - HI.ReturnType = "bool"; - HI.Parameters = { - {std::string("int"), std::string("T"), llvm::None}, - {std::string("bool"), std::string("B"), llvm::None}, - }; - return HI; - }}, - // Lambda variable - {R"cpp( - void foo() { - int bar = 5; - auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; }; - bool res = [[lam^b]](bar, false); - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.LocalScope = "foo::"; - HI.Name = "lamb"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}"; - HI.Type = "class (lambda)"; - HI.ReturnType = "bool"; - HI.Parameters = { - {std::string("int"), std::string("T"), llvm::None}, - {std::string("bool"), std::string("B"), llvm::None}, - }; - return HI; - }}, - // Local variable in lambda - {R"cpp( - void foo() { - auto lamb = []{int [[te^st]];}; - } - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.LocalScope = "foo::(anonymous class)::operator()::"; - HI.Name = "test"; - HI.Kind = SymbolKind::Variable; - HI.Definition = "int test"; - HI.Type = "int"; - }}, - // Partially-specialized class template. (formerly type-parameter-0-0) - {R"cpp( - template <typename T> class X; - template <typename T> class [[^X]]<T*> {}; - )cpp", - [](HoverInfo &HI) { - HI.Name = "X<T *>"; - HI.NamespaceScope = ""; - HI.Kind = SymbolKind::Class; - HI.Definition = "template <typename T> class X<T *> {}"; - }}, - // Constructor of partially-specialized class template - {R"cpp( - template<typename, typename=void> struct X; - template<typename T> struct X<T*>{ [[^X]](); }; - )cpp", - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "X"; - HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>:: - HI.Kind = SymbolKind::Constructor; - HI.ReturnType = "X<T *>"; - HI.Definition = "X()"; - HI.Parameters.emplace(); - }}, - {"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]() - [](HoverInfo &HI) { - HI.NamespaceScope = ""; - HI.Name = "~X"; - HI.LocalScope = "X::"; - HI.Kind = SymbolKind::Constructor; - HI.ReturnType = "void"; - HI.Definition = "~X()"; - HI.Parameters.emplace(); - }}, - - // auto on lambda - {R"cpp( - void foo() { - [[au^to]] lamb = []{}; - } - )cpp", - [](HoverInfo &HI) { - HI.Name = "class (lambda)"; - HI.Kind = SymbolKind::Variable; - }}, - // auto on template instantiation - {R"cpp( - template<typename T> class Foo{}; - void foo() { - [[au^to]] x = Foo<int>(); - } - )cpp", - [](HoverInfo &HI) { - HI.Name = "class Foo<int>"; - HI.Kind = SymbolKind::Variable; - }}, - // auto on specialized template - {R"cpp( - template<typename T> class Foo{}; - template<> class Foo<int>{}; - void foo() { - [[au^to]] x = Foo<int>(); - } - )cpp", - [](HoverInfo &HI) { - HI.Name = "class Foo<int>"; - HI.Kind = SymbolKind::Variable; - }}, - - // macro - {R"cpp( - // Best MACRO ever. - #define MACRO(x,y,z) void foo(x, y, z); - [[MAC^RO]](int, double d, bool z = false); - )cpp", - [](HoverInfo &HI) { - HI.Name = "MACRO", HI.Kind = SymbolKind::String, - HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);"; - }}, - - // constexprs - {R"cpp( - constexpr int add(int a, int b) { return a + b; } - int [[b^ar]] = add(1, 2); - )cpp", - [](HoverInfo &HI) { - HI.Name = "bar"; - HI.Definition = "int bar = add(1, 2)"; - HI.Kind = SymbolKind::Variable; - HI.Type = "int"; - HI.NamespaceScope = ""; - HI.Value = "3"; - }}, - {R"cpp( - int [[b^ar]] = sizeof(char); - )cpp", - [](HoverInfo &HI) { - HI.Name = "bar"; - HI.Definition = "int bar = sizeof(char)"; - HI.Kind = SymbolKind::Variable; - HI.Type = "int"; - HI.NamespaceScope = ""; - HI.Value = "1"; - }}, - {R"cpp( - template<int a, int b> struct Add { - static constexpr int result = a + b; - }; - int [[ba^r]] = Add<1, 2>::result; - )cpp", - [](HoverInfo &HI) { - HI.Name = "bar"; - HI.Definition = "int bar = Add<1, 2>::result"; - HI.Kind = SymbolKind::Variable; - HI.Type = "int"; - HI.NamespaceScope = ""; - HI.Value = "3"; - }}, - {R"cpp( - enum Color { RED, GREEN, }; - Color x = [[GR^EEN]]; - )cpp", - [](HoverInfo &HI) { - HI.Name = "GREEN"; - HI.NamespaceScope = ""; - HI.LocalScope = "Color::"; - HI.Definition = "GREEN"; - HI.Kind = SymbolKind::EnumMember; - HI.Type = "enum Color"; - HI.Value = "1"; - }}, - // FIXME: We should use the Decl referenced, even if from an implicit - // instantiation. Then the scope would be Add<1, 2> and the value 3. - {R"cpp( - template<int a, int b> struct Add { - static constexpr int result = a + b; - }; - int bar = Add<1, 2>::[[resu^lt]]; - )cpp", - [](HoverInfo &HI) { - HI.Name = "result"; - HI.Definition = "static constexpr int result = a + b"; - HI.Kind = SymbolKind::Property; - HI.Type = "const int"; - HI.NamespaceScope = ""; - HI.LocalScope = "Add<a, b>::"; - }}, - {R"cpp( - const char *[[ba^r]] = "1234"; - )cpp", - [](HoverInfo &HI) { - HI.Name = "bar"; - HI.Definition = "const char *bar = \"1234\""; - HI.Kind = SymbolKind::Variable; - HI.Type = "const char *"; - HI.NamespaceScope = ""; - HI.Value = "&\"1234\"[0]"; - }}, - }; - for (const auto &Case : Cases) { - SCOPED_TRACE(Case.Code); - - Annotations T(Case.Code); - TestTU TU = TestTU::withCode(T.code()); - TU.ExtraArgs.push_back("-std=c++17"); - auto AST = TU.build(); - ASSERT_TRUE(AST.getDiagnostics().empty()); - - auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); - ASSERT_TRUE(H); - HoverInfo Expected; - Expected.SymRange = T.range(); - Case.ExpectedBuilder(Expected); - - EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope); - EXPECT_EQ(H->LocalScope, Expected.LocalScope); - EXPECT_EQ(H->Name, Expected.Name); - EXPECT_EQ(H->Kind, Expected.Kind); - EXPECT_EQ(H->Documentation, Expected.Documentation); - EXPECT_EQ(H->Definition, Expected.Definition); - EXPECT_EQ(H->Type, Expected.Type); - EXPECT_EQ(H->ReturnType, Expected.ReturnType); - EXPECT_EQ(H->Parameters, Expected.Parameters); - EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters); - EXPECT_EQ(H->SymRange, Expected.SymRange); - EXPECT_EQ(H->Value, Expected.Value); - } -} // namespace clang - -TEST(Hover, All) { - struct OneTest { - StringRef Input; - StringRef ExpectedHover; - }; - - OneTest Tests[] = { - { - R"cpp(// No hover - ^int main() { - } - )cpp", - "", - }, - { - R"cpp(// Local variable - int main() { - int bonjour; - ^bonjour = 2; - int test1 = bonjour; - } - )cpp", - "text[Declared in]code[main]\n" - "codeblock(cpp) [\n" - "int bonjour\n" - "]", - }, - { - R"cpp(// Local variable in method - struct s { - void method() { - int bonjour; - ^bonjour = 2; - } - }; - )cpp", - "text[Declared in]code[s::method]\n" - "codeblock(cpp) [\n" - "int bonjour\n" - "]", - }, - { - R"cpp(// Struct - namespace ns1 { - struct MyClass {}; - } // namespace ns1 - int main() { - ns1::My^Class* Params; - } - )cpp", - "text[Declared in]code[ns1]\n" - "codeblock(cpp) [\n" - "struct MyClass {}\n" - "]", - }, - { - R"cpp(// Class - namespace ns1 { - class MyClass {}; - } // namespace ns1 - int main() { - ns1::My^Class* Params; - } - )cpp", - "text[Declared in]code[ns1]\n" - "codeblock(cpp) [\n" - "class MyClass {}\n" - "]", - }, - { - R"cpp(// Union - namespace ns1 { - union MyUnion { int x; int y; }; - } // namespace ns1 - int main() { - ns1::My^Union Params; - } - )cpp", - "text[Declared in]code[ns1]\n" - "codeblock(cpp) [\n" - "union MyUnion {}\n" - "]", - }, - { - R"cpp(// Function definition via pointer - int foo(int) {} - int main() { - auto *X = &^foo; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "int foo(int)\n" - "]\n" - "text[Function definition via pointer]", - }, - { - R"cpp(// Function declaration via call - int foo(int); - int main() { - return ^foo(42); - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "int foo(int)\n" - "]\n" - "text[Function declaration via call]", - }, - { - R"cpp(// Field - struct Foo { int x; }; - int main() { - Foo bar; - bar.^x; - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x\n" - "]", - }, - { - R"cpp(// Field with initialization - struct Foo { int x = 5; }; - int main() { - Foo bar; - bar.^x; - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x = 5\n" - "]", - }, - { - R"cpp(// Static field - struct Foo { static int x; }; - int main() { - Foo::^x; - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "static int x\n" - "]", - }, - { - R"cpp(// Field, member initializer - struct Foo { - int x; - Foo() : ^x(0) {} - }; - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x\n" - "]", - }, - { - R"cpp(// Field, GNU old-style field designator - struct Foo { int x; }; - int main() { - Foo bar = { ^x : 1 }; - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x\n" - "]", - }, - { - R"cpp(// Field, field designator - struct Foo { int x; }; - int main() { - Foo bar = { .^x = 2 }; - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x\n" - "]", - }, - { - R"cpp(// Method call - struct Foo { int x(); }; - int main() { - Foo bar; - bar.^x(); - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "int x()\n" - "]", - }, - { - R"cpp(// Static method call - struct Foo { static int x(); }; - int main() { - Foo::^x(); - } - )cpp", - "text[Declared in]code[Foo]\n" - "codeblock(cpp) [\n" - "static int x()\n" - "]", - }, - { - R"cpp(// Typedef - typedef int Foo; - int main() { - ^Foo bar; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "typedef int Foo\n" - "]\n" - "text[Typedef]", - }, - { - R"cpp(// Typedef with embedded definition - typedef struct Bar {} Foo; - int main() { - ^Foo bar; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "typedef struct Bar Foo\n" - "]\n" - "text[Typedef with embedded definition]", - }, - { - R"cpp(// Namespace - namespace ns { - struct Foo { static void bar(); } - } // namespace ns - int main() { ^ns::Foo::bar(); } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "namespace ns {}\n" - "]", - }, - { - R"cpp(// Anonymous namespace - namespace ns { - namespace { - int foo; - } // anonymous namespace - } // namespace ns - int main() { ns::f^oo++; } - )cpp", - "text[Declared in]code[ns::(anonymous)]\n" - "codeblock(cpp) [\n" - "int foo\n" - "]", - }, - { - R"cpp(// Macro - #define MACRO 0 - #define MACRO 1 - int main() { return ^MACRO; } - #define MACRO 2 - #undef macro - )cpp", - "codeblock(cpp) [\n" - "#define MACRO 1\n" - "]", - }, - { - R"cpp(// Macro - #define MACRO 0 - #define MACRO2 ^MACRO - )cpp", - "codeblock(cpp) [\n" - "#define MACRO 0\n" - "]", - }, - { - R"cpp(// Macro - #define MACRO {\ - return 0;\ - } - int main() ^MACRO - )cpp", - R"cpp(codeblock(cpp) [ -#define MACRO \ - { return 0; } -])cpp", - }, - { - R"cpp(// Forward class declaration - class Foo; - class Foo {}; - F^oo* foo(); - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "class Foo {}\n" - "]\n" - "text[Forward class declaration]", - }, - { - R"cpp(// Function declaration - void foo(); - void g() { f^oo(); } - void foo() {} - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "void foo()\n" - "]\n" - "text[Function declaration]", - }, - { - R"cpp(// Enum declaration - enum Hello { - ONE, TWO, THREE, - }; - void foo() { - Hel^lo hello = ONE; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "enum Hello {}\n" - "]\n" - "text[Enum declaration]", - }, - { - R"cpp(// Enumerator - enum Hello { - ONE, TWO, THREE, - }; - void foo() { - Hello hello = O^NE; - } - )cpp", - "text[Declared in]code[Hello]\n" - "codeblock(cpp) [\n" - "ONE\n" - "]", - }, - { - R"cpp(// Enumerator in anonymous enum - enum { - ONE, TWO, THREE, - }; - void foo() { - int hello = O^NE; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "ONE\n" - "]", - }, - { - R"cpp(// Global variable - static int hey = 10; - void foo() { - he^y++; - } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "static int hey = 10\n" - "]\n" - "text[Global variable]", - }, - { - R"cpp(// Global variable in namespace - namespace ns1 { - static int hey = 10; - } - void foo() { - ns1::he^y++; - } - )cpp", - "text[Declared in]code[ns1]\n" - "codeblock(cpp) [\n" - "static int hey = 10\n" - "]", - }, - { - R"cpp(// Field in anonymous struct - static struct { - int hello; - } s; - void foo() { - s.he^llo++; - } - )cpp", - "text[Declared in]code[(anonymous struct)]\n" - "codeblock(cpp) [\n" - "int hello\n" - "]", - }, - { - R"cpp(// Templated function - template <typename T> - T foo() { - return 17; - } - void g() { auto x = f^oo<int>(); } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "template <typename T> T foo()\n" - "]\n" - "text[Templated function]", - }, - { - R"cpp(// Anonymous union - struct outer { - union { - int abc, def; - } v; - }; - void g() { struct outer o; o.v.d^ef++; } - )cpp", - "text[Declared in]code[outer::(anonymous union)]\n" - "codeblock(cpp) [\n" - "int def\n" - "]", - }, - { - R"cpp(// documentation from index - int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs; - void indexSymbol(); - void g() { ind^exSymbol(); } - )cpp", - "text[Declared in]code[global namespace]\n" - "codeblock(cpp) [\n" - "void indexSymbol()\n" - "]\n" - "text[comment from index]", - }, - { - R"cpp(// Nothing - void foo() { - ^ - } - )cpp", - "", - }, - { - R"cpp(// Simple initialization with auto - void foo() { - ^auto i = 1; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with const auto - void foo() { - const ^auto i = 1; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with const auto& - void foo() { - const ^auto& i = 1; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with auto& - void foo() { - ^auto& i = 1; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with auto* - void foo() { - int a = 1; - ^auto* i = &a; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Auto with initializer list. - namespace std - { - template<class _E> - class initializer_list {}; - } - void foo() { - ^auto i = {1,2}; - } - )cpp", - "codeblock(cpp) [\n" - "class std::initializer_list<int>\n" - "]", - }, - { - R"cpp(// User defined conversion to auto - struct Bar { - operator ^auto() const { return 10; } - }; - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with decltype(auto) - void foo() { - ^decltype(auto) i = 1; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Simple initialization with const decltype(auto) - void foo() { - const int j = 0; - ^decltype(auto) i = j; - } - )cpp", - "codeblock(cpp) [\n" - "const int\n" - "]", - }, - { - R"cpp(// Simple initialization with const& decltype(auto) - void foo() { - int k = 0; - const int& j = k; - ^decltype(auto) i = j; - } - )cpp", - "codeblock(cpp) [\n" - "const int &\n" - "]", - }, - { - R"cpp(// Simple initialization with & decltype(auto) - void foo() { - int k = 0; - int& j = k; - ^decltype(auto) i = j; - } - )cpp", - "codeblock(cpp) [\n" - "int &\n" - "]", - }, - { - R"cpp(// decltype with initializer list: nothing - namespace std - { - template<class _E> - class initializer_list {}; - } - void foo() { - ^decltype(auto) i = {1,2}; - } - )cpp", - "", - }, - { - R"cpp(// simple trailing return type - ^auto main() -> int { - return 0; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// auto function return with trailing type - struct Bar {}; - ^auto test() -> decltype(Bar()) { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// trailing return type - struct Bar {}; - auto test() -> ^decltype(Bar()) { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// auto in function return - struct Bar {}; - ^auto test() { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// auto& in function return - struct Bar {}; - ^auto& test() { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// auto* in function return - struct Bar {}; - ^auto* test() { - Bar* bar; - return bar; - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// const auto& in function return - struct Bar {}; - const ^auto& test() { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// decltype(auto) in function return - struct Bar {}; - ^decltype(auto) test() { - return Bar(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// decltype(auto) reference in function return - struct Bar {}; - ^decltype(auto) test() { - int a; - return (a); - } - )cpp", - "codeblock(cpp) [\n" - "int &\n" - "]", - }, - { - R"cpp(// decltype lvalue reference - void foo() { - int I = 0; - ^decltype(I) J = I; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// decltype lvalue reference - void foo() { - int I= 0; - int &K = I; - ^decltype(K) J = I; - } - )cpp", - "codeblock(cpp) [\n" - "int &\n" - "]", - }, - { - R"cpp(// decltype lvalue reference parenthesis - void foo() { - int I = 0; - ^decltype((I)) J = I; - } - )cpp", - "codeblock(cpp) [\n" - "int &\n" - "]", - }, - { - R"cpp(// decltype rvalue reference - void foo() { - int I = 0; - ^decltype(static_cast<int&&>(I)) J = static_cast<int&&>(I); - } - )cpp", - "codeblock(cpp) [\n" - "int &&\n" - "]", - }, - { - R"cpp(// decltype rvalue reference function call - int && bar(); - void foo() { - int I = 0; - ^decltype(bar()) J = bar(); - } - )cpp", - "codeblock(cpp) [\n" - "int &&\n" - "]", - }, - { - R"cpp(// decltype of function with trailing return type. - struct Bar {}; - auto test() -> decltype(Bar()) { - return Bar(); - } - void foo() { - ^decltype(test()) i = test(); - } - )cpp", - "codeblock(cpp) [\n" - "struct Bar\n" - "]", - }, - { - R"cpp(// decltype of var with decltype. - void foo() { - int I = 0; - decltype(I) J = I; - ^decltype(J) K = J; - } - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// structured binding. Not supported yet - struct Bar {}; - void foo() { - Bar a[2]; - ^auto [x,y] = a; - } - )cpp", - "", - }, - { - R"cpp(// Template auto parameter. Nothing (Not useful). - template<^auto T> - void func() { - } - void foo() { - func<1>(); - } - )cpp", - "", - }, - { - R"cpp(// More compilcated structured types. - int bar(); - ^auto (*foo)() = bar; - )cpp", - "codeblock(cpp) [\n" - "int\n" - "]", - }, - { - R"cpp(// Should not crash when evaluating the initializer. - struct Test {}; - void test() { Test && te^st = {}; } - )cpp", - "text[Declared in]code[test]\n" - "codeblock(cpp) [\n" - "struct Test &&test = {}\n" - "]", - }, - }; - - // Create a tiny index, so tests above can verify documentation is fetched. - Symbol IndexSym = func("indexSymbol"); - IndexSym.Documentation = "comment from index"; - SymbolSlab::Builder Symbols; - Symbols.insert(IndexSym); - auto Index = - MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab()); - - for (const OneTest &Test : Tests) { - Annotations T(Test.Input); - TestTU TU = TestTU::withCode(T.code()); - TU.ExtraArgs.push_back("-std=c++17"); - auto AST = TU.build(); - if (auto H = - getHover(AST, T.point(), format::getLLVMStyle(), Index.get())) { - EXPECT_NE("", Test.ExpectedHover) << Test.Input; - EXPECT_EQ(H->present().renderForTests(), Test.ExpectedHover.str()) - << Test.Input; - } else - EXPECT_EQ("", Test.ExpectedHover.str()) << Test.Input; - } -} - TEST(GoToInclude, All) { MockFSProvider FS; IgnoreDiagnostics DiagConsumer; @@ -2256,30 +941,6 @@ TEST(FindReferences, NoQueryForLocalSymbols) { } } -TEST(GetDeducedType, KwAutoExpansion) { - struct Test { - StringRef AnnotatedCode; - const char *DeducedType; - } Tests[] = { - {"^auto i = 0;", "int"}, - {"^auto f(){ return 1;};", "int"}, - }; - for (Test T : Tests) { - Annotations File(T.AnnotatedCode); - auto AST = TestTU::withCode(File.code()).build(); - ASSERT_TRUE(AST.getDiagnostics().empty()) - << AST.getDiagnostics().begin()->Message; - SourceManagerForFile SM("foo.cpp", File.code()); - - for (Position Pos : File.points()) { - auto Location = sourceLocationInMainFile(SM.get(), Pos); - ASSERT_TRUE(!!Location) << llvm::toString(Location.takeError()); - auto DeducedType = getDeducedType(AST, *Location); - EXPECT_EQ(DeducedType->getAsString(), T.DeducedType); - } - } -} - TEST(GetNonLocalDeclRefs, All) { struct Case { llvm::StringRef AnnotatedCode; |