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