1cf481012SJonas Toth #include "../clang-tidy/utils/FixItHintUtils.h" 2cf481012SJonas Toth #include "ClangTidyDiagnosticConsumer.h" 3cf481012SJonas Toth #include "ClangTidyTest.h" 4cf481012SJonas Toth #include "clang/ASTMatchers/ASTMatchFinder.h" 5cf481012SJonas Toth #include "clang/ASTMatchers/ASTMatchers.h" 6cf481012SJonas Toth #include "clang/Tooling/Tooling.h" 7cf481012SJonas Toth #include "gtest/gtest.h" 871f55735SKazu Hirata #include <optional> 9cf481012SJonas Toth 10cf481012SJonas Toth namespace clang { 11cf481012SJonas Toth namespace tidy { 12cf481012SJonas Toth 13cf481012SJonas Toth namespace { 14cf481012SJonas Toth using namespace clang::ast_matchers; 15cf481012SJonas Toth using namespace utils::fixit; 16cf481012SJonas Toth 17cf481012SJonas Toth template <QualifierTarget CT, QualifierPolicy CP> 18cf481012SJonas Toth class ConstTransform : public ClangTidyCheck { 19cf481012SJonas Toth public: 20cf481012SJonas Toth ConstTransform(StringRef CheckName, ClangTidyContext *Context) 21cf481012SJonas Toth : ClangTidyCheck(CheckName, Context) {} 22cf481012SJonas Toth 23cf481012SJonas Toth void registerMatchers(MatchFinder *Finder) override { 24cf481012SJonas Toth Finder->addMatcher(varDecl(hasName("target")).bind("var"), this); 25cf481012SJonas Toth } 26cf481012SJonas Toth 27cf481012SJonas Toth void check(const MatchFinder::MatchResult &Result) override { 28cf481012SJonas Toth const auto *D = Result.Nodes.getNodeAs<VarDecl>("var"); 29cf481012SJonas Toth using utils::fixit::addQualifierToVarDecl; 30*1b0fcf1eSVlad Serebrennikov std::optional<FixItHint> Fix = 31*1b0fcf1eSVlad Serebrennikov addQualifierToVarDecl(*D, *Result.Context, Qualifiers::Const, CT, CP); 32cf481012SJonas Toth auto Diag = diag(D->getBeginLoc(), "doing const transformation"); 33cf481012SJonas Toth if (Fix) 34cf481012SJonas Toth Diag << *Fix; 35cf481012SJonas Toth } 36cf481012SJonas Toth }; 37cf481012SJonas Toth } // namespace 38cf481012SJonas Toth 39cf481012SJonas Toth namespace test { 40cf481012SJonas Toth using PointeeLTransform = 41cf481012SJonas Toth ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Left>; 42cf481012SJonas Toth using PointeeRTransform = 43cf481012SJonas Toth ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Right>; 44cf481012SJonas Toth 45cf481012SJonas Toth using ValueLTransform = 46cf481012SJonas Toth ConstTransform<QualifierTarget::Value, QualifierPolicy::Left>; 47cf481012SJonas Toth using ValueRTransform = 48cf481012SJonas Toth ConstTransform<QualifierTarget::Value, QualifierPolicy::Right>; 49cf481012SJonas Toth 50cf481012SJonas Toth // ---------------------------------------------------------------------------- 51cf481012SJonas Toth // Test Value-like types. Everything with indirection is done later. 52cf481012SJonas Toth // ---------------------------------------------------------------------------- 53cf481012SJonas Toth 54cf481012SJonas Toth TEST(Values, Builtin) { 55cf481012SJonas Toth StringRef Snippet = "int target = 0;"; 56cf481012SJonas Toth 57cf481012SJonas Toth EXPECT_EQ("const int target = 0;", runCheckOnCode<ValueLTransform>(Snippet)); 58cf481012SJonas Toth EXPECT_EQ("const int target = 0;", 59cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 60cf481012SJonas Toth 61cf481012SJonas Toth EXPECT_EQ("int const target = 0;", runCheckOnCode<ValueRTransform>(Snippet)); 62cf481012SJonas Toth EXPECT_EQ("int const target = 0;", 63cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 64cf481012SJonas Toth } 65cf481012SJonas Toth TEST(Values, TypedefBuiltin) { 66cf481012SJonas Toth StringRef T = "typedef int MyInt;"; 67cf481012SJonas Toth StringRef S = "MyInt target = 0;"; 68cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 69cf481012SJonas Toth 70cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = 0;"), 71cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 72cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = 0;"), 73cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 74cf481012SJonas Toth 75cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = 0;"), 76cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 77cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = 0;"), 78cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 79cf481012SJonas Toth } 80cf481012SJonas Toth TEST(Values, TypedefBuiltinPointer) { 81cf481012SJonas Toth StringRef T = "typedef int* MyInt;"; 82cf481012SJonas Toth StringRef S = "MyInt target = nullptr;"; 83cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 84cf481012SJonas Toth 85cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = nullptr;"), 86cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 87cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = nullptr;"), 88cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 89cf481012SJonas Toth 90cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = nullptr;"), 91cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 92cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = nullptr;"), 93cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 94cf481012SJonas Toth } 95cf481012SJonas Toth TEST(Values, UsingBuiltin) { 96cf481012SJonas Toth StringRef T = "using MyInt = int;"; 97cf481012SJonas Toth StringRef S = "MyInt target = 0;"; 98cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 99cf481012SJonas Toth 100cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = 0;"), 101cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 102cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = 0;"), 103cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 104cf481012SJonas Toth 105cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = 0;"), 106cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 107cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = 0;"), 108cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 109cf481012SJonas Toth } 110cf481012SJonas Toth TEST(Values, UsingBuiltinPointer) { 111cf481012SJonas Toth StringRef T = "using MyInt = int*;"; 112cf481012SJonas Toth StringRef S = "MyInt target = nullptr;"; 113cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 114cf481012SJonas Toth 115cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = nullptr;"), 116cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 117cf481012SJonas Toth EXPECT_EQ(Cat("const MyInt target = nullptr;"), 118cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 119cf481012SJonas Toth 120cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = nullptr;"), 121cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 122cf481012SJonas Toth EXPECT_EQ(Cat("MyInt const target = nullptr;"), 123cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 124cf481012SJonas Toth } 125cf481012SJonas Toth TEST(Values, AutoValue) { 126cf481012SJonas Toth StringRef T = "int f() { return 42; }\n"; 127cf481012SJonas Toth StringRef S = "auto target = f();"; 128cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 129cf481012SJonas Toth 130cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 131cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 132cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 133cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 134cf481012SJonas Toth 135cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 136cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 137cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 138cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 139cf481012SJonas Toth } 140cf481012SJonas Toth TEST(Values, AutoPointer) { 141cf481012SJonas Toth StringRef T = "int* f() { return nullptr; }\n"; 142cf481012SJonas Toth StringRef S = "auto target = f();"; 143cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 144cf481012SJonas Toth 145cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 146cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 147cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 148cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 149cf481012SJonas Toth 150cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 151cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 152cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 153cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 154cf481012SJonas Toth } 155cf481012SJonas Toth TEST(Values, AutoReference) { 156cf481012SJonas Toth StringRef T = "static int global = 42; int& f() { return global; }\n"; 157cf481012SJonas Toth StringRef S = "auto target = f();"; 158cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 159cf481012SJonas Toth 160cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 161cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 162cf481012SJonas Toth EXPECT_EQ(Cat("const auto target = f();"), 163cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 164cf481012SJonas Toth 165cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 166cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 167cf481012SJonas Toth EXPECT_EQ(Cat("auto const target = f();"), 168cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 169cf481012SJonas Toth } 170cf481012SJonas Toth TEST(Values, DeclTypeValue) { 171cf481012SJonas Toth StringRef T = "int f() { return 42; }\n"; 172cf481012SJonas Toth StringRef S = "decltype(f()) target = f();"; 173cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 174cf481012SJonas Toth 175cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 176cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 177cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 178cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 179cf481012SJonas Toth 180cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 181cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 182cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 183cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 184cf481012SJonas Toth } 185cf481012SJonas Toth TEST(Values, DeclTypePointer) { 186cf481012SJonas Toth // The pointer itself will be changed to 'const'. There is no 187cf481012SJonas Toth // way to make the pointee 'const' with this syntax. 188cf481012SJonas Toth StringRef T = "int* f() { return nullptr; }\n"; 189cf481012SJonas Toth StringRef S = "decltype(f()) target = f();"; 190cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 191cf481012SJonas Toth 192cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 193cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 194cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 195cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 196cf481012SJonas Toth 197cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 198cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 199cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 200cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 201cf481012SJonas Toth } 202cf481012SJonas Toth TEST(Values, DeclTypeReference) { 203cf481012SJonas Toth // Same as pointer, but the reference itself will be marked 'const'. 204cf481012SJonas Toth // This has no effect and will result in a warning afterwards. The 205cf481012SJonas Toth // transformation itself is still correct. 206cf481012SJonas Toth StringRef T = "static int global = 42; int& f() { return global; }\n"; 207cf481012SJonas Toth StringRef S = "decltype(f()) target = f();"; 208cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 209cf481012SJonas Toth 210cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 211cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 212cf481012SJonas Toth EXPECT_EQ(Cat("const decltype(f()) target = f();"), 213cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 214cf481012SJonas Toth 215cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 216cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 217cf481012SJonas Toth EXPECT_EQ(Cat("decltype(f()) const target = f();"), 218cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 219cf481012SJonas Toth } 220cf481012SJonas Toth TEST(Values, Parens) { 221cf481012SJonas Toth StringRef Snippet = "int ((target)) = 0;"; 222cf481012SJonas Toth 223cf481012SJonas Toth EXPECT_EQ("const int ((target)) = 0;", 224cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 225cf481012SJonas Toth EXPECT_EQ("const int ((target)) = 0;", 226cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 227cf481012SJonas Toth 228cf481012SJonas Toth EXPECT_EQ("int const ((target)) = 0;", 229cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 230cf481012SJonas Toth EXPECT_EQ("int const ((target)) = 0;", 231cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 232cf481012SJonas Toth } 233cf481012SJonas Toth 234cf481012SJonas Toth // ---------------------------------------------------------------------------- 235cf481012SJonas Toth // Test builtin-arrays 236cf481012SJonas Toth // ---------------------------------------------------------------------------- 237cf481012SJonas Toth 238cf481012SJonas Toth TEST(Arrays, Builtin) { 239cf481012SJonas Toth StringRef Snippet = "int target[][1] = {{1}, {2}, {3}};"; 240cf481012SJonas Toth 241cf481012SJonas Toth EXPECT_EQ("const int target[][1] = {{1}, {2}, {3}};", 242cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 243cf481012SJonas Toth EXPECT_EQ("const int target[][1] = {{1}, {2}, {3}};", 244cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 245cf481012SJonas Toth 246cf481012SJonas Toth EXPECT_EQ("int const target[][1] = {{1}, {2}, {3}};", 247cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 248cf481012SJonas Toth EXPECT_EQ("int const target[][1] = {{1}, {2}, {3}};", 249cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 250cf481012SJonas Toth } 251cf481012SJonas Toth TEST(Arrays, BuiltinParens) { 252cf481012SJonas Toth StringRef Snippet = "int ((target))[][1] = {{1}, {2}, {3}};"; 253cf481012SJonas Toth 254cf481012SJonas Toth EXPECT_EQ("const int ((target))[][1] = {{1}, {2}, {3}};", 255cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 256cf481012SJonas Toth EXPECT_EQ("const int ((target))[][1] = {{1}, {2}, {3}};", 257cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 258cf481012SJonas Toth 259cf481012SJonas Toth EXPECT_EQ("int const ((target))[][1] = {{1}, {2}, {3}};", 260cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 261cf481012SJonas Toth EXPECT_EQ("int const ((target))[][1] = {{1}, {2}, {3}};", 262cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 263cf481012SJonas Toth } 264cf481012SJonas Toth TEST(Arrays, Pointers) { 265cf481012SJonas Toth StringRef Snippet = "int x; int* target[] = {&x, &x, &x};"; 266cf481012SJonas Toth 267cf481012SJonas Toth EXPECT_EQ("int x; const int* target[] = {&x, &x, &x};", 268cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 269cf481012SJonas Toth EXPECT_EQ("int x; int const* target[] = {&x, &x, &x};", 270cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 271cf481012SJonas Toth 272cf481012SJonas Toth EXPECT_EQ("int x; int* const target[] = {&x, &x, &x};", 273cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 274cf481012SJonas Toth EXPECT_EQ("int x; int* const target[] = {&x, &x, &x};", 275cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 276cf481012SJonas Toth } 277cf481012SJonas Toth TEST(Arrays, PointerPointers) { 278cf481012SJonas Toth StringRef Snippet = "int* x = nullptr; int** target[] = {&x, &x, &x};"; 279cf481012SJonas Toth 280cf481012SJonas Toth EXPECT_EQ("int* x = nullptr; int* const* target[] = {&x, &x, &x};", 281cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 282cf481012SJonas Toth EXPECT_EQ("int* x = nullptr; int** const target[] = {&x, &x, &x};", 283cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 284cf481012SJonas Toth 285cf481012SJonas Toth EXPECT_EQ("int* x = nullptr; int* const* target[] = {&x, &x, &x};", 286cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 287cf481012SJonas Toth EXPECT_EQ("int* x = nullptr; int** const target[] = {&x, &x, &x};", 288cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 289cf481012SJonas Toth } 290cf481012SJonas Toth TEST(Arrays, PointersParens) { 291cf481012SJonas Toth StringRef Snippet = "int x; int* (target)[] = {&x, &x, &x};"; 292cf481012SJonas Toth 293cf481012SJonas Toth EXPECT_EQ("int x; const int* (target)[] = {&x, &x, &x};", 294cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 295cf481012SJonas Toth EXPECT_EQ("int x; int const* (target)[] = {&x, &x, &x};", 296cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 297cf481012SJonas Toth 298cf481012SJonas Toth EXPECT_EQ("int x; int* const (target)[] = {&x, &x, &x};", 299cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 300cf481012SJonas Toth EXPECT_EQ("int x; int* const (target)[] = {&x, &x, &x};", 301cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 302cf481012SJonas Toth } 303cf481012SJonas Toth 304cf481012SJonas Toth // ---------------------------------------------------------------------------- 305cf481012SJonas Toth // Test reference types. This does not include pointers and arrays. 306cf481012SJonas Toth // ---------------------------------------------------------------------------- 307cf481012SJonas Toth 308cf481012SJonas Toth TEST(Reference, LValueBuiltin) { 309cf481012SJonas Toth StringRef Snippet = "int x = 42; int& target = x;"; 310cf481012SJonas Toth 311cf481012SJonas Toth EXPECT_EQ("int x = 42; const int& target = x;", 312cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 313cf481012SJonas Toth EXPECT_EQ("int x = 42; const int& target = x;", 314cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 315cf481012SJonas Toth 316cf481012SJonas Toth EXPECT_EQ("int x = 42; int const& target = x;", 317cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 318cf481012SJonas Toth EXPECT_EQ("int x = 42; int const& target = x;", 319cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 320cf481012SJonas Toth } 321cf481012SJonas Toth TEST(Reference, RValueBuiltin) { 322cf481012SJonas Toth StringRef Snippet = "int&& target = 42;"; 323cf481012SJonas Toth EXPECT_EQ("const int&& target = 42;", 324cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 325cf481012SJonas Toth EXPECT_EQ("const int&& target = 42;", 326cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 327cf481012SJonas Toth 328cf481012SJonas Toth EXPECT_EQ("int const&& target = 42;", 329cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 330cf481012SJonas Toth EXPECT_EQ("int const&& target = 42;", 331cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 332cf481012SJonas Toth } 333cf481012SJonas Toth TEST(Reference, LValueToPointer) { 334cf481012SJonas Toth StringRef Snippet = "int* p; int *& target = p;"; 335cf481012SJonas Toth EXPECT_EQ("int* p; int * const& target = p;", 336cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 337cf481012SJonas Toth EXPECT_EQ("int* p; int * const& target = p;", 338cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 339cf481012SJonas Toth 340cf481012SJonas Toth EXPECT_EQ("int* p; int * const& target = p;", 341cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 342cf481012SJonas Toth EXPECT_EQ("int* p; int * const& target = p;", 343cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 344cf481012SJonas Toth } 345cf481012SJonas Toth TEST(Reference, LValueParens) { 346cf481012SJonas Toth StringRef Snippet = "int x = 42; int ((& target)) = x;"; 347cf481012SJonas Toth 348cf481012SJonas Toth EXPECT_EQ("int x = 42; const int ((& target)) = x;", 349cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 350cf481012SJonas Toth EXPECT_EQ("int x = 42; const int ((& target)) = x;", 351cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 352cf481012SJonas Toth 353cf481012SJonas Toth EXPECT_EQ("int x = 42; int const((& target)) = x;", 354cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 355cf481012SJonas Toth EXPECT_EQ("int x = 42; int const((& target)) = x;", 356cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 357cf481012SJonas Toth } 358cf481012SJonas Toth TEST(Reference, ToArray) { 359cf481012SJonas Toth StringRef ArraySnippet = "int a[4] = {1, 2, 3, 4};"; 360cf481012SJonas Toth StringRef Snippet = "int (&target)[4] = a;"; 361cf481012SJonas Toth auto Cat = [&ArraySnippet](StringRef S) { return (ArraySnippet + S).str(); }; 362cf481012SJonas Toth 363cf481012SJonas Toth EXPECT_EQ(Cat("const int (&target)[4] = a;"), 364cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(Snippet))); 365cf481012SJonas Toth EXPECT_EQ(Cat("const int (&target)[4] = a;"), 366cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(Snippet))); 367cf481012SJonas Toth 368cf481012SJonas Toth EXPECT_EQ(Cat("int const(&target)[4] = a;"), 369cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(Snippet))); 370cf481012SJonas Toth EXPECT_EQ(Cat("int const(&target)[4] = a;"), 371cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(Snippet))); 372cf481012SJonas Toth } 373cf481012SJonas Toth TEST(Reference, Auto) { 374cf481012SJonas Toth StringRef T = "static int global = 42; int& f() { return global; }\n"; 375cf481012SJonas Toth StringRef S = "auto& target = f();"; 376cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 377cf481012SJonas Toth 378cf481012SJonas Toth EXPECT_EQ(Cat("const auto& target = f();"), 379cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 380cf481012SJonas Toth EXPECT_EQ(Cat("auto const& target = f();"), 381cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 382cf481012SJonas Toth 383cf481012SJonas Toth EXPECT_EQ(Cat("const auto& target = f();"), 384cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 385cf481012SJonas Toth EXPECT_EQ(Cat("auto const& target = f();"), 386cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 387cf481012SJonas Toth } 388cf481012SJonas Toth 389cf481012SJonas Toth // ---------------------------------------------------------------------------- 390cf481012SJonas Toth // Test pointers types. 391cf481012SJonas Toth // ---------------------------------------------------------------------------- 392cf481012SJonas Toth 393cf481012SJonas Toth TEST(Pointers, SingleBuiltin) { 394cf481012SJonas Toth StringRef Snippet = "int* target = nullptr;"; 395cf481012SJonas Toth 396cf481012SJonas Toth EXPECT_EQ("int* const target = nullptr;", 397cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 398cf481012SJonas Toth EXPECT_EQ("int* const target = nullptr;", 399cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 400cf481012SJonas Toth 401cf481012SJonas Toth EXPECT_EQ("const int* target = nullptr;", 402cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 403cf481012SJonas Toth EXPECT_EQ("int const* target = nullptr;", 404cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 405cf481012SJonas Toth } 406cf481012SJonas Toth TEST(Pointers, MultiBuiltin) { 407cf481012SJonas Toth StringRef Snippet = "int** target = nullptr;"; 408cf481012SJonas Toth 409cf481012SJonas Toth EXPECT_EQ("int** const target = nullptr;", 410cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 411cf481012SJonas Toth EXPECT_EQ("int** const target = nullptr;", 412cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 413cf481012SJonas Toth 414cf481012SJonas Toth EXPECT_EQ("int* const* target = nullptr;", 415cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 416cf481012SJonas Toth EXPECT_EQ("int* const* target = nullptr;", 417cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 418cf481012SJonas Toth } 419cf481012SJonas Toth TEST(Pointers, ToArray) { 420cf481012SJonas Toth StringRef ArraySnippet = "int a[4] = {1, 2, 3, 4};"; 421cf481012SJonas Toth StringRef Snippet = "int (*target)[4] = &a;"; 422cf481012SJonas Toth auto Cat = [&ArraySnippet](StringRef S) { return (ArraySnippet + S).str(); }; 423cf481012SJonas Toth 424cf481012SJonas Toth EXPECT_EQ(Cat("int (*const target)[4] = &a;"), 425cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(Snippet))); 426cf481012SJonas Toth EXPECT_EQ(Cat("const int (*target)[4] = &a;"), 427cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(Snippet))); 428cf481012SJonas Toth 429cf481012SJonas Toth EXPECT_EQ(Cat("int (*const target)[4] = &a;"), 430cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(Snippet))); 431cf481012SJonas Toth EXPECT_EQ(Cat("int const(*target)[4] = &a;"), 432cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(Snippet))); 433cf481012SJonas Toth } 434cf481012SJonas Toth TEST(Pointers, Parens) { 435cf481012SJonas Toth StringRef Snippet = "int ((**target)) = nullptr;"; 436cf481012SJonas Toth 437cf481012SJonas Toth EXPECT_EQ("int ((**const target)) = nullptr;", 438cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Snippet)); 439cf481012SJonas Toth EXPECT_EQ("int ((**const target)) = nullptr;", 440cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Snippet)); 441cf481012SJonas Toth 442cf481012SJonas Toth EXPECT_EQ("int ((* const*target)) = nullptr;", 443cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Snippet)); 444cf481012SJonas Toth EXPECT_EQ("int ((* const*target)) = nullptr;", 445cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Snippet)); 446cf481012SJonas Toth } 447cf481012SJonas Toth TEST(Pointers, Auto) { 448cf481012SJonas Toth StringRef T = "int* f() { return nullptr; }\n"; 449cf481012SJonas Toth StringRef S = "auto* target = f();"; 450cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 451cf481012SJonas Toth 452cf481012SJonas Toth EXPECT_EQ(Cat("auto* const target = f();"), 453cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 454cf481012SJonas Toth EXPECT_EQ(Cat("auto* const target = f();"), 455cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 456cf481012SJonas Toth 457cf481012SJonas Toth EXPECT_EQ(Cat("const auto* target = f();"), 458cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 459cf481012SJonas Toth EXPECT_EQ(Cat("auto const* target = f();"), 460cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 461cf481012SJonas Toth } 462cf481012SJonas Toth TEST(Pointers, AutoParens) { 463cf481012SJonas Toth StringRef T = "int* f() { return nullptr; }\n"; 464cf481012SJonas Toth StringRef S = "auto (((* target))) = f();"; 465cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 466cf481012SJonas Toth 467cf481012SJonas Toth EXPECT_EQ(Cat("auto (((* const target))) = f();"), 468cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 469cf481012SJonas Toth EXPECT_EQ(Cat("auto (((* const target))) = f();"), 470cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 471cf481012SJonas Toth 472cf481012SJonas Toth EXPECT_EQ(Cat("const auto (((* target))) = f();"), 473cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 474cf481012SJonas Toth EXPECT_EQ(Cat("auto const(((* target))) = f();"), 475cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 476cf481012SJonas Toth } 477cf481012SJonas Toth TEST(Pointers, FunctionPointer) { 478cf481012SJonas Toth StringRef S = "int (*target)(float, int, double) = nullptr;"; 479cf481012SJonas Toth 480cf481012SJonas Toth EXPECT_EQ("int (*const target)(float, int, double) = nullptr;", 481cf481012SJonas Toth runCheckOnCode<ValueLTransform>(S)); 482cf481012SJonas Toth EXPECT_EQ("int (*const target)(float, int, double) = nullptr;", 483cf481012SJonas Toth runCheckOnCode<ValueRTransform>(S)); 484cf481012SJonas Toth 485cf481012SJonas Toth EXPECT_EQ("int (*const target)(float, int, double) = nullptr;", 486cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(S)); 487cf481012SJonas Toth EXPECT_EQ("int (*const target)(float, int, double) = nullptr;", 488cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 489cf481012SJonas Toth 490cf481012SJonas Toth S = "int (((*target)))(float, int, double) = nullptr;"; 491cf481012SJonas Toth EXPECT_EQ("int (((*const target)))(float, int, double) = nullptr;", 492cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 493cf481012SJonas Toth } 494cf481012SJonas Toth TEST(Pointers, MemberFunctionPointer) { 495cf481012SJonas Toth StringRef T = "struct A { int f() { return 1; } };"; 496cf481012SJonas Toth StringRef S = "int (A::*target)() = &A::f;"; 497cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 498cf481012SJonas Toth 499cf481012SJonas Toth EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"), 500cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 501cf481012SJonas Toth EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"), 502cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 503cf481012SJonas Toth 504cf481012SJonas Toth EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"), 505cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 506cf481012SJonas Toth EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"), 507cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 508cf481012SJonas Toth 509cf481012SJonas Toth S = "int (A::*((target)))() = &A::f;"; 510cf481012SJonas Toth EXPECT_EQ(Cat("int (A::*const ((target)))() = &A::f;"), 511cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 512cf481012SJonas Toth } 513cf481012SJonas Toth TEST(Pointers, MemberDataPointer) { 514cf481012SJonas Toth StringRef T = "struct A { int member = 0; };"; 515cf481012SJonas Toth StringRef S = "int A::*target = &A::member;"; 516cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 517cf481012SJonas Toth 518cf481012SJonas Toth EXPECT_EQ(Cat("int A::*const target = &A::member;"), 519cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 520cf481012SJonas Toth EXPECT_EQ(Cat("int A::*const target = &A::member;"), 521cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 522cf481012SJonas Toth 523cf481012SJonas Toth EXPECT_EQ(Cat("int A::*const target = &A::member;"), 524cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 525cf481012SJonas Toth EXPECT_EQ(Cat("int A::*const target = &A::member;"), 526cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 527cf481012SJonas Toth 528cf481012SJonas Toth S = "int A::*((target)) = &A::member;"; 529cf481012SJonas Toth EXPECT_EQ(Cat("int A::*const ((target)) = &A::member;"), 530cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 531cf481012SJonas Toth } 532cf481012SJonas Toth 533cf481012SJonas Toth // ---------------------------------------------------------------------------- 534cf481012SJonas Toth // Test TagTypes (struct, class, unions, enums) 535cf481012SJonas Toth // ---------------------------------------------------------------------------- 536cf481012SJonas Toth 537cf481012SJonas Toth TEST(TagTypes, Struct) { 538cf481012SJonas Toth StringRef T = "struct Foo { int data; int method(); };\n"; 539cf481012SJonas Toth StringRef S = "struct Foo target{0};"; 540cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 541cf481012SJonas Toth 542cf481012SJonas Toth EXPECT_EQ(Cat("const struct Foo target{0};"), 543cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 544cf481012SJonas Toth EXPECT_EQ(Cat("const struct Foo target{0};"), 545cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 546cf481012SJonas Toth 547cf481012SJonas Toth EXPECT_EQ(Cat("struct Foo const target{0};"), 548cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 549cf481012SJonas Toth EXPECT_EQ(Cat("struct Foo const target{0};"), 550cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 551cf481012SJonas Toth 552cf481012SJonas Toth S = "Foo target{0};"; 553cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target{0};"), 554cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 555cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target{0};"), 556cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 557cf481012SJonas Toth 558cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target{0};"), 559cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 560cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target{0};"), 561cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 562cf481012SJonas Toth 563cf481012SJonas Toth S = "Foo (target){0};"; 564cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target){0};"), 565cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 566cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target){0};"), 567cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 568cf481012SJonas Toth 569cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target){0};"), 570cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 571cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target){0};"), 572cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 573cf481012SJonas Toth 574cf481012SJonas Toth S = "struct S { int i; } target = { 0 };"; 575cf481012SJonas Toth EXPECT_EQ("const struct S { int i; } target = { 0 };", 576cf481012SJonas Toth runCheckOnCode<ValueLTransform>(S)); 577cf481012SJonas Toth EXPECT_EQ("const struct S { int i; } target = { 0 };", 578cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(S)); 579cf481012SJonas Toth 580cf481012SJonas Toth EXPECT_EQ("struct S { int i; } const target = { 0 };", 581cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 582cf481012SJonas Toth EXPECT_EQ("struct S { int i; } const target = { 0 };", 583cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 584cf481012SJonas Toth 585cf481012SJonas Toth S = "struct { int i; } target = { 0 };"; 586cf481012SJonas Toth EXPECT_EQ("const struct { int i; } target = { 0 };", 587cf481012SJonas Toth runCheckOnCode<ValueLTransform>(S)); 588cf481012SJonas Toth EXPECT_EQ("const struct { int i; } target = { 0 };", 589cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(S)); 590cf481012SJonas Toth 591cf481012SJonas Toth EXPECT_EQ("struct { int i; } const target = { 0 };", 592cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 593cf481012SJonas Toth EXPECT_EQ("struct { int i; } const target = { 0 };", 594cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(S)); 595cf481012SJonas Toth } 596cf481012SJonas Toth TEST(TagTypes, Class) { 597cf481012SJonas Toth StringRef T = "class Foo { int data; int method(); };\n"; 598cf481012SJonas Toth StringRef S = "class Foo target;"; 599cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 600cf481012SJonas Toth 601cf481012SJonas Toth EXPECT_EQ(Cat("const class Foo target;"), 602cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 603cf481012SJonas Toth EXPECT_EQ(Cat("const class Foo target;"), 604cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 605cf481012SJonas Toth 606cf481012SJonas Toth EXPECT_EQ(Cat("class Foo const target;"), 607cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 608cf481012SJonas Toth EXPECT_EQ(Cat("class Foo const target;"), 609cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 610cf481012SJonas Toth 611cf481012SJonas Toth S = "Foo target;"; 612cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S))); 613cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), 614cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 615cf481012SJonas Toth 616cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S))); 617cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), 618cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 619cf481012SJonas Toth 620cf481012SJonas Toth S = "Foo (target);"; 621cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 622cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 623cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 624cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 625cf481012SJonas Toth 626cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 627cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 628cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 629cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 630cf481012SJonas Toth } 631cf481012SJonas Toth TEST(TagTypes, Enum) { 632cf481012SJonas Toth StringRef T = "enum Foo { N_ONE, N_TWO, N_THREE };\n"; 633cf481012SJonas Toth StringRef S = "enum Foo target;"; 634cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 635cf481012SJonas Toth 636cf481012SJonas Toth EXPECT_EQ(Cat("const enum Foo target;"), 637cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 638cf481012SJonas Toth EXPECT_EQ(Cat("const enum Foo target;"), 639cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 640cf481012SJonas Toth 641cf481012SJonas Toth EXPECT_EQ(Cat("enum Foo const target;"), 642cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 643cf481012SJonas Toth EXPECT_EQ(Cat("enum Foo const target;"), 644cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 645cf481012SJonas Toth 646cf481012SJonas Toth S = "Foo target;"; 647cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S))); 648cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), 649cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 650cf481012SJonas Toth 651cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S))); 652cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), 653cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 654cf481012SJonas Toth 655cf481012SJonas Toth S = "Foo (target);"; 656cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 657cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 658cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 659cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 660cf481012SJonas Toth 661cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 662cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 663cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 664cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 665cf481012SJonas Toth } 666cf481012SJonas Toth TEST(TagTypes, Union) { 667cf481012SJonas Toth StringRef T = "union Foo { int yay; float nej; };\n"; 668cf481012SJonas Toth StringRef S = "union Foo target;"; 669cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 670cf481012SJonas Toth 671cf481012SJonas Toth EXPECT_EQ(Cat("const union Foo target;"), 672cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 673cf481012SJonas Toth EXPECT_EQ(Cat("const union Foo target;"), 674cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 675cf481012SJonas Toth 676cf481012SJonas Toth EXPECT_EQ(Cat("union Foo const target;"), 677cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 678cf481012SJonas Toth EXPECT_EQ(Cat("union Foo const target;"), 679cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 680cf481012SJonas Toth 681cf481012SJonas Toth S = "Foo target;"; 682cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S))); 683cf481012SJonas Toth EXPECT_EQ(Cat("const Foo target;"), 684cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 685cf481012SJonas Toth 686cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S))); 687cf481012SJonas Toth EXPECT_EQ(Cat("Foo const target;"), 688cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 689cf481012SJonas Toth 690cf481012SJonas Toth S = "Foo (target);"; 691cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 692cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 693cf481012SJonas Toth EXPECT_EQ(Cat("const Foo (target);"), 694cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 695cf481012SJonas Toth 696cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 697cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 698cf481012SJonas Toth EXPECT_EQ(Cat("Foo const (target);"), 699cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 700cf481012SJonas Toth } 701cf481012SJonas Toth 702cf481012SJonas Toth // ---------------------------------------------------------------------------- 703cf481012SJonas Toth // Test Macro expansions. 704cf481012SJonas Toth // ---------------------------------------------------------------------------- 705cf481012SJonas Toth 706cf481012SJonas Toth TEST(Macro, AllInMacro) { 707cf481012SJonas Toth StringRef T = "#define DEFINE_VARIABLE int target = 42\n"; 708cf481012SJonas Toth StringRef S = "DEFINE_VARIABLE;"; 709cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 710cf481012SJonas Toth 711cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueLTransform>(Cat(S))); 712cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueRTransform>(Cat(S))); 713cf481012SJonas Toth 714cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeLTransform>(Cat(S))); 715cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeRTransform>(Cat(S))); 716cf481012SJonas Toth } 717cf481012SJonas Toth TEST(Macro, MacroParameter) { 718cf481012SJonas Toth StringRef T = "#define DEFINE_VARIABLE(X) int X = 42\n"; 719cf481012SJonas Toth StringRef S = "DEFINE_VARIABLE(target);"; 720cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 721cf481012SJonas Toth 722cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"), 723cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 724cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"), 725cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 726cf481012SJonas Toth 727cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"), 728cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 729cf481012SJonas Toth EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"), 730cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 731cf481012SJonas Toth } 732cf481012SJonas Toth TEST(Macro, MacroTypeValue) { 733cf481012SJonas Toth StringRef T = "#define BAD_TYPEDEF int\n"; 734cf481012SJonas Toth StringRef S = "BAD_TYPEDEF target = 42;"; 735cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 736cf481012SJonas Toth 737cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF target = 42;"), 738cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 739cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF target = 42;"), 740cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 741cf481012SJonas Toth 742cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF const target = 42;"), 743cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 744cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF const target = 42;"), 745cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 746cf481012SJonas Toth } 747cf481012SJonas Toth TEST(Macro, MacroTypePointer) { 748cf481012SJonas Toth StringRef T = "#define BAD_TYPEDEF int *\n"; 749cf481012SJonas Toth StringRef S = "BAD_TYPEDEF target = nullptr;"; 750cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 751cf481012SJonas Toth 752cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF const target = nullptr;"), 753cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 754cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF const target = nullptr;"), 755cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 756cf481012SJonas Toth 757cf481012SJonas Toth // FIXME: Failing even all parts seem to bail-out in for isMacroID() 758cf481012SJonas Toth // The macro itself is changed here and below which is not intended. 759cf481012SJonas Toth EXPECT_NE(Cat("BAD_TYPEDEF target = nullptr;"), 760cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 761cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF target = nullptr;"), 762cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 763cf481012SJonas Toth } 764cf481012SJonas Toth TEST(Macro, MacroTypeReference) { 765cf481012SJonas Toth StringRef T = "static int g = 42;\n#define BAD_TYPEDEF int&\n"; 766cf481012SJonas Toth StringRef S = "BAD_TYPEDEF target = g;"; 767cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 768cf481012SJonas Toth 769cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF target = g;"), 770cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 771cf481012SJonas Toth // FIXME: Failing even all parts seem to bail-out in for isMacroID() 772cf481012SJonas Toth EXPECT_NE(Cat("BAD_TYPEDEF target = g;"), 773cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 774cf481012SJonas Toth 775cf481012SJonas Toth EXPECT_EQ(Cat("BAD_TYPEDEF target = g;"), 776cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 777cf481012SJonas Toth // FIXME: Failing even all parts seem to bail-out in for isMacroID() 778cf481012SJonas Toth EXPECT_NE(Cat("BAD_TYPEDEF target = g;"), 779cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 780cf481012SJonas Toth } 781cf481012SJonas Toth // This failed in LLVM. 782cf481012SJonas Toth TEST(Macro, Variable) { 783cf481012SJonas Toth StringRef M = "#define DEBUG(X) do { if (1) { X; } } while (0)\n"; 784cf481012SJonas Toth StringRef F = "void foo() "; 785cf481012SJonas Toth StringRef V = "{ DEBUG(int target = 42;); }"; 786cf481012SJonas Toth 787cf481012SJonas Toth auto Cat = [&](StringRef S) { return (M + F + V).str(); }; 788cf481012SJonas Toth 789cf481012SJonas Toth EXPECT_EQ(Cat("{ DEBUG(const int target = 42;); }"), 790cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(V))); 791cf481012SJonas Toth EXPECT_EQ(Cat("{ DEBUG(int const target = 42;); }"), 792cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(V))); 793cf481012SJonas Toth } 794cf481012SJonas Toth TEST(Macro, RangeLoop) { 795cf481012SJonas Toth StringRef M = "#define DEBUG(X) do { if (1) { X; }} while (false)\n"; 796cf481012SJonas Toth StringRef F = "void foo() { char array[] = {'a', 'b', 'c'}; "; 797cf481012SJonas Toth StringRef V = "DEBUG( for(auto& target: array) 10 + target; );"; 798cf481012SJonas Toth StringRef E = "}"; 799cf481012SJonas Toth 800cf481012SJonas Toth auto Cat = [&](StringRef S) { return (M + F + V + E).str(); }; 801cf481012SJonas Toth 802cf481012SJonas Toth EXPECT_EQ(Cat("DEBUG( for(const auto& target: array); );"), 803cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(V))); 804cf481012SJonas Toth EXPECT_EQ(Cat("DEBUG( for(auto const& target: array); );"), 805cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(V))); 806cf481012SJonas Toth } 807cf481012SJonas Toth 808cf481012SJonas Toth // ---------------------------------------------------------------------------- 809cf481012SJonas Toth // Test template code. 810cf481012SJonas Toth // ---------------------------------------------------------------------------- 811cf481012SJonas Toth 812cf481012SJonas Toth TEST(Template, TemplateVariable) { 813cf481012SJonas Toth StringRef T = "template <typename T> T target = 3.1415;"; 814cf481012SJonas Toth 815cf481012SJonas Toth EXPECT_EQ("template <typename T> const T target = 3.1415;", 816cf481012SJonas Toth runCheckOnCode<ValueLTransform>(T)); 817cf481012SJonas Toth EXPECT_EQ("template <typename T> T const target = 3.1415;", 818cf481012SJonas Toth runCheckOnCode<ValueRTransform>(T)); 819cf481012SJonas Toth 820cf481012SJonas Toth EXPECT_EQ("template <typename T> const T target = 3.1415;", 821cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(T)); 822cf481012SJonas Toth EXPECT_EQ("template <typename T> T const target = 3.1415;", 823cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(T)); 824cf481012SJonas Toth } 825cf481012SJonas Toth TEST(Template, FunctionValue) { 826cf481012SJonas Toth StringRef T = "template <typename T> void f(T v) \n"; 827cf481012SJonas Toth StringRef S = "{ T target = v; }"; 828cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 829cf481012SJonas Toth 830cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 831cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 832cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 833cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 834cf481012SJonas Toth 835cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 836cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 837cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 838cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 839cf481012SJonas Toth } 840cf481012SJonas Toth TEST(Template, FunctionPointer) { 841cf481012SJonas Toth StringRef T = "template <typename T> void f(T* v) \n"; 842cf481012SJonas Toth StringRef S = "{ T* target = v; }"; 843cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 844cf481012SJonas Toth 845cf481012SJonas Toth EXPECT_EQ(Cat("{ T* const target = v; }"), 846cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 847cf481012SJonas Toth EXPECT_EQ(Cat("{ T* const target = v; }"), 848cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 849cf481012SJonas Toth 850cf481012SJonas Toth EXPECT_EQ(Cat("{ const T* target = v; }"), 851cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 852cf481012SJonas Toth EXPECT_EQ(Cat("{ T const* target = v; }"), 853cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 854cf481012SJonas Toth } 855cf481012SJonas Toth TEST(Template, FunctionReference) { 856cf481012SJonas Toth StringRef T = "template <typename T> void f(T& v) \n"; 857cf481012SJonas Toth StringRef S = "{ T& target = v; }"; 858cf481012SJonas Toth auto Cat = [&T](StringRef S) { return (T + S).str(); }; 859cf481012SJonas Toth 860cf481012SJonas Toth EXPECT_EQ(Cat("{ const T& target = v; }"), 861cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 862cf481012SJonas Toth EXPECT_EQ(Cat("{ T const& target = v; }"), 863cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 864cf481012SJonas Toth 865cf481012SJonas Toth EXPECT_EQ(Cat("{ const T& target = v; }"), 866cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 867cf481012SJonas Toth EXPECT_EQ(Cat("{ T const& target = v; }"), 868cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 869cf481012SJonas Toth } 870cf481012SJonas Toth TEST(Template, MultiInstantiationsFunction) { 871cf481012SJonas Toth StringRef T = "template <typename T> void f(T v) \n"; 872cf481012SJonas Toth StringRef S = "{ T target = v; }"; 873cf481012SJonas Toth StringRef InstantStart = "void calls() {\n"; 874cf481012SJonas Toth StringRef InstValue = "f<int>(42);\n"; 875cf481012SJonas Toth StringRef InstConstValue = "f<const int>(42);\n"; 876cf481012SJonas Toth StringRef InstPointer = "f<int*>(nullptr);\n"; 877cf481012SJonas Toth StringRef InstPointerConst = "f<int* const>(nullptr);\n"; 878cf481012SJonas Toth StringRef InstConstPointer = "f<const int*>(nullptr);\n"; 879cf481012SJonas Toth StringRef InstConstPointerConst = "f<const int* const>(nullptr);\n"; 880cf481012SJonas Toth StringRef InstRef = "int i = 42;\nf<int&>(i);\n"; 881cf481012SJonas Toth StringRef InstConstRef = "f<const int&>(i);\n"; 882cf481012SJonas Toth StringRef InstantEnd = "}"; 883cf481012SJonas Toth auto Cat = [&](StringRef Target) { 884cf481012SJonas Toth return (T + Target + InstantStart + InstValue + InstConstValue + 885cf481012SJonas Toth InstPointer + InstPointerConst + InstConstPointer + 886cf481012SJonas Toth InstConstPointerConst + InstRef + InstConstRef + InstantEnd) 887cf481012SJonas Toth .str(); 888cf481012SJonas Toth }; 889cf481012SJonas Toth 890cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 891cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 892cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 893cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 894cf481012SJonas Toth 895cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 896cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 897cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 898cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 899cf481012SJonas Toth } 900cf481012SJonas Toth 901cf481012SJonas Toth TEST(Template, StructValue) { 902cf481012SJonas Toth StringRef T = "template <typename T> struct S { void f(T& v) \n"; 903cf481012SJonas Toth StringRef S = "{ T target = v; }"; 904cf481012SJonas Toth StringRef End = "\n};"; 905cf481012SJonas Toth auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); }; 906cf481012SJonas Toth 907cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 908cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 909cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 910cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 911cf481012SJonas Toth 912cf481012SJonas Toth EXPECT_EQ(Cat("{ const T target = v; }"), 913cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 914cf481012SJonas Toth EXPECT_EQ(Cat("{ T const target = v; }"), 915cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 916cf481012SJonas Toth } 917cf481012SJonas Toth TEST(Template, StructPointer) { 918cf481012SJonas Toth StringRef T = "template <typename T> struct S { void f(T* v) \n"; 919cf481012SJonas Toth StringRef S = "{ T* target = v; }"; 920cf481012SJonas Toth StringRef End = "\n};"; 921cf481012SJonas Toth auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); }; 922cf481012SJonas Toth 923cf481012SJonas Toth EXPECT_EQ(Cat("{ T* const target = v; }"), 924cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 925cf481012SJonas Toth EXPECT_EQ(Cat("{ T* const target = v; }"), 926cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 927cf481012SJonas Toth 928cf481012SJonas Toth EXPECT_EQ(Cat("{ const T* target = v; }"), 929cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 930cf481012SJonas Toth EXPECT_EQ(Cat("{ T const* target = v; }"), 931cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 932cf481012SJonas Toth } 933cf481012SJonas Toth TEST(Template, StructReference) { 934cf481012SJonas Toth StringRef T = "template <typename T> struct S { void f(T& v) \n"; 935cf481012SJonas Toth StringRef S = "{ T& target = v; }"; 936cf481012SJonas Toth StringRef End = "\n};"; 937cf481012SJonas Toth auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); }; 938cf481012SJonas Toth 939cf481012SJonas Toth EXPECT_EQ(Cat("{ const T& target = v; }"), 940cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 941cf481012SJonas Toth EXPECT_EQ(Cat("{ T const& target = v; }"), 942cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 943cf481012SJonas Toth 944cf481012SJonas Toth EXPECT_EQ(Cat("{ const T& target = v; }"), 945cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 946cf481012SJonas Toth EXPECT_EQ(Cat("{ T const& target = v; }"), 947cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 948cf481012SJonas Toth } 949cf481012SJonas Toth TEST(Template, DependentReturnFunction) { 950cf481012SJonas Toth StringRef TS = "template <typename T> struct TS { using value_type = T; };"; 951cf481012SJonas Toth StringRef T = "template <typename T> void foo() "; 952cf481012SJonas Toth StringRef S = "{ typename T::value_type target; }"; 953cf481012SJonas Toth auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); }; 954cf481012SJonas Toth 955cf481012SJonas Toth EXPECT_EQ(Cat("{ const typename T::value_type target; }"), 956cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 957cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type const target; }"), 958cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 959cf481012SJonas Toth 960cf481012SJonas Toth EXPECT_EQ(Cat("{ const typename T::value_type target; }"), 961cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 962cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type const target; }"), 963cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 964cf481012SJonas Toth } 965cf481012SJonas Toth TEST(Template, DependentReturnPointerFunction) { 966cf481012SJonas Toth StringRef TS = "template <typename T> struct TS { using value_type = T; };"; 967cf481012SJonas Toth StringRef T = "template <typename T> void foo() "; 968cf481012SJonas Toth StringRef S = "{ typename T::value_type *target; }"; 969cf481012SJonas Toth auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); }; 970cf481012SJonas Toth 971cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type *const target; }"), 972cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 973cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type *const target; }"), 974cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 975cf481012SJonas Toth 976cf481012SJonas Toth EXPECT_EQ(Cat("{ const typename T::value_type *target; }"), 977cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 978cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type const*target; }"), 979cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 980cf481012SJonas Toth } 981cf481012SJonas Toth TEST(Template, DependentReturnReferenceFunction) { 982cf481012SJonas Toth StringRef TS = "template <typename T> struct TS { using value_type = T; };"; 983cf481012SJonas Toth StringRef T = "template <typename T> void foo(T& f) "; 984cf481012SJonas Toth StringRef S = "{ typename T::value_type &target = f; }"; 985cf481012SJonas Toth auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); }; 986cf481012SJonas Toth 987cf481012SJonas Toth EXPECT_EQ(Cat("{ const typename T::value_type &target = f; }"), 988cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 989cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type const&target = f; }"), 990cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 991cf481012SJonas Toth 992cf481012SJonas Toth EXPECT_EQ(Cat("{ const typename T::value_type &target = f; }"), 993cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 994cf481012SJonas Toth EXPECT_EQ(Cat("{ typename T::value_type const&target = f; }"), 995cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 996cf481012SJonas Toth } 997cf481012SJonas Toth TEST(Template, VectorLikeType) { 998cf481012SJonas Toth StringRef TS = "template <typename T> struct TS { TS(const T&) {} }; "; 999cf481012SJonas Toth StringRef T = "void foo() "; 1000cf481012SJonas Toth StringRef S = "{ TS<int> target(42); }"; 1001cf481012SJonas Toth auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); }; 1002cf481012SJonas Toth 1003cf481012SJonas Toth EXPECT_EQ(Cat("{ const TS<int> target(42); }"), 1004cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 1005cf481012SJonas Toth EXPECT_EQ(Cat("{ TS<int> const target(42); }"), 1006cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 1007cf481012SJonas Toth 1008cf481012SJonas Toth EXPECT_EQ(Cat("{ const TS<int> target(42); }"), 1009cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 1010cf481012SJonas Toth EXPECT_EQ(Cat("{ TS<int> const target(42); }"), 1011cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 1012cf481012SJonas Toth } 1013cf481012SJonas Toth TEST(Template, SpecializedTemplate) { 1014cf481012SJonas Toth StringRef TS = "template <typename T = int> struct TS { TS(const T&) {} }; "; 1015cf481012SJonas Toth StringRef TS2 = "template <> struct TS<double> { TS(const double&) {} }; "; 1016cf481012SJonas Toth StringRef T = "void foo() "; 1017cf481012SJonas Toth StringRef S = "{ TS<double> target(42.42); }"; 1018cf481012SJonas Toth auto Cat = [&](StringRef S) { return (TS + TS2 + T + S).str(); }; 1019cf481012SJonas Toth 1020cf481012SJonas Toth EXPECT_EQ(Cat("{ const TS<double> target(42.42); }"), 1021cf481012SJonas Toth runCheckOnCode<ValueLTransform>(Cat(S))); 1022cf481012SJonas Toth EXPECT_EQ(Cat("{ TS<double> const target(42.42); }"), 1023cf481012SJonas Toth runCheckOnCode<ValueRTransform>(Cat(S))); 1024cf481012SJonas Toth 1025cf481012SJonas Toth EXPECT_EQ(Cat("{ const TS<double> target(42.42); }"), 1026cf481012SJonas Toth runCheckOnCode<PointeeLTransform>(Cat(S))); 1027cf481012SJonas Toth EXPECT_EQ(Cat("{ TS<double> const target(42.42); }"), 1028cf481012SJonas Toth runCheckOnCode<PointeeRTransform>(Cat(S))); 1029cf481012SJonas Toth } 1030cf481012SJonas Toth 1031cf481012SJonas Toth // ----------------------------------------------------------------------------- 1032cf481012SJonas Toth // ObjC Pointers 1033cf481012SJonas Toth // ----------------------------------------------------------------------------- 1034cf481012SJonas Toth 1035cf481012SJonas Toth TEST(ObjC, SimplePointers) { 1036cf481012SJonas Toth StringRef S = "int * target = 0;"; 1037cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<PointeeLTransform>(S, nullptr, "input.m"), 1038cf481012SJonas Toth "const int * target = 0;"); 1039cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<PointeeRTransform>(S, nullptr, "input.m"), 1040cf481012SJonas Toth "int const* target = 0;"); 1041cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<ValueLTransform>(S, nullptr, "input.m"), 1042cf481012SJonas Toth "int * const target = 0;"); 1043cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<ValueRTransform>(S, nullptr, "input.m"), 1044cf481012SJonas Toth "int * const target = 0;"); 1045cf481012SJonas Toth } 1046cf481012SJonas Toth TEST(ObjC, ClassPointer) { 1047cf481012SJonas Toth StringRef TB = "@class Object;\nint main() {\n"; 1048cf481012SJonas Toth StringRef S = "Object *target;"; 1049cf481012SJonas Toth StringRef TE = "\n}"; 1050cf481012SJonas Toth auto Cat = [&](StringRef S) { return (TB + S + TE).str(); }; 1051cf481012SJonas Toth 1052cf481012SJonas Toth // FIXME: Not done properly for some reason. 1053cf481012SJonas Toth EXPECT_NE(runCheckOnCode<PointeeLTransform>(Cat(S), nullptr, "input.m"), 1054cf481012SJonas Toth Cat("const Object *target;")); 1055cf481012SJonas Toth EXPECT_NE(runCheckOnCode<PointeeRTransform>(Cat(S), nullptr, "input.m"), 1056cf481012SJonas Toth Cat("Object const*target;")); 1057cf481012SJonas Toth EXPECT_NE(runCheckOnCode<ValueLTransform>(Cat(S), nullptr, "input.m"), 1058cf481012SJonas Toth Cat("Object *const target;")); 1059cf481012SJonas Toth EXPECT_NE(runCheckOnCode<ValueRTransform>(Cat(S), nullptr, "input.m"), 1060cf481012SJonas Toth Cat("Object *const target;")); 1061cf481012SJonas Toth } 1062cf481012SJonas Toth TEST(ObjC, InterfacePointer) { 1063cf481012SJonas Toth StringRef TB = "@interface I\n"; 1064cf481012SJonas Toth StringRef S = "- (void) foo: (int *) target;"; 1065cf481012SJonas Toth StringRef TE = "\n@end"; 1066cf481012SJonas Toth auto Cat = [&](StringRef S) { return (TB + S + TE).str(); }; 1067cf481012SJonas Toth 1068cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<PointeeLTransform>(Cat(S), nullptr, "input.m"), 1069cf481012SJonas Toth Cat("- (void) foo: (const int *) target;")); 1070cf481012SJonas Toth EXPECT_EQ(runCheckOnCode<PointeeRTransform>(Cat(S), nullptr, "input.m"), 1071cf481012SJonas Toth Cat("- (void) foo: (int const*) target;")); 1072cf481012SJonas Toth // FIXME: These transformations are incorrect. ObjC seems to need 1073cf481012SJonas Toth // RParenSkipping which is not implemented. 1074cf481012SJonas Toth EXPECT_NE(runCheckOnCode<ValueLTransform>(Cat(S), nullptr, "input.m"), 1075cf481012SJonas Toth Cat("- (void) foo: (int * const) target;")); 1076cf481012SJonas Toth EXPECT_NE(runCheckOnCode<ValueRTransform>(Cat(S), nullptr, "input.m"), 1077cf481012SJonas Toth Cat("- (void) foo: (int * const) target;")); 1078cf481012SJonas Toth } 1079cf481012SJonas Toth 1080cf481012SJonas Toth } // namespace test 1081cf481012SJonas Toth } // namespace tidy 1082cf481012SJonas Toth } // namespace clang 1083