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