diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -253,7 +253,7 @@ )cpp", R"cpp(// Function definition via pointer - int [[foo]](int) {} + void [[foo]](int) {} int main() { auto *X = &^foo; } @@ -270,7 +270,7 @@ struct Foo { int [[x]]; }; int main() { Foo bar; - bar.^x; + (void)bar.^x; } )cpp", @@ -281,13 +281,6 @@ }; )cpp", - R"cpp(// Field, GNU old-style field designator - struct Foo { int [[x]]; }; - int main() { - Foo bar = { ^x : 1 }; - } - )cpp", - R"cpp(// Field, field designator struct Foo { int [[x]]; }; int main() { @@ -322,20 +315,12 @@ R"cpp(// Namespace namespace $decl[[ns]] { - struct Foo { static void bar(); } + struct Foo { static void bar(); }; } // namespace ns int main() { ^ns::Foo::bar(); } )cpp", R"cpp(// Macro - #define MACRO 0 - #define [[MACRO]] 1 - int main() { return ^MACRO; } - #define MACRO 2 - #undef macro - )cpp", - - R"cpp(// Macro class TTT { public: int a; }; #define [[FF]](S) if (int b = S.a) {} void f() { @@ -352,7 +337,7 @@ R"cpp(// Symbol concatenated inside macro (not supported) int *pi; - #define POINTER(X) p # X; + #define POINTER(X) p ## X; int i = *POINTER(^i); )cpp", @@ -433,10 +418,10 @@ )cpp", R"cpp(// No implicit constructors - class X { + struct X { X(X&& x) = default; }; - X [[makeX]]() {} + X $decl[[makeX]](); void foo() { auto x = m^akeX(); } @@ -444,7 +429,7 @@ R"cpp( struct X { - X& [[operator]]++() {} + X& $decl[[operator]]++(); }; void foo(X& x) { +^+x; @@ -530,6 +515,61 @@ TU.ExtraArgs.push_back("-fno-delayed-template-parsing"); auto AST = TU.build(); + for (auto &D : AST.getDiagnostics()) + ADD_FAILURE() << D; + ASSERT_TRUE(AST.getDiagnostics().empty()) << Test; + + auto Results = locateSymbolAt(AST, T.point()); + + if (!WantDecl) { + EXPECT_THAT(Results, IsEmpty()) << Test; + } else { + ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test; + EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test; + llvm::Optional GotDef; + if (Results[0].Definition) + GotDef = Results[0].Definition->range; + EXPECT_EQ(WantDef, GotDef) << Test; + } + } +} + +// LocateSymbol test cases that produce warnings. +// These are separated out from All so that in All we can assert +// that there are no diagnostics. +TEST(LocateSymbol, Warnings) { + const char *Tests[] = { + R"cpp(// Field, GNU old-style field designator + struct Foo { int [[x]]; }; + int main() { + Foo bar = { ^x : 1 }; + } + )cpp", + + R"cpp(// Macro + #define MACRO 0 + #define [[MACRO]] 1 + int main() { return ^MACRO; } + #define MACRO 2 + #undef macro + )cpp", + }; + + for (const char *Test : Tests) { + Annotations T(Test); + llvm::Optional WantDecl; + llvm::Optional WantDef; + if (!T.ranges().empty()) + WantDecl = WantDef = T.range(); + if (!T.ranges("decl").empty()) + WantDecl = T.range("decl"); + if (!T.ranges("def").empty()) + WantDef = T.range("def"); + + TestTU TU; + TU.Code = T.code(); + + auto AST = TU.build(); auto Results = locateSymbolAt(AST, T.point()); if (!WantDecl) {