15 #include "clang/AST/Expr.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticIDs.h"
18 #include "clang/Basic/DiagnosticOptions.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/FileSystemOptions.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Rewrite/Core/Rewriter.h"
25 #include "clang/Tooling/Core/Replacement.h"
26 #include "llvm/ADT/IntrusiveRefCntPtr.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/ADT/StringMap.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/VirtualFileSystem.h"
33 #include "llvm/Testing/Support/Error.h"
34 #include "gmock/gmock-matchers.h"
35 #include "gmock/gmock.h"
36 #include "gtest/gtest.h"
42 using ::testing::AllOf;
43 using ::testing::ElementsAre;
44 using ::testing::HasSubstr;
45 using ::testing::StartsWith;
56 auto RelPaths = {
"a.h",
"foo.cpp",
"test/test.cpp"};
58 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
60 MemFS->setCurrentWorkingDirectory(
testRoot());
61 for (
auto Path : RelPaths)
62 MemFS->addFile(
Path, 0, llvm::MemoryBuffer::getMemBuffer(
"",
Path));
63 FileManager FM(FileSystemOptions(), MemFS);
64 DiagnosticsEngine DE(
new DiagnosticIDs,
new DiagnosticOptions);
65 SourceManager SM(DE, FM);
67 for (
auto Path : RelPaths) {
68 auto FID = SM.createFileID(*FM.getFile(
Path), SourceLocation(),
69 clang::SrcMgr::C_User);
71 ASSERT_THAT_EXPECTED(Res, llvm::Succeeded());
77 TEST_F(SwapIfBranchesTest, Test) {
79 EXPECT_EQ(apply(
"^if (true) {return;} else {(void)0;}"),
80 "if (true) {(void)0;} else {return;}");
81 EXPECT_EQ(apply(
"^if (/*error-ok*/) {return;} else {(void)0;}"),
82 "if (/*error-ok*/) {(void)0;} else {return;}")
83 <<
"broken condition";
87 EXPECT_THAT(
"if(2 + [[2]] + 2) { return; } else {return;}", isAvailable());
89 EXPECT_THAT(
"if(2 + 2 + 2) { [[return]]; } else { return; }",
92 EXPECT_THAT(
"if(2 + 2 + 2) { return[[; } else {return;]]}", isAvailable());
94 EXPECT_THAT(
"if([]{return [[true]];}()) { return; } else { return; }",
97 EXPECT_THAT(
"^if (1) return; else { return; }", Not(isAvailable()));
99 EXPECT_THAT(
"[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
103 TEST_F(RawStringLiteralTest, Test) {
104 Context = Expression;
113 const char *Input = R
"cpp(R"(multi
114 token)" "\nst^ring\n" "literal")cpp";
115 const char *
Output = R
"cpp(R"(multi
119 EXPECT_EQ(apply(Input), Output);
123 TEST_F(ObjCLocalizeStringLiteralTest, Test) {
124 ExtraArgs.push_back("-x");
125 ExtraArgs.push_back(
"objective-c");
136 const char *Input = R
"(id x = [[@"test"]];)";
137 const char *
Output = R
"(id x = NSLocalizedString(@"test", @"");)";
138 EXPECT_EQ(apply(Input), Output);
142 TEST_F(DumpASTTest, Test) {
145 EXPECT_THAT(apply(
"int x = 2 ^+ 2;"),
146 AllOf(StartsWith(
"message:"), HasSubstr(
"BinaryOperator"),
147 HasSubstr(
"'+'"), HasSubstr(
"|-IntegerLiteral"),
148 HasSubstr(
"<col:9> 'int' 2\n`-IntegerLiteral"),
149 HasSubstr(
"<col:13> 'int' 2")));
153 TEST_F(DumpSymbolTest, Test) {
154 std::string ID = R
"("id":"CA2EBE44A1D76D2A")";
155 std::string USR = R"("usr":"c:@F@foo#")";
156 EXPECT_THAT(apply("void f^oo();"),
157 AllOf(StartsWith(
"message:"), testing::HasSubstr(ID),
158 testing::HasSubstr(USR)));
162 TEST_F(ShowSelectionTreeTest, Test) {
166 const char *
Output = R
"(message:
168 VarDecl int x = fcall(2 + 2)
169 .CallExpr fcall(2 + 2)
170 ImplicitCastExpr fcall
172 .BinaryOperator 2 + 2
175 EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"),
Output);
179 FunctionDecl void x()
184 EXPECT_EQ(apply("void x() { for (;;) br^eak; }"),
Output);
188 TEST_F(DumpRecordLayoutTest, Test) {
190 EXPECT_THAT(
"struct X { int ^a; };", Not(isAvailable()));
191 EXPECT_THAT(
"struct ^X;", Not(isAvailable()));
192 EXPECT_THAT(
"template <typename T> struct ^X { T t; };", Not(isAvailable()));
193 EXPECT_THAT(
"enum ^X {};", Not(isAvailable()));
195 EXPECT_THAT(apply(
"struct ^X { int x; int y; };"),
196 AllOf(StartsWith(
"message:"), HasSubstr(
"0 | int x")));
200 TEST_F(ExtractVariableTest, Test) {
201 const char *AvailableCases = R
"cpp(
208 return [[[[t.b[[a]]r]](t.z)]];
211 int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
212 // multivariable initialization
214 int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
229 for(a = [[1]]; a > [[[[3]] + [[4]]]]; a++)
243 const char *AvailableButC = R
"cpp(
250 const char *NoCrashCases = R
"cpp(
251 // error-ok: broken code, but shouldn't crash
252 template<typename T, typename ...Args>
253 struct Test<T, Args...> {
254 Test(const T &v) :val[[(^]]) {}
260 const char *UnavailableCases = R
"cpp(
261 int xyz(int a = [[1]]) {
263 int bar(int a = [[1]]);
266 return [[t]].bar([[[[t]].z]]);
269 // function default argument
270 void f(int b = [[1]]) {
274 auto i = new int, j = new int;
275 [[[[delete i]], delete j]];
279 int x = 1, y = a + 1, a = 1, z = [[a + 1]];
284 for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]])
287 auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;};
291 // Variable DeclRefExpr
293 // statement expression
306 const std::vector<std::pair<std::string, std::string>>
309 {R
"cpp(void varDecl() {
310 int a = 5 * (4 + (3 [[- 1)]]);
312 R"cpp(void varDecl() {
313 auto dummy = (3 - 1); int a = 5 * (4 + dummy);
339 {R
"cpp(#define PLUS(x) x++
341 int y = PLUS([[1+a]]);
348 R
"cpp(#define PLUS(x) x++
350 auto dummy = PLUS(1+a); int y = dummy;
353 {R
"cpp(#define LOOP(x) while (1) {a = x;}
358 R"cpp(#define LOOP(x) while (1) {a = x;}
360 auto dummy = 3; if(1)
363 {R"cpp(#define LOOP(x) do {x;} while(1);
368 R"cpp(#define LOOP(x) do {x;} while(1);
370 auto dummy = 3; if(1)
374 {R
"cpp(void f(int a) {
375 [ [gsl::suppress("type")] ] for (;;) a = [[1]];
377 R"cpp(void f(int a) {
378 auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy;
383 return [[T().f()]].f();
388 auto dummy = T().f(); return dummy.f();
396 auto dummy = f(); return dummy;
404 int x = 1 + [[2 + 3 + 4]] + 5;
407 auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5;
410 int x = [[1 + 2 + 3]] + 4 + 5;
413 auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5;
416 int x = 1 + 2 + [[3 + 4 + 5]];
419 auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy;
423 int x = 1 - [[2 - 3 - 4]] - 5;
426 auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5;
430 int x = 0 + 1 * [[2 + 3]] * 4 + 5;
433 auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5;
443 S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5);
451 auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5);
455 {R
"cpp(#define ECHO(X) X
457 int x = 1 + [[ECHO(2 + 3) + 4]] + 5;
459 R"cpp(#define ECHO(X) X
461 auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5;
463 {R"cpp(#define ECHO(X) X
465 int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5;
467 R"cpp(#define ECHO(X) X
469 auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5;
472 for (
const auto &IO : InputOutputs) {
473 EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
478 TEST_F(AnnotateHighlightingsTest, Test) {
481 EXPECT_EQ(
"void /* entity.name.function.cpp */f() {}", apply(
"void ^f() {}"));
483 EXPECT_EQ(apply(
"[[void f1(); void f2();]]"),
484 "void /* entity.name.function.cpp */f1(); "
485 "void /* entity.name.function.cpp */f2();");
487 EXPECT_EQ(apply(
"void f1(); void f2() {^}"),
489 "void /* entity.name.function.cpp */f2() {}");
493 TEST_F(ExpandMacroTest, Test) {
495 // error-ok: not real c++, just token manipulation
497 #define FUNC(X) X+X+X
510 EXPECT_EQ(apply(
"^FOO BAR FOO"),
"1 2 3 BAR FOO");
511 EXPECT_EQ(apply(
"FOO BAR ^FOO"),
"FOO BAR 1 2 3");
513 EXPECT_EQ(apply(
"F^UNC(2)"),
"2 + 2 + 2");
516 EXPECT_EQ(apply(
"int a ^EMPTY;"),
"int a ;");
517 EXPECT_EQ(apply(
"int a ^EMPTY_FN(1 2 3);"),
"int a ;");
518 EXPECT_EQ(apply(
"int a = 123 ^EMPTY EMPTY_FN(1);"),
519 "int a = 123 EMPTY_FN(1);");
520 EXPECT_EQ(apply(
"int a = 123 ^EMPTY_FN(1) EMPTY;"),
"int a = 123 EMPTY;");
521 EXPECT_EQ(apply(
"int a = 123 EMPTY_FN(1) ^EMPTY;"),
522 "int a = 123 EMPTY_FN(1) ;");
526 TEST_F(ExpandAutoTypeTest, Test) {
535 inline namespace inl_ns {
546 EXPECT_EQ(apply(
"[[auto]] i = 0;"),
"int i = 0;");
547 EXPECT_EQ(apply(
"au^to i = 0;"),
"int i = 0;");
549 EXPECT_EQ(apply(
"^auto C = ns::Class::Nested();"),
550 "ns::Class::Nested C = ns::Class::Nested();");
552 EXPECT_EQ(apply(
"namespace ns { void f() { ^auto C = Class(); } }"),
553 "namespace ns { void f() { Class C = Class(); } }");
555 EXPECT_THAT(apply(
"au^to x = doesnt_exist(); // error-ok"),
556 StartsWith(
"fail: Could not deduce type for 'auto' type"));
558 EXPECT_THAT(apply(
"au^to x = &ns::Func;"),
559 StartsWith(
"fail: Could not expand type of function pointer"));
561 EXPECT_THAT(apply(
"au^to x = []{};"),
562 StartsWith(
"fail: Could not expand type of lambda expression"));
564 EXPECT_EQ(apply(
"au^to x = inl_ns::Visible();"),
565 "Visible x = inl_ns::Visible();");
567 EXPECT_EQ(apply(
"namespace x { void y() { struct S{}; ^auto z = S(); } }"),
568 "namespace x { void y() { struct S{}; S z = S(); } }");
570 EXPECT_EQ(apply(R
"cpp(au^to x = "test";)cpp"),
571 R"cpp(const char * x = "test";)cpp");
577 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
579 EXPECT_THAT(apply(
"template <typename T> void x() { ^auto y = T::z(); }"),
580 StartsWith(
"fail: Could not deduce type for 'auto' type"));
584 TEST_F(ExtractFunctionTest, FunctionTest) {
588 EXPECT_EQ(apply(
"for(;;) [[1+2; 1+2;]]"),
"unavailable");
590 EXPECT_EQ(apply(
"int x = 0; [[x++;]]"),
"unavailable");
592 EXPECT_EQ(apply(
"auto lam = [](){ [[int x;]] }; "),
"unavailable");
594 EXPECT_THAT(apply(
"int [[x = 0]];"),
"unavailable");
598 EXPECT_THAT(apply(
"for(;;) { [[int x;]]break; }"), HasSubstr(
"extracted"));
601 EXPECT_THAT(apply(
" for([[int i = 0;]];);"), HasSubstr(
"extracted"));
603 EXPECT_THAT(apply(
" [[int a = 5;]] a++; "), StartsWith(
"fail"));
605 EXPECT_THAT(apply(
" if(true) [[{ return; }]] "), HasSubstr(
"extracted"));
607 EXPECT_THAT(apply(
" if(true) [[if (false) return;]] "), StartsWith(
"fail"));
610 TEST_F(ExtractFunctionTest, FileTest) {
612 std::string ParameterCheckInput = R
"cpp(
623 std::string ParameterCheckOutput = R"cpp(
627 void extracted(int &a, int &b, int * &ptr, Foo &foo) {
635 extracted(a, b, ptr, foo);
637 EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
640 std::string ConstCheckInput = R
"cpp(
641 void f(const int c) {
644 std::string ConstCheckOutput = R"cpp(
645 void extracted(const int &c) {
648 void f(const int c) {
651 EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
654 EXPECT_THAT(apply(
"void f() { [[int a; f();]] }"), StartsWith(
"fail"));
658 std::string MethodFailInput = R
"cpp(
665 EXPECT_EQ(apply(MethodFailInput), "unavailable");
669 std::string TemplateFailInput = R
"cpp(
675 EXPECT_EQ(apply(TemplateFailInput), "unavailable");
677 std::string MacroInput = R
"cpp(
678 #define F(BODY) void f() { BODY }
681 std::string MacroOutput = R"cpp(
682 #define F(BODY) void f() { BODY }
688 EXPECT_EQ(apply(MacroInput), MacroOutput);
691 EXPECT_EQ(apply(
"void f([[int a]]);"),
"unavailable");
693 std::string CompoundFailInput = R
"cpp(
698 EXPECT_EQ(apply(CompoundFailInput), "unavailable");
701 TEST_F(ExtractFunctionTest, ControlFlow) {
704 EXPECT_THAT(apply(
" [[for(;;) if(1) break;]] "), HasSubstr(
"extracted"));
705 EXPECT_THAT(apply(
" for(;;) [[while(1) break;]] "), HasSubstr(
"extracted"));
706 EXPECT_THAT(apply(
" [[switch(1) { break; }]]"), HasSubstr(
"extracted"));
707 EXPECT_THAT(apply(
" [[while(1) switch(1) { continue; }]]"),
708 HasSubstr(
"extracted"));
710 EXPECT_THAT(apply(
" for(;;) [[if(1) continue;]] "), StartsWith(
"fail"));
711 EXPECT_THAT(apply(
" while(1) [[if(1) break;]] "), StartsWith(
"fail"));
712 EXPECT_THAT(apply(
" switch(1) { [[break;]] }"), StartsWith(
"fail"));
713 EXPECT_THAT(apply(
" for(;;) { [[while(1) break; break;]] }"),
717 TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
719 const char* Before = R
"cpp(
721 int getNum(bool Superstitious, int Min, int Max) {
722 if (Superstitious) [[{
723 for (int I = Min; I <= Max; ++I)
728 return (Min + Max) / 2;
734 const char* After = R
"cpp(
736 int extracted(int &Min, int &Max) {
738 for (int I = Min; I <= Max; ++I)
744 int getNum(bool Superstitious, int Min, int Max) {
745 if (Superstitious) return extracted(Min, Max); else {
746 return (Min + Max) / 2;
750 EXPECT_EQ(apply(Before), After);
754 TEST_F(RemoveUsingNamespaceTest, All) {
755 std::pair<llvm::StringRef , llvm::StringRef > Cases[] = {
758 namespace ns1 { struct vector {}; }
759 namespace ns2 { struct map {}; }
760 using namespace n^s1;
770 namespace ns1 { struct vector {}; }
771 namespace ns2 { struct map {}; }
783 #define DECLARE(x, y) x y
784 namespace ns { struct vector {}; }
787 DECLARE(ns::vector, v1);
792 #define DECLARE(x, y) x y
793 namespace ns { struct vector {}; }
796 DECLARE(ns::vector, v1);
797 DECLARE(ns::vector, v2);
802 namespace aa { namespace bb { struct map {}; }}
803 using namespace aa::b^b;
809 namespace aa { namespace bb { struct map {}; }}
817 namespace aa { namespace bb { struct map {}; }}
824 namespace aa { namespace bb { struct map {}; }}
832 namespace aa { namespace bb { struct map {}; }}
835 int main() { map M; }
838 namespace aa { namespace bb { struct map {}; }}
840 typedef aa::bb::map map;
841 int main() { map M; }
845 namespace aa { namespace bb { struct map {}; }}
846 using name[[space aa::b]]b;
853 namespace aa { namespace bb { struct map {}; }}
862 namespace aa { namespace bb { struct map {}; }}
863 using namespace aa::bb;
870 namespace aa { namespace bb { struct map {}; }}
871 using namespace aa::bb;
880 namespace bb { struct map {}; }
883 int main() { aa::map m; }
889 namespace bb { struct map {}; }
899 namespace a::b { struct Foo {}; }
901 using namespace a::[[b]];
906 namespace a::b { struct Foo {}; }
910 int main() { a::b::Foo F;}
913 namespace a::b { struct Foo {}; }
915 using namespace a::b;
916 using namespace [[b]];
920 namespace a::b { struct Foo {}; }
924 int main() { b::Foo F;}
930 comma, identifier, numeric
933 using namespace tok^ens;
941 comma, identifier, numeric
946 auto x = tokens::comma;
951 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
952 using namespace st^d;
958 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
965 EXPECT_EQ(C.second, apply(C.first)) << C.first;
969 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
976 [[void [[Bar::[[b^a^z]]]]() [[{
981 [[void [[f^o^o]]() [[{
990 [[vo^id ]]foo[[()]] {[[
995 // Definition with no body.
996 class Bar { Bar() = def^ault; };
1000 TEST_F(DefineInlineTest, NoForwardDecl) {
1001 Header = "void bar();";
1006 // FIXME: Generate a decl in the header.
1012 TEST_F(DefineInlineTest, ReferencedDecls) {
1017 void fo^o(int baz) {
1023 Header =
"void foo(int test);";
1026 void fo^o(int baz) {
1032 Header =
"void bar();" + Header;
1034 void fo^o(int baz) {
1061 ExtraFiles[
"a.h"] =
"void bar();";
1062 Header =
"void foo(int test);";
1065 void fo^o(int baz) {
1071 TEST_F(DefineInlineTest, TemplateSpec) {
1073 template <typename T> void foo();
1074 template<> void foo<char>();
1076 template<> void f^oo<int>() {
1079 template <typename T> void foo();
1081 template<> void f^oo<int>() {
1084 template <typename T> struct Foo { void foo(); };
1086 template <typename T> void Foo<T>::f^oo() {
1089 template <typename T> void foo();
1091 template <> void foo<int>();
1093 template<> void f^oo<int>() {
1098 TEST_F(DefineInlineTest, CheckForCanonDecl) {
1104 // This bar normally refers to the definition just above, but it is not
1105 // visible from the forward declaration of foo.
1119 TEST_F(DefineInlineTest, UsingShadowDecls) {
1122 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1124 namespace ns1 { void foo(int); }
1125 namespace ns2 { void foo(int*); }
1126 template <typename T>
1132 template <typename T>
1138 TEST_F(DefineInlineTest, TransformNestedNamespaces) {
1198 TEST_F(DefineInlineTest, TransformUsings) {
1200 namespace a { namespace b { namespace c { void aux(); } } }
1211 namespace a { namespace b { namespace c { void aux(); } } }
1215 using namespace a::b;
1216 using namespace a::b::c;
1218 namespace d = a::b::c;
1224 TEST_F(DefineInlineTest, TransformDecls) {
1234 enum En { Zero, One };
1237 enum class EnClass { Zero, One };
1238 EnClass y = EnClass::Zero;
1248 enum En { Zero, One };
1251 enum class EnClass { Zero, One };
1252 EnClass y = EnClass::Zero;
1258 TEST_F(DefineInlineTest, TransformTemplDecls) {
1261 template <typename T> class Bar {
1265 template <typename T> T bar;
1266 template <typename T> void aux() {}
1273 bar<Bar<int>>.bar();
1278 template <typename T> class Bar {
1282 template <typename T> T bar;
1283 template <typename T> void aux() {}
1287 a::bar<a::Bar<int>>.bar();
1288 a::aux<a::Bar<int>>();
1296 TEST_F(DefineInlineTest, TransformMembers) {
1315 ExtraFiles["a.h"] = R
"cpp(
1320 llvm::StringMap<std::string> EditedFiles;
1329 EXPECT_EQ(apply(Test, &EditedFiles), Expected);
1337 EXPECT_THAT(EditedFiles,
1341 TEST_F(DefineInlineTest, TransformDependentTypes) {
1344 template <typename T> class Bar {};
1347 template <typename T>
1351 template <typename T>
1358 template <typename T> class Bar {};
1361 template <typename T>
1364 a::Bar<a::Bar<T>> q;
1372 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1376 TEST_F(DefineInlineTest, TransformFunctionTempls) {
1378 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1380 template <typename T>
1384 void foo<int>(int p);
1387 void foo<char>(char p);
1390 void fo^o<int>(int p) {
1394 template <typename T>
1398 void foo<int>(int p){
1403 void foo<char>(char p);
1408 template <typename T>
1412 void foo<int>(int p);
1415 void foo<char>(char p);
1418 void fo^o<char>(char p) {
1422 template <typename T>
1426 void foo<int>(int p);
1429 void foo<char>(char p){
1435 template <typename T>
1439 void foo<int>(int p);
1441 template <typename T>
1446 template <typename T>
1452 void foo<int>(int p);
1458 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1459 for (
const auto &Case : Cases)
1460 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1463 TEST_F(DefineInlineTest, TransformTypeLocs) {
1466 template <typename T> class Bar {
1468 template <typename Q> class Baz {};
1479 a::Bar<Bar<int>>::Baz<Bar<int>> q;
1483 template <typename T> class Bar {
1485 template <typename Q> class Baz {};
1493 a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
1501 TEST_F(DefineInlineTest, TransformDeclRefs) {
1504 template <typename T> class Bar {
1521 Bar<Bar<int>>::bar();
1530 template <typename T> class Bar {
1545 a::Bar<a::Bar<int>>::bar();
1547 B.x = a::Bar<int>::y;
1557 TEST_F(DefineInlineTest, StaticMembers) {
1559 namespace ns { class X { static void foo(); void bar(); }; }
1560 void ns::X::b^ar() {
1564 namespace ns { class X { static void foo(); void bar(){
1571 TEST_F(DefineInlineTest, TransformParamNames) {
1572 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1574 void foo(int, bool b, int T\
1576 void ^foo(int f, bool x, int z) {})cpp",
1578 void foo(int f, bool x, int z){}
1584 void ^foo(int X) {})cpp",
1585 "fail: Cant rename parameter inside macro body."},
1588 #define PARAM TYPE Z
1589 #define BODY(x) 5 * (x) + 2
1591 void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
1593 void ^foo(int Z, int b, int c, int d) {})cpp",
1596 #define PARAM TYPE Z
1597 #define BODY(x) 5 * (x) + 2
1599 void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
1602 ExtraArgs.push_back("-fno-delayed-template-parsing");
1603 for (
const auto &Case : Cases)
1604 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1607 TEST_F(DefineInlineTest, TransformTemplParamNames) {
1611 template <class, class X,
1612 template<typename> class, template<typename> class Y,
1614 void foo(X, Y<X>, int W = 5 * Z + 2);
1618 template <class T, class U,
1619 template<typename> class V, template<typename> class W,
1621 void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
1625 template <class T, class U,
1626 template<typename> class V, template<typename> class W,
1628 void foo(U, W<U>, int Q = 5 * Y + 2){}
1633 ExtraArgs.push_back("-fno-delayed-template-parsing");
1637 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
1639 namespace a { inline namespace b { namespace { struct Foo{}; } } }
1643 void ^foo() {Foo foo;})cpp";
1645 namespace a { inline namespace b { namespace { struct Foo{}; } } }
1646 void foo(){a::Foo foo;}
1653 TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
1654 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1656 void foo() /*Comment -_-*/ /*Com 2*/ ;
1657 void fo^o() { return ; })cpp",
1659 void foo() /*Comment -_-*/ /*Com 2*/ { return ; }
1664 void fo^o() { return ; })cpp",
1666 void foo(){ return ; }
1672 void fo^o() { return ; })cpp",
1673 "fail: Couldn't find semicolon for target declaration."},
1675 for (
const auto &Case : Cases)
1676 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1679 TEST_F(DefineInlineTest, HandleMacros) {
1681 #define BODY { return; }
1683 void f^oo()BODY)cpp");
1686 #define BODY void foo(){ return; }
1690 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1694 namespace a { class Foo{}; }
1697 void f^oo(){BODY();})cpp",
1700 namespace a { class Foo{}; }
1708 #define BODY return;
1709 void f^oo(){BODY})cpp",
1712 #define BODY return;
1716 #define TARGET void foo()
1718 void f^oo(){ return; })cpp",
1720 #define TARGET void foo()
1727 void f^oo(){ return; })cpp",
1730 void TARGET(){ return; }
1733 for (
const auto &Case : Cases)
1734 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1737 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
1739 llvm::StringRef Test;
1743 namespace a { namespace b { void aux(); } }
1746 namespace qq { void test(); }
1749 namespace ns3 { void baz(); }
1754 using namespace a::b;
1755 using namespace ns1::qq;
1756 void ns1::ns2::ns3::b^az() {
1760 ns1::ns2::ns3::baz();
1765 namespace a { namespace b { void aux(); } }
1768 namespace qq { void test(); }
1771 namespace ns3 { void baz(){
1775 ns1::ns2::ns3::baz();
1783 using namespace a::b;
1784 using namespace ns1::qq;
1788 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1789 namespace ns2 { void baz(); }
1792 using namespace ns1::qq;
1793 void ns1::ns2::b^az() { Foo f; B b; })cpp",
1796 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1797 namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
1800 using namespace ns1::qq;
1805 template<class T> struct Foo { template <class U> struct Bar {}; };
1806 template<class T, class U>
1807 using B = typename Foo<T>::template Bar<U>;
1809 namespace ns2 { void baz(); }
1812 using namespace ns1::qq;
1813 void ns1::ns2::b^az() { B<int, bool> b; })cpp",
1817 template<class T> struct Foo { template <class U> struct Bar {}; };
1818 template<class T, class U>
1819 using B = typename Foo<T>::template Bar<U>;
1821 namespace ns2 { void baz(){ qq::B<int, bool> b; } }
1824 using namespace ns1::qq;
1827 for (
const auto &Case : Cases)
1828 EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
1831 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
1832 llvm::StringRef Test = R
"cpp(
1835 namespace b { struct Foo{}; void aux(); }
1836 namespace c { void cux(); }
1850 // FIXME: The last reference to cux() in body of foo should not be
1851 // qualified, since there is a using directive inside the function body.
1857 namespace b { struct Foo{}; void aux(); }
1858 namespace c { void cux(); }
1868 // FIXME: The last reference to cux() in body of foo should not be
1869 // qualified, since there is a using directive inside the function body.
1876 EXPECT_EQ(apply(Test), Expected) << Test;
1879 TEST_F(DefineInlineTest, AddInline) {
1880 ExtraArgs.push_back("-fno-delayed-template-parsing");
1881 llvm::StringMap<std::string> EditedFiles;
1882 ExtraFiles[
"a.h"] =
"void foo();";
1883 apply(R
"cpp(#include "a.h"
1884 void fo^o() {})cpp",
1886 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1887 testPath("a.h"),
"inline void foo(){}")));
1890 ExtraFiles[
"a.h"] =
"const int foo();";
1891 apply(R
"cpp(#include "a.h"
1892 const int fo^o() {})cpp",
1894 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1895 testPath("a.h"),
"inline const int foo(){}")));
1898 ExtraFiles[
"a.h"] =
"inline void foo();";
1899 apply(R
"cpp(#include "a.h"
1900 inline void fo^o() {})cpp",
1902 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1903 testPath("a.h"),
"inline void foo(){}")));
1906 ExtraFiles[
"a.h"] =
"constexpr void foo();";
1907 apply(R
"cpp(#include "a.h"
1908 constexpr void fo^o() {})cpp",
1910 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1911 testPath("a.h"),
"constexpr void foo(){}")));
1914 ExtraFiles[
"a.h"] =
"struct Foo { void foo(); };";
1915 apply(R
"cpp(#include "a.h"
1916 void Foo::fo^o() {})cpp",
1918 EXPECT_THAT(EditedFiles,
1919 testing::ElementsAre(FileWithContents(
1920 testPath("a.h"),
"struct Foo { void foo(){} };")));
1923 ExtraFiles[
"a.h"] =
"template <typename T> void foo();";
1924 apply(R
"cpp(#include "a.h"
1925 template <typename T>
1926 void fo^o() {})cpp",
1928 EXPECT_THAT(EditedFiles,
1929 testing::ElementsAre(FileWithContents(
1930 testPath("a.h"),
"template <typename T> void foo(){}")));
1933 ExtraFiles[
"a.h"] = R
"cpp(
1934 template <typename T> void foo();
1935 template <> void foo<int>();)cpp";
1936 apply(R"cpp(#include "a.h"
1938 void fo^o<int>() {})cpp",
1940 EXPECT_THAT(EditedFiles,
1941 testing::ElementsAre(FileWithContents(testPath("a.h"),
1943 template <typename T> void foo();
1944 template <> inline void foo<int>(){})cpp")));
1948 TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
1952 [[void [[f^o^o]]() [[{
1962 [[vo^id ]]foo[[()]] {[[
1969 [[void [[f^o^o]]() [[{
1979 [[void [[Bar::[[b^a^z]]]]() [[{
1986 [[void [[f^o^o^]]() [[{ return; }]]]]
1990 [[void [[f^o^o]]() [[{
1998 F^oo(const Foo&) = delete;
2004 template <typename> struct Foo { void fo^o(){} };
2008 TEST_F(DefineOutlineTest, FailsWithoutSource) {
2010 llvm::StringRef Test =
"void fo^o() { return; }";
2012 "fail: Couldn't find a suitable implementation file.";
2016 TEST_F(DefineOutlineTest, ApplyTest) {
2017 llvm::StringMap<std::string> EditedFiles;
2018 ExtraFiles[
"Test.cpp"] =
"";
2022 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
2025 llvm::StringRef Test;
2026 llvm::StringRef ExpectedHeader;
2027 llvm::StringRef ExpectedSource;
2031 "void fo^o() { return; }",
2033 "void foo() { return; }",
2037 "template <typename T> void fo^o(T, T x) { return; }",
2038 "template <typename T> void foo(T, T x) ;",
2039 "template <typename T> void foo(T, T x) { return; }",
2042 "template <typename> void fo^o() { return; }",
2043 "template <typename> void foo() ;",
2044 "template <typename> void foo() { return; }",
2049 template <typename> void foo();
2050 template <> void fo^o<int>() { return; })cpp",
2052 template <typename> void foo();
2053 template <> void foo<int>() ;)cpp",
2054 "template <> void foo<int>() { return; }",
2058 "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
2059 "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
2060 "void foo(int x, int y , int , int (*foo)(int) ) {}",
2065 class Foo {public: Foo(); Foo(int);};
2068 Bar(int x) : f1(x) {}
2073 class Foo {public: Foo(); Foo(int);};
2076 Bar(int x) : f1(x) {}
2085 class Foo {public: Foo(); Foo(int);};
2088 B^ar(int x) : f1(x), f2(3) {}
2093 class Foo {public: Foo(); Foo(int);};
2100 "Bar::Bar(int x) : f1(x), f2(3) {}\n",
2106 F^oo(int z) __attribute__((weak)) : bar(2){}
2111 Foo(int z) __attribute__((weak)) ;
2114 "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
2120 virtual void f^oo() {}
2124 virtual void foo() ;
2126 " void A::foo() {}\n",
2131 virtual virtual void virtual f^oo() {}
2135 virtual virtual void virtual foo() ;
2137 " void A::foo() {}\n",
2142 virtual void foo() = 0;
2145 void fo^o() override {}
2149 virtual void foo() = 0;
2152 void foo() override ;
2154 "void B::foo() {}\n",
2159 virtual void foo() = 0;
2162 void fo^o() final {}
2166 virtual void foo() = 0;
2171 "void B::foo() {}\n",
2176 virtual void foo() = 0;
2179 void fo^o() final override {}
2183 virtual void foo() = 0;
2186 void foo() final override ;
2188 "void B::foo() {}\n",
2193 static void fo^o() {}
2199 " void A::foo() {}\n",
2204 static static void fo^o() {}
2208 static static void foo() ;
2210 " void A::foo() {}\n",
2213 for (
const auto &Case : Cases) {
2214 SCOPED_TRACE(Case.Test);
2215 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2216 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2217 testPath(
"Test.cpp"), Case.ExpectedSource)));
2221 TEST_F(DefineOutlineTest, HandleMacros) {
2222 llvm::StringMap<std::string> EditedFiles;
2223 ExtraFiles[
"Test.cpp"] =
"";
2225 ExtraArgs.push_back(
"-DVIRTUAL=virtual");
2226 ExtraArgs.push_back(
"-DOVER=override");
2229 llvm::StringRef Test;
2230 llvm::StringRef ExpectedHeader;
2231 llvm::StringRef ExpectedSource;
2234 #define BODY { return; }
2235 void f^oo()BODY)cpp",
2237 #define BODY { return; }
2242 #define BODY return;
2243 void f^oo(){BODY})cpp",
2245 #define BODY return;
2247 "void foo(){BODY}"},
2250 #define TARGET void foo()
2251 [[TARGET]]{ return; })cpp",
2253 #define TARGET void foo()
2255 "TARGET{ return; }"},
2259 void [[TARGET]](){ return; })cpp",
2262 void TARGET();)cpp",
2263 "void TARGET(){ return; }"},
2264 {R
"cpp(#define VIRT virtual
2268 R"cpp(#define VIRT virtual
2272 " void A::foo() {}\n"},
2275 VIRTUAL void f^oo() {}
2279 VIRTUAL void foo() ;
2281 " void A::foo() {}\n"},
2284 virtual void foo() = 0;
2291 virtual void foo() = 0;
2296 "void B::foo() {}\n"},
2297 {R
"cpp(#define STUPID_MACRO(X) virtual
2299 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
2301 R"cpp(#define STUPID_MACRO(X) virtual
2303 STUPID_MACRO(sizeof sizeof int) void foo() ;
2305 " void A::foo() {}\n"},
2306 {R
"cpp(#define STAT static
2310 R"cpp(#define STAT static
2314 " void A::foo() {}\n"},
2315 {R
"cpp(#define STUPID_MACRO(X) static
2317 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
2319 R"cpp(#define STUPID_MACRO(X) static
2321 STUPID_MACRO(sizeof sizeof int) void foo() ;
2323 " void A::foo() {}\n"},
2325 for (
const auto &Case : Cases) {
2326 SCOPED_TRACE(Case.Test);
2327 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2328 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2329 testPath(
"Test.cpp"), Case.ExpectedSource)));
2333 TEST_F(DefineOutlineTest, QualifyReturnValue) {
2335 ExtraFiles[
"Test.cpp"] =
"";
2338 llvm::StringRef Test;
2339 llvm::StringRef ExpectedHeader;
2340 llvm::StringRef ExpectedSource;
2343 namespace a { class Foo{}; }
2345 Foo fo^o() { return {}; })cpp",
2347 namespace a { class Foo{}; }
2350 "a::Foo foo() { return {}; }"},
2355 Bar fo^o() { return {}; }
2365 "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
2368 Foo fo^o() { return {}; })cpp",
2372 "Foo foo() { return {}; }"},
2374 llvm::StringMap<std::string> EditedFiles;
2375 for (
auto &Case : Cases) {
2376 apply(Case.Test, &EditedFiles);
2377 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2378 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2379 testPath(
"Test.cpp"), Case.ExpectedSource)));
2383 TEST_F(DefineOutlineTest, QualifyFunctionName) {
2386 llvm::StringRef TestHeader;
2387 llvm::StringRef TestSource;
2388 llvm::StringRef ExpectedHeader;
2389 llvm::StringRef ExpectedSource;
2409 "void a::b::Foo::foo() {}\n",
2412 "namespace a { namespace b { void f^oo() {} } }",
2414 "namespace a { namespace b { void foo() ; } }",
2415 "namespace a{void b::foo() {} }",
2418 "namespace a { namespace b { void f^oo() {} } }",
2419 "using namespace a;",
2420 "namespace a { namespace b { void foo() ; } }",
2423 "using namespace a;void a::b::foo() {} ",
2426 llvm::StringMap<std::string> EditedFiles;
2427 for (
auto &Case : Cases) {
2428 ExtraFiles[
"Test.cpp"] = std::string(Case.TestSource);
2429 EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
2430 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2431 testPath(
"Test.cpp"), Case.ExpectedSource)))
2436 TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
2438 ExtraFiles[
"Test.cpp"] =
"";
2439 ExtraArgs.push_back(
"-DFINALOVER=final override");
2441 std::pair<StringRef, StringRef> Cases[] = {
2444 #define VIRT virtual void
2448 "fail: define outline: couldn't remove `virtual` keyword."},
2451 #define OVERFINAL final override
2453 virtual void foo() {}
2456 void fo^o() OVERFINAL {}
2458 "fail: define outline: Can't move out of line as function has a "
2459 "macro `override` specifier.\ndefine outline: Can't move out of line "
2460 "as function has a macro `final` specifier."},
2464 virtual void foo() {}
2467 void fo^o() FINALOVER {}
2469 "fail: define outline: Can't move out of line as function has a "
2470 "macro `override` specifier.\ndefine outline: Can't move out of line "
2471 "as function has a macro `final` specifier."},
2473 for (
const auto &Case : Cases) {
2474 EXPECT_EQ(apply(Case.first), Case.second);
2479 TEST_F(AddUsingTest, Prepare) {
2480 const std::string Header = R
"cpp(
2481 #define NS(name) one::two::name
2484 template<typename TT> class tt {};
2492 cc operator|(const cc& x) const { return x; }
2502 "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }");
2504 "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
2506 "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
2511 "template<typename TT> using foo = one::tt<T^T>;");
2514 "void fun() { one::two::cc() ^| one::two::cc(); }");
2518 ExtraArgs.push_back(
"-xc++-header");
2527 llvm::StringRef TestSource;
2528 llvm::StringRef ExpectedSource;
2535 ^o^n^e^:^:^t^w^o^:^:^f^f();
2540 namespace {using one::two::ff;
2553 ::on^e::t^wo::c^c inst;
2558 namespace {using ::one::two::cc;
2571 on^e::t^wo::e^e inst;
2598 using one::two::ff;using one::two::ee;
2628 using one::oo;using one::two::ff;
2651 namespace {using one::two::ff;
2679 #define NS_BEGIN(name) namespace name {
2689 #define NS_BEGIN(name) namespace name {
2702 #define CALL(name) name()
2705 CALL(one::t^wo::ff);
2709 #define CALL(name) name()
2719 namespace foo { void fun(); }
2728 namespace foo { void fun(); }
2733 llvm::StringMap<std::string> EditedFiles;
2734 for (
const auto &Case : Cases) {
2735 for (
const auto &SubCase : expandCases(Case.TestSource)) {
2736 ExtraFiles[
"test.hpp"] = R
"cpp(
2744 struct st { struct nested {}; };
2749 EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource);