• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- DefineInlineTests.cpp -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TestTU.h"
10 #include "TweakTesting.h"
11 #include "gmock/gmock-matchers.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 
15 using ::testing::ElementsAre;
16 
17 namespace clang {
18 namespace clangd {
19 namespace {
20 
21 TWEAK_TEST(DefineInline);
22 
TEST_F(DefineInlineTest,TriggersOnFunctionDecl)23 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
24   // Basic check for function body and signature.
25   EXPECT_AVAILABLE(R"cpp(
26   class Bar {
27     void baz();
28   };
29 
30   [[void [[Bar::[[b^a^z]]]]() [[{
31     return;
32   }]]]]
33 
34   void foo();
35   [[void [[f^o^o]]() [[{
36     return;
37   }]]]]
38   )cpp");
39 
40   EXPECT_UNAVAILABLE(R"cpp(
41   // Not a definition
42   vo^i[[d^ ^f]]^oo();
43 
44   [[vo^id ]]foo[[()]] {[[
45     [[(void)(5+3);
46     return;]]
47   }]]
48 
49   // Definition with no body.
50   class Bar { Bar() = def^ault; };
51   )cpp");
52 }
53 
TEST_F(DefineInlineTest,NoForwardDecl)54 TEST_F(DefineInlineTest, NoForwardDecl) {
55   Header = "void bar();";
56   EXPECT_UNAVAILABLE(R"cpp(
57   void bar() {
58     return;
59   }
60   // FIXME: Generate a decl in the header.
61   void fo^o() {
62     return;
63   })cpp");
64 }
65 
TEST_F(DefineInlineTest,ReferencedDecls)66 TEST_F(DefineInlineTest, ReferencedDecls) {
67   EXPECT_AVAILABLE(R"cpp(
68     void bar();
69     void foo(int test);
70 
71     void fo^o(int baz) {
72       int x = 10;
73       bar();
74     })cpp");
75 
76   // Internal symbol usage.
77   Header = "void foo(int test);";
78   EXPECT_UNAVAILABLE(R"cpp(
79     void bar();
80     void fo^o(int baz) {
81       int x = 10;
82       bar();
83     })cpp");
84 
85   // Becomes available after making symbol visible.
86   Header = "void bar();" + Header;
87   EXPECT_AVAILABLE(R"cpp(
88     void fo^o(int baz) {
89       int x = 10;
90       bar();
91     })cpp");
92 
93   // FIXME: Move declaration below bar to make it visible.
94   Header.clear();
95   EXPECT_UNAVAILABLE(R"cpp(
96     void foo();
97     void bar();
98 
99     void fo^o() {
100       bar();
101     })cpp");
102 
103   // Order doesn't matter within a class.
104   EXPECT_AVAILABLE(R"cpp(
105     class Bar {
106       void foo();
107       void bar();
108     };
109 
110     void Bar::fo^o() {
111       bar();
112     })cpp");
113 
114   // FIXME: Perform include insertion to make symbol visible.
115   ExtraFiles["a.h"] = "void bar();";
116   Header = "void foo(int test);";
117   EXPECT_UNAVAILABLE(R"cpp(
118     #include "a.h"
119     void fo^o(int baz) {
120       int x = 10;
121       bar();
122     })cpp");
123 }
124 
TEST_F(DefineInlineTest,TemplateSpec)125 TEST_F(DefineInlineTest, TemplateSpec) {
126   EXPECT_UNAVAILABLE(R"cpp(
127     template <typename T> void foo();
128     template<> void foo<char>();
129 
130     template<> void f^oo<int>() {
131     })cpp");
132   EXPECT_UNAVAILABLE(R"cpp(
133     template <typename T> void foo();
134 
135     template<> void f^oo<int>() {
136     })cpp");
137   EXPECT_UNAVAILABLE(R"cpp(
138     template <typename T> struct Foo { void foo(); };
139 
140     template <typename T> void Foo<T>::f^oo() {
141     })cpp");
142   EXPECT_AVAILABLE(R"cpp(
143     template <typename T> void foo();
144     void bar();
145     template <> void foo<int>();
146 
147     template<> void f^oo<int>() {
148       bar();
149     })cpp");
150   EXPECT_UNAVAILABLE(R"cpp(
151     namespace bar {
152       template <typename T> void f^oo() {}
153       template void foo<int>();
154     })cpp");
155 }
156 
TEST_F(DefineInlineTest,CheckForCanonDecl)157 TEST_F(DefineInlineTest, CheckForCanonDecl) {
158   EXPECT_UNAVAILABLE(R"cpp(
159     void foo();
160 
161     void bar() {}
162     void f^oo() {
163       // This bar normally refers to the definition just above, but it is not
164       // visible from the forward declaration of foo.
165       bar();
166     })cpp");
167   // Make it available with a forward decl.
168   EXPECT_AVAILABLE(R"cpp(
169     void bar();
170     void foo();
171 
172     void bar() {}
173     void f^oo() {
174       bar();
175     })cpp");
176 }
177 
TEST_F(DefineInlineTest,UsingShadowDecls)178 TEST_F(DefineInlineTest, UsingShadowDecls) {
179   // Template body is not parsed until instantiation time on windows, which
180   // results in arbitrary failures as function body becomes NULL.
181   ExtraArgs.push_back("-fno-delayed-template-parsing");
182   EXPECT_UNAVAILABLE(R"cpp(
183   namespace ns1 { void foo(int); }
184   namespace ns2 { void foo(int*); }
185   template <typename T>
186   void bar();
187 
188   using ns1::foo;
189   using ns2::foo;
190 
191   template <typename T>
192   void b^ar() {
193     foo(T());
194   })cpp");
195 }
196 
TEST_F(DefineInlineTest,TransformNestedNamespaces)197 TEST_F(DefineInlineTest, TransformNestedNamespaces) {
198   auto Test = R"cpp(
199     namespace a {
200       void bar();
201       namespace b {
202         void baz();
203         namespace c {
204           void aux();
205         }
206       }
207     }
208 
209     void foo();
210     using namespace a;
211     using namespace b;
212     using namespace c;
213     void f^oo() {
214       bar();
215       a::bar();
216 
217       baz();
218       b::baz();
219       a::b::baz();
220 
221       aux();
222       c::aux();
223       b::c::aux();
224       a::b::c::aux();
225     })cpp";
226   auto Expected = R"cpp(
227     namespace a {
228       void bar();
229       namespace b {
230         void baz();
231         namespace c {
232           void aux();
233         }
234       }
235     }
236 
237     void foo(){
238       a::bar();
239       a::bar();
240 
241       a::b::baz();
242       a::b::baz();
243       a::b::baz();
244 
245       a::b::c::aux();
246       a::b::c::aux();
247       a::b::c::aux();
248       a::b::c::aux();
249     }
250     using namespace a;
251     using namespace b;
252     using namespace c;
253     )cpp";
254   EXPECT_EQ(apply(Test), Expected);
255 }
256 
TEST_F(DefineInlineTest,TransformUsings)257 TEST_F(DefineInlineTest, TransformUsings) {
258   auto Test = R"cpp(
259     namespace a { namespace b { namespace c { void aux(); } } }
260 
261     void foo();
262     void f^oo() {
263       using namespace a;
264       using namespace b;
265       using namespace c;
266       using c::aux;
267       namespace d = c;
268     })cpp";
269   auto Expected = R"cpp(
270     namespace a { namespace b { namespace c { void aux(); } } }
271 
272     void foo(){
273       using namespace a;
274       using namespace a::b;
275       using namespace a::b::c;
276       using a::b::c::aux;
277       namespace d = a::b::c;
278     }
279     )cpp";
280   EXPECT_EQ(apply(Test), Expected);
281 }
282 
TEST_F(DefineInlineTest,TransformDecls)283 TEST_F(DefineInlineTest, TransformDecls) {
284   auto Test = R"cpp(
285     void foo();
286     void f^oo() {
287       class Foo {
288       public:
289         void foo();
290         int x;
291       };
292 
293       enum En { Zero, One };
294       En x = Zero;
295 
296       enum class EnClass { Zero, One };
297       EnClass y = EnClass::Zero;
298     })cpp";
299   auto Expected = R"cpp(
300     void foo(){
301       class Foo {
302       public:
303         void foo();
304         int x;
305       };
306 
307       enum En { Zero, One };
308       En x = Zero;
309 
310       enum class EnClass { Zero, One };
311       EnClass y = EnClass::Zero;
312     }
313     )cpp";
314   EXPECT_EQ(apply(Test), Expected);
315 }
316 
TEST_F(DefineInlineTest,TransformTemplDecls)317 TEST_F(DefineInlineTest, TransformTemplDecls) {
318   auto Test = R"cpp(
319     namespace a {
320       template <typename T> class Bar {
321       public:
322         void bar();
323       };
324       template <typename T> T bar;
325       template <typename T> void aux() {}
326     }
327 
328     void foo();
329 
330     using namespace a;
331     void f^oo() {
332       bar<Bar<int>>.bar();
333       aux<Bar<int>>();
334     })cpp";
335   auto Expected = R"cpp(
336     namespace a {
337       template <typename T> class Bar {
338       public:
339         void bar();
340       };
341       template <typename T> T bar;
342       template <typename T> void aux() {}
343     }
344 
345     void foo(){
346       a::bar<a::Bar<int>>.bar();
347       a::aux<a::Bar<int>>();
348     }
349 
350     using namespace a;
351     )cpp";
352   EXPECT_EQ(apply(Test), Expected);
353 }
354 
TEST_F(DefineInlineTest,TransformMembers)355 TEST_F(DefineInlineTest, TransformMembers) {
356   auto Test = R"cpp(
357     class Foo {
358       void foo();
359     };
360 
361     void Foo::f^oo() {
362       return;
363     })cpp";
364   auto Expected = R"cpp(
365     class Foo {
366       void foo(){
367       return;
368     }
369     };
370 
371     )cpp";
372   EXPECT_EQ(apply(Test), Expected);
373 
374   ExtraFiles["a.h"] = R"cpp(
375     class Foo {
376       void foo();
377     };)cpp";
378 
379   llvm::StringMap<std::string> EditedFiles;
380   Test = R"cpp(
381     #include "a.h"
382     void Foo::f^oo() {
383       return;
384     })cpp";
385   Expected = R"cpp(
386     #include "a.h"
387     )cpp";
388   EXPECT_EQ(apply(Test, &EditedFiles), Expected);
389 
390   Expected = R"cpp(
391     class Foo {
392       void foo(){
393       return;
394     }
395     };)cpp";
396   EXPECT_THAT(EditedFiles,
397               ElementsAre(FileWithContents(testPath("a.h"), Expected)));
398 }
399 
TEST_F(DefineInlineTest,TransformDependentTypes)400 TEST_F(DefineInlineTest, TransformDependentTypes) {
401   auto Test = R"cpp(
402     namespace a {
403       template <typename T> class Bar {};
404     }
405 
406     template <typename T>
407     void foo();
408 
409     using namespace a;
410     template <typename T>
411     void f^oo() {
412       Bar<T> B;
413       Bar<Bar<T>> q;
414     })cpp";
415   auto Expected = R"cpp(
416     namespace a {
417       template <typename T> class Bar {};
418     }
419 
420     template <typename T>
421     void foo(){
422       a::Bar<T> B;
423       a::Bar<a::Bar<T>> q;
424     }
425 
426     using namespace a;
427     )cpp";
428 
429   // Template body is not parsed until instantiation time on windows, which
430   // results in arbitrary failures as function body becomes NULL.
431   ExtraArgs.push_back("-fno-delayed-template-parsing");
432   EXPECT_EQ(apply(Test), Expected);
433 }
434 
TEST_F(DefineInlineTest,TransformFunctionTempls)435 TEST_F(DefineInlineTest, TransformFunctionTempls) {
436   // Check we select correct specialization decl.
437   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
438       {R"cpp(
439           template <typename T>
440           void foo(T p);
441 
442           template <>
443           void foo<int>(int p);
444 
445           template <>
446           void foo<char>(char p);
447 
448           template <>
449           void fo^o<int>(int p) {
450             return;
451           })cpp",
452        R"cpp(
453           template <typename T>
454           void foo(T p);
455 
456           template <>
457           void foo<int>(int p){
458             return;
459           }
460 
461           template <>
462           void foo<char>(char p);
463 
464           )cpp"},
465       {// Make sure we are not selecting the first specialization all the time.
466        R"cpp(
467           template <typename T>
468           void foo(T p);
469 
470           template <>
471           void foo<int>(int p);
472 
473           template <>
474           void foo<char>(char p);
475 
476           template <>
477           void fo^o<char>(char p) {
478             return;
479           })cpp",
480        R"cpp(
481           template <typename T>
482           void foo(T p);
483 
484           template <>
485           void foo<int>(int p);
486 
487           template <>
488           void foo<char>(char p){
489             return;
490           }
491 
492           )cpp"},
493       {R"cpp(
494           template <typename T>
495           void foo(T p);
496 
497           template <>
498           void foo<int>(int p);
499 
500           template <typename T>
501           void fo^o(T p) {
502             return;
503           })cpp",
504        R"cpp(
505           template <typename T>
506           void foo(T p){
507             return;
508           }
509 
510           template <>
511           void foo<int>(int p);
512 
513           )cpp"},
514   };
515   // Template body is not parsed until instantiation time on windows, which
516   // results in arbitrary failures as function body becomes NULL.
517   ExtraArgs.push_back("-fno-delayed-template-parsing");
518   for (const auto &Case : Cases)
519     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
520 }
521 
TEST_F(DefineInlineTest,TransformTypeLocs)522 TEST_F(DefineInlineTest, TransformTypeLocs) {
523   auto Test = R"cpp(
524     namespace a {
525       template <typename T> class Bar {
526       public:
527         template <typename Q> class Baz {};
528       };
529       class Foo{};
530     }
531 
532     void foo();
533 
534     using namespace a;
535     void f^oo() {
536       Bar<int> B;
537       Foo foo;
538       a::Bar<Bar<int>>::Baz<Bar<int>> q;
539     })cpp";
540   auto Expected = R"cpp(
541     namespace a {
542       template <typename T> class Bar {
543       public:
544         template <typename Q> class Baz {};
545       };
546       class Foo{};
547     }
548 
549     void foo(){
550       a::Bar<int> B;
551       a::Foo foo;
552       a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
553     }
554 
555     using namespace a;
556     )cpp";
557   EXPECT_EQ(apply(Test), Expected);
558 }
559 
TEST_F(DefineInlineTest,TransformDeclRefs)560 TEST_F(DefineInlineTest, TransformDeclRefs) {
561   auto Test = R"cpp(
562     namespace a {
563       template <typename T> class Bar {
564       public:
565         void foo();
566         static void bar();
567         int x;
568         static int y;
569       };
570       void bar();
571       void test();
572     }
573 
574     void foo();
575     using namespace a;
576     void f^oo() {
577       a::Bar<int> B;
578       B.foo();
579       a::bar();
580       Bar<Bar<int>>::bar();
581       a::Bar<int>::bar();
582       B.x = Bar<int>::y;
583       Bar<int>::y = 3;
584       bar();
585       a::test();
586     })cpp";
587   auto Expected = R"cpp(
588     namespace a {
589       template <typename T> class Bar {
590       public:
591         void foo();
592         static void bar();
593         int x;
594         static int y;
595       };
596       void bar();
597       void test();
598     }
599 
600     void foo(){
601       a::Bar<int> B;
602       B.foo();
603       a::bar();
604       a::Bar<a::Bar<int>>::bar();
605       a::Bar<int>::bar();
606       B.x = a::Bar<int>::y;
607       a::Bar<int>::y = 3;
608       a::bar();
609       a::test();
610     }
611     using namespace a;
612     )cpp";
613   EXPECT_EQ(apply(Test), Expected);
614 }
615 
TEST_F(DefineInlineTest,StaticMembers)616 TEST_F(DefineInlineTest, StaticMembers) {
617   auto Test = R"cpp(
618     namespace ns { class X { static void foo(); void bar(); }; }
619     void ns::X::b^ar() {
620       foo();
621     })cpp";
622   auto Expected = R"cpp(
623     namespace ns { class X { static void foo(); void bar(){
624       foo();
625     } }; }
626     )cpp";
627   EXPECT_EQ(apply(Test), Expected);
628 }
629 
TEST_F(DefineInlineTest,TransformParamNames)630 TEST_F(DefineInlineTest, TransformParamNames) {
631   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
632       {R"cpp(
633         void foo(int, bool b, int T\
634 est);
635         void ^foo(int f, bool x, int z) {})cpp",
636        R"cpp(
637         void foo(int f, bool x, int z){}
638         )cpp"},
639       {R"cpp(
640         #define PARAM int Z
641         void foo(PARAM);
642 
643         void ^foo(int X) {})cpp",
644        "fail: Cant rename parameter inside macro body."},
645       {R"cpp(
646         #define TYPE int
647         #define PARAM TYPE Z
648         #define BODY(x) 5 * (x) + 2
649         template <int P>
650         void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
651         template <int x>
652         void ^foo(int Z, int b, int c, int d) {})cpp",
653        R"cpp(
654         #define TYPE int
655         #define PARAM TYPE Z
656         #define BODY(x) 5 * (x) + 2
657         template <int x>
658         void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
659         )cpp"},
660   };
661   ExtraArgs.push_back("-fno-delayed-template-parsing");
662   for (const auto &Case : Cases)
663     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
664 }
665 
TEST_F(DefineInlineTest,TransformTemplParamNames)666 TEST_F(DefineInlineTest, TransformTemplParamNames) {
667   auto Test = R"cpp(
668     struct Foo {
669       struct Bar {
670         template <class, class X,
671                   template<typename> class, template<typename> class Y,
672                   int, int Z>
673         void foo(X, Y<X>, int W = 5 * Z + 2);
674       };
675     };
676 
677     template <class T, class U,
678               template<typename> class V, template<typename> class W,
679               int X, int Y>
680     void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
681   auto Expected = R"cpp(
682     struct Foo {
683       struct Bar {
684         template <class T, class U,
685                   template<typename> class V, template<typename> class W,
686                   int X, int Y>
687         void foo(U, W<U>, int Q = 5 * Y + 2){}
688       };
689     };
690 
691     )cpp";
692   ExtraArgs.push_back("-fno-delayed-template-parsing");
693   EXPECT_EQ(apply(Test), Expected);
694 }
695 
TEST_F(DefineInlineTest,TransformInlineNamespaces)696 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
697   auto Test = R"cpp(
698     namespace a { inline namespace b { namespace { struct Foo{}; } } }
699     void foo();
700 
701     using namespace a;
702     void ^foo() {Foo foo;})cpp";
703   auto Expected = R"cpp(
704     namespace a { inline namespace b { namespace { struct Foo{}; } } }
705     void foo(){a::Foo foo;}
706 
707     using namespace a;
708     )cpp";
709   EXPECT_EQ(apply(Test), Expected);
710 }
711 
TEST_F(DefineInlineTest,TokensBeforeSemicolon)712 TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
713   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
714       {R"cpp(
715           void foo()    /*Comment -_-*/ /*Com 2*/ ;
716           void fo^o() { return ; })cpp",
717        R"cpp(
718           void foo()    /*Comment -_-*/ /*Com 2*/ { return ; }
719           )cpp"},
720 
721       {R"cpp(
722           void foo();
723           void fo^o() { return ; })cpp",
724        R"cpp(
725           void foo(){ return ; }
726           )cpp"},
727 
728       {R"cpp(
729           #define SEMI ;
730           void foo() SEMI
731           void fo^o() { return ; })cpp",
732        "fail: Couldn't find semicolon for target declaration."},
733   };
734   for (const auto &Case : Cases)
735     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
736 }
737 
TEST_F(DefineInlineTest,HandleMacros)738 TEST_F(DefineInlineTest, HandleMacros) {
739   EXPECT_UNAVAILABLE(R"cpp(
740     #define BODY { return; }
741     void foo();
742     void f^oo()BODY)cpp");
743 
744   EXPECT_UNAVAILABLE(R"cpp(
745     #define BODY void foo(){ return; }
746     void foo();
747     [[BODY]])cpp");
748 
749   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
750       // We don't qualify declarations coming from macros.
751       {R"cpp(
752           #define BODY Foo
753           namespace a { class Foo{}; }
754           void foo();
755           using namespace a;
756           void f^oo(){BODY();})cpp",
757        R"cpp(
758           #define BODY Foo
759           namespace a { class Foo{}; }
760           void foo(){BODY();}
761           using namespace a;
762           )cpp"},
763 
764       // Macro is not visible at declaration location, but we proceed.
765       {R"cpp(
766           void foo();
767           #define BODY return;
768           void f^oo(){BODY})cpp",
769        R"cpp(
770           void foo(){BODY}
771           #define BODY return;
772           )cpp"},
773 
774       {R"cpp(
775           #define TARGET void foo()
776           TARGET;
777           void f^oo(){ return; })cpp",
778        R"cpp(
779           #define TARGET void foo()
780           TARGET{ return; }
781           )cpp"},
782 
783       {R"cpp(
784           #define TARGET foo
785           void TARGET();
786           void f^oo(){ return; })cpp",
787        R"cpp(
788           #define TARGET foo
789           void TARGET(){ return; }
790           )cpp"},
791   };
792   for (const auto &Case : Cases)
793     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
794 }
795 
TEST_F(DefineInlineTest,DropCommonNameSpecifiers)796 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
797   struct {
798     llvm::StringRef Test;
799     llvm::StringRef Expected;
800   } Cases[] = {
801       {R"cpp(
802         namespace a { namespace b { void aux(); } }
803         namespace ns1 {
804           void foo();
805           namespace qq { void test(); }
806           namespace ns2 {
807             void bar();
808             namespace ns3 { void baz(); }
809           }
810         }
811 
812         using namespace a;
813         using namespace a::b;
814         using namespace ns1::qq;
815         void ns1::ns2::ns3::b^az() {
816           foo();
817           bar();
818           baz();
819           ns1::ns2::ns3::baz();
820           aux();
821           test();
822         })cpp",
823        R"cpp(
824         namespace a { namespace b { void aux(); } }
825         namespace ns1 {
826           void foo();
827           namespace qq { void test(); }
828           namespace ns2 {
829             void bar();
830             namespace ns3 { void baz(){
831           foo();
832           bar();
833           baz();
834           ns1::ns2::ns3::baz();
835           a::b::aux();
836           qq::test();
837         } }
838           }
839         }
840 
841         using namespace a;
842         using namespace a::b;
843         using namespace ns1::qq;
844         )cpp"},
845       {R"cpp(
846         namespace ns1 {
847           namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
848           namespace ns2 { void baz(); }
849         }
850 
851         using namespace ns1::qq;
852         void ns1::ns2::b^az() { Foo f; B b; })cpp",
853        R"cpp(
854         namespace ns1 {
855           namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
856           namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
857         }
858 
859         using namespace ns1::qq;
860         )cpp"},
861       {R"cpp(
862         namespace ns1 {
863           namespace qq {
864             template<class T> struct Foo { template <class U> struct Bar {}; };
865             template<class T, class U>
866             using B = typename Foo<T>::template Bar<U>;
867           }
868           namespace ns2 { void baz(); }
869         }
870 
871         using namespace ns1::qq;
872         void ns1::ns2::b^az() { B<int, bool> b; })cpp",
873        R"cpp(
874         namespace ns1 {
875           namespace qq {
876             template<class T> struct Foo { template <class U> struct Bar {}; };
877             template<class T, class U>
878             using B = typename Foo<T>::template Bar<U>;
879           }
880           namespace ns2 { void baz(){ qq::B<int, bool> b; } }
881         }
882 
883         using namespace ns1::qq;
884         )cpp"},
885   };
886   for (const auto &Case : Cases)
887     EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
888 }
889 
TEST_F(DefineInlineTest,QualifyWithUsingDirectives)890 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
891   llvm::StringRef Test = R"cpp(
892     namespace a {
893       void bar();
894       namespace b { struct Foo{}; void aux(); }
895       namespace c { void cux(); }
896     }
897     using namespace a;
898     using X = b::Foo;
899     void foo();
900 
901     using namespace b;
902     using namespace c;
903     void ^foo() {
904       cux();
905       bar();
906       X x;
907       aux();
908       using namespace c;
909       // FIXME: The last reference to cux() in body of foo should not be
910       // qualified, since there is a using directive inside the function body.
911       cux();
912     })cpp";
913   llvm::StringRef Expected = R"cpp(
914     namespace a {
915       void bar();
916       namespace b { struct Foo{}; void aux(); }
917       namespace c { void cux(); }
918     }
919     using namespace a;
920     using X = b::Foo;
921     void foo(){
922       c::cux();
923       bar();
924       X x;
925       b::aux();
926       using namespace c;
927       // FIXME: The last reference to cux() in body of foo should not be
928       // qualified, since there is a using directive inside the function body.
929       c::cux();
930     }
931 
932     using namespace b;
933     using namespace c;
934     )cpp";
935   EXPECT_EQ(apply(Test), Expected) << Test;
936 }
937 
TEST_F(DefineInlineTest,AddInline)938 TEST_F(DefineInlineTest, AddInline) {
939   ExtraArgs.push_back("-fno-delayed-template-parsing");
940   llvm::StringMap<std::string> EditedFiles;
941   ExtraFiles["a.h"] = "void foo();";
942   apply(R"cpp(#include "a.h"
943               void fo^o() {})cpp",
944         &EditedFiles);
945   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
946                                testPath("a.h"), "inline void foo(){}")));
947 
948   // Check we put inline before cv-qualifiers.
949   ExtraFiles["a.h"] = "const int foo();";
950   apply(R"cpp(#include "a.h"
951               const int fo^o() {})cpp",
952         &EditedFiles);
953   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
954                                testPath("a.h"), "inline const int foo(){}")));
955 
956   // No double inline.
957   ExtraFiles["a.h"] = "inline void foo();";
958   apply(R"cpp(#include "a.h"
959               inline void fo^o() {})cpp",
960         &EditedFiles);
961   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
962                                testPath("a.h"), "inline void foo(){}")));
963 
964   // Constexprs don't need "inline".
965   ExtraFiles["a.h"] = "constexpr void foo();";
966   apply(R"cpp(#include "a.h"
967               constexpr void fo^o() {})cpp",
968         &EditedFiles);
969   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
970                                testPath("a.h"), "constexpr void foo(){}")));
971 
972   // Class members don't need "inline".
973   ExtraFiles["a.h"] = "struct Foo { void foo(); };";
974   apply(R"cpp(#include "a.h"
975               void Foo::fo^o() {})cpp",
976         &EditedFiles);
977   EXPECT_THAT(EditedFiles,
978               testing::ElementsAre(FileWithContents(
979                   testPath("a.h"), "struct Foo { void foo(){} };")));
980 
981   // Function template doesn't need to be "inline"d.
982   ExtraFiles["a.h"] = "template <typename T> void foo();";
983   apply(R"cpp(#include "a.h"
984               template <typename T>
985               void fo^o() {})cpp",
986         &EditedFiles);
987   EXPECT_THAT(EditedFiles,
988               testing::ElementsAre(FileWithContents(
989                   testPath("a.h"), "template <typename T> void foo(){}")));
990 
991   // Specializations needs to be marked "inline".
992   ExtraFiles["a.h"] = R"cpp(
993                             template <typename T> void foo();
994                             template <> void foo<int>();)cpp";
995   apply(R"cpp(#include "a.h"
996               template <>
997               void fo^o<int>() {})cpp",
998         &EditedFiles);
999   EXPECT_THAT(EditedFiles,
1000               testing::ElementsAre(FileWithContents(testPath("a.h"),
1001                                                     R"cpp(
1002                             template <typename T> void foo();
1003                             template <> inline void foo<int>(){})cpp")));
1004 }
1005 
1006 } // namespace
1007 } // namespace clangd
1008 } // namespace clang
1009