15934a791SAdam Czachorowski //===-- DefineInlineTests.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 "TweakTesting.h"
10*4d006520SSam McCall #include "TestFS.h"
115934a791SAdam Czachorowski #include "gmock/gmock.h"
125934a791SAdam Czachorowski #include "gtest/gtest.h"
135934a791SAdam Czachorowski
145934a791SAdam Czachorowski using ::testing::ElementsAre;
155934a791SAdam Czachorowski
165934a791SAdam Czachorowski namespace clang {
175934a791SAdam Czachorowski namespace clangd {
185934a791SAdam Czachorowski namespace {
195934a791SAdam Czachorowski
205934a791SAdam Czachorowski TWEAK_TEST(DefineInline);
215934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TriggersOnFunctionDecl)225934a791SAdam Czachorowski TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
235934a791SAdam Czachorowski // Basic check for function body and signature.
245934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
255934a791SAdam Czachorowski class Bar {
265934a791SAdam Czachorowski void baz();
275934a791SAdam Czachorowski };
285934a791SAdam Czachorowski
295934a791SAdam Czachorowski [[void [[Bar::[[b^a^z]]]]() [[{
305934a791SAdam Czachorowski return;
315934a791SAdam Czachorowski }]]]]
325934a791SAdam Czachorowski
335934a791SAdam Czachorowski void foo();
345934a791SAdam Czachorowski [[void [[f^o^o]]() [[{
355934a791SAdam Czachorowski return;
365934a791SAdam Czachorowski }]]]]
375934a791SAdam Czachorowski )cpp");
385934a791SAdam Czachorowski
395934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
405934a791SAdam Czachorowski // Not a definition
415934a791SAdam Czachorowski vo^i[[d^ ^f]]^oo();
425934a791SAdam Czachorowski
435934a791SAdam Czachorowski [[vo^id ]]foo[[()]] {[[
445934a791SAdam Czachorowski [[(void)(5+3);
455934a791SAdam Czachorowski return;]]
465934a791SAdam Czachorowski }]]
475934a791SAdam Czachorowski
485934a791SAdam Czachorowski // Definition with no body.
495934a791SAdam Czachorowski class Bar { Bar() = def^ault; };
505934a791SAdam Czachorowski )cpp");
515934a791SAdam Czachorowski }
525934a791SAdam Czachorowski
TEST_F(DefineInlineTest,NoForwardDecl)535934a791SAdam Czachorowski TEST_F(DefineInlineTest, NoForwardDecl) {
545934a791SAdam Czachorowski Header = "void bar();";
555934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
565934a791SAdam Czachorowski void bar() {
575934a791SAdam Czachorowski return;
585934a791SAdam Czachorowski }
595934a791SAdam Czachorowski // FIXME: Generate a decl in the header.
605934a791SAdam Czachorowski void fo^o() {
615934a791SAdam Czachorowski return;
625934a791SAdam Czachorowski })cpp");
635934a791SAdam Czachorowski }
645934a791SAdam Czachorowski
TEST_F(DefineInlineTest,ReferencedDecls)655934a791SAdam Czachorowski TEST_F(DefineInlineTest, ReferencedDecls) {
665934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
675934a791SAdam Czachorowski void bar();
685934a791SAdam Czachorowski void foo(int test);
695934a791SAdam Czachorowski
705934a791SAdam Czachorowski void fo^o(int baz) {
715934a791SAdam Czachorowski int x = 10;
725934a791SAdam Czachorowski bar();
735934a791SAdam Czachorowski })cpp");
745934a791SAdam Czachorowski
755934a791SAdam Czachorowski // Internal symbol usage.
765934a791SAdam Czachorowski Header = "void foo(int test);";
775934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
785934a791SAdam Czachorowski void bar();
795934a791SAdam Czachorowski void fo^o(int baz) {
805934a791SAdam Czachorowski int x = 10;
815934a791SAdam Czachorowski bar();
825934a791SAdam Czachorowski })cpp");
835934a791SAdam Czachorowski
845934a791SAdam Czachorowski // Becomes available after making symbol visible.
855934a791SAdam Czachorowski Header = "void bar();" + Header;
865934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
875934a791SAdam Czachorowski void fo^o(int baz) {
885934a791SAdam Czachorowski int x = 10;
895934a791SAdam Czachorowski bar();
905934a791SAdam Czachorowski })cpp");
915934a791SAdam Czachorowski
925934a791SAdam Czachorowski // FIXME: Move declaration below bar to make it visible.
935934a791SAdam Czachorowski Header.clear();
945934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
955934a791SAdam Czachorowski void foo();
965934a791SAdam Czachorowski void bar();
975934a791SAdam Czachorowski
985934a791SAdam Czachorowski void fo^o() {
995934a791SAdam Czachorowski bar();
1005934a791SAdam Czachorowski })cpp");
1015934a791SAdam Czachorowski
1025934a791SAdam Czachorowski // Order doesn't matter within a class.
1035934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
1045934a791SAdam Czachorowski class Bar {
1055934a791SAdam Czachorowski void foo();
1065934a791SAdam Czachorowski void bar();
1075934a791SAdam Czachorowski };
1085934a791SAdam Czachorowski
1095934a791SAdam Czachorowski void Bar::fo^o() {
1105934a791SAdam Czachorowski bar();
1115934a791SAdam Czachorowski })cpp");
1125934a791SAdam Czachorowski
1135934a791SAdam Czachorowski // FIXME: Perform include insertion to make symbol visible.
1145934a791SAdam Czachorowski ExtraFiles["a.h"] = "void bar();";
1155934a791SAdam Czachorowski Header = "void foo(int test);";
1165934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1175934a791SAdam Czachorowski #include "a.h"
1185934a791SAdam Czachorowski void fo^o(int baz) {
1195934a791SAdam Czachorowski int x = 10;
1205934a791SAdam Czachorowski bar();
1215934a791SAdam Czachorowski })cpp");
1225934a791SAdam Czachorowski }
1235934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TemplateSpec)1245934a791SAdam Czachorowski TEST_F(DefineInlineTest, TemplateSpec) {
1255934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1265934a791SAdam Czachorowski template <typename T> void foo();
1275934a791SAdam Czachorowski template<> void foo<char>();
1285934a791SAdam Czachorowski
1295934a791SAdam Czachorowski template<> void f^oo<int>() {
1305934a791SAdam Czachorowski })cpp");
1315934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1325934a791SAdam Czachorowski template <typename T> void foo();
1335934a791SAdam Czachorowski
1345934a791SAdam Czachorowski template<> void f^oo<int>() {
1355934a791SAdam Czachorowski })cpp");
1365934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1375934a791SAdam Czachorowski template <typename T> struct Foo { void foo(); };
1385934a791SAdam Czachorowski
1395934a791SAdam Czachorowski template <typename T> void Foo<T>::f^oo() {
1405934a791SAdam Czachorowski })cpp");
1415934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
1425934a791SAdam Czachorowski template <typename T> void foo();
1435934a791SAdam Czachorowski void bar();
1445934a791SAdam Czachorowski template <> void foo<int>();
1455934a791SAdam Czachorowski
1465934a791SAdam Czachorowski template<> void f^oo<int>() {
1475934a791SAdam Czachorowski bar();
1485934a791SAdam Czachorowski })cpp");
1495934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1505934a791SAdam Czachorowski namespace bar {
1515934a791SAdam Czachorowski template <typename T> void f^oo() {}
1525934a791SAdam Czachorowski template void foo<int>();
1535934a791SAdam Czachorowski })cpp");
1545934a791SAdam Czachorowski }
1555934a791SAdam Czachorowski
TEST_F(DefineInlineTest,CheckForCanonDecl)1565934a791SAdam Czachorowski TEST_F(DefineInlineTest, CheckForCanonDecl) {
1575934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1585934a791SAdam Czachorowski void foo();
1595934a791SAdam Czachorowski
1605934a791SAdam Czachorowski void bar() {}
1615934a791SAdam Czachorowski void f^oo() {
1625934a791SAdam Czachorowski // This bar normally refers to the definition just above, but it is not
1635934a791SAdam Czachorowski // visible from the forward declaration of foo.
1645934a791SAdam Czachorowski bar();
1655934a791SAdam Czachorowski })cpp");
1665934a791SAdam Czachorowski // Make it available with a forward decl.
1675934a791SAdam Czachorowski EXPECT_AVAILABLE(R"cpp(
1685934a791SAdam Czachorowski void bar();
1695934a791SAdam Czachorowski void foo();
1705934a791SAdam Czachorowski
1715934a791SAdam Czachorowski void bar() {}
1725934a791SAdam Czachorowski void f^oo() {
1735934a791SAdam Czachorowski bar();
1745934a791SAdam Czachorowski })cpp");
1755934a791SAdam Czachorowski }
1765934a791SAdam Czachorowski
TEST_F(DefineInlineTest,UsingShadowDecls)1775934a791SAdam Czachorowski TEST_F(DefineInlineTest, UsingShadowDecls) {
1785934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
1795934a791SAdam Czachorowski namespace ns1 { void foo(int); }
1805934a791SAdam Czachorowski namespace ns2 { void foo(int*); }
1815934a791SAdam Czachorowski template <typename T>
1825934a791SAdam Czachorowski void bar();
1835934a791SAdam Czachorowski
1845934a791SAdam Czachorowski using ns1::foo;
1855934a791SAdam Czachorowski using ns2::foo;
1865934a791SAdam Czachorowski
1875934a791SAdam Czachorowski template <typename T>
1885934a791SAdam Czachorowski void b^ar() {
1895934a791SAdam Czachorowski foo(T());
1905934a791SAdam Czachorowski })cpp");
1915934a791SAdam Czachorowski }
1925934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformNestedNamespaces)1935934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformNestedNamespaces) {
194c0e3c893SChristian Kühnel auto *Test = R"cpp(
1955934a791SAdam Czachorowski namespace a {
1965934a791SAdam Czachorowski void bar();
1975934a791SAdam Czachorowski namespace b {
1985934a791SAdam Czachorowski void baz();
1995934a791SAdam Czachorowski namespace c {
2005934a791SAdam Czachorowski void aux();
2015934a791SAdam Czachorowski }
2025934a791SAdam Czachorowski }
2035934a791SAdam Czachorowski }
2045934a791SAdam Czachorowski
2055934a791SAdam Czachorowski void foo();
2065934a791SAdam Czachorowski using namespace a;
2075934a791SAdam Czachorowski using namespace b;
2085934a791SAdam Czachorowski using namespace c;
2095934a791SAdam Czachorowski void f^oo() {
2105934a791SAdam Czachorowski bar();
2115934a791SAdam Czachorowski a::bar();
2125934a791SAdam Czachorowski
2135934a791SAdam Czachorowski baz();
2145934a791SAdam Czachorowski b::baz();
2155934a791SAdam Czachorowski a::b::baz();
2165934a791SAdam Czachorowski
2175934a791SAdam Czachorowski aux();
2185934a791SAdam Czachorowski c::aux();
2195934a791SAdam Czachorowski b::c::aux();
2205934a791SAdam Czachorowski a::b::c::aux();
2215934a791SAdam Czachorowski })cpp";
222c0e3c893SChristian Kühnel auto *Expected = R"cpp(
2235934a791SAdam Czachorowski namespace a {
2245934a791SAdam Czachorowski void bar();
2255934a791SAdam Czachorowski namespace b {
2265934a791SAdam Czachorowski void baz();
2275934a791SAdam Czachorowski namespace c {
2285934a791SAdam Czachorowski void aux();
2295934a791SAdam Czachorowski }
2305934a791SAdam Czachorowski }
2315934a791SAdam Czachorowski }
2325934a791SAdam Czachorowski
2335934a791SAdam Czachorowski void foo(){
2345934a791SAdam Czachorowski a::bar();
2355934a791SAdam Czachorowski a::bar();
2365934a791SAdam Czachorowski
2375934a791SAdam Czachorowski a::b::baz();
2385934a791SAdam Czachorowski a::b::baz();
2395934a791SAdam Czachorowski a::b::baz();
2405934a791SAdam Czachorowski
2415934a791SAdam Czachorowski a::b::c::aux();
2425934a791SAdam Czachorowski a::b::c::aux();
2435934a791SAdam Czachorowski a::b::c::aux();
2445934a791SAdam Czachorowski a::b::c::aux();
2455934a791SAdam Czachorowski }
2465934a791SAdam Czachorowski using namespace a;
2475934a791SAdam Czachorowski using namespace b;
2485934a791SAdam Czachorowski using namespace c;
2495934a791SAdam Czachorowski )cpp";
2505934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
2515934a791SAdam Czachorowski }
2525934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformUsings)2535934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformUsings) {
254c0e3c893SChristian Kühnel auto *Test = R"cpp(
2555934a791SAdam Czachorowski namespace a { namespace b { namespace c { void aux(); } } }
2565934a791SAdam Czachorowski
2575934a791SAdam Czachorowski void foo();
2585934a791SAdam Czachorowski void f^oo() {
2595934a791SAdam Czachorowski using namespace a;
2605934a791SAdam Czachorowski using namespace b;
2615934a791SAdam Czachorowski using namespace c;
2625934a791SAdam Czachorowski using c::aux;
2635934a791SAdam Czachorowski namespace d = c;
2645934a791SAdam Czachorowski })cpp";
265c0e3c893SChristian Kühnel auto *Expected = R"cpp(
2665934a791SAdam Czachorowski namespace a { namespace b { namespace c { void aux(); } } }
2675934a791SAdam Czachorowski
2685934a791SAdam Czachorowski void foo(){
2695934a791SAdam Czachorowski using namespace a;
2705934a791SAdam Czachorowski using namespace a::b;
2715934a791SAdam Czachorowski using namespace a::b::c;
2725934a791SAdam Czachorowski using a::b::c::aux;
2735934a791SAdam Czachorowski namespace d = a::b::c;
2745934a791SAdam Czachorowski }
2755934a791SAdam Czachorowski )cpp";
2765934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
2775934a791SAdam Czachorowski }
2785934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformDecls)2795934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformDecls) {
280c0e3c893SChristian Kühnel auto *Test = R"cpp(
2815934a791SAdam Czachorowski void foo();
2825934a791SAdam Czachorowski void f^oo() {
2835934a791SAdam Czachorowski class Foo {
2845934a791SAdam Czachorowski public:
2855934a791SAdam Czachorowski void foo();
2865934a791SAdam Czachorowski int x;
2875934a791SAdam Czachorowski };
2885934a791SAdam Czachorowski
2895934a791SAdam Czachorowski enum En { Zero, One };
2905934a791SAdam Czachorowski En x = Zero;
2915934a791SAdam Czachorowski
2925934a791SAdam Czachorowski enum class EnClass { Zero, One };
2935934a791SAdam Czachorowski EnClass y = EnClass::Zero;
2945934a791SAdam Czachorowski })cpp";
295c0e3c893SChristian Kühnel auto *Expected = R"cpp(
2965934a791SAdam Czachorowski void foo(){
2975934a791SAdam Czachorowski class Foo {
2985934a791SAdam Czachorowski public:
2995934a791SAdam Czachorowski void foo();
3005934a791SAdam Czachorowski int x;
3015934a791SAdam Czachorowski };
3025934a791SAdam Czachorowski
3035934a791SAdam Czachorowski enum En { Zero, One };
3045934a791SAdam Czachorowski En x = Zero;
3055934a791SAdam Czachorowski
3065934a791SAdam Czachorowski enum class EnClass { Zero, One };
3075934a791SAdam Czachorowski EnClass y = EnClass::Zero;
3085934a791SAdam Czachorowski }
3095934a791SAdam Czachorowski )cpp";
3105934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
3115934a791SAdam Czachorowski }
3125934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformTemplDecls)3135934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformTemplDecls) {
314c0e3c893SChristian Kühnel auto *Test = R"cpp(
3155934a791SAdam Czachorowski namespace a {
3165934a791SAdam Czachorowski template <typename T> class Bar {
3175934a791SAdam Czachorowski public:
3185934a791SAdam Czachorowski void bar();
3195934a791SAdam Czachorowski };
3205934a791SAdam Czachorowski template <typename T> T bar;
3215934a791SAdam Czachorowski template <typename T> void aux() {}
3225934a791SAdam Czachorowski }
3235934a791SAdam Czachorowski
3245934a791SAdam Czachorowski void foo();
3255934a791SAdam Czachorowski
3265934a791SAdam Czachorowski using namespace a;
3275934a791SAdam Czachorowski void f^oo() {
3285934a791SAdam Czachorowski bar<Bar<int>>.bar();
3295934a791SAdam Czachorowski aux<Bar<int>>();
3305934a791SAdam Czachorowski })cpp";
331c0e3c893SChristian Kühnel auto *Expected = R"cpp(
3325934a791SAdam Czachorowski namespace a {
3335934a791SAdam Czachorowski template <typename T> class Bar {
3345934a791SAdam Czachorowski public:
3355934a791SAdam Czachorowski void bar();
3365934a791SAdam Czachorowski };
3375934a791SAdam Czachorowski template <typename T> T bar;
3385934a791SAdam Czachorowski template <typename T> void aux() {}
3395934a791SAdam Czachorowski }
3405934a791SAdam Czachorowski
3415934a791SAdam Czachorowski void foo(){
3425934a791SAdam Czachorowski a::bar<a::Bar<int>>.bar();
3435934a791SAdam Czachorowski a::aux<a::Bar<int>>();
3445934a791SAdam Czachorowski }
3455934a791SAdam Czachorowski
3465934a791SAdam Czachorowski using namespace a;
3475934a791SAdam Czachorowski )cpp";
3485934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
3495934a791SAdam Czachorowski }
3505934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformMembers)3515934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformMembers) {
352c0e3c893SChristian Kühnel auto *Test = R"cpp(
3535934a791SAdam Czachorowski class Foo {
3545934a791SAdam Czachorowski void foo();
3555934a791SAdam Czachorowski };
3565934a791SAdam Czachorowski
3575934a791SAdam Czachorowski void Foo::f^oo() {
3585934a791SAdam Czachorowski return;
3595934a791SAdam Czachorowski })cpp";
360c0e3c893SChristian Kühnel auto *Expected = R"cpp(
3615934a791SAdam Czachorowski class Foo {
3625934a791SAdam Czachorowski void foo(){
3635934a791SAdam Czachorowski return;
3645934a791SAdam Czachorowski }
3655934a791SAdam Czachorowski };
3665934a791SAdam Czachorowski
3675934a791SAdam Czachorowski )cpp";
3685934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
3695934a791SAdam Czachorowski
3705934a791SAdam Czachorowski ExtraFiles["a.h"] = R"cpp(
3715934a791SAdam Czachorowski class Foo {
3725934a791SAdam Czachorowski void foo();
3735934a791SAdam Czachorowski };)cpp";
3745934a791SAdam Czachorowski
3755934a791SAdam Czachorowski llvm::StringMap<std::string> EditedFiles;
3765934a791SAdam Czachorowski Test = R"cpp(
3775934a791SAdam Czachorowski #include "a.h"
3785934a791SAdam Czachorowski void Foo::f^oo() {
3795934a791SAdam Czachorowski return;
3805934a791SAdam Czachorowski })cpp";
3815934a791SAdam Czachorowski Expected = R"cpp(
3825934a791SAdam Czachorowski #include "a.h"
3835934a791SAdam Czachorowski )cpp";
3845934a791SAdam Czachorowski EXPECT_EQ(apply(Test, &EditedFiles), Expected);
3855934a791SAdam Czachorowski
3865934a791SAdam Czachorowski Expected = R"cpp(
3875934a791SAdam Czachorowski class Foo {
3885934a791SAdam Czachorowski void foo(){
3895934a791SAdam Czachorowski return;
3905934a791SAdam Czachorowski }
3915934a791SAdam Czachorowski };)cpp";
3925934a791SAdam Czachorowski EXPECT_THAT(EditedFiles,
3935934a791SAdam Czachorowski ElementsAre(FileWithContents(testPath("a.h"), Expected)));
3945934a791SAdam Czachorowski }
3955934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformDependentTypes)3965934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformDependentTypes) {
397c0e3c893SChristian Kühnel auto *Test = R"cpp(
3985934a791SAdam Czachorowski namespace a {
3995934a791SAdam Czachorowski template <typename T> class Bar {};
4005934a791SAdam Czachorowski }
4015934a791SAdam Czachorowski
4025934a791SAdam Czachorowski template <typename T>
4035934a791SAdam Czachorowski void foo();
4045934a791SAdam Czachorowski
4055934a791SAdam Czachorowski using namespace a;
4065934a791SAdam Czachorowski template <typename T>
4075934a791SAdam Czachorowski void f^oo() {
4085934a791SAdam Czachorowski Bar<T> B;
4095934a791SAdam Czachorowski Bar<Bar<T>> q;
4105934a791SAdam Czachorowski })cpp";
411c0e3c893SChristian Kühnel auto *Expected = R"cpp(
4125934a791SAdam Czachorowski namespace a {
4135934a791SAdam Czachorowski template <typename T> class Bar {};
4145934a791SAdam Czachorowski }
4155934a791SAdam Czachorowski
4165934a791SAdam Czachorowski template <typename T>
4175934a791SAdam Czachorowski void foo(){
4185934a791SAdam Czachorowski a::Bar<T> B;
4195934a791SAdam Czachorowski a::Bar<a::Bar<T>> q;
4205934a791SAdam Czachorowski }
4215934a791SAdam Czachorowski
4225934a791SAdam Czachorowski using namespace a;
4235934a791SAdam Czachorowski )cpp";
4245934a791SAdam Czachorowski
4255934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
4265934a791SAdam Czachorowski }
4275934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformFunctionTempls)4285934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformFunctionTempls) {
4295934a791SAdam Czachorowski // Check we select correct specialization decl.
4305934a791SAdam Czachorowski std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
4315934a791SAdam Czachorowski {R"cpp(
4325934a791SAdam Czachorowski template <typename T>
4335934a791SAdam Czachorowski void foo(T p);
4345934a791SAdam Czachorowski
4355934a791SAdam Czachorowski template <>
4365934a791SAdam Czachorowski void foo<int>(int p);
4375934a791SAdam Czachorowski
4385934a791SAdam Czachorowski template <>
4395934a791SAdam Czachorowski void foo<char>(char p);
4405934a791SAdam Czachorowski
4415934a791SAdam Czachorowski template <>
4425934a791SAdam Czachorowski void fo^o<int>(int p) {
4435934a791SAdam Czachorowski return;
4445934a791SAdam Czachorowski })cpp",
4455934a791SAdam Czachorowski R"cpp(
4465934a791SAdam Czachorowski template <typename T>
4475934a791SAdam Czachorowski void foo(T p);
4485934a791SAdam Czachorowski
4495934a791SAdam Czachorowski template <>
4505934a791SAdam Czachorowski void foo<int>(int p){
4515934a791SAdam Czachorowski return;
4525934a791SAdam Czachorowski }
4535934a791SAdam Czachorowski
4545934a791SAdam Czachorowski template <>
4555934a791SAdam Czachorowski void foo<char>(char p);
4565934a791SAdam Czachorowski
4575934a791SAdam Czachorowski )cpp"},
4585934a791SAdam Czachorowski {// Make sure we are not selecting the first specialization all the time.
4595934a791SAdam Czachorowski R"cpp(
4605934a791SAdam Czachorowski template <typename T>
4615934a791SAdam Czachorowski void foo(T p);
4625934a791SAdam Czachorowski
4635934a791SAdam Czachorowski template <>
4645934a791SAdam Czachorowski void foo<int>(int p);
4655934a791SAdam Czachorowski
4665934a791SAdam Czachorowski template <>
4675934a791SAdam Czachorowski void foo<char>(char p);
4685934a791SAdam Czachorowski
4695934a791SAdam Czachorowski template <>
4705934a791SAdam Czachorowski void fo^o<char>(char p) {
4715934a791SAdam Czachorowski return;
4725934a791SAdam Czachorowski })cpp",
4735934a791SAdam Czachorowski R"cpp(
4745934a791SAdam Czachorowski template <typename T>
4755934a791SAdam Czachorowski void foo(T p);
4765934a791SAdam Czachorowski
4775934a791SAdam Czachorowski template <>
4785934a791SAdam Czachorowski void foo<int>(int p);
4795934a791SAdam Czachorowski
4805934a791SAdam Czachorowski template <>
4815934a791SAdam Czachorowski void foo<char>(char p){
4825934a791SAdam Czachorowski return;
4835934a791SAdam Czachorowski }
4845934a791SAdam Czachorowski
4855934a791SAdam Czachorowski )cpp"},
4865934a791SAdam Czachorowski {R"cpp(
4875934a791SAdam Czachorowski template <typename T>
4885934a791SAdam Czachorowski void foo(T p);
4895934a791SAdam Czachorowski
4905934a791SAdam Czachorowski template <>
4915934a791SAdam Czachorowski void foo<int>(int p);
4925934a791SAdam Czachorowski
4935934a791SAdam Czachorowski template <typename T>
4945934a791SAdam Czachorowski void fo^o(T p) {
4955934a791SAdam Czachorowski return;
4965934a791SAdam Czachorowski })cpp",
4975934a791SAdam Czachorowski R"cpp(
4985934a791SAdam Czachorowski template <typename T>
4995934a791SAdam Czachorowski void foo(T p){
5005934a791SAdam Czachorowski return;
5015934a791SAdam Czachorowski }
5025934a791SAdam Czachorowski
5035934a791SAdam Czachorowski template <>
5045934a791SAdam Czachorowski void foo<int>(int p);
5055934a791SAdam Czachorowski
5065934a791SAdam Czachorowski )cpp"},
5075934a791SAdam Czachorowski };
5085934a791SAdam Czachorowski for (const auto &Case : Cases)
5095934a791SAdam Czachorowski EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
5105934a791SAdam Czachorowski }
5115934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformTypeLocs)5125934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformTypeLocs) {
513c0e3c893SChristian Kühnel auto *Test = R"cpp(
5145934a791SAdam Czachorowski namespace a {
5155934a791SAdam Czachorowski template <typename T> class Bar {
5165934a791SAdam Czachorowski public:
5175934a791SAdam Czachorowski template <typename Q> class Baz {};
5185934a791SAdam Czachorowski };
5195934a791SAdam Czachorowski class Foo{};
5205934a791SAdam Czachorowski }
5215934a791SAdam Czachorowski
5225934a791SAdam Czachorowski void foo();
5235934a791SAdam Czachorowski
5245934a791SAdam Czachorowski using namespace a;
5255934a791SAdam Czachorowski void f^oo() {
5265934a791SAdam Czachorowski Bar<int> B;
5275934a791SAdam Czachorowski Foo foo;
5285934a791SAdam Czachorowski a::Bar<Bar<int>>::Baz<Bar<int>> q;
5295934a791SAdam Czachorowski })cpp";
530c0e3c893SChristian Kühnel auto *Expected = R"cpp(
5315934a791SAdam Czachorowski namespace a {
5325934a791SAdam Czachorowski template <typename T> class Bar {
5335934a791SAdam Czachorowski public:
5345934a791SAdam Czachorowski template <typename Q> class Baz {};
5355934a791SAdam Czachorowski };
5365934a791SAdam Czachorowski class Foo{};
5375934a791SAdam Czachorowski }
5385934a791SAdam Czachorowski
5395934a791SAdam Czachorowski void foo(){
5405934a791SAdam Czachorowski a::Bar<int> B;
5415934a791SAdam Czachorowski a::Foo foo;
5425934a791SAdam Czachorowski a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
5435934a791SAdam Czachorowski }
5445934a791SAdam Czachorowski
5455934a791SAdam Czachorowski using namespace a;
5465934a791SAdam Czachorowski )cpp";
5475934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
5485934a791SAdam Czachorowski }
5495934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformDeclRefs)5505934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformDeclRefs) {
551c0e3c893SChristian Kühnel auto *Test = R"cpp(
5525934a791SAdam Czachorowski namespace a {
5535934a791SAdam Czachorowski template <typename T> class Bar {
5545934a791SAdam Czachorowski public:
5555934a791SAdam Czachorowski void foo();
5565934a791SAdam Czachorowski static void bar();
5575934a791SAdam Czachorowski int x;
5585934a791SAdam Czachorowski static int y;
5595934a791SAdam Czachorowski };
5605934a791SAdam Czachorowski void bar();
5615934a791SAdam Czachorowski void test();
5625934a791SAdam Czachorowski }
5635934a791SAdam Czachorowski
5645934a791SAdam Czachorowski void foo();
5655934a791SAdam Czachorowski using namespace a;
5665934a791SAdam Czachorowski void f^oo() {
5675934a791SAdam Czachorowski a::Bar<int> B;
5685934a791SAdam Czachorowski B.foo();
5695934a791SAdam Czachorowski a::bar();
5705934a791SAdam Czachorowski Bar<Bar<int>>::bar();
5715934a791SAdam Czachorowski a::Bar<int>::bar();
5725934a791SAdam Czachorowski B.x = Bar<int>::y;
5735934a791SAdam Czachorowski Bar<int>::y = 3;
5745934a791SAdam Czachorowski bar();
5755934a791SAdam Czachorowski a::test();
5765934a791SAdam Czachorowski })cpp";
577c0e3c893SChristian Kühnel auto *Expected = R"cpp(
5785934a791SAdam Czachorowski namespace a {
5795934a791SAdam Czachorowski template <typename T> class Bar {
5805934a791SAdam Czachorowski public:
5815934a791SAdam Czachorowski void foo();
5825934a791SAdam Czachorowski static void bar();
5835934a791SAdam Czachorowski int x;
5845934a791SAdam Czachorowski static int y;
5855934a791SAdam Czachorowski };
5865934a791SAdam Czachorowski void bar();
5875934a791SAdam Czachorowski void test();
5885934a791SAdam Czachorowski }
5895934a791SAdam Czachorowski
5905934a791SAdam Czachorowski void foo(){
5915934a791SAdam Czachorowski a::Bar<int> B;
5925934a791SAdam Czachorowski B.foo();
5935934a791SAdam Czachorowski a::bar();
5945934a791SAdam Czachorowski a::Bar<a::Bar<int>>::bar();
5955934a791SAdam Czachorowski a::Bar<int>::bar();
5965934a791SAdam Czachorowski B.x = a::Bar<int>::y;
5975934a791SAdam Czachorowski a::Bar<int>::y = 3;
5985934a791SAdam Czachorowski a::bar();
5995934a791SAdam Czachorowski a::test();
6005934a791SAdam Czachorowski }
6015934a791SAdam Czachorowski using namespace a;
6025934a791SAdam Czachorowski )cpp";
6035934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
6045934a791SAdam Czachorowski }
6055934a791SAdam Czachorowski
TEST_F(DefineInlineTest,StaticMembers)6065934a791SAdam Czachorowski TEST_F(DefineInlineTest, StaticMembers) {
607c0e3c893SChristian Kühnel auto *Test = R"cpp(
6085934a791SAdam Czachorowski namespace ns { class X { static void foo(); void bar(); }; }
6095934a791SAdam Czachorowski void ns::X::b^ar() {
6105934a791SAdam Czachorowski foo();
6115934a791SAdam Czachorowski })cpp";
612c0e3c893SChristian Kühnel auto *Expected = R"cpp(
6135934a791SAdam Czachorowski namespace ns { class X { static void foo(); void bar(){
6145934a791SAdam Czachorowski foo();
6155934a791SAdam Czachorowski } }; }
6165934a791SAdam Czachorowski )cpp";
6175934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
6185934a791SAdam Czachorowski }
6195934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformParamNames)6205934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformParamNames) {
6215934a791SAdam Czachorowski std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
6225934a791SAdam Czachorowski {R"cpp(
6235934a791SAdam Czachorowski void foo(int, bool b, int T\
6245934a791SAdam Czachorowski est);
6255934a791SAdam Czachorowski void ^foo(int f, bool x, int z) {})cpp",
6265934a791SAdam Czachorowski R"cpp(
6275934a791SAdam Czachorowski void foo(int f, bool x, int z){}
6285934a791SAdam Czachorowski )cpp"},
6295934a791SAdam Czachorowski {R"cpp(
6305934a791SAdam Czachorowski #define PARAM int Z
6315934a791SAdam Czachorowski void foo(PARAM);
6325934a791SAdam Czachorowski
6335934a791SAdam Czachorowski void ^foo(int X) {})cpp",
6345934a791SAdam Czachorowski "fail: Cant rename parameter inside macro body."},
6355934a791SAdam Czachorowski {R"cpp(
6365934a791SAdam Czachorowski #define TYPE int
6375934a791SAdam Czachorowski #define PARAM TYPE Z
6385934a791SAdam Czachorowski #define BODY(x) 5 * (x) + 2
6395934a791SAdam Czachorowski template <int P>
6405934a791SAdam Czachorowski void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
6415934a791SAdam Czachorowski template <int x>
6425934a791SAdam Czachorowski void ^foo(int Z, int b, int c, int d) {})cpp",
6435934a791SAdam Czachorowski R"cpp(
6445934a791SAdam Czachorowski #define TYPE int
6455934a791SAdam Czachorowski #define PARAM TYPE Z
6465934a791SAdam Czachorowski #define BODY(x) 5 * (x) + 2
6475934a791SAdam Czachorowski template <int x>
6485934a791SAdam Czachorowski void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
6495934a791SAdam Czachorowski )cpp"},
6505934a791SAdam Czachorowski };
6515934a791SAdam Czachorowski for (const auto &Case : Cases)
6525934a791SAdam Czachorowski EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
6535934a791SAdam Czachorowski }
6545934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformTemplParamNames)6555934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformTemplParamNames) {
656c0e3c893SChristian Kühnel auto *Test = R"cpp(
6575934a791SAdam Czachorowski struct Foo {
6585934a791SAdam Czachorowski struct Bar {
6595934a791SAdam Czachorowski template <class, class X,
6605934a791SAdam Czachorowski template<typename> class, template<typename> class Y,
6615934a791SAdam Czachorowski int, int Z>
6625934a791SAdam Czachorowski void foo(X, Y<X>, int W = 5 * Z + 2);
6635934a791SAdam Czachorowski };
6645934a791SAdam Czachorowski };
6655934a791SAdam Czachorowski
6665934a791SAdam Czachorowski template <class T, class U,
6675934a791SAdam Czachorowski template<typename> class V, template<typename> class W,
6685934a791SAdam Czachorowski int X, int Y>
6695934a791SAdam Czachorowski void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
670c0e3c893SChristian Kühnel auto *Expected = R"cpp(
6715934a791SAdam Czachorowski struct Foo {
6725934a791SAdam Czachorowski struct Bar {
6735934a791SAdam Czachorowski template <class T, class U,
6745934a791SAdam Czachorowski template<typename> class V, template<typename> class W,
6755934a791SAdam Czachorowski int X, int Y>
6765934a791SAdam Czachorowski void foo(U, W<U>, int Q = 5 * Y + 2){}
6775934a791SAdam Czachorowski };
6785934a791SAdam Czachorowski };
6795934a791SAdam Czachorowski
6805934a791SAdam Czachorowski )cpp";
6815934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
6825934a791SAdam Czachorowski }
6835934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TransformInlineNamespaces)6845934a791SAdam Czachorowski TEST_F(DefineInlineTest, TransformInlineNamespaces) {
685c0e3c893SChristian Kühnel auto *Test = R"cpp(
6865934a791SAdam Czachorowski namespace a { inline namespace b { namespace { struct Foo{}; } } }
6875934a791SAdam Czachorowski void foo();
6885934a791SAdam Czachorowski
6895934a791SAdam Czachorowski using namespace a;
6905934a791SAdam Czachorowski void ^foo() {Foo foo;})cpp";
691c0e3c893SChristian Kühnel auto *Expected = R"cpp(
6925934a791SAdam Czachorowski namespace a { inline namespace b { namespace { struct Foo{}; } } }
6935934a791SAdam Czachorowski void foo(){a::Foo foo;}
6945934a791SAdam Czachorowski
6955934a791SAdam Czachorowski using namespace a;
6965934a791SAdam Czachorowski )cpp";
6975934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected);
6985934a791SAdam Czachorowski }
6995934a791SAdam Czachorowski
TEST_F(DefineInlineTest,TokensBeforeSemicolon)7005934a791SAdam Czachorowski TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
7015934a791SAdam Czachorowski std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
7025934a791SAdam Czachorowski {R"cpp(
7035934a791SAdam Czachorowski void foo() /*Comment -_-*/ /*Com 2*/ ;
7045934a791SAdam Czachorowski void fo^o() { return ; })cpp",
7055934a791SAdam Czachorowski R"cpp(
7065934a791SAdam Czachorowski void foo() /*Comment -_-*/ /*Com 2*/ { return ; }
7075934a791SAdam Czachorowski )cpp"},
7085934a791SAdam Czachorowski
7095934a791SAdam Czachorowski {R"cpp(
7105934a791SAdam Czachorowski void foo();
7115934a791SAdam Czachorowski void fo^o() { return ; })cpp",
7125934a791SAdam Czachorowski R"cpp(
7135934a791SAdam Czachorowski void foo(){ return ; }
7145934a791SAdam Czachorowski )cpp"},
7155934a791SAdam Czachorowski
7165934a791SAdam Czachorowski {R"cpp(
7175934a791SAdam Czachorowski #define SEMI ;
7185934a791SAdam Czachorowski void foo() SEMI
7195934a791SAdam Czachorowski void fo^o() { return ; })cpp",
7205934a791SAdam Czachorowski "fail: Couldn't find semicolon for target declaration."},
7215934a791SAdam Czachorowski };
7225934a791SAdam Czachorowski for (const auto &Case : Cases)
7235934a791SAdam Czachorowski EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
7245934a791SAdam Czachorowski }
7255934a791SAdam Czachorowski
TEST_F(DefineInlineTest,HandleMacros)7265934a791SAdam Czachorowski TEST_F(DefineInlineTest, HandleMacros) {
7275934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
7285934a791SAdam Czachorowski #define BODY { return; }
7295934a791SAdam Czachorowski void foo();
7305934a791SAdam Czachorowski void f^oo()BODY)cpp");
7315934a791SAdam Czachorowski
7325934a791SAdam Czachorowski EXPECT_UNAVAILABLE(R"cpp(
7335934a791SAdam Czachorowski #define BODY void foo(){ return; }
7345934a791SAdam Czachorowski void foo();
7355934a791SAdam Czachorowski [[BODY]])cpp");
7365934a791SAdam Czachorowski
7375934a791SAdam Czachorowski std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
7385934a791SAdam Czachorowski // We don't qualify declarations coming from macros.
7395934a791SAdam Czachorowski {R"cpp(
7405934a791SAdam Czachorowski #define BODY Foo
7415934a791SAdam Czachorowski namespace a { class Foo{}; }
7425934a791SAdam Czachorowski void foo();
7435934a791SAdam Czachorowski using namespace a;
7445934a791SAdam Czachorowski void f^oo(){BODY();})cpp",
7455934a791SAdam Czachorowski R"cpp(
7465934a791SAdam Czachorowski #define BODY Foo
7475934a791SAdam Czachorowski namespace a { class Foo{}; }
7485934a791SAdam Czachorowski void foo(){BODY();}
7495934a791SAdam Czachorowski using namespace a;
7505934a791SAdam Czachorowski )cpp"},
7515934a791SAdam Czachorowski
7525934a791SAdam Czachorowski // Macro is not visible at declaration location, but we proceed.
7535934a791SAdam Czachorowski {R"cpp(
7545934a791SAdam Czachorowski void foo();
7555934a791SAdam Czachorowski #define BODY return;
7565934a791SAdam Czachorowski void f^oo(){BODY})cpp",
7575934a791SAdam Czachorowski R"cpp(
7585934a791SAdam Czachorowski void foo(){BODY}
7595934a791SAdam Czachorowski #define BODY return;
7605934a791SAdam Czachorowski )cpp"},
7615934a791SAdam Czachorowski
7625934a791SAdam Czachorowski {R"cpp(
7635934a791SAdam Czachorowski #define TARGET void foo()
7645934a791SAdam Czachorowski TARGET;
7655934a791SAdam Czachorowski void f^oo(){ return; })cpp",
7665934a791SAdam Czachorowski R"cpp(
7675934a791SAdam Czachorowski #define TARGET void foo()
7685934a791SAdam Czachorowski TARGET{ return; }
7695934a791SAdam Czachorowski )cpp"},
7705934a791SAdam Czachorowski
7715934a791SAdam Czachorowski {R"cpp(
7725934a791SAdam Czachorowski #define TARGET foo
7735934a791SAdam Czachorowski void TARGET();
7745934a791SAdam Czachorowski void f^oo(){ return; })cpp",
7755934a791SAdam Czachorowski R"cpp(
7765934a791SAdam Czachorowski #define TARGET foo
7775934a791SAdam Czachorowski void TARGET(){ return; }
7785934a791SAdam Czachorowski )cpp"},
7795934a791SAdam Czachorowski };
7805934a791SAdam Czachorowski for (const auto &Case : Cases)
7815934a791SAdam Czachorowski EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
7825934a791SAdam Czachorowski }
7835934a791SAdam Czachorowski
TEST_F(DefineInlineTest,DropCommonNameSpecifiers)7845934a791SAdam Czachorowski TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
7855934a791SAdam Czachorowski struct {
7865934a791SAdam Czachorowski llvm::StringRef Test;
7875934a791SAdam Czachorowski llvm::StringRef Expected;
7885934a791SAdam Czachorowski } Cases[] = {
7895934a791SAdam Czachorowski {R"cpp(
7905934a791SAdam Czachorowski namespace a { namespace b { void aux(); } }
7915934a791SAdam Czachorowski namespace ns1 {
7925934a791SAdam Czachorowski void foo();
7935934a791SAdam Czachorowski namespace qq { void test(); }
7945934a791SAdam Czachorowski namespace ns2 {
7955934a791SAdam Czachorowski void bar();
7965934a791SAdam Czachorowski namespace ns3 { void baz(); }
7975934a791SAdam Czachorowski }
7985934a791SAdam Czachorowski }
7995934a791SAdam Czachorowski
8005934a791SAdam Czachorowski using namespace a;
8015934a791SAdam Czachorowski using namespace a::b;
8025934a791SAdam Czachorowski using namespace ns1::qq;
8035934a791SAdam Czachorowski void ns1::ns2::ns3::b^az() {
8045934a791SAdam Czachorowski foo();
8055934a791SAdam Czachorowski bar();
8065934a791SAdam Czachorowski baz();
8075934a791SAdam Czachorowski ns1::ns2::ns3::baz();
8085934a791SAdam Czachorowski aux();
8095934a791SAdam Czachorowski test();
8105934a791SAdam Czachorowski })cpp",
8115934a791SAdam Czachorowski R"cpp(
8125934a791SAdam Czachorowski namespace a { namespace b { void aux(); } }
8135934a791SAdam Czachorowski namespace ns1 {
8145934a791SAdam Czachorowski void foo();
8155934a791SAdam Czachorowski namespace qq { void test(); }
8165934a791SAdam Czachorowski namespace ns2 {
8175934a791SAdam Czachorowski void bar();
8185934a791SAdam Czachorowski namespace ns3 { void baz(){
8195934a791SAdam Czachorowski foo();
8205934a791SAdam Czachorowski bar();
8215934a791SAdam Czachorowski baz();
8225934a791SAdam Czachorowski ns1::ns2::ns3::baz();
8235934a791SAdam Czachorowski a::b::aux();
8245934a791SAdam Czachorowski qq::test();
8255934a791SAdam Czachorowski } }
8265934a791SAdam Czachorowski }
8275934a791SAdam Czachorowski }
8285934a791SAdam Czachorowski
8295934a791SAdam Czachorowski using namespace a;
8305934a791SAdam Czachorowski using namespace a::b;
8315934a791SAdam Czachorowski using namespace ns1::qq;
8325934a791SAdam Czachorowski )cpp"},
8335934a791SAdam Czachorowski {R"cpp(
8345934a791SAdam Czachorowski namespace ns1 {
8355934a791SAdam Czachorowski namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
8365934a791SAdam Czachorowski namespace ns2 { void baz(); }
8375934a791SAdam Czachorowski }
8385934a791SAdam Czachorowski
8395934a791SAdam Czachorowski using namespace ns1::qq;
8405934a791SAdam Czachorowski void ns1::ns2::b^az() { Foo f; B b; })cpp",
8415934a791SAdam Czachorowski R"cpp(
8425934a791SAdam Czachorowski namespace ns1 {
8435934a791SAdam Czachorowski namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
8445934a791SAdam Czachorowski namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
8455934a791SAdam Czachorowski }
8465934a791SAdam Czachorowski
8475934a791SAdam Czachorowski using namespace ns1::qq;
8485934a791SAdam Czachorowski )cpp"},
8495934a791SAdam Czachorowski {R"cpp(
8505934a791SAdam Czachorowski namespace ns1 {
8515934a791SAdam Czachorowski namespace qq {
8525934a791SAdam Czachorowski template<class T> struct Foo { template <class U> struct Bar {}; };
8535934a791SAdam Czachorowski template<class T, class U>
8545934a791SAdam Czachorowski using B = typename Foo<T>::template Bar<U>;
8555934a791SAdam Czachorowski }
8565934a791SAdam Czachorowski namespace ns2 { void baz(); }
8575934a791SAdam Czachorowski }
8585934a791SAdam Czachorowski
8595934a791SAdam Czachorowski using namespace ns1::qq;
8605934a791SAdam Czachorowski void ns1::ns2::b^az() { B<int, bool> b; })cpp",
8615934a791SAdam Czachorowski R"cpp(
8625934a791SAdam Czachorowski namespace ns1 {
8635934a791SAdam Czachorowski namespace qq {
8645934a791SAdam Czachorowski template<class T> struct Foo { template <class U> struct Bar {}; };
8655934a791SAdam Czachorowski template<class T, class U>
8665934a791SAdam Czachorowski using B = typename Foo<T>::template Bar<U>;
8675934a791SAdam Czachorowski }
8685934a791SAdam Czachorowski namespace ns2 { void baz(){ qq::B<int, bool> b; } }
8695934a791SAdam Czachorowski }
8705934a791SAdam Czachorowski
8715934a791SAdam Czachorowski using namespace ns1::qq;
8725934a791SAdam Czachorowski )cpp"},
8735934a791SAdam Czachorowski };
8745934a791SAdam Czachorowski for (const auto &Case : Cases)
8755934a791SAdam Czachorowski EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
8765934a791SAdam Czachorowski }
8775934a791SAdam Czachorowski
TEST_F(DefineInlineTest,QualifyWithUsingDirectives)8785934a791SAdam Czachorowski TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
8795934a791SAdam Czachorowski llvm::StringRef Test = R"cpp(
8805934a791SAdam Czachorowski namespace a {
8815934a791SAdam Czachorowski void bar();
8825934a791SAdam Czachorowski namespace b { struct Foo{}; void aux(); }
8835934a791SAdam Czachorowski namespace c { void cux(); }
8845934a791SAdam Czachorowski }
8855934a791SAdam Czachorowski using namespace a;
8865934a791SAdam Czachorowski using X = b::Foo;
8875934a791SAdam Czachorowski void foo();
8885934a791SAdam Czachorowski
8895934a791SAdam Czachorowski using namespace b;
8905934a791SAdam Czachorowski using namespace c;
8915934a791SAdam Czachorowski void ^foo() {
8925934a791SAdam Czachorowski cux();
8935934a791SAdam Czachorowski bar();
8945934a791SAdam Czachorowski X x;
8955934a791SAdam Czachorowski aux();
8965934a791SAdam Czachorowski using namespace c;
8975934a791SAdam Czachorowski // FIXME: The last reference to cux() in body of foo should not be
8985934a791SAdam Czachorowski // qualified, since there is a using directive inside the function body.
8995934a791SAdam Czachorowski cux();
9005934a791SAdam Czachorowski })cpp";
9015934a791SAdam Czachorowski llvm::StringRef Expected = R"cpp(
9025934a791SAdam Czachorowski namespace a {
9035934a791SAdam Czachorowski void bar();
9045934a791SAdam Czachorowski namespace b { struct Foo{}; void aux(); }
9055934a791SAdam Czachorowski namespace c { void cux(); }
9065934a791SAdam Czachorowski }
9075934a791SAdam Czachorowski using namespace a;
9085934a791SAdam Czachorowski using X = b::Foo;
9095934a791SAdam Czachorowski void foo(){
9105934a791SAdam Czachorowski c::cux();
9115934a791SAdam Czachorowski bar();
9125934a791SAdam Czachorowski X x;
9135934a791SAdam Czachorowski b::aux();
9145934a791SAdam Czachorowski using namespace c;
9155934a791SAdam Czachorowski // FIXME: The last reference to cux() in body of foo should not be
9165934a791SAdam Czachorowski // qualified, since there is a using directive inside the function body.
9175934a791SAdam Czachorowski c::cux();
9185934a791SAdam Czachorowski }
9195934a791SAdam Czachorowski
9205934a791SAdam Czachorowski using namespace b;
9215934a791SAdam Czachorowski using namespace c;
9225934a791SAdam Czachorowski )cpp";
9235934a791SAdam Czachorowski EXPECT_EQ(apply(Test), Expected) << Test;
9245934a791SAdam Czachorowski }
9255934a791SAdam Czachorowski
TEST_F(DefineInlineTest,AddInline)9265934a791SAdam Czachorowski TEST_F(DefineInlineTest, AddInline) {
9275934a791SAdam Czachorowski llvm::StringMap<std::string> EditedFiles;
9285934a791SAdam Czachorowski ExtraFiles["a.h"] = "void foo();";
9295934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9305934a791SAdam Czachorowski void fo^o() {})cpp",
9315934a791SAdam Czachorowski &EditedFiles);
9325934a791SAdam Czachorowski EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
9335934a791SAdam Czachorowski testPath("a.h"), "inline void foo(){}")));
9345934a791SAdam Czachorowski
9355934a791SAdam Czachorowski // Check we put inline before cv-qualifiers.
9365934a791SAdam Czachorowski ExtraFiles["a.h"] = "const int foo();";
9375934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9385934a791SAdam Czachorowski const int fo^o() {})cpp",
9395934a791SAdam Czachorowski &EditedFiles);
9405934a791SAdam Czachorowski EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
9415934a791SAdam Czachorowski testPath("a.h"), "inline const int foo(){}")));
9425934a791SAdam Czachorowski
9435934a791SAdam Czachorowski // No double inline.
9445934a791SAdam Czachorowski ExtraFiles["a.h"] = "inline void foo();";
9455934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9465934a791SAdam Czachorowski inline void fo^o() {})cpp",
9475934a791SAdam Czachorowski &EditedFiles);
9485934a791SAdam Czachorowski EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
9495934a791SAdam Czachorowski testPath("a.h"), "inline void foo(){}")));
9505934a791SAdam Czachorowski
9515934a791SAdam Czachorowski // Constexprs don't need "inline".
9525934a791SAdam Czachorowski ExtraFiles["a.h"] = "constexpr void foo();";
9535934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9545934a791SAdam Czachorowski constexpr void fo^o() {})cpp",
9555934a791SAdam Czachorowski &EditedFiles);
9565934a791SAdam Czachorowski EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
9575934a791SAdam Czachorowski testPath("a.h"), "constexpr void foo(){}")));
9585934a791SAdam Czachorowski
9595934a791SAdam Czachorowski // Class members don't need "inline".
9605934a791SAdam Czachorowski ExtraFiles["a.h"] = "struct Foo { void foo(); };";
9615934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9625934a791SAdam Czachorowski void Foo::fo^o() {})cpp",
9635934a791SAdam Czachorowski &EditedFiles);
9645934a791SAdam Czachorowski EXPECT_THAT(EditedFiles,
9655934a791SAdam Czachorowski testing::ElementsAre(FileWithContents(
9665934a791SAdam Czachorowski testPath("a.h"), "struct Foo { void foo(){} };")));
9675934a791SAdam Czachorowski
9685934a791SAdam Czachorowski // Function template doesn't need to be "inline"d.
9695934a791SAdam Czachorowski ExtraFiles["a.h"] = "template <typename T> void foo();";
9705934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9715934a791SAdam Czachorowski template <typename T>
9725934a791SAdam Czachorowski void fo^o() {})cpp",
9735934a791SAdam Czachorowski &EditedFiles);
9745934a791SAdam Czachorowski EXPECT_THAT(EditedFiles,
9755934a791SAdam Czachorowski testing::ElementsAre(FileWithContents(
9765934a791SAdam Czachorowski testPath("a.h"), "template <typename T> void foo(){}")));
9775934a791SAdam Czachorowski
9785934a791SAdam Czachorowski // Specializations needs to be marked "inline".
9795934a791SAdam Czachorowski ExtraFiles["a.h"] = R"cpp(
9805934a791SAdam Czachorowski template <typename T> void foo();
9815934a791SAdam Czachorowski template <> void foo<int>();)cpp";
9825934a791SAdam Czachorowski apply(R"cpp(#include "a.h"
9835934a791SAdam Czachorowski template <>
9845934a791SAdam Czachorowski void fo^o<int>() {})cpp",
9855934a791SAdam Czachorowski &EditedFiles);
9865934a791SAdam Czachorowski EXPECT_THAT(EditedFiles,
9875934a791SAdam Czachorowski testing::ElementsAre(FileWithContents(testPath("a.h"),
9885934a791SAdam Czachorowski R"cpp(
9895934a791SAdam Czachorowski template <typename T> void foo();
9905934a791SAdam Czachorowski template <> inline void foo<int>(){})cpp")));
9915934a791SAdam Czachorowski }
9925934a791SAdam Czachorowski
9935934a791SAdam Czachorowski } // namespace
9945934a791SAdam Czachorowski } // namespace clangd
9955934a791SAdam Czachorowski } // namespace clang
996