11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
14using ::testing::ElementsAre;
22TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
29 [[void [[Bar::[[b^a^z]]]]() [[{
34 [[void [[f^o^o]]() [[{
43 [[vo^id ]]foo[[()]] {[[
48 // Definition with no body.
49 class Bar { Bar() = def^ault; };
53 // Redeclaration after the definition.
62 // Target is already a definition.
81TEST_F(DefineInlineTest, NoForwardDecl) {
82 Header = "void bar();";
87 // FIXME: Generate a decl in the header.
93TEST_F(DefineInlineTest, ReferencedDecls) {
104 Header =
"void foo(int test);";
113 Header =
"void bar();" + Header;
142 ExtraFiles[
"a.h"] =
"void bar();";
143 Header =
"void foo(int test);";
152TEST_F(DefineInlineTest, TemplateSpec) {
154 template <typename T> void foo();
155 template<> void foo<char>();
157 template<> void f^oo<int>() {
160 template <typename T> void foo();
162 template<> void f^oo<int>() {
165 template <typename T> struct Foo { void foo(); };
167 template <typename T> void Foo<T>::f^oo() {
170 template <typename T> void foo();
172 template <> void foo<int>();
174 template<> void f^oo<int>() {
179 template <typename T> void f^oo() {}
180 template void foo<int>();
184TEST_F(DefineInlineTest, CheckForCanonDecl) {
190 // This bar normally refers to the definition just above, but it is not
191 // visible from the forward declaration of foo.
205TEST_F(DefineInlineTest, UsingShadowDecls) {
207 namespace ns1 { void foo(int); }
208 namespace ns2 { void foo(int*); }
209 template <typename T>
215 template <typename T>
221TEST_F(DefineInlineTest, TransformNestedNamespaces) {
250 auto *Expected = R
"cpp(
278 EXPECT_EQ(apply(Test), Expected);
281TEST_F(DefineInlineTest, TransformUsings) {
283 namespace a { namespace b { namespace c { void aux(); } } }
293 auto *Expected = R
"cpp(
294 namespace a { namespace b { namespace c { void aux(); } } }
298 using namespace a::b;
299 using namespace a::b::c;
301 namespace d = a::b::c;
304 EXPECT_EQ(apply(Test), Expected);
307TEST_F(DefineInlineTest, TransformDecls) {
317 enum En { Zero, One };
320 enum class EnClass { Zero, One };
321 EnClass y = EnClass::Zero;
323 auto *Expected = R
"cpp(
331 enum En { Zero, One };
334 enum class EnClass { Zero, One };
335 EnClass y = EnClass::Zero;
338 EXPECT_EQ(apply(Test), Expected);
341TEST_F(DefineInlineTest, TransformTemplDecls) {
344 template <typename T> class Bar {
348 template <typename T> T bar;
349 template <typename T> void aux() {}
359 auto *Expected = R
"cpp(
361 template <typename T> class Bar {
365 template <typename T> T bar;
366 template <typename T> void aux() {}
370 a::bar<a::Bar<int>>.bar();
371 a::aux<a::Bar<int>>();
376 EXPECT_EQ(apply(Test), Expected);
379TEST_F(DefineInlineTest, TransformMembers) {
388 auto *Expected = R
"cpp(
396 EXPECT_EQ(apply(Test), Expected);
398 ExtraFiles["a.h"] = R
"cpp(
403 llvm::StringMap<std::string> EditedFiles;
412 EXPECT_EQ(apply(Test, &EditedFiles), Expected);
420 EXPECT_THAT(EditedFiles,
421 ElementsAre(FileWithContents(testPath("a.h"), Expected)));
424TEST_F(DefineInlineTest, TransformDependentTypes) {
427 template <typename T> class Bar {};
430 template <typename T>
434 template <typename T>
439 auto *Expected = R
"cpp(
441 template <typename T> class Bar {};
444 template <typename T>
453 EXPECT_EQ(apply(Test), Expected);
456TEST_F(DefineInlineTest, TransformFunctionTempls) {
458 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
460 template <typename T>
464 void foo<int>(int p);
467 void foo<char>(char p);
470 void fo^o<int>(int p) {
474 template <typename T>
478 void foo<int>(int p){
483 void foo<char>(char p);
488 template <typename T>
492 void foo<int>(int p);
495 void foo<char>(char p);
498 void fo^o<char>(char p) {
502 template <typename T>
506 void foo<int>(int p);
509 void foo<char>(char p){
515 template <typename T>
519 void foo<int>(int p);
521 template <typename T>
526 template <typename T>
532 void foo<int>(int p);
536 for (
const auto &Case : Cases)
537 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
540TEST_F(DefineInlineTest, TransformTypeLocs) {
543 template <typename T> class Bar {
545 template <typename Q> class Baz {};
556 a::Bar<Bar<int>>::Baz<Bar<int>> q;
558 auto *Expected = R
"cpp(
560 template <typename T> class Bar {
562 template <typename Q> class Baz {};
570 a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
575 EXPECT_EQ(apply(Test), Expected);
578TEST_F(DefineInlineTest, TransformDeclRefs) {
581 template <typename T> class Bar {
598 Bar<Bar<int>>::bar();
605 auto *Expected = R
"cpp(
607 template <typename T> class Bar {
622 a::Bar<a::Bar<int>>::bar();
624 B.x = a::Bar<int>::y;
631 EXPECT_EQ(apply(Test), Expected);
634TEST_F(DefineInlineTest, StaticMembers) {
636 namespace ns { class X { static void foo(); void bar(); }; }
640 auto *Expected = R
"cpp(
641 namespace ns { class X { static void foo(); void bar(){
645 EXPECT_EQ(apply(Test), Expected);
648TEST_F(DefineInlineTest, TransformParamNames) {
649 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
651 void foo(int, bool b, int T\
653 void ^foo(int f, bool x, int z) {})cpp",
655 void foo(int f, bool x, int z){}
661 void ^foo(int X) {})cpp",
662 "fail: Cant rename parameter inside macro body."},
666 #define BODY(x) 5 * (x) + 2
668 void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
670 void ^foo(int Z, int b, int c, int d) {})cpp",
674 #define BODY(x) 5 * (x) + 2
676 void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
679 for (
const auto &Case : Cases)
680 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
683TEST_F(DefineInlineTest, TransformTemplParamNames) {
687 template <class, class X,
688 template<typename> class, template<typename> class Y,
690 void foo(X, Y<X>, int W = 5 * Z + 2);
694 template <class T, class U,
695 template<typename> class V, template<typename> class W,
697 void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
698 auto *Expected = R
"cpp(
701 template <class T, class U,
702 template<typename> class V, template<typename> class W,
704 void foo(U, W<U>, int Q = 5 * Y + 2){}
709 EXPECT_EQ(apply(Test), Expected);
712TEST_F(DefineInlineTest, TransformInlineNamespaces) {
714 namespace a { inline namespace b { namespace { struct Foo{}; } } }
718 void ^foo() {Foo foo;})cpp";
719 auto *Expected = R
"cpp(
720 namespace a { inline namespace b { namespace { struct Foo{}; } } }
721 void foo(){a::Foo foo;}
725 EXPECT_EQ(apply(Test), Expected);
728TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
729 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
731 void foo() /*Comment -_-*/ /*Com 2*/ ;
732 void fo^o() { return ; })cpp",
734 void foo() /*Comment -_-*/ /*Com 2*/ { return ; }
739 void fo^o() { return ; })cpp",
741 void foo(){ return ; }
747 void fo^o() { return ; })cpp",
748 "fail: Couldn't find semicolon for target declaration."},
750 for (
const auto &Case : Cases)
751 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
754TEST_F(DefineInlineTest, HandleMacros) {
756 #define BODY { return; }
758 void f^oo()BODY)cpp");
761 #define BODY void foo(){ return; }
765 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
769 namespace a { class Foo{}; }
772 void f^oo(){BODY();})cpp",
775 namespace a { class Foo{}; }
784 void f^oo(){BODY})cpp",
791 #define TARGET void foo()
793 void f^oo(){ return; })cpp",
795 #define TARGET void foo()
802 void f^oo(){ return; })cpp",
805 void TARGET(){ return; }
808 for (
const auto &Case : Cases)
809 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
812TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
814 llvm::StringRef Test;
815 llvm::StringRef Expected;
818 namespace a { namespace b { void aux(); } }
821 namespace qq { void test(); }
824 namespace ns3 { void baz(); }
829 using namespace a::b;
830 using namespace ns1::qq;
831 void ns1::ns2::ns3::b^az() {
835 ns1::ns2::ns3::baz();
840 namespace a { namespace b { void aux(); } }
843 namespace qq { void test(); }
846 namespace ns3 { void baz(){
850 ns1::ns2::ns3::baz();
858 using namespace a::b;
859 using namespace ns1::qq;
863 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
864 namespace ns2 { void baz(); }
867 using namespace ns1::qq;
868 void ns1::ns2::b^az() { Foo f; B b; })cpp",
871 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
872 namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
875 using namespace ns1::qq;
880 template<class T> struct Foo { template <class U> struct Bar {}; };
881 template<class T, class U>
882 using B = typename Foo<T>::template Bar<U>;
884 namespace ns2 { void baz(); }
887 using namespace ns1::qq;
888 void ns1::ns2::b^az() { B<int, bool> b; })cpp",
892 template<class T> struct Foo { template <class U> struct Bar {}; };
893 template<class T, class U>
894 using B = typename Foo<T>::template Bar<U>;
896 namespace ns2 { void baz(){ qq::B<int, bool> b; } }
899 using namespace ns1::qq;
902 for (
const auto &Case : Cases)
903 EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
906TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
907 llvm::StringRef Test = R
"cpp(
910 namespace b { struct Foo{}; void aux(); }
911 namespace c { void cux(); }
925 // FIXME: The last reference to cux() in body of foo should not be
926 // qualified, since there is a using directive inside the function body.
929 llvm::StringRef Expected = R"cpp(
932 namespace b { struct Foo{}; void aux(); }
933 namespace c { void cux(); }
943 // FIXME: The last reference to cux() in body of foo should not be
944 // qualified, since there is a using directive inside the function body.
951 EXPECT_EQ(apply(Test), Expected) << Test;
954TEST_F(DefineInlineTest, AddInline) {
955 llvm::StringMap<std::string> EditedFiles;
956 ExtraFiles["a.h"] =
"void foo();";
957 apply(R
"cpp(#include "a.h"
960 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
961 testPath("a.h"),
"inline void foo(){}")));
964 ExtraFiles[
"a.h"] =
"const int foo();";
965 apply(R
"cpp(#include "a.h"
966 const int fo^o() { return 0; })cpp",
968 EXPECT_THAT(EditedFiles,
969 testing::ElementsAre(FileWithContents(
970 testPath("a.h"),
"inline const int foo(){ return 0; }")));
973 ExtraFiles[
"a.h"] =
"inline void foo();";
974 apply(R
"cpp(#include "a.h"
975 inline void fo^o() {})cpp",
977 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
978 testPath("a.h"),
"inline void foo(){}")));
981 ExtraFiles[
"a.h"] =
"constexpr void foo();";
982 apply(R
"cpp(#include "a.h"
983 constexpr void fo^o() {})cpp",
985 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
986 testPath("a.h"),
"constexpr void foo(){}")));
989 ExtraFiles[
"a.h"] =
"struct Foo { void foo(); };";
990 apply(R
"cpp(#include "a.h"
991 void Foo::fo^o() {})cpp",
993 EXPECT_THAT(EditedFiles,
994 testing::ElementsAre(FileWithContents(
995 testPath("a.h"),
"struct Foo { void foo(){} };")));
998 ExtraFiles[
"a.h"] =
"template <typename T> void foo();";
999 apply(R
"cpp(#include "a.h"
1000 template <typename T>
1001 void fo^o() {})cpp",
1003 EXPECT_THAT(EditedFiles,
1004 testing::ElementsAre(FileWithContents(
1005 testPath("a.h"),
"template <typename T> void foo(){}")));
1008 ExtraFiles[
"a.h"] = R
"cpp(
1009 template <typename T> void foo();
1010 template <> void foo<int>();)cpp";
1011 apply(R"cpp(#include "a.h"
1013 void fo^o<int>() {})cpp",
1015 EXPECT_THAT(EditedFiles,
1016 testing::ElementsAre(FileWithContents(testPath("a.h"),
1018 template <typename T> void foo();
1019 template <> inline void foo<int>(){})cpp")));
#define TWEAK_TEST(TweakID)
#define EXPECT_AVAILABLE(MarkedCode)
#define EXPECT_UNAVAILABLE(MarkedCode)
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//