xref: /llvm-project/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp (revision 9ef2ac3ad1bd5aa9e589f63047e8abeac11ad1b2)
15934a791SAdam Czachorowski //===-- AddUsingTests.cpp ---------------------------------------*- C++ -*-===//
25934a791SAdam Czachorowski //
35934a791SAdam Czachorowski // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45934a791SAdam Czachorowski // See https://llvm.org/LICENSE.txt for license information.
55934a791SAdam Czachorowski // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65934a791SAdam Czachorowski //
75934a791SAdam Czachorowski //===----------------------------------------------------------------------===//
85934a791SAdam Czachorowski 
95934a791SAdam Czachorowski #include "Config.h"
105934a791SAdam Czachorowski #include "TweakTesting.h"
11029ec03aSKadir Cetinkaya #include "support/Context.h"
1235c2aac6SKadir Cetinkaya #include "llvm/ADT/StringMap.h"
1335c2aac6SKadir Cetinkaya #include "llvm/ADT/StringRef.h"
145934a791SAdam Czachorowski #include "gtest/gtest.h"
1535c2aac6SKadir Cetinkaya #include <string>
16029ec03aSKadir Cetinkaya #include <utility>
175934a791SAdam Czachorowski 
185934a791SAdam Czachorowski namespace clang {
195934a791SAdam Czachorowski namespace clangd {
205934a791SAdam Czachorowski namespace {
215934a791SAdam Czachorowski 
225934a791SAdam Czachorowski TWEAK_TEST(AddUsing);
235934a791SAdam Czachorowski 
TEST_F(AddUsingTest,Prepare)245934a791SAdam Czachorowski TEST_F(AddUsingTest, Prepare) {
255934a791SAdam Czachorowski   Config Cfg;
265934a791SAdam Czachorowski   Cfg.Style.FullyQualifiedNamespaces.push_back("ban");
275934a791SAdam Czachorowski   WithContextValue WithConfig(Config::Key, std::move(Cfg));
285934a791SAdam Czachorowski 
295934a791SAdam Czachorowski   const std::string Header = R"cpp(
305934a791SAdam Czachorowski #define NS(name) one::two::name
315934a791SAdam Czachorowski namespace ban { void foo() {} }
325934a791SAdam Czachorowski namespace banana { void foo() {} }
335934a791SAdam Czachorowski namespace one {
345934a791SAdam Czachorowski void oo() {}
355934a791SAdam Czachorowski template<typename TT> class tt {};
365934a791SAdam Czachorowski namespace two {
3735c2aac6SKadir Cetinkaya enum ee { ee_enum_value };
385934a791SAdam Czachorowski void ff() {}
395934a791SAdam Czachorowski class cc {
405934a791SAdam Czachorowski public:
415934a791SAdam Czachorowski   struct st {};
425934a791SAdam Czachorowski   static void mm() {}
435934a791SAdam Czachorowski   cc operator|(const cc& x) const { return x; }
445934a791SAdam Czachorowski };
455934a791SAdam Czachorowski }
465934a791SAdam Czachorowski })cpp";
475934a791SAdam Czachorowski 
485934a791SAdam Czachorowski   EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^f^f(); }");
495934a791SAdam Czachorowski   EXPECT_AVAILABLE(Header + "void fun() { o^n^e^::^o^o(); }");
505934a791SAdam Czachorowski   EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^e^e E; }");
515934a791SAdam Czachorowski   EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o:^:^c^c C; }");
525934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header +
535934a791SAdam Czachorowski                      "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }");
545934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header +
555934a791SAdam Czachorowski                      "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
565934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header +
575934a791SAdam Czachorowski                      "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
585934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "void fun() { N^S(c^c) inst; }");
595934a791SAdam Czachorowski   // This used to crash. Ideally we would support this case, but for now we just
605934a791SAdam Czachorowski   // test that we don't crash.
615934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header +
625934a791SAdam Czachorowski                      "template<typename TT> using foo = one::tt<T^T>;");
635934a791SAdam Czachorowski   // Test that we don't crash or misbehave on unnamed DeclRefExpr.
645934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header +
655934a791SAdam Czachorowski                      "void fun() { one::two::cc() ^| one::two::cc(); }");
665934a791SAdam Czachorowski   // Do not offer code action when operating on a banned namespace.
675934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "void fun() { ban::fo^o(); }");
685934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "void fun() { ::ban::fo^o(); }");
695934a791SAdam Czachorowski   EXPECT_AVAILABLE(Header + "void fun() { banana::fo^o(); }");
705934a791SAdam Czachorowski 
715934a791SAdam Czachorowski   // NestedNameSpecifier, but no namespace.
725934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "class Foo {}; class F^oo foo;");
735934a791SAdam Czachorowski 
749841daf2SKadir Cetinkaya   // Nested macro case.
759841daf2SKadir Cetinkaya   EXPECT_AVAILABLE(R"cpp(
769841daf2SKadir Cetinkaya   #define ID2(X) X
779841daf2SKadir Cetinkaya   #define ID(Y, X) Y;ID2(X)
789841daf2SKadir Cetinkaya   namespace ns { struct Foo{}; }
799841daf2SKadir Cetinkaya   ID(int xyz, ns::F^oo) f;)cpp");
809841daf2SKadir Cetinkaya 
815934a791SAdam Czachorowski   // Check that we do not trigger in header files.
825934a791SAdam Czachorowski   FileName = "test.h";
835934a791SAdam Czachorowski   ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default.
845934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
855934a791SAdam Czachorowski   FileName = "test.hpp";
865934a791SAdam Czachorowski   EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
875934a791SAdam Czachorowski }
885934a791SAdam Czachorowski 
TEST_F(AddUsingTest,Crash1072)8946dbd19aSSam McCall TEST_F(AddUsingTest, Crash1072) {
9046dbd19aSSam McCall   // Used to crash when traversing catch(...)
9146dbd19aSSam McCall   // https://github.com/clangd/clangd/issues/1072
9246dbd19aSSam McCall   const char *Code = R"cpp(
9346dbd19aSSam McCall   namespace ns { class A; }
9446dbd19aSSam McCall   ns::^A *err;
9546dbd19aSSam McCall   void catchall() {
9646dbd19aSSam McCall     try {} catch(...) {}
9746dbd19aSSam McCall   }
9846dbd19aSSam McCall   )cpp";
9946dbd19aSSam McCall   EXPECT_AVAILABLE(Code);
10046dbd19aSSam McCall }
10146dbd19aSSam McCall 
TEST_F(AddUsingTest,Apply)1025934a791SAdam Czachorowski TEST_F(AddUsingTest, Apply) {
1035934a791SAdam Czachorowski   FileName = "test.cpp";
1045934a791SAdam Czachorowski   struct {
1055934a791SAdam Czachorowski     llvm::StringRef TestSource;
1065934a791SAdam Czachorowski     llvm::StringRef ExpectedSource;
107029ec03aSKadir Cetinkaya   } Cases[]{
108029ec03aSKadir Cetinkaya       {
1095934a791SAdam Czachorowski           // Function, no other using, namespace.
1105934a791SAdam Czachorowski           R"cpp(
1115934a791SAdam Czachorowski #include "test.hpp"
1125934a791SAdam Czachorowski namespace {
1135934a791SAdam Czachorowski void fun() {
114a316a981SSam McCall   ^one::two::ff();
1155934a791SAdam Czachorowski }
1165934a791SAdam Czachorowski })cpp",
1175934a791SAdam Czachorowski           R"cpp(
1185934a791SAdam Czachorowski #include "test.hpp"
1195934a791SAdam Czachorowski namespace {using one::two::ff;
1205934a791SAdam Czachorowski 
1215934a791SAdam Czachorowski void fun() {
1225934a791SAdam Czachorowski   ff();
1235934a791SAdam Czachorowski }
1245934a791SAdam Czachorowski })cpp",
1255934a791SAdam Czachorowski       },
1265934a791SAdam Czachorowski       // Type, no other using, namespace.
1275934a791SAdam Czachorowski       {
1285934a791SAdam Czachorowski           R"cpp(
1295934a791SAdam Czachorowski #include "test.hpp"
1305934a791SAdam Czachorowski namespace {
1315934a791SAdam Czachorowski void fun() {
132a316a981SSam McCall   ::one::t^wo::cc inst;
1335934a791SAdam Czachorowski }
1345934a791SAdam Czachorowski })cpp",
1355934a791SAdam Czachorowski           R"cpp(
1365934a791SAdam Czachorowski #include "test.hpp"
1375934a791SAdam Czachorowski namespace {using ::one::two::cc;
1385934a791SAdam Czachorowski 
1395934a791SAdam Czachorowski void fun() {
1405934a791SAdam Czachorowski   cc inst;
1415934a791SAdam Czachorowski }
1425934a791SAdam Czachorowski })cpp",
1435934a791SAdam Czachorowski       },
1445934a791SAdam Czachorowski       // Type, no other using, no namespace.
1455934a791SAdam Czachorowski       {
1465934a791SAdam Czachorowski           R"cpp(
1475934a791SAdam Czachorowski #include "test.hpp"
1485934a791SAdam Czachorowski 
1495934a791SAdam Czachorowski void fun() {
150a316a981SSam McCall   one::two::e^e inst;
1515934a791SAdam Czachorowski })cpp",
1525934a791SAdam Czachorowski           R"cpp(
1535934a791SAdam Czachorowski #include "test.hpp"
1545934a791SAdam Czachorowski 
1555934a791SAdam Czachorowski using one::two::ee;
1565934a791SAdam Czachorowski 
1575934a791SAdam Czachorowski void fun() {
1585934a791SAdam Czachorowski   ee inst;
1595934a791SAdam Czachorowski })cpp"},
1605934a791SAdam Czachorowski       // Function, other usings.
1615934a791SAdam Czachorowski       {
1625934a791SAdam Czachorowski           R"cpp(
1635934a791SAdam Czachorowski #include "test.hpp"
1645934a791SAdam Czachorowski 
1655934a791SAdam Czachorowski using one::two::cc;
1665934a791SAdam Czachorowski using one::two::ee;
1675934a791SAdam Czachorowski 
1685934a791SAdam Czachorowski namespace {
1695934a791SAdam Czachorowski void fun() {
1705934a791SAdam Czachorowski   one::two::f^f();
1715934a791SAdam Czachorowski }
1725934a791SAdam Czachorowski })cpp",
1735934a791SAdam Czachorowski           R"cpp(
1745934a791SAdam Czachorowski #include "test.hpp"
1755934a791SAdam Czachorowski 
1765934a791SAdam Czachorowski using one::two::cc;
1775934a791SAdam Czachorowski using one::two::ff;using one::two::ee;
1785934a791SAdam Czachorowski 
1795934a791SAdam Czachorowski namespace {
1805934a791SAdam Czachorowski void fun() {
1815934a791SAdam Czachorowski   ff();
1825934a791SAdam Czachorowski }
1835934a791SAdam Czachorowski })cpp",
1845934a791SAdam Czachorowski       },
1855934a791SAdam Czachorowski       // Function, other usings inside namespace.
1865934a791SAdam Czachorowski       {
1875934a791SAdam Czachorowski           R"cpp(
1885934a791SAdam Czachorowski #include "test.hpp"
1895934a791SAdam Czachorowski 
1905934a791SAdam Czachorowski using one::two::cc;
1915934a791SAdam Czachorowski 
1925934a791SAdam Czachorowski namespace {
1935934a791SAdam Czachorowski 
1945934a791SAdam Czachorowski using one::two::ff;
1955934a791SAdam Czachorowski 
1965934a791SAdam Czachorowski void fun() {
197a316a981SSam McCall   o^ne::oo();
1985934a791SAdam Czachorowski }
1995934a791SAdam Czachorowski })cpp",
2005934a791SAdam Czachorowski           R"cpp(
2015934a791SAdam Czachorowski #include "test.hpp"
2025934a791SAdam Czachorowski 
2035934a791SAdam Czachorowski using one::two::cc;
2045934a791SAdam Czachorowski 
2055934a791SAdam Czachorowski namespace {
2065934a791SAdam Czachorowski 
2075934a791SAdam Czachorowski using one::oo;using one::two::ff;
2085934a791SAdam Czachorowski 
2095934a791SAdam Czachorowski void fun() {
2105934a791SAdam Czachorowski   oo();
2115934a791SAdam Czachorowski }
2125934a791SAdam Czachorowski })cpp"},
2135934a791SAdam Czachorowski       // Using comes after cursor.
2145934a791SAdam Czachorowski       {
2155934a791SAdam Czachorowski           R"cpp(
2165934a791SAdam Czachorowski #include "test.hpp"
2175934a791SAdam Czachorowski 
2185934a791SAdam Czachorowski namespace {
2195934a791SAdam Czachorowski 
2205934a791SAdam Czachorowski void fun() {
2215934a791SAdam Czachorowski   one::t^wo::ff();
2225934a791SAdam Czachorowski }
2235934a791SAdam Czachorowski 
2245934a791SAdam Czachorowski using one::two::cc;
2255934a791SAdam Czachorowski 
2265934a791SAdam Czachorowski })cpp",
2275934a791SAdam Czachorowski           R"cpp(
2285934a791SAdam Czachorowski #include "test.hpp"
2295934a791SAdam Czachorowski 
2305934a791SAdam Czachorowski namespace {using one::two::ff;
2315934a791SAdam Czachorowski 
2325934a791SAdam Czachorowski 
2335934a791SAdam Czachorowski void fun() {
2345934a791SAdam Czachorowski   ff();
2355934a791SAdam Czachorowski }
2365934a791SAdam Czachorowski 
2375934a791SAdam Czachorowski using one::two::cc;
2385934a791SAdam Czachorowski 
2395934a791SAdam Czachorowski })cpp"},
2405934a791SAdam Czachorowski       // Pointer type.
2415934a791SAdam Czachorowski       {R"cpp(
2425934a791SAdam Czachorowski #include "test.hpp"
2435934a791SAdam Czachorowski 
2445934a791SAdam Czachorowski void fun() {
2455934a791SAdam Czachorowski   one::two::c^c *p;
2465934a791SAdam Czachorowski })cpp",
2475934a791SAdam Czachorowski        R"cpp(
2485934a791SAdam Czachorowski #include "test.hpp"
2495934a791SAdam Czachorowski 
2505934a791SAdam Czachorowski using one::two::cc;
2515934a791SAdam Czachorowski 
2525934a791SAdam Czachorowski void fun() {
2535934a791SAdam Czachorowski   cc *p;
2545934a791SAdam Czachorowski })cpp"},
2555934a791SAdam Czachorowski       // Namespace declared via macro.
2565934a791SAdam Czachorowski       {R"cpp(
2575934a791SAdam Czachorowski #include "test.hpp"
2585934a791SAdam Czachorowski #define NS_BEGIN(name) namespace name {
2595934a791SAdam Czachorowski 
2605934a791SAdam Czachorowski NS_BEGIN(foo)
2615934a791SAdam Czachorowski 
2625934a791SAdam Czachorowski void fun() {
2635934a791SAdam Czachorowski   one::two::f^f();
2645934a791SAdam Czachorowski }
2655934a791SAdam Czachorowski })cpp",
2665934a791SAdam Czachorowski        R"cpp(
2675934a791SAdam Czachorowski #include "test.hpp"
2685934a791SAdam Czachorowski #define NS_BEGIN(name) namespace name {
2695934a791SAdam Czachorowski 
2705934a791SAdam Czachorowski using one::two::ff;
2715934a791SAdam Czachorowski 
2725934a791SAdam Czachorowski NS_BEGIN(foo)
2735934a791SAdam Czachorowski 
2745934a791SAdam Czachorowski void fun() {
2755934a791SAdam Czachorowski   ff();
2765934a791SAdam Czachorowski }
2775934a791SAdam Czachorowski })cpp"},
2785934a791SAdam Czachorowski       // Inside macro argument.
2795934a791SAdam Czachorowski       {R"cpp(
2805934a791SAdam Czachorowski #include "test.hpp"
2815934a791SAdam Czachorowski #define CALL(name) name()
2825934a791SAdam Czachorowski 
2835934a791SAdam Czachorowski void fun() {
2845934a791SAdam Czachorowski   CALL(one::t^wo::ff);
2855934a791SAdam Czachorowski })cpp",
2865934a791SAdam Czachorowski        R"cpp(
2875934a791SAdam Czachorowski #include "test.hpp"
2885934a791SAdam Czachorowski #define CALL(name) name()
2895934a791SAdam Czachorowski 
2905934a791SAdam Czachorowski using one::two::ff;
2915934a791SAdam Czachorowski 
2925934a791SAdam Czachorowski void fun() {
2935934a791SAdam Czachorowski   CALL(ff);
2945934a791SAdam Czachorowski })cpp"},
2955934a791SAdam Czachorowski       // Parent namespace != lexical parent namespace
2965934a791SAdam Czachorowski       {R"cpp(
2975934a791SAdam Czachorowski #include "test.hpp"
2985934a791SAdam Czachorowski namespace foo { void fun(); }
2995934a791SAdam Czachorowski 
3005934a791SAdam Czachorowski void foo::fun() {
3015934a791SAdam Czachorowski   one::two::f^f();
3025934a791SAdam Czachorowski })cpp",
3035934a791SAdam Czachorowski        R"cpp(
3045934a791SAdam Czachorowski #include "test.hpp"
3055934a791SAdam Czachorowski using one::two::ff;
3065934a791SAdam Czachorowski 
3075934a791SAdam Czachorowski namespace foo { void fun(); }
3085934a791SAdam Czachorowski 
3095934a791SAdam Czachorowski void foo::fun() {
3105934a791SAdam Czachorowski   ff();
3115934a791SAdam Czachorowski })cpp"},
312*9ef2ac3aSYounan Zhang       // Inside a lambda.
313*9ef2ac3aSYounan Zhang       {
314*9ef2ac3aSYounan Zhang           R"cpp(
315*9ef2ac3aSYounan Zhang namespace NS {
316*9ef2ac3aSYounan Zhang void unrelated();
317*9ef2ac3aSYounan Zhang void foo();
318*9ef2ac3aSYounan Zhang }
319*9ef2ac3aSYounan Zhang 
320*9ef2ac3aSYounan Zhang auto L = [] {
321*9ef2ac3aSYounan Zhang   using NS::unrelated;
322*9ef2ac3aSYounan Zhang   NS::f^oo();
323*9ef2ac3aSYounan Zhang };)cpp",
324*9ef2ac3aSYounan Zhang           R"cpp(
325*9ef2ac3aSYounan Zhang namespace NS {
326*9ef2ac3aSYounan Zhang void unrelated();
327*9ef2ac3aSYounan Zhang void foo();
328*9ef2ac3aSYounan Zhang }
329*9ef2ac3aSYounan Zhang 
330*9ef2ac3aSYounan Zhang auto L = [] {
331*9ef2ac3aSYounan Zhang   using NS::foo;using NS::unrelated;
332*9ef2ac3aSYounan Zhang   foo();
333*9ef2ac3aSYounan Zhang };)cpp",
334*9ef2ac3aSYounan Zhang       },
3355934a791SAdam Czachorowski       // If all other using are fully qualified, add ::
3365934a791SAdam Czachorowski       {R"cpp(
3375934a791SAdam Czachorowski #include "test.hpp"
3385934a791SAdam Czachorowski 
3395934a791SAdam Czachorowski using ::one::two::cc;
3405934a791SAdam Czachorowski using ::one::two::ee;
3415934a791SAdam Czachorowski 
3425934a791SAdam Czachorowski void fun() {
3435934a791SAdam Czachorowski   one::two::f^f();
3445934a791SAdam Czachorowski })cpp",
3455934a791SAdam Czachorowski        R"cpp(
3465934a791SAdam Czachorowski #include "test.hpp"
3475934a791SAdam Czachorowski 
3485934a791SAdam Czachorowski using ::one::two::cc;
3495934a791SAdam Czachorowski using ::one::two::ff;using ::one::two::ee;
3505934a791SAdam Czachorowski 
3515934a791SAdam Czachorowski void fun() {
3525934a791SAdam Czachorowski   ff();
3535934a791SAdam Czachorowski })cpp"},
3545934a791SAdam Czachorowski       // Make sure we don't add :: if it's already there
3555934a791SAdam Czachorowski       {R"cpp(
3565934a791SAdam Czachorowski #include "test.hpp"
3575934a791SAdam Czachorowski 
3585934a791SAdam Czachorowski using ::one::two::cc;
3595934a791SAdam Czachorowski using ::one::two::ee;
3605934a791SAdam Czachorowski 
3615934a791SAdam Czachorowski void fun() {
3625934a791SAdam Czachorowski   ::one::two::f^f();
3635934a791SAdam Czachorowski })cpp",
3645934a791SAdam Czachorowski        R"cpp(
3655934a791SAdam Czachorowski #include "test.hpp"
3665934a791SAdam Czachorowski 
3675934a791SAdam Czachorowski using ::one::two::cc;
3685934a791SAdam Czachorowski using ::one::two::ff;using ::one::two::ee;
3695934a791SAdam Czachorowski 
3705934a791SAdam Czachorowski void fun() {
3715934a791SAdam Czachorowski   ff();
3725934a791SAdam Czachorowski })cpp"},
3735934a791SAdam Czachorowski       // If even one using doesn't start with ::, do not add it
3745934a791SAdam Czachorowski       {R"cpp(
3755934a791SAdam Czachorowski #include "test.hpp"
3765934a791SAdam Czachorowski 
3775934a791SAdam Czachorowski using ::one::two::cc;
3785934a791SAdam Czachorowski using one::two::ee;
3795934a791SAdam Czachorowski 
3805934a791SAdam Czachorowski void fun() {
3815934a791SAdam Czachorowski   one::two::f^f();
3825934a791SAdam Czachorowski })cpp",
3835934a791SAdam Czachorowski        R"cpp(
3845934a791SAdam Czachorowski #include "test.hpp"
3855934a791SAdam Czachorowski 
3865934a791SAdam Czachorowski using ::one::two::cc;
3875934a791SAdam Czachorowski using one::two::ff;using one::two::ee;
3885934a791SAdam Czachorowski 
3895934a791SAdam Czachorowski void fun() {
3905934a791SAdam Czachorowski   ff();
3915934a791SAdam Czachorowski })cpp"},
3925934a791SAdam Czachorowski       // using alias; insert using for the spelled name.
3935934a791SAdam Czachorowski       {R"cpp(
3945934a791SAdam Czachorowski #include "test.hpp"
3955934a791SAdam Czachorowski 
3965934a791SAdam Czachorowski void fun() {
3975934a791SAdam Czachorowski   one::u^u u;
3985934a791SAdam Czachorowski })cpp",
3995934a791SAdam Czachorowski        R"cpp(
4005934a791SAdam Czachorowski #include "test.hpp"
4015934a791SAdam Czachorowski 
4025934a791SAdam Czachorowski using one::uu;
4035934a791SAdam Czachorowski 
4045934a791SAdam Czachorowski void fun() {
4055934a791SAdam Czachorowski   uu u;
4065934a791SAdam Czachorowski })cpp"},
4075934a791SAdam Czachorowski       // using namespace.
4085934a791SAdam Czachorowski       {R"cpp(
4095934a791SAdam Czachorowski #include "test.hpp"
4105934a791SAdam Czachorowski using namespace one;
4115934a791SAdam Czachorowski namespace {
4125934a791SAdam Czachorowski two::c^c C;
4135934a791SAdam Czachorowski })cpp",
4145934a791SAdam Czachorowski        R"cpp(
4155934a791SAdam Czachorowski #include "test.hpp"
4165934a791SAdam Czachorowski using namespace one;
4175934a791SAdam Czachorowski namespace {using two::cc;
4185934a791SAdam Czachorowski 
4195934a791SAdam Czachorowski cc C;
4205934a791SAdam Czachorowski })cpp"},
4215934a791SAdam Czachorowski       // Type defined in main file, make sure using is after that.
4225934a791SAdam Czachorowski       {R"cpp(
4235934a791SAdam Czachorowski namespace xx {
4245934a791SAdam Czachorowski   struct yy {};
4255934a791SAdam Czachorowski }
4265934a791SAdam Czachorowski 
4275934a791SAdam Czachorowski x^x::yy X;
4285934a791SAdam Czachorowski )cpp",
4295934a791SAdam Czachorowski        R"cpp(
4305934a791SAdam Czachorowski namespace xx {
4315934a791SAdam Czachorowski   struct yy {};
4325934a791SAdam Czachorowski }
4335934a791SAdam Czachorowski 
4345934a791SAdam Czachorowski using xx::yy;
4355934a791SAdam Czachorowski 
4365934a791SAdam Czachorowski yy X;
4375934a791SAdam Czachorowski )cpp"},
4385934a791SAdam Czachorowski       // Type defined in main file via "using", insert after that.
4395934a791SAdam Czachorowski       {R"cpp(
4405934a791SAdam Czachorowski #include "test.hpp"
4415934a791SAdam Czachorowski 
4425934a791SAdam Czachorowski namespace xx {
4435934a791SAdam Czachorowski   using yy = one::two::cc;
4445934a791SAdam Czachorowski }
4455934a791SAdam Czachorowski 
4465934a791SAdam Czachorowski x^x::yy X;
4475934a791SAdam Czachorowski )cpp",
4485934a791SAdam Czachorowski        R"cpp(
4495934a791SAdam Czachorowski #include "test.hpp"
4505934a791SAdam Czachorowski 
4515934a791SAdam Czachorowski namespace xx {
4525934a791SAdam Czachorowski   using yy = one::two::cc;
4535934a791SAdam Czachorowski }
4545934a791SAdam Czachorowski 
4555934a791SAdam Czachorowski using xx::yy;
4565934a791SAdam Czachorowski 
4575934a791SAdam Czachorowski yy X;
4585934a791SAdam Czachorowski )cpp"},
4595934a791SAdam Czachorowski       // Using must come after function definition.
4605934a791SAdam Czachorowski       {R"cpp(
4615934a791SAdam Czachorowski namespace xx {
4625934a791SAdam Czachorowski   void yy();
4635934a791SAdam Czachorowski }
4645934a791SAdam Czachorowski 
4655934a791SAdam Czachorowski void fun() {
4665934a791SAdam Czachorowski   x^x::yy();
4675934a791SAdam Czachorowski }
4685934a791SAdam Czachorowski )cpp",
4695934a791SAdam Czachorowski        R"cpp(
4705934a791SAdam Czachorowski namespace xx {
4715934a791SAdam Czachorowski   void yy();
4725934a791SAdam Czachorowski }
4735934a791SAdam Czachorowski 
4745934a791SAdam Czachorowski using xx::yy;
4755934a791SAdam Czachorowski 
4765934a791SAdam Czachorowski void fun() {
4775934a791SAdam Czachorowski   yy();
4785934a791SAdam Czachorowski }
4795934a791SAdam Czachorowski )cpp"},
4805934a791SAdam Czachorowski       // Existing using with non-namespace part.
4815934a791SAdam Czachorowski       {R"cpp(
4825934a791SAdam Czachorowski #include "test.hpp"
4835934a791SAdam Czachorowski using one::two::ee::ee_one;
4845934a791SAdam Czachorowski one::t^wo::cc c;
4855934a791SAdam Czachorowski )cpp",
4865934a791SAdam Czachorowski        R"cpp(
4875934a791SAdam Czachorowski #include "test.hpp"
4885934a791SAdam Czachorowski using one::two::cc;using one::two::ee::ee_one;
4895934a791SAdam Czachorowski cc c;
49021745241SAdam Czachorowski )cpp"},
49121745241SAdam Czachorowski       // Template (like std::vector).
49221745241SAdam Czachorowski       {R"cpp(
49321745241SAdam Czachorowski #include "test.hpp"
49421745241SAdam Czachorowski one::v^ec<int> foo;
49521745241SAdam Czachorowski )cpp",
49621745241SAdam Czachorowski        R"cpp(
49721745241SAdam Czachorowski #include "test.hpp"
49821745241SAdam Czachorowski using one::vec;
49921745241SAdam Czachorowski 
50021745241SAdam Czachorowski vec<int> foo;
50135c2aac6SKadir Cetinkaya )cpp"},
50235c2aac6SKadir Cetinkaya       // Typo correction.
50335c2aac6SKadir Cetinkaya       {R"cpp(
50435c2aac6SKadir Cetinkaya // error-ok
50535c2aac6SKadir Cetinkaya #include "test.hpp"
50635c2aac6SKadir Cetinkaya c^c C;
50735c2aac6SKadir Cetinkaya )cpp",
50835c2aac6SKadir Cetinkaya        R"cpp(
50935c2aac6SKadir Cetinkaya // error-ok
51035c2aac6SKadir Cetinkaya #include "test.hpp"
51135c2aac6SKadir Cetinkaya using one::two::cc;
51235c2aac6SKadir Cetinkaya 
51335c2aac6SKadir Cetinkaya cc C;
51435c2aac6SKadir Cetinkaya )cpp"},
51535c2aac6SKadir Cetinkaya       {R"cpp(
51635c2aac6SKadir Cetinkaya // error-ok
51735c2aac6SKadir Cetinkaya #include "test.hpp"
51835c2aac6SKadir Cetinkaya void foo() {
51935c2aac6SKadir Cetinkaya   switch(one::two::ee{}) { case two::ee_^one:break; }
52035c2aac6SKadir Cetinkaya }
52135c2aac6SKadir Cetinkaya )cpp",
52235c2aac6SKadir Cetinkaya        R"cpp(
52335c2aac6SKadir Cetinkaya // error-ok
52435c2aac6SKadir Cetinkaya #include "test.hpp"
52535c2aac6SKadir Cetinkaya using one::two::ee_one;
52635c2aac6SKadir Cetinkaya 
52735c2aac6SKadir Cetinkaya void foo() {
52835c2aac6SKadir Cetinkaya   switch(one::two::ee{}) { case ee_one:break; }
52935c2aac6SKadir Cetinkaya }
53035c2aac6SKadir Cetinkaya )cpp"},
53151df1a9aSKadir Cetinkaya       {R"cpp(
53251df1a9aSKadir Cetinkaya #include "test.hpp"
53351df1a9aSKadir Cetinkaya void foo() {
53451df1a9aSKadir Cetinkaya   one::f^unc_temp<int>();
53551df1a9aSKadir Cetinkaya })cpp",
53651df1a9aSKadir Cetinkaya        R"cpp(
53751df1a9aSKadir Cetinkaya #include "test.hpp"
53851df1a9aSKadir Cetinkaya using one::func_temp;
53951df1a9aSKadir Cetinkaya 
54051df1a9aSKadir Cetinkaya void foo() {
54151df1a9aSKadir Cetinkaya   func_temp<int>();
54251df1a9aSKadir Cetinkaya })cpp"},
54351df1a9aSKadir Cetinkaya       {R"cpp(
54451df1a9aSKadir Cetinkaya #include "test.hpp"
54551df1a9aSKadir Cetinkaya void foo() {
54651df1a9aSKadir Cetinkaya   one::va^r_temp<int>;
54751df1a9aSKadir Cetinkaya })cpp",
54851df1a9aSKadir Cetinkaya        R"cpp(
54951df1a9aSKadir Cetinkaya #include "test.hpp"
55051df1a9aSKadir Cetinkaya using one::var_temp;
55151df1a9aSKadir Cetinkaya 
55251df1a9aSKadir Cetinkaya void foo() {
55351df1a9aSKadir Cetinkaya   var_temp<int>;
55451df1a9aSKadir Cetinkaya })cpp"},
55535c2aac6SKadir Cetinkaya   };
5565934a791SAdam Czachorowski   llvm::StringMap<std::string> EditedFiles;
5575934a791SAdam Czachorowski   for (const auto &Case : Cases) {
5585934a791SAdam Czachorowski     ExtraFiles["test.hpp"] = R"cpp(
5595934a791SAdam Czachorowski namespace one {
5605934a791SAdam Czachorowski void oo() {}
5615934a791SAdam Czachorowski namespace two {
5625934a791SAdam Czachorowski enum ee {ee_one};
5635934a791SAdam Czachorowski void ff() {}
5645934a791SAdam Czachorowski class cc {
5655934a791SAdam Czachorowski public:
5665934a791SAdam Czachorowski   struct st { struct nested {}; };
5675934a791SAdam Czachorowski   static void mm() {}
5685934a791SAdam Czachorowski };
5695934a791SAdam Czachorowski }
5705934a791SAdam Czachorowski using uu = two::cc;
57121745241SAdam Czachorowski template<typename T> struct vec {};
57251df1a9aSKadir Cetinkaya template <typename T> void func_temp();
57351df1a9aSKadir Cetinkaya template <typename T> T var_temp();
5745934a791SAdam Czachorowski })cpp";
57535c2aac6SKadir Cetinkaya     // Typo correction is disabled in msvc-compatibility mode.
57635c2aac6SKadir Cetinkaya     ExtraArgs.push_back("-fno-ms-compatibility");
577a316a981SSam McCall     EXPECT_EQ(apply(Case.TestSource, &EditedFiles), Case.ExpectedSource);
5785934a791SAdam Czachorowski   }
5795934a791SAdam Czachorowski }
5805934a791SAdam Czachorowski 
5815934a791SAdam Czachorowski } // namespace
5825934a791SAdam Czachorowski } // namespace clangd
5835934a791SAdam Czachorowski } // namespace clang
584