summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/unittests/XRefsTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/unittests/XRefsTests.cpp')
-rw-r--r--clang-tools-extra/clangd/unittests/XRefsTests.cpp1339
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;
OpenPOWER on IntegriCloud