brintos

brintos / llvm-project-archived public Read only

0
0
Text · 61.8 KiB · 86c69a5 Raw
1451 lines · cpp
1//===- unittest/Format/QualifierFixerTest.cpp - Formatting unit tests -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../lib/Format/QualifierAlignmentFixer.h"10#include "FormatTestBase.h"11#include "TestLexer.h"12 13#define DEBUG_TYPE "format-qualifier-fixer-test"14 15namespace clang {16namespace format {17namespace test {18namespace {19 20#define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \21  EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!";          \22  EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \23  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"24 25#define FAIL_PARSE(TEXT, FIELD, VALUE)                                         \26  EXPECT_NE(0, parseConfiguration(TEXT, &Style).value());                      \27  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"28 29class QualifierFixerTest : public FormatTestBase {30protected:31  TokenList annotate(StringRef Code,32                     const FormatStyle &Style = getLLVMStyle()) {33    return TestLexer(Allocator, Buffers, Style).annotate(Code);34  }35  llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;36  std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;37};38 39TEST_F(QualifierFixerTest, RotateTokens) {40  // TODO add test41  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("const"),42            tok::kw_const);43  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("volatile"),44            tok::kw_volatile);45  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("inline"),46            tok::kw_inline);47  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("static"),48            tok::kw_static);49  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("restrict"),50            tok::kw_restrict);51  EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("friend"),52            tok::kw_friend);53}54 55TEST_F(QualifierFixerTest, FailQualifierInvalidConfiguration) {56  FormatStyle Style = {};57  Style.Language = FormatStyle::LK_Cpp;58  FAIL_PARSE("QualifierAlignment: Custom\n"59             "QualifierOrder: [const, volatile, apples, type]",60             QualifierOrder,61             std::vector<std::string>({"const", "volatile", "apples", "type"}));62}63 64TEST_F(QualifierFixerTest, FailQualifierDuplicateConfiguration) {65  FormatStyle Style = {};66  Style.Language = FormatStyle::LK_Cpp;67  FAIL_PARSE("QualifierAlignment: Custom\n"68             "QualifierOrder: [const, volatile, const, type]",69             QualifierOrder,70             std::vector<std::string>({"const", "volatile", "const", "type"}));71}72 73TEST_F(QualifierFixerTest, FailQualifierMissingType) {74  FormatStyle Style = {};75  Style.Language = FormatStyle::LK_Cpp;76  FAIL_PARSE("QualifierAlignment: Custom\n"77             "QualifierOrder: [const, volatile ]",78             QualifierOrder,79             std::vector<std::string>({80                 "const",81                 "volatile",82             }));83}84 85TEST_F(QualifierFixerTest, FailQualifierEmptyOrder) {86  FormatStyle Style = {};87  Style.Language = FormatStyle::LK_Cpp;88  FAIL_PARSE("QualifierAlignment: Custom\nQualifierOrder: []", QualifierOrder,89             std::vector<std::string>({}));90}91 92TEST_F(QualifierFixerTest, FailQualifierMissingOrder) {93  FormatStyle Style = {};94  Style.Language = FormatStyle::LK_Cpp;95  FAIL_PARSE("QualifierAlignment: Custom", QualifierOrder,96             std::vector<std::string>());97}98 99TEST_F(QualifierFixerTest, QualifierLeft) {100  FormatStyle Style = {};101  Style.Language = FormatStyle::LK_Cpp;102  CHECK_PARSE("QualifierAlignment: Left", QualifierOrder,103              std::vector<std::string>({"const", "volatile", "type"}));104}105 106TEST_F(QualifierFixerTest, QualifierRight) {107  FormatStyle Style = {};108  Style.Language = FormatStyle::LK_Cpp;109  CHECK_PARSE("QualifierAlignment: Right", QualifierOrder,110              std::vector<std::string>({"type", "const", "volatile"}));111}112 113TEST_F(QualifierFixerTest, QualifiersCustomOrder) {114  FormatStyle Style = getLLVMStyle();115  Style.QualifierAlignment = FormatStyle::QAS_Left;116  Style.QualifierOrder = {"friend", "inline",   "constexpr", "static",117                          "const",  "volatile", "type"};118 119  verifyFormat("const volatile int a;", Style);120  verifyFormat("const volatile int a;", "volatile const int a;", Style);121  verifyFormat("const volatile int a;", "int const volatile a;", Style);122  verifyFormat("const volatile int a;", "int volatile const a;", Style);123  verifyFormat("const volatile int a;", "const int volatile a;", Style);124 125  verifyFormat("static const volatile int a;", "const static int volatile a;",126               Style);127  verifyFormat("inline static const volatile int a;",128               "const static inline int volatile a;", Style);129 130  verifyFormat("constexpr static int a;", "static constexpr int a;", Style);131  verifyFormat("constexpr static int A;", "static constexpr int A;", Style);132  verifyFormat("constexpr static int Bar;", "static constexpr int Bar;", Style);133  verifyFormat("constexpr static LPINT Bar;", "static constexpr LPINT Bar;",134               Style);135  verifyFormat("const const int a;", "const int const a;", Style);136 137  verifyFormat(138      "friend constexpr auto operator<=>(const foo &, const foo &) = default;",139      "constexpr friend auto operator<=>(const foo &, const foo &) = default;",140      Style);141  verifyFormat(142      "friend constexpr bool operator==(const foo &, const foo &) = default;",143      "constexpr bool friend operator==(const foo &, const foo &) = default;",144      Style);145}146 147TEST_F(QualifierFixerTest, LeftRightQualifier) {148  FormatStyle Style = getLLVMStyle();149 150  // keep the const style unaltered151  verifyFormat("const int a;", Style);152  verifyFormat("const int *a;", Style);153  verifyFormat("const int &a;", Style);154  verifyFormat("const int &&a;", Style);155  verifyFormat("int const b;", Style);156  verifyFormat("int const *b;", Style);157  verifyFormat("int const &b;", Style);158  verifyFormat("int const &&b;", Style);159  verifyFormat("int const *const b;", Style);160  verifyFormat("int *const c;", Style);161 162  verifyFormat("const Foo a;", Style);163  verifyFormat("const Foo *a;", Style);164  verifyFormat("const Foo &a;", Style);165  verifyFormat("const Foo &&a;", Style);166  verifyFormat("Foo const b;", Style);167  verifyFormat("Foo const *b;", Style);168  verifyFormat("Foo const &b;", Style);169  verifyFormat("Foo const &&b;", Style);170  verifyFormat("Foo const *const b;", Style);171 172  verifyFormat("LLVM_NODISCARD const int &Foo();", Style);173  verifyFormat("LLVM_NODISCARD int const &Foo();", Style);174 175  verifyFormat("volatile const int *restrict;", Style);176  verifyFormat("const volatile int *restrict;", Style);177  verifyFormat("const int volatile *restrict;", Style);178}179 180TEST_F(QualifierFixerTest, RightQualifier) {181  FormatStyle Style = getLLVMStyle();182  Style.QualifierAlignment = FormatStyle::QAS_Right;183  Style.QualifierOrder = {"type", "const", "volatile"};184 185  verifyFormat("int const a;", Style);186  verifyFormat("int const *a;", Style);187  verifyFormat("int const &a;", Style);188  verifyFormat("int const &&a;", Style);189  verifyFormat("int const b;", Style);190  verifyFormat("int const *b;", Style);191  verifyFormat("int const &b;", Style);192  verifyFormat("int const &&b;", Style);193  verifyFormat("int const *const b;", Style);194  verifyFormat("int *const c;", Style);195 196  verifyFormat("Foo const a;", Style);197  verifyFormat("Foo const *a;", Style);198  verifyFormat("Foo const &a;", Style);199  verifyFormat("Foo const &&a;", Style);200  verifyFormat("Foo const b;", Style);201  verifyFormat("Foo const *b;", Style);202  verifyFormat("Foo const &b;", Style);203  verifyFormat("Foo const &&b;", Style);204  verifyFormat("Foo const *const b;", Style);205  verifyFormat("Foo *const b;", Style);206  verifyFormat("Foo const *const b;", Style);207  verifyFormat("auto const v = get_value();", Style);208  verifyFormat("long long const &a;", Style);209  verifyFormat("unsigned char const *a;", Style);210  verifyFormat("int main(int const argc, char const *const *const argv)",211               Style);212 213  verifyFormat("LLVM_NODISCARD int const &Foo();", Style);214  verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY",215               Style);216  verifyFormat("void foo() const override;", Style);217  verifyFormat("void foo() const override LLVM_READONLY;", Style);218  verifyFormat("MOCK_METHOD(ReturnType, myMethod, (int), (const override));",219               Style);220  verifyFormat("void foo() const final;", Style);221  verifyFormat("void foo() const final LLVM_READONLY;", Style);222  verifyFormat("void foo() const LLVM_READONLY;", Style);223  verifyFormat("void foo() const volatile override;", Style);224  verifyFormat("void foo() const volatile override LLVM_READONLY;", Style);225  verifyFormat("void foo() const volatile final;", Style);226  verifyFormat("void foo() const volatile final LLVM_READONLY;", Style);227  verifyFormat("void foo() const volatile LLVM_READONLY;", Style);228 229  verifyFormat(230      "template <typename Func> explicit Action(Action<Func> const &action);",231      Style);232  verifyFormat(233      "template <typename Func> explicit Action(Action<Func> const &action);",234      "template <typename Func> explicit Action(const Action<Func>& action);",235      Style);236  verifyFormat(237      "template <typename Func> explicit Action(Action<Func> const &action);",238      "template <typename Func>\nexplicit Action(const Action<Func>& action);",239      Style);240 241  verifyFormat("int const a;", "const int a;", Style);242  verifyFormat("int const *a;", "const int *a;", Style);243  verifyFormat("int const &a;", "const int &a;", Style);244  verifyFormat("foo(int const &a)", "foo(const int &a)", Style);245  verifyFormat("unsigned char *a;", Style);246  verifyFormat("unsigned char const *a;", "const unsigned char *a;", Style);247  verifyFormat("vector<int, int const, int &, int const &> args1",248               "vector<int, const int, int &, const int &> args1", Style);249  verifyFormat("unsigned int const &get_nu() const",250               "const unsigned int &get_nu() const", Style);251  verifyFormat("Foo<int> const &a", "const Foo<int> &a", Style);252  verifyFormat("Foo<int>::iterator const &a", "const Foo<int>::iterator &a",253               Style);254  verifyFormat("::Foo<int>::iterator const &a", "const ::Foo<int>::iterator &a",255               Style);256 257  verifyFormat("Foo(int a, "258               "unsigned b, // c-style args\n"259               "    Bar const &c);",260               "Foo(int a, "261               "unsigned b, // c-style args\n"262               "    const Bar &c);",263               Style);264 265  verifyFormat("int const volatile;", "volatile const int;", Style);266  verifyFormat("int const volatile;", "const volatile int;", Style);267  verifyFormat("int const volatile;", "const int volatile;", Style);268 269  verifyFormat("int const volatile *restrict;", "volatile const int *restrict;",270               Style);271  verifyFormat("int const volatile *restrict;", "const volatile int *restrict;",272               Style);273  verifyFormat("int const volatile *restrict;", "const int volatile *restrict;",274               Style);275 276  verifyFormat("long long int const volatile;", "const long long int volatile;",277               Style);278  verifyFormat("long long int const volatile;", "long const long int volatile;",279               Style);280  verifyFormat("long long int const volatile;", "long long volatile int const;",281               Style);282  verifyFormat("long long int const volatile;", "long volatile long const int;",283               Style);284  verifyFormat("long long int const volatile;", "const long long volatile int;",285               Style);286 287  verifyFormat("static int const bat;", "static const int bat;", Style);288  verifyFormat("static int const bat;", Style);289 290  // static is not configured, unchanged on the left of the right hand291  // qualifiers.292  verifyFormat("int static const volatile;", "volatile const int static;",293               Style);294  verifyFormat("int static const volatile;", "const volatile int static;",295               Style);296  verifyFormat("int static const volatile;", "const int volatile static;",297               Style);298  verifyFormat("Foo static const volatile;", "volatile const Foo static;",299               Style);300  verifyFormat("Foo static const volatile;", "const volatile Foo static;",301               Style);302  verifyFormat("Foo static const volatile;", "const Foo volatile static;",303               Style);304 305  verifyFormat("Foo inline static const;", "const Foo inline static;", Style);306  verifyFormat("Foo inline static const;", "Foo const inline static;", Style);307  verifyFormat("Foo inline static const;", "Foo inline const static;", Style);308  verifyFormat("Foo inline static const;", Style);309 310  verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A::*;",311               "volatile const Foo<volatile T>::Bar<const Type, 5> A::*;",312               Style);313 314  verifyFormat("int const Foo<int>::bat = 0;", "const int Foo<int>::bat = 0;",315               Style);316  verifyFormat("int const Foo<int>::bat = 0;", Style);317  verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);318  verifyFormat("int const Foo<int>::fn() {", Style);319  verifyFormat("Foo<Foo<int>> const *p;", "const Foo<Foo<int>> *p;", Style);320  verifyFormat(321      "Foo<Foo<int>> const *p = const_cast<Foo<Foo<int>> const *>(&ffi);",322      "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",323      Style);324 325  verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);326  verifyFormat("void fns(ns::S const &s);", "void fns(const ns::S &s);", Style);327  verifyFormat("void fns(::ns::S const &s);", "void fns(const ::ns::S &s);",328               Style);329  verifyFormat("void fn(ns::Foo<T> const &i);", "void fn(const ns::Foo<T> &i);",330               Style);331  verifyFormat("void fns(ns::ns2::S const &s);",332               "void fns(const ns::ns2::S &s);", Style);333  verifyFormat("void fn(ns::Foo<Bar<T>> const &i);",334               "void fn(const ns::Foo<Bar<T>> &i);", Style);335  verifyFormat("void fn(ns::ns2::Foo<Bar<T>> const &i);",336               "void fn(const ns::ns2::Foo<Bar<T>> &i);", Style);337  verifyFormat("void fn(ns::ns2::Foo<Bar<T, U>> const &i);",338               "void fn(const ns::ns2::Foo<Bar<T, U>> &i);", Style);339 340  verifyFormat("LocalScope const *Scope = nullptr;",341               "const LocalScope* Scope = nullptr;", Style);342  verifyFormat("struct DOTGraphTraits<Stmt const *>",343               "struct DOTGraphTraits<const Stmt *>", Style);344 345  verifyFormat(346      "bool tools::addXRayRuntime(ToolChain const &TC, ArgList const &Args) {",347      "bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args) {",348      Style);349  verifyFormat("Foo<Foo<int> const> P;", "Foo<const Foo<int>> P;", Style);350  verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",351               "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);352 353  verifyFormat("auto const i = 0;", "const auto i = 0;", Style);354  verifyFormat("auto const &ir = i;", "const auto &ir = i;", Style);355  verifyFormat("auto const *ip = &i;", "const auto *ip = &i;", Style);356 357  verifyFormat("void f(Concept auto const &x);",358               "void f(const Concept auto &x);", Style);359  verifyFormat("void f(std::integral auto const &x);",360               "void f(const std::integral auto &x);", Style);361 362  verifyFormat("auto lambda = [] { int const i = 0; };",363               "auto lambda = [] { const int i = 0; };", Style);364 365  verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",366               "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);367 368  verifyFormat("Bar<Bar<int const> const> P;\n#if 0\n#else\n#endif",369               "Bar<Bar<const int> const> P;\n#if 0\n#else\n#endif", Style);370 371  verifyFormat("Baz<Baz<int const> const> P;\n#if 0\n#else\n#endif",372               "Baz<const Baz<const int>> P;\n#if 0\n#else\n#endif", Style);373 374  // verifyFormat("#if 0\nBoo<Boo<int const> const> P;\n#else\n#endif",375  //             "#if 0\nBoo<const Boo<const int>> P;\n#else\n#endif", Style);376 377  verifyFormat("int const P;\n#if 0\n#else\n#endif",378               "const int P;\n#if 0\n#else\n#endif", Style);379 380  verifyFormat("unsigned long const a;", "const unsigned long a;", Style);381  verifyFormat("unsigned long long const a;", "const unsigned long long a;",382               Style);383 384  // Multiple template parameters.385  verifyFormat("Bar<std::Foo const, 32>", "Bar<const std::Foo, 32>", Style);386  // Variable declaration based on template type.387  verifyFormat("Bar<std::Foo const> bar", "Bar<const std::Foo> bar", Style);388 389  // Using typename for a nested dependent type name.390  verifyFormat("typename Foo::iterator const;", "const typename Foo::iterator;",391               Style);392 393  // Don't move past C-style struct/class.394  verifyFormat("void foo(const struct A a);", Style);395  verifyFormat("void foo(const class A a);", Style);396 397  // Don't move past struct/class combined declaration and variable398  // definition.399  verifyFormat("const struct {\n} var;", Style);400  verifyFormat("struct {\n} const var;", Style);401  verifyFormat("const class {\n} var;", Style);402  verifyFormat("class {\n} const var;", Style);403 404  // Leave left qualifers unchanged for combined declaration and variable405  // definition.406  verifyFormat("volatile const class {\n} var;", Style);407  verifyFormat("const volatile class {\n} var;", Style);408  // Also do no sorting with respect to not-configured tokens.409  verifyFormat("const static volatile class {\n} var;", Style);410  // Sort right qualifiers for combined declaration and variable definition.411  verifyFormat("class {\n} const volatile var;", Style);412  verifyFormat("class {\n} const volatile var;",413               "class {\n} volatile const var;", Style);414  // Static keyword is not configured, should end up on the left of the right415  // side.416  verifyFormat("class {\n} static const volatile var;", Style);417  verifyFormat("class {\n} static const volatile var;",418               "class {\n} volatile static const var;", Style);419 420  // ::template for dependent names421  verifyFormat("::template Foo<T> const volatile var;",422               "const volatile ::template Foo<T> var;", Style);423  verifyFormat("typename ::template Foo<T> const volatile var;",424               "const volatile typename ::template Foo<T> var;", Style);425  verifyFormat("typename Bar::template Foo<T>::T const;",426               "const typename Bar::template Foo<T>::T;", Style);427  verifyFormat("typename Bar::template Foo<T>::T const volatile;",428               "const volatile typename Bar::template Foo<T>::T;", Style);429 430  // typename ::431  verifyFormat("typename ::Bar<int> const;", "const typename ::Bar<int>;",432               Style);433  // typename ::template434  verifyFormat("typename ::template Bar<int> const;",435               "const typename ::template Bar<int>;", Style);436 437  verifyFormat("foo<Bar<Baz> const>();", "foo<const Bar<Baz>>();", Style);438  verifyFormat("foo<Bar<Baz> const>();", "foo<const Bar<Baz> >();", Style);439  verifyFormat("Bar<32, Foo<25> const>;", "Bar<32, const Foo<25>>;", Style);440  verifyFormat("A<B<C<D> const> const>;", "A<const B<const C<D>>>;", Style);441  verifyFormat("A<B<C<D const> const> const>;", "A<const B<const C<const D>>>;",442               Style);443 444  // Don't move past decltype, typeof, or _Atomic.445  verifyFormat("const decltype(foo)", Style);446  verifyFormat("const typeof(foo)", Style);447  verifyFormat("const _Atomic(foo)", Style);448 449  // Comments450  const int ColumnLimit = Style.ColumnLimit;451  Style.ColumnLimit = 200;452  verifyFormat("/*c*/ Foo const *foo;", "const /*c*/ Foo *foo;", Style);453  verifyFormat("Foo const /*c*/ *foo;", "const Foo /*c*/ *foo;", Style);454  verifyFormat("Foo const * /*c*/ foo;", "const Foo * /*c*/ foo;", Style);455 456  verifyFormat("/*comment*/ std::vector<int> const v;",457               "const /*comment*/ std::vector<int> v;", Style);458  verifyFormat("std /*comment*/ ::vector<int> const v;",459               "const std /*comment*/ ::vector<int> v;", Style);460  verifyFormat("std::/*comment*/ vector<int> const v;",461               "const std::/*comment*/ vector<int> v;", Style);462  verifyFormat("std::vector /*comment*/<int> const v;",463               "const std::vector /*comment*/ <int> v;", Style);464  verifyFormat("std::vector</*comment*/ int> const v;",465               "const std::vector</*comment*/ int> v;", Style);466  verifyFormat("std::vector<int /*comment*/> const v;",467               "const std::vector<int /*comment*/> v;", Style);468  verifyFormat("std::vector<int> const /*comment*/ v;",469               "const std::vector<int> /*comment*/ v;", Style);470 471  verifyFormat("std::vector</*comment*/ int const> v;",472               "std::vector</*comment*/ const int> v;", Style);473  verifyFormat("std::vector</*comment*/ int const> v;",474               "std::vector<const /*comment*/ int> v;", Style);475  verifyFormat("std::vector<int const /*comment*/> v;",476               "std::vector<const int /*comment*/> v;", Style);477  verifyFormat("std::vector</*comment*/ Foo const> v;",478               "std::vector</*comment*/ const Foo> v;", Style);479  verifyFormat("std::vector</*comment*/ Foo const> v;",480               "std::vector<const /*comment*/ Foo> v;", Style);481  verifyFormat("std::vector<Foo const /*comment*/> v;",482               "std::vector<const Foo /*comment*/> v;", Style);483 484  verifyFormat("typename C<T>::template B<T> const;",485               "const typename C<T>::template B<T>;", Style);486  verifyFormat("/*c*/ typename C<T>::template B<T> const;",487               "const /*c*/ typename C<T>::template B<T>;", Style);488  verifyFormat("typename /*c*/ C<T>::template B<T> const;",489               "const typename /*c*/ C<T>::template B<T>;", Style);490  verifyFormat("typename C /*c*/<T>::template B<T> const;",491               "const typename C /*c*/<T>::template B<T>;", Style);492  verifyFormat("typename C<T> /*c*/ ::template B<T> const;",493               "const typename C<T> /*c*/ ::template B<T>;", Style);494  verifyFormat("typename C<T>::/*c*/ template B<T> const;",495               "const typename C<T>::/*c*/ template B<T>;", Style);496  verifyFormat("typename C<T>::template /*c*/ B<T> const;",497               "const typename C<T>::template /*c*/B<T>;", Style);498  verifyFormat("typename C<T>::template B<T> const /*c*/;",499               "const typename C<T>::template B<T>/*c*/;", Style);500 501  verifyFormat("/*c*/ /*c*/ typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template "502               "/*c*/ B /*c*/<T> const /*c*/ v;",503               "/*c*/ const /*c*/ typename /*c*/ C /*c*/<T> /*c*/ "504               "::/*c*/template /*c*/ B /*c*/<T> /*c*/ v;",505               Style);506 507  verifyFormat("/*c*/ unsigned /*c*/ long const /*c*/ a;",508               "const /*c*/ unsigned /*c*/ long /*c*/ a;", Style);509  verifyFormat("unsigned /*c*/ long /*c*/ long const a;",510               "const unsigned /*c*/ long /*c*/ long a;", Style);511 512  // Not changed513  verifyFormat("foo() /*c*/ const", Style);514  verifyFormat("const /*c*/ struct a;", Style);515  verifyFormat("const /*c*/ class a;", Style);516  verifyFormat("const /*c*/ decltype(v) a;", Style);517  verifyFormat("const /*c*/ typeof(v) a;", Style);518  verifyFormat("const /*c*/ _Atomic(v) a;", Style);519  verifyFormat("const decltype /*c*/ (v) a;", Style);520  verifyFormat("const /*c*/ class {\n} volatile /*c*/ foo = {};", Style);521 522  Style.ColumnLimit = ColumnLimit;523 524  // Don't adjust macros525  verifyFormat("const INTPTR a;", Style);526 527  // Pointers to members528  verifyFormat("int S::*a;", Style);529  verifyFormat("int const S::*a;", "const int S::*a;", Style);530  verifyFormat("int const S::*const a;", "const int S::* const a;", Style);531  verifyFormat("int A::*const A::*p1;", Style);532  verifyFormat("float (C::*p)(int);", Style);533  verifyFormat("float (C::*const p)(int);", Style);534  verifyFormat("float (C::*p)(int) const;", Style);535  verifyFormat("float const (C::*p)(int);", "const float (C::*p)(int);", Style);536 537  Style.BreakBeforeBraces = FormatStyle::BS_Custom;538  Style.BraceWrapping.AfterFunction = true;539  verifyFormat("auto foo() -> T const { return bar; }",540               "auto foo() -> const T { return bar; }", Style);541}542 543TEST_F(QualifierFixerTest, LeftQualifier) {544  FormatStyle Style = getLLVMStyle();545  Style.QualifierAlignment = FormatStyle::QAS_Left;546  Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};547 548  verifyFormat("const int a;", Style);549  verifyFormat("const int *a;", Style);550  verifyFormat("const int &a;", Style);551  verifyFormat("const int &&a;", Style);552  verifyFormat("const int b;", Style);553  verifyFormat("const int *b;", Style);554  verifyFormat("const int &b;", Style);555  verifyFormat("const int &&b;", Style);556  verifyFormat("const int *const b;", Style);557  verifyFormat("int *const c;", Style);558 559  verifyFormat("const Foo a;", Style);560  verifyFormat("const Foo *a;", Style);561  verifyFormat("const Foo &a;", Style);562  verifyFormat("const Foo &&a;", Style);563  verifyFormat("const Foo b;", Style);564  verifyFormat("const Foo *b;", Style);565  verifyFormat("const Foo &b;", Style);566  verifyFormat("const Foo &&b;", Style);567  verifyFormat("const Foo *const b;", Style);568  verifyFormat("Foo *const b;", Style);569  verifyFormat("const Foo *const b;", Style);570 571  verifyFormat("LLVM_NODISCARD const int &Foo();", Style);572 573  verifyFormat("const char a[];", Style);574  verifyFormat("const auto v = get_value();", Style);575  verifyFormat("const long long &a;", Style);576  verifyFormat("const unsigned char *a;", Style);577  verifyFormat("const unsigned char *a;", "unsigned char const *a;", Style);578  verifyFormat("const Foo<int> &a", "Foo<int> const &a", Style);579  verifyFormat("const Foo<int>::iterator &a", "Foo<int>::iterator const &a",580               Style);581  verifyFormat("const ::Foo<int>::iterator &a", "::Foo<int>::iterator const &a",582               Style);583 584  verifyFormat("const int a;", "int const a;", Style);585  verifyFormat("const int *a;", "int const *a;", Style);586  verifyFormat("const int &a;", "int const &a;", Style);587  verifyFormat("foo(const int &a)", "foo(int const &a)", Style);588  verifyFormat("unsigned char *a;", Style);589  verifyFormat("const unsigned int &get_nu() const",590               "unsigned int const &get_nu() const", Style);591 592  verifyFormat("const volatile int;", "volatile const int;", Style);593  verifyFormat("const volatile int;", Style);594  verifyFormat("const volatile int;", "const int volatile;", Style);595 596  verifyFormat("const volatile int *restrict;", "volatile const int *restrict;",597               Style);598  verifyFormat("const volatile int *restrict;", Style);599  verifyFormat("const volatile int *restrict;", "const int volatile *restrict;",600               Style);601 602  verifyFormat("const volatile long long int;", "volatile long long int const;",603               Style);604  verifyFormat("const volatile long long int;", "volatile long long const int;",605               Style);606  verifyFormat("const volatile long long int;", "long long volatile int const;",607               Style);608  verifyFormat("const volatile long long int;", "long volatile long int const;",609               Style);610  verifyFormat("const volatile long long int;", "const long long volatile int;",611               Style);612 613  verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY;",614               Style);615 616  verifyFormat("void foo() const override;", Style);617  verifyFormat("void foo() const override LLVM_READONLY;", Style);618  verifyFormat("void foo() const final;", Style);619  verifyFormat("void foo() const final LLVM_READONLY;", Style);620  verifyFormat("void foo() const LLVM_READONLY;", Style);621 622  verifyFormat(623      "template <typename Func> explicit Action(const Action<Func> &action);",624      Style);625  verifyFormat(626      "template <typename Func> explicit Action(const Action<Func> &action);",627      "template <typename Func> explicit Action(Action<Func> const &action);",628      Style);629 630  verifyFormat("static const int bat;", Style);631  verifyFormat("static const int bat;", "static int const bat;", Style);632 633  verifyFormat("static const int Foo<int>::bat = 0;", Style);634  verifyFormat("static const int Foo<int>::bat = 0;",635               "static int const Foo<int>::bat = 0;", Style);636 637  verifyFormat("void fn(const Foo<T> &i);");638 639  verifyFormat("const int Foo<int>::bat = 0;", Style);640  verifyFormat("const int Foo<int>::bat = 0;", "int const Foo<int>::bat = 0;",641               Style);642  verifyFormat("void fn(const Foo<T> &i);", "void fn( Foo<T> const &i);",643               Style);644  verifyFormat("const int Foo<int>::fn() {", "int const Foo<int>::fn() {",645               Style);646  verifyFormat("const Foo<Foo<int>> *p;", "Foo<Foo<int>> const *p;", Style);647  verifyFormat(648      "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",649      "const Foo<Foo<int>> *p = const_cast<Foo<Foo<int>> const *>(&ffi);",650      Style);651 652  verifyFormat("void fn(const Foo<T> &i);", "void fn(Foo<T> const &i);", Style);653  verifyFormat("void fns(const ns::S &s);", "void fns(ns::S const &s);", Style);654  verifyFormat("void fns(const ::ns::S &s);", "void fns(::ns::S const &s);",655               Style);656  verifyFormat("void fn(const ns::Foo<T> &i);", "void fn(ns::Foo<T> const &i);",657               Style);658  verifyFormat("void fns(const ns::ns2::S &s);",659               "void fns(ns::ns2::S const &s);", Style);660  verifyFormat("void fn(const ns::Foo<Bar<T>> &i);",661               "void fn(ns::Foo<Bar<T>> const &i);", Style);662  verifyFormat("void fn(const ns::ns2::Foo<Bar<T>> &i);",663               "void fn(ns::ns2::Foo<Bar<T>> const &i);", Style);664  verifyFormat("void fn(const ns::ns2::Foo<Bar<T, U>> &i);",665               "void fn(ns::ns2::Foo<Bar<T, U>> const &i);", Style);666 667  verifyFormat("const auto i = 0;", "auto const i = 0;", Style);668  verifyFormat("const auto &ir = i;", "auto const &ir = i;", Style);669  verifyFormat("const auto *ip = &i;", "auto const *ip = &i;", Style);670 671  verifyFormat("void f(const Concept auto &x);",672               "void f(Concept auto const &x);", Style);673  verifyFormat("void f(const std::integral auto &x);",674               "void f(std::integral auto const &x);", Style);675 676  verifyFormat("auto lambda = [] { const int i = 0; };",677               "auto lambda = [] { int const i = 0; };", Style);678 679  verifyFormat("Foo<const Foo<int>> P;\n#if 0\n#else\n#endif",680               "Foo<Foo<int> const> P;\n#if 0\n#else\n#endif", Style);681 682  verifyFormat("Foo<Foo<const int>> P;\n#if 0\n#else\n#endif",683               "Foo<Foo<int const>> P;\n#if 0\n#else\n#endif", Style);684 685  verifyFormat("const int P;\n#if 0\n#else\n#endif",686               "int const P;\n#if 0\n#else\n#endif", Style);687 688  verifyFormat("const unsigned long a;", "unsigned long const a;", Style);689  verifyFormat("const unsigned long long a;", "unsigned long long const a;",690               Style);691 692  verifyFormat("const long long unsigned a;", "long const long unsigned a;",693               Style);694 695  verifyFormat("const std::Foo", Style);696  verifyFormat("const std::Foo<>", Style);697  verifyFormat("const std::Foo < int", "const std::Foo<int", Style);698  verifyFormat("const std::Foo<int>", Style);699 700  // Multiple template parameters.701  verifyFormat("Bar<const std::Foo, 32>;", "Bar<std::Foo const, 32>;", Style);702 703  // Variable declaration based on template type.704  verifyFormat("Bar<const std::Foo> bar;", "Bar<std::Foo const> bar;", Style);705 706  // Using typename for a dependent name.707  verifyFormat("const typename Foo::iterator;", "typename Foo::iterator const;",708               Style);709 710  // Don't move past C-style struct/class.711  verifyFormat("void foo(struct A const a);", Style);712  verifyFormat("void foo(class A const a);", Style);713 714  // Don't move past struct/class combined declaration and variable715  // definition.716  verifyFormat("const struct {\n} var;", Style);717  verifyFormat("struct {\n} const var;", Style);718  verifyFormat("const class {\n} var;", Style);719  verifyFormat("class {\n} const var;", Style);720 721  // Sort left qualifiers for struct/class combined declaration and variable722  // definition.723  verifyFormat("const volatile class {\n} var;", Style);724  verifyFormat("const volatile class {\n} var;",725               "volatile const class {\n} var;", Style);726  // Leave right qualifers unchanged for struct/class combined declaration and727  // variable definition.728  verifyFormat("class {\n} const volatile var;", Style);729  verifyFormat("class {\n} volatile const var;", Style);730 731  verifyFormat("foo<const Bar<Baz<T>>>();", "foo<Bar<Baz<T>> const>();", Style);732  verifyFormat("foo<const Bar<Baz<T>>>();", "foo<Bar<Baz<T> > const>();",733               Style);734  verifyFormat("Bar<32, const Foo<25>>;", "Bar<32, Foo<25> const>;", Style);735  verifyFormat("A<const B<const C<D>>>;", "A<B<C<D> const> const>;", Style);736  verifyFormat("A<const B<const C<const D>>>;", "A<B<C<D const> const> const>;",737               Style);738 739  // Don't move past decltype, typeof, or _Atomic.740  verifyFormat("decltype(foo) const", Style);741  verifyFormat("typeof(foo) const", Style);742  verifyFormat("_Atomic(foo) const", Style);743 744  // ::template for dependent names745  verifyFormat("const volatile ::template Foo<T> var;",746               "::template Foo<T> const volatile var;", Style);747  verifyFormat("const volatile typename ::template Foo<T> var;",748               "typename ::template Foo<T> const volatile var;", Style);749  verifyFormat("const typename Bar::template Foo<T>::T;",750               "typename Bar::template Foo<T>::T const;", Style);751  verifyFormat("const volatile typename Bar::template Foo<T>::T;",752               "typename Bar::template Foo<T>::T const volatile;", Style);753 754  // typename ::755  verifyFormat("const typename ::Bar<int>;", "typename ::Bar<int> const;",756               Style);757  // typename ::template758  verifyFormat("const typename ::template Bar<int>;",759               "typename ::template Bar<int> const;", Style);760 761  // Comments762  const int ColumnLimit = Style.ColumnLimit;763  Style.ColumnLimit = 200;764  verifyFormat("/*c*/ const Foo *foo;", "/*c*/ Foo const *foo;", Style);765  verifyFormat("const Foo /*c*/ *foo;", "Foo const /*c*/ *foo;", Style);766  verifyFormat("const Foo * /*c*/ foo;", "Foo const * /*c*/ foo;", Style);767 768  verifyFormat("/*comment*/ const std::vector<int> v;",769               "/*comment*/ std::vector<int> const v;", Style);770  verifyFormat("const std /*comment*/ ::vector<int> v;",771               "std /*comment*/ ::vector<int> const v;", Style);772  verifyFormat("const std::/*comment*/ vector<int> v;",773               "std::/*comment*/ vector<int> const v;", Style);774  verifyFormat("const std::vector /*comment*/<int> v;",775               "std::vector /*comment*/<int> const v;", Style);776  verifyFormat("const std::vector</*comment*/ int> v;",777               "std::vector</*comment*/ int> const v;", Style);778  verifyFormat("const std::vector<int /*comment*/> v;",779               "std::vector<int /*comment*/> const v;", Style);780  verifyFormat("const std::vector<int> /*comment*/ v;",781               "std::vector<int> /*comment*/ const v;", Style);782 783  verifyFormat("std::vector</*comment*/ const int> v;",784               "std::vector</*comment*/ int const> v;", Style);785  verifyFormat("std::vector<const int /*comment*/> v;",786               "std::vector<int /*comment*/ const> v;", Style);787  verifyFormat("std::vector<const int /*comment*/> v;",788               "std::vector<int const /*comment*/> v;", Style);789  verifyFormat("std::vector</*comment*/ const Foo> v;",790               "std::vector</*comment*/ Foo const> v;", Style);791  verifyFormat("std::vector<const Foo /*comment*/> v;",792               "std::vector<Foo /*comment*/ const> v;", Style);793  verifyFormat("std::vector<const Foo /*comment*/> v;",794               "std::vector<Foo const /*comment*/> v;", Style);795 796  verifyFormat("const typename C<T>::template B<T>;",797               "typename C<T>::template B<T> const;", Style);798  verifyFormat("/*c*/ const typename C<T>::template B<T>;",799               "/*c*/ typename C<T>::template B<T> const;", Style);800  verifyFormat("const typename /*c*/ C<T>::template B<T>;",801               "typename /*c*/ C<T>::template B<T> const;", Style);802  verifyFormat("const typename C /*c*/<T>::template B<T>;",803               "typename C /*c*/<T>::template B<T> const;", Style);804  verifyFormat("const typename C<T> /*c*/ ::template B<T>;",805               "typename C<T> /*c*/ ::template B<T> const;", Style);806  verifyFormat("const typename C<T>::/*c*/ template B<T>;",807               "typename C<T>::/*c*/ template B<T> const;", Style);808  verifyFormat("const typename C<T>::template /*c*/ B<T>;",809               "typename C<T>::template /*c*/ B<T> const;", Style);810  verifyFormat("const typename C<T>::template B<T> /*c*/;",811               "typename C<T>::template B<T> /*c*/ const;", Style);812 813  verifyFormat("/*c*/ const typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template "814               "/*c*/ B /*c*/<T> /*c*/ v;",815               "/*c*/ typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template /*c*/ B "816               "/*c*/<T> /*c*/ const v;",817               Style);818 819  verifyFormat("const unsigned /*c*/ long /*c*/ a;",820               "unsigned /*c*/ long /*c*/ const a;", Style);821  verifyFormat("const unsigned /*c*/ long /*c*/ long a;",822               "unsigned /*c*/ long /*c*/ long const a;", Style);823 824  // Not changed825  verifyFormat("foo() /*c*/ const", Style);826  verifyFormat("struct /*c*/ const a;", Style);827  verifyFormat("class /*c*/ const a;", Style);828  verifyFormat("decltype(v) /*c*/ const a;", Style);829  verifyFormat("typeof(v) /*c*/ const a;", Style);830  verifyFormat("_Atomic(v) /*c*/ const a;", Style);831  verifyFormat("decltype /*c*/ (v) const a;", Style);832  verifyFormat("const /*c*/ class {\n} /*c*/ volatile /*c*/ foo = {};", Style);833 834  Style.ColumnLimit = ColumnLimit;835 836  // Don't adjust macros837  verifyFormat("INTPTR const a;", Style);838 839  // Pointers to members840  verifyFormat("int S::*a;", Style);841  verifyFormat("const int S::*a;", "int const S::*a;", Style);842  verifyFormat("const int S::*const a;", "int const S::*const a;", Style);843  verifyFormat("int A::*const A::*p1;", Style);844  verifyFormat("float (C::*p)(int);", Style);845  verifyFormat("float (C::*const p)(int);", Style);846  verifyFormat("float (C::*p)(int) const;", Style);847  verifyFormat("const float (C::*p)(int);", "float const (C::*p)(int);", Style);848}849 850TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) {851  FormatStyle Style = getLLVMStyle();852  Style.QualifierAlignment = FormatStyle::QAS_Left;853  Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};854 855  // The Default856  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);857 858  verifyFormat("const volatile int a;", Style);859  verifyFormat("const volatile int a;", "volatile const int a;", Style);860  verifyFormat("const volatile int a;", "int const volatile a;", Style);861  verifyFormat("const volatile int a;", "int volatile const a;", Style);862  verifyFormat("const volatile int a;", "const int volatile a;", Style);863 864  verifyFormat("const volatile Foo a;", Style);865  verifyFormat("const volatile Foo a;", "volatile const Foo a;", Style);866  verifyFormat("const volatile Foo a;", "Foo const volatile a;", Style);867  verifyFormat("const volatile Foo a;", "Foo volatile const a;", Style);868  verifyFormat("const volatile Foo a;", "const Foo volatile a;", Style);869 870  Style.QualifierAlignment = FormatStyle::QAS_Right;871  Style.QualifierOrder = {"type", "const", "volatile"};872 873  verifyFormat("int const volatile a;", "const volatile int a;", Style);874  verifyFormat("int const volatile a;", "volatile const int a;", Style);875  verifyFormat("int const volatile a;", Style);876  verifyFormat("int const volatile a;", "int volatile const a;", Style);877  verifyFormat("int const volatile a;", "const int volatile a;", Style);878 879  verifyFormat("Foo const volatile a;", "const volatile Foo a;", Style);880  verifyFormat("Foo const volatile a;", "volatile const Foo a;", Style);881  verifyFormat("Foo const volatile a;", Style);882  verifyFormat("Foo const volatile a;", "Foo volatile const a;", Style);883  verifyFormat("Foo const volatile a;", "const Foo volatile a;", Style);884 885  Style.QualifierAlignment = FormatStyle::QAS_Left;886  Style.QualifierOrder = {"volatile", "const", "type"};887 888  verifyFormat("volatile const int a;", "const volatile int a;", Style);889  verifyFormat("volatile const int a;", Style);890  verifyFormat("volatile const int a;", "int const volatile a;", Style);891  verifyFormat("volatile const int a;", "int volatile const a;", Style);892  verifyFormat("volatile const int a;", "const int volatile a;", Style);893 894  verifyFormat("volatile const Foo a;", "const volatile Foo a;", Style);895  verifyFormat("volatile const Foo a;", Style);896  verifyFormat("volatile const Foo a;", "Foo const volatile a;", Style);897  verifyFormat("volatile const Foo a;", "Foo volatile const a;", Style);898  verifyFormat("volatile const Foo a;", "const Foo volatile a;", Style);899 900  Style.QualifierAlignment = FormatStyle::QAS_Right;901  Style.QualifierOrder = {"type", "volatile", "const"};902 903  verifyFormat("int volatile const a;", "const volatile int a;", Style);904  verifyFormat("int volatile const a;", "volatile const int a;", Style);905  verifyFormat("int volatile const a;", "int const volatile a;", Style);906  verifyFormat("int volatile const a;", Style);907  verifyFormat("int volatile const a;", "const int volatile a;", Style);908 909  verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);910  verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);911  verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);912  verifyFormat("Foo volatile const a;", Style);913  verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);914 915  Style.QualifierAlignment = FormatStyle::QAS_Custom;916  Style.QualifierOrder = {"type", "volatile", "const"};917 918  verifyFormat("int volatile const a;", "const volatile int a;", Style);919  verifyFormat("int volatile const a;", "volatile const int a;", Style);920  verifyFormat("int volatile const a;", "int const volatile a;", Style);921  verifyFormat("int volatile const a;", Style);922  verifyFormat("int volatile const a;", "const int volatile a;", Style);923 924  verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);925  verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);926  verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);927  verifyFormat("Foo volatile const a;", Style);928  verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);929}930 931TEST_F(QualifierFixerTest, InlineStatics) {932  FormatStyle Style = getLLVMStyle();933  Style.QualifierAlignment = FormatStyle::QAS_Left;934  Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};935  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);936 937  verifyFormat("inline static const volatile int a;",938               "const inline static volatile int a;", Style);939  verifyFormat("inline static const volatile int a;",940               "volatile inline static const int a;", Style);941  verifyFormat("inline static const volatile int a;",942               "int const inline static  volatile a;", Style);943  verifyFormat("inline static const volatile int a;",944               "int volatile inline static  const a;", Style);945  verifyFormat("inline static const volatile int a;",946               "const int inline static  volatile a;", Style);947}948 949TEST_F(QualifierFixerTest, AmpEqual) {950  FormatStyle Style = getLLVMStyle();951  Style.QualifierAlignment = FormatStyle::QAS_Custom;952  Style.QualifierOrder = {"static", "type", "const"};953  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)3);954 955  verifyFormat("foo(std::string const & = std::string()) const",956               "foo(const std::string & = std::string()) const", Style);957  verifyFormat("foo(std::string const & = std::string())",958               "foo(const std::string & = std::string())", Style);959}960 961TEST_F(QualifierFixerTest, MoveConstBeyondTypeSmall) {962 963  FormatStyle Style = getLLVMStyle();964  Style.QualifierAlignment = FormatStyle::QAS_Custom;965  Style.QualifierOrder = {"type", "const"};966  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);967 968  verifyFormat("int const a;", "const int a;", Style);969  verifyFormat("int const *a;", "const int*a;", Style);970  verifyFormat("int const *a;", "const int *a;", Style);971  verifyFormat("int const &a;", "const int &a;", Style);972  verifyFormat("int const &&a;", "const int &&a;", Style);973}974 975TEST_F(QualifierFixerTest, MoveConstBeforeTypeSmall) {976 977  FormatStyle Style = getLLVMStyle();978  Style.QualifierAlignment = FormatStyle::QAS_Custom;979  Style.QualifierOrder = {"const", "type"};980  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);981 982  verifyFormat("const int a;", "int const a;", Style);983  verifyFormat("const int *a;", "int const *a;", Style);984  verifyFormat("const int *const a;", "int const *const a;", Style);985 986  verifyFormat("const int a = foo();", "int const a = foo();", Style);987  verifyFormat("const int *a = foo();", "int const *a = foo();", Style);988  verifyFormat("const int *const a = foo();", "int const *const a = foo();",989               Style);990 991  verifyFormat("const auto a = foo();", "auto const a = foo();", Style);992  verifyFormat("const auto *a = foo();", "auto const *a = foo();", Style);993  verifyFormat("const auto *const a = foo();", "auto const *const a = foo();",994               Style);995}996 997TEST_F(QualifierFixerTest, MoveConstBeyondType) {998 999  FormatStyle Style = getLLVMStyle();1000  Style.QualifierAlignment = FormatStyle::QAS_Custom;1001  Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};1002  EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);1003 1004  verifyFormat("static inline int const volatile a;",1005               "const inline static volatile int a;", Style);1006  verifyFormat("static inline int const volatile a;",1007               "volatile inline static const int a;", Style);1008  verifyFormat("static inline int const volatile a;",1009               "int const inline static  volatile a;", Style);1010  verifyFormat("static inline int const volatile a;",1011               "int volatile inline static  const a;", Style);1012  verifyFormat("static inline int const volatile a;",1013               "const int inline static  volatile a;", Style);1014 1015  verifyFormat("static inline int const volatile *const a;",1016               "const int inline static  volatile *const a;", Style);1017 1018  verifyFormat("static inline Foo const volatile a;",1019               "const inline static volatile Foo a;", Style);1020  verifyFormat("static inline Foo const volatile a;",1021               "volatile inline static const Foo a;", Style);1022  verifyFormat("static inline Foo const volatile a;",1023               "Foo const inline static  volatile a;", Style);1024  verifyFormat("static inline Foo const volatile a;",1025               "Foo volatile inline static  const a;", Style);1026  verifyFormat("static inline Foo const volatile a;",1027               "const Foo inline static  volatile a;", Style);1028 1029  verifyFormat("static inline Foo const volatile *const a;",1030               "const Foo inline static volatile *const a;", Style);1031}1032 1033TEST_F(QualifierFixerTest, PrepareLeftRightOrdering) {1034  FormatStyle Style = getLLVMStyle();1035  Style.QualifierAlignment = FormatStyle::QAS_Custom;1036  Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};1037 1038  std::vector<std::string> Left;1039  std::vector<std::string> Right;1040  std::vector<tok::TokenKind> ConfiguredTokens;1041  prepareLeftRightOrderingForQualifierAlignmentFixer(Style.QualifierOrder, Left,1042                                                     Right, ConfiguredTokens);1043 1044  EXPECT_EQ(Left.size(), (size_t)2);1045  EXPECT_EQ(Right.size(), (size_t)2);1046 1047  std::vector<std::string> LeftResult = {"inline", "static"};1048  std::vector<std::string> RightResult = {"const", "volatile"};1049  EXPECT_EQ(Left, LeftResult);1050  EXPECT_EQ(Right, RightResult);1051}1052 1053TEST_F(QualifierFixerTest, IsQualifierType) {1054 1055  std::vector<tok::TokenKind> ConfiguredTokens;1056  ConfiguredTokens.push_back(tok::kw_const);1057  ConfiguredTokens.push_back(tok::kw_static);1058  ConfiguredTokens.push_back(tok::kw_inline);1059  ConfiguredTokens.push_back(tok::kw_restrict);1060  ConfiguredTokens.push_back(tok::kw_constexpr);1061  ConfiguredTokens.push_back(tok::kw_friend);1062 1063  TestLexer lexer{Allocator, Buffers};1064  const auto LangOpts = getFormattingLangOpts();1065 1066  auto Tokens = lexer.lex(1067      "const static inline auto restrict int double long constexpr friend");1068  ASSERT_EQ(Tokens.size(), 11u) << Tokens;1069 1070  EXPECT_TRUE(1071      isConfiguredQualifierOrType(Tokens[0], ConfiguredTokens, LangOpts));1072  EXPECT_TRUE(1073      isConfiguredQualifierOrType(Tokens[1], ConfiguredTokens, LangOpts));1074  EXPECT_TRUE(1075      isConfiguredQualifierOrType(Tokens[2], ConfiguredTokens, LangOpts));1076  EXPECT_TRUE(1077      isConfiguredQualifierOrType(Tokens[3], ConfiguredTokens, LangOpts));1078  EXPECT_TRUE(1079      isConfiguredQualifierOrType(Tokens[4], ConfiguredTokens, LangOpts));1080  EXPECT_TRUE(1081      isConfiguredQualifierOrType(Tokens[5], ConfiguredTokens, LangOpts));1082  EXPECT_TRUE(1083      isConfiguredQualifierOrType(Tokens[6], ConfiguredTokens, LangOpts));1084  EXPECT_TRUE(1085      isConfiguredQualifierOrType(Tokens[7], ConfiguredTokens, LangOpts));1086  EXPECT_TRUE(1087      isConfiguredQualifierOrType(Tokens[8], ConfiguredTokens, LangOpts));1088  EXPECT_TRUE(1089      isConfiguredQualifierOrType(Tokens[9], ConfiguredTokens, LangOpts));1090 1091  EXPECT_TRUE(isQualifierOrType(Tokens[0], LangOpts));1092  EXPECT_TRUE(isQualifierOrType(Tokens[1], LangOpts));1093  EXPECT_TRUE(isQualifierOrType(Tokens[2], LangOpts));1094  EXPECT_TRUE(isQualifierOrType(Tokens[3], LangOpts));1095  EXPECT_TRUE(isQualifierOrType(Tokens[4], LangOpts));1096  EXPECT_TRUE(isQualifierOrType(Tokens[5], LangOpts));1097  EXPECT_TRUE(isQualifierOrType(Tokens[6], LangOpts));1098  EXPECT_TRUE(isQualifierOrType(Tokens[7], LangOpts));1099  EXPECT_TRUE(isQualifierOrType(Tokens[8], LangOpts));1100  EXPECT_TRUE(isQualifierOrType(Tokens[9], LangOpts));1101 1102  auto NotTokens = lexer.lex("for while do Foo Bar ");1103  ASSERT_EQ(NotTokens.size(), 6u) << Tokens;1104 1105  EXPECT_FALSE(1106      isConfiguredQualifierOrType(NotTokens[0], ConfiguredTokens, LangOpts));1107  EXPECT_FALSE(1108      isConfiguredQualifierOrType(NotTokens[1], ConfiguredTokens, LangOpts));1109  EXPECT_FALSE(1110      isConfiguredQualifierOrType(NotTokens[2], ConfiguredTokens, LangOpts));1111  EXPECT_FALSE(1112      isConfiguredQualifierOrType(NotTokens[3], ConfiguredTokens, LangOpts));1113  EXPECT_FALSE(1114      isConfiguredQualifierOrType(NotTokens[4], ConfiguredTokens, LangOpts));1115  EXPECT_FALSE(1116      isConfiguredQualifierOrType(NotTokens[5], ConfiguredTokens, LangOpts));1117 1118  EXPECT_FALSE(isQualifierOrType(NotTokens[0], LangOpts));1119  EXPECT_FALSE(isQualifierOrType(NotTokens[1], LangOpts));1120  EXPECT_FALSE(isQualifierOrType(NotTokens[2], LangOpts));1121  EXPECT_FALSE(isQualifierOrType(NotTokens[3], LangOpts));1122  EXPECT_FALSE(isQualifierOrType(NotTokens[4], LangOpts));1123  EXPECT_FALSE(isQualifierOrType(NotTokens[5], LangOpts));1124}1125 1126TEST_F(QualifierFixerTest, IsMacro) {1127  auto Tokens = annotate("INT INTPR Foo int");1128  ASSERT_EQ(Tokens.size(), 5u) << Tokens;1129  EXPECT_TRUE(isPossibleMacro(Tokens[0]));1130  EXPECT_TRUE(isPossibleMacro(Tokens[1]));1131  EXPECT_FALSE(isPossibleMacro(Tokens[2]));1132  EXPECT_FALSE(isPossibleMacro(Tokens[3]));1133 1134  Tokens = annotate("FOO::BAR");1135  ASSERT_EQ(Tokens.size(), 4u) << Tokens;1136  EXPECT_FALSE(isPossibleMacro(Tokens[0]));1137  EXPECT_FALSE(isPossibleMacro(Tokens[2]));1138}1139 1140TEST_F(QualifierFixerTest, OverlappingQualifier) {1141 1142  FormatStyle Style = getLLVMStyle();1143  Style.QualifierAlignment = FormatStyle::QAS_Left;1144  Style.QualifierOrder = {"const", "type"};1145 1146  verifyFormat("Foo(const Bar &name);", "Foo(Bar const &name);", Style);1147}1148 1149TEST_F(QualifierFixerTest, DontPushQualifierThroughNonSpecifiedTypes) {1150 1151  FormatStyle Style = getLLVMStyle();1152  Style.QualifierAlignment = FormatStyle::QAS_Left;1153  Style.QualifierOrder = {"const", "volatile", "type"};1154 1155  verifyFormat("inline static const int a;", Style);1156 1157  Style.QualifierOrder = {"static", "const", "type"};1158 1159  verifyFormat("inline static const int a;", Style);1160  verifyFormat("static inline const int a;", Style);1161 1162  verifyFormat("static const int a;", "const static int a;", Style);1163 1164  Style.QualifierOrder = {"const", "volatile", "type"};1165  // static is not configured, unchanged at right hand qualifiers.1166  verifyFormat("const volatile int static;", "int volatile static const;",1167               Style);1168  verifyFormat("const volatile int static;", "int const static volatile;",1169               Style);1170  verifyFormat("const volatile int static;", "const int static volatile;",1171               Style);1172  verifyFormat("const volatile Foo static;", "Foo volatile static const;",1173               Style);1174  verifyFormat("const volatile Foo static;", "Foo const static volatile;",1175               Style);1176  verifyFormat("const volatile Foo static;", "const Foo static volatile;",1177               Style);1178 1179  verifyFormat("inline static const Foo;", "inline static Foo const;", Style);1180  verifyFormat("inline static const Foo;", Style);1181 1182  // Don't move qualifiers to the right for aestethics only.1183  verifyFormat("inline const static Foo;", Style);1184  verifyFormat("const inline static Foo;", Style);1185}1186 1187TEST_F(QualifierFixerTest, QualifiersBrokenUpByPPDirectives) {1188  auto Style = getLLVMStyle();1189  Style.QualifierAlignment = FormatStyle::QAS_Custom;1190  Style.QualifierOrder = {"constexpr", "inline", "type"};1191 1192  verifyFormat("inline\n"1193               "#if FOO\n"1194               "    constexpr\n"1195               "#endif\n"1196               "    int i = 0;",1197               Style);1198}1199 1200TEST_F(QualifierFixerTest, QualifierOrderingAfterPreprocessorDirectives) {1201  auto Style = getLLVMStyle();1202  Style.QualifierAlignment = FormatStyle::QAS_Custom;1203  Style.QualifierOrder = {"static", "inline", "const", "type"};1204 1205  verifyFormat("#if 1\n"1206               "void foo(const int par);\n"1207               "const int var1;\n"1208               "#endif\n"1209               "\n"1210               "const int var2;\n"1211               "const int var3;",1212               "#if 1\n"1213               "void foo(int const par);\n"1214               "int const var1;\n"1215               "#endif\n"1216               "\n"1217               "int const var2;\n"1218               "int const var3;",1219               Style);1220  verifyFormat("#if defined(FOO)\n"1221               "static const int x = 1;\n"1222               "#else\n"1223               "static const int x = 2;\n"1224               "#endif\n"1225               "static const int y = 3;",1226               "#if defined(FOO)\n"1227               "const static int x = 1;\n"1228               "#else\n"1229               "const static int x = 2;\n"1230               "#endif\n"1231               "const static int y = 3;",1232               Style);1233}1234 1235TEST_F(QualifierFixerTest, UnsignedQualifier) {1236 1237  FormatStyle Style = getLLVMStyle();1238  Style.QualifierAlignment = FormatStyle::QAS_Left;1239  Style.QualifierOrder = {"const", "type"};1240 1241  verifyFormat("Foo(const unsigned char *bytes)",1242               "Foo(unsigned const char *bytes)", Style);1243 1244  Style.QualifierAlignment = FormatStyle::QAS_Right;1245  Style.QualifierOrder = {"type", "const"};1246 1247  verifyFormat("Foo(unsigned char const *bytes)",1248               "Foo(unsigned const char *bytes)", Style);1249}1250 1251TEST_F(QualifierFixerTest, NoOpQualifierReplacements) {1252 1253  FormatStyle Style = getLLVMStyle();1254  Style.QualifierAlignment = FormatStyle::QAS_Custom;1255  Style.QualifierOrder = {"static", "const", "type"};1256 1257  verifyFormat("static const uint32 foo[] = {0, 31};", Style);1258  EXPECT_EQ(ReplacementCount, 0);1259 1260  verifyFormat("#define MACRO static const", Style);1261  EXPECT_EQ(ReplacementCount, 0);1262 1263  verifyFormat("using sc = static const", Style);1264  EXPECT_EQ(ReplacementCount, 0);1265}1266 1267TEST_F(QualifierFixerTest, QualifierTemplates) {1268  FormatStyle Style = getLLVMStyle();1269  Style.QualifierAlignment = FormatStyle::QAS_Custom;1270  Style.QualifierOrder = {"static", "const", "type"};1271 1272  ReplacementCount = 0;1273  EXPECT_EQ(ReplacementCount, 0);1274  verifyFormat("using A = B<>;", Style);1275  verifyFormat("using A = B /**/<>;", Style);1276  verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);1277  verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);1278  verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);1279  verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);1280  verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);1281  verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);1282  verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);1283  EXPECT_EQ(ReplacementCount, 0);1284  verifyFormat("template <class C>\n"1285               "using A = B // foo\n"1286               "    <Foo<C>, 1>;",1287               Style);1288 1289  ReplacementCount = 0;1290  Style.QualifierOrder = {"type", "static", "const"};1291  verifyFormat("using A = B<>;", Style);1292  verifyFormat("using A = B /**/<>;", Style);1293  verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);1294  verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);1295  verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);1296  verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);1297  verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);1298  verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);1299  verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);1300  EXPECT_EQ(ReplacementCount, 0);1301  verifyFormat("template <class C>\n"1302               "using A = B // foo\n"1303               "    <Foo<C>, 1>;",1304               Style);1305}1306 1307TEST_F(QualifierFixerTest, WithConstraints) {1308  FormatStyle Style = getLLVMStyle();1309  Style.QualifierAlignment = FormatStyle::QAS_Custom;1310  Style.QualifierOrder = {"constexpr", "type"};1311 1312  verifyFormat("template <typename T>\n"1313               "  requires Concept<F>\n"1314               "constexpr constructor();",1315               Style);1316  verifyFormat("template <typename T>\n"1317               "  requires Concept1<F> && Concept2<F>\n"1318               "constexpr constructor();",1319               Style);1320}1321 1322TEST_F(QualifierFixerTest, WithCpp11Attribute) {1323  FormatStyle Style = getLLVMStyle();1324  Style.QualifierAlignment = FormatStyle::QAS_Custom;1325  Style.QualifierOrder = {"static", "constexpr", "inline", "type"};1326 1327  verifyFormat("[[nodiscard]] static constexpr inline int func() noexcept {}",1328               "[[nodiscard]] inline constexpr static int func() noexcept {}",1329               Style);1330  verifyFormat("[[maybe_unused]] static constexpr int A",1331               "[[maybe_unused]] constexpr static int A", Style);1332}1333 1334TEST_F(QualifierFixerTest, WithQualifiedTypeName) {1335  auto Style = getLLVMStyle();1336  Style.QualifierAlignment = FormatStyle::QAS_Custom;1337  Style.QualifierOrder = {"constexpr", "type", "const"};1338 1339  verifyFormat("constexpr ::int64_t x{1};", "::int64_t constexpr x{1};", Style);1340  verifyFormat("constexpr std::int64_t x{123};",1341               "std::int64_t constexpr x{123};", Style);1342  verifyFormat("constexpr ::std::int64_t x{123};",1343               "::std::int64_t constexpr x{123};", Style);1344 1345  Style.TypeNames.push_back("bar");1346  verifyFormat("constexpr foo::bar x{12};", "foo::bar constexpr x{12};", Style);1347}1348 1349TEST_F(QualifierFixerTest, DisableRegions) {1350  FormatStyle Style = getLLVMStyle();1351  Style.QualifierAlignment = FormatStyle::QAS_Custom;1352  Style.QualifierOrder = {"inline", "static", "const", "type"};1353 1354  ReplacementCount = 0;1355  verifyFormat("// clang-format off\n"1356               "int const inline static a = 0;\n"1357               "// clang-format on",1358               Style);1359  EXPECT_EQ(ReplacementCount, 0);1360  verifyFormat("// clang-format off\n"1361               "int const inline static a = 0;\n"1362               "// clang-format on\n"1363               "inline static const int a = 0;",1364               "// clang-format off\n"1365               "int const inline static a = 0;\n"1366               "// clang-format on\n"1367               "int const inline static a = 0;",1368               Style);1369}1370 1371TEST_F(QualifierFixerTest, TemplatesRight) {1372  FormatStyle Style = getLLVMStyle();1373  Style.QualifierAlignment = FormatStyle::QAS_Custom;1374  Style.QualifierOrder = {"type", "const"};1375 1376  verifyFormat("template <typename T> Foo const f();",1377               "template <typename T> const Foo f();", Style);1378  verifyFormat("template <typename T> int const f();",1379               "template <typename T> const int f();", Style);1380 1381  verifyFormat("template <T const> t;", "template <const T> t;", Style);1382  verifyFormat("template <typename T>\n"1383               "  requires Concept<T const>\n"1384               "Foo const f();",1385               "template <typename T>\n"1386               "  requires Concept<const T>\n"1387               "const Foo f();",1388               Style);1389  verifyFormat("TemplateType<T const> t;", "TemplateType<const T> t;", Style);1390  verifyFormat("TemplateType<Container const> t;",1391               "TemplateType<const Container> t;", Style);1392}1393 1394TEST_F(QualifierFixerTest, TemplatesLeft) {1395  FormatStyle Style = getLLVMStyle();1396  Style.QualifierAlignment = FormatStyle::QAS_Custom;1397  Style.QualifierOrder = {"const", "volatile", "type"};1398 1399  verifyFormat("template <typename T> const Foo f();",1400               "template <typename T> Foo const f();", Style);1401  verifyFormat("template <typename T> const int f();",1402               "template <typename T> int const f();", Style);1403 1404  verifyFormat("template <const T> t;", "template <T const> t;", Style);1405  verifyFormat("template <typename T>\n"1406               "  requires Concept<const T>\n"1407               "const Foo f();",1408               "template <typename T>\n"1409               "  requires Concept<T const>\n"1410               "Foo const f();",1411               Style);1412  verifyFormat("template <typename T>\n"1413               "  requires Concept<const T>\n"1414               "const volatile Foo f();",1415               "template <typename T>\n"1416               "  requires Concept<T const>\n"1417               "volatile const Foo f();",1418               Style);1419  verifyFormat("TemplateType<const T> t;", "TemplateType<T const> t;", Style);1420  verifyFormat("TemplateType<const Container> t;",1421               "TemplateType<Container const> t;", Style);1422}1423 1424TEST_F(QualifierFixerTest, Ranges) {1425  FormatStyle Style = getLLVMStyle();1426  Style.QualifierAlignment = FormatStyle::QAS_Custom;1427  Style.QualifierOrder = {"const", "volatile", "type"};1428 1429  // Only the first line should be formatted; the second should remain as is.1430  verifyFormat("template <typename T> const Foo f();\n"1431               "template <typename T> Foo const f();",1432               "template <typename T> Foo const f();\n"1433               "template <typename T> Foo const f();",1434               Style, {tooling::Range(0, 36)});1435 1436  // Only the middle line should be formatted; the first and last should remain1437  // as is.1438  verifyFormat("template <typename T> Foo const f();\n"1439               "template <typename T> const Foo f();\n"1440               "template <typename T> Foo const f();",1441               "template <typename T> Foo const f();\n"1442               "template <typename T> Foo const f();\n"1443               "template <typename T> Foo const f();",1444               Style, {tooling::Range(37, 36)});1445}1446 1447} // namespace1448} // namespace test1449} // namespace format1450} // namespace clang1451