brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.2 KiB · d8c7604 Raw
1083 lines · cpp
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 10namespace clang {11namespace tidy {12 13namespace {14using namespace clang::ast_matchers;15using namespace utils::fixit;16 17template <QualifierTarget CT, QualifierPolicy CP>18class ConstTransform : public ClangTidyCheck {19public: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} // namespace38 39namespace test {40using PointeeLTransform =41    ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Left>;42using PointeeRTransform =43    ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Right>;44 45using ValueLTransform =46    ConstTransform<QualifierTarget::Value, QualifierPolicy::Left>;47using ValueRTransform =48    ConstTransform<QualifierTarget::Value, QualifierPolicy::Right>;49 50// ----------------------------------------------------------------------------51// Test Value-like types. Everything with indirection is done later.52// ----------------------------------------------------------------------------53 54TEST(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}65TEST(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}80TEST(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}95TEST(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}110TEST(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}125TEST(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}140TEST(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}155TEST(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}170TEST(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}185TEST(Values, DeclTypePointer) {186  // The pointer itself will be changed to 'const'. There is no187  // 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}202TEST(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. The205  // 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}220TEST(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-arrays236// ----------------------------------------------------------------------------237 238TEST(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}251TEST(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}264TEST(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}277TEST(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}290TEST(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 308TEST(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}321TEST(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}333TEST(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}345TEST(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}358TEST(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}373TEST(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 393TEST(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}406TEST(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}419TEST(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}434TEST(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}447TEST(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}462TEST(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}477TEST(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}494TEST(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}513TEST(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 537TEST(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}596TEST(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}631TEST(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}666TEST(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 706TEST(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}717TEST(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}732TEST(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}747TEST(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}764TEST(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.782TEST(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}794TEST(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 812TEST(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}825TEST(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}840TEST(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}855TEST(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}870TEST(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 901TEST(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}917TEST(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}933TEST(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}949TEST(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}965TEST(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}981TEST(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}997TEST(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}1013TEST(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 Pointers1033// -----------------------------------------------------------------------------1034 1035TEST(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}1046TEST(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}1062TEST(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 need1073  // 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 test1081} // namespace tidy1082} // namespace clang1083