xref: /llvm-project/clang/unittests/Format/QualifierFixerTest.cpp (revision 3bd8b02aa0c5fcbb005f6d72f58f4a05421e7823)
1a44ab170Smydeveloperday //===- unittest/Format/QualifierFixerTest.cpp - Formatting unit tests -----===//
2a44ab170Smydeveloperday //
3a44ab170Smydeveloperday // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a44ab170Smydeveloperday // See https://llvm.org/LICENSE.txt for license information.
5a44ab170Smydeveloperday // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a44ab170Smydeveloperday //
7a44ab170Smydeveloperday //===----------------------------------------------------------------------===//
8a44ab170Smydeveloperday 
9f8d10d5aSManuel Klimek #include "../lib/Format/QualifierAlignmentFixer.h"
10f8d10d5aSManuel Klimek #include "FormatTestBase.h"
11a44ab170Smydeveloperday #include "TestLexer.h"
12a44ab170Smydeveloperday 
13a44ab170Smydeveloperday #define DEBUG_TYPE "format-qualifier-fixer-test"
14a44ab170Smydeveloperday 
15a44ab170Smydeveloperday namespace clang {
16a44ab170Smydeveloperday namespace format {
17f8d10d5aSManuel Klimek namespace test {
18a44ab170Smydeveloperday namespace {
19a44ab170Smydeveloperday 
20a44ab170Smydeveloperday #define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \
21a44ab170Smydeveloperday   EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!";          \
22a44ab170Smydeveloperday   EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \
23a44ab170Smydeveloperday   EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
24a44ab170Smydeveloperday 
25a44ab170Smydeveloperday #define FAIL_PARSE(TEXT, FIELD, VALUE)                                         \
26a44ab170Smydeveloperday   EXPECT_NE(0, parseConfiguration(TEXT, &Style).value());                      \
27a44ab170Smydeveloperday   EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
28a44ab170Smydeveloperday 
29f8d10d5aSManuel Klimek class QualifierFixerTest : public FormatTestBase {
30a44ab170Smydeveloperday protected:
311c58208dSOwen Pan   TokenList annotate(StringRef Code,
32a44ab170Smydeveloperday                      const FormatStyle &Style = getLLVMStyle()) {
33a44ab170Smydeveloperday     return TestLexer(Allocator, Buffers, Style).annotate(Code);
34a44ab170Smydeveloperday   }
35a44ab170Smydeveloperday   llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
36a44ab170Smydeveloperday   std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
37a44ab170Smydeveloperday };
38a44ab170Smydeveloperday 
39a44ab170Smydeveloperday TEST_F(QualifierFixerTest, RotateTokens) {
40a44ab170Smydeveloperday   // TODO add test
41a44ab170Smydeveloperday   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("const"),
42a44ab170Smydeveloperday             tok::kw_const);
43a44ab170Smydeveloperday   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("volatile"),
44a44ab170Smydeveloperday             tok::kw_volatile);
45a44ab170Smydeveloperday   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("inline"),
46a44ab170Smydeveloperday             tok::kw_inline);
47a44ab170Smydeveloperday   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("static"),
48a44ab170Smydeveloperday             tok::kw_static);
49a44ab170Smydeveloperday   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("restrict"),
50a44ab170Smydeveloperday             tok::kw_restrict);
514cafc372SMicah Weston   EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("friend"),
524cafc372SMicah Weston             tok::kw_friend);
53a44ab170Smydeveloperday }
54a44ab170Smydeveloperday 
55a44ab170Smydeveloperday TEST_F(QualifierFixerTest, FailQualifierInvalidConfiguration) {
56a44ab170Smydeveloperday   FormatStyle Style = {};
57a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
58a44ab170Smydeveloperday   FAIL_PARSE("QualifierAlignment: Custom\n"
59a44ab170Smydeveloperday              "QualifierOrder: [const, volatile, apples, type]",
60a44ab170Smydeveloperday              QualifierOrder,
61a44ab170Smydeveloperday              std::vector<std::string>({"const", "volatile", "apples", "type"}));
62a44ab170Smydeveloperday }
63a44ab170Smydeveloperday 
64a44ab170Smydeveloperday TEST_F(QualifierFixerTest, FailQualifierDuplicateConfiguration) {
65a44ab170Smydeveloperday   FormatStyle Style = {};
66a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
67a44ab170Smydeveloperday   FAIL_PARSE("QualifierAlignment: Custom\n"
68a44ab170Smydeveloperday              "QualifierOrder: [const, volatile, const, type]",
69a44ab170Smydeveloperday              QualifierOrder,
70a44ab170Smydeveloperday              std::vector<std::string>({"const", "volatile", "const", "type"}));
71a44ab170Smydeveloperday }
72a44ab170Smydeveloperday 
73a44ab170Smydeveloperday TEST_F(QualifierFixerTest, FailQualifierMissingType) {
74a44ab170Smydeveloperday   FormatStyle Style = {};
75a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
76a44ab170Smydeveloperday   FAIL_PARSE("QualifierAlignment: Custom\n"
77a44ab170Smydeveloperday              "QualifierOrder: [const, volatile ]",
78a44ab170Smydeveloperday              QualifierOrder,
79a44ab170Smydeveloperday              std::vector<std::string>({
80a44ab170Smydeveloperday                  "const",
81a44ab170Smydeveloperday                  "volatile",
82a44ab170Smydeveloperday              }));
83a44ab170Smydeveloperday }
84a44ab170Smydeveloperday 
85a44ab170Smydeveloperday TEST_F(QualifierFixerTest, FailQualifierEmptyOrder) {
86a44ab170Smydeveloperday   FormatStyle Style = {};
87a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
88a44ab170Smydeveloperday   FAIL_PARSE("QualifierAlignment: Custom\nQualifierOrder: []", QualifierOrder,
89a44ab170Smydeveloperday              std::vector<std::string>({}));
90a44ab170Smydeveloperday }
91a44ab170Smydeveloperday 
92a44ab170Smydeveloperday TEST_F(QualifierFixerTest, FailQualifierMissingOrder) {
93a44ab170Smydeveloperday   FormatStyle Style = {};
94a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
95a44ab170Smydeveloperday   FAIL_PARSE("QualifierAlignment: Custom", QualifierOrder,
96a44ab170Smydeveloperday              std::vector<std::string>());
97a44ab170Smydeveloperday }
98a44ab170Smydeveloperday 
99a44ab170Smydeveloperday TEST_F(QualifierFixerTest, QualifierLeft) {
100a44ab170Smydeveloperday   FormatStyle Style = {};
101a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
102a44ab170Smydeveloperday   CHECK_PARSE("QualifierAlignment: Left", QualifierOrder,
103a44ab170Smydeveloperday               std::vector<std::string>({"const", "volatile", "type"}));
104a44ab170Smydeveloperday }
105a44ab170Smydeveloperday 
106a44ab170Smydeveloperday TEST_F(QualifierFixerTest, QualifierRight) {
107a44ab170Smydeveloperday   FormatStyle Style = {};
108a44ab170Smydeveloperday   Style.Language = FormatStyle::LK_Cpp;
109a44ab170Smydeveloperday   CHECK_PARSE("QualifierAlignment: Right", QualifierOrder,
110a44ab170Smydeveloperday               std::vector<std::string>({"type", "const", "volatile"}));
111a44ab170Smydeveloperday }
112a44ab170Smydeveloperday 
113a44ab170Smydeveloperday TEST_F(QualifierFixerTest, QualifiersCustomOrder) {
114a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
115a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
1164cafc372SMicah Weston   Style.QualifierOrder = {"friend", "inline",   "constexpr", "static",
117a44ab170Smydeveloperday                           "const",  "volatile", "type"};
118a44ab170Smydeveloperday 
11920b4df1eSOwen Pan   verifyFormat("const volatile int a;", Style);
120a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "volatile const int a;", Style);
121a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "int const volatile a;", Style);
122a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "int volatile const a;", Style);
123a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "const int volatile a;", Style);
124a44ab170Smydeveloperday 
125a44ab170Smydeveloperday   verifyFormat("static const volatile int a;", "const static int volatile a;",
126a44ab170Smydeveloperday                Style);
127a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
128a44ab170Smydeveloperday                "const static inline int volatile a;", Style);
129a44ab170Smydeveloperday 
130a44ab170Smydeveloperday   verifyFormat("constexpr static int a;", "static constexpr int a;", Style);
131a44ab170Smydeveloperday   verifyFormat("constexpr static int A;", "static constexpr int A;", Style);
132a44ab170Smydeveloperday   verifyFormat("constexpr static int Bar;", "static constexpr int Bar;", Style);
133a44ab170Smydeveloperday   verifyFormat("constexpr static LPINT Bar;", "static constexpr LPINT Bar;",
134a44ab170Smydeveloperday                Style);
135a44ab170Smydeveloperday   verifyFormat("const const int a;", "const int const a;", Style);
1364cafc372SMicah Weston 
1374cafc372SMicah Weston   verifyFormat(
1384cafc372SMicah Weston       "friend constexpr auto operator<=>(const foo &, const foo &) = default;",
1394cafc372SMicah Weston       "constexpr friend auto operator<=>(const foo &, const foo &) = default;",
1404cafc372SMicah Weston       Style);
1414cafc372SMicah Weston   verifyFormat(
1424cafc372SMicah Weston       "friend constexpr bool operator==(const foo &, const foo &) = default;",
1434cafc372SMicah Weston       "constexpr bool friend operator==(const foo &, const foo &) = default;",
1444cafc372SMicah Weston       Style);
145a44ab170Smydeveloperday }
146a44ab170Smydeveloperday 
147a44ab170Smydeveloperday TEST_F(QualifierFixerTest, LeftRightQualifier) {
148a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
149a44ab170Smydeveloperday 
150a44ab170Smydeveloperday   // keep the const style unaltered
151a44ab170Smydeveloperday   verifyFormat("const int a;", Style);
152a44ab170Smydeveloperday   verifyFormat("const int *a;", Style);
153a44ab170Smydeveloperday   verifyFormat("const int &a;", Style);
154a44ab170Smydeveloperday   verifyFormat("const int &&a;", Style);
155a44ab170Smydeveloperday   verifyFormat("int const b;", Style);
156a44ab170Smydeveloperday   verifyFormat("int const *b;", Style);
157a44ab170Smydeveloperday   verifyFormat("int const &b;", Style);
158a44ab170Smydeveloperday   verifyFormat("int const &&b;", Style);
159cd7ab4b5SAlexander Hederstaf   verifyFormat("int const *const b;", Style);
160a44ab170Smydeveloperday   verifyFormat("int *const c;", Style);
161a44ab170Smydeveloperday 
162a44ab170Smydeveloperday   verifyFormat("const Foo a;", Style);
163a44ab170Smydeveloperday   verifyFormat("const Foo *a;", Style);
164a44ab170Smydeveloperday   verifyFormat("const Foo &a;", Style);
165a44ab170Smydeveloperday   verifyFormat("const Foo &&a;", Style);
166a44ab170Smydeveloperday   verifyFormat("Foo const b;", Style);
167a44ab170Smydeveloperday   verifyFormat("Foo const *b;", Style);
168a44ab170Smydeveloperday   verifyFormat("Foo const &b;", Style);
169a44ab170Smydeveloperday   verifyFormat("Foo const &&b;", Style);
170cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const *const b;", Style);
171a44ab170Smydeveloperday 
172a44ab170Smydeveloperday   verifyFormat("LLVM_NODISCARD const int &Foo();", Style);
173a44ab170Smydeveloperday   verifyFormat("LLVM_NODISCARD int const &Foo();", Style);
174a44ab170Smydeveloperday 
175a44ab170Smydeveloperday   verifyFormat("volatile const int *restrict;", Style);
176a44ab170Smydeveloperday   verifyFormat("const volatile int *restrict;", Style);
177a44ab170Smydeveloperday   verifyFormat("const int volatile *restrict;", Style);
178a44ab170Smydeveloperday }
179a44ab170Smydeveloperday 
180a44ab170Smydeveloperday TEST_F(QualifierFixerTest, RightQualifier) {
181a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
182a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Right;
183a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "const", "volatile"};
184a44ab170Smydeveloperday 
185a44ab170Smydeveloperday   verifyFormat("int const a;", Style);
186a44ab170Smydeveloperday   verifyFormat("int const *a;", Style);
187a44ab170Smydeveloperday   verifyFormat("int const &a;", Style);
188a44ab170Smydeveloperday   verifyFormat("int const &&a;", Style);
189a44ab170Smydeveloperday   verifyFormat("int const b;", Style);
190a44ab170Smydeveloperday   verifyFormat("int const *b;", Style);
191a44ab170Smydeveloperday   verifyFormat("int const &b;", Style);
192a44ab170Smydeveloperday   verifyFormat("int const &&b;", Style);
193cd7ab4b5SAlexander Hederstaf   verifyFormat("int const *const b;", Style);
194a44ab170Smydeveloperday   verifyFormat("int *const c;", Style);
195a44ab170Smydeveloperday 
196a44ab170Smydeveloperday   verifyFormat("Foo const a;", Style);
197a44ab170Smydeveloperday   verifyFormat("Foo const *a;", Style);
198a44ab170Smydeveloperday   verifyFormat("Foo const &a;", Style);
199a44ab170Smydeveloperday   verifyFormat("Foo const &&a;", Style);
200a44ab170Smydeveloperday   verifyFormat("Foo const b;", Style);
201a44ab170Smydeveloperday   verifyFormat("Foo const *b;", Style);
202a44ab170Smydeveloperday   verifyFormat("Foo const &b;", Style);
203a44ab170Smydeveloperday   verifyFormat("Foo const &&b;", Style);
204cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const *const b;", Style);
205a44ab170Smydeveloperday   verifyFormat("Foo *const b;", Style);
206a44ab170Smydeveloperday   verifyFormat("Foo const *const b;", Style);
207a44ab170Smydeveloperday   verifyFormat("auto const v = get_value();", Style);
208a44ab170Smydeveloperday   verifyFormat("long long const &a;", Style);
209a44ab170Smydeveloperday   verifyFormat("unsigned char const *a;", Style);
210a44ab170Smydeveloperday   verifyFormat("int main(int const argc, char const *const *const argv)",
211a44ab170Smydeveloperday                Style);
212a44ab170Smydeveloperday 
213a44ab170Smydeveloperday   verifyFormat("LLVM_NODISCARD int const &Foo();", Style);
214a44ab170Smydeveloperday   verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY",
215a44ab170Smydeveloperday                Style);
216a44ab170Smydeveloperday   verifyFormat("void foo() const override;", Style);
217a44ab170Smydeveloperday   verifyFormat("void foo() const override LLVM_READONLY;", Style);
218a44ab170Smydeveloperday   verifyFormat("void foo() const final;", Style);
219a44ab170Smydeveloperday   verifyFormat("void foo() const final LLVM_READONLY;", Style);
220a44ab170Smydeveloperday   verifyFormat("void foo() const LLVM_READONLY;", Style);
221cd7ab4b5SAlexander Hederstaf   verifyFormat("void foo() const volatile override;", Style);
222cd7ab4b5SAlexander Hederstaf   verifyFormat("void foo() const volatile override LLVM_READONLY;", Style);
223cd7ab4b5SAlexander Hederstaf   verifyFormat("void foo() const volatile final;", Style);
224cd7ab4b5SAlexander Hederstaf   verifyFormat("void foo() const volatile final LLVM_READONLY;", Style);
225cd7ab4b5SAlexander Hederstaf   verifyFormat("void foo() const volatile LLVM_READONLY;", Style);
226a44ab170Smydeveloperday 
227a44ab170Smydeveloperday   verifyFormat(
228a44ab170Smydeveloperday       "template <typename Func> explicit Action(Action<Func> const &action);",
229a44ab170Smydeveloperday       Style);
230a44ab170Smydeveloperday   verifyFormat(
231a44ab170Smydeveloperday       "template <typename Func> explicit Action(Action<Func> const &action);",
232a44ab170Smydeveloperday       "template <typename Func> explicit Action(const Action<Func>& action);",
233a44ab170Smydeveloperday       Style);
234a44ab170Smydeveloperday   verifyFormat(
235a44ab170Smydeveloperday       "template <typename Func> explicit Action(Action<Func> const &action);",
236a44ab170Smydeveloperday       "template <typename Func>\nexplicit Action(const Action<Func>& action);",
237a44ab170Smydeveloperday       Style);
238a44ab170Smydeveloperday 
239a44ab170Smydeveloperday   verifyFormat("int const a;", "const int a;", Style);
240a44ab170Smydeveloperday   verifyFormat("int const *a;", "const int *a;", Style);
241a44ab170Smydeveloperday   verifyFormat("int const &a;", "const int &a;", Style);
242a44ab170Smydeveloperday   verifyFormat("foo(int const &a)", "foo(const int &a)", Style);
24320b4df1eSOwen Pan   verifyFormat("unsigned char *a;", Style);
244a44ab170Smydeveloperday   verifyFormat("unsigned char const *a;", "const unsigned char *a;", Style);
245a44ab170Smydeveloperday   verifyFormat("vector<int, int const, int &, int const &> args1",
246a44ab170Smydeveloperday                "vector<int, const int, int &, const int &> args1", Style);
247a44ab170Smydeveloperday   verifyFormat("unsigned int const &get_nu() const",
248a44ab170Smydeveloperday                "const unsigned int &get_nu() const", Style);
249a44ab170Smydeveloperday   verifyFormat("Foo<int> const &a", "const Foo<int> &a", Style);
250a44ab170Smydeveloperday   verifyFormat("Foo<int>::iterator const &a", "const Foo<int>::iterator &a",
251a44ab170Smydeveloperday                Style);
252d4d28f2aSMarek Kurdej   verifyFormat("::Foo<int>::iterator const &a", "const ::Foo<int>::iterator &a",
253d4d28f2aSMarek Kurdej                Style);
254a44ab170Smydeveloperday 
255a44ab170Smydeveloperday   verifyFormat("Foo(int a, "
256a44ab170Smydeveloperday                "unsigned b, // c-style args\n"
257a44ab170Smydeveloperday                "    Bar const &c);",
258a44ab170Smydeveloperday                "Foo(int a, "
259a44ab170Smydeveloperday                "unsigned b, // c-style args\n"
260a44ab170Smydeveloperday                "    const Bar &c);",
261a44ab170Smydeveloperday                Style);
262a44ab170Smydeveloperday 
263a44ab170Smydeveloperday   verifyFormat("int const volatile;", "volatile const int;", Style);
264a44ab170Smydeveloperday   verifyFormat("int const volatile;", "const volatile int;", Style);
265a44ab170Smydeveloperday   verifyFormat("int const volatile;", "const int volatile;", Style);
266cd7ab4b5SAlexander Hederstaf 
267a44ab170Smydeveloperday   verifyFormat("int const volatile *restrict;", "volatile const int *restrict;",
268a44ab170Smydeveloperday                Style);
269a44ab170Smydeveloperday   verifyFormat("int const volatile *restrict;", "const volatile int *restrict;",
270a44ab170Smydeveloperday                Style);
271a44ab170Smydeveloperday   verifyFormat("int const volatile *restrict;", "const int volatile *restrict;",
272a44ab170Smydeveloperday                Style);
273a44ab170Smydeveloperday 
274cd7ab4b5SAlexander Hederstaf   verifyFormat("long long int const volatile;", "const long long int volatile;",
275cd7ab4b5SAlexander Hederstaf                Style);
276cd7ab4b5SAlexander Hederstaf   verifyFormat("long long int const volatile;", "long const long int volatile;",
277cd7ab4b5SAlexander Hederstaf                Style);
278cd7ab4b5SAlexander Hederstaf   verifyFormat("long long int const volatile;", "long long volatile int const;",
279cd7ab4b5SAlexander Hederstaf                Style);
280cd7ab4b5SAlexander Hederstaf   verifyFormat("long long int const volatile;", "long volatile long const int;",
281cd7ab4b5SAlexander Hederstaf                Style);
282cd7ab4b5SAlexander Hederstaf   verifyFormat("long long int const volatile;", "const long long volatile int;",
283cd7ab4b5SAlexander Hederstaf                Style);
284cd7ab4b5SAlexander Hederstaf 
285a44ab170Smydeveloperday   verifyFormat("static int const bat;", "static const int bat;", Style);
28620b4df1eSOwen Pan   verifyFormat("static int const bat;", Style);
287a44ab170Smydeveloperday 
288cd7ab4b5SAlexander Hederstaf   // static is not configured, unchanged on the left of the right hand
289cd7ab4b5SAlexander Hederstaf   // qualifiers.
290cd7ab4b5SAlexander Hederstaf   verifyFormat("int static const volatile;", "volatile const int static;",
291cd7ab4b5SAlexander Hederstaf                Style);
292cd7ab4b5SAlexander Hederstaf   verifyFormat("int static const volatile;", "const volatile int static;",
293cd7ab4b5SAlexander Hederstaf                Style);
294cd7ab4b5SAlexander Hederstaf   verifyFormat("int static const volatile;", "const int volatile static;",
295cd7ab4b5SAlexander Hederstaf                Style);
296cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo static const volatile;", "volatile const Foo static;",
297cd7ab4b5SAlexander Hederstaf                Style);
298cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo static const volatile;", "const volatile Foo static;",
299cd7ab4b5SAlexander Hederstaf                Style);
300cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo static const volatile;", "const Foo volatile static;",
301cd7ab4b5SAlexander Hederstaf                Style);
302cd7ab4b5SAlexander Hederstaf 
303cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo inline static const;", "const Foo inline static;", Style);
304cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo inline static const;", "Foo const inline static;", Style);
305cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo inline static const;", "Foo inline const static;", Style);
30620b4df1eSOwen Pan   verifyFormat("Foo inline static const;", Style);
307cd7ab4b5SAlexander Hederstaf 
308cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A::*;",
309cd7ab4b5SAlexander Hederstaf                "volatile const Foo<volatile T>::Bar<const Type, 5> A::*;",
310cd7ab4b5SAlexander Hederstaf                Style);
311cd7ab4b5SAlexander Hederstaf 
312a44ab170Smydeveloperday   verifyFormat("int const Foo<int>::bat = 0;", "const int Foo<int>::bat = 0;",
313a44ab170Smydeveloperday                Style);
31420b4df1eSOwen Pan   verifyFormat("int const Foo<int>::bat = 0;", Style);
315a44ab170Smydeveloperday   verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);
31620b4df1eSOwen Pan   verifyFormat("int const Foo<int>::fn() {", Style);
317a44ab170Smydeveloperday   verifyFormat("Foo<Foo<int>> const *p;", "const Foo<Foo<int>> *p;", Style);
318a44ab170Smydeveloperday   verifyFormat(
319a44ab170Smydeveloperday       "Foo<Foo<int>> const *p = const_cast<Foo<Foo<int>> const *>(&ffi);",
320a44ab170Smydeveloperday       "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",
321a44ab170Smydeveloperday       Style);
322a44ab170Smydeveloperday 
323a44ab170Smydeveloperday   verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);
324a44ab170Smydeveloperday   verifyFormat("void fns(ns::S const &s);", "void fns(const ns::S &s);", Style);
325d4d28f2aSMarek Kurdej   verifyFormat("void fns(::ns::S const &s);", "void fns(const ::ns::S &s);",
326d4d28f2aSMarek Kurdej                Style);
327a44ab170Smydeveloperday   verifyFormat("void fn(ns::Foo<T> const &i);", "void fn(const ns::Foo<T> &i);",
328a44ab170Smydeveloperday                Style);
329a44ab170Smydeveloperday   verifyFormat("void fns(ns::ns2::S const &s);",
330a44ab170Smydeveloperday                "void fns(const ns::ns2::S &s);", Style);
331a44ab170Smydeveloperday   verifyFormat("void fn(ns::Foo<Bar<T>> const &i);",
332a44ab170Smydeveloperday                "void fn(const ns::Foo<Bar<T>> &i);", Style);
333a44ab170Smydeveloperday   verifyFormat("void fn(ns::ns2::Foo<Bar<T>> const &i);",
334a44ab170Smydeveloperday                "void fn(const ns::ns2::Foo<Bar<T>> &i);", Style);
335a44ab170Smydeveloperday   verifyFormat("void fn(ns::ns2::Foo<Bar<T, U>> const &i);",
336a44ab170Smydeveloperday                "void fn(const ns::ns2::Foo<Bar<T, U>> &i);", Style);
337a44ab170Smydeveloperday 
338a44ab170Smydeveloperday   verifyFormat("LocalScope const *Scope = nullptr;",
339a44ab170Smydeveloperday                "const LocalScope* Scope = nullptr;", Style);
340a44ab170Smydeveloperday   verifyFormat("struct DOTGraphTraits<Stmt const *>",
341a44ab170Smydeveloperday                "struct DOTGraphTraits<const Stmt *>", Style);
342a44ab170Smydeveloperday 
343a44ab170Smydeveloperday   verifyFormat(
344a44ab170Smydeveloperday       "bool tools::addXRayRuntime(ToolChain const &TC, ArgList const &Args) {",
345a44ab170Smydeveloperday       "bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args) {",
346a44ab170Smydeveloperday       Style);
347a44ab170Smydeveloperday   verifyFormat("Foo<Foo<int> const> P;", "Foo<const Foo<int>> P;", Style);
348a44ab170Smydeveloperday   verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",
349a44ab170Smydeveloperday                "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);
350a44ab170Smydeveloperday 
351a44ab170Smydeveloperday   verifyFormat("auto const i = 0;", "const auto i = 0;", Style);
352a44ab170Smydeveloperday   verifyFormat("auto const &ir = i;", "const auto &ir = i;", Style);
353a44ab170Smydeveloperday   verifyFormat("auto const *ip = &i;", "const auto *ip = &i;", Style);
354a44ab170Smydeveloperday 
355b04664beSOwen Pan   verifyFormat("void f(Concept auto const &x);",
356b04664beSOwen Pan                "void f(const Concept auto &x);", Style);
357b04664beSOwen Pan   verifyFormat("void f(std::integral auto const &x);",
358b04664beSOwen Pan                "void f(const std::integral auto &x);", Style);
359b04664beSOwen Pan 
360f0ad9ea3SOwen Pan   verifyFormat("auto lambda = [] { int const i = 0; };",
361f0ad9ea3SOwen Pan                "auto lambda = [] { const int i = 0; };", Style);
362f0ad9ea3SOwen Pan 
363a44ab170Smydeveloperday   verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",
364a44ab170Smydeveloperday                "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);
365a44ab170Smydeveloperday 
366a44ab170Smydeveloperday   verifyFormat("Bar<Bar<int const> const> P;\n#if 0\n#else\n#endif",
367a44ab170Smydeveloperday                "Bar<Bar<const int> const> P;\n#if 0\n#else\n#endif", Style);
368a44ab170Smydeveloperday 
369a44ab170Smydeveloperday   verifyFormat("Baz<Baz<int const> const> P;\n#if 0\n#else\n#endif",
370a44ab170Smydeveloperday                "Baz<const Baz<const int>> P;\n#if 0\n#else\n#endif", Style);
371a44ab170Smydeveloperday 
372a44ab170Smydeveloperday   // verifyFormat("#if 0\nBoo<Boo<int const> const> P;\n#else\n#endif",
373a44ab170Smydeveloperday   //             "#if 0\nBoo<const Boo<const int>> P;\n#else\n#endif", Style);
374a44ab170Smydeveloperday 
375a44ab170Smydeveloperday   verifyFormat("int const P;\n#if 0\n#else\n#endif",
376a44ab170Smydeveloperday                "const int P;\n#if 0\n#else\n#endif", Style);
377a44ab170Smydeveloperday 
378a44ab170Smydeveloperday   verifyFormat("unsigned long const a;", "const unsigned long a;", Style);
379a44ab170Smydeveloperday   verifyFormat("unsigned long long const a;", "const unsigned long long a;",
380a44ab170Smydeveloperday                Style);
381a44ab170Smydeveloperday 
382cd7ab4b5SAlexander Hederstaf   // Multiple template parameters.
383cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<std::Foo const, 32>", "Bar<const std::Foo, 32>", Style);
384cd7ab4b5SAlexander Hederstaf   // Variable declaration based on template type.
385cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<std::Foo const> bar", "Bar<const std::Foo> bar", Style);
386cd7ab4b5SAlexander Hederstaf 
387cd7ab4b5SAlexander Hederstaf   // Using typename for a nested dependent type name.
388cd7ab4b5SAlexander Hederstaf   verifyFormat("typename Foo::iterator const;", "const typename Foo::iterator;",
389cd7ab4b5SAlexander Hederstaf                Style);
390cd7ab4b5SAlexander Hederstaf 
391cd7ab4b5SAlexander Hederstaf   // Don't move past C-style struct/class.
39220b4df1eSOwen Pan   verifyFormat("void foo(const struct A a);", Style);
39320b4df1eSOwen Pan   verifyFormat("void foo(const class A a);", Style);
394cd7ab4b5SAlexander Hederstaf 
395cd7ab4b5SAlexander Hederstaf   // Don't move past struct/class combined declaration and variable
396cd7ab4b5SAlexander Hederstaf   // definition.
39720b4df1eSOwen Pan   verifyFormat("const struct {\n} var;", Style);
39820b4df1eSOwen Pan   verifyFormat("struct {\n} const var;", Style);
39920b4df1eSOwen Pan   verifyFormat("const class {\n} var;", Style);
40020b4df1eSOwen Pan   verifyFormat("class {\n} const var;", Style);
401cd7ab4b5SAlexander Hederstaf 
402cd7ab4b5SAlexander Hederstaf   // Leave left qualifers unchanged for combined declaration and variable
403cd7ab4b5SAlexander Hederstaf   // definition.
40420b4df1eSOwen Pan   verifyFormat("volatile const class {\n} var;", Style);
40520b4df1eSOwen Pan   verifyFormat("const volatile class {\n} var;", Style);
406cd7ab4b5SAlexander Hederstaf   // Also do no sorting with respect to not-configured tokens.
40720b4df1eSOwen Pan   verifyFormat("const static volatile class {\n} var;", Style);
408cd7ab4b5SAlexander Hederstaf   // Sort right qualifiers for combined declaration and variable definition.
40920b4df1eSOwen Pan   verifyFormat("class {\n} const volatile var;", Style);
410cd7ab4b5SAlexander Hederstaf   verifyFormat("class {\n} const volatile var;",
411cd7ab4b5SAlexander Hederstaf                "class {\n} volatile const var;", Style);
412cd7ab4b5SAlexander Hederstaf   // Static keyword is not configured, should end up on the left of the right
413cd7ab4b5SAlexander Hederstaf   // side.
41420b4df1eSOwen Pan   verifyFormat("class {\n} static const volatile var;", Style);
415cd7ab4b5SAlexander Hederstaf   verifyFormat("class {\n} static const volatile var;",
416cd7ab4b5SAlexander Hederstaf                "class {\n} volatile static const var;", Style);
417cd7ab4b5SAlexander Hederstaf 
418cd7ab4b5SAlexander Hederstaf   // ::template for dependent names
419cd7ab4b5SAlexander Hederstaf   verifyFormat("::template Foo<T> const volatile var;",
420cd7ab4b5SAlexander Hederstaf                "const volatile ::template Foo<T> var;", Style);
421cd7ab4b5SAlexander Hederstaf   verifyFormat("typename ::template Foo<T> const volatile var;",
422cd7ab4b5SAlexander Hederstaf                "const volatile typename ::template Foo<T> var;", Style);
423cd7ab4b5SAlexander Hederstaf   verifyFormat("typename Bar::template Foo<T>::T const;",
424cd7ab4b5SAlexander Hederstaf                "const typename Bar::template Foo<T>::T;", Style);
425cd7ab4b5SAlexander Hederstaf   verifyFormat("typename Bar::template Foo<T>::T const volatile;",
426cd7ab4b5SAlexander Hederstaf                "const volatile typename Bar::template Foo<T>::T;", Style);
427cd7ab4b5SAlexander Hederstaf 
428cd7ab4b5SAlexander Hederstaf   // typename ::
429cd7ab4b5SAlexander Hederstaf   verifyFormat("typename ::Bar<int> const;", "const typename ::Bar<int>;",
430cd7ab4b5SAlexander Hederstaf                Style);
431cd7ab4b5SAlexander Hederstaf   // typename ::template
432cd7ab4b5SAlexander Hederstaf   verifyFormat("typename ::template Bar<int> const;",
433cd7ab4b5SAlexander Hederstaf                "const typename ::template Bar<int>;", Style);
434cd7ab4b5SAlexander Hederstaf 
435cd7ab4b5SAlexander Hederstaf   verifyFormat("foo<Bar<Baz> const>();", "foo<const Bar<Baz>>();", Style);
436cd7ab4b5SAlexander Hederstaf   verifyFormat("foo<Bar<Baz> const>();", "foo<const Bar<Baz> >();", Style);
437cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<32, Foo<25> const>;", "Bar<32, const Foo<25>>;", Style);
438cd7ab4b5SAlexander Hederstaf   verifyFormat("A<B<C<D> const> const>;", "A<const B<const C<D>>>;", Style);
439cd7ab4b5SAlexander Hederstaf   verifyFormat("A<B<C<D const> const> const>;", "A<const B<const C<const D>>>;",
440cd7ab4b5SAlexander Hederstaf                Style);
441cd7ab4b5SAlexander Hederstaf 
442cd7ab4b5SAlexander Hederstaf   // Don't move past decltype, typeof, or _Atomic.
44320b4df1eSOwen Pan   verifyFormat("const decltype(foo)", Style);
44420b4df1eSOwen Pan   verifyFormat("const typeof(foo)", Style);
44520b4df1eSOwen Pan   verifyFormat("const _Atomic(foo)", Style);
446cd7ab4b5SAlexander Hederstaf 
447cd7ab4b5SAlexander Hederstaf   // Comments
448cd7ab4b5SAlexander Hederstaf   const int ColumnLimit = Style.ColumnLimit;
449cd7ab4b5SAlexander Hederstaf   Style.ColumnLimit = 200;
450cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ Foo const *foo;", "const /*c*/ Foo *foo;", Style);
451cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const /*c*/ *foo;", "const Foo /*c*/ *foo;", Style);
452cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const * /*c*/ foo;", "const Foo * /*c*/ foo;", Style);
453cd7ab4b5SAlexander Hederstaf 
454cd7ab4b5SAlexander Hederstaf   verifyFormat("/*comment*/ std::vector<int> const v;",
455cd7ab4b5SAlexander Hederstaf                "const /*comment*/ std::vector<int> v;", Style);
456cd7ab4b5SAlexander Hederstaf   verifyFormat("std /*comment*/ ::vector<int> const v;",
457cd7ab4b5SAlexander Hederstaf                "const std /*comment*/ ::vector<int> v;", Style);
458cd7ab4b5SAlexander Hederstaf   verifyFormat("std::/*comment*/ vector<int> const v;",
459cd7ab4b5SAlexander Hederstaf                "const std::/*comment*/ vector<int> v;", Style);
460cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector /*comment*/<int> const v;",
461cd7ab4b5SAlexander Hederstaf                "const std::vector /*comment*/ <int> v;", Style);
462cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ int> const v;",
463cd7ab4b5SAlexander Hederstaf                "const std::vector</*comment*/ int> v;", Style);
464cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<int /*comment*/> const v;",
465cd7ab4b5SAlexander Hederstaf                "const std::vector<int /*comment*/> v;", Style);
466cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<int> const /*comment*/ v;",
467cd7ab4b5SAlexander Hederstaf                "const std::vector<int> /*comment*/ v;", Style);
468cd7ab4b5SAlexander Hederstaf 
469cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ int const> v;",
470cd7ab4b5SAlexander Hederstaf                "std::vector</*comment*/ const int> v;", Style);
471cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ int const> v;",
472cd7ab4b5SAlexander Hederstaf                "std::vector<const /*comment*/ int> v;", Style);
473cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<int const /*comment*/> v;",
474cd7ab4b5SAlexander Hederstaf                "std::vector<const int /*comment*/> v;", Style);
475cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ Foo const> v;",
476cd7ab4b5SAlexander Hederstaf                "std::vector</*comment*/ const Foo> v;", Style);
477cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ Foo const> v;",
478cd7ab4b5SAlexander Hederstaf                "std::vector<const /*comment*/ Foo> v;", Style);
479cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<Foo const /*comment*/> v;",
480cd7ab4b5SAlexander Hederstaf                "std::vector<const Foo /*comment*/> v;", Style);
481cd7ab4b5SAlexander Hederstaf 
482cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C<T>::template B<T> const;",
483cd7ab4b5SAlexander Hederstaf                "const typename C<T>::template B<T>;", Style);
484cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ typename C<T>::template B<T> const;",
485cd7ab4b5SAlexander Hederstaf                "const /*c*/ typename C<T>::template B<T>;", Style);
486cd7ab4b5SAlexander Hederstaf   verifyFormat("typename /*c*/ C<T>::template B<T> const;",
487cd7ab4b5SAlexander Hederstaf                "const typename /*c*/ C<T>::template B<T>;", Style);
488cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C /*c*/<T>::template B<T> const;",
489cd7ab4b5SAlexander Hederstaf                "const typename C /*c*/<T>::template B<T>;", Style);
490cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C<T> /*c*/ ::template B<T> const;",
491cd7ab4b5SAlexander Hederstaf                "const typename C<T> /*c*/ ::template B<T>;", Style);
492cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C<T>::/*c*/ template B<T> const;",
493cd7ab4b5SAlexander Hederstaf                "const typename C<T>::/*c*/ template B<T>;", Style);
494cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C<T>::template /*c*/ B<T> const;",
495cd7ab4b5SAlexander Hederstaf                "const typename C<T>::template /*c*/B<T>;", Style);
496cd7ab4b5SAlexander Hederstaf   verifyFormat("typename C<T>::template B<T> const /*c*/;",
497cd7ab4b5SAlexander Hederstaf                "const typename C<T>::template B<T>/*c*/;", Style);
498cd7ab4b5SAlexander Hederstaf 
499cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ /*c*/ typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template "
500cd7ab4b5SAlexander Hederstaf                "/*c*/ B /*c*/<T> const /*c*/ v;",
501cd7ab4b5SAlexander Hederstaf                "/*c*/ const /*c*/ typename /*c*/ C /*c*/<T> /*c*/ "
502cd7ab4b5SAlexander Hederstaf                "::/*c*/template /*c*/ B /*c*/<T> /*c*/ v;",
503cd7ab4b5SAlexander Hederstaf                Style);
504cd7ab4b5SAlexander Hederstaf 
505cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ unsigned /*c*/ long const /*c*/ a;",
506cd7ab4b5SAlexander Hederstaf                "const /*c*/ unsigned /*c*/ long /*c*/ a;", Style);
507cd7ab4b5SAlexander Hederstaf   verifyFormat("unsigned /*c*/ long /*c*/ long const a;",
508cd7ab4b5SAlexander Hederstaf                "const unsigned /*c*/ long /*c*/ long a;", Style);
509cd7ab4b5SAlexander Hederstaf 
510cd7ab4b5SAlexander Hederstaf   // Not changed
51120b4df1eSOwen Pan   verifyFormat("foo() /*c*/ const", Style);
51220b4df1eSOwen Pan   verifyFormat("const /*c*/ struct a;", Style);
51320b4df1eSOwen Pan   verifyFormat("const /*c*/ class a;", Style);
51420b4df1eSOwen Pan   verifyFormat("const /*c*/ decltype(v) a;", Style);
51520b4df1eSOwen Pan   verifyFormat("const /*c*/ typeof(v) a;", Style);
51620b4df1eSOwen Pan   verifyFormat("const /*c*/ _Atomic(v) a;", Style);
51720b4df1eSOwen Pan   verifyFormat("const decltype /*c*/ (v) a;", Style);
51820b4df1eSOwen Pan   verifyFormat("const /*c*/ class {\n} volatile /*c*/ foo = {};", Style);
519cd7ab4b5SAlexander Hederstaf 
520cd7ab4b5SAlexander Hederstaf   Style.ColumnLimit = ColumnLimit;
521cd7ab4b5SAlexander Hederstaf 
522cd7ab4b5SAlexander Hederstaf   // Don't adjust macros
52320b4df1eSOwen Pan   verifyFormat("const INTPTR a;", Style);
524393e197cSEmilia Dreamer 
525393e197cSEmilia Dreamer   // Pointers to members
526393e197cSEmilia Dreamer   verifyFormat("int S::*a;", Style);
527393e197cSEmilia Dreamer   verifyFormat("int const S::*a;", "const int S::*a;", Style);
528393e197cSEmilia Dreamer   verifyFormat("int const S::*const a;", "const int S::* const a;", Style);
529393e197cSEmilia Dreamer   verifyFormat("int A::*const A::*p1;", Style);
530393e197cSEmilia Dreamer   verifyFormat("float (C::*p)(int);", Style);
531393e197cSEmilia Dreamer   verifyFormat("float (C::*const p)(int);", Style);
532393e197cSEmilia Dreamer   verifyFormat("float (C::*p)(int) const;", Style);
533714033a6SOwen Pan   verifyFormat("float const (C::*p)(int);", "const float (C::*p)(int);", Style);
53440acaa39SOwen Pan 
53540acaa39SOwen Pan   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
53640acaa39SOwen Pan   Style.BraceWrapping.AfterFunction = true;
53740acaa39SOwen Pan   verifyFormat("auto foo() -> T const { return bar; }",
53840acaa39SOwen Pan                "auto foo() -> const T { return bar; }", Style);
539a44ab170Smydeveloperday }
540a44ab170Smydeveloperday 
541a44ab170Smydeveloperday TEST_F(QualifierFixerTest, LeftQualifier) {
542a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
543a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
544a44ab170Smydeveloperday   Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
545a44ab170Smydeveloperday 
546a44ab170Smydeveloperday   verifyFormat("const int a;", Style);
547a44ab170Smydeveloperday   verifyFormat("const int *a;", Style);
548a44ab170Smydeveloperday   verifyFormat("const int &a;", Style);
549a44ab170Smydeveloperday   verifyFormat("const int &&a;", Style);
550a44ab170Smydeveloperday   verifyFormat("const int b;", Style);
551a44ab170Smydeveloperday   verifyFormat("const int *b;", Style);
552a44ab170Smydeveloperday   verifyFormat("const int &b;", Style);
553a44ab170Smydeveloperday   verifyFormat("const int &&b;", Style);
554cd7ab4b5SAlexander Hederstaf   verifyFormat("const int *const b;", Style);
555a44ab170Smydeveloperday   verifyFormat("int *const c;", Style);
556a44ab170Smydeveloperday 
557a44ab170Smydeveloperday   verifyFormat("const Foo a;", Style);
558a44ab170Smydeveloperday   verifyFormat("const Foo *a;", Style);
559a44ab170Smydeveloperday   verifyFormat("const Foo &a;", Style);
560a44ab170Smydeveloperday   verifyFormat("const Foo &&a;", Style);
561a44ab170Smydeveloperday   verifyFormat("const Foo b;", Style);
562a44ab170Smydeveloperday   verifyFormat("const Foo *b;", Style);
563a44ab170Smydeveloperday   verifyFormat("const Foo &b;", Style);
564a44ab170Smydeveloperday   verifyFormat("const Foo &&b;", Style);
565cd7ab4b5SAlexander Hederstaf   verifyFormat("const Foo *const b;", Style);
566a44ab170Smydeveloperday   verifyFormat("Foo *const b;", Style);
567a44ab170Smydeveloperday   verifyFormat("const Foo *const b;", Style);
568a44ab170Smydeveloperday 
569a44ab170Smydeveloperday   verifyFormat("LLVM_NODISCARD const int &Foo();", Style);
570a44ab170Smydeveloperday 
571a44ab170Smydeveloperday   verifyFormat("const char a[];", Style);
572a44ab170Smydeveloperday   verifyFormat("const auto v = get_value();", Style);
573a44ab170Smydeveloperday   verifyFormat("const long long &a;", Style);
574a44ab170Smydeveloperday   verifyFormat("const unsigned char *a;", Style);
575a44ab170Smydeveloperday   verifyFormat("const unsigned char *a;", "unsigned char const *a;", Style);
576a44ab170Smydeveloperday   verifyFormat("const Foo<int> &a", "Foo<int> const &a", Style);
577a44ab170Smydeveloperday   verifyFormat("const Foo<int>::iterator &a", "Foo<int>::iterator const &a",
578a44ab170Smydeveloperday                Style);
579d4d28f2aSMarek Kurdej   verifyFormat("const ::Foo<int>::iterator &a", "::Foo<int>::iterator const &a",
580d4d28f2aSMarek Kurdej                Style);
581a44ab170Smydeveloperday 
582a44ab170Smydeveloperday   verifyFormat("const int a;", "int const a;", Style);
583a44ab170Smydeveloperday   verifyFormat("const int *a;", "int const *a;", Style);
584a44ab170Smydeveloperday   verifyFormat("const int &a;", "int const &a;", Style);
585a44ab170Smydeveloperday   verifyFormat("foo(const int &a)", "foo(int const &a)", Style);
58620b4df1eSOwen Pan   verifyFormat("unsigned char *a;", Style);
587a44ab170Smydeveloperday   verifyFormat("const unsigned int &get_nu() const",
588a44ab170Smydeveloperday                "unsigned int const &get_nu() const", Style);
589a44ab170Smydeveloperday 
590a44ab170Smydeveloperday   verifyFormat("const volatile int;", "volatile const int;", Style);
59120b4df1eSOwen Pan   verifyFormat("const volatile int;", Style);
592a44ab170Smydeveloperday   verifyFormat("const volatile int;", "const int volatile;", Style);
593a44ab170Smydeveloperday 
594a44ab170Smydeveloperday   verifyFormat("const volatile int *restrict;", "volatile const int *restrict;",
595a44ab170Smydeveloperday                Style);
59620b4df1eSOwen Pan   verifyFormat("const volatile int *restrict;", Style);
597a44ab170Smydeveloperday   verifyFormat("const volatile int *restrict;", "const int volatile *restrict;",
598a44ab170Smydeveloperday                Style);
599a44ab170Smydeveloperday 
600cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile long long int;", "volatile long long int const;",
601cd7ab4b5SAlexander Hederstaf                Style);
602cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile long long int;", "volatile long long const int;",
603cd7ab4b5SAlexander Hederstaf                Style);
604cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile long long int;", "long long volatile int const;",
605cd7ab4b5SAlexander Hederstaf                Style);
606cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile long long int;", "long volatile long int const;",
607cd7ab4b5SAlexander Hederstaf                Style);
608cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile long long int;", "const long long volatile int;",
609cd7ab4b5SAlexander Hederstaf                Style);
610cd7ab4b5SAlexander Hederstaf 
611a44ab170Smydeveloperday   verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY;",
612a44ab170Smydeveloperday                Style);
613a44ab170Smydeveloperday 
614a44ab170Smydeveloperday   verifyFormat("void foo() const override;", Style);
615a44ab170Smydeveloperday   verifyFormat("void foo() const override LLVM_READONLY;", Style);
616a44ab170Smydeveloperday   verifyFormat("void foo() const final;", Style);
617a44ab170Smydeveloperday   verifyFormat("void foo() const final LLVM_READONLY;", Style);
618a44ab170Smydeveloperday   verifyFormat("void foo() const LLVM_READONLY;", Style);
619a44ab170Smydeveloperday 
620a44ab170Smydeveloperday   verifyFormat(
621a44ab170Smydeveloperday       "template <typename Func> explicit Action(const Action<Func> &action);",
622a44ab170Smydeveloperday       Style);
623a44ab170Smydeveloperday   verifyFormat(
624a44ab170Smydeveloperday       "template <typename Func> explicit Action(const Action<Func> &action);",
625a44ab170Smydeveloperday       "template <typename Func> explicit Action(Action<Func> const &action);",
626a44ab170Smydeveloperday       Style);
627a44ab170Smydeveloperday 
62820b4df1eSOwen Pan   verifyFormat("static const int bat;", Style);
629a44ab170Smydeveloperday   verifyFormat("static const int bat;", "static int const bat;", Style);
630a44ab170Smydeveloperday 
63120b4df1eSOwen Pan   verifyFormat("static const int Foo<int>::bat = 0;", Style);
632a44ab170Smydeveloperday   verifyFormat("static const int Foo<int>::bat = 0;",
633a44ab170Smydeveloperday                "static int const Foo<int>::bat = 0;", Style);
634a44ab170Smydeveloperday 
635a44ab170Smydeveloperday   verifyFormat("void fn(const Foo<T> &i);");
636a44ab170Smydeveloperday 
63720b4df1eSOwen Pan   verifyFormat("const int Foo<int>::bat = 0;", Style);
638a44ab170Smydeveloperday   verifyFormat("const int Foo<int>::bat = 0;", "int const Foo<int>::bat = 0;",
639a44ab170Smydeveloperday                Style);
640a44ab170Smydeveloperday   verifyFormat("void fn(const Foo<T> &i);", "void fn( Foo<T> const &i);",
641a44ab170Smydeveloperday                Style);
642a44ab170Smydeveloperday   verifyFormat("const int Foo<int>::fn() {", "int const Foo<int>::fn() {",
643a44ab170Smydeveloperday                Style);
644a44ab170Smydeveloperday   verifyFormat("const Foo<Foo<int>> *p;", "Foo<Foo<int>> const *p;", Style);
645a44ab170Smydeveloperday   verifyFormat(
646a44ab170Smydeveloperday       "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",
647a44ab170Smydeveloperday       "const Foo<Foo<int>> *p = const_cast<Foo<Foo<int>> const *>(&ffi);",
648a44ab170Smydeveloperday       Style);
649a44ab170Smydeveloperday 
650a44ab170Smydeveloperday   verifyFormat("void fn(const Foo<T> &i);", "void fn(Foo<T> const &i);", Style);
651a44ab170Smydeveloperday   verifyFormat("void fns(const ns::S &s);", "void fns(ns::S const &s);", Style);
652d4d28f2aSMarek Kurdej   verifyFormat("void fns(const ::ns::S &s);", "void fns(::ns::S const &s);",
653d4d28f2aSMarek Kurdej                Style);
654a44ab170Smydeveloperday   verifyFormat("void fn(const ns::Foo<T> &i);", "void fn(ns::Foo<T> const &i);",
655a44ab170Smydeveloperday                Style);
656a44ab170Smydeveloperday   verifyFormat("void fns(const ns::ns2::S &s);",
657a44ab170Smydeveloperday                "void fns(ns::ns2::S const &s);", Style);
658a44ab170Smydeveloperday   verifyFormat("void fn(const ns::Foo<Bar<T>> &i);",
659a44ab170Smydeveloperday                "void fn(ns::Foo<Bar<T>> const &i);", Style);
660a44ab170Smydeveloperday   verifyFormat("void fn(const ns::ns2::Foo<Bar<T>> &i);",
661a44ab170Smydeveloperday                "void fn(ns::ns2::Foo<Bar<T>> const &i);", Style);
662a44ab170Smydeveloperday   verifyFormat("void fn(const ns::ns2::Foo<Bar<T, U>> &i);",
663a44ab170Smydeveloperday                "void fn(ns::ns2::Foo<Bar<T, U>> const &i);", Style);
664a44ab170Smydeveloperday 
665a44ab170Smydeveloperday   verifyFormat("const auto i = 0;", "auto const i = 0;", Style);
666a44ab170Smydeveloperday   verifyFormat("const auto &ir = i;", "auto const &ir = i;", Style);
667a44ab170Smydeveloperday   verifyFormat("const auto *ip = &i;", "auto const *ip = &i;", Style);
668a44ab170Smydeveloperday 
669b04664beSOwen Pan   verifyFormat("void f(const Concept auto &x);",
670b04664beSOwen Pan                "void f(Concept auto const &x);", Style);
671b04664beSOwen Pan   verifyFormat("void f(const std::integral auto &x);",
672b04664beSOwen Pan                "void f(std::integral auto const &x);", Style);
673b04664beSOwen Pan 
674f0ad9ea3SOwen Pan   verifyFormat("auto lambda = [] { const int i = 0; };",
675f0ad9ea3SOwen Pan                "auto lambda = [] { int const i = 0; };", Style);
676f0ad9ea3SOwen Pan 
677a44ab170Smydeveloperday   verifyFormat("Foo<const Foo<int>> P;\n#if 0\n#else\n#endif",
678a44ab170Smydeveloperday                "Foo<Foo<int> const> P;\n#if 0\n#else\n#endif", Style);
679a44ab170Smydeveloperday 
680a44ab170Smydeveloperday   verifyFormat("Foo<Foo<const int>> P;\n#if 0\n#else\n#endif",
681a44ab170Smydeveloperday                "Foo<Foo<int const>> P;\n#if 0\n#else\n#endif", Style);
682a44ab170Smydeveloperday 
683a44ab170Smydeveloperday   verifyFormat("const int P;\n#if 0\n#else\n#endif",
684a44ab170Smydeveloperday                "int const P;\n#if 0\n#else\n#endif", Style);
685a44ab170Smydeveloperday 
686a44ab170Smydeveloperday   verifyFormat("const unsigned long a;", "unsigned long const a;", Style);
687a44ab170Smydeveloperday   verifyFormat("const unsigned long long a;", "unsigned long long const a;",
688a44ab170Smydeveloperday                Style);
689a44ab170Smydeveloperday 
690a44ab170Smydeveloperday   verifyFormat("const long long unsigned a;", "long const long unsigned a;",
691a44ab170Smydeveloperday                Style);
692a44ab170Smydeveloperday 
69320b4df1eSOwen Pan   verifyFormat("const std::Foo", Style);
69420b4df1eSOwen Pan   verifyFormat("const std::Foo<>", Style);
695a44ab170Smydeveloperday   verifyFormat("const std::Foo < int", "const std::Foo<int", Style);
69620b4df1eSOwen Pan   verifyFormat("const std::Foo<int>", Style);
697a44ab170Smydeveloperday 
698cd7ab4b5SAlexander Hederstaf   // Multiple template parameters.
699cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<const std::Foo, 32>;", "Bar<std::Foo const, 32>;", Style);
700cd7ab4b5SAlexander Hederstaf 
701cd7ab4b5SAlexander Hederstaf   // Variable declaration based on template type.
702cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<const std::Foo> bar;", "Bar<std::Foo const> bar;", Style);
703cd7ab4b5SAlexander Hederstaf 
704cd7ab4b5SAlexander Hederstaf   // Using typename for a dependent name.
705cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename Foo::iterator;", "typename Foo::iterator const;",
706cd7ab4b5SAlexander Hederstaf                Style);
707cd7ab4b5SAlexander Hederstaf 
708cd7ab4b5SAlexander Hederstaf   // Don't move past C-style struct/class.
70920b4df1eSOwen Pan   verifyFormat("void foo(struct A const a);", Style);
71020b4df1eSOwen Pan   verifyFormat("void foo(class A const a);", Style);
711cd7ab4b5SAlexander Hederstaf 
712cd7ab4b5SAlexander Hederstaf   // Don't move past struct/class combined declaration and variable
713cd7ab4b5SAlexander Hederstaf   // definition.
71420b4df1eSOwen Pan   verifyFormat("const struct {\n} var;", Style);
71520b4df1eSOwen Pan   verifyFormat("struct {\n} const var;", Style);
71620b4df1eSOwen Pan   verifyFormat("const class {\n} var;", Style);
71720b4df1eSOwen Pan   verifyFormat("class {\n} const var;", Style);
718cd7ab4b5SAlexander Hederstaf 
719cd7ab4b5SAlexander Hederstaf   // Sort left qualifiers for struct/class combined declaration and variable
720cd7ab4b5SAlexander Hederstaf   // definition.
72120b4df1eSOwen Pan   verifyFormat("const volatile class {\n} var;", Style);
722cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile class {\n} var;",
723cd7ab4b5SAlexander Hederstaf                "volatile const class {\n} var;", Style);
724cd7ab4b5SAlexander Hederstaf   // Leave right qualifers unchanged for struct/class combined declaration and
725cd7ab4b5SAlexander Hederstaf   // variable definition.
72620b4df1eSOwen Pan   verifyFormat("class {\n} const volatile var;", Style);
72720b4df1eSOwen Pan   verifyFormat("class {\n} volatile const var;", Style);
728cd7ab4b5SAlexander Hederstaf 
729cd7ab4b5SAlexander Hederstaf   verifyFormat("foo<const Bar<Baz<T>>>();", "foo<Bar<Baz<T>> const>();", Style);
730cd7ab4b5SAlexander Hederstaf   verifyFormat("foo<const Bar<Baz<T>>>();", "foo<Bar<Baz<T> > const>();",
731cd7ab4b5SAlexander Hederstaf                Style);
732cd7ab4b5SAlexander Hederstaf   verifyFormat("Bar<32, const Foo<25>>;", "Bar<32, Foo<25> const>;", Style);
733cd7ab4b5SAlexander Hederstaf   verifyFormat("A<const B<const C<D>>>;", "A<B<C<D> const> const>;", Style);
734cd7ab4b5SAlexander Hederstaf   verifyFormat("A<const B<const C<const D>>>;", "A<B<C<D const> const> const>;",
735cd7ab4b5SAlexander Hederstaf                Style);
736cd7ab4b5SAlexander Hederstaf 
737cd7ab4b5SAlexander Hederstaf   // Don't move past decltype, typeof, or _Atomic.
73820b4df1eSOwen Pan   verifyFormat("decltype(foo) const", Style);
73920b4df1eSOwen Pan   verifyFormat("typeof(foo) const", Style);
74020b4df1eSOwen Pan   verifyFormat("_Atomic(foo) const", Style);
741cd7ab4b5SAlexander Hederstaf 
742cd7ab4b5SAlexander Hederstaf   // ::template for dependent names
743cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile ::template Foo<T> var;",
744cd7ab4b5SAlexander Hederstaf                "::template Foo<T> const volatile var;", Style);
745cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile typename ::template Foo<T> var;",
746cd7ab4b5SAlexander Hederstaf                "typename ::template Foo<T> const volatile var;", Style);
747cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename Bar::template Foo<T>::T;",
748cd7ab4b5SAlexander Hederstaf                "typename Bar::template Foo<T>::T const;", Style);
749cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile typename Bar::template Foo<T>::T;",
750cd7ab4b5SAlexander Hederstaf                "typename Bar::template Foo<T>::T const volatile;", Style);
751cd7ab4b5SAlexander Hederstaf 
752cd7ab4b5SAlexander Hederstaf   // typename ::
753cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename ::Bar<int>;", "typename ::Bar<int> const;",
754cd7ab4b5SAlexander Hederstaf                Style);
755cd7ab4b5SAlexander Hederstaf   // typename ::template
756cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename ::template Bar<int>;",
757cd7ab4b5SAlexander Hederstaf                "typename ::template Bar<int> const;", Style);
758cd7ab4b5SAlexander Hederstaf 
759cd7ab4b5SAlexander Hederstaf   // Comments
760cd7ab4b5SAlexander Hederstaf   const int ColumnLimit = Style.ColumnLimit;
761cd7ab4b5SAlexander Hederstaf   Style.ColumnLimit = 200;
762cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ const Foo *foo;", "/*c*/ Foo const *foo;", Style);
763cd7ab4b5SAlexander Hederstaf   verifyFormat("const Foo /*c*/ *foo;", "Foo const /*c*/ *foo;", Style);
764cd7ab4b5SAlexander Hederstaf   verifyFormat("const Foo * /*c*/ foo;", "Foo const * /*c*/ foo;", Style);
765cd7ab4b5SAlexander Hederstaf 
766cd7ab4b5SAlexander Hederstaf   verifyFormat("/*comment*/ const std::vector<int> v;",
767cd7ab4b5SAlexander Hederstaf                "/*comment*/ std::vector<int> const v;", Style);
768cd7ab4b5SAlexander Hederstaf   verifyFormat("const std /*comment*/ ::vector<int> v;",
769cd7ab4b5SAlexander Hederstaf                "std /*comment*/ ::vector<int> const v;", Style);
770cd7ab4b5SAlexander Hederstaf   verifyFormat("const std::/*comment*/ vector<int> v;",
771cd7ab4b5SAlexander Hederstaf                "std::/*comment*/ vector<int> const v;", Style);
772cd7ab4b5SAlexander Hederstaf   verifyFormat("const std::vector /*comment*/<int> v;",
773cd7ab4b5SAlexander Hederstaf                "std::vector /*comment*/<int> const v;", Style);
774cd7ab4b5SAlexander Hederstaf   verifyFormat("const std::vector</*comment*/ int> v;",
775cd7ab4b5SAlexander Hederstaf                "std::vector</*comment*/ int> const v;", Style);
776cd7ab4b5SAlexander Hederstaf   verifyFormat("const std::vector<int /*comment*/> v;",
777cd7ab4b5SAlexander Hederstaf                "std::vector<int /*comment*/> const v;", Style);
778cd7ab4b5SAlexander Hederstaf   verifyFormat("const std::vector<int> /*comment*/ v;",
779cd7ab4b5SAlexander Hederstaf                "std::vector<int> /*comment*/ const v;", Style);
780cd7ab4b5SAlexander Hederstaf 
781cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ const int> v;",
782cd7ab4b5SAlexander Hederstaf                "std::vector</*comment*/ int const> v;", Style);
783cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<const int /*comment*/> v;",
784cd7ab4b5SAlexander Hederstaf                "std::vector<int /*comment*/ const> v;", Style);
785cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<const int /*comment*/> v;",
786cd7ab4b5SAlexander Hederstaf                "std::vector<int const /*comment*/> v;", Style);
787cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector</*comment*/ const Foo> v;",
788cd7ab4b5SAlexander Hederstaf                "std::vector</*comment*/ Foo const> v;", Style);
789cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<const Foo /*comment*/> v;",
790cd7ab4b5SAlexander Hederstaf                "std::vector<Foo /*comment*/ const> v;", Style);
791cd7ab4b5SAlexander Hederstaf   verifyFormat("std::vector<const Foo /*comment*/> v;",
792cd7ab4b5SAlexander Hederstaf                "std::vector<Foo const /*comment*/> v;", Style);
793cd7ab4b5SAlexander Hederstaf 
794cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C<T>::template B<T>;",
795cd7ab4b5SAlexander Hederstaf                "typename C<T>::template B<T> const;", Style);
796cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ const typename C<T>::template B<T>;",
797cd7ab4b5SAlexander Hederstaf                "/*c*/ typename C<T>::template B<T> const;", Style);
798cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename /*c*/ C<T>::template B<T>;",
799cd7ab4b5SAlexander Hederstaf                "typename /*c*/ C<T>::template B<T> const;", Style);
800cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C /*c*/<T>::template B<T>;",
801cd7ab4b5SAlexander Hederstaf                "typename C /*c*/<T>::template B<T> const;", Style);
802cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C<T> /*c*/ ::template B<T>;",
803cd7ab4b5SAlexander Hederstaf                "typename C<T> /*c*/ ::template B<T> const;", Style);
804cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C<T>::/*c*/ template B<T>;",
805cd7ab4b5SAlexander Hederstaf                "typename C<T>::/*c*/ template B<T> const;", Style);
806cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C<T>::template /*c*/ B<T>;",
807cd7ab4b5SAlexander Hederstaf                "typename C<T>::template /*c*/ B<T> const;", Style);
808cd7ab4b5SAlexander Hederstaf   verifyFormat("const typename C<T>::template B<T> /*c*/;",
809cd7ab4b5SAlexander Hederstaf                "typename C<T>::template B<T> /*c*/ const;", Style);
810cd7ab4b5SAlexander Hederstaf 
811cd7ab4b5SAlexander Hederstaf   verifyFormat("/*c*/ const typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template "
812cd7ab4b5SAlexander Hederstaf                "/*c*/ B /*c*/<T> /*c*/ v;",
813cd7ab4b5SAlexander Hederstaf                "/*c*/ typename /*c*/ C /*c*/<T> /*c*/ ::/*c*/ template /*c*/ B "
814cd7ab4b5SAlexander Hederstaf                "/*c*/<T> /*c*/ const v;",
815cd7ab4b5SAlexander Hederstaf                Style);
816cd7ab4b5SAlexander Hederstaf 
817cd7ab4b5SAlexander Hederstaf   verifyFormat("const unsigned /*c*/ long /*c*/ a;",
818cd7ab4b5SAlexander Hederstaf                "unsigned /*c*/ long /*c*/ const a;", Style);
819cd7ab4b5SAlexander Hederstaf   verifyFormat("const unsigned /*c*/ long /*c*/ long a;",
820cd7ab4b5SAlexander Hederstaf                "unsigned /*c*/ long /*c*/ long const a;", Style);
821cd7ab4b5SAlexander Hederstaf 
822cd7ab4b5SAlexander Hederstaf   // Not changed
82320b4df1eSOwen Pan   verifyFormat("foo() /*c*/ const", Style);
82420b4df1eSOwen Pan   verifyFormat("struct /*c*/ const a;", Style);
82520b4df1eSOwen Pan   verifyFormat("class /*c*/ const a;", Style);
82620b4df1eSOwen Pan   verifyFormat("decltype(v) /*c*/ const a;", Style);
82720b4df1eSOwen Pan   verifyFormat("typeof(v) /*c*/ const a;", Style);
82820b4df1eSOwen Pan   verifyFormat("_Atomic(v) /*c*/ const a;", Style);
82920b4df1eSOwen Pan   verifyFormat("decltype /*c*/ (v) const a;", Style);
83020b4df1eSOwen Pan   verifyFormat("const /*c*/ class {\n} /*c*/ volatile /*c*/ foo = {};", Style);
831cd7ab4b5SAlexander Hederstaf 
832cd7ab4b5SAlexander Hederstaf   Style.ColumnLimit = ColumnLimit;
833cd7ab4b5SAlexander Hederstaf 
834cd7ab4b5SAlexander Hederstaf   // Don't adjust macros
83520b4df1eSOwen Pan   verifyFormat("INTPTR const a;", Style);
836393e197cSEmilia Dreamer 
837393e197cSEmilia Dreamer   // Pointers to members
838393e197cSEmilia Dreamer   verifyFormat("int S::*a;", Style);
839393e197cSEmilia Dreamer   verifyFormat("const int S::*a;", "int const S::*a;", Style);
840393e197cSEmilia Dreamer   verifyFormat("const int S::*const a;", "int const S::*const a;", Style);
841393e197cSEmilia Dreamer   verifyFormat("int A::*const A::*p1;", Style);
842393e197cSEmilia Dreamer   verifyFormat("float (C::*p)(int);", Style);
843393e197cSEmilia Dreamer   verifyFormat("float (C::*const p)(int);", Style);
844393e197cSEmilia Dreamer   verifyFormat("float (C::*p)(int) const;", Style);
845714033a6SOwen Pan   verifyFormat("const float (C::*p)(int);", "float const (C::*p)(int);", Style);
846a44ab170Smydeveloperday }
847a44ab170Smydeveloperday 
848a44ab170Smydeveloperday TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) {
849a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
850a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
851a44ab170Smydeveloperday   Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
852a44ab170Smydeveloperday 
853a44ab170Smydeveloperday   // The Default
85476d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
855a44ab170Smydeveloperday 
85620b4df1eSOwen Pan   verifyFormat("const volatile int a;", Style);
857a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "volatile const int a;", Style);
858a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "int const volatile a;", Style);
859a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "int volatile const a;", Style);
860a44ab170Smydeveloperday   verifyFormat("const volatile int a;", "const int volatile a;", Style);
861a44ab170Smydeveloperday 
86220b4df1eSOwen Pan   verifyFormat("const volatile Foo a;", Style);
863cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo a;", "volatile const Foo a;", Style);
864cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo a;", "Foo const volatile a;", Style);
865cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo a;", "Foo volatile const a;", Style);
866cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo a;", "const Foo volatile a;", Style);
867cd7ab4b5SAlexander Hederstaf 
868a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Right;
869a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "const", "volatile"};
870a44ab170Smydeveloperday 
871a44ab170Smydeveloperday   verifyFormat("int const volatile a;", "const volatile int a;", Style);
872a44ab170Smydeveloperday   verifyFormat("int const volatile a;", "volatile const int a;", Style);
87320b4df1eSOwen Pan   verifyFormat("int const volatile a;", Style);
874a44ab170Smydeveloperday   verifyFormat("int const volatile a;", "int volatile const a;", Style);
875a44ab170Smydeveloperday   verifyFormat("int const volatile a;", "const int volatile a;", Style);
876a44ab170Smydeveloperday 
877cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const volatile a;", "const volatile Foo a;", Style);
878cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const volatile a;", "volatile const Foo a;", Style);
87920b4df1eSOwen Pan   verifyFormat("Foo const volatile a;", Style);
880cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const volatile a;", "Foo volatile const a;", Style);
881cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo const volatile a;", "const Foo volatile a;", Style);
882cd7ab4b5SAlexander Hederstaf 
883a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
884a44ab170Smydeveloperday   Style.QualifierOrder = {"volatile", "const", "type"};
885a44ab170Smydeveloperday 
886a44ab170Smydeveloperday   verifyFormat("volatile const int a;", "const volatile int a;", Style);
88720b4df1eSOwen Pan   verifyFormat("volatile const int a;", Style);
888a44ab170Smydeveloperday   verifyFormat("volatile const int a;", "int const volatile a;", Style);
889a44ab170Smydeveloperday   verifyFormat("volatile const int a;", "int volatile const a;", Style);
890a44ab170Smydeveloperday   verifyFormat("volatile const int a;", "const int volatile a;", Style);
891a44ab170Smydeveloperday 
892cd7ab4b5SAlexander Hederstaf   verifyFormat("volatile const Foo a;", "const volatile Foo a;", Style);
89320b4df1eSOwen Pan   verifyFormat("volatile const Foo a;", Style);
894cd7ab4b5SAlexander Hederstaf   verifyFormat("volatile const Foo a;", "Foo const volatile a;", Style);
895cd7ab4b5SAlexander Hederstaf   verifyFormat("volatile const Foo a;", "Foo volatile const a;", Style);
896cd7ab4b5SAlexander Hederstaf   verifyFormat("volatile const Foo a;", "const Foo volatile a;", Style);
897cd7ab4b5SAlexander Hederstaf 
898a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Right;
899a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "volatile", "const"};
900a44ab170Smydeveloperday 
901a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "const volatile int a;", Style);
902a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "volatile const int a;", Style);
903a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "int const volatile a;", Style);
90420b4df1eSOwen Pan   verifyFormat("int volatile const a;", Style);
905a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "const int volatile a;", Style);
906a44ab170Smydeveloperday 
907cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);
908cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);
909cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);
91020b4df1eSOwen Pan   verifyFormat("Foo volatile const a;", Style);
911cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);
912cd7ab4b5SAlexander Hederstaf 
913a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
914a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "volatile", "const"};
915a44ab170Smydeveloperday 
916a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "const volatile int a;", Style);
917a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "volatile const int a;", Style);
918a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "int const volatile a;", Style);
91920b4df1eSOwen Pan   verifyFormat("int volatile const a;", Style);
920a44ab170Smydeveloperday   verifyFormat("int volatile const a;", "const int volatile a;", Style);
921cd7ab4b5SAlexander Hederstaf 
922cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "const volatile Foo a;", Style);
923cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "volatile const Foo a;", Style);
924cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "Foo const volatile a;", Style);
92520b4df1eSOwen Pan   verifyFormat("Foo volatile const a;", Style);
926cd7ab4b5SAlexander Hederstaf   verifyFormat("Foo volatile const a;", "const Foo volatile a;", Style);
927a44ab170Smydeveloperday }
928a44ab170Smydeveloperday 
929a44ab170Smydeveloperday TEST_F(QualifierFixerTest, InlineStatics) {
930a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
931a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
932a44ab170Smydeveloperday   Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
93376d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
934a44ab170Smydeveloperday 
935a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
936a44ab170Smydeveloperday                "const inline static volatile int a;", Style);
937a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
938a44ab170Smydeveloperday                "volatile inline static const int a;", Style);
939a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
940a44ab170Smydeveloperday                "int const inline static  volatile a;", Style);
941a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
942a44ab170Smydeveloperday                "int volatile inline static  const a;", Style);
943a44ab170Smydeveloperday   verifyFormat("inline static const volatile int a;",
944a44ab170Smydeveloperday                "const int inline static  volatile a;", Style);
945a44ab170Smydeveloperday }
946a44ab170Smydeveloperday 
947a44ab170Smydeveloperday TEST_F(QualifierFixerTest, AmpEqual) {
948a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
949a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
950a44ab170Smydeveloperday   Style.QualifierOrder = {"static", "type", "const"};
95176d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)3);
952a44ab170Smydeveloperday 
953a44ab170Smydeveloperday   verifyFormat("foo(std::string const & = std::string()) const",
954a44ab170Smydeveloperday                "foo(const std::string & = std::string()) const", Style);
955a44ab170Smydeveloperday   verifyFormat("foo(std::string const & = std::string())",
956a44ab170Smydeveloperday                "foo(const std::string & = std::string())", Style);
957a44ab170Smydeveloperday }
958a44ab170Smydeveloperday 
959a44ab170Smydeveloperday TEST_F(QualifierFixerTest, MoveConstBeyondTypeSmall) {
960a44ab170Smydeveloperday 
961a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
962a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
963a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "const"};
96476d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);
965a44ab170Smydeveloperday 
966a44ab170Smydeveloperday   verifyFormat("int const a;", "const int a;", Style);
967a44ab170Smydeveloperday   verifyFormat("int const *a;", "const int*a;", Style);
968a44ab170Smydeveloperday   verifyFormat("int const *a;", "const int *a;", Style);
969a44ab170Smydeveloperday   verifyFormat("int const &a;", "const int &a;", Style);
970a44ab170Smydeveloperday   verifyFormat("int const &&a;", "const int &&a;", Style);
971a44ab170Smydeveloperday }
972a44ab170Smydeveloperday 
973a44ab170Smydeveloperday TEST_F(QualifierFixerTest, MoveConstBeforeTypeSmall) {
974a44ab170Smydeveloperday 
975a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
976a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
977a44ab170Smydeveloperday   Style.QualifierOrder = {"const", "type"};
97876d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);
979a44ab170Smydeveloperday 
980a44ab170Smydeveloperday   verifyFormat("const int a;", "int const a;", Style);
981a44ab170Smydeveloperday   verifyFormat("const int *a;", "int const *a;", Style);
982cd7ab4b5SAlexander Hederstaf   verifyFormat("const int *const a;", "int const *const a;", Style);
983a44ab170Smydeveloperday 
984a44ab170Smydeveloperday   verifyFormat("const int a = foo();", "int const a = foo();", Style);
985a44ab170Smydeveloperday   verifyFormat("const int *a = foo();", "int const *a = foo();", Style);
986cd7ab4b5SAlexander Hederstaf   verifyFormat("const int *const a = foo();", "int const *const a = foo();",
987a44ab170Smydeveloperday                Style);
988a44ab170Smydeveloperday 
989a44ab170Smydeveloperday   verifyFormat("const auto a = foo();", "auto const a = foo();", Style);
990a44ab170Smydeveloperday   verifyFormat("const auto *a = foo();", "auto const *a = foo();", Style);
991cd7ab4b5SAlexander Hederstaf   verifyFormat("const auto *const a = foo();", "auto const *const a = foo();",
992a44ab170Smydeveloperday                Style);
993a44ab170Smydeveloperday }
994a44ab170Smydeveloperday 
995a44ab170Smydeveloperday TEST_F(QualifierFixerTest, MoveConstBeyondType) {
996a44ab170Smydeveloperday 
997a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
998a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
999a44ab170Smydeveloperday   Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};
100076d845cbSNemanja Ivanovic   EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
1001a44ab170Smydeveloperday 
1002a44ab170Smydeveloperday   verifyFormat("static inline int const volatile a;",
1003a44ab170Smydeveloperday                "const inline static volatile int a;", Style);
1004a44ab170Smydeveloperday   verifyFormat("static inline int const volatile a;",
1005a44ab170Smydeveloperday                "volatile inline static const int a;", Style);
1006a44ab170Smydeveloperday   verifyFormat("static inline int const volatile a;",
1007a44ab170Smydeveloperday                "int const inline static  volatile a;", Style);
1008a44ab170Smydeveloperday   verifyFormat("static inline int const volatile a;",
1009a44ab170Smydeveloperday                "int volatile inline static  const a;", Style);
1010a44ab170Smydeveloperday   verifyFormat("static inline int const volatile a;",
1011a44ab170Smydeveloperday                "const int inline static  volatile a;", Style);
1012a44ab170Smydeveloperday 
1013cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline int const volatile *const a;",
1014cd7ab4b5SAlexander Hederstaf                "const int inline static  volatile *const a;", Style);
1015cd7ab4b5SAlexander Hederstaf 
1016cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile a;",
1017cd7ab4b5SAlexander Hederstaf                "const inline static volatile Foo a;", Style);
1018cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile a;",
1019cd7ab4b5SAlexander Hederstaf                "volatile inline static const Foo a;", Style);
1020cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile a;",
1021cd7ab4b5SAlexander Hederstaf                "Foo const inline static  volatile a;", Style);
1022cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile a;",
1023cd7ab4b5SAlexander Hederstaf                "Foo volatile inline static  const a;", Style);
1024cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile a;",
1025cd7ab4b5SAlexander Hederstaf                "const Foo inline static  volatile a;", Style);
1026cd7ab4b5SAlexander Hederstaf 
1027cd7ab4b5SAlexander Hederstaf   verifyFormat("static inline Foo const volatile *const a;",
1028cd7ab4b5SAlexander Hederstaf                "const Foo inline static volatile *const a;", Style);
1029a44ab170Smydeveloperday }
1030a44ab170Smydeveloperday 
1031a44ab170Smydeveloperday TEST_F(QualifierFixerTest, PrepareLeftRightOrdering) {
1032a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
1033a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1034a44ab170Smydeveloperday   Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};
1035a44ab170Smydeveloperday 
1036a44ab170Smydeveloperday   std::vector<std::string> Left;
1037a44ab170Smydeveloperday   std::vector<std::string> Right;
1038a44ab170Smydeveloperday   std::vector<tok::TokenKind> ConfiguredTokens;
1039899c8677SSedenion   prepareLeftRightOrderingForQualifierAlignmentFixer(Style.QualifierOrder, Left,
1040a44ab170Smydeveloperday                                                      Right, ConfiguredTokens);
1041a44ab170Smydeveloperday 
104276d845cbSNemanja Ivanovic   EXPECT_EQ(Left.size(), (size_t)2);
104376d845cbSNemanja Ivanovic   EXPECT_EQ(Right.size(), (size_t)2);
1044a44ab170Smydeveloperday 
1045a44ab170Smydeveloperday   std::vector<std::string> LeftResult = {"inline", "static"};
1046a44ab170Smydeveloperday   std::vector<std::string> RightResult = {"const", "volatile"};
1047a44ab170Smydeveloperday   EXPECT_EQ(Left, LeftResult);
1048a44ab170Smydeveloperday   EXPECT_EQ(Right, RightResult);
1049a44ab170Smydeveloperday }
1050a44ab170Smydeveloperday 
1051a44ab170Smydeveloperday TEST_F(QualifierFixerTest, IsQualifierType) {
1052a44ab170Smydeveloperday 
1053a44ab170Smydeveloperday   std::vector<tok::TokenKind> ConfiguredTokens;
1054a44ab170Smydeveloperday   ConfiguredTokens.push_back(tok::kw_const);
1055a44ab170Smydeveloperday   ConfiguredTokens.push_back(tok::kw_static);
1056a44ab170Smydeveloperday   ConfiguredTokens.push_back(tok::kw_inline);
1057a44ab170Smydeveloperday   ConfiguredTokens.push_back(tok::kw_restrict);
1058a44ab170Smydeveloperday   ConfiguredTokens.push_back(tok::kw_constexpr);
10594cafc372SMicah Weston   ConfiguredTokens.push_back(tok::kw_friend);
1060a44ab170Smydeveloperday 
1061e20800c1SOwen Pan   TestLexer lexer{Allocator, Buffers};
1062364f988dSOwen Pan   const auto LangOpts = getFormattingLangOpts();
1063e20800c1SOwen Pan 
1064e20800c1SOwen Pan   auto Tokens = lexer.lex(
10654cafc372SMicah Weston       "const static inline auto restrict int double long constexpr friend");
106602362b1aSOwen Pan   ASSERT_EQ(Tokens.size(), 11u) << Tokens;
1067a44ab170Smydeveloperday 
1068364f988dSOwen Pan   EXPECT_TRUE(
1069364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[0], ConfiguredTokens, LangOpts));
1070364f988dSOwen Pan   EXPECT_TRUE(
1071364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[1], ConfiguredTokens, LangOpts));
1072364f988dSOwen Pan   EXPECT_TRUE(
1073364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[2], ConfiguredTokens, LangOpts));
1074364f988dSOwen Pan   EXPECT_TRUE(
1075364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[3], ConfiguredTokens, LangOpts));
1076364f988dSOwen Pan   EXPECT_TRUE(
1077364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[4], ConfiguredTokens, LangOpts));
1078364f988dSOwen Pan   EXPECT_TRUE(
1079364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[5], ConfiguredTokens, LangOpts));
1080364f988dSOwen Pan   EXPECT_TRUE(
1081364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[6], ConfiguredTokens, LangOpts));
1082364f988dSOwen Pan   EXPECT_TRUE(
1083364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[7], ConfiguredTokens, LangOpts));
1084364f988dSOwen Pan   EXPECT_TRUE(
1085364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[8], ConfiguredTokens, LangOpts));
1086364f988dSOwen Pan   EXPECT_TRUE(
1087364f988dSOwen Pan       isConfiguredQualifierOrType(Tokens[9], ConfiguredTokens, LangOpts));
1088a44ab170Smydeveloperday 
1089364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[0], LangOpts));
1090364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[1], LangOpts));
1091364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[2], LangOpts));
1092364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[3], LangOpts));
1093364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[4], LangOpts));
1094364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[5], LangOpts));
1095364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[6], LangOpts));
1096364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[7], LangOpts));
1097364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[8], LangOpts));
1098364f988dSOwen Pan   EXPECT_TRUE(isQualifierOrType(Tokens[9], LangOpts));
1099cd7ab4b5SAlexander Hederstaf 
1100e20800c1SOwen Pan   auto NotTokens = lexer.lex("for while do Foo Bar ");
110102362b1aSOwen Pan   ASSERT_EQ(NotTokens.size(), 6u) << Tokens;
1102a44ab170Smydeveloperday 
1103364f988dSOwen Pan   EXPECT_FALSE(
1104364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[0], ConfiguredTokens, LangOpts));
1105364f988dSOwen Pan   EXPECT_FALSE(
1106364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[1], ConfiguredTokens, LangOpts));
1107364f988dSOwen Pan   EXPECT_FALSE(
1108364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[2], ConfiguredTokens, LangOpts));
1109364f988dSOwen Pan   EXPECT_FALSE(
1110364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[3], ConfiguredTokens, LangOpts));
1111364f988dSOwen Pan   EXPECT_FALSE(
1112364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[4], ConfiguredTokens, LangOpts));
1113364f988dSOwen Pan   EXPECT_FALSE(
1114364f988dSOwen Pan       isConfiguredQualifierOrType(NotTokens[5], ConfiguredTokens, LangOpts));
1115cd7ab4b5SAlexander Hederstaf 
1116364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[0], LangOpts));
1117364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[1], LangOpts));
1118364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[2], LangOpts));
1119364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[3], LangOpts));
1120364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[4], LangOpts));
1121364f988dSOwen Pan   EXPECT_FALSE(isQualifierOrType(NotTokens[5], LangOpts));
1122a44ab170Smydeveloperday }
1123a44ab170Smydeveloperday 
1124a44ab170Smydeveloperday TEST_F(QualifierFixerTest, IsMacro) {
1125a44ab170Smydeveloperday 
1126a44ab170Smydeveloperday   auto Tokens = annotate("INT INTPR Foo int");
112702362b1aSOwen Pan   ASSERT_EQ(Tokens.size(), 5u) << Tokens;
1128a44ab170Smydeveloperday 
1129c72e9438SOwen Pan   EXPECT_TRUE(isPossibleMacro(Tokens[0]));
1130c72e9438SOwen Pan   EXPECT_TRUE(isPossibleMacro(Tokens[1]));
1131c72e9438SOwen Pan   EXPECT_FALSE(isPossibleMacro(Tokens[2]));
1132c72e9438SOwen Pan   EXPECT_FALSE(isPossibleMacro(Tokens[3]));
1133a44ab170Smydeveloperday }
1134a44ab170Smydeveloperday 
1135a44ab170Smydeveloperday TEST_F(QualifierFixerTest, OverlappingQualifier) {
1136a44ab170Smydeveloperday 
1137a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
1138a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
1139a44ab170Smydeveloperday   Style.QualifierOrder = {"const", "type"};
1140a44ab170Smydeveloperday 
1141a44ab170Smydeveloperday   verifyFormat("Foo(const Bar &name);", "Foo(Bar const &name);", Style);
1142a44ab170Smydeveloperday }
1143a44ab170Smydeveloperday 
1144a44ab170Smydeveloperday TEST_F(QualifierFixerTest, DontPushQualifierThroughNonSpecifiedTypes) {
1145a44ab170Smydeveloperday 
1146a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
1147a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
1148cd7ab4b5SAlexander Hederstaf   Style.QualifierOrder = {"const", "volatile", "type"};
1149a44ab170Smydeveloperday 
1150a44ab170Smydeveloperday   verifyFormat("inline static const int a;", Style);
1151a44ab170Smydeveloperday 
1152a44ab170Smydeveloperday   Style.QualifierOrder = {"static", "const", "type"};
1153a44ab170Smydeveloperday 
1154a44ab170Smydeveloperday   verifyFormat("inline static const int a;", Style);
115520b4df1eSOwen Pan   verifyFormat("static inline const int a;", Style);
1156a44ab170Smydeveloperday 
1157a44ab170Smydeveloperday   verifyFormat("static const int a;", "const static int a;", Style);
1158cd7ab4b5SAlexander Hederstaf 
1159cd7ab4b5SAlexander Hederstaf   Style.QualifierOrder = {"const", "volatile", "type"};
1160cd7ab4b5SAlexander Hederstaf   // static is not configured, unchanged at right hand qualifiers.
1161cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile int static;", "int volatile static const;",
1162cd7ab4b5SAlexander Hederstaf                Style);
1163cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile int static;", "int const static volatile;",
1164cd7ab4b5SAlexander Hederstaf                Style);
1165cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile int static;", "const int static volatile;",
1166cd7ab4b5SAlexander Hederstaf                Style);
1167cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo static;", "Foo volatile static const;",
1168cd7ab4b5SAlexander Hederstaf                Style);
1169cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo static;", "Foo const static volatile;",
1170cd7ab4b5SAlexander Hederstaf                Style);
1171cd7ab4b5SAlexander Hederstaf   verifyFormat("const volatile Foo static;", "const Foo static volatile;",
1172cd7ab4b5SAlexander Hederstaf                Style);
1173cd7ab4b5SAlexander Hederstaf 
1174cd7ab4b5SAlexander Hederstaf   verifyFormat("inline static const Foo;", "inline static Foo const;", Style);
117520b4df1eSOwen Pan   verifyFormat("inline static const Foo;", Style);
1176cd7ab4b5SAlexander Hederstaf 
1177cd7ab4b5SAlexander Hederstaf   // Don't move qualifiers to the right for aestethics only.
117820b4df1eSOwen Pan   verifyFormat("inline const static Foo;", Style);
117920b4df1eSOwen Pan   verifyFormat("const inline static Foo;", Style);
1180a44ab170Smydeveloperday }
1181a44ab170Smydeveloperday 
1182ea16a3bbSOwen Pan TEST_F(QualifierFixerTest, QualifiersBrokenUpByPPDirectives) {
1183ea16a3bbSOwen Pan   auto Style = getLLVMStyle();
1184ea16a3bbSOwen Pan   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1185ea16a3bbSOwen Pan   Style.QualifierOrder = {"constexpr", "inline", "type"};
1186ea16a3bbSOwen Pan 
1187ea16a3bbSOwen Pan   verifyFormat("inline\n"
1188ea16a3bbSOwen Pan                "#if FOO\n"
1189ea16a3bbSOwen Pan                "    constexpr\n"
1190ea16a3bbSOwen Pan                "#endif\n"
1191ea16a3bbSOwen Pan                "    int i = 0;",
1192ea16a3bbSOwen Pan                Style);
1193ea16a3bbSOwen Pan }
1194ea16a3bbSOwen Pan 
1195a44ab170Smydeveloperday TEST_F(QualifierFixerTest, UnsignedQualifier) {
1196a44ab170Smydeveloperday 
1197a44ab170Smydeveloperday   FormatStyle Style = getLLVMStyle();
1198a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Left;
1199a44ab170Smydeveloperday   Style.QualifierOrder = {"const", "type"};
1200a44ab170Smydeveloperday 
1201a44ab170Smydeveloperday   verifyFormat("Foo(const unsigned char *bytes)",
1202a44ab170Smydeveloperday                "Foo(unsigned const char *bytes)", Style);
1203a44ab170Smydeveloperday 
1204a44ab170Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Right;
1205a44ab170Smydeveloperday   Style.QualifierOrder = {"type", "const"};
1206a44ab170Smydeveloperday 
1207a44ab170Smydeveloperday   verifyFormat("Foo(unsigned char const *bytes)",
1208a44ab170Smydeveloperday                "Foo(unsigned const char *bytes)", Style);
1209a44ab170Smydeveloperday }
1210a44ab170Smydeveloperday 
1211c2ec5dd2Smydeveloperday TEST_F(QualifierFixerTest, NoOpQualifierReplacements) {
1212c2ec5dd2Smydeveloperday 
1213c2ec5dd2Smydeveloperday   FormatStyle Style = getLLVMStyle();
1214c2ec5dd2Smydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1215c2ec5dd2Smydeveloperday   Style.QualifierOrder = {"static", "const", "type"};
1216c2ec5dd2Smydeveloperday 
1217c2ec5dd2Smydeveloperday   verifyFormat("static const uint32 foo[] = {0, 31};", Style);
1218899c8677SSedenion   EXPECT_EQ(ReplacementCount, 0);
1219899c8677SSedenion 
1220eee536ddSowenca   verifyFormat("#define MACRO static const", Style);
1221899c8677SSedenion   EXPECT_EQ(ReplacementCount, 0);
1222899c8677SSedenion 
1223492cb7bfSOwen Pan   verifyFormat("using sc = static const", Style);
1224c2ec5dd2Smydeveloperday   EXPECT_EQ(ReplacementCount, 0);
1225c2ec5dd2Smydeveloperday }
1226c2ec5dd2Smydeveloperday 
1227031d3eceSmydeveloperday TEST_F(QualifierFixerTest, QualifierTemplates) {
1228031d3eceSmydeveloperday   FormatStyle Style = getLLVMStyle();
1229031d3eceSmydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1230031d3eceSmydeveloperday   Style.QualifierOrder = {"static", "const", "type"};
1231031d3eceSmydeveloperday 
1232031d3eceSmydeveloperday   ReplacementCount = 0;
1233031d3eceSmydeveloperday   EXPECT_EQ(ReplacementCount, 0);
1234031d3eceSmydeveloperday   verifyFormat("using A = B<>;", Style);
1235031d3eceSmydeveloperday   verifyFormat("using A = B /**/<>;", Style);
1236031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);
1237031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);
1238031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);
1239031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);
1240031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);
1241031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);
1242031d3eceSmydeveloperday   verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);
1243031d3eceSmydeveloperday   EXPECT_EQ(ReplacementCount, 0);
1244031d3eceSmydeveloperday   verifyFormat("template <class C>\n"
1245031d3eceSmydeveloperday                "using A = B // foo\n"
1246031d3eceSmydeveloperday                "    <Foo<C>, 1>;",
1247031d3eceSmydeveloperday                Style);
1248031d3eceSmydeveloperday 
1249031d3eceSmydeveloperday   ReplacementCount = 0;
1250031d3eceSmydeveloperday   Style.QualifierOrder = {"type", "static", "const"};
1251031d3eceSmydeveloperday   verifyFormat("using A = B<>;", Style);
1252031d3eceSmydeveloperday   verifyFormat("using A = B /**/<>;", Style);
1253031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);
1254031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);
1255031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);
1256031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);
1257031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);
1258031d3eceSmydeveloperday   verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);
1259031d3eceSmydeveloperday   verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);
1260031d3eceSmydeveloperday   EXPECT_EQ(ReplacementCount, 0);
1261031d3eceSmydeveloperday   verifyFormat("template <class C>\n"
1262031d3eceSmydeveloperday                "using A = B // foo\n"
1263031d3eceSmydeveloperday                "    <Foo<C>, 1>;",
1264031d3eceSmydeveloperday                Style);
1265031d3eceSmydeveloperday }
1266031d3eceSmydeveloperday 
126746f6c834SMarek Kurdej TEST_F(QualifierFixerTest, WithConstraints) {
126846f6c834SMarek Kurdej   FormatStyle Style = getLLVMStyle();
126946f6c834SMarek Kurdej   Style.QualifierAlignment = FormatStyle::QAS_Custom;
127046f6c834SMarek Kurdej   Style.QualifierOrder = {"constexpr", "type"};
127146f6c834SMarek Kurdej 
127246f6c834SMarek Kurdej   verifyFormat("template <typename T>\n"
127346f6c834SMarek Kurdej                "  requires Concept<F>\n"
127446f6c834SMarek Kurdej                "constexpr constructor();",
127546f6c834SMarek Kurdej                Style);
127646f6c834SMarek Kurdej   verifyFormat("template <typename T>\n"
127746f6c834SMarek Kurdej                "  requires Concept1<F> && Concept2<F>\n"
127846f6c834SMarek Kurdej                "constexpr constructor();",
127946f6c834SMarek Kurdej                Style);
128046f6c834SMarek Kurdej }
128146f6c834SMarek Kurdej 
1282*3bd8b02aSOwen Pan TEST_F(QualifierFixerTest, WithCpp11Attribute) {
1283*3bd8b02aSOwen Pan   FormatStyle Style = getLLVMStyle();
1284*3bd8b02aSOwen Pan   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1285*3bd8b02aSOwen Pan   Style.QualifierOrder = {"static", "constexpr", "inline", "type"};
1286*3bd8b02aSOwen Pan 
1287*3bd8b02aSOwen Pan   verifyFormat("[[nodiscard]] static constexpr inline int func() noexcept {}",
1288*3bd8b02aSOwen Pan                "[[nodiscard]] inline constexpr static int func() noexcept {}",
1289*3bd8b02aSOwen Pan                Style);
1290*3bd8b02aSOwen Pan   verifyFormat("[[maybe_unused]] static constexpr int A",
1291*3bd8b02aSOwen Pan                "[[maybe_unused]] constexpr static int A", Style);
1292*3bd8b02aSOwen Pan }
1293*3bd8b02aSOwen Pan 
1294e329b586SMarek Kurdej TEST_F(QualifierFixerTest, DisableRegions) {
1295e329b586SMarek Kurdej   FormatStyle Style = getLLVMStyle();
1296e329b586SMarek Kurdej   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1297e329b586SMarek Kurdej   Style.QualifierOrder = {"inline", "static", "const", "type"};
1298e329b586SMarek Kurdej 
1299e329b586SMarek Kurdej   ReplacementCount = 0;
1300e329b586SMarek Kurdej   verifyFormat("// clang-format off\n"
1301e329b586SMarek Kurdej                "int const inline static a = 0;\n"
13026c3bc910SOwen Pan                "// clang-format on",
1303e329b586SMarek Kurdej                Style);
1304e329b586SMarek Kurdej   EXPECT_EQ(ReplacementCount, 0);
1305e329b586SMarek Kurdej   verifyFormat("// clang-format off\n"
1306e329b586SMarek Kurdej                "int const inline static a = 0;\n"
1307e329b586SMarek Kurdej                "// clang-format on\n"
13086c3bc910SOwen Pan                "inline static const int a = 0;",
1309e329b586SMarek Kurdej                "// clang-format off\n"
1310e329b586SMarek Kurdej                "int const inline static a = 0;\n"
1311e329b586SMarek Kurdej                "// clang-format on\n"
13126c3bc910SOwen Pan                "int const inline static a = 0;",
1313e329b586SMarek Kurdej                Style);
1314e329b586SMarek Kurdej }
1315e329b586SMarek Kurdej 
131628bb040dSmydeveloperday TEST_F(QualifierFixerTest, TemplatesRight) {
131728bb040dSmydeveloperday   FormatStyle Style = getLLVMStyle();
131828bb040dSmydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
131928bb040dSmydeveloperday   Style.QualifierOrder = {"type", "const"};
132028bb040dSmydeveloperday 
1321cd7ab4b5SAlexander Hederstaf   verifyFormat("template <typename T> Foo const f();",
1322cd7ab4b5SAlexander Hederstaf                "template <typename T> const Foo f();", Style);
1323cd7ab4b5SAlexander Hederstaf   verifyFormat("template <typename T> int const f();",
1324cd7ab4b5SAlexander Hederstaf                "template <typename T> const int f();", Style);
1325cd7ab4b5SAlexander Hederstaf 
1326cd7ab4b5SAlexander Hederstaf   verifyFormat("template <T const> t;", "template <const T> t;", Style);
132728bb040dSmydeveloperday   verifyFormat("template <typename T>\n"
132828bb040dSmydeveloperday                "  requires Concept<T const>\n"
1329cd7ab4b5SAlexander Hederstaf                "Foo const f();",
133028bb040dSmydeveloperday                "template <typename T>\n"
133128bb040dSmydeveloperday                "  requires Concept<const T>\n"
1332cd7ab4b5SAlexander Hederstaf                "const Foo f();",
133328bb040dSmydeveloperday                Style);
133428bb040dSmydeveloperday   verifyFormat("TemplateType<T const> t;", "TemplateType<const T> t;", Style);
133528bb040dSmydeveloperday   verifyFormat("TemplateType<Container const> t;",
133628bb040dSmydeveloperday                "TemplateType<const Container> t;", Style);
133728bb040dSmydeveloperday }
133828bb040dSmydeveloperday 
133928bb040dSmydeveloperday TEST_F(QualifierFixerTest, TemplatesLeft) {
134028bb040dSmydeveloperday   FormatStyle Style = getLLVMStyle();
134128bb040dSmydeveloperday   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1342cd7ab4b5SAlexander Hederstaf   Style.QualifierOrder = {"const", "volatile", "type"};
1343cd7ab4b5SAlexander Hederstaf 
1344cd7ab4b5SAlexander Hederstaf   verifyFormat("template <typename T> const Foo f();",
1345cd7ab4b5SAlexander Hederstaf                "template <typename T> Foo const f();", Style);
1346cd7ab4b5SAlexander Hederstaf   verifyFormat("template <typename T> const int f();",
1347cd7ab4b5SAlexander Hederstaf                "template <typename T> int const f();", Style);
134828bb040dSmydeveloperday 
134928bb040dSmydeveloperday   verifyFormat("template <const T> t;", "template <T const> t;", Style);
135028bb040dSmydeveloperday   verifyFormat("template <typename T>\n"
135128bb040dSmydeveloperday                "  requires Concept<const T>\n"
1352cd7ab4b5SAlexander Hederstaf                "const Foo f();",
135328bb040dSmydeveloperday                "template <typename T>\n"
135428bb040dSmydeveloperday                "  requires Concept<T const>\n"
1355cd7ab4b5SAlexander Hederstaf                "Foo const f();",
1356cd7ab4b5SAlexander Hederstaf                Style);
1357cd7ab4b5SAlexander Hederstaf   verifyFormat("template <typename T>\n"
1358cd7ab4b5SAlexander Hederstaf                "  requires Concept<const T>\n"
1359cd7ab4b5SAlexander Hederstaf                "const volatile Foo f();",
1360cd7ab4b5SAlexander Hederstaf                "template <typename T>\n"
1361cd7ab4b5SAlexander Hederstaf                "  requires Concept<T const>\n"
1362cd7ab4b5SAlexander Hederstaf                "volatile const Foo f();",
136328bb040dSmydeveloperday                Style);
136428bb040dSmydeveloperday   verifyFormat("TemplateType<const T> t;", "TemplateType<T const> t;", Style);
136528bb040dSmydeveloperday   verifyFormat("TemplateType<const Container> t;",
136628bb040dSmydeveloperday                "TemplateType<Container const> t;", Style);
136728bb040dSmydeveloperday }
136828bb040dSmydeveloperday 
1369f3dcd3adSColin Ogilvie TEST_F(QualifierFixerTest, Ranges) {
1370f3dcd3adSColin Ogilvie   FormatStyle Style = getLLVMStyle();
1371f3dcd3adSColin Ogilvie   Style.QualifierAlignment = FormatStyle::QAS_Custom;
1372f3dcd3adSColin Ogilvie   Style.QualifierOrder = {"const", "volatile", "type"};
1373f3dcd3adSColin Ogilvie 
1374f3dcd3adSColin Ogilvie   // Only the first line should be formatted; the second should remain as is.
1375f3dcd3adSColin Ogilvie   verifyFormat("template <typename T> const Foo f();\n"
1376f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();",
1377f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();\n"
1378f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();",
1379f3dcd3adSColin Ogilvie                Style, {tooling::Range(0, 36)});
1380f3dcd3adSColin Ogilvie 
1381f3dcd3adSColin Ogilvie   // Only the middle line should be formatted; the first and last should remain
1382f3dcd3adSColin Ogilvie   // as is.
1383f3dcd3adSColin Ogilvie   verifyFormat("template <typename T> Foo const f();\n"
1384f3dcd3adSColin Ogilvie                "template <typename T> const Foo f();\n"
1385f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();",
1386f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();\n"
1387f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();\n"
1388f3dcd3adSColin Ogilvie                "template <typename T> Foo const f();",
1389f3dcd3adSColin Ogilvie                Style, {tooling::Range(37, 36)});
1390f3dcd3adSColin Ogilvie }
1391f3dcd3adSColin Ogilvie 
1392f8d10d5aSManuel Klimek } // namespace
1393f8d10d5aSManuel Klimek } // namespace test
1394a44ab170Smydeveloperday } // namespace format
1395a44ab170Smydeveloperday } // namespace clang
1396