1 //===- unittest/Format/QualifierFixerTest.cpp - Formatting unit tests -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "clang/Format/Format.h"
10
11 #include "FormatTestUtils.h"
12 #include "TestLexer.h"
13 #include "gtest/gtest.h"
14
15 #include "../../lib/Format/QualifierAlignmentFixer.h"
16
17 #define DEBUG_TYPE "format-qualifier-fixer-test"
18
19 using testing::ScopedTrace;
20
21 namespace clang {
22 namespace format {
23 namespace {
24
25 #define CHECK_PARSE(TEXT, FIELD, VALUE) \
26 EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!"; \
27 EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \
28 EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
29
30 #define FAIL_PARSE(TEXT, FIELD, VALUE) \
31 EXPECT_NE(0, parseConfiguration(TEXT, &Style).value()); \
32 EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
33
34 class QualifierFixerTest : public ::testing::Test {
35 protected:
36 enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck };
37
annotate(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())38 TokenList annotate(llvm::StringRef Code,
39 const FormatStyle &Style = getLLVMStyle()) {
40 return TestLexer(Allocator, Buffers, Style).annotate(Code);
41 }
42 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
43 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
44
format(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle (),StatusCheck CheckComplete=SC_ExpectComplete)45 std::string format(llvm::StringRef Code,
46 const FormatStyle &Style = getLLVMStyle(),
47 StatusCheck CheckComplete = SC_ExpectComplete) {
48 LLVM_DEBUG(llvm::errs() << "---\n");
49 LLVM_DEBUG(llvm::errs() << Code << "\n\n");
50 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
51 FormattingAttemptStatus Status;
52 tooling::Replacements Replaces =
53 reformat(Style, Code, Ranges, "<stdin>", &Status);
54 if (CheckComplete != SC_DoNotCheck) {
55 bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete;
56 EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete)
57 << Code << "\n\n";
58 }
59 ReplacementCount = Replaces.size();
60 auto Result = applyAllReplacements(Code, Replaces);
61 EXPECT_TRUE(static_cast<bool>(Result));
62 LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
63 return *Result;
64 }
65
getStyleWithColumns(FormatStyle Style,unsigned ColumnLimit)66 FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) {
67 Style.ColumnLimit = ColumnLimit;
68 return Style;
69 }
70
getLLVMStyleWithColumns(unsigned ColumnLimit)71 FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
72 return getStyleWithColumns(getLLVMStyle(), ColumnLimit);
73 }
74
_verifyFormat(const char * File,int Line,llvm::StringRef Expected,llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())75 void _verifyFormat(const char *File, int Line, llvm::StringRef Expected,
76 llvm::StringRef Code,
77 const FormatStyle &Style = getLLVMStyle()) {
78 ScopedTrace t(File, Line, ::testing::Message() << Code.str());
79 EXPECT_EQ(Expected.str(), format(Expected, Style))
80 << "Expected code is not stable";
81 EXPECT_EQ(Expected.str(), format(Code, Style));
82 if (Style.Language == FormatStyle::LK_Cpp) {
83 // Objective-C++ is a superset of C++, so everything checked for C++
84 // needs to be checked for Objective-C++ as well.
85 FormatStyle ObjCStyle = Style;
86 ObjCStyle.Language = FormatStyle::LK_ObjC;
87 EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle));
88 }
89 }
90
_verifyFormat(const char * File,int Line,llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())91 void _verifyFormat(const char *File, int Line, llvm::StringRef Code,
92 const FormatStyle &Style = getLLVMStyle()) {
93 _verifyFormat(File, Line, Code, test::messUp(Code), Style);
94 }
95
_verifyIncompleteFormat(const char * File,int Line,llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())96 void _verifyIncompleteFormat(const char *File, int Line, llvm::StringRef Code,
97 const FormatStyle &Style = getLLVMStyle()) {
98 ScopedTrace t(File, Line, ::testing::Message() << Code.str());
99 EXPECT_EQ(Code.str(),
100 format(test::messUp(Code), Style, SC_ExpectIncomplete));
101 }
102
_verifyIndependentOfContext(const char * File,int Line,llvm::StringRef Text,const FormatStyle & Style=getLLVMStyle ())103 void _verifyIndependentOfContext(const char *File, int Line,
104 llvm::StringRef Text,
105 const FormatStyle &Style = getLLVMStyle()) {
106 _verifyFormat(File, Line, Text, Style);
107 _verifyFormat(File, Line, llvm::Twine("void f() { " + Text + " }").str(),
108 Style);
109 }
110
111 /// \brief Verify that clang-format does not crash on the given input.
verifyNoCrash(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())112 void verifyNoCrash(llvm::StringRef Code,
113 const FormatStyle &Style = getLLVMStyle()) {
114 format(Code, Style, SC_DoNotCheck);
115 }
116
117 int ReplacementCount;
118 };
119
120 #define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
121
122 } // namespace
123
TEST_F(QualifierFixerTest,RotateTokens)124 TEST_F(QualifierFixerTest, RotateTokens) {
125 // TODO add test
126 EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("const"),
127 tok::kw_const);
128 EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("volatile"),
129 tok::kw_volatile);
130 EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("inline"),
131 tok::kw_inline);
132 EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("static"),
133 tok::kw_static);
134 EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("restrict"),
135 tok::kw_restrict);
136 }
137
TEST_F(QualifierFixerTest,FailQualifierInvalidConfiguration)138 TEST_F(QualifierFixerTest, FailQualifierInvalidConfiguration) {
139 FormatStyle Style = {};
140 Style.Language = FormatStyle::LK_Cpp;
141 FAIL_PARSE("QualifierAlignment: Custom\n"
142 "QualifierOrder: [const, volatile, apples, type]",
143 QualifierOrder,
144 std::vector<std::string>({"const", "volatile", "apples", "type"}));
145 }
146
TEST_F(QualifierFixerTest,FailQualifierDuplicateConfiguration)147 TEST_F(QualifierFixerTest, FailQualifierDuplicateConfiguration) {
148 FormatStyle Style = {};
149 Style.Language = FormatStyle::LK_Cpp;
150 FAIL_PARSE("QualifierAlignment: Custom\n"
151 "QualifierOrder: [const, volatile, const, type]",
152 QualifierOrder,
153 std::vector<std::string>({"const", "volatile", "const", "type"}));
154 }
155
TEST_F(QualifierFixerTest,FailQualifierMissingType)156 TEST_F(QualifierFixerTest, FailQualifierMissingType) {
157 FormatStyle Style = {};
158 Style.Language = FormatStyle::LK_Cpp;
159 FAIL_PARSE("QualifierAlignment: Custom\n"
160 "QualifierOrder: [const, volatile ]",
161 QualifierOrder,
162 std::vector<std::string>({
163 "const",
164 "volatile",
165 }));
166 }
167
TEST_F(QualifierFixerTest,FailQualifierEmptyOrder)168 TEST_F(QualifierFixerTest, FailQualifierEmptyOrder) {
169 FormatStyle Style = {};
170 Style.Language = FormatStyle::LK_Cpp;
171 FAIL_PARSE("QualifierAlignment: Custom\nQualifierOrder: []", QualifierOrder,
172 std::vector<std::string>({}));
173 }
174
TEST_F(QualifierFixerTest,FailQualifierMissingOrder)175 TEST_F(QualifierFixerTest, FailQualifierMissingOrder) {
176 FormatStyle Style = {};
177 Style.Language = FormatStyle::LK_Cpp;
178 FAIL_PARSE("QualifierAlignment: Custom", QualifierOrder,
179 std::vector<std::string>());
180 }
181
TEST_F(QualifierFixerTest,QualifierLeft)182 TEST_F(QualifierFixerTest, QualifierLeft) {
183 FormatStyle Style = {};
184 Style.Language = FormatStyle::LK_Cpp;
185 CHECK_PARSE("QualifierAlignment: Left", QualifierOrder,
186 std::vector<std::string>({"const", "volatile", "type"}));
187 }
188
TEST_F(QualifierFixerTest,QualifierRight)189 TEST_F(QualifierFixerTest, QualifierRight) {
190 FormatStyle Style = {};
191 Style.Language = FormatStyle::LK_Cpp;
192 CHECK_PARSE("QualifierAlignment: Right", QualifierOrder,
193 std::vector<std::string>({"type", "const", "volatile"}));
194 }
195
TEST_F(QualifierFixerTest,QualifiersCustomOrder)196 TEST_F(QualifierFixerTest, QualifiersCustomOrder) {
197 FormatStyle Style = getLLVMStyle();
198 Style.QualifierAlignment = FormatStyle::QAS_Left;
199 Style.QualifierOrder = {"inline", "constexpr", "static",
200 "const", "volatile", "type"};
201
202 verifyFormat("const volatile int a;", "const volatile int a;", Style);
203 verifyFormat("const volatile int a;", "volatile const int a;", Style);
204 verifyFormat("const volatile int a;", "int const volatile a;", Style);
205 verifyFormat("const volatile int a;", "int volatile const a;", Style);
206 verifyFormat("const volatile int a;", "const int volatile a;", Style);
207
208 verifyFormat("static const volatile int a;", "const static int volatile a;",
209 Style);
210 verifyFormat("inline static const volatile int a;",
211 "const static inline int volatile a;", Style);
212
213 verifyFormat("constexpr static int a;", "static constexpr int a;", Style);
214 verifyFormat("constexpr static int A;", "static constexpr int A;", Style);
215 verifyFormat("constexpr static int Bar;", "static constexpr int Bar;", Style);
216 verifyFormat("constexpr static LPINT Bar;", "static constexpr LPINT Bar;",
217 Style);
218 verifyFormat("const const int a;", "const int const a;", Style);
219 }
220
TEST_F(QualifierFixerTest,LeftRightQualifier)221 TEST_F(QualifierFixerTest, LeftRightQualifier) {
222 FormatStyle Style = getLLVMStyle();
223
224 // keep the const style unaltered
225 verifyFormat("const int a;", Style);
226 verifyFormat("const int *a;", Style);
227 verifyFormat("const int &a;", Style);
228 verifyFormat("const int &&a;", Style);
229 verifyFormat("int const b;", Style);
230 verifyFormat("int const *b;", Style);
231 verifyFormat("int const &b;", Style);
232 verifyFormat("int const &&b;", Style);
233 verifyFormat("int const *b const;", Style);
234 verifyFormat("int *const c;", Style);
235
236 verifyFormat("const Foo a;", Style);
237 verifyFormat("const Foo *a;", Style);
238 verifyFormat("const Foo &a;", Style);
239 verifyFormat("const Foo &&a;", Style);
240 verifyFormat("Foo const b;", Style);
241 verifyFormat("Foo const *b;", Style);
242 verifyFormat("Foo const &b;", Style);
243 verifyFormat("Foo const &&b;", Style);
244 verifyFormat("Foo const *b const;", Style);
245
246 verifyFormat("LLVM_NODISCARD const int &Foo();", Style);
247 verifyFormat("LLVM_NODISCARD int const &Foo();", Style);
248
249 verifyFormat("volatile const int *restrict;", Style);
250 verifyFormat("const volatile int *restrict;", Style);
251 verifyFormat("const int volatile *restrict;", Style);
252 }
253
TEST_F(QualifierFixerTest,RightQualifier)254 TEST_F(QualifierFixerTest, RightQualifier) {
255 FormatStyle Style = getLLVMStyle();
256 Style.QualifierAlignment = FormatStyle::QAS_Right;
257 Style.QualifierOrder = {"type", "const", "volatile"};
258
259 verifyFormat("int const a;", Style);
260 verifyFormat("int const *a;", Style);
261 verifyFormat("int const &a;", Style);
262 verifyFormat("int const &&a;", Style);
263 verifyFormat("int const b;", Style);
264 verifyFormat("int const *b;", Style);
265 verifyFormat("int const &b;", Style);
266 verifyFormat("int const &&b;", Style);
267 verifyFormat("int const *b const;", Style);
268 verifyFormat("int *const c;", Style);
269
270 verifyFormat("Foo const a;", Style);
271 verifyFormat("Foo const *a;", Style);
272 verifyFormat("Foo const &a;", Style);
273 verifyFormat("Foo const &&a;", Style);
274 verifyFormat("Foo const b;", Style);
275 verifyFormat("Foo const *b;", Style);
276 verifyFormat("Foo const &b;", Style);
277 verifyFormat("Foo const &&b;", Style);
278 verifyFormat("Foo const *b const;", Style);
279 verifyFormat("Foo *const b;", Style);
280 verifyFormat("Foo const *const b;", Style);
281 verifyFormat("auto const v = get_value();", Style);
282 verifyFormat("long long const &a;", Style);
283 verifyFormat("unsigned char const *a;", Style);
284 verifyFormat("int main(int const argc, char const *const *const argv)",
285 Style);
286
287 verifyFormat("LLVM_NODISCARD int const &Foo();", Style);
288 verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY",
289 Style);
290 verifyFormat("void foo() const override;", Style);
291 verifyFormat("void foo() const override LLVM_READONLY;", Style);
292 verifyFormat("void foo() const final;", Style);
293 verifyFormat("void foo() const final LLVM_READONLY;", Style);
294 verifyFormat("void foo() const LLVM_READONLY;", Style);
295
296 verifyFormat(
297 "template <typename Func> explicit Action(Action<Func> const &action);",
298 Style);
299 verifyFormat(
300 "template <typename Func> explicit Action(Action<Func> const &action);",
301 "template <typename Func> explicit Action(const Action<Func>& action);",
302 Style);
303 verifyFormat(
304 "template <typename Func> explicit Action(Action<Func> const &action);",
305 "template <typename Func>\nexplicit Action(const Action<Func>& action);",
306 Style);
307
308 verifyFormat("int const a;", "const int a;", Style);
309 verifyFormat("int const *a;", "const int *a;", Style);
310 verifyFormat("int const &a;", "const int &a;", Style);
311 verifyFormat("foo(int const &a)", "foo(const int &a)", Style);
312 verifyFormat("unsigned char *a;", "unsigned char *a;", Style);
313 verifyFormat("unsigned char const *a;", "const unsigned char *a;", Style);
314 verifyFormat("vector<int, int const, int &, int const &> args1",
315 "vector<int, const int, int &, const int &> args1", Style);
316 verifyFormat("unsigned int const &get_nu() const",
317 "const unsigned int &get_nu() const", Style);
318 verifyFormat("Foo<int> const &a", "const Foo<int> &a", Style);
319 verifyFormat("Foo<int>::iterator const &a", "const Foo<int>::iterator &a",
320 Style);
321 verifyFormat("::Foo<int>::iterator const &a", "const ::Foo<int>::iterator &a",
322 Style);
323
324 verifyFormat("Foo(int a, "
325 "unsigned b, // c-style args\n"
326 " Bar const &c);",
327 "Foo(int a, "
328 "unsigned b, // c-style args\n"
329 " const Bar &c);",
330 Style);
331
332 verifyFormat("int const volatile;", "volatile const int;", Style);
333 verifyFormat("int const volatile;", "const volatile int;", Style);
334 verifyFormat("int const volatile;", "const int volatile;", Style);
335 verifyFormat("int const volatile *restrict;", "volatile const int *restrict;",
336 Style);
337 verifyFormat("int const volatile *restrict;", "const volatile int *restrict;",
338 Style);
339 verifyFormat("int const volatile *restrict;", "const int volatile *restrict;",
340 Style);
341
342 verifyFormat("static int const bat;", "static const int bat;", Style);
343 verifyFormat("static int const bat;", "static int const bat;", Style);
344
345 verifyFormat("int const Foo<int>::bat = 0;", "const int Foo<int>::bat = 0;",
346 Style);
347 verifyFormat("int const Foo<int>::bat = 0;", "int const Foo<int>::bat = 0;",
348 Style);
349 verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);
350 verifyFormat("int const Foo<int>::fn() {", "int const Foo<int>::fn() {",
351 Style);
352 verifyFormat("Foo<Foo<int>> const *p;", "const Foo<Foo<int>> *p;", Style);
353 verifyFormat(
354 "Foo<Foo<int>> const *p = const_cast<Foo<Foo<int>> const *>(&ffi);",
355 "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",
356 Style);
357
358 verifyFormat("void fn(Foo<T> const &i);", "void fn(const Foo<T> &i);", Style);
359 verifyFormat("void fns(ns::S const &s);", "void fns(const ns::S &s);", Style);
360 verifyFormat("void fns(::ns::S const &s);", "void fns(const ::ns::S &s);",
361 Style);
362 verifyFormat("void fn(ns::Foo<T> const &i);", "void fn(const ns::Foo<T> &i);",
363 Style);
364 verifyFormat("void fns(ns::ns2::S const &s);",
365 "void fns(const ns::ns2::S &s);", Style);
366 verifyFormat("void fn(ns::Foo<Bar<T>> const &i);",
367 "void fn(const ns::Foo<Bar<T>> &i);", Style);
368 verifyFormat("void fn(ns::ns2::Foo<Bar<T>> const &i);",
369 "void fn(const ns::ns2::Foo<Bar<T>> &i);", Style);
370 verifyFormat("void fn(ns::ns2::Foo<Bar<T, U>> const &i);",
371 "void fn(const ns::ns2::Foo<Bar<T, U>> &i);", Style);
372
373 verifyFormat("LocalScope const *Scope = nullptr;",
374 "const LocalScope* Scope = nullptr;", Style);
375 verifyFormat("struct DOTGraphTraits<Stmt const *>",
376 "struct DOTGraphTraits<const Stmt *>", Style);
377
378 verifyFormat(
379 "bool tools::addXRayRuntime(ToolChain const &TC, ArgList const &Args) {",
380 "bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args) {",
381 Style);
382 verifyFormat("Foo<Foo<int> const> P;", "Foo<const Foo<int>> P;", Style);
383 verifyFormat("Foo<Foo<int> const> P;\n", "Foo<const Foo<int>> P;\n", Style);
384 verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",
385 "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);
386
387 verifyFormat("auto const i = 0;", "const auto i = 0;", Style);
388 verifyFormat("auto const &ir = i;", "const auto &ir = i;", Style);
389 verifyFormat("auto const *ip = &i;", "const auto *ip = &i;", Style);
390
391 verifyFormat("Foo<Foo<int> const> P;\n#if 0\n#else\n#endif",
392 "Foo<const Foo<int>> P;\n#if 0\n#else\n#endif", Style);
393
394 verifyFormat("Bar<Bar<int const> const> P;\n#if 0\n#else\n#endif",
395 "Bar<Bar<const int> const> P;\n#if 0\n#else\n#endif", Style);
396
397 verifyFormat("Baz<Baz<int const> const> P;\n#if 0\n#else\n#endif",
398 "Baz<const Baz<const int>> P;\n#if 0\n#else\n#endif", Style);
399
400 // verifyFormat("#if 0\nBoo<Boo<int const> const> P;\n#else\n#endif",
401 // "#if 0\nBoo<const Boo<const int>> P;\n#else\n#endif", Style);
402
403 verifyFormat("int const P;\n#if 0\n#else\n#endif",
404 "const int P;\n#if 0\n#else\n#endif", Style);
405
406 verifyFormat("unsigned long const a;", "const unsigned long a;", Style);
407 verifyFormat("unsigned long long const a;", "const unsigned long long a;",
408 Style);
409
410 // don't adjust macros
411 verifyFormat("const INTPTR a;", "const INTPTR a;", Style);
412 }
413
TEST_F(QualifierFixerTest,LeftQualifier)414 TEST_F(QualifierFixerTest, LeftQualifier) {
415 FormatStyle Style = getLLVMStyle();
416 Style.QualifierAlignment = FormatStyle::QAS_Left;
417 Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
418
419 verifyFormat("const int a;", Style);
420 verifyFormat("const int *a;", Style);
421 verifyFormat("const int &a;", Style);
422 verifyFormat("const int &&a;", Style);
423 verifyFormat("const int b;", Style);
424 verifyFormat("const int *b;", Style);
425 verifyFormat("const int &b;", Style);
426 verifyFormat("const int &&b;", Style);
427 verifyFormat("const int *b const;", Style);
428 verifyFormat("int *const c;", Style);
429
430 verifyFormat("const Foo a;", Style);
431 verifyFormat("const Foo *a;", Style);
432 verifyFormat("const Foo &a;", Style);
433 verifyFormat("const Foo &&a;", Style);
434 verifyFormat("const Foo b;", Style);
435 verifyFormat("const Foo *b;", Style);
436 verifyFormat("const Foo &b;", Style);
437 verifyFormat("const Foo &&b;", Style);
438 verifyFormat("const Foo *b const;", Style);
439 verifyFormat("Foo *const b;", Style);
440 verifyFormat("const Foo *const b;", Style);
441
442 verifyFormat("LLVM_NODISCARD const int &Foo();", Style);
443
444 verifyFormat("const char a[];", Style);
445 verifyFormat("const auto v = get_value();", Style);
446 verifyFormat("const long long &a;", Style);
447 verifyFormat("const unsigned char *a;", Style);
448 verifyFormat("const unsigned char *a;", "unsigned char const *a;", Style);
449 verifyFormat("const Foo<int> &a", "Foo<int> const &a", Style);
450 verifyFormat("const Foo<int>::iterator &a", "Foo<int>::iterator const &a",
451 Style);
452 verifyFormat("const ::Foo<int>::iterator &a", "::Foo<int>::iterator const &a",
453 Style);
454
455 verifyFormat("const int a;", "int const a;", Style);
456 verifyFormat("const int *a;", "int const *a;", Style);
457 verifyFormat("const int &a;", "int const &a;", Style);
458 verifyFormat("foo(const int &a)", "foo(int const &a)", Style);
459 verifyFormat("unsigned char *a;", "unsigned char *a;", Style);
460 verifyFormat("const unsigned int &get_nu() const",
461 "unsigned int const &get_nu() const", Style);
462
463 verifyFormat("const volatile int;", "volatile const int;", Style);
464 verifyFormat("const volatile int;", "const volatile int;", Style);
465 verifyFormat("const volatile int;", "const int volatile;", Style);
466
467 verifyFormat("const volatile int *restrict;", "volatile const int *restrict;",
468 Style);
469 verifyFormat("const volatile int *restrict;", "const volatile int *restrict;",
470 Style);
471 verifyFormat("const volatile int *restrict;", "const int volatile *restrict;",
472 Style);
473
474 verifyFormat("SourceRange getSourceRange() const override LLVM_READONLY;",
475 Style);
476
477 verifyFormat("void foo() const override;", Style);
478 verifyFormat("void foo() const override LLVM_READONLY;", Style);
479 verifyFormat("void foo() const final;", Style);
480 verifyFormat("void foo() const final LLVM_READONLY;", Style);
481 verifyFormat("void foo() const LLVM_READONLY;", Style);
482
483 verifyFormat(
484 "template <typename Func> explicit Action(const Action<Func> &action);",
485 Style);
486 verifyFormat(
487 "template <typename Func> explicit Action(const Action<Func> &action);",
488 "template <typename Func> explicit Action(Action<Func> const &action);",
489 Style);
490
491 verifyFormat("static const int bat;", "static const int bat;", Style);
492 verifyFormat("static const int bat;", "static int const bat;", Style);
493
494 verifyFormat("static const int Foo<int>::bat = 0;",
495 "static const int Foo<int>::bat = 0;", Style);
496 verifyFormat("static const int Foo<int>::bat = 0;",
497 "static int const Foo<int>::bat = 0;", Style);
498
499 verifyFormat("void fn(const Foo<T> &i);");
500
501 verifyFormat("const int Foo<int>::bat = 0;", "const int Foo<int>::bat = 0;",
502 Style);
503 verifyFormat("const int Foo<int>::bat = 0;", "int const Foo<int>::bat = 0;",
504 Style);
505 verifyFormat("void fn(const Foo<T> &i);", "void fn( Foo<T> const &i);",
506 Style);
507 verifyFormat("const int Foo<int>::fn() {", "int const Foo<int>::fn() {",
508 Style);
509 verifyFormat("const Foo<Foo<int>> *p;", "Foo<Foo<int>> const *p;", Style);
510 verifyFormat(
511 "const Foo<Foo<int>> *p = const_cast<const Foo<Foo<int>> *>(&ffi);",
512 "const Foo<Foo<int>> *p = const_cast<Foo<Foo<int>> const *>(&ffi);",
513 Style);
514
515 verifyFormat("void fn(const Foo<T> &i);", "void fn(Foo<T> const &i);", Style);
516 verifyFormat("void fns(const ns::S &s);", "void fns(ns::S const &s);", Style);
517 verifyFormat("void fns(const ::ns::S &s);", "void fns(::ns::S const &s);",
518 Style);
519 verifyFormat("void fn(const ns::Foo<T> &i);", "void fn(ns::Foo<T> const &i);",
520 Style);
521 verifyFormat("void fns(const ns::ns2::S &s);",
522 "void fns(ns::ns2::S const &s);", Style);
523 verifyFormat("void fn(const ns::Foo<Bar<T>> &i);",
524 "void fn(ns::Foo<Bar<T>> const &i);", Style);
525 verifyFormat("void fn(const ns::ns2::Foo<Bar<T>> &i);",
526 "void fn(ns::ns2::Foo<Bar<T>> const &i);", Style);
527 verifyFormat("void fn(const ns::ns2::Foo<Bar<T, U>> &i);",
528 "void fn(ns::ns2::Foo<Bar<T, U>> const &i);", Style);
529
530 verifyFormat("const auto i = 0;", "auto const i = 0;", Style);
531 verifyFormat("const auto &ir = i;", "auto const &ir = i;", Style);
532 verifyFormat("const auto *ip = &i;", "auto const *ip = &i;", Style);
533
534 verifyFormat("Foo<const Foo<int>> P;\n#if 0\n#else\n#endif",
535 "Foo<Foo<int> const> P;\n#if 0\n#else\n#endif", Style);
536
537 verifyFormat("Foo<Foo<const int>> P;\n#if 0\n#else\n#endif",
538 "Foo<Foo<int const>> P;\n#if 0\n#else\n#endif", Style);
539
540 verifyFormat("const int P;\n#if 0\n#else\n#endif",
541 "int const P;\n#if 0\n#else\n#endif", Style);
542
543 verifyFormat("const unsigned long a;", "unsigned long const a;", Style);
544 verifyFormat("const unsigned long long a;", "unsigned long long const a;",
545 Style);
546
547 verifyFormat("const long long unsigned a;", "long const long unsigned a;",
548 Style);
549
550 verifyFormat("const std::Foo", "const std::Foo", Style);
551 verifyFormat("const std::Foo<>", "const std::Foo<>", Style);
552 verifyFormat("const std::Foo < int", "const std::Foo<int", Style);
553 verifyFormat("const std::Foo<int>", "const std::Foo<int>", Style);
554
555 // don't adjust macros
556 verifyFormat("INTPTR const a;", "INTPTR const a;", Style);
557 }
558
TEST_F(QualifierFixerTest,ConstVolatileQualifiersOrder)559 TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) {
560 FormatStyle Style = getLLVMStyle();
561 Style.QualifierAlignment = FormatStyle::QAS_Left;
562 Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
563
564 // The Default
565 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
566
567 verifyFormat("const volatile int a;", "const volatile int a;", Style);
568 verifyFormat("const volatile int a;", "volatile const int a;", Style);
569 verifyFormat("const volatile int a;", "int const volatile a;", Style);
570 verifyFormat("const volatile int a;", "int volatile const a;", Style);
571 verifyFormat("const volatile int a;", "const int volatile a;", Style);
572
573 Style.QualifierAlignment = FormatStyle::QAS_Right;
574 Style.QualifierOrder = {"type", "const", "volatile"};
575
576 verifyFormat("int const volatile a;", "const volatile int a;", Style);
577 verifyFormat("int const volatile a;", "volatile const int a;", Style);
578 verifyFormat("int const volatile a;", "int const volatile a;", Style);
579 verifyFormat("int const volatile a;", "int volatile const a;", Style);
580 verifyFormat("int const volatile a;", "const int volatile a;", Style);
581
582 Style.QualifierAlignment = FormatStyle::QAS_Left;
583 Style.QualifierOrder = {"volatile", "const", "type"};
584
585 verifyFormat("volatile const int a;", "const volatile int a;", Style);
586 verifyFormat("volatile const int a;", "volatile const int a;", Style);
587 verifyFormat("volatile const int a;", "int const volatile a;", Style);
588 verifyFormat("volatile const int a;", "int volatile const a;", Style);
589 verifyFormat("volatile const int a;", "const int volatile a;", Style);
590
591 Style.QualifierAlignment = FormatStyle::QAS_Right;
592 Style.QualifierOrder = {"type", "volatile", "const"};
593
594 verifyFormat("int volatile const a;", "const volatile int a;", Style);
595 verifyFormat("int volatile const a;", "volatile const int a;", Style);
596 verifyFormat("int volatile const a;", "int const volatile a;", Style);
597 verifyFormat("int volatile const a;", "int volatile const a;", Style);
598 verifyFormat("int volatile const a;", "const int volatile a;", Style);
599
600 Style.QualifierAlignment = FormatStyle::QAS_Custom;
601 Style.QualifierOrder = {"type", "volatile", "const"};
602
603 verifyFormat("int volatile const a;", "const volatile int a;", Style);
604 verifyFormat("int volatile const a;", "volatile const int a;", Style);
605 verifyFormat("int volatile const a;", "int const volatile a;", Style);
606 verifyFormat("int volatile const a;", "int volatile const a;", Style);
607 verifyFormat("int volatile const a;", "const int volatile a;", Style);
608 }
609
TEST_F(QualifierFixerTest,InlineStatics)610 TEST_F(QualifierFixerTest, InlineStatics) {
611 FormatStyle Style = getLLVMStyle();
612 Style.QualifierAlignment = FormatStyle::QAS_Left;
613 Style.QualifierOrder = {"inline", "static", "const", "volatile", "type"};
614 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
615
616 verifyFormat("inline static const volatile int a;",
617 "const inline static volatile int a;", Style);
618 verifyFormat("inline static const volatile int a;",
619 "volatile inline static const int a;", Style);
620 verifyFormat("inline static const volatile int a;",
621 "int const inline static volatile a;", Style);
622 verifyFormat("inline static const volatile int a;",
623 "int volatile inline static const a;", Style);
624 verifyFormat("inline static const volatile int a;",
625 "const int inline static volatile a;", Style);
626 }
627
TEST_F(QualifierFixerTest,AmpEqual)628 TEST_F(QualifierFixerTest, AmpEqual) {
629 FormatStyle Style = getLLVMStyle();
630 Style.QualifierAlignment = FormatStyle::QAS_Custom;
631 Style.QualifierOrder = {"static", "type", "const"};
632 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)3);
633
634 verifyFormat("foo(std::string const & = std::string()) const",
635 "foo(const std::string & = std::string()) const", Style);
636 verifyFormat("foo(std::string const & = std::string())",
637 "foo(const std::string & = std::string())", Style);
638 }
639
TEST_F(QualifierFixerTest,MoveConstBeyondTypeSmall)640 TEST_F(QualifierFixerTest, MoveConstBeyondTypeSmall) {
641
642 FormatStyle Style = getLLVMStyle();
643 Style.QualifierAlignment = FormatStyle::QAS_Custom;
644 Style.QualifierOrder = {"type", "const"};
645 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);
646
647 verifyFormat("int const a;", "const int a;", Style);
648 verifyFormat("int const *a;", "const int*a;", Style);
649 verifyFormat("int const *a;", "const int *a;", Style);
650 verifyFormat("int const &a;", "const int &a;", Style);
651 verifyFormat("int const &&a;", "const int &&a;", Style);
652 }
653
TEST_F(QualifierFixerTest,MoveConstBeforeTypeSmall)654 TEST_F(QualifierFixerTest, MoveConstBeforeTypeSmall) {
655
656 FormatStyle Style = getLLVMStyle();
657 Style.QualifierAlignment = FormatStyle::QAS_Custom;
658 Style.QualifierOrder = {"const", "type"};
659 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)2);
660
661 verifyFormat("const int a;", "int const a;", Style);
662 verifyFormat("const int *a;", "int const *a;", Style);
663 verifyFormat("const int *a const;", "int const *a const;", Style);
664
665 verifyFormat("const int a = foo();", "int const a = foo();", Style);
666 verifyFormat("const int *a = foo();", "int const *a = foo();", Style);
667 verifyFormat("const int *a const = foo();", "int const *a const = foo();",
668 Style);
669
670 verifyFormat("const auto a = foo();", "auto const a = foo();", Style);
671 verifyFormat("const auto *a = foo();", "auto const *a = foo();", Style);
672 verifyFormat("const auto *a const = foo();", "auto const *a const = foo();",
673 Style);
674 }
675
TEST_F(QualifierFixerTest,MoveConstBeyondType)676 TEST_F(QualifierFixerTest, MoveConstBeyondType) {
677
678 FormatStyle Style = getLLVMStyle();
679 Style.QualifierAlignment = FormatStyle::QAS_Custom;
680 Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};
681 EXPECT_EQ(Style.QualifierOrder.size(), (size_t)5);
682
683 verifyFormat("static inline int const volatile a;",
684 "const inline static volatile int a;", Style);
685 verifyFormat("static inline int const volatile a;",
686 "volatile inline static const int a;", Style);
687 verifyFormat("static inline int const volatile a;",
688 "int const inline static volatile a;", Style);
689 verifyFormat("static inline int const volatile a;",
690 "int volatile inline static const a;", Style);
691 verifyFormat("static inline int const volatile a;",
692 "const int inline static volatile a;", Style);
693
694 verifyFormat("static inline int const volatile *a const;",
695 "const int inline static volatile *a const;", Style);
696 }
697
TEST_F(QualifierFixerTest,PrepareLeftRightOrdering)698 TEST_F(QualifierFixerTest, PrepareLeftRightOrdering) {
699 FormatStyle Style = getLLVMStyle();
700 Style.QualifierAlignment = FormatStyle::QAS_Custom;
701 Style.QualifierOrder = {"static", "inline", "type", "const", "volatile"};
702
703 std::vector<std::string> Left;
704 std::vector<std::string> Right;
705 std::vector<tok::TokenKind> ConfiguredTokens;
706 QualifierAlignmentFixer::PrepareLeftRightOrdering(Style.QualifierOrder, Left,
707 Right, ConfiguredTokens);
708
709 EXPECT_EQ(Left.size(), (size_t)2);
710 EXPECT_EQ(Right.size(), (size_t)2);
711
712 std::vector<std::string> LeftResult = {"inline", "static"};
713 std::vector<std::string> RightResult = {"const", "volatile"};
714 EXPECT_EQ(Left, LeftResult);
715 EXPECT_EQ(Right, RightResult);
716 }
717
TEST_F(QualifierFixerTest,IsQualifierType)718 TEST_F(QualifierFixerTest, IsQualifierType) {
719
720 std::vector<tok::TokenKind> ConfiguredTokens;
721 ConfiguredTokens.push_back(tok::kw_const);
722 ConfiguredTokens.push_back(tok::kw_static);
723 ConfiguredTokens.push_back(tok::kw_inline);
724 ConfiguredTokens.push_back(tok::kw_restrict);
725 ConfiguredTokens.push_back(tok::kw_constexpr);
726
727 auto Tokens =
728 annotate("const static inline auto restrict int double long constexpr");
729
730 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
731 Tokens[0], ConfiguredTokens));
732 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
733 Tokens[1], ConfiguredTokens));
734 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
735 Tokens[2], ConfiguredTokens));
736 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
737 Tokens[3], ConfiguredTokens));
738 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
739 Tokens[4], ConfiguredTokens));
740 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
741 Tokens[5], ConfiguredTokens));
742 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
743 Tokens[6], ConfiguredTokens));
744 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
745 Tokens[7], ConfiguredTokens));
746 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
747 Tokens[8], ConfiguredTokens));
748
749 auto NotTokens = annotate("for while do Foo Bar ");
750
751 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
752 NotTokens[0], ConfiguredTokens));
753 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
754 NotTokens[1], ConfiguredTokens));
755 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
756 NotTokens[2], ConfiguredTokens));
757 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
758 NotTokens[3], ConfiguredTokens));
759 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
760 NotTokens[4], ConfiguredTokens));
761 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isQualifierOrType(
762 NotTokens[5], ConfiguredTokens));
763 }
764
TEST_F(QualifierFixerTest,IsMacro)765 TEST_F(QualifierFixerTest, IsMacro) {
766
767 auto Tokens = annotate("INT INTPR Foo int");
768
769 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[0]));
770 EXPECT_TRUE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[1]));
771 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[2]));
772 EXPECT_FALSE(LeftRightQualifierAlignmentFixer::isPossibleMacro(Tokens[3]));
773 }
774
TEST_F(QualifierFixerTest,OverlappingQualifier)775 TEST_F(QualifierFixerTest, OverlappingQualifier) {
776
777 FormatStyle Style = getLLVMStyle();
778 Style.QualifierAlignment = FormatStyle::QAS_Left;
779 Style.QualifierOrder = {"const", "type"};
780
781 verifyFormat("Foo(const Bar &name);", "Foo(Bar const &name);", Style);
782 }
783
TEST_F(QualifierFixerTest,DontPushQualifierThroughNonSpecifiedTypes)784 TEST_F(QualifierFixerTest, DontPushQualifierThroughNonSpecifiedTypes) {
785
786 FormatStyle Style = getLLVMStyle();
787 Style.QualifierAlignment = FormatStyle::QAS_Left;
788 Style.QualifierOrder = {"const", "type"};
789
790 verifyFormat("inline static const int a;", Style);
791
792 Style.QualifierOrder = {"static", "const", "type"};
793
794 verifyFormat("inline static const int a;", Style);
795 verifyFormat("static inline const int a;", "static inline const int a;",
796 Style);
797
798 verifyFormat("static const int a;", "const static int a;", Style);
799 }
800
TEST_F(QualifierFixerTest,UnsignedQualifier)801 TEST_F(QualifierFixerTest, UnsignedQualifier) {
802
803 FormatStyle Style = getLLVMStyle();
804 Style.QualifierAlignment = FormatStyle::QAS_Left;
805 Style.QualifierOrder = {"const", "type"};
806
807 verifyFormat("Foo(const unsigned char *bytes)",
808 "Foo(unsigned const char *bytes)", Style);
809
810 Style.QualifierAlignment = FormatStyle::QAS_Right;
811 Style.QualifierOrder = {"type", "const"};
812
813 verifyFormat("Foo(unsigned char const *bytes)",
814 "Foo(unsigned const char *bytes)", Style);
815 }
816
TEST_F(QualifierFixerTest,NoOpQualifierReplacements)817 TEST_F(QualifierFixerTest, NoOpQualifierReplacements) {
818
819 FormatStyle Style = getLLVMStyle();
820 Style.QualifierAlignment = FormatStyle::QAS_Custom;
821 Style.QualifierOrder = {"static", "const", "type"};
822
823 ReplacementCount = 0;
824 EXPECT_EQ(ReplacementCount, 0);
825 verifyFormat("static const uint32 foo[] = {0, 31};", Style);
826 verifyFormat("#define MACRO static const", Style);
827 verifyFormat("using sc = static const", Style);
828 EXPECT_EQ(ReplacementCount, 0);
829 }
830
TEST_F(QualifierFixerTest,QualifierTemplates)831 TEST_F(QualifierFixerTest, QualifierTemplates) {
832 FormatStyle Style = getLLVMStyle();
833 Style.QualifierAlignment = FormatStyle::QAS_Custom;
834 Style.QualifierOrder = {"static", "const", "type"};
835
836 ReplacementCount = 0;
837 EXPECT_EQ(ReplacementCount, 0);
838 verifyFormat("using A = B<>;", Style);
839 verifyFormat("using A = B /**/<>;", Style);
840 verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);
841 verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);
842 verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);
843 verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);
844 verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);
845 verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);
846 verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);
847 EXPECT_EQ(ReplacementCount, 0);
848 verifyFormat("template <class C>\n"
849 "using A = B // foo\n"
850 " <Foo<C>, 1>;",
851 Style);
852
853 ReplacementCount = 0;
854 Style.QualifierOrder = {"type", "static", "const"};
855 verifyFormat("using A = B<>;", Style);
856 verifyFormat("using A = B /**/<>;", Style);
857 verifyFormat("template <class C> using A = B<Foo<C>, 1>;", Style);
858 verifyFormat("template <class C> using A = B /**/<Foo<C>, 1>;", Style);
859 verifyFormat("template <class C> using A = B /* */<Foo<C>, 1>;", Style);
860 verifyFormat("template <class C> using A = B /*foo*/<Foo<C>, 1>;", Style);
861 verifyFormat("template <class C> using A = B /**/ /**/<Foo<C>, 1>;", Style);
862 verifyFormat("template <class C> using A = B<Foo</**/ C>, 1>;", Style);
863 verifyFormat("template <class C> using A = /**/ B<Foo<C>, 1>;", Style);
864 EXPECT_EQ(ReplacementCount, 0);
865 verifyFormat("template <class C>\n"
866 "using A = B // foo\n"
867 " <Foo<C>, 1>;",
868 Style);
869 }
870
TEST_F(QualifierFixerTest,WithConstraints)871 TEST_F(QualifierFixerTest, WithConstraints) {
872 FormatStyle Style = getLLVMStyle();
873 Style.QualifierAlignment = FormatStyle::QAS_Custom;
874 Style.QualifierOrder = {"constexpr", "type"};
875
876 verifyFormat("template <typename T>\n"
877 " requires Concept<F>\n"
878 "constexpr constructor();",
879 Style);
880 verifyFormat("template <typename T>\n"
881 " requires Concept1<F> && Concept2<F>\n"
882 "constexpr constructor();",
883 Style);
884 }
885
TEST_F(QualifierFixerTest,DisableRegions)886 TEST_F(QualifierFixerTest, DisableRegions) {
887 FormatStyle Style = getLLVMStyle();
888 Style.QualifierAlignment = FormatStyle::QAS_Custom;
889 Style.QualifierOrder = {"inline", "static", "const", "type"};
890
891 ReplacementCount = 0;
892 verifyFormat("// clang-format off\n"
893 "int const inline static a = 0;\n"
894 "// clang-format on\n",
895 Style);
896 EXPECT_EQ(ReplacementCount, 0);
897 verifyFormat("// clang-format off\n"
898 "int const inline static a = 0;\n"
899 "// clang-format on\n"
900 "inline static const int a = 0;\n",
901 "// clang-format off\n"
902 "int const inline static a = 0;\n"
903 "// clang-format on\n"
904 "int const inline static a = 0;\n",
905 Style);
906 }
907
TEST_F(QualifierFixerTest,TemplatesRight)908 TEST_F(QualifierFixerTest, TemplatesRight) {
909 FormatStyle Style = getLLVMStyle();
910 Style.QualifierAlignment = FormatStyle::QAS_Custom;
911 Style.QualifierOrder = {"type", "const"};
912
913 verifyFormat("template <typename T>\n"
914 " requires Concept<T const>\n"
915 "void f();",
916 "template <typename T>\n"
917 " requires Concept<const T>\n"
918 "void f();",
919 Style);
920 verifyFormat("TemplateType<T const> t;", "TemplateType<const T> t;", Style);
921 verifyFormat("TemplateType<Container const> t;",
922 "TemplateType<const Container> t;", Style);
923 }
924
TEST_F(QualifierFixerTest,TemplatesLeft)925 TEST_F(QualifierFixerTest, TemplatesLeft) {
926 FormatStyle Style = getLLVMStyle();
927 Style.QualifierAlignment = FormatStyle::QAS_Custom;
928 Style.QualifierOrder = {"const", "type"};
929
930 verifyFormat("template <const T> t;", "template <T const> t;", Style);
931 verifyFormat("template <typename T>\n"
932 " requires Concept<const T>\n"
933 "void f();",
934 "template <typename T>\n"
935 " requires Concept<T const>\n"
936 "void f();",
937 Style);
938 verifyFormat("TemplateType<const T> t;", "TemplateType<T const> t;", Style);
939 verifyFormat("TemplateType<const Container> t;",
940 "TemplateType<Container const> t;", Style);
941 }
942
943 } // namespace format
944 } // namespace clang
945