//===- unittest/Format/QualifierFixerTest.cpp - Formatting unit tests -----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "../lib/Format/QualifierAlignmentFixer.h" #include "FormatTestBase.h" #include "TestLexer.h" #define DEBUG_TYPE "format-qualifier-fixer-test" namespace clang { namespace format { namespace test { namespace { #define CHECK_PARSE(TEXT, FIELD, VALUE) \ EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!"; \ EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \ EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!" #define FAIL_PARSE(TEXT, FIELD, VALUE) \ EXPECT_NE(0, parseConfiguration(TEXT, &Style).value()); \ EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!" class QualifierFixerTest : public FormatTestBase { protected: TokenList annotate(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { return TestLexer(Allocator, Buffers, Style).annotate(Code); } llvm::SpecificBumpPtrAllocator Allocator; std::vector> Buffers; }; TEST_F(QualifierFixerTest, RotateTokens) { // TODO add test EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("const"), tok::kw_const); EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("volatile"), tok::kw_volatile); EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("inline"), tok::kw_inline); EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("static"), tok::kw_static); EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("restrict"), tok::kw_restrict); EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("friend"), tok::kw_friend); } TEST_F(QualifierFixerTest, FailQualifierInvalidConfiguration) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; FAIL_PARSE("QualifierAlignment: Custom\n" "QualifierOrder: [const, volatile, apples, type]", QualifierOrder, std::vector({"const", "volatile", "apples", "type"})); } TEST_F(QualifierFixerTest, FailQualifierDuplicateConfiguration) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; FAIL_PARSE("QualifierAlignment: Custom\n" "QualifierOrder: [const, volatile, const, type]", QualifierOrder, std::vector({"const", "volatile", "const", "type"})); } TEST_F(QualifierFixerTest, FailQualifierMissingType) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; FAIL_PARSE("QualifierAlignment: Custom\n" "QualifierOrder: [const, volatile ]", QualifierOrder, std::vector({ "const", "volatile", })); } TEST_F(QualifierFixerTest, FailQualifierEmptyOrder) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; FAIL_PARSE("QualifierAlignment: Custom\nQualifierOrder: []", QualifierOrder, std::vector({})); } TEST_F(QualifierFixerTest, FailQualifierMissingOrder) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; FAIL_PARSE("QualifierAlignment: Custom", QualifierOrder, std::vector()); } TEST_F(QualifierFixerTest, QualifierLeft) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; CHECK_PARSE("QualifierAlignment: Left", QualifierOrder, std::vector({"const", "volatile", "type"})); } TEST_F(QualifierFixerTest, QualifierRight) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; CHECK_PARSE("QualifierAlignment: Right", QualifierOrder, std::vector({"type", "const", "volatile"})); } TEST_F(QualifierFixerTest, QualifiersCustomOrder) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"friend", "inline", "constexpr", "static", "const", "volatile", "type"}; verifyFormat("const volatile int a;", Style); verifyFormat("const volatile int a;", "volatile const int a;", Style); verifyFormat("const volatile int a;", "int const volatile a;", Style); verifyFormat("const volatile int a;", "int volatile const a;", Style); verifyFormat("const volatile int a;", "const int volatile a;", Style); verifyFormat("static const volatile int a;", "const static int volatile a;", Style); verifyFormat("inline static const volatile int a;", "const static inline int volatile a;", Style); verifyFormat("constexpr static int a;", "static constexpr int a;", Style); verifyFormat("constexpr static int A;", "static constexpr int A;", Style); verifyFormat("constexpr static int Bar;", "static constexpr int Bar;", Style); verifyFormat("constexpr static LPINT Bar;", "static constexpr LPINT Bar;", Style); verifyFormat("const const int a;", "const int const a;", Style); verifyFormat( "friend constexpr auto operator<=>(const foo &, const foo &) = default;", "constexpr friend auto operator<=>(const foo &, const foo &) = default;", Style); verifyFormat( "friend constexpr bool operator==(const foo &, const foo &) = default;", "constexpr bool friend operator==(const foo &, const foo &) = default;", Style); } TEST_F(QualifierFixerTest, LeftRightQualifier) { FormatStyle Style = getLLVMStyle(); // keep the const style unaltered verifyFormat("const int a;", Style); verifyFormat("const int *a;", Style); verifyFormat("const int &a;", Style); verifyFormat("const int &&a;", Style); verifyFormat("int const b;", Style); verifyFormat("int const *b;", Style); verifyFormat("int const &b;", Style); verifyFormat("int const &&b;", Style); verifyFormat("int const *const b;", Style); verifyFormat("int *const c;", Style); verifyFormat("const Foo a;", Style); verifyFormat("const Foo *a;", Style); verifyFormat("const Foo &a;", Style); verifyFormat("const Foo &&a;", Style); verifyFormat("Foo const b;", Style); verifyFormat("Foo const *b;", Style); verifyFormat("Foo const &b;", Style); verifyFormat("Foo const &&b;", Style); verifyFormat("Foo const *const b;", Style); verifyFormat("LLVM_NODISCARD const int &Foo();", Style); verifyFormat("LLVM_NODISCARD int const &Foo();", Style); verifyFormat("volatile const int *restrict;", Style); verifyFormat("const volatile int *restrict;", Style); verifyFormat("const int volatile *restrict;", Style); } TEST_F(QualifierFixerTest, RightQualifier) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Right; Style.QualifierOrder = {"type", "const", "volatile"}; verifyFormat("int const a;", Style); verifyFormat("int const *a;", Style); verifyFormat("int const &a;", Style); verifyFormat("int const &&a;", Style); verifyFormat("int const b;", Style); verifyFormat("int const *b;", Style); verifyFormat("int const &b;", Style); verifyFormat("int const &&b;", Style); verifyFormat("int const *const b;", Style); verifyFormat("int *const c;", Style); verifyFormat("Foo const a;", Style); verifyFormat("Foo const *a;", Style); verifyFormat("Foo const &a;", Style); verifyFormat("Foo const &&a;", Style); verifyFormat("Foo const b;", Style); verifyFormat("Foo const *b;", Style); verifyFormat("Foo const &b;", Style); verifyFormat("Foo const &&b;", Style); verifyFormat("Foo const *const b;", Style); verifyFormat("Foo *const b;", Style); verifyFormat("Foo const *const b;", Style); verifyFormat("auto const v = get_value();", Style); verifyFormat("long long const &a;", Style); verifyFormat("unsigned char const *a;", Style); verifyFormat("int main(int const argc, char const *const *const argv)", Style); verifyFormat("LLVM_NODISCARD int const &Foo();", Style); verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY", Style); verifyFormat("void foo() const override;", Style); verifyFormat("void foo() const override LLVM_READONLY;", Style); verifyFormat("void foo() const final;", Style); verifyFormat("void foo() const final LLVM_READONLY;", Style); verifyFormat("void foo() const LLVM_READONLY;", Style); verifyFormat("void foo() const volatile override;", Style); verifyFormat("void foo() const volatile override LLVM_READONLY;", Style); verifyFormat("void foo() const volatile final;", Style); verifyFormat("void foo() const volatile final LLVM_READONLY;", Style); verifyFormat("void foo() const volatile LLVM_READONLY;", Style); verifyFormat( "template explicit Action(Action const &action);", Style); verifyFormat( "template explicit Action(Action const &action);", "template explicit Action(const Action& action);", Style); verifyFormat( "template explicit Action(Action const &action);", "template \nexplicit Action(const Action& action);", Style); verifyFormat("int const a;", "const int a;", Style); verifyFormat("int const *a;", "const int *a;", Style); verifyFormat("int const &a;", "const int &a;", Style); verifyFormat("foo(int const &a)", "foo(const int &a)", Style); verifyFormat("unsigned char *a;", Style); verifyFormat("unsigned char const *a;", "const unsigned char *a;", Style); verifyFormat("vector args1", "vector args1", Style); verifyFormat("unsigned int const &get_nu() const", "const unsigned int &get_nu() const", Style); verifyFormat("Foo const &a", "const Foo &a", Style); verifyFormat("Foo::iterator const &a", "const Foo::iterator &a", Style); verifyFormat("::Foo::iterator const &a", "const ::Foo::iterator &a", Style); verifyFormat("Foo(int a, " "unsigned b, // c-style args\n" " Bar const &c);", "Foo(int a, " "unsigned b, // c-style args\n" " const Bar &c);", Style); verifyFormat("int const volatile;", "volatile const int;", Style); verifyFormat("int const volatile;", "const volatile int;", Style); verifyFormat("int const volatile;", "const int volatile;", Style); verifyFormat("int const volatile *restrict;", "volatile const int *restrict;", Style); verifyFormat("int const volatile *restrict;", "const volatile int *restrict;", Style); verifyFormat("int const volatile *restrict;", "const int volatile *restrict;", Style); verifyFormat("long long int const volatile;", "const long long int volatile;", Style); verifyFormat("long long int const volatile;", "long const long int volatile;", Style); verifyFormat("long long int const volatile;", "long long volatile int const;", Style); verifyFormat("long long int const volatile;", "long volatile long const int;", Style); verifyFormat("long long int const volatile;", "const long long volatile int;", Style); verifyFormat("static int const bat;", "static const int bat;", Style); verifyFormat("static int const bat;", Style); // static is not configured, unchanged on the left of the right hand // qualifiers. verifyFormat("int static const volatile;", "volatile const int static;", Style); verifyFormat("int static const volatile;", "const volatile int static;", Style); verifyFormat("int static const volatile;", "const int volatile static;", Style); verifyFormat("Foo static const volatile;", "volatile const Foo static;", Style); verifyFormat("Foo static const volatile;", "const volatile Foo static;", Style); verifyFormat("Foo static const volatile;", "const Foo volatile static;", Style); verifyFormat("Foo inline static const;", "const Foo inline static;", Style); verifyFormat("Foo inline static const;", "Foo const inline static;", Style); verifyFormat("Foo inline static const;", "Foo inline const static;", Style); verifyFormat("Foo inline static const;", Style); verifyFormat("Foo::Bar const volatile A::*;", "volatile const Foo::Bar A::*;", Style); verifyFormat("int const Foo::bat = 0;", "const int Foo::bat = 0;", Style); verifyFormat("int const Foo::bat = 0;", Style); verifyFormat("void fn(Foo const &i);", "void fn(const Foo &i);", Style); verifyFormat("int const Foo::fn() {", Style); verifyFormat("Foo> const *p;", "const Foo> *p;", Style); verifyFormat( "Foo> const *p = const_cast> const *>(&ffi);", "const Foo> *p = const_cast> *>(&ffi);", Style); verifyFormat("void fn(Foo const &i);", "void fn(const Foo &i);", Style); verifyFormat("void fns(ns::S const &s);", "void fns(const ns::S &s);", Style); verifyFormat("void fns(::ns::S const &s);", "void fns(const ::ns::S &s);", Style); verifyFormat("void fn(ns::Foo const &i);", "void fn(const ns::Foo &i);", Style); verifyFormat("void fns(ns::ns2::S const &s);", "void fns(const ns::ns2::S &s);", Style); verifyFormat("void fn(ns::Foo> const &i);", "void fn(const ns::Foo> &i);", Style); verifyFormat("void fn(ns::ns2::Foo> const &i);", "void fn(const ns::ns2::Foo> &i);", Style); verifyFormat("void fn(ns::ns2::Foo> const &i);", "void fn(const ns::ns2::Foo> &i);", Style); verifyFormat("LocalScope const *Scope = nullptr;", "const LocalScope* Scope = nullptr;", Style); verifyFormat("struct DOTGraphTraits", "struct DOTGraphTraits", Style); verifyFormat( "bool tools::addXRayRuntime(ToolChain const &TC, ArgList const &Args) {", "bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args) {", Style); verifyFormat("Foo const> P;", "Foo> P;", Style); verifyFormat("Foo const> P;\n#if 0\n#else\n#endif", "Foo> P;\n#if 0\n#else\n#endif", Style); verifyFormat("auto const i = 0;", "const auto i = 0;", Style); verifyFormat("auto const &ir = i;", "const auto &ir = i;", Style); verifyFormat("auto const *ip = &i;", "const auto *ip = &i;", Style); verifyFormat("void f(Concept auto const &x);", "void f(const Concept auto &x);", Style); verifyFormat("void f(std::integral auto const &x);", "void f(const std::integral auto &x);", Style); verifyFormat("auto lambda = [] { int const i = 0; };", "auto lambda = [] { const int i = 0; };", Style); verifyFormat("Foo const> P;\n#if 0\n#else\n#endif", "Foo> P;\n#if 0\n#else\n#endif", Style); verifyFormat("Bar const> P;\n#if 0\n#else\n#endif", "Bar const> P;\n#if 0\n#else\n#endif", Style); verifyFormat("Baz const> P;\n#if 0\n#else\n#endif", "Baz> P;\n#if 0\n#else\n#endif", Style); // verifyFormat("#if 0\nBoo const> P;\n#else\n#endif", // "#if 0\nBoo> P;\n#else\n#endif", Style); verifyFormat("int const P;\n#if 0\n#else\n#endif", "const int P;\n#if 0\n#else\n#endif", Style); verifyFormat("unsigned long const a;", "const unsigned long a;", Style); verifyFormat("unsigned long long const a;", "const unsigned long long a;", Style); // Multiple template parameters. verifyFormat("Bar", "Bar", Style); // Variable declaration based on template type. verifyFormat("Bar bar", "Bar bar", Style); // Using typename for a nested dependent type name. verifyFormat("typename Foo::iterator const;", "const typename Foo::iterator;", Style); // Don't move past C-style struct/class. verifyFormat("void foo(const struct A a);", Style); verifyFormat("void foo(const class A a);", Style); // Don't move past struct/class combined declaration and variable // definition. verifyFormat("const struct {\n} var;", Style); verifyFormat("struct {\n} const var;", Style); verifyFormat("const class {\n} var;", Style); verifyFormat("class {\n} const var;", Style); // Leave left qualifers unchanged for combined declaration and variable // definition. verifyFormat("volatile const class {\n} var;", Style); verifyFormat("const volatile class {\n} var;", Style); // Also do no sorting with respect to not-configured tokens. verifyFormat("const static volatile class {\n} var;", Style); // Sort right qualifiers for combined declaration and variable definition. verifyFormat("class {\n} const volatile var;", Style); verifyFormat("class {\n} const volatile var;", "class {\n} volatile const var;", Style); // Static keyword is not configured, should end up on the left of the right // side. verifyFormat("class {\n} static const volatile var;", Style); verifyFormat("class {\n} static const volatile var;", "class {\n} volatile static const var;", Style); // ::template for dependent names verifyFormat("::template Foo const volatile var;", "const volatile ::template Foo var;", Style); verifyFormat("typename ::template Foo const volatile var;", "const volatile typename ::template Foo var;", Style); verifyFormat("typename Bar::template Foo::T const;", "const typename Bar::template Foo::T;", Style); verifyFormat("typename Bar::template Foo::T const volatile;", "const volatile typename Bar::template Foo::T;", Style); // typename :: verifyFormat("typename ::Bar const;", "const typename ::Bar;", Style); // typename ::template verifyFormat("typename ::template Bar const;", "const typename ::template Bar;", Style); verifyFormat("foo const>();", "foo>();", Style); verifyFormat("foo const>();", "foo >();", Style); verifyFormat("Bar<32, Foo<25> const>;", "Bar<32, const Foo<25>>;", Style); verifyFormat("A const> const>;", "A>>;", Style); verifyFormat("A const> const>;", "A>>;", Style); // Don't move past decltype, typeof, or _Atomic. verifyFormat("const decltype(foo)", Style); verifyFormat("const typeof(foo)", Style); verifyFormat("const _Atomic(foo)", Style); // Comments const int ColumnLimit = Style.ColumnLimit; Style.ColumnLimit = 200; verifyFormat("/*c*/ Foo const *foo;", "const /*c*/ Foo *foo;", Style); verifyFormat("Foo const /*c*/ *foo;", "const Foo /*c*/ *foo;", Style); verifyFormat("Foo const * /*c*/ foo;", "const Foo * /*c*/ foo;", Style); verifyFormat("/*comment*/ std::vector const v;", "const /*comment*/ std::vector v;", Style); verifyFormat("std /*comment*/ ::vector const v;", "const std /*comment*/ ::vector v;", Style); verifyFormat("std::/*comment*/ vector const v;", "const std::/*comment*/ vector v;", Style); verifyFormat("std::vector /*comment*/ const v;", "const std::vector /*comment*/ v;", Style); verifyFormat("std::vector const v;", "const std::vector v;", Style); verifyFormat("std::vector const v;", "const std::vector v;", Style); verifyFormat("std::vector const /*comment*/ v;", "const std::vector /*comment*/ v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("typename C::template B const;", "const typename C::template B;", Style); verifyFormat("/*c*/ typename C::template B const;", "const /*c*/ typename C::template B;", Style); verifyFormat("typename /*c*/ C::template B const;", "const typename /*c*/ C::template B;", Style); verifyFormat("typename C /*c*/::template B const;", "const typename C /*c*/::template B;", Style); verifyFormat("typename C /*c*/ ::template B const;", "const typename C /*c*/ ::template B;", Style); verifyFormat("typename C::/*c*/ template B const;", "const typename C::/*c*/ template B;", Style); verifyFormat("typename C::template /*c*/ B const;", "const typename C::template /*c*/B;", Style); verifyFormat("typename C::template B const /*c*/;", "const typename C::template B/*c*/;", Style); verifyFormat("/*c*/ /*c*/ typename /*c*/ C /*c*/ /*c*/ ::/*c*/ template " "/*c*/ B /*c*/ const /*c*/ v;", "/*c*/ const /*c*/ typename /*c*/ C /*c*/ /*c*/ " "::/*c*/template /*c*/ B /*c*/ /*c*/ v;", Style); verifyFormat("/*c*/ unsigned /*c*/ long const /*c*/ a;", "const /*c*/ unsigned /*c*/ long /*c*/ a;", Style); verifyFormat("unsigned /*c*/ long /*c*/ long const a;", "const unsigned /*c*/ long /*c*/ long a;", Style); // Not changed verifyFormat("foo() /*c*/ const", Style); verifyFormat("const /*c*/ struct a;", Style); verifyFormat("const /*c*/ class a;", Style); verifyFormat("const /*c*/ decltype(v) a;", Style); verifyFormat("const /*c*/ typeof(v) a;", Style); verifyFormat("const /*c*/ _Atomic(v) a;", Style); verifyFormat("const decltype /*c*/ (v) a;", Style); verifyFormat("const /*c*/ class {\n} volatile /*c*/ foo = {};", Style); Style.ColumnLimit = ColumnLimit; // Don't adjust macros verifyFormat("const INTPTR a;", Style); // Pointers to members verifyFormat("int S::*a;", Style); verifyFormat("int const S::*a;", "const int S:: *a;", Style); verifyFormat("int const S::*const a;", "const int S::* const a;", Style); verifyFormat("int A::*const A::*p1;", Style); verifyFormat("float (C::*p)(int);", Style); verifyFormat("float (C::*const p)(int);", Style); verifyFormat("float (C::*p)(int) const;", Style); verifyFormat("float const (C::*p)(int);", "const float (C::*p)(int);", Style); } TEST_F(QualifierFixerTest, LeftQualifier) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"}; verifyFormat("const int a;", Style); verifyFormat("const int *a;", Style); verifyFormat("const int &a;", Style); verifyFormat("const int &&a;", Style); verifyFormat("const int b;", Style); verifyFormat("const int *b;", Style); verifyFormat("const int &b;", Style); verifyFormat("const int &&b;", Style); verifyFormat("const int *const b;", Style); verifyFormat("int *const c;", Style); verifyFormat("const Foo a;", Style); verifyFormat("const Foo *a;", Style); verifyFormat("const Foo &a;", Style); verifyFormat("const Foo &&a;", Style); verifyFormat("const Foo b;", Style); verifyFormat("const Foo *b;", Style); verifyFormat("const Foo &b;", Style); verifyFormat("const Foo &&b;", Style); verifyFormat("const Foo *const b;", Style); verifyFormat("Foo *const b;", Style); verifyFormat("const Foo *const b;", Style); verifyFormat("LLVM_NODISCARD const int &Foo();", Style); verifyFormat("const char a[];", Style); verifyFormat("const auto v = get_value();", Style); verifyFormat("const long long &a;", Style); verifyFormat("const unsigned char *a;", Style); verifyFormat("const unsigned char *a;", "unsigned char const *a;", Style); verifyFormat("const Foo &a", "Foo const &a", Style); verifyFormat("const Foo::iterator &a", "Foo::iterator const &a", Style); verifyFormat("const ::Foo::iterator &a", "::Foo::iterator const &a", Style); verifyFormat("const int a;", "int const a;", Style); verifyFormat("const int *a;", "int const *a;", Style); verifyFormat("const int &a;", "int const &a;", Style); verifyFormat("foo(const int &a)", "foo(int const &a)", Style); verifyFormat("unsigned char *a;", Style); verifyFormat("const unsigned int &get_nu() const", "unsigned int const &get_nu() const", Style); verifyFormat("const volatile int;", "volatile const int;", Style); verifyFormat("const volatile int;", Style); verifyFormat("const volatile int;", "const int volatile;", Style); verifyFormat("const volatile int *restrict;", "volatile const int *restrict;", Style); verifyFormat("const volatile int *restrict;", Style); verifyFormat("const volatile int *restrict;", "const int volatile *restrict;", Style); verifyFormat("const volatile long long int;", "volatile long long int const;", Style); verifyFormat("const volatile long long int;", "volatile long long const int;", Style); verifyFormat("const volatile long long int;", "long long volatile int const;", Style); verifyFormat("const volatile long long int;", "long volatile long int const;", Style); verifyFormat("const volatile long long int;", "const long long volatile int;", Style); verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY;", Style); verifyFormat("void foo() const override;", Style); verifyFormat("void foo() const override LLVM_READONLY;", Style); verifyFormat("void foo() const final;", Style); verifyFormat("void foo() const final LLVM_READONLY;", Style); verifyFormat("void foo() const LLVM_READONLY;", Style); verifyFormat( "template explicit Action(const Action &action);", Style); verifyFormat( "template explicit Action(const Action &action);", "template explicit Action(Action const &action);", Style); verifyFormat("static const int bat;", Style); verifyFormat("static const int bat;", "static int const bat;", Style); verifyFormat("static const int Foo::bat = 0;", Style); verifyFormat("static const int Foo::bat = 0;", "static int const Foo::bat = 0;", Style); verifyFormat("void fn(const Foo &i);"); verifyFormat("const int Foo::bat = 0;", Style); verifyFormat("const int Foo::bat = 0;", "int const Foo::bat = 0;", Style); verifyFormat("void fn(const Foo &i);", "void fn( Foo const &i);", Style); verifyFormat("const int Foo::fn() {", "int const Foo::fn() {", Style); verifyFormat("const Foo> *p;", "Foo> const *p;", Style); verifyFormat( "const Foo> *p = const_cast> *>(&ffi);", "const Foo> *p = const_cast> const *>(&ffi);", Style); verifyFormat("void fn(const Foo &i);", "void fn(Foo const &i);", Style); verifyFormat("void fns(const ns::S &s);", "void fns(ns::S const &s);", Style); verifyFormat("void fns(const ::ns::S &s);", "void fns(::ns::S const &s);", Style); verifyFormat("void fn(const ns::Foo &i);", "void fn(ns::Foo const &i);", Style); verifyFormat("void fns(const ns::ns2::S &s);", "void fns(ns::ns2::S const &s);", Style); verifyFormat("void fn(const ns::Foo> &i);", "void fn(ns::Foo> const &i);", Style); verifyFormat("void fn(const ns::ns2::Foo> &i);", "void fn(ns::ns2::Foo> const &i);", Style); verifyFormat("void fn(const ns::ns2::Foo> &i);", "void fn(ns::ns2::Foo> const &i);", Style); verifyFormat("const auto i = 0;", "auto const i = 0;", Style); verifyFormat("const auto &ir = i;", "auto const &ir = i;", Style); verifyFormat("const auto *ip = &i;", "auto const *ip = &i;", Style); verifyFormat("void f(const Concept auto &x);", "void f(Concept auto const &x);", Style); verifyFormat("void f(const std::integral auto &x);", "void f(std::integral auto const &x);", Style); verifyFormat("auto lambda = [] { const int i = 0; };", "auto lambda = [] { int const i = 0; };", Style); verifyFormat("Foo> P;\n#if 0\n#else\n#endif", "Foo const> P;\n#if 0\n#else\n#endif", Style); verifyFormat("Foo> P;\n#if 0\n#else\n#endif", "Foo> P;\n#if 0\n#else\n#endif", Style); verifyFormat("const int P;\n#if 0\n#else\n#endif", "int const P;\n#if 0\n#else\n#endif", Style); verifyFormat("const unsigned long a;", "unsigned long const a;", Style); verifyFormat("const unsigned long long a;", "unsigned long long const a;", Style); verifyFormat("const long long unsigned a;", "long const long unsigned a;", Style); verifyFormat("const std::Foo", Style); verifyFormat("const std::Foo<>", Style); verifyFormat("const std::Foo < int", "const std::Foo", Style); // Multiple template parameters. verifyFormat("Bar;", "Bar;", Style); // Variable declaration based on template type. verifyFormat("Bar bar;", "Bar bar;", Style); // Using typename for a dependent name. verifyFormat("const typename Foo::iterator;", "typename Foo::iterator const;", Style); // Don't move past C-style struct/class. verifyFormat("void foo(struct A const a);", Style); verifyFormat("void foo(class A const a);", Style); // Don't move past struct/class combined declaration and variable // definition. verifyFormat("const struct {\n} var;", Style); verifyFormat("struct {\n} const var;", Style); verifyFormat("const class {\n} var;", Style); verifyFormat("class {\n} const var;", Style); // Sort left qualifiers for struct/class combined declaration and variable // definition. verifyFormat("const volatile class {\n} var;", Style); verifyFormat("const volatile class {\n} var;", "volatile const class {\n} var;", Style); // Leave right qualifers unchanged for struct/class combined declaration and // variable definition. verifyFormat("class {\n} const volatile var;", Style); verifyFormat("class {\n} volatile const var;", Style); verifyFormat("foo>>();", "foo> const>();", Style); verifyFormat("foo>>();", "foo > const>();", Style); verifyFormat("Bar<32, const Foo<25>>;", "Bar<32, Foo<25> const>;", Style); verifyFormat("A>>;", "A const> const>;", Style); verifyFormat("A>>;", "A const> const>;", Style); // Don't move past decltype, typeof, or _Atomic. verifyFormat("decltype(foo) const", Style); verifyFormat("typeof(foo) const", Style); verifyFormat("_Atomic(foo) const", Style); // ::template for dependent names verifyFormat("const volatile ::template Foo var;", "::template Foo const volatile var;", Style); verifyFormat("const volatile typename ::template Foo var;", "typename ::template Foo const volatile var;", Style); verifyFormat("const typename Bar::template Foo::T;", "typename Bar::template Foo::T const;", Style); verifyFormat("const volatile typename Bar::template Foo::T;", "typename Bar::template Foo::T const volatile;", Style); // typename :: verifyFormat("const typename ::Bar;", "typename ::Bar const;", Style); // typename ::template verifyFormat("const typename ::template Bar;", "typename ::template Bar const;", Style); // Comments const int ColumnLimit = Style.ColumnLimit; Style.ColumnLimit = 200; verifyFormat("/*c*/ const Foo *foo;", "/*c*/ Foo const *foo;", Style); verifyFormat("const Foo /*c*/ *foo;", "Foo const /*c*/ *foo;", Style); verifyFormat("const Foo * /*c*/ foo;", "Foo const * /*c*/ foo;", Style); verifyFormat("/*comment*/ const std::vector v;", "/*comment*/ std::vector const v;", Style); verifyFormat("const std /*comment*/ ::vector v;", "std /*comment*/ ::vector const v;", Style); verifyFormat("const std::/*comment*/ vector v;", "std::/*comment*/ vector const v;", Style); verifyFormat("const std::vector /*comment*/ v;", "std::vector /*comment*/ const v;", Style); verifyFormat("const std::vector v;", "std::vector const v;", Style); verifyFormat("const std::vector v;", "std::vector const v;", Style); verifyFormat("const std::vector /*comment*/ v;", "std::vector /*comment*/ const v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("std::vector v;", "std::vector v;", Style); verifyFormat("const typename C::template B;", "typename C::template B const;", Style); verifyFormat("/*c*/ const typename C::template B;", "/*c*/ typename C::template B const;", Style); verifyFormat("const typename /*c*/ C::template B;", "typename /*c*/ C::template B const;", Style); verifyFormat("const typename C /*c*/::template B;", "typename C /*c*/::template B const;", Style); verifyFormat("const typename C /*c*/ ::template B;", "typename C /*c*/ ::template B const;", Style); verifyFormat("const typename C::/*c*/ template B;", "typename C::/*c*/ template B const;", Style); verifyFormat("const typename C::template /*c*/ B;", "typename C::template /*c*/ B const;", Style); verifyFormat("const typename C::template B /*c*/;", "typename C::template B /*c*/ const;", Style); verifyFormat("/*c*/ const typename /*c*/ C /*c*/ /*c*/ ::/*c*/ template " "/*c*/ B /*c*/ /*c*/ v;", "/*c*/ typename /*c*/ C /*c*/ /*c*/ ::/*c*/ template /*c*/ B " "/*c*/ /*c*/ const v;", Style); verifyFormat("const unsigned /*c*/ long /*c*/ a;", "unsigned /*c*/ long /*c*/ const a;", Style); verifyFormat("const unsigned /*c*/ long /*c*/ long a;", "unsigned /*c*/ long /*c*/ long const a;", Style); // Not changed verifyFormat("foo() /*c*/ const", Style); verifyFormat("struct /*c*/ const a;", Style); verifyFormat("class /*c*/ const a;", Style); verifyFormat("decltype(v) /*c*/ const a;", Style); verifyFormat("typeof(v) /*c*/ const a;", Style); verifyFormat("_Atomic(v) /*c*/ const a;", Style); verifyFormat("decltype /*c*/ (v) const a;", Style); verifyFormat("const /*c*/ class {\n} /*c*/ volatile /*c*/ foo = {};", Style); Style.ColumnLimit = ColumnLimit; // Don't adjust macros verifyFormat("INTPTR const a;", Style); // Pointers to members verifyFormat("int S::*a;", Style); verifyFormat("const int S::*a;", "int const S:: *a;", Style); verifyFormat("const int S::*const a;", "int const S::* const a;", Style); verifyFormat("int A::*const A::*p1;", Style); verifyFormat("float (C::*p)(int);", Style); verifyFormat("float (C::*const p)(int);", Style); verifyFormat("float (C::*p)(int) const;", Style); verifyFormat("const float (C::*p)(int);", "float const (C::*p)(int);", Style); } TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"}; // The Default EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5); verifyFormat("const volatile int a;", Style); verifyFormat("const volatile int a;", "volatile const int a;", Style); verifyFormat("const volatile int a;", "int const volatile a;", Style); verifyFormat("const volatile int a;", "int volatile const a;", Style); verifyFormat("const volatile int a;", "const int volatile a;", Style); verifyFormat("const volatile Foo a;", Style); verifyFormat("const volatile Foo a;", "volatile const Foo a;", Style); verifyFormat("const volatile Foo a;", "Foo const volatile a;", Style); verifyFormat("const volatile Foo a;", "Foo volatile const a;", Style); verifyFormat("const volatile Foo a;", "const Foo volatile a;", Style); Style.QualifierAlignment = FormatStyle::QAS_Right; Style.QualifierOrder = {"type", "const", "volatile"}; verifyFormat("int const volatile a;", "const volatile int a;", Style); verifyFormat("int const volatile a;", "volatile const int a;", Style); verifyFormat("int const volatile a;", Style); verifyFormat("int const volatile a;", "int volatile const a;", Style); verifyFormat("int const volatile a;", "const int volatile a;", Style); verifyFormat("Foo const volatile a;", "const volatile Foo a;", Style); verifyFormat("Foo const volatile a;", "volatile const Foo a;", Style); verifyFormat("Foo const volatile a;", Style); verifyFormat("Foo const volatile a;", "Foo volatile const a;", Style); verifyFormat("Foo const volatile a;", "const Foo volatile a;", Style); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"volatile", "const", "type"}; verifyFormat("volatile const int a;", "const volatile int a;", Style); verifyFormat("volatile const int a;", Style); verifyFormat("volatile const int a;", "int const volatile a;", Style); verifyFormat("volatile const int a;", "int volatile const a;", Style); verifyFormat("volatile const int a;", "const int volatile a;", Style); verifyFormat("volatile const Foo a;", "const volatile Foo a;", Style); verifyFormat("volatile const Foo a;", Style); verifyFormat("volatile const Foo a;", "Foo const volatile a;", Style); verifyFormat("volatile const Foo a;", "Foo volatile const a;", Style); verifyFormat("volatile const Foo a;", "const Foo volatile a;", Style); Style.QualifierAlignment = FormatStyle::QAS_Right; Style.QualifierOrder = {"type", "volatile", "const"}; verifyFormat("int volatile const a;", "const volatile int a;", Style); verifyFormat("int volatile const a;", "volatile const int a;", Style); verifyFormat("int volatile const a;", "int const volatile a;", Style); verifyFormat("int volatile const a;", Style); verifyFormat("int volatile const a;", "const int volatile a;", Style); verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style); verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style); verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style); verifyFormat("Foo volatile const a;", Style); verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"type", "volatile", "const"}; verifyFormat("int volatile const a;", "const volatile int a;", Style); verifyFormat("int volatile const a;", "volatile const int a;", Style); verifyFormat("int volatile const a;", "int const volatile a;", Style); verifyFormat("int volatile const a;", Style); verifyFormat("int volatile const a;", "const int volatile a;", Style); verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style); verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style); verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style); verifyFormat("Foo volatile const a;", Style); verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style); } TEST_F(QualifierFixerTest, InlineStatics) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"}; EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5); verifyFormat("inline static const volatile int a;", "const inline static volatile int a;", Style); verifyFormat("inline static const volatile int a;", "volatile inline static const int a;", Style); verifyFormat("inline static const volatile int a;", "int const inline static volatile a;", Style); verifyFormat("inline static const volatile int a;", "int volatile inline static const a;", Style); verifyFormat("inline static const volatile int a;", "const int inline static volatile a;", Style); } TEST_F(QualifierFixerTest, AmpEqual) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "type", "const"}; EXPECT_EQ(Style.QualifierOrder.size(), (size_t)3); verifyFormat("foo(std::string const & = std::string()) const", "foo(const std::string & = std::string()) const", Style); verifyFormat("foo(std::string const & = std::string())", "foo(const std::string & = std::string())", Style); } TEST_F(QualifierFixerTest, MoveConstBeyondTypeSmall) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"type", "const"}; EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2); verifyFormat("int const a;", "const int a;", Style); verifyFormat("int const *a;", "const int*a;", Style); verifyFormat("int const *a;", "const int *a;", Style); verifyFormat("int const &a;", "const int &a;", Style); verifyFormat("int const &&a;", "const int &&a;", Style); } TEST_F(QualifierFixerTest, MoveConstBeforeTypeSmall) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"const", "type"}; EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2); verifyFormat("const int a;", "int const a;", Style); verifyFormat("const int *a;", "int const *a;", Style); verifyFormat("const int *const a;", "int const *const a;", Style); verifyFormat("const int a = foo();", "int const a = foo();", Style); verifyFormat("const int *a = foo();", "int const *a = foo();", Style); verifyFormat("const int *const a = foo();", "int const *const a = foo();", Style); verifyFormat("const auto a = foo();", "auto const a = foo();", Style); verifyFormat("const auto *a = foo();", "auto const *a = foo();", Style); verifyFormat("const auto *const a = foo();", "auto const *const a = foo();", Style); } TEST_F(QualifierFixerTest, MoveConstBeyondType) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"}; EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5); verifyFormat("static inline int const volatile a;", "const inline static volatile int a;", Style); verifyFormat("static inline int const volatile a;", "volatile inline static const int a;", Style); verifyFormat("static inline int const volatile a;", "int const inline static volatile a;", Style); verifyFormat("static inline int const volatile a;", "int volatile inline static const a;", Style); verifyFormat("static inline int const volatile a;", "const int inline static volatile a;", Style); verifyFormat("static inline int const volatile *const a;", "const int inline static volatile *const a;", Style); verifyFormat("static inline Foo const volatile a;", "const inline static volatile Foo a;", Style); verifyFormat("static inline Foo const volatile a;", "volatile inline static const Foo a;", Style); verifyFormat("static inline Foo const volatile a;", "Foo const inline static volatile a;", Style); verifyFormat("static inline Foo const volatile a;", "Foo volatile inline static const a;", Style); verifyFormat("static inline Foo const volatile a;", "const Foo inline static volatile a;", Style); verifyFormat("static inline Foo const volatile *const a;", "const Foo inline static volatile *const a;", Style); } TEST_F(QualifierFixerTest, PrepareLeftRightOrdering) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"}; std::vector Left; std::vector Right; std::vector ConfiguredTokens; prepareLeftRightOrderingForQualifierAlignmentFixer(Style.QualifierOrder, Left, Right, ConfiguredTokens); EXPECT_EQ(Left.size(), (size_t)2); EXPECT_EQ(Right.size(), (size_t)2); std::vector LeftResult = {"inline", "static"}; std::vector RightResult = {"const", "volatile"}; EXPECT_EQ(Left, LeftResult); EXPECT_EQ(Right, RightResult); } TEST_F(QualifierFixerTest, IsQualifierType) { std::vector ConfiguredTokens; ConfiguredTokens.push_back(tok::kw_const); ConfiguredTokens.push_back(tok::kw_static); ConfiguredTokens.push_back(tok::kw_inline); ConfiguredTokens.push_back(tok::kw_restrict); ConfiguredTokens.push_back(tok::kw_constexpr); ConfiguredTokens.push_back(tok::kw_friend); auto Tokens = annotate( "const static inline auto restrict int double long constexpr friend"); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[0], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[1], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[2], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[3], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[4], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[5], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[6], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[7], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[8], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( Tokens[9], ConfiguredTokens)); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[0])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[1])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[2])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[3])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[4])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[5])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[6])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[7])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[8])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(Tokens[9])); auto NotTokens = annotate("for while do Foo Bar "); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[0], ConfiguredTokens)); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[1], ConfiguredTokens)); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[2], ConfiguredTokens)); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[3], ConfiguredTokens)); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[4], ConfiguredTokens)); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( NotTokens[5], ConfiguredTokens)); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[0])); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[1])); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[2])); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[3])); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[4])); EXPECT_FALSE( LeftRightQualifierAlignmentFixer::isQualifierOrType(NotTokens[5])); } TEST_F(QualifierFixerTest, IsMacro) { auto Tokens = annotate("INT INTPR Foo int"); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[0])); EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[1])); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[2])); EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[3])); } TEST_F(QualifierFixerTest, OverlappingQualifier) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"const", "type"}; verifyFormat("Foo(const Bar &name);", "Foo(Bar const &name);", Style); } TEST_F(QualifierFixerTest, DontPushQualifierThroughNonSpecifiedTypes) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"const", "volatile", "type"}; verifyFormat("inline static const int a;", Style); Style.QualifierOrder = {"static", "const", "type"}; verifyFormat("inline static const int a;", Style); verifyFormat("static inline const int a;", Style); verifyFormat("static const int a;", "const static int a;", Style); Style.QualifierOrder = {"const", "volatile", "type"}; // static is not configured, unchanged at right hand qualifiers. verifyFormat("const volatile int static;", "int volatile static const;", Style); verifyFormat("const volatile int static;", "int const static volatile;", Style); verifyFormat("const volatile int static;", "const int static volatile;", Style); verifyFormat("const volatile Foo static;", "Foo volatile static const;", Style); verifyFormat("const volatile Foo static;", "Foo const static volatile;", Style); verifyFormat("const volatile Foo static;", "const Foo static volatile;", Style); verifyFormat("inline static const Foo;", "inline static Foo const;", Style); verifyFormat("inline static const Foo;", Style); // Don't move qualifiers to the right for aestethics only. verifyFormat("inline const static Foo;", Style); verifyFormat("const inline static Foo;", Style); } TEST_F(QualifierFixerTest, UnsignedQualifier) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Left; Style.QualifierOrder = {"const", "type"}; verifyFormat("Foo(const unsigned char *bytes)", "Foo(unsigned const char *bytes)", Style); Style.QualifierAlignment = FormatStyle::QAS_Right; Style.QualifierOrder = {"type", "const"}; verifyFormat("Foo(unsigned char const *bytes)", "Foo(unsigned const char *bytes)", Style); } TEST_F(QualifierFixerTest, NoOpQualifierReplacements) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "const", "type"}; verifyFormat("static const uint32 foo[] = {0, 31};", Style); EXPECT_EQ(ReplacementCount, 0); verifyFormat("#define MACRO static const", Style); EXPECT_EQ(ReplacementCount, 0); verifyFormat("using sc = static const", Style); EXPECT_EQ(ReplacementCount, 0); } TEST_F(QualifierFixerTest, QualifierTemplates) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"static", "const", "type"}; ReplacementCount = 0; EXPECT_EQ(ReplacementCount, 0); verifyFormat("using A = B<>;", Style); verifyFormat("using A = B /**/<>;", Style); verifyFormat("template using A = B, 1>;", Style); verifyFormat("template using A = B /**/, 1>;", Style); verifyFormat("template using A = B /* */, 1>;", Style); verifyFormat("template using A = B /*foo*/, 1>;", Style); verifyFormat("template using A = B /**/ /**/, 1>;", Style); verifyFormat("template using A = B, 1>;", Style); verifyFormat("template using A = /**/ B, 1>;", Style); EXPECT_EQ(ReplacementCount, 0); verifyFormat("template \n" "using A = B // foo\n" " , 1>;", Style); ReplacementCount = 0; Style.QualifierOrder = {"type", "static", "const"}; verifyFormat("using A = B<>;", Style); verifyFormat("using A = B /**/<>;", Style); verifyFormat("template using A = B, 1>;", Style); verifyFormat("template using A = B /**/, 1>;", Style); verifyFormat("template using A = B /* */, 1>;", Style); verifyFormat("template using A = B /*foo*/, 1>;", Style); verifyFormat("template using A = B /**/ /**/, 1>;", Style); verifyFormat("template using A = B, 1>;", Style); verifyFormat("template using A = /**/ B, 1>;", Style); EXPECT_EQ(ReplacementCount, 0); verifyFormat("template \n" "using A = B // foo\n" " , 1>;", Style); } TEST_F(QualifierFixerTest, WithConstraints) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"constexpr", "type"}; verifyFormat("template \n" " requires Concept\n" "constexpr constructor();", Style); verifyFormat("template \n" " requires Concept1 && Concept2\n" "constexpr constructor();", Style); } TEST_F(QualifierFixerTest, DisableRegions) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"inline", "static", "const", "type"}; ReplacementCount = 0; verifyFormat("// clang-format off\n" "int const inline static a = 0;\n" "// clang-format on", Style); EXPECT_EQ(ReplacementCount, 0); verifyFormat("// clang-format off\n" "int const inline static a = 0;\n" "// clang-format on\n" "inline static const int a = 0;", "// clang-format off\n" "int const inline static a = 0;\n" "// clang-format on\n" "int const inline static a = 0;", Style); } TEST_F(QualifierFixerTest, TemplatesRight) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"type", "const"}; verifyFormat("template Foo const f();", "template const Foo f();", Style); verifyFormat("template int const f();", "template const int f();", Style); verifyFormat("template t;", "template t;", Style); verifyFormat("template \n" " requires Concept\n" "Foo const f();", "template \n" " requires Concept\n" "const Foo f();", Style); verifyFormat("TemplateType t;", "TemplateType t;", Style); verifyFormat("TemplateType t;", "TemplateType t;", Style); } TEST_F(QualifierFixerTest, TemplatesLeft) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"const", "volatile", "type"}; verifyFormat("template const Foo f();", "template Foo const f();", Style); verifyFormat("template const int f();", "template int const f();", Style); verifyFormat("template t;", "template t;", Style); verifyFormat("template \n" " requires Concept\n" "const Foo f();", "template \n" " requires Concept\n" "Foo const f();", Style); verifyFormat("template \n" " requires Concept\n" "const volatile Foo f();", "template \n" " requires Concept\n" "volatile const Foo f();", Style); verifyFormat("TemplateType t;", "TemplateType t;", Style); verifyFormat("TemplateType t;", "TemplateType t;", Style); } TEST_F(QualifierFixerTest, Ranges) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; Style.QualifierOrder = {"const", "volatile", "type"}; // Only the first line should be formatted; the second should remain as is. verifyFormat("template const Foo f();\n" "template Foo const f();", "template Foo const f();\n" "template Foo const f();", Style, {tooling::Range(0, 36)}); // Only the middle line should be formatted; the first and last should remain // as is. verifyFormat("template Foo const f();\n" "template const Foo f();\n" "template Foo const f();", "template Foo const f();\n" "template Foo const f();\n" "template Foo const f();", Style, {tooling::Range(37, 36)}); } } // namespace } // namespace test } // namespace format } // namespace clang