clang 22.0.0git
Format.cpp
Go to the documentation of this file.
1//===--- Format.cpp - Format C++ code -------------------------------------===//
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/// \file
10/// This file implements functions declared in Format.h. This will be
11/// split into separate files as we go.
12///
13//===----------------------------------------------------------------------===//
14
15#include "clang/Format/Format.h"
26#include "llvm/ADT/Sequence.h"
27#include <limits>
28
29#define DEBUG_TYPE "format-formatter"
30
31using clang::format::FormatStyle;
32
33LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat)
34
41
42namespace llvm {
43namespace yaml {
44template <>
45struct ScalarEnumerationTraits<FormatStyle::BreakBeforeNoexceptSpecifierStyle> {
46 static void
47 enumeration(IO &IO, FormatStyle::BreakBeforeNoexceptSpecifierStyle &Value) {
48 IO.enumCase(Value, "Never", FormatStyle::BBNSS_Never);
49 IO.enumCase(Value, "OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen);
50 IO.enumCase(Value, "Always", FormatStyle::BBNSS_Always);
51 }
52};
53
54template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {
55 static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
56 IO.enumCase(Value, "None", FormatStyle::AlignConsecutiveStyle({}));
57 IO.enumCase(Value, "Consecutive",
58 FormatStyle::AlignConsecutiveStyle(
59 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
60 /*AcrossComments=*/false, /*AlignCompound=*/false,
61 /*AlignFunctionDeclarations=*/true,
62 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
63 IO.enumCase(Value, "AcrossEmptyLines",
64 FormatStyle::AlignConsecutiveStyle(
65 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
66 /*AcrossComments=*/false, /*AlignCompound=*/false,
67 /*AlignFunctionDeclarations=*/true,
68 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
69 IO.enumCase(Value, "AcrossComments",
70 FormatStyle::AlignConsecutiveStyle(
71 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
72 /*AcrossComments=*/true, /*AlignCompound=*/false,
73 /*AlignFunctionDeclarations=*/true,
74 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
75 IO.enumCase(Value, "AcrossEmptyLinesAndComments",
76 FormatStyle::AlignConsecutiveStyle(
77 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
78 /*AcrossComments=*/true, /*AlignCompound=*/false,
79 /*AlignFunctionDeclarations=*/true,
80 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
81
82 // For backward compatibility.
83 IO.enumCase(Value, "true",
84 FormatStyle::AlignConsecutiveStyle(
85 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
86 /*AcrossComments=*/false, /*AlignCompound=*/false,
87 /*AlignFunctionDeclarations=*/true,
88 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
89 IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));
90 }
91
92 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
93 IO.mapOptional("Enabled", Value.Enabled);
94 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
95 IO.mapOptional("AcrossComments", Value.AcrossComments);
96 IO.mapOptional("AlignCompound", Value.AlignCompound);
97 IO.mapOptional("AlignFunctionDeclarations",
98 Value.AlignFunctionDeclarations);
99 IO.mapOptional("AlignFunctionPointers", Value.AlignFunctionPointers);
100 IO.mapOptional("PadOperators", Value.PadOperators);
101 }
102};
103
104template <>
105struct MappingTraits<FormatStyle::ShortCaseStatementsAlignmentStyle> {
106 static void mapping(IO &IO,
107 FormatStyle::ShortCaseStatementsAlignmentStyle &Value) {
108 IO.mapOptional("Enabled", Value.Enabled);
109 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
110 IO.mapOptional("AcrossComments", Value.AcrossComments);
111 IO.mapOptional("AlignCaseArrows", Value.AlignCaseArrows);
112 IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);
113 }
114};
115
116template <>
117struct ScalarEnumerationTraits<FormatStyle::AttributeBreakingStyle> {
118 static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value) {
119 IO.enumCase(Value, "Always", FormatStyle::ABS_Always);
120 IO.enumCase(Value, "Leave", FormatStyle::ABS_Leave);
121 IO.enumCase(Value, "Never", FormatStyle::ABS_Never);
122 }
123};
124
125template <>
126struct ScalarEnumerationTraits<FormatStyle::ArrayInitializerAlignmentStyle> {
127 static void enumeration(IO &IO,
128 FormatStyle::ArrayInitializerAlignmentStyle &Value) {
129 IO.enumCase(Value, "None", FormatStyle::AIAS_None);
130 IO.enumCase(Value, "Left", FormatStyle::AIAS_Left);
131 IO.enumCase(Value, "Right", FormatStyle::AIAS_Right);
132 }
133};
134
135template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {
136 static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {
137 IO.enumCase(Value, "All", FormatStyle::BOS_All);
138 IO.enumCase(Value, "true", FormatStyle::BOS_All);
139 IO.enumCase(Value, "None", FormatStyle::BOS_None);
140 IO.enumCase(Value, "false", FormatStyle::BOS_None);
141 IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);
142 }
143};
144
145template <>
146struct ScalarEnumerationTraits<FormatStyle::BinPackParametersStyle> {
147 static void enumeration(IO &IO, FormatStyle::BinPackParametersStyle &Value) {
148 IO.enumCase(Value, "BinPack", FormatStyle::BPPS_BinPack);
149 IO.enumCase(Value, "OnePerLine", FormatStyle::BPPS_OnePerLine);
150 IO.enumCase(Value, "AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine);
151
152 // For backward compatibility.
153 IO.enumCase(Value, "true", FormatStyle::BPPS_BinPack);
154 IO.enumCase(Value, "false", FormatStyle::BPPS_OnePerLine);
155 }
156};
157
158template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
159 static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
160 IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
161 IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
162 IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
163 }
164};
165
166template <>
167struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
168 static void enumeration(IO &IO,
169 FormatStyle::BitFieldColonSpacingStyle &Value) {
170 IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);
171 IO.enumCase(Value, "None", FormatStyle::BFCS_None);
172 IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);
173 IO.enumCase(Value, "After", FormatStyle::BFCS_After);
174 }
175};
176
177template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
178 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
179 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
180 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
181 IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
182 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
183 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
184 IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
185 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
186 IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
187 IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
188 }
189};
190
191template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
192 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
193 IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
194 IO.mapOptional("AfterClass", Wrapping.AfterClass);
195 IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
196 IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
197 IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
198 IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
199 IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
200 IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
201 IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
202 IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
203 IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
204 IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
205 IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
206 IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
207 IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
208 IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
209 IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
210 IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
211 }
212};
213
214template <> struct ScalarEnumerationTraits<BracketAlignmentStyle> {
216 IO.enumCase(Value, "Align", BAS_Align);
217 IO.enumCase(Value, "DontAlign", BAS_DontAlign);
218
219 // For backward compatibility.
220 IO.enumCase(Value, "true", BAS_Align);
221 IO.enumCase(Value, "false", BAS_DontAlign);
222 IO.enumCase(Value, "AlwaysBreak", BAS_AlwaysBreak);
223 IO.enumCase(Value, "BlockIndent", BAS_BlockIndent);
224 }
225};
226
227template <>
228struct ScalarEnumerationTraits<
229 FormatStyle::BraceWrappingAfterControlStatementStyle> {
230 static void
232 FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {
233 IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);
234 IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);
235 IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
236
237 // For backward compatibility.
238 IO.enumCase(Value, "false", FormatStyle::BWACS_Never);
239 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
240 }
241};
242
243template <>
244struct ScalarEnumerationTraits<
245 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
246 static void
247 enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value) {
248 IO.enumCase(Value, "Never", FormatStyle::BBCDS_Never);
249 IO.enumCase(Value, "Allowed", FormatStyle::BBCDS_Allowed);
250 IO.enumCase(Value, "Always", FormatStyle::BBCDS_Always);
251
252 // For backward compatibility.
253 IO.enumCase(Value, "true", FormatStyle::BBCDS_Always);
254 IO.enumCase(Value, "false", FormatStyle::BBCDS_Allowed);
255 }
256};
257
258template <>
259struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
260 static void enumeration(IO &IO,
261 FormatStyle::BreakBeforeInlineASMColonStyle &Value) {
262 IO.enumCase(Value, "Never", FormatStyle::BBIAS_Never);
263 IO.enumCase(Value, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
264 IO.enumCase(Value, "Always", FormatStyle::BBIAS_Always);
265 }
266};
267
268template <>
269struct ScalarEnumerationTraits<FormatStyle::BreakBinaryOperationsStyle> {
270 static void enumeration(IO &IO,
271 FormatStyle::BreakBinaryOperationsStyle &Value) {
272 IO.enumCase(Value, "Never", FormatStyle::BBO_Never);
273 IO.enumCase(Value, "OnePerLine", FormatStyle::BBO_OnePerLine);
274 IO.enumCase(Value, "RespectPrecedence", FormatStyle::BBO_RespectPrecedence);
275 }
276};
277
278template <>
279struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
280 static void
281 enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
282 IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
283 IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
284 IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
285 }
286};
287
288template <>
289struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
290 static void enumeration(IO &IO,
291 FormatStyle::BreakInheritanceListStyle &Value) {
292 IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
293 IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
294 IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
295 IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
296 }
297};
298
299template <>
300struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
301 static void enumeration(IO &IO,
302 FormatStyle::BreakTemplateDeclarationsStyle &Value) {
303 IO.enumCase(Value, "Leave", FormatStyle::BTDS_Leave);
304 IO.enumCase(Value, "No", FormatStyle::BTDS_No);
305 IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
306 IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
307
308 // For backward compatibility.
309 IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
310 IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
311 }
312};
313
314template <> struct ScalarEnumerationTraits<FormatStyle::BracedListStyle> {
315 static void enumeration(IO &IO, FormatStyle::BracedListStyle &Value) {
316 IO.enumCase(Value, "Block", FormatStyle::BLS_Block);
317 IO.enumCase(Value, "FunctionCall", FormatStyle::BLS_FunctionCall);
318 IO.enumCase(Value, "AlignFirstComment", FormatStyle::BLS_AlignFirstComment);
319
320 // For backward compatibility.
321 IO.enumCase(Value, "false", FormatStyle::BLS_Block);
322 IO.enumCase(Value, "true", FormatStyle::BLS_AlignFirstComment);
323 }
324};
325
326template <> struct ScalarEnumerationTraits<FormatStyle::DAGArgStyle> {
327 static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value) {
328 IO.enumCase(Value, "DontBreak", FormatStyle::DAS_DontBreak);
329 IO.enumCase(Value, "BreakElements", FormatStyle::DAS_BreakElements);
330 IO.enumCase(Value, "BreakAll", FormatStyle::DAS_BreakAll);
331 }
332};
333
334template <>
335struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
336 static void
337 enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
338 IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
339 IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
340 IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
341
342 // For backward compatibility.
343 IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
344 IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
345 }
346};
347
348template <>
349struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
350 static void enumeration(IO &IO,
351 FormatStyle::EscapedNewlineAlignmentStyle &Value) {
352 IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
353 IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
354 IO.enumCase(Value, "LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);
355 IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
356
357 // For backward compatibility.
358 IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
359 IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
360 }
361};
362
363template <>
364struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
365 static void
366 enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
367 IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
368 IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
369 IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
370 }
371};
372
373template <>
374struct ScalarEnumerationTraits<
375 FormatStyle::EmptyLineBeforeAccessModifierStyle> {
376 static void
377 enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
378 IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
379 IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
380 IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
381 IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
382 }
383};
384
385template <>
386struct ScalarEnumerationTraits<FormatStyle::EnumTrailingCommaStyle> {
387 static void enumeration(IO &IO, FormatStyle::EnumTrailingCommaStyle &Value) {
388 IO.enumCase(Value, "Leave", FormatStyle::ETC_Leave);
389 IO.enumCase(Value, "Insert", FormatStyle::ETC_Insert);
390 IO.enumCase(Value, "Remove", FormatStyle::ETC_Remove);
391 }
392};
393
394template <>
395struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
396 static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
397 IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
398 IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
399 IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
400 IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
401 IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
402 }
403};
404
405template <> struct MappingTraits<FormatStyle::IntegerLiteralSeparatorStyle> {
406 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base) {
407 IO.mapOptional("Binary", Base.Binary);
408 IO.mapOptional("BinaryMinDigits", Base.BinaryMinDigits);
409 IO.mapOptional("Decimal", Base.Decimal);
410 IO.mapOptional("DecimalMinDigits", Base.DecimalMinDigits);
411 IO.mapOptional("Hex", Base.Hex);
412 IO.mapOptional("HexMinDigits", Base.HexMinDigits);
413 }
414};
415
416template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
417 static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
418 IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
419 IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
420 IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
421 }
422};
423
424template <> struct MappingTraits<FormatStyle::KeepEmptyLinesStyle> {
425 static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value) {
426 IO.mapOptional("AtEndOfFile", Value.AtEndOfFile);
427 IO.mapOptional("AtStartOfBlock", Value.AtStartOfBlock);
428 IO.mapOptional("AtStartOfFile", Value.AtStartOfFile);
429 }
430};
431
432template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
433 static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
434 IO.enumCase(Value, "C", FormatStyle::LK_C);
435 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
436 IO.enumCase(Value, "Java", FormatStyle::LK_Java);
437 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
438 IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
439 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
440 IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
441 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
442 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
443 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
444 IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
445 }
446};
447
448template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
449 static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
450 IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);
451 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias
452 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias
453
454 IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);
455 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias
456
457 IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);
458 IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);
459 IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);
460
461 IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);
462 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias
463 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
464 }
465};
466
467template <>
468struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> {
469 static void enumeration(IO &IO,
470 FormatStyle::LambdaBodyIndentationKind &Value) {
471 IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature);
472 IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope);
473 }
474};
475
476template <> struct ScalarEnumerationTraits<FormatStyle::LineEndingStyle> {
477 static void enumeration(IO &IO, FormatStyle::LineEndingStyle &Value) {
478 IO.enumCase(Value, "LF", FormatStyle::LE_LF);
479 IO.enumCase(Value, "CRLF", FormatStyle::LE_CRLF);
480 IO.enumCase(Value, "DeriveLF", FormatStyle::LE_DeriveLF);
481 IO.enumCase(Value, "DeriveCRLF", FormatStyle::LE_DeriveCRLF);
482 }
483};
484
485template <>
486struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
487 static void enumeration(IO &IO,
488 FormatStyle::NamespaceIndentationKind &Value) {
489 IO.enumCase(Value, "None", FormatStyle::NI_None);
490 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
491 IO.enumCase(Value, "All", FormatStyle::NI_All);
492 }
493};
494
495template <>
496struct ScalarEnumerationTraits<FormatStyle::NumericLiteralComponentStyle> {
497 static void enumeration(IO &IO,
498 FormatStyle::NumericLiteralComponentStyle &Value) {
499 IO.enumCase(Value, "Leave", FormatStyle::NLCS_Leave);
500 IO.enumCase(Value, "Upper", FormatStyle::NLCS_Upper);
501 IO.enumCase(Value, "Lower", FormatStyle::NLCS_Lower);
502 }
503};
504
505template <> struct MappingTraits<FormatStyle::NumericLiteralCaseStyle> {
506 static void mapping(IO &IO, FormatStyle::NumericLiteralCaseStyle &Value) {
507 IO.mapOptional("ExponentLetter", Value.ExponentLetter);
508 IO.mapOptional("HexDigit", Value.HexDigit);
509 IO.mapOptional("Prefix", Value.Prefix);
510 IO.mapOptional("Suffix", Value.Suffix);
511 }
512};
513
514template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
515 static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
516 IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
517 IO.enumCase(Value, "Align", FormatStyle::OAS_Align);
518 IO.enumCase(Value, "AlignAfterOperator",
519 FormatStyle::OAS_AlignAfterOperator);
520
521 // For backward compatibility.
522 IO.enumCase(Value, "true", FormatStyle::OAS_Align);
523 IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);
524 }
525};
526
527template <>
528struct ScalarEnumerationTraits<FormatStyle::PackConstructorInitializersStyle> {
529 static void
530 enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value) {
531 IO.enumCase(Value, "Never", FormatStyle::PCIS_Never);
532 IO.enumCase(Value, "BinPack", FormatStyle::PCIS_BinPack);
533 IO.enumCase(Value, "CurrentLine", FormatStyle::PCIS_CurrentLine);
534 IO.enumCase(Value, "NextLine", FormatStyle::PCIS_NextLine);
535 IO.enumCase(Value, "NextLineOnly", FormatStyle::PCIS_NextLineOnly);
536 }
537};
538
539template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
540 static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
541 IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
542 IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
543 IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
544
545 // For backward compatibility.
546 IO.enumCase(Value, "true", FormatStyle::PAS_Left);
547 IO.enumCase(Value, "false", FormatStyle::PAS_Right);
548 }
549};
550
551template <>
552struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
553 static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
554 IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
555 IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
556 IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
557 IO.enumCase(Value, "Leave", FormatStyle::PPDIS_Leave);
558 }
559};
560
561template <>
562struct ScalarEnumerationTraits<FormatStyle::QualifierAlignmentStyle> {
563 static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value) {
564 IO.enumCase(Value, "Leave", FormatStyle::QAS_Leave);
565 IO.enumCase(Value, "Left", FormatStyle::QAS_Left);
566 IO.enumCase(Value, "Right", FormatStyle::QAS_Right);
567 IO.enumCase(Value, "Custom", FormatStyle::QAS_Custom);
568 }
569};
570
571template <> struct MappingTraits<FormatStyle::RawStringFormat> {
572 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
573 IO.mapOptional("Language", Format.Language);
574 IO.mapOptional("Delimiters", Format.Delimiters);
575 IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
576 IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
577 IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
578 }
579};
580
581template <> struct ScalarEnumerationTraits<FormatStyle::ReflowCommentsStyle> {
582 static void enumeration(IO &IO, FormatStyle::ReflowCommentsStyle &Value) {
583 IO.enumCase(Value, "Never", FormatStyle::RCS_Never);
584 IO.enumCase(Value, "IndentOnly", FormatStyle::RCS_IndentOnly);
585 IO.enumCase(Value, "Always", FormatStyle::RCS_Always);
586 // For backward compatibility:
587 IO.enumCase(Value, "false", FormatStyle::RCS_Never);
588 IO.enumCase(Value, "true", FormatStyle::RCS_Always);
589 }
590};
591
592template <>
593struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> {
594 static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) {
595 IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer);
596 IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle);
597 IO.enumCase(Value, "Left", FormatStyle::RAS_Left);
598 IO.enumCase(Value, "Right", FormatStyle::RAS_Right);
599 }
600};
601
602template <>
603struct ScalarEnumerationTraits<FormatStyle::RemoveParenthesesStyle> {
604 static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value) {
605 IO.enumCase(Value, "Leave", FormatStyle::RPS_Leave);
606 IO.enumCase(Value, "MultipleParentheses",
607 FormatStyle::RPS_MultipleParentheses);
608 IO.enumCase(Value, "ReturnStatement", FormatStyle::RPS_ReturnStatement);
609 }
610};
611
612template <>
613struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> {
614 static void enumeration(IO &IO,
615 FormatStyle::RequiresClausePositionStyle &Value) {
616 IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine);
617 IO.enumCase(Value, "OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace);
618 IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding);
619 IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing);
620 IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine);
621 }
622};
623
624template <>
625struct ScalarEnumerationTraits<FormatStyle::RequiresExpressionIndentationKind> {
626 static void
627 enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value) {
628 IO.enumCase(Value, "Keyword", FormatStyle::REI_Keyword);
629 IO.enumCase(Value, "OuterScope", FormatStyle::REI_OuterScope);
630 }
631};
632
633template <>
634struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
635 static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
636 IO.enumCase(Value, "None", FormatStyle::RTBS_None);
637 IO.enumCase(Value, "Automatic", FormatStyle::RTBS_Automatic);
638 IO.enumCase(Value, "ExceptShortType", FormatStyle::RTBS_ExceptShortType);
639 IO.enumCase(Value, "All", FormatStyle::RTBS_All);
640 IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
641 IO.enumCase(Value, "TopLevelDefinitions",
642 FormatStyle::RTBS_TopLevelDefinitions);
643 IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
644 }
645};
646
647template <>
648struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> {
649 static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) {
650 IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave);
651 IO.enumCase(Value, "Always", FormatStyle::SDS_Always);
652 IO.enumCase(Value, "Never", FormatStyle::SDS_Never);
653 }
654};
655
656template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
657 static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) {
658 IO.enumCase(Value, "Never", FormatStyle::SBS_Never);
659 IO.enumCase(Value, "false", FormatStyle::SBS_Never);
660 IO.enumCase(Value, "Always", FormatStyle::SBS_Always);
661 IO.enumCase(Value, "true", FormatStyle::SBS_Always);
662 IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);
663 }
664};
665
666template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
667 static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
668 IO.enumCase(Value, "None", FormatStyle::SFS_None);
669 IO.enumCase(Value, "false", FormatStyle::SFS_None);
670 IO.enumCase(Value, "All", FormatStyle::SFS_All);
671 IO.enumCase(Value, "true", FormatStyle::SFS_All);
672 IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
673 IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
674 IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
675 }
676};
677
678template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
679 static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
680 IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
681 IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
682 IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
683 IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
684
685 // For backward compatibility.
686 IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
687 IO.enumCase(Value, "false", FormatStyle::SIS_Never);
688 IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
689 }
690};
691
692template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
693 static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) {
694 IO.enumCase(Value, "None", FormatStyle::SLS_None);
695 IO.enumCase(Value, "false", FormatStyle::SLS_None);
696 IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
697 IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
698 IO.enumCase(Value, "All", FormatStyle::SLS_All);
699 IO.enumCase(Value, "true", FormatStyle::SLS_All);
700 }
701};
702
703template <> struct MappingTraits<FormatStyle::SortIncludesOptions> {
704 static void enumInput(IO &IO, FormatStyle::SortIncludesOptions &Value) {
705 IO.enumCase(Value, "Never", FormatStyle::SortIncludesOptions({}));
706 IO.enumCase(Value, "CaseInsensitive",
707 FormatStyle::SortIncludesOptions({/*Enabled=*/true,
708 /*IgnoreCase=*/true,
709 /*IgnoreExtension=*/false}));
710 IO.enumCase(Value, "CaseSensitive",
711 FormatStyle::SortIncludesOptions({/*Enabled=*/true,
712 /*IgnoreCase=*/false,
713 /*IgnoreExtension=*/false}));
714
715 // For backward compatibility.
716 IO.enumCase(Value, "false", FormatStyle::SortIncludesOptions({}));
717 IO.enumCase(Value, "true",
718 FormatStyle::SortIncludesOptions({/*Enabled=*/true,
719 /*IgnoreCase=*/false,
720 /*IgnoreExtension=*/false}));
721 }
722
723 static void mapping(IO &IO, FormatStyle::SortIncludesOptions &Value) {
724 IO.mapOptional("Enabled", Value.Enabled);
725 IO.mapOptional("IgnoreCase", Value.IgnoreCase);
726 IO.mapOptional("IgnoreExtension", Value.IgnoreExtension);
727 }
728};
729
730template <>
731struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
732 static void enumeration(IO &IO,
733 FormatStyle::SortJavaStaticImportOptions &Value) {
734 IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
735 IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
736 }
737};
738
739template <>
740struct ScalarEnumerationTraits<FormatStyle::SortUsingDeclarationsOptions> {
741 static void enumeration(IO &IO,
742 FormatStyle::SortUsingDeclarationsOptions &Value) {
743 IO.enumCase(Value, "Never", FormatStyle::SUD_Never);
744 IO.enumCase(Value, "Lexicographic", FormatStyle::SUD_Lexicographic);
745 IO.enumCase(Value, "LexicographicNumeric",
746 FormatStyle::SUD_LexicographicNumeric);
747
748 // For backward compatibility.
749 IO.enumCase(Value, "false", FormatStyle::SUD_Never);
750 IO.enumCase(Value, "true", FormatStyle::SUD_LexicographicNumeric);
751 }
752};
753
754template <>
755struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
756 static void
757 enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
758 IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
759 IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
760 IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
761 IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
762 }
763};
764
765template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> {
766 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
767 IO.mapOptional("AfterControlStatements", Spacing.AfterControlStatements);
768 IO.mapOptional("AfterForeachMacros", Spacing.AfterForeachMacros);
769 IO.mapOptional("AfterFunctionDefinitionName",
770 Spacing.AfterFunctionDefinitionName);
771 IO.mapOptional("AfterFunctionDeclarationName",
772 Spacing.AfterFunctionDeclarationName);
773 IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
774 IO.mapOptional("AfterNot", Spacing.AfterNot);
775 IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
776 IO.mapOptional("AfterPlacementOperator", Spacing.AfterPlacementOperator);
777 IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause);
778 IO.mapOptional("AfterRequiresInExpression",
779 Spacing.AfterRequiresInExpression);
780 IO.mapOptional("BeforeNonEmptyParentheses",
781 Spacing.BeforeNonEmptyParentheses);
782 }
783};
784
785template <>
786struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> {
787 static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value) {
788 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
789 IO.enumCase(Value, "ControlStatements",
790 FormatStyle::SBPO_ControlStatements);
791 IO.enumCase(Value, "ControlStatementsExceptControlMacros",
792 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
793 IO.enumCase(Value, "NonEmptyParentheses",
794 FormatStyle::SBPO_NonEmptyParentheses);
795 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
796 IO.enumCase(Value, "Custom", FormatStyle::SBPO_Custom);
797
798 // For backward compatibility.
799 IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
800 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
801 IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
802 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
803 }
804};
805
806template <>
807struct ScalarEnumerationTraits<FormatStyle::SpaceInEmptyBracesStyle> {
808 static void enumeration(IO &IO, FormatStyle::SpaceInEmptyBracesStyle &Value) {
809 IO.enumCase(Value, "Always", FormatStyle::SIEB_Always);
810 IO.enumCase(Value, "Block", FormatStyle::SIEB_Block);
811 IO.enumCase(Value, "Never", FormatStyle::SIEB_Never);
812 }
813};
814
815template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
816 static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
817 IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
818 IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
819 IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
820
821 // For backward compatibility.
822 IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
823 IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
824 }
825};
826
827template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
828 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
829 // Transform the maximum to signed, to parse "-1" correctly
830 int signedMaximum = static_cast<int>(Space.Maximum);
831 IO.mapOptional("Minimum", Space.Minimum);
832 IO.mapOptional("Maximum", signedMaximum);
833 Space.Maximum = static_cast<unsigned>(signedMaximum);
834
835 if (Space.Maximum < std::numeric_limits<unsigned>::max())
836 Space.Minimum = std::min(Space.Minimum, Space.Maximum);
837 }
838};
839
840template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
841 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
842 IO.mapOptional("ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
843 IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
844 IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
845 IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
846 IO.mapOptional("Other", Spaces.Other);
847 }
848};
849
850template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensStyle> {
851 static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value) {
852 IO.enumCase(Value, "Never", FormatStyle::SIPO_Never);
853 IO.enumCase(Value, "Custom", FormatStyle::SIPO_Custom);
854 }
855};
856
857template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {
858 static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {
859 IO.enumCase(Value, "None", FormatStyle::TCS_None);
860 IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);
861 }
862};
863
864template <>
865struct ScalarEnumerationTraits<FormatStyle::TrailingCommentsAlignmentKinds> {
866 static void enumeration(IO &IO,
867 FormatStyle::TrailingCommentsAlignmentKinds &Value) {
868 IO.enumCase(Value, "Leave", FormatStyle::TCAS_Leave);
869 IO.enumCase(Value, "Always", FormatStyle::TCAS_Always);
870 IO.enumCase(Value, "Never", FormatStyle::TCAS_Never);
871 }
872};
873
874template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> {
875 static void enumInput(IO &IO,
876 FormatStyle::TrailingCommentsAlignmentStyle &Value) {
877 IO.enumCase(Value, "Leave",
878 FormatStyle::TrailingCommentsAlignmentStyle(
879 {FormatStyle::TCAS_Leave, 0, true}));
880
881 IO.enumCase(Value, "Always",
882 FormatStyle::TrailingCommentsAlignmentStyle(
883 {FormatStyle::TCAS_Always, 0, true}));
884
885 IO.enumCase(Value, "Never",
886 FormatStyle::TrailingCommentsAlignmentStyle(
887 {FormatStyle::TCAS_Never, 0, true}));
888
889 // For backwards compatibility
890 IO.enumCase(Value, "true",
891 FormatStyle::TrailingCommentsAlignmentStyle(
892 {FormatStyle::TCAS_Always, 0, true}));
893 IO.enumCase(Value, "false",
894 FormatStyle::TrailingCommentsAlignmentStyle(
895 {FormatStyle::TCAS_Never, 0, true}));
896 }
897
898 static void mapping(IO &IO,
899 FormatStyle::TrailingCommentsAlignmentStyle &Value) {
900 IO.mapOptional("AlignPPAndNotPP", Value.AlignPPAndNotPP);
901 IO.mapOptional("Kind", Value.Kind);
902 IO.mapOptional("OverEmptyLines", Value.OverEmptyLines);
903 }
904};
905
906template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
907 static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
908 IO.enumCase(Value, "Never", FormatStyle::UT_Never);
909 IO.enumCase(Value, "false", FormatStyle::UT_Never);
910 IO.enumCase(Value, "Always", FormatStyle::UT_Always);
911 IO.enumCase(Value, "true", FormatStyle::UT_Always);
912 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
913 IO.enumCase(Value, "ForContinuationAndIndentation",
914 FormatStyle::UT_ForContinuationAndIndentation);
915 IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
916 }
917};
918
919template <>
920struct ScalarEnumerationTraits<
921 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
922 static void
924 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value) {
925 IO.enumCase(Value, "Never", FormatStyle::WNBWELS_Never);
926 IO.enumCase(Value, "Always", FormatStyle::WNBWELS_Always);
927 IO.enumCase(Value, "Leave", FormatStyle::WNBWELS_Leave);
928 }
929};
930
931template <> struct MappingTraits<FormatStyle> {
932 static void mapping(IO &IO, FormatStyle &Style) {
933 // When reading, read the language first, we need it for getPredefinedStyle.
934 IO.mapOptional("Language", Style.Language);
935
936 StringRef BasedOnStyle;
937 if (IO.outputting()) {
938 StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla",
939 "WebKit", "GNU", "Microsoft", "clang-format"};
940 for (StringRef StyleName : Styles) {
941 FormatStyle PredefinedStyle;
942 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
943 Style == PredefinedStyle) {
944 BasedOnStyle = StyleName;
945 break;
946 }
947 }
948 } else {
949 IO.mapOptional("BasedOnStyle", BasedOnStyle);
950 if (!BasedOnStyle.empty()) {
951 FormatStyle::LanguageKind OldLanguage = Style.Language;
952 FormatStyle::LanguageKind Language =
953 ((FormatStyle *)IO.getContext())->Language;
954 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
955 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
956 return;
957 }
958 Style.Language = OldLanguage;
959 }
960 }
961
962 // Initialize some variables used in the parsing. The using logic is at the
963 // end.
964
965 // For backward compatibility:
966 // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was
967 // false unless BasedOnStyle was Google or Chromium whereas that of
968 // AllowAllConstructorInitializersOnNextLine was always true, so the
969 // equivalent default value of PackConstructorInitializers is PCIS_NextLine
970 // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options
971 // had a non-default value while PackConstructorInitializers has a default
972 // value, set the latter to an equivalent non-default value if needed.
973 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive("google") ||
974 BasedOnStyle.equals_insensitive("chromium");
975 bool OnCurrentLine = IsGoogleOrChromium;
976 bool OnNextLine = true;
977
978 bool BreakBeforeInheritanceComma = false;
979 bool BreakConstructorInitializersBeforeComma = false;
980
981 bool DeriveLineEnding = true;
982 bool UseCRLF = false;
983
984 bool SpaceInEmptyBlock = false;
985 bool SpaceInEmptyParentheses = false;
986 bool SpacesInConditionalStatement = false;
987 bool SpacesInCStyleCastParentheses = false;
988 bool SpacesInParentheses = false;
989
990 if (IO.outputting()) {
991 IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
992 } else {
993 // For backward compatibility.
995 if (IsGoogleOrChromium) {
996 FormatStyle::LanguageKind Language = Style.Language;
997 if (Language == FormatStyle::LK_None)
998 Language = ((FormatStyle *)IO.getContext())->Language;
999 if (Language == FormatStyle::LK_JavaScript)
1000 LocalBAS = BAS_AlwaysBreak;
1001 else if (Language == FormatStyle::LK_Java)
1002 LocalBAS = BAS_DontAlign;
1003 } else if (BasedOnStyle.equals_insensitive("webkit")) {
1004 LocalBAS = BAS_DontAlign;
1005 }
1006 IO.mapOptional("AlignAfterOpenBracket", LocalBAS);
1007 Style.BreakAfterOpenBracketBracedList = false;
1008 Style.BreakAfterOpenBracketFunction = false;
1009 Style.BreakAfterOpenBracketIf = false;
1010 Style.BreakAfterOpenBracketLoop = false;
1011 Style.BreakAfterOpenBracketSwitch = false;
1012 Style.BreakBeforeCloseBracketBracedList = false;
1013 Style.BreakBeforeCloseBracketFunction = false;
1014 Style.BreakBeforeCloseBracketIf = false;
1015 Style.BreakBeforeCloseBracketLoop = false;
1016 Style.BreakBeforeCloseBracketSwitch = false;
1017
1018 switch (LocalBAS) {
1019 case BAS_DontAlign:
1020 Style.AlignAfterOpenBracket = false;
1021 break;
1022 case BAS_BlockIndent:
1023 Style.BreakBeforeCloseBracketBracedList = true;
1024 Style.BreakBeforeCloseBracketFunction = true;
1025 Style.BreakBeforeCloseBracketIf = true;
1026 [[fallthrough]];
1027 case BAS_AlwaysBreak:
1028 Style.BreakAfterOpenBracketBracedList = true;
1029 Style.BreakAfterOpenBracketFunction = true;
1030 Style.BreakAfterOpenBracketIf = true;
1031 [[fallthrough]];
1032 case BAS_Align:
1033 Style.AlignAfterOpenBracket = true;
1034 break;
1035 }
1036 }
1037
1038 // For backward compatibility.
1039 if (!IO.outputting()) {
1040 IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
1041 IO.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine);
1042 IO.mapOptional("AlwaysBreakAfterReturnType", Style.BreakAfterReturnType);
1043 IO.mapOptional("AlwaysBreakTemplateDeclarations",
1044 Style.BreakTemplateDeclarations);
1045 IO.mapOptional("BreakBeforeInheritanceComma",
1046 BreakBeforeInheritanceComma);
1047 IO.mapOptional("BreakConstructorInitializersBeforeComma",
1048 BreakConstructorInitializersBeforeComma);
1049 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
1050 OnCurrentLine);
1051 IO.mapOptional("DeriveLineEnding", DeriveLineEnding);
1052 IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
1053 IO.mapOptional("KeepEmptyLinesAtEOF", Style.KeepEmptyLines.AtEndOfFile);
1054 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
1055 Style.KeepEmptyLines.AtStartOfBlock);
1056 IO.mapOptional("IndentFunctionDeclarationAfterType",
1057 Style.IndentWrappedFunctionNames);
1058 IO.mapOptional("IndentRequires", Style.IndentRequiresClause);
1059 IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
1060 IO.mapOptional("SpaceAfterControlStatementKeyword",
1061 Style.SpaceBeforeParens);
1062 IO.mapOptional("SpaceInEmptyBlock", SpaceInEmptyBlock);
1063 IO.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses);
1064 IO.mapOptional("SpacesInConditionalStatement",
1065 SpacesInConditionalStatement);
1066 IO.mapOptional("SpacesInCStyleCastParentheses",
1067 SpacesInCStyleCastParentheses);
1068 IO.mapOptional("SpacesInParentheses", SpacesInParentheses);
1069 IO.mapOptional("UseCRLF", UseCRLF);
1070 }
1071
1072 IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
1073 IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures);
1074 IO.mapOptional("AlignConsecutiveAssignments",
1075 Style.AlignConsecutiveAssignments);
1076 IO.mapOptional("AlignConsecutiveBitFields",
1077 Style.AlignConsecutiveBitFields);
1078 IO.mapOptional("AlignConsecutiveDeclarations",
1079 Style.AlignConsecutiveDeclarations);
1080 IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
1081 IO.mapOptional("AlignConsecutiveShortCaseStatements",
1082 Style.AlignConsecutiveShortCaseStatements);
1083 IO.mapOptional("AlignConsecutiveTableGenBreakingDAGArgColons",
1084 Style.AlignConsecutiveTableGenBreakingDAGArgColons);
1085 IO.mapOptional("AlignConsecutiveTableGenCondOperatorColons",
1086 Style.AlignConsecutiveTableGenCondOperatorColons);
1087 IO.mapOptional("AlignConsecutiveTableGenDefinitionColons",
1088 Style.AlignConsecutiveTableGenDefinitionColons);
1089 IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
1090 IO.mapOptional("AlignOperands", Style.AlignOperands);
1091 IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
1092 IO.mapOptional("AllowAllArgumentsOnNextLine",
1093 Style.AllowAllArgumentsOnNextLine);
1094 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
1095 Style.AllowAllParametersOfDeclarationOnNextLine);
1096 IO.mapOptional("AllowBreakBeforeNoexceptSpecifier",
1097 Style.AllowBreakBeforeNoexceptSpecifier);
1098 IO.mapOptional("AllowBreakBeforeQtProperty",
1099 Style.AllowBreakBeforeQtProperty);
1100 IO.mapOptional("AllowShortBlocksOnASingleLine",
1101 Style.AllowShortBlocksOnASingleLine);
1102 IO.mapOptional("AllowShortCaseExpressionOnASingleLine",
1103 Style.AllowShortCaseExpressionOnASingleLine);
1104 IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
1105 Style.AllowShortCaseLabelsOnASingleLine);
1106 IO.mapOptional("AllowShortCompoundRequirementOnASingleLine",
1107 Style.AllowShortCompoundRequirementOnASingleLine);
1108 IO.mapOptional("AllowShortEnumsOnASingleLine",
1109 Style.AllowShortEnumsOnASingleLine);
1110 IO.mapOptional("AllowShortFunctionsOnASingleLine",
1111 Style.AllowShortFunctionsOnASingleLine);
1112 IO.mapOptional("AllowShortIfStatementsOnASingleLine",
1113 Style.AllowShortIfStatementsOnASingleLine);
1114 IO.mapOptional("AllowShortLambdasOnASingleLine",
1115 Style.AllowShortLambdasOnASingleLine);
1116 IO.mapOptional("AllowShortLoopsOnASingleLine",
1117 Style.AllowShortLoopsOnASingleLine);
1118 IO.mapOptional("AllowShortNamespacesOnASingleLine",
1119 Style.AllowShortNamespacesOnASingleLine);
1120 IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
1121 Style.AlwaysBreakAfterDefinitionReturnType);
1122 IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
1123 Style.AlwaysBreakBeforeMultilineStrings);
1124 IO.mapOptional("AttributeMacros", Style.AttributeMacros);
1125 IO.mapOptional("BinPackArguments", Style.BinPackArguments);
1126 IO.mapOptional("BinPackLongBracedList", Style.BinPackLongBracedList);
1127 IO.mapOptional("BinPackParameters", Style.BinPackParameters);
1128 IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing);
1129 IO.mapOptional("BracedInitializerIndentWidth",
1130 Style.BracedInitializerIndentWidth);
1131 IO.mapOptional("BraceWrapping", Style.BraceWrapping);
1132 IO.mapOptional("BreakAdjacentStringLiterals",
1133 Style.BreakAdjacentStringLiterals);
1134 IO.mapOptional("BreakAfterAttributes", Style.BreakAfterAttributes);
1135 IO.mapOptional("BreakAfterJavaFieldAnnotations",
1136 Style.BreakAfterJavaFieldAnnotations);
1137 IO.mapOptional("BreakAfterOpenBracketBracedList",
1138 Style.BreakAfterOpenBracketBracedList);
1139 IO.mapOptional("BreakAfterOpenBracketFunction",
1140 Style.BreakAfterOpenBracketFunction);
1141 IO.mapOptional("BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf);
1142 IO.mapOptional("BreakAfterOpenBracketLoop",
1143 Style.BreakAfterOpenBracketLoop);
1144 IO.mapOptional("BreakAfterOpenBracketSwitch",
1145 Style.BreakAfterOpenBracketSwitch);
1146 IO.mapOptional("BreakAfterReturnType", Style.BreakAfterReturnType);
1147 IO.mapOptional("BreakArrays", Style.BreakArrays);
1148 IO.mapOptional("BreakBeforeBinaryOperators",
1149 Style.BreakBeforeBinaryOperators);
1150 IO.mapOptional("BreakBeforeCloseBracketBracedList",
1151 Style.BreakBeforeCloseBracketBracedList);
1152 IO.mapOptional("BreakBeforeCloseBracketFunction",
1153 Style.BreakBeforeCloseBracketFunction);
1154 IO.mapOptional("BreakBeforeCloseBracketIf",
1155 Style.BreakBeforeCloseBracketIf);
1156 IO.mapOptional("BreakBeforeCloseBracketLoop",
1157 Style.BreakBeforeCloseBracketLoop);
1158 IO.mapOptional("BreakBeforeCloseBracketSwitch",
1159 Style.BreakBeforeCloseBracketSwitch);
1160 IO.mapOptional("BreakBeforeConceptDeclarations",
1161 Style.BreakBeforeConceptDeclarations);
1162 IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
1163 IO.mapOptional("BreakBeforeInlineASMColon",
1164 Style.BreakBeforeInlineASMColon);
1165 IO.mapOptional("BreakBeforeTemplateCloser",
1166 Style.BreakBeforeTemplateCloser);
1167 IO.mapOptional("BreakBeforeTernaryOperators",
1168 Style.BreakBeforeTernaryOperators);
1169 IO.mapOptional("BreakBinaryOperations", Style.BreakBinaryOperations);
1170 IO.mapOptional("BreakConstructorInitializers",
1171 Style.BreakConstructorInitializers);
1172 IO.mapOptional("BreakFunctionDefinitionParameters",
1173 Style.BreakFunctionDefinitionParameters);
1174 IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
1175 IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
1176 IO.mapOptional("BreakTemplateDeclarations",
1177 Style.BreakTemplateDeclarations);
1178 IO.mapOptional("ColumnLimit", Style.ColumnLimit);
1179 IO.mapOptional("CommentPragmas", Style.CommentPragmas);
1180 IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
1181 IO.mapOptional("ConstructorInitializerIndentWidth",
1182 Style.ConstructorInitializerIndentWidth);
1183 IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
1184 IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
1185 IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
1186 IO.mapOptional("DisableFormat", Style.DisableFormat);
1187 IO.mapOptional("EmptyLineAfterAccessModifier",
1188 Style.EmptyLineAfterAccessModifier);
1189 IO.mapOptional("EmptyLineBeforeAccessModifier",
1190 Style.EmptyLineBeforeAccessModifier);
1191 IO.mapOptional("EnumTrailingComma", Style.EnumTrailingComma);
1192 IO.mapOptional("ExperimentalAutoDetectBinPacking",
1193 Style.ExperimentalAutoDetectBinPacking);
1194 IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
1195 IO.mapOptional("ForEachMacros", Style.ForEachMacros);
1196 IO.mapOptional("IfMacros", Style.IfMacros);
1197 IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1198 IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
1199 IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1200 IO.mapOptional("IncludeIsMainSourceRegex",
1201 Style.IncludeStyle.IncludeIsMainSourceRegex);
1202 IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
1203 IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
1204 IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
1205 IO.mapOptional("IndentExportBlock", Style.IndentExportBlock);
1206 IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
1207 IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
1208 IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
1209 IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause);
1210 IO.mapOptional("IndentWidth", Style.IndentWidth);
1211 IO.mapOptional("IndentWrappedFunctionNames",
1212 Style.IndentWrappedFunctionNames);
1213 IO.mapOptional("InsertBraces", Style.InsertBraces);
1214 IO.mapOptional("InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1215 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
1216 IO.mapOptional("IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1217 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
1218 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
1219 IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
1220 IO.mapOptional("KeepEmptyLines", Style.KeepEmptyLines);
1221 IO.mapOptional("KeepFormFeed", Style.KeepFormFeed);
1222 IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
1223 IO.mapOptional("LineEnding", Style.LineEnding);
1224 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
1225 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
1226 IO.mapOptional("Macros", Style.Macros);
1227 IO.mapOptional("MacrosSkippedByRemoveParentheses",
1228 Style.MacrosSkippedByRemoveParentheses);
1229 IO.mapOptional("MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1230 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1231 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
1232 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
1233 IO.mapOptional("NumericLiteralCase", Style.NumericLiteralCase);
1234 IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1235 IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1236 IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
1237 Style.ObjCBreakBeforeNestedBlockParam);
1238 IO.mapOptional("ObjCPropertyAttributeOrder",
1239 Style.ObjCPropertyAttributeOrder);
1240 IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1241 IO.mapOptional("ObjCSpaceBeforeProtocolList",
1242 Style.ObjCSpaceBeforeProtocolList);
1243 IO.mapOptional("OneLineFormatOffRegex", Style.OneLineFormatOffRegex);
1244 IO.mapOptional("PackConstructorInitializers",
1245 Style.PackConstructorInitializers);
1246 IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1247 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1248 Style.PenaltyBreakBeforeFirstCallParameter);
1249 IO.mapOptional("PenaltyBreakBeforeMemberAccess",
1250 Style.PenaltyBreakBeforeMemberAccess);
1251 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
1252 IO.mapOptional("PenaltyBreakFirstLessLess",
1253 Style.PenaltyBreakFirstLessLess);
1254 IO.mapOptional("PenaltyBreakOpenParenthesis",
1255 Style.PenaltyBreakOpenParenthesis);
1256 IO.mapOptional("PenaltyBreakScopeResolution",
1257 Style.PenaltyBreakScopeResolution);
1258 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
1259 IO.mapOptional("PenaltyBreakTemplateDeclaration",
1260 Style.PenaltyBreakTemplateDeclaration);
1261 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1262 IO.mapOptional("PenaltyIndentedWhitespace",
1263 Style.PenaltyIndentedWhitespace);
1264 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1265 Style.PenaltyReturnTypeOnItsOwnLine);
1266 IO.mapOptional("PointerAlignment", Style.PointerAlignment);
1267 IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
1268 IO.mapOptional("QualifierAlignment", Style.QualifierAlignment);
1269 // Default Order for Left/Right based Qualifier alignment.
1270 if (Style.QualifierAlignment == FormatStyle::QAS_Right)
1271 Style.QualifierOrder = {"type", "const", "volatile"};
1272 else if (Style.QualifierAlignment == FormatStyle::QAS_Left)
1273 Style.QualifierOrder = {"const", "volatile", "type"};
1274 else if (Style.QualifierAlignment == FormatStyle::QAS_Custom)
1275 IO.mapOptional("QualifierOrder", Style.QualifierOrder);
1276 IO.mapOptional("RawStringFormats", Style.RawStringFormats);
1277 IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
1278 IO.mapOptional("ReflowComments", Style.ReflowComments);
1279 IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
1280 IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1281 Style.RemoveEmptyLinesInUnwrappedLines);
1282 IO.mapOptional("RemoveParentheses", Style.RemoveParentheses);
1283 IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
1284 IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
1285 IO.mapOptional("RequiresExpressionIndentation",
1286 Style.RequiresExpressionIndentation);
1287 IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1288 IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
1289 IO.mapOptional("SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1290 IO.mapOptional("SortIncludes", Style.SortIncludes);
1291 IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
1292 IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
1293 IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1294 IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1295 IO.mapOptional("SpaceAfterOperatorKeyword",
1296 Style.SpaceAfterOperatorKeyword);
1297 IO.mapOptional("SpaceAfterTemplateKeyword",
1298 Style.SpaceAfterTemplateKeyword);
1299 IO.mapOptional("SpaceAroundPointerQualifiers",
1300 Style.SpaceAroundPointerQualifiers);
1301 IO.mapOptional("SpaceBeforeAssignmentOperators",
1302 Style.SpaceBeforeAssignmentOperators);
1303 IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1304 IO.mapOptional("SpaceBeforeCpp11BracedList",
1305 Style.SpaceBeforeCpp11BracedList);
1306 IO.mapOptional("SpaceBeforeCtorInitializerColon",
1307 Style.SpaceBeforeCtorInitializerColon);
1308 IO.mapOptional("SpaceBeforeInheritanceColon",
1309 Style.SpaceBeforeInheritanceColon);
1310 IO.mapOptional("SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1311 IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
1312 IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1313 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1314 Style.SpaceBeforeRangeBasedForLoopColon);
1315 IO.mapOptional("SpaceBeforeSquareBrackets",
1316 Style.SpaceBeforeSquareBrackets);
1317 IO.mapOptional("SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
1318 IO.mapOptional("SpacesBeforeTrailingComments",
1319 Style.SpacesBeforeTrailingComments);
1320 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
1321 IO.mapOptional("SpacesInContainerLiterals",
1322 Style.SpacesInContainerLiterals);
1323 IO.mapOptional("SpacesInLineCommentPrefix",
1324 Style.SpacesInLineCommentPrefix);
1325 IO.mapOptional("SpacesInParens", Style.SpacesInParens);
1326 IO.mapOptional("SpacesInParensOptions", Style.SpacesInParensOptions);
1327 IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1328 IO.mapOptional("Standard", Style.Standard);
1329 IO.mapOptional("StatementAttributeLikeMacros",
1330 Style.StatementAttributeLikeMacros);
1331 IO.mapOptional("StatementMacros", Style.StatementMacros);
1332 IO.mapOptional("TableGenBreakingDAGArgOperators",
1333 Style.TableGenBreakingDAGArgOperators);
1334 IO.mapOptional("TableGenBreakInsideDAGArg",
1335 Style.TableGenBreakInsideDAGArg);
1336 IO.mapOptional("TabWidth", Style.TabWidth);
1337 IO.mapOptional("TemplateNames", Style.TemplateNames);
1338 IO.mapOptional("TypeNames", Style.TypeNames);
1339 IO.mapOptional("TypenameMacros", Style.TypenameMacros);
1340 IO.mapOptional("UseTab", Style.UseTab);
1341 IO.mapOptional("VariableTemplates", Style.VariableTemplates);
1342 IO.mapOptional("VerilogBreakBetweenInstancePorts",
1343 Style.VerilogBreakBetweenInstancePorts);
1344 IO.mapOptional("WhitespaceSensitiveMacros",
1345 Style.WhitespaceSensitiveMacros);
1346 IO.mapOptional("WrapNamespaceBodyWithEmptyLines",
1347 Style.WrapNamespaceBodyWithEmptyLines);
1348
1349 // If AlwaysBreakAfterDefinitionReturnType was specified but
1350 // BreakAfterReturnType was not, initialize the latter from the former for
1351 // backwards compatibility.
1352 if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
1353 Style.BreakAfterReturnType == FormatStyle::RTBS_None) {
1354 if (Style.AlwaysBreakAfterDefinitionReturnType ==
1355 FormatStyle::DRTBS_All) {
1356 Style.BreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1357 } else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1358 FormatStyle::DRTBS_TopLevel) {
1359 Style.BreakAfterReturnType = FormatStyle::RTBS_TopLevelDefinitions;
1360 }
1361 }
1362
1363 // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1364 // not, initialize the latter from the former for backwards compatibility.
1365 if (BreakBeforeInheritanceComma &&
1366 Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) {
1367 Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1368 }
1369
1370 // If BreakConstructorInitializersBeforeComma was specified but
1371 // BreakConstructorInitializers was not, initialize the latter from the
1372 // former for backwards compatibility.
1373 if (BreakConstructorInitializersBeforeComma &&
1374 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon) {
1375 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1376 }
1377
1378 if (!IsGoogleOrChromium) {
1379 if (Style.PackConstructorInitializers == FormatStyle::PCIS_BinPack &&
1380 OnCurrentLine) {
1381 Style.PackConstructorInitializers = OnNextLine
1382 ? FormatStyle::PCIS_NextLine
1383 : FormatStyle::PCIS_CurrentLine;
1384 }
1385 } else if (Style.PackConstructorInitializers ==
1386 FormatStyle::PCIS_NextLine) {
1387 if (!OnCurrentLine)
1388 Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1389 else if (!OnNextLine)
1390 Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine;
1391 }
1392
1393 if (Style.LineEnding == FormatStyle::LE_DeriveLF) {
1394 if (!DeriveLineEnding)
1395 Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1396 else if (UseCRLF)
1397 Style.LineEnding = FormatStyle::LE_DeriveCRLF;
1398 }
1399
1400 // If SpaceInEmptyBlock was specified but SpaceInEmptyBraces was not,
1401 // initialize the latter from the former for backward compatibility.
1402 if (SpaceInEmptyBlock &&
1403 Style.SpaceInEmptyBraces == FormatStyle::SIEB_Never) {
1404 Style.SpaceInEmptyBraces = FormatStyle::SIEB_Block;
1405 }
1406
1407 if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
1408 (SpacesInParentheses || SpaceInEmptyParentheses ||
1409 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1410 if (SpacesInParentheses) {
1411 // For backward compatibility.
1412 Style.SpacesInParensOptions.ExceptDoubleParentheses = false;
1413 Style.SpacesInParensOptions.InConditionalStatements = true;
1414 Style.SpacesInParensOptions.InCStyleCasts =
1415 SpacesInCStyleCastParentheses;
1416 Style.SpacesInParensOptions.InEmptyParentheses =
1417 SpaceInEmptyParentheses;
1418 Style.SpacesInParensOptions.Other = true;
1419 } else {
1420 Style.SpacesInParensOptions = {};
1421 Style.SpacesInParensOptions.InConditionalStatements =
1422 SpacesInConditionalStatement;
1423 Style.SpacesInParensOptions.InCStyleCasts =
1424 SpacesInCStyleCastParentheses;
1425 Style.SpacesInParensOptions.InEmptyParentheses =
1426 SpaceInEmptyParentheses;
1427 }
1428 Style.SpacesInParens = FormatStyle::SIPO_Custom;
1429 }
1430 }
1431};
1432
1433// Allows to read vector<FormatStyle> while keeping default values.
1434// IO.getContext() should contain a pointer to the FormatStyle structure, that
1435// will be used to get default values for missing keys.
1436// If the first element has no Language specified, it will be treated as the
1437// default one for the following elements.
1438template <> struct DocumentListTraits<std::vector<FormatStyle>> {
1439 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1440 return Seq.size();
1441 }
1442 static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
1443 size_t Index) {
1444 if (Index >= Seq.size()) {
1445 assert(Index == Seq.size());
1446 FormatStyle Template;
1447 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1448 Template = Seq[0];
1449 } else {
1450 Template = *((const FormatStyle *)IO.getContext());
1451 Template.Language = FormatStyle::LK_None;
1452 }
1453 Seq.resize(Index + 1, Template);
1454 }
1455 return Seq[Index];
1456 }
1457};
1458} // namespace yaml
1459} // namespace llvm
1460
1461namespace clang {
1462namespace format {
1463
1464const std::error_category &getParseCategory() {
1465 static const ParseErrorCategory C{};
1466 return C;
1467}
1468std::error_code make_error_code(ParseError e) {
1469 return std::error_code(static_cast<int>(e), getParseCategory());
1470}
1471
1472inline llvm::Error make_string_error(const Twine &Message) {
1473 return llvm::make_error<llvm::StringError>(Message,
1474 llvm::inconvertibleErrorCode());
1475}
1476
1477const char *ParseErrorCategory::name() const noexcept {
1478 return "clang-format.parse_error";
1479}
1480
1481std::string ParseErrorCategory::message(int EV) const {
1482 switch (static_cast<ParseError>(EV)) {
1484 return "Success";
1485 case ParseError::Error:
1486 return "Invalid argument";
1488 return "Unsuitable";
1490 return "trailing comma insertion cannot be used with bin packing";
1492 return "Invalid qualifier specified in QualifierOrder";
1494 return "Duplicate qualifier specified in QualifierOrder";
1496 return "Missing type in QualifierOrder";
1498 return "Missing QualifierOrder";
1499 }
1500 llvm_unreachable("unexpected parse error");
1501}
1502
1503static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
1504 if (Expanded.BreakBeforeBraces == FormatStyle::BS_Custom)
1505 return;
1506 Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
1507 /*AfterClass=*/false,
1508 /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1509 /*AfterEnum=*/false,
1510 /*AfterFunction=*/false,
1511 /*AfterNamespace=*/false,
1512 /*AfterObjCDeclaration=*/false,
1513 /*AfterStruct=*/false,
1514 /*AfterUnion=*/false,
1515 /*AfterExternBlock=*/false,
1516 /*BeforeCatch=*/false,
1517 /*BeforeElse=*/false,
1518 /*BeforeLambdaBody=*/false,
1519 /*BeforeWhile=*/false,
1520 /*IndentBraces=*/false,
1521 /*SplitEmptyFunction=*/true,
1522 /*SplitEmptyRecord=*/true,
1523 /*SplitEmptyNamespace=*/true};
1524 switch (Expanded.BreakBeforeBraces) {
1525 case FormatStyle::BS_Linux:
1526 Expanded.BraceWrapping.AfterClass = true;
1527 Expanded.BraceWrapping.AfterFunction = true;
1528 Expanded.BraceWrapping.AfterNamespace = true;
1529 break;
1530 case FormatStyle::BS_Mozilla:
1531 Expanded.BraceWrapping.AfterClass = true;
1532 Expanded.BraceWrapping.AfterEnum = true;
1533 Expanded.BraceWrapping.AfterFunction = true;
1534 Expanded.BraceWrapping.AfterStruct = true;
1535 Expanded.BraceWrapping.AfterUnion = true;
1536 Expanded.BraceWrapping.AfterExternBlock = true;
1537 Expanded.BraceWrapping.SplitEmptyFunction = true;
1538 Expanded.BraceWrapping.SplitEmptyRecord = false;
1539 break;
1540 case FormatStyle::BS_Stroustrup:
1541 Expanded.BraceWrapping.AfterFunction = true;
1542 Expanded.BraceWrapping.BeforeCatch = true;
1543 Expanded.BraceWrapping.BeforeElse = true;
1544 break;
1545 case FormatStyle::BS_Allman:
1546 Expanded.BraceWrapping.AfterCaseLabel = true;
1547 Expanded.BraceWrapping.AfterClass = true;
1548 Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1549 Expanded.BraceWrapping.AfterEnum = true;
1550 Expanded.BraceWrapping.AfterFunction = true;
1551 Expanded.BraceWrapping.AfterNamespace = true;
1552 Expanded.BraceWrapping.AfterObjCDeclaration = true;
1553 Expanded.BraceWrapping.AfterStruct = true;
1554 Expanded.BraceWrapping.AfterUnion = true;
1555 Expanded.BraceWrapping.AfterExternBlock = true;
1556 Expanded.BraceWrapping.BeforeCatch = true;
1557 Expanded.BraceWrapping.BeforeElse = true;
1558 Expanded.BraceWrapping.BeforeLambdaBody = true;
1559 break;
1560 case FormatStyle::BS_Whitesmiths:
1561 Expanded.BraceWrapping.AfterCaseLabel = true;
1562 Expanded.BraceWrapping.AfterClass = true;
1563 Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1564 Expanded.BraceWrapping.AfterEnum = true;
1565 Expanded.BraceWrapping.AfterFunction = true;
1566 Expanded.BraceWrapping.AfterNamespace = true;
1567 Expanded.BraceWrapping.AfterObjCDeclaration = true;
1568 Expanded.BraceWrapping.AfterStruct = true;
1569 Expanded.BraceWrapping.AfterExternBlock = true;
1570 Expanded.BraceWrapping.BeforeCatch = true;
1571 Expanded.BraceWrapping.BeforeElse = true;
1572 Expanded.BraceWrapping.BeforeLambdaBody = true;
1573 break;
1574 case FormatStyle::BS_GNU:
1575 Expanded.BraceWrapping = {
1576 /*AfterCaseLabel=*/true,
1577 /*AfterClass=*/true,
1578 /*AfterControlStatement=*/FormatStyle::BWACS_Always,
1579 /*AfterEnum=*/true,
1580 /*AfterFunction=*/true,
1581 /*AfterNamespace=*/true,
1582 /*AfterObjCDeclaration=*/true,
1583 /*AfterStruct=*/true,
1584 /*AfterUnion=*/true,
1585 /*AfterExternBlock=*/true,
1586 /*BeforeCatch=*/true,
1587 /*BeforeElse=*/true,
1588 /*BeforeLambdaBody=*/true,
1589 /*BeforeWhile=*/true,
1590 /*IndentBraces=*/true,
1591 /*SplitEmptyFunction=*/true,
1592 /*SplitEmptyRecord=*/true,
1593 /*SplitEmptyNamespace=*/true};
1594 break;
1595 case FormatStyle::BS_WebKit:
1596 Expanded.BraceWrapping.AfterFunction = true;
1597 break;
1598 default:
1599 break;
1600 }
1601}
1602
1603static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded) {
1604 if (Expanded.SpaceBeforeParens == FormatStyle::SBPO_Custom)
1605 return;
1606 // Reset all flags
1607 Expanded.SpaceBeforeParensOptions = {};
1608 Expanded.SpaceBeforeParensOptions.AfterPlacementOperator = true;
1609
1610 switch (Expanded.SpaceBeforeParens) {
1611 case FormatStyle::SBPO_ControlStatements:
1612 Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1613 Expanded.SpaceBeforeParensOptions.AfterForeachMacros = true;
1614 Expanded.SpaceBeforeParensOptions.AfterIfMacros = true;
1615 break;
1616 case FormatStyle::SBPO_ControlStatementsExceptControlMacros:
1617 Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1618 break;
1619 case FormatStyle::SBPO_NonEmptyParentheses:
1620 Expanded.SpaceBeforeParensOptions.BeforeNonEmptyParentheses = true;
1621 break;
1622 default:
1623 break;
1624 }
1625}
1626
1627static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
1628 if (Expanded.SpacesInParens == FormatStyle::SIPO_Custom)
1629 return;
1630 assert(Expanded.SpacesInParens == FormatStyle::SIPO_Never);
1631 // Reset all flags
1632 Expanded.SpacesInParensOptions = {};
1633}
1634
1635FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
1636 FormatStyle LLVMStyle;
1637 LLVMStyle.AccessModifierOffset = -2;
1638 LLVMStyle.AlignAfterOpenBracket = true;
1639 LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
1640 LLVMStyle.AlignConsecutiveAssignments = {};
1641 LLVMStyle.AlignConsecutiveAssignments.PadOperators = true;
1642 LLVMStyle.AlignConsecutiveBitFields = {};
1643 LLVMStyle.AlignConsecutiveDeclarations = {};
1644 LLVMStyle.AlignConsecutiveDeclarations.AlignFunctionDeclarations = true;
1645 LLVMStyle.AlignConsecutiveMacros = {};
1646 LLVMStyle.AlignConsecutiveShortCaseStatements = {};
1647 LLVMStyle.AlignConsecutiveTableGenBreakingDAGArgColons = {};
1648 LLVMStyle.AlignConsecutiveTableGenCondOperatorColons = {};
1649 LLVMStyle.AlignConsecutiveTableGenDefinitionColons = {};
1650 LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
1651 LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
1652 LLVMStyle.AlignTrailingComments = {};
1653 LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
1654 LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;
1655 LLVMStyle.AlignTrailingComments.AlignPPAndNotPP = true;
1656 LLVMStyle.AllowAllArgumentsOnNextLine = true;
1657 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
1658 LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never;
1659 LLVMStyle.AllowBreakBeforeQtProperty = false;
1660 LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
1661 LLVMStyle.AllowShortCaseExpressionOnASingleLine = true;
1662 LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
1663 LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
1664 LLVMStyle.AllowShortEnumsOnASingleLine = true;
1665 LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
1666 LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1667 LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
1668 LLVMStyle.AllowShortLoopsOnASingleLine = false;
1669 LLVMStyle.AllowShortNamespacesOnASingleLine = false;
1670 LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1671 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
1672 LLVMStyle.AttributeMacros.push_back("__capability");
1673 LLVMStyle.BinPackArguments = true;
1674 LLVMStyle.BinPackLongBracedList = true;
1675 LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack;
1676 LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
1677 LLVMStyle.BracedInitializerIndentWidth = -1;
1678 LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
1679 /*AfterClass=*/false,
1680 /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1681 /*AfterEnum=*/false,
1682 /*AfterFunction=*/false,
1683 /*AfterNamespace=*/false,
1684 /*AfterObjCDeclaration=*/false,
1685 /*AfterStruct=*/false,
1686 /*AfterUnion=*/false,
1687 /*AfterExternBlock=*/false,
1688 /*BeforeCatch=*/false,
1689 /*BeforeElse=*/false,
1690 /*BeforeLambdaBody=*/false,
1691 /*BeforeWhile=*/false,
1692 /*IndentBraces=*/false,
1693 /*SplitEmptyFunction=*/true,
1694 /*SplitEmptyRecord=*/true,
1695 /*SplitEmptyNamespace=*/true};
1696 LLVMStyle.BreakAdjacentStringLiterals = true;
1697 LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave;
1698 LLVMStyle.BreakAfterJavaFieldAnnotations = false;
1699 LLVMStyle.BreakAfterOpenBracketBracedList = false;
1700 LLVMStyle.BreakAfterOpenBracketFunction = false;
1701 LLVMStyle.BreakAfterOpenBracketIf = false;
1702 LLVMStyle.BreakAfterOpenBracketLoop = false;
1703 LLVMStyle.BreakAfterOpenBracketSwitch = false;
1704 LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None;
1705 LLVMStyle.BreakArrays = true;
1706 LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
1707 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
1708 LLVMStyle.BreakBeforeCloseBracketBracedList = false;
1709 LLVMStyle.BreakBeforeCloseBracketFunction = false;
1710 LLVMStyle.BreakBeforeCloseBracketIf = false;
1711 LLVMStyle.BreakBeforeCloseBracketLoop = false;
1712 LLVMStyle.BreakBeforeCloseBracketSwitch = false;
1713 LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
1714 LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
1715 LLVMStyle.BreakBeforeTemplateCloser = false;
1716 LLVMStyle.BreakBeforeTernaryOperators = true;
1717 LLVMStyle.BreakBinaryOperations = FormatStyle::BBO_Never;
1718 LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
1719 LLVMStyle.BreakFunctionDefinitionParameters = false;
1720 LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
1721 LLVMStyle.BreakStringLiterals = true;
1722 LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
1723 LLVMStyle.ColumnLimit = 80;
1724 LLVMStyle.CommentPragmas = "^ IWYU pragma:";
1725 LLVMStyle.CompactNamespaces = false;
1726 LLVMStyle.ConstructorInitializerIndentWidth = 4;
1727 LLVMStyle.ContinuationIndentWidth = 4;
1728 LLVMStyle.Cpp11BracedListStyle = FormatStyle::BLS_AlignFirstComment;
1729 LLVMStyle.DerivePointerAlignment = false;
1730 LLVMStyle.DisableFormat = false;
1731 LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
1732 LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
1733 LLVMStyle.EnumTrailingComma = FormatStyle::ETC_Leave;
1734 LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1735 LLVMStyle.FixNamespaceComments = true;
1736 LLVMStyle.ForEachMacros.push_back("foreach");
1737 LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1738 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1739 LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
1740 LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
1741 LLVMStyle.IncludeStyle.IncludeCategories = {
1742 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1743 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1744 {".*", 1, 0, false}};
1745 LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1746 LLVMStyle.IncludeStyle.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1747 LLVMStyle.IndentAccessModifiers = false;
1748 LLVMStyle.IndentCaseBlocks = false;
1749 LLVMStyle.IndentCaseLabels = false;
1750 LLVMStyle.IndentExportBlock = true;
1751 LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1752 LLVMStyle.IndentGotoLabels = true;
1753 LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
1754 LLVMStyle.IndentRequiresClause = true;
1755 LLVMStyle.IndentWidth = 2;
1756 LLVMStyle.IndentWrappedFunctionNames = false;
1757 LLVMStyle.InheritsParentConfig = false;
1758 LLVMStyle.InsertBraces = false;
1759 LLVMStyle.InsertNewlineAtEOF = false;
1760 LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1761 LLVMStyle.IntegerLiteralSeparator = {
1762 /*Binary=*/0, /*BinaryMinDigits=*/0,
1763 /*Decimal=*/0, /*DecimalMinDigits=*/0,
1764 /*Hex=*/0, /*HexMinDigits=*/0};
1765 LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
1766 LLVMStyle.JavaScriptWrapImports = true;
1767 LLVMStyle.KeepEmptyLines = {
1768 /*AtEndOfFile=*/false,
1769 /*AtStartOfBlock=*/true,
1770 /*AtStartOfFile=*/true,
1771 };
1772 LLVMStyle.KeepFormFeed = false;
1773 LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature;
1774 LLVMStyle.Language = Language;
1775 LLVMStyle.LineEnding = FormatStyle::LE_DeriveLF;
1776 LLVMStyle.MaxEmptyLinesToKeep = 1;
1777 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
1778 LLVMStyle.NumericLiteralCase = {/*ExponentLetter=*/FormatStyle::NLCS_Leave,
1779 /*HexDigit=*/FormatStyle::NLCS_Leave,
1780 /*Prefix=*/FormatStyle::NLCS_Leave,
1781 /*Suffix=*/FormatStyle::NLCS_Leave};
1782 LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
1783 LLVMStyle.ObjCBlockIndentWidth = 2;
1784 LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1785 LLVMStyle.ObjCSpaceAfterProperty = false;
1786 LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1787 LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1788 LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
1789 LLVMStyle.PPIndentWidth = -1;
1790 LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave;
1791 LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
1792 LLVMStyle.ReflowComments = FormatStyle::RCS_Always;
1793 LLVMStyle.RemoveBracesLLVM = false;
1794 LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false;
1795 LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave;
1796 LLVMStyle.RemoveSemicolon = false;
1797 LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine;
1798 LLVMStyle.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
1799 LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
1800 LLVMStyle.ShortNamespaceLines = 1;
1801 LLVMStyle.SkipMacroDefinitionBody = false;
1802 LLVMStyle.SortIncludes = {/*Enabled=*/true, /*IgnoreCase=*/false,
1803 /*IgnoreExtension=*/false};
1804 LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
1805 LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
1806 LLVMStyle.SpaceAfterCStyleCast = false;
1807 LLVMStyle.SpaceAfterLogicalNot = false;
1808 LLVMStyle.SpaceAfterOperatorKeyword = false;
1809 LLVMStyle.SpaceAfterTemplateKeyword = true;
1810 LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
1811 LLVMStyle.SpaceBeforeAssignmentOperators = true;
1812 LLVMStyle.SpaceBeforeCaseColon = false;
1813 LLVMStyle.SpaceBeforeCpp11BracedList = false;
1814 LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1815 LLVMStyle.SpaceBeforeInheritanceColon = true;
1816 LLVMStyle.SpaceBeforeJsonColon = false;
1817 LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
1818 LLVMStyle.SpaceBeforeParensOptions = {};
1819 LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true;
1820 LLVMStyle.SpaceBeforeParensOptions.AfterForeachMacros = true;
1821 LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true;
1822 LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1823 LLVMStyle.SpaceBeforeSquareBrackets = false;
1824 LLVMStyle.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
1825 LLVMStyle.SpacesBeforeTrailingComments = 1;
1826 LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
1827 LLVMStyle.SpacesInContainerLiterals = true;
1828 LLVMStyle.SpacesInLineCommentPrefix = {
1829 /*Minimum=*/1, /*Maximum=*/std::numeric_limits<unsigned>::max()};
1830 LLVMStyle.SpacesInParens = FormatStyle::SIPO_Never;
1831 LLVMStyle.SpacesInSquareBrackets = false;
1832 LLVMStyle.Standard = FormatStyle::LS_Latest;
1833 LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1834 LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1835 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1836 LLVMStyle.TableGenBreakingDAGArgOperators = {};
1837 LLVMStyle.TableGenBreakInsideDAGArg = FormatStyle::DAS_DontBreak;
1838 LLVMStyle.TabWidth = 8;
1839 LLVMStyle.UseTab = FormatStyle::UT_Never;
1840 LLVMStyle.VerilogBreakBetweenInstancePorts = true;
1841 LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1842 LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1843 LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1844 LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1845 LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1846 LLVMStyle.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
1847
1848 LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
1849 LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
1850 LLVMStyle.PenaltyBreakBeforeMemberAccess = 150;
1851 LLVMStyle.PenaltyBreakComment = 300;
1852 LLVMStyle.PenaltyBreakFirstLessLess = 120;
1853 LLVMStyle.PenaltyBreakOpenParenthesis = 0;
1854 LLVMStyle.PenaltyBreakScopeResolution = 500;
1855 LLVMStyle.PenaltyBreakString = 1000;
1856 LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
1857 LLVMStyle.PenaltyExcessCharacter = 1'000'000;
1858 LLVMStyle.PenaltyIndentedWhitespace = 0;
1859 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1860
1861 // Defaults that differ when not C++.
1862 switch (Language) {
1863 case FormatStyle::LK_TableGen:
1864 LLVMStyle.SpacesInContainerLiterals = false;
1865 break;
1866 case FormatStyle::LK_Json:
1867 LLVMStyle.ColumnLimit = 0;
1868 break;
1869 case FormatStyle::LK_Verilog:
1870 LLVMStyle.IndentCaseLabels = true;
1871 LLVMStyle.SpacesInContainerLiterals = false;
1872 break;
1873 default:
1874 break;
1875 }
1876
1877 return LLVMStyle;
1878}
1879
1880FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
1881 if (Language == FormatStyle::LK_TextProto) {
1882 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
1883 GoogleStyle.Language = FormatStyle::LK_TextProto;
1884
1885 return GoogleStyle;
1886 }
1887
1888 FormatStyle GoogleStyle = getLLVMStyle(Language);
1889
1890 GoogleStyle.AccessModifierOffset = -1;
1891 GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
1892 GoogleStyle.AllowShortIfStatementsOnASingleLine =
1893 FormatStyle::SIS_WithoutElse;
1894 GoogleStyle.AllowShortLoopsOnASingleLine = true;
1895 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1896 // Abseil aliases to clang's `_Nonnull`, `_Nullable` and `_Null_unspecified`.
1897 GoogleStyle.AttributeMacros.push_back("absl_nonnull");
1898 GoogleStyle.AttributeMacros.push_back("absl_nullable");
1899 GoogleStyle.AttributeMacros.push_back("absl_nullability_unknown");
1900 GoogleStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1901 GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1902 GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1903 {"^<.*\\.h>", 1, 0, false},
1904 {"^<.*", 2, 0, false},
1905 {".*", 3, 0, false}};
1906 GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1907 GoogleStyle.IndentCaseLabels = true;
1908 GoogleStyle.KeepEmptyLines.AtStartOfBlock = false;
1909 GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
1910 GoogleStyle.ObjCSpaceAfterProperty = false;
1911 GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1912 GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
1913 GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
1914 GoogleStyle.RawStringFormats = {
1915 {
1916 FormatStyle::LK_Cpp,
1917 /*Delimiters=*/
1918 {
1919 "cc",
1920 "CC",
1921 "cpp",
1922 "Cpp",
1923 "CPP",
1924 "c++",
1925 "C++",
1926 },
1927 /*EnclosingFunctionNames=*/
1928 {},
1929 /*CanonicalDelimiter=*/"",
1930 /*BasedOnStyle=*/"google",
1931 },
1932 {
1933 FormatStyle::LK_TextProto,
1934 /*Delimiters=*/
1935 {
1936 "pb",
1937 "PB",
1938 "proto",
1939 "PROTO",
1940 },
1941 /*EnclosingFunctionNames=*/
1942 {
1943 "EqualsProto",
1944 "EquivToProto",
1945 "PARSE_PARTIAL_TEXT_PROTO",
1946 "PARSE_TEST_PROTO",
1947 "PARSE_TEXT_PROTO",
1948 "ParseTextOrDie",
1949 "ParseTextProtoOrDie",
1950 "ParseTestProto",
1951 "ParsePartialTestProto",
1952 },
1953 /*CanonicalDelimiter=*/"pb",
1954 /*BasedOnStyle=*/"google",
1955 },
1956 };
1957
1958 GoogleStyle.SpacesBeforeTrailingComments = 2;
1959 GoogleStyle.Standard = FormatStyle::LS_Auto;
1960
1961 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
1962 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1963
1964 if (Language == FormatStyle::LK_Java) {
1965 GoogleStyle.AlignAfterOpenBracket = false;
1966 GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1967 GoogleStyle.AlignTrailingComments = {};
1968 GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
1969 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1970 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1971 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1972 GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
1973 GoogleStyle.ColumnLimit = 100;
1974 GoogleStyle.SpaceAfterCStyleCast = true;
1975 GoogleStyle.SpacesBeforeTrailingComments = 1;
1976 } else if (Language == FormatStyle::LK_JavaScript) {
1977 GoogleStyle.BreakAfterOpenBracketBracedList = true;
1978 GoogleStyle.BreakAfterOpenBracketFunction = true;
1979 GoogleStyle.BreakAfterOpenBracketIf = true;
1980 GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1981 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1982 // TODO: still under discussion whether to switch to SLS_All.
1983 GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
1984 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1985 GoogleStyle.BreakBeforeTernaryOperators = false;
1986 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1987 // commonly followed by overlong URLs.
1988 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1989 // TODO: enable once decided, in particular re disabling bin packing.
1990 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1991 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1992 GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
1993 GoogleStyle.JavaScriptWrapImports = false;
1994 GoogleStyle.MaxEmptyLinesToKeep = 3;
1995 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1996 GoogleStyle.SpacesInContainerLiterals = false;
1997 } else if (Language == FormatStyle::LK_Proto) {
1998 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1999 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
2000 // This affects protocol buffer options specifications and text protos.
2001 // Text protos are currently mostly formatted inside C++ raw string literals
2002 // and often the current breaking behavior of string literals is not
2003 // beneficial there. Investigate turning this on once proper string reflow
2004 // has been implemented.
2005 GoogleStyle.BreakStringLiterals = false;
2006 GoogleStyle.Cpp11BracedListStyle = FormatStyle::BLS_Block;
2007 GoogleStyle.SpacesInContainerLiterals = false;
2008 } else if (Language == FormatStyle::LK_ObjC) {
2009 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
2010 GoogleStyle.ColumnLimit = 100;
2011 GoogleStyle.DerivePointerAlignment = true;
2012 // "Regroup" doesn't work well for ObjC yet (main header heuristic,
2013 // relationship between ObjC standard library headers and other heades,
2014 // #imports, etc.)
2015 GoogleStyle.IncludeStyle.IncludeBlocks =
2017 } else if (Language == FormatStyle::LK_CSharp) {
2018 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
2019 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
2020 GoogleStyle.BreakStringLiterals = false;
2021 GoogleStyle.ColumnLimit = 100;
2022 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
2023 }
2024
2025 return GoogleStyle;
2026}
2027
2028FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
2029 FormatStyle ChromiumStyle = getGoogleStyle(Language);
2030
2031 // Disable include reordering across blocks in Chromium code.
2032 // - clang-format tries to detect that foo.h is the "main" header for
2033 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
2034 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
2035 // _private.cc, _impl.cc etc) in different permutations
2036 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
2037 // better default for Chromium code.
2038 // - The default for .cc and .mm files is different (r357695) for Google style
2039 // for the same reason. The plan is to unify this again once the main
2040 // header detection works for Google's ObjC code, but this hasn't happened
2041 // yet. Since Chromium has some ObjC code, switching Chromium is blocked
2042 // on that.
2043 // - Finally, "If include reordering is harmful, put things in different
2044 // blocks to prevent it" has been a recommendation for a long time that
2045 // people are used to. We'll need a dev education push to change this to
2046 // "If include reordering is harmful, put things in a different block and
2047 // _prepend that with a comment_ to prevent it" before changing behavior.
2048 ChromiumStyle.IncludeStyle.IncludeBlocks =
2050
2051 if (Language == FormatStyle::LK_Java) {
2052 ChromiumStyle.AllowShortIfStatementsOnASingleLine =
2053 FormatStyle::SIS_WithoutElse;
2054 ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
2055 ChromiumStyle.ContinuationIndentWidth = 8;
2056 ChromiumStyle.IndentWidth = 4;
2057 // See styleguide for import groups:
2058 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
2059 ChromiumStyle.JavaImportGroups = {
2060 "android",
2061 "androidx",
2062 "com",
2063 "dalvik",
2064 "junit",
2065 "org",
2066 "com.google.android.apps.chrome",
2067 "org.chromium",
2068 "java",
2069 "javax",
2070 };
2071 } else if (Language == FormatStyle::LK_JavaScript) {
2072 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
2073 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
2074 } else {
2075 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
2076 ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
2077 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
2078 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
2079 ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
2080 ChromiumStyle.DerivePointerAlignment = false;
2081 if (Language == FormatStyle::LK_ObjC)
2082 ChromiumStyle.ColumnLimit = 80;
2083 }
2084 return ChromiumStyle;
2085}
2086
2087FormatStyle getMozillaStyle() {
2088 FormatStyle MozillaStyle = getLLVMStyle();
2089 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
2090 MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
2091 MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
2092 FormatStyle::DRTBS_TopLevel;
2093 MozillaStyle.BinPackArguments = false;
2094 MozillaStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
2095 MozillaStyle.BreakAfterReturnType = FormatStyle::RTBS_TopLevel;
2096 MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
2097 MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
2098 MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
2099 MozillaStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
2100 MozillaStyle.ConstructorInitializerIndentWidth = 2;
2101 MozillaStyle.ContinuationIndentWidth = 2;
2102 MozillaStyle.Cpp11BracedListStyle = FormatStyle::BLS_Block;
2103 MozillaStyle.FixNamespaceComments = false;
2104 MozillaStyle.IndentCaseLabels = true;
2105 MozillaStyle.ObjCSpaceAfterProperty = true;
2106 MozillaStyle.ObjCSpaceBeforeProtocolList = false;
2107 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
2108 MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
2109 MozillaStyle.SpaceAfterTemplateKeyword = false;
2110 return MozillaStyle;
2111}
2112
2113FormatStyle getWebKitStyle() {
2114 FormatStyle Style = getLLVMStyle();
2115 Style.AccessModifierOffset = -4;
2116 Style.AlignAfterOpenBracket = false;
2117 Style.AlignOperands = FormatStyle::OAS_DontAlign;
2118 Style.AlignTrailingComments = {};
2119 Style.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
2120 Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
2121 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
2122 Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
2123 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
2124 Style.ColumnLimit = 0;
2125 Style.Cpp11BracedListStyle = FormatStyle::BLS_Block;
2126 Style.FixNamespaceComments = false;
2127 Style.IndentWidth = 4;
2128 Style.NamespaceIndentation = FormatStyle::NI_Inner;
2129 Style.ObjCBlockIndentWidth = 4;
2130 Style.ObjCSpaceAfterProperty = true;
2131 Style.PointerAlignment = FormatStyle::PAS_Left;
2132 Style.SpaceBeforeCpp11BracedList = true;
2133 Style.SpaceInEmptyBraces = FormatStyle::SIEB_Always;
2134 return Style;
2135}
2136
2137FormatStyle getGNUStyle() {
2138 FormatStyle Style = getLLVMStyle();
2139 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
2140 Style.BreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
2141 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
2142 Style.BreakBeforeBraces = FormatStyle::BS_GNU;
2143 Style.BreakBeforeTernaryOperators = true;
2144 Style.ColumnLimit = 79;
2145 Style.Cpp11BracedListStyle = FormatStyle::BLS_Block;
2146 Style.FixNamespaceComments = false;
2147 Style.KeepFormFeed = true;
2148 Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
2149 return Style;
2150}
2151
2152FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
2153 FormatStyle Style = getLLVMStyle(Language);
2154 Style.ColumnLimit = 120;
2155 Style.TabWidth = 4;
2156 Style.IndentWidth = 4;
2157 Style.UseTab = FormatStyle::UT_Never;
2158 Style.BreakBeforeBraces = FormatStyle::BS_Custom;
2159 Style.BraceWrapping.AfterClass = true;
2160 Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
2161 Style.BraceWrapping.AfterEnum = true;
2162 Style.BraceWrapping.AfterFunction = true;
2163 Style.BraceWrapping.AfterNamespace = true;
2164 Style.BraceWrapping.AfterObjCDeclaration = true;
2165 Style.BraceWrapping.AfterStruct = true;
2166 Style.BraceWrapping.AfterExternBlock = true;
2167 Style.BraceWrapping.BeforeCatch = true;
2168 Style.BraceWrapping.BeforeElse = true;
2169 Style.BraceWrapping.BeforeWhile = false;
2170 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
2171 Style.AllowShortEnumsOnASingleLine = false;
2172 Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
2173 Style.AllowShortCaseLabelsOnASingleLine = false;
2174 Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
2175 Style.AllowShortLoopsOnASingleLine = false;
2176 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
2177 Style.BreakAfterReturnType = FormatStyle::RTBS_None;
2178 return Style;
2179}
2180
2181FormatStyle getClangFormatStyle() {
2182 FormatStyle Style = getLLVMStyle();
2183 Style.InsertBraces = true;
2184 Style.InsertNewlineAtEOF = true;
2185 Style.IntegerLiteralSeparator.Decimal = 3;
2186 Style.IntegerLiteralSeparator.DecimalMinDigits = 5;
2187 Style.LineEnding = FormatStyle::LE_LF;
2188 Style.RemoveBracesLLVM = true;
2189 Style.RemoveEmptyLinesInUnwrappedLines = true;
2190 Style.RemoveParentheses = FormatStyle::RPS_ReturnStatement;
2191 Style.RemoveSemicolon = true;
2192 return Style;
2193}
2194
2195FormatStyle getNoStyle() {
2196 FormatStyle NoStyle = getLLVMStyle();
2197 NoStyle.DisableFormat = true;
2198 NoStyle.SortIncludes = {};
2199 NoStyle.SortUsingDeclarations = FormatStyle::SUD_Never;
2200 return NoStyle;
2201}
2202
2203bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
2204 FormatStyle *Style) {
2205 if (Name.equals_insensitive("llvm"))
2206 *Style = getLLVMStyle(Language);
2207 else if (Name.equals_insensitive("chromium"))
2208 *Style = getChromiumStyle(Language);
2209 else if (Name.equals_insensitive("mozilla"))
2210 *Style = getMozillaStyle();
2211 else if (Name.equals_insensitive("google"))
2212 *Style = getGoogleStyle(Language);
2213 else if (Name.equals_insensitive("webkit"))
2214 *Style = getWebKitStyle();
2215 else if (Name.equals_insensitive("gnu"))
2216 *Style = getGNUStyle();
2217 else if (Name.equals_insensitive("microsoft"))
2218 *Style = getMicrosoftStyle(Language);
2219 else if (Name.equals_insensitive("clang-format"))
2220 *Style = getClangFormatStyle();
2221 else if (Name.equals_insensitive("none"))
2222 *Style = getNoStyle();
2223 else if (Name.equals_insensitive("inheritparentconfig"))
2224 Style->InheritsParentConfig = true;
2225 else
2226 return false;
2227
2228 Style->Language = Language;
2229 return true;
2230}
2231
2233 // If its empty then it means don't do anything.
2234 if (Style->QualifierOrder.empty())
2236
2237 // Ensure the list contains only currently valid qualifiers.
2238 for (const auto &Qualifier : Style->QualifierOrder) {
2239 if (Qualifier == "type")
2240 continue;
2241 auto token =
2243 if (token == tok::identifier)
2245 }
2246
2247 // Ensure the list is unique (no duplicates).
2248 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2249 Style->QualifierOrder.end());
2250 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2251 LLVM_DEBUG(llvm::dbgs()
2252 << "Duplicate Qualifiers " << Style->QualifierOrder.size()
2253 << " vs " << UniqueQualifiers.size() << "\n");
2255 }
2256
2257 // Ensure the list has 'type' in it.
2258 if (!llvm::is_contained(Style->QualifierOrder, "type"))
2260
2261 return ParseError::Success;
2262}
2263
2264std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
2265 FormatStyle *Style, bool AllowUnknownOptions,
2266 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2267 void *DiagHandlerCtxt, bool IsDotHFile) {
2268 assert(Style);
2269 FormatStyle::LanguageKind Language = Style->Language;
2270 assert(Language != FormatStyle::LK_None);
2271 if (Config.getBuffer().trim().empty())
2273 Style->StyleSet.Clear();
2274 std::vector<FormatStyle> Styles;
2275 llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
2276 DiagHandlerCtxt);
2277 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
2278 // values for the fields, keys for which are missing from the configuration.
2279 // Mapping also uses the context to get the language to find the correct
2280 // base style.
2281 Input.setContext(Style);
2282 Input.setAllowUnknownKeys(AllowUnknownOptions);
2283 Input >> Styles;
2284 if (Input.error())
2285 return Input.error();
2286 if (Styles.empty())
2288
2289 const auto StyleCount = Styles.size();
2290
2291 // Start from the second style as (only) the first one may be the default.
2292 for (unsigned I = 1; I < StyleCount; ++I) {
2293 const auto Lang = Styles[I].Language;
2294 if (Lang == FormatStyle::LK_None)
2296 // Ensure that each language is configured at most once.
2297 for (unsigned J = 0; J < I; ++J) {
2298 if (Lang == Styles[J].Language) {
2299 LLVM_DEBUG(llvm::dbgs()
2300 << "Duplicate languages in the config file on positions "
2301 << J << " and " << I << '\n');
2303 }
2304 }
2305 }
2306
2307 int LanguagePos = -1; // Position of the style for Language.
2308 int CppPos = -1; // Position of the style for C++.
2309 int CPos = -1; // Position of the style for C.
2310
2311 // Search Styles for Language and store the positions of C++ and C styles in
2312 // case Language is not found.
2313 for (unsigned I = 0; I < StyleCount; ++I) {
2314 const auto Lang = Styles[I].Language;
2315 if (Lang == Language) {
2316 LanguagePos = I;
2317 break;
2318 }
2319 if (Lang == FormatStyle::LK_Cpp)
2320 CppPos = I;
2321 else if (Lang == FormatStyle::LK_C)
2322 CPos = I;
2323 }
2324
2325 // If Language is not found, use the default style if there is one. Otherwise,
2326 // use the C style for C++ .h files and for backward compatibility, the C++
2327 // style for .c files.
2328 if (LanguagePos < 0) {
2329 if (Styles[0].Language == FormatStyle::LK_None) // Default style.
2330 LanguagePos = 0;
2331 else if (IsDotHFile && Language == FormatStyle::LK_Cpp)
2332 LanguagePos = CPos;
2333 else if (!IsDotHFile && Language == FormatStyle::LK_C)
2334 LanguagePos = CppPos;
2335 if (LanguagePos < 0)
2337 }
2338
2339 for (const auto &S : llvm::reverse(llvm::drop_begin(Styles)))
2340 Style->StyleSet.Add(S);
2341
2342 *Style = Styles[LanguagePos];
2343
2344 if (LanguagePos == 0) {
2345 if (Style->Language == FormatStyle::LK_None) // Default style.
2346 Style->Language = Language;
2347 Style->StyleSet.Add(*Style);
2348 }
2349
2350 if (Style->InsertTrailingCommas != FormatStyle::TCS_None &&
2351 Style->BinPackArguments) {
2352 // See comment on FormatStyle::TSC_Wrapped.
2354 }
2355 if (Style->QualifierAlignment != FormatStyle::QAS_Leave)
2358}
2359
2360std::string configurationAsText(const FormatStyle &Style) {
2361 std::string Text;
2362 llvm::raw_string_ostream Stream(Text);
2363 llvm::yaml::Output Output(Stream);
2364 // We use the same mapping method for input and output, so we need a non-const
2365 // reference here.
2366 FormatStyle NonConstStyle = Style;
2367 expandPresetsBraceWrapping(NonConstStyle);
2368 expandPresetsSpaceBeforeParens(NonConstStyle);
2369 expandPresetsSpacesInParens(NonConstStyle);
2370 Output << NonConstStyle;
2371
2372 return Stream.str();
2373}
2374
2375std::optional<FormatStyle>
2376FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
2377 if (!Styles)
2378 return std::nullopt;
2379 auto It = Styles->find(Language);
2380 if (It == Styles->end())
2381 return std::nullopt;
2382 FormatStyle Style = It->second;
2383 Style.StyleSet = *this;
2384 return Style;
2385}
2386
2387void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
2388 assert(Style.Language != LK_None &&
2389 "Cannot add a style for LK_None to a StyleSet");
2390 assert(
2391 !Style.StyleSet.Styles &&
2392 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2393 if (!Styles)
2394 Styles = std::make_shared<MapType>();
2395 (*Styles)[Style.Language] = std::move(Style);
2396}
2397
2398void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
2399
2400std::optional<FormatStyle>
2401FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
2402 return StyleSet.Get(Language);
2403}
2404
2405namespace {
2406
2407void replaceToken(const FormatToken &Token, FormatToken *Next,
2408 const SourceManager &SourceMgr, tooling::Replacements &Result,
2409 StringRef Text = "") {
2410 const auto &Tok = Token.Tok;
2411 SourceLocation Start;
2412 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2413 Start = Tok.getLocation();
2414 Next->WhitespaceRange = Token.WhitespaceRange;
2415 } else {
2416 Start = Token.WhitespaceRange.getBegin();
2417 }
2418 const auto &Range = CharSourceRange::getCharRange(Start, Tok.getEndLoc());
2419 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, Text)));
2420}
2421
2422class ParensRemover : public TokenAnalyzer {
2423public:
2424 ParensRemover(const Environment &Env, const FormatStyle &Style)
2425 : TokenAnalyzer(Env, Style) {}
2426
2427 std::pair<tooling::Replacements, unsigned>
2428 analyze(TokenAnnotator &Annotator,
2429 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2430 FormatTokenLexer &Tokens) override {
2431 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2432 tooling::Replacements Result;
2433 removeParens(AnnotatedLines, Result);
2434 return {Result, 0};
2435 }
2436
2437private:
2438 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2439 tooling::Replacements &Result) {
2440 const auto &SourceMgr = Env.getSourceManager();
2441 for (auto *Line : Lines) {
2442 if (!Line->Children.empty())
2443 removeParens(Line->Children, Result);
2444 if (!Line->Affected)
2445 continue;
2446 for (const auto *Token = Line->First; Token && !Token->Finalized;
2447 Token = Token->Next) {
2448 if (Token->Optional && Token->isOneOf(tok::l_paren, tok::r_paren))
2449 replaceToken(*Token, Token->Next, SourceMgr, Result, " ");
2450 }
2451 }
2452 }
2453};
2454
2455class BracesInserter : public TokenAnalyzer {
2456public:
2457 BracesInserter(const Environment &Env, const FormatStyle &Style)
2458 : TokenAnalyzer(Env, Style) {}
2459
2460 std::pair<tooling::Replacements, unsigned>
2461 analyze(TokenAnnotator &Annotator,
2462 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2463 FormatTokenLexer &Tokens) override {
2464 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2465 tooling::Replacements Result;
2466 insertBraces(AnnotatedLines, Result);
2467 return {Result, 0};
2468 }
2469
2470private:
2471 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2472 tooling::Replacements &Result) {
2473 const auto &SourceMgr = Env.getSourceManager();
2474 int OpeningBraceSurplus = 0;
2475 for (AnnotatedLine *Line : Lines) {
2476 if (!Line->Children.empty())
2477 insertBraces(Line->Children, Result);
2478 if (!Line->Affected && OpeningBraceSurplus == 0)
2479 continue;
2480 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2481 Token = Token->Next) {
2482 int BraceCount = Token->BraceCount;
2483 if (BraceCount == 0)
2484 continue;
2485 std::string Brace;
2486 if (BraceCount < 0) {
2487 assert(BraceCount == -1);
2488 if (!Line->Affected)
2489 break;
2490 Brace = Token->is(tok::comment) ? "\n{" : "{";
2491 ++OpeningBraceSurplus;
2492 } else {
2493 if (OpeningBraceSurplus == 0)
2494 break;
2495 if (OpeningBraceSurplus < BraceCount)
2496 BraceCount = OpeningBraceSurplus;
2497 Brace = '\n' + std::string(BraceCount, '}');
2498 OpeningBraceSurplus -= BraceCount;
2499 }
2500 Token->BraceCount = 0;
2501 const auto Start = Token->Tok.getEndLoc();
2502 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
2503 }
2504 }
2505 assert(OpeningBraceSurplus == 0);
2506 }
2507};
2508
2509class BracesRemover : public TokenAnalyzer {
2510public:
2511 BracesRemover(const Environment &Env, const FormatStyle &Style)
2512 : TokenAnalyzer(Env, Style) {}
2513
2514 std::pair<tooling::Replacements, unsigned>
2515 analyze(TokenAnnotator &Annotator,
2516 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2517 FormatTokenLexer &Tokens) override {
2518 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2519 tooling::Replacements Result;
2520 removeBraces(AnnotatedLines, Result);
2521 return {Result, 0};
2522 }
2523
2524private:
2525 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2526 tooling::Replacements &Result) {
2527 const auto &SourceMgr = Env.getSourceManager();
2528 const auto *End = Lines.end();
2529 for (const auto *I = Lines.begin(); I != End; ++I) {
2530 const auto &Line = *I;
2531 if (!Line->Children.empty())
2532 removeBraces(Line->Children, Result);
2533 if (!Line->Affected)
2534 continue;
2535 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2536 for (const auto *Token = Line->First; Token && !Token->Finalized;
2537 Token = Token->Next) {
2538 if (!Token->Optional || Token->isNoneOf(tok::l_brace, tok::r_brace))
2539 continue;
2540 auto *Next = Token->Next;
2541 assert(Next || Token == Line->Last);
2542 if (!Next && NextLine)
2543 Next = NextLine->First;
2544 replaceToken(*Token, Next, SourceMgr, Result);
2545 }
2546 }
2547 }
2548};
2549
2550class SemiRemover : public TokenAnalyzer {
2551public:
2552 SemiRemover(const Environment &Env, const FormatStyle &Style)
2553 : TokenAnalyzer(Env, Style) {}
2554
2555 std::pair<tooling::Replacements, unsigned>
2556 analyze(TokenAnnotator &Annotator,
2557 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2558 FormatTokenLexer &Tokens) override {
2559 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2560 tooling::Replacements Result;
2561 removeSemi(Annotator, AnnotatedLines, Result);
2562 return {Result, 0};
2563 }
2564
2565private:
2566 void removeSemi(TokenAnnotator &Annotator,
2567 SmallVectorImpl<AnnotatedLine *> &Lines,
2568 tooling::Replacements &Result) {
2569 auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {
2570 const auto *Prev = Tok.Previous;
2571 if (!Prev || Prev->isNot(tok::r_brace))
2572 return false;
2573 const auto *LBrace = Prev->MatchingParen;
2574 return LBrace && LBrace->is(TT_FunctionLBrace);
2575 };
2576 const auto &SourceMgr = Env.getSourceManager();
2577 const auto *End = Lines.end();
2578 for (const auto *I = Lines.begin(); I != End; ++I) {
2579 const auto &Line = *I;
2580 if (!Line->Children.empty())
2581 removeSemi(Annotator, Line->Children, Result);
2582 if (!Line->Affected)
2583 continue;
2584 Annotator.calculateFormattingInformation(*Line);
2585 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2586 for (const auto *Token = Line->First; Token && !Token->Finalized;
2587 Token = Token->Next) {
2588 if (Token->isNot(tok::semi) ||
2589 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2590 continue;
2591 }
2592 auto *Next = Token->Next;
2593 assert(Next || Token == Line->Last);
2594 if (!Next && NextLine)
2595 Next = NextLine->First;
2596 replaceToken(*Token, Next, SourceMgr, Result);
2597 }
2598 }
2599 }
2600};
2601
2602class EnumTrailingCommaEditor : public TokenAnalyzer {
2603public:
2604 EnumTrailingCommaEditor(const Environment &Env, const FormatStyle &Style)
2605 : TokenAnalyzer(Env, Style) {}
2606
2607 std::pair<tooling::Replacements, unsigned>
2608 analyze(TokenAnnotator &Annotator,
2609 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2610 FormatTokenLexer &Tokens) override {
2611 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2612 tooling::Replacements Result;
2613 editEnumTrailingComma(AnnotatedLines, Result);
2614 return {Result, 0};
2615 }
2616
2617private:
2618 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2619 tooling::Replacements &Result) {
2620 bool InEnumBraces = false;
2621 const FormatToken *BeforeRBrace = nullptr;
2622 const auto &SourceMgr = Env.getSourceManager();
2623 for (auto *Line : Lines) {
2624 if (!Line->Children.empty())
2625 editEnumTrailingComma(Line->Children, Result);
2626 for (const auto *Token = Line->First; Token && !Token->Finalized;
2627 Token = Token->Next) {
2628 if (Token->isNot(TT_EnumRBrace)) {
2629 if (Token->is(TT_EnumLBrace))
2630 InEnumBraces = true;
2631 else if (InEnumBraces && Token->isNot(tok::comment))
2632 BeforeRBrace = Line->Affected ? Token : nullptr;
2633 continue;
2634 }
2635 InEnumBraces = false;
2636 if (!BeforeRBrace) // Empty braces or Line not affected.
2637 continue;
2638 if (BeforeRBrace->is(tok::comma)) {
2639 if (Style.EnumTrailingComma == FormatStyle::ETC_Remove)
2640 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr, Result);
2641 } else if (Style.EnumTrailingComma == FormatStyle::ETC_Insert) {
2642 cantFail(Result.add(tooling::Replacement(
2643 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0, ",")));
2644 }
2645 BeforeRBrace = nullptr;
2646 }
2647 }
2648 }
2649};
2650
2651class JavaScriptRequoter : public TokenAnalyzer {
2652public:
2653 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
2654 : TokenAnalyzer(Env, Style) {}
2655
2656 std::pair<tooling::Replacements, unsigned>
2657 analyze(TokenAnnotator &Annotator,
2658 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2659 FormatTokenLexer &Tokens) override {
2660 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2661 tooling::Replacements Result;
2662 requoteJSStringLiteral(AnnotatedLines, Result);
2663 return {Result, 0};
2664 }
2665
2666private:
2667 // Replaces double/single-quoted string literal as appropriate, re-escaping
2668 // the contents in the process.
2669 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2670 tooling::Replacements &Result) {
2671 for (AnnotatedLine *Line : Lines) {
2672 requoteJSStringLiteral(Line->Children, Result);
2673 if (!Line->Affected)
2674 continue;
2675 for (FormatToken *FormatTok = Line->First; FormatTok;
2676 FormatTok = FormatTok->Next) {
2677 StringRef Input = FormatTok->TokenText;
2678 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2679 // NB: testing for not starting with a double quote to avoid
2680 // breaking `template strings`.
2681 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
2682 !Input.starts_with("\"")) ||
2683 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
2684 !Input.starts_with("\'"))) {
2685 continue;
2686 }
2687
2688 // Change start and end quote.
2689 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
2690 SourceLocation Start = FormatTok->Tok.getLocation();
2691 auto Replace = [&](SourceLocation Start, unsigned Length,
2692 StringRef ReplacementText) {
2693 auto Err = Result.add(tooling::Replacement(
2694 Env.getSourceManager(), Start, Length, ReplacementText));
2695 // FIXME: handle error. For now, print error message and skip the
2696 // replacement for release version.
2697 if (Err) {
2698 llvm::errs() << toString(std::move(Err)) << "\n";
2699 assert(false);
2700 }
2701 };
2702 Replace(Start, 1, IsSingle ? "'" : "\"");
2703 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2704 IsSingle ? "'" : "\"");
2705
2706 // Escape internal quotes.
2707 bool Escaped = false;
2708 for (size_t i = 1; i < Input.size() - 1; i++) {
2709 switch (Input[i]) {
2710 case '\\':
2711 if (!Escaped && i + 1 < Input.size() &&
2712 ((IsSingle && Input[i + 1] == '"') ||
2713 (!IsSingle && Input[i + 1] == '\''))) {
2714 // Remove this \, it's escaping a " or ' that no longer needs
2715 // escaping
2716 Replace(Start.getLocWithOffset(i), 1, "");
2717 continue;
2718 }
2719 Escaped = !Escaped;
2720 break;
2721 case '\"':
2722 case '\'':
2723 if (!Escaped && IsSingle == (Input[i] == '\'')) {
2724 // Escape the quote.
2725 Replace(Start.getLocWithOffset(i), 0, "\\");
2726 }
2727 Escaped = false;
2728 break;
2729 default:
2730 Escaped = false;
2731 break;
2732 }
2733 }
2734 }
2735 }
2736 }
2737};
2738
2739class Formatter : public TokenAnalyzer {
2740public:
2741 Formatter(const Environment &Env, const FormatStyle &Style,
2742 FormattingAttemptStatus *Status)
2743 : TokenAnalyzer(Env, Style), Status(Status) {}
2744
2745 std::pair<tooling::Replacements, unsigned>
2746 analyze(TokenAnnotator &Annotator,
2747 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2748 FormatTokenLexer &Tokens) override {
2749 tooling::Replacements Result;
2750 deriveLocalStyle(AnnotatedLines);
2751 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2752 for (AnnotatedLine *Line : AnnotatedLines)
2753 Annotator.calculateFormattingInformation(*Line);
2754 Annotator.setCommentLineLevels(AnnotatedLines);
2755
2756 WhitespaceManager Whitespaces(
2757 Env.getSourceManager(), Style,
2758 Style.LineEnding > FormatStyle::LE_CRLF
2760 Env.getSourceManager().getBufferData(Env.getFileID()),
2761 Style.LineEnding == FormatStyle::LE_DeriveCRLF)
2762 : Style.LineEnding == FormatStyle::LE_CRLF);
2763 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
2764 Env.getSourceManager(), Whitespaces, Encoding,
2765 BinPackInconclusiveFunctions);
2766 unsigned Penalty =
2767 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
2768 Tokens.getKeywords(), Env.getSourceManager(),
2769 Status)
2770 .format(AnnotatedLines, /*DryRun=*/false,
2771 /*AdditionalIndent=*/0,
2772 /*FixBadIndentation=*/false,
2773 /*FirstStartColumn=*/Env.getFirstStartColumn(),
2774 /*NextStartColumn=*/Env.getNextStartColumn(),
2775 /*LastStartColumn=*/Env.getLastStartColumn());
2776 for (const auto &R : Whitespaces.generateReplacements())
2777 if (Result.add(R))
2778 return std::make_pair(Result, 0);
2779 return std::make_pair(Result, Penalty);
2780 }
2781
2782private:
2783 bool
2784 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2785 for (const AnnotatedLine *Line : Lines) {
2786 if (hasCpp03IncompatibleFormat(Line->Children))
2787 return true;
2788 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2789 if (!Tok->hasWhitespaceBefore()) {
2790 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2791 return true;
2792 if (Tok->is(TT_TemplateCloser) &&
2793 Tok->Previous->is(TT_TemplateCloser)) {
2794 return true;
2795 }
2796 }
2797 }
2798 }
2799 return false;
2800 }
2801
2802 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2803 int AlignmentDiff = 0;
2804
2805 for (const AnnotatedLine *Line : Lines) {
2806 AlignmentDiff += countVariableAlignments(Line->Children);
2807
2808 for (const auto *Tok = Line->getFirstNonComment(); Tok; Tok = Tok->Next) {
2809 if (Tok->isNot(TT_PointerOrReference))
2810 continue;
2811
2812 const auto *Prev = Tok->Previous;
2813 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
2814 const bool SpaceBefore = Tok->hasWhitespaceBefore();
2815
2816 // e.g. `int **`, `int*&`, etc.
2817 while (Tok->Next && Tok->Next->is(TT_PointerOrReference))
2818 Tok = Tok->Next;
2819
2820 const auto *Next = Tok->Next;
2821 const bool FollowedByName = Next && Next->Tok.getIdentifierInfo();
2822 const bool SpaceAfter = Next && Next->hasWhitespaceBefore();
2823
2824 if ((!PrecededByName && !FollowedByName) ||
2825 // e.g. `int * i` or `int*i`
2826 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
2827 continue;
2828 }
2829
2830 if ((PrecededByName && SpaceBefore) ||
2831 (FollowedByName && !SpaceAfter)) {
2832 // Right alignment.
2833 ++AlignmentDiff;
2834 } else if ((PrecededByName && !SpaceBefore) ||
2835 (FollowedByName && SpaceAfter)) {
2836 // Left alignment.
2837 --AlignmentDiff;
2838 }
2839 }
2840 }
2841
2842 return AlignmentDiff;
2843 }
2844
2845 void
2846 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2847 bool HasBinPackedFunction = false;
2848 bool HasOnePerLineFunction = false;
2849 for (AnnotatedLine *Line : AnnotatedLines) {
2850 if (!Line->First->Next)
2851 continue;
2852 FormatToken *Tok = Line->First->Next;
2853 while (Tok->Next) {
2854 if (Tok->is(PPK_BinPacked))
2855 HasBinPackedFunction = true;
2856 if (Tok->is(PPK_OnePerLine))
2857 HasOnePerLineFunction = true;
2858
2859 Tok = Tok->Next;
2860 }
2861 }
2862 if (Style.DerivePointerAlignment) {
2863 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2864 if (NetRightCount > 0)
2865 Style.PointerAlignment = FormatStyle::PAS_Right;
2866 else if (NetRightCount < 0)
2867 Style.PointerAlignment = FormatStyle::PAS_Left;
2868 Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
2869 }
2870 if (Style.Standard == FormatStyle::LS_Auto) {
2871 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2872 ? FormatStyle::LS_Latest
2873 : FormatStyle::LS_Cpp03;
2874 }
2875 BinPackInconclusiveFunctions =
2876 HasBinPackedFunction || !HasOnePerLineFunction;
2877 }
2878
2879 bool BinPackInconclusiveFunctions;
2880 FormattingAttemptStatus *Status;
2881};
2882
2883/// TrailingCommaInserter inserts trailing commas into container literals.
2884/// E.g.:
2885/// const x = [
2886/// 1,
2887/// ];
2888/// TrailingCommaInserter runs after formatting. To avoid causing a required
2889/// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2890/// ColumnLimit.
2891///
2892/// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2893/// is conceptually incompatible with bin packing.
2894class TrailingCommaInserter : public TokenAnalyzer {
2895public:
2896 TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2897 : TokenAnalyzer(Env, Style) {}
2898
2899 std::pair<tooling::Replacements, unsigned>
2900 analyze(TokenAnnotator &Annotator,
2901 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2902 FormatTokenLexer &Tokens) override {
2903 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2904 tooling::Replacements Result;
2905 insertTrailingCommas(AnnotatedLines, Result);
2906 return {Result, 0};
2907 }
2908
2909private:
2910 /// Inserts trailing commas in [] and {} initializers if they wrap over
2911 /// multiple lines.
2912 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2913 tooling::Replacements &Result) {
2914 for (AnnotatedLine *Line : Lines) {
2915 insertTrailingCommas(Line->Children, Result);
2916 if (!Line->Affected)
2917 continue;
2918 for (FormatToken *FormatTok = Line->First; FormatTok;
2919 FormatTok = FormatTok->Next) {
2920 if (FormatTok->NewlinesBefore == 0)
2921 continue;
2922 FormatToken *Matching = FormatTok->MatchingParen;
2923 if (!Matching || !FormatTok->getPreviousNonComment())
2924 continue;
2925 if (!(FormatTok->is(tok::r_square) &&
2926 Matching->is(TT_ArrayInitializerLSquare)) &&
2927 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2928 continue;
2929 }
2930 FormatToken *Prev = FormatTok->getPreviousNonComment();
2931 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2932 continue;
2933 // getEndLoc is not reliably set during re-lexing, use text length
2934 // instead.
2935 SourceLocation Start =
2936 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2937 // If inserting a comma would push the code over the column limit, skip
2938 // this location - it'd introduce an unstable formatting due to the
2939 // required reflow.
2940 unsigned ColumnNumber =
2941 Env.getSourceManager().getSpellingColumnNumber(Start);
2942 if (ColumnNumber > Style.ColumnLimit)
2943 continue;
2944 // Comma insertions cannot conflict with each other, and this pass has a
2945 // clean set of Replacements, so the operation below cannot fail.
2946 cantFail(Result.add(
2947 tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2948 }
2949 }
2950 }
2951};
2952
2953// This class clean up the erroneous/redundant code around the given ranges in
2954// file.
2955class Cleaner : public TokenAnalyzer {
2956public:
2957 Cleaner(const Environment &Env, const FormatStyle &Style)
2958 : TokenAnalyzer(Env, Style),
2959 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2960
2961 // FIXME: eliminate unused parameters.
2962 std::pair<tooling::Replacements, unsigned>
2963 analyze(TokenAnnotator &Annotator,
2964 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2965 FormatTokenLexer &Tokens) override {
2966 // FIXME: in the current implementation the granularity of affected range
2967 // is an annotated line. However, this is not sufficient. Furthermore,
2968 // redundant code introduced by replacements does not necessarily
2969 // intercept with ranges of replacements that result in the redundancy.
2970 // To determine if some redundant code is actually introduced by
2971 // replacements(e.g. deletions), we need to come up with a more
2972 // sophisticated way of computing affected ranges.
2973 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2974
2975 checkEmptyNamespace(AnnotatedLines);
2976
2977 for (auto *Line : AnnotatedLines)
2978 cleanupLine(Line);
2979
2980 return {generateFixes(), 0};
2981 }
2982
2983private:
2984 void cleanupLine(AnnotatedLine *Line) {
2985 for (auto *Child : Line->Children)
2986 cleanupLine(Child);
2987
2988 if (Line->Affected) {
2989 cleanupRight(Line->First, tok::comma, tok::comma);
2990 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2991 cleanupRight(Line->First, tok::l_paren, tok::comma);
2992 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2993 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2994 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2995 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2996 }
2997 }
2998
2999 bool containsOnlyComments(const AnnotatedLine &Line) {
3000 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
3001 if (Tok->isNot(tok::comment))
3002 return false;
3003 return true;
3004 }
3005
3006 // Iterate through all lines and remove any empty (nested) namespaces.
3007 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3008 std::set<unsigned> DeletedLines;
3009 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
3010 auto &Line = *AnnotatedLines[i];
3011 if (Line.startsWithNamespace())
3012 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
3013 }
3014
3015 for (auto Line : DeletedLines) {
3016 FormatToken *Tok = AnnotatedLines[Line]->First;
3017 while (Tok) {
3018 deleteToken(Tok);
3019 Tok = Tok->Next;
3020 }
3021 }
3022 }
3023
3024 // The function checks if the namespace, which starts from \p CurrentLine, and
3025 // its nested namespaces are empty and delete them if they are empty. It also
3026 // sets \p NewLine to the last line checked.
3027 // Returns true if the current namespace is empty.
3028 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3029 unsigned CurrentLine, unsigned &NewLine,
3030 std::set<unsigned> &DeletedLines) {
3031 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
3032 if (Style.BraceWrapping.AfterNamespace) {
3033 // If the left brace is in a new line, we should consume it first so that
3034 // it does not make the namespace non-empty.
3035 // FIXME: error handling if there is no left brace.
3036 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
3037 NewLine = CurrentLine;
3038 return false;
3039 }
3040 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
3041 return false;
3042 }
3043 while (++CurrentLine < End) {
3044 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
3045 break;
3046
3047 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
3048 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
3049 DeletedLines)) {
3050 return false;
3051 }
3052 CurrentLine = NewLine;
3053 continue;
3054 }
3055
3056 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
3057 continue;
3058
3059 // If there is anything other than comments or nested namespaces in the
3060 // current namespace, the namespace cannot be empty.
3061 NewLine = CurrentLine;
3062 return false;
3063 }
3064
3065 NewLine = CurrentLine;
3066 if (CurrentLine >= End)
3067 return false;
3068
3069 // Check if the empty namespace is actually affected by changed ranges.
3070 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
3071 AnnotatedLines[InitLine]->First->Tok.getLocation(),
3072 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
3073 return false;
3074 }
3075
3076 for (unsigned i = InitLine; i <= CurrentLine; ++i)
3077 DeletedLines.insert(i);
3078
3079 return true;
3080 }
3081
3082 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
3083 // of the token in the pair if the left token has \p LK token kind and the
3084 // right token has \p RK token kind. If \p DeleteLeft is true, the left token
3085 // is deleted on match; otherwise, the right token is deleted.
3086 template <typename LeftKind, typename RightKind>
3087 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
3088 bool DeleteLeft) {
3089 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
3090 for (auto *Res = Tok.Next; Res; Res = Res->Next) {
3091 if (Res->isNot(tok::comment) &&
3092 DeletedTokens.find(Res) == DeletedTokens.end()) {
3093 return Res;
3094 }
3095 }
3096 return nullptr;
3097 };
3098 for (auto *Left = Start; Left;) {
3099 auto *Right = NextNotDeleted(*Left);
3100 if (!Right)
3101 break;
3102 if (Left->is(LK) && Right->is(RK)) {
3103 deleteToken(DeleteLeft ? Left : Right);
3104 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
3105 deleteToken(Tok);
3106 // If the right token is deleted, we should keep the left token
3107 // unchanged and pair it with the new right token.
3108 if (!DeleteLeft)
3109 continue;
3110 }
3111 Left = Right;
3112 }
3113 }
3114
3115 template <typename LeftKind, typename RightKind>
3116 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
3117 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
3118 }
3119
3120 template <typename LeftKind, typename RightKind>
3121 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
3122 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
3123 }
3124
3125 // Delete the given token.
3126 inline void deleteToken(FormatToken *Tok) {
3127 if (Tok)
3128 DeletedTokens.insert(Tok);
3129 }
3130
3131 tooling::Replacements generateFixes() {
3132 tooling::Replacements Fixes;
3133 SmallVector<FormatToken *> Tokens;
3134 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
3135 std::back_inserter(Tokens));
3136
3137 // Merge multiple continuous token deletions into one big deletion so that
3138 // the number of replacements can be reduced. This makes computing affected
3139 // ranges more efficient when we run reformat on the changed code.
3140 unsigned Idx = 0;
3141 while (Idx < Tokens.size()) {
3142 unsigned St = Idx, End = Idx;
3143 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3144 ++End;
3145 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
3146 Tokens[End]->Tok.getEndLoc());
3147 auto Err =
3148 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
3149 // FIXME: better error handling. for now just print error message and skip
3150 // for the release version.
3151 if (Err) {
3152 llvm::errs() << toString(std::move(Err)) << "\n";
3153 assert(false && "Fixes must not conflict!");
3154 }
3155 Idx = End + 1;
3156 }
3157
3158 return Fixes;
3159 }
3160
3161 // Class for less-than inequality comparason for the set `RedundantTokens`.
3162 // We store tokens in the order they appear in the translation unit so that
3163 // we do not need to sort them in `generateFixes()`.
3164 struct FormatTokenLess {
3165 FormatTokenLess(const SourceManager &SM) : SM(SM) {}
3166
3167 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
3168 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3169 RHS->Tok.getLocation());
3170 }
3171 const SourceManager &SM;
3172 };
3173
3174 // Tokens to be deleted.
3175 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3176};
3177
3178class ObjCHeaderStyleGuesser : public TokenAnalyzer {
3179public:
3180 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
3181 : TokenAnalyzer(Env, Style), IsObjC(false) {}
3182
3183 std::pair<tooling::Replacements, unsigned>
3184 analyze(TokenAnnotator &Annotator,
3185 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3186 FormatTokenLexer &Tokens) override {
3187 assert(Style.Language == FormatStyle::LK_Cpp);
3188 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
3189 Tokens.getKeywords());
3190 tooling::Replacements Result;
3191 return {Result, 0};
3192 }
3193
3194 bool isObjC() { return IsObjC; }
3195
3196private:
3197 static bool
3198 guessIsObjC(const SourceManager &SourceManager,
3199 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3200 const AdditionalKeywords &Keywords) {
3201 // Keep this array sorted, since we are binary searching over it.
3202 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3203 "CGFloat",
3204 "CGPoint",
3205 "CGPointMake",
3206 "CGPointZero",
3207 "CGRect",
3208 "CGRectEdge",
3209 "CGRectInfinite",
3210 "CGRectMake",
3211 "CGRectNull",
3212 "CGRectZero",
3213 "CGSize",
3214 "CGSizeMake",
3215 "CGVector",
3216 "CGVectorMake",
3217 "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
3218 "FOUNDATION_EXTERN",
3219 "NSAffineTransform",
3220 "NSArray",
3221 "NSAttributedString",
3222 "NSBlockOperation",
3223 "NSBundle",
3224 "NSCache",
3225 "NSCalendar",
3226 "NSCharacterSet",
3227 "NSCountedSet",
3228 "NSData",
3229 "NSDataDetector",
3230 "NSDecimal",
3231 "NSDecimalNumber",
3232 "NSDictionary",
3233 "NSEdgeInsets",
3234 "NSError",
3235 "NSErrorDomain",
3236 "NSHashTable",
3237 "NSIndexPath",
3238 "NSIndexSet",
3239 "NSInteger",
3240 "NSInvocationOperation",
3241 "NSLocale",
3242 "NSMapTable",
3243 "NSMutableArray",
3244 "NSMutableAttributedString",
3245 "NSMutableCharacterSet",
3246 "NSMutableData",
3247 "NSMutableDictionary",
3248 "NSMutableIndexSet",
3249 "NSMutableOrderedSet",
3250 "NSMutableSet",
3251 "NSMutableString",
3252 "NSNumber",
3253 "NSNumberFormatter",
3254 "NSObject",
3255 "NSOperation",
3256 "NSOperationQueue",
3257 "NSOperationQueuePriority",
3258 "NSOrderedSet",
3259 "NSPoint",
3260 "NSPointerArray",
3261 "NSQualityOfService",
3262 "NSRange",
3263 "NSRect",
3264 "NSRegularExpression",
3265 "NSSet",
3266 "NSSize",
3267 "NSString",
3268 "NSTimeZone",
3269 "NSUInteger",
3270 "NSURL",
3271 "NSURLComponents",
3272 "NSURLQueryItem",
3273 "NSUUID",
3274 "NSValue",
3275 "NS_ASSUME_NONNULL_BEGIN",
3276 "UIImage",
3277 "UIView",
3278 };
3279 assert(llvm::is_sorted(FoundationIdentifiers));
3280
3281 for (auto *Line : AnnotatedLines) {
3282 if (Line->First && (Line->First->TokenText.starts_with("#") ||
3283 Line->First->TokenText == "__pragma" ||
3284 Line->First->TokenText == "_Pragma")) {
3285 continue;
3286 }
3287 for (const FormatToken *FormatTok = Line->First; FormatTok;
3288 FormatTok = FormatTok->Next) {
3289 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3290 (FormatTok->isNot(tok::objc_not_keyword) ||
3291 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3292 tok::l_brace))) ||
3293 (FormatTok->Tok.isAnyIdentifier() &&
3294 llvm::binary_search(FoundationIdentifiers,
3295 FormatTok->TokenText)) ||
3296 FormatTok->is(TT_ObjCStringLiteral) ||
3297 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3298 Keywords.kw_NS_ERROR_ENUM,
3299 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3300 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3301 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3302 TT_ObjCProperty, TT_ObjCSelector)) {
3303 LLVM_DEBUG(llvm::dbgs()
3304 << "Detected ObjC at location "
3305 << FormatTok->Tok.getLocation().printToString(
3306 SourceManager)
3307 << " token: " << FormatTok->TokenText << " token type: "
3308 << getTokenTypeName(FormatTok->getType()) << "\n");
3309 return true;
3310 }
3311 }
3312 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3313 return true;
3314 }
3315 return false;
3316 }
3317
3318 bool IsObjC;
3319};
3320
3321struct IncludeDirective {
3322 StringRef Filename;
3323 StringRef Text;
3324 unsigned Offset;
3325 int Category;
3326 int Priority;
3327};
3328
3329struct JavaImportDirective {
3330 StringRef Identifier;
3331 StringRef Text;
3332 unsigned Offset;
3333 SmallVector<StringRef> AssociatedCommentLines;
3334 bool IsStatic;
3335};
3336
3337} // end anonymous namespace
3338
3339// Determines whether 'Ranges' intersects with ('Start', 'End').
3340static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
3341 unsigned End) {
3342 for (const auto &Range : Ranges) {
3343 if (Range.getOffset() < End &&
3344 Range.getOffset() + Range.getLength() > Start) {
3345 return true;
3346 }
3347 }
3348 return false;
3349}
3350
3351// Returns a pair (Index, OffsetToEOL) describing the position of the cursor
3352// before sorting/deduplicating. Index is the index of the include under the
3353// cursor in the original set of includes. If this include has duplicates, it is
3354// the index of the first of the duplicates as the others are going to be
3355// removed. OffsetToEOL describes the cursor's position relative to the end of
3356// its current line.
3357// If `Cursor` is not on any #include, `Index` will be
3358// std::numeric_limits<unsigned>::max().
3359static std::pair<unsigned, unsigned>
3361 const ArrayRef<unsigned> &Indices, unsigned Cursor) {
3362 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3363 unsigned OffsetToEOL = 0;
3364 for (int i = 0, e = Includes.size(); i != e; ++i) {
3365 unsigned Start = Includes[Indices[i]].Offset;
3366 unsigned End = Start + Includes[Indices[i]].Text.size();
3367 if (!(Cursor >= Start && Cursor < End))
3368 continue;
3369 CursorIndex = Indices[i];
3370 OffsetToEOL = End - Cursor;
3371 // Put the cursor on the only remaining #include among the duplicate
3372 // #includes.
3373 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
3374 CursorIndex = i;
3375 break;
3376 }
3377 return std::make_pair(CursorIndex, OffsetToEOL);
3378}
3379
3380// Replace all "\r\n" with "\n".
3381std::string replaceCRLF(const std::string &Code) {
3382 std::string NewCode;
3383 size_t Pos = 0, LastPos = 0;
3384
3385 do {
3386 Pos = Code.find("\r\n", LastPos);
3387 if (Pos == LastPos) {
3388 ++LastPos;
3389 continue;
3390 }
3391 if (Pos == std::string::npos) {
3392 NewCode += Code.substr(LastPos);
3393 break;
3394 }
3395 NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
3396 LastPos = Pos + 2;
3397 } while (Pos != std::string::npos);
3398
3399 return NewCode;
3400}
3401
3402// Sorts and deduplicate a block of includes given by 'Includes' alphabetically
3403// adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
3404// source order.
3405// #include directives with the same text will be deduplicated, and only the
3406// first #include in the duplicate #includes remains. If the `Cursor` is
3407// provided and put on a deleted #include, it will be moved to the remaining
3408// #include in the duplicate #includes.
3409static void sortCppIncludes(const FormatStyle &Style,
3410 const ArrayRef<IncludeDirective> &Includes,
3411 ArrayRef<tooling::Range> Ranges, StringRef FileName,
3412 StringRef Code, tooling::Replacements &Replaces,
3413 unsigned *Cursor) {
3414 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
3415 const unsigned IncludesBeginOffset = Includes.front().Offset;
3416 const unsigned IncludesEndOffset =
3417 Includes.back().Offset + Includes.back().Text.size();
3418 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3419 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3420 return;
3422 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3423
3424 if (Style.SortIncludes.Enabled) {
3425 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3426 SmallString<128> LHSStem, RHSStem;
3427 if (Style.SortIncludes.IgnoreExtension) {
3428 LHSStem = Includes[LHSI].Filename;
3429 RHSStem = Includes[RHSI].Filename;
3430 llvm::sys::path::replace_extension(LHSStem, "");
3431 llvm::sys::path::replace_extension(RHSStem, "");
3432 }
3433 std::string LHSStemLower, RHSStemLower;
3434 std::string LHSFilenameLower, RHSFilenameLower;
3435 if (Style.SortIncludes.IgnoreCase) {
3436 LHSStemLower = LHSStem.str().lower();
3437 RHSStemLower = RHSStem.str().lower();
3438 LHSFilenameLower = Includes[LHSI].Filename.lower();
3439 RHSFilenameLower = Includes[RHSI].Filename.lower();
3440 }
3441 return std::tie(Includes[LHSI].Priority, LHSStemLower, LHSStem,
3442 LHSFilenameLower, Includes[LHSI].Filename) <
3443 std::tie(Includes[RHSI].Priority, RHSStemLower, RHSStem,
3444 RHSFilenameLower, Includes[RHSI].Filename);
3445 });
3446 }
3447
3448 // The index of the include on which the cursor will be put after
3449 // sorting/deduplicating.
3450 unsigned CursorIndex;
3451 // The offset from cursor to the end of line.
3452 unsigned CursorToEOLOffset;
3453 if (Cursor) {
3454 std::tie(CursorIndex, CursorToEOLOffset) =
3455 FindCursorIndex(Includes, Indices, *Cursor);
3456 }
3457
3458 // Deduplicate #includes.
3459 Indices.erase(llvm::unique(Indices,
3460 [&](unsigned LHSI, unsigned RHSI) {
3461 return Includes[LHSI].Text.trim() ==
3462 Includes[RHSI].Text.trim();
3463 }),
3464 Indices.end());
3465
3466 int CurrentCategory = Includes.front().Category;
3467
3468 // If the #includes are out of order, we generate a single replacement fixing
3469 // the entire block. Otherwise, no replacement is generated.
3470 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
3471 // enough as additional newlines might be added or removed across #include
3472 // blocks. This we handle below by generating the updated #include blocks and
3473 // comparing it to the original.
3474 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3475 Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) {
3476 return;
3477 }
3478
3479 const auto OldCursor = Cursor ? *Cursor : 0;
3480 std::string result;
3481 for (unsigned Index : Indices) {
3482 if (!result.empty()) {
3483 result += "\n";
3484 if (Style.IncludeStyle.IncludeBlocks ==
3486 CurrentCategory != Includes[Index].Category) {
3487 result += "\n";
3488 }
3489 }
3490 result += Includes[Index].Text;
3491 if (Cursor && CursorIndex == Index)
3492 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3493 CurrentCategory = Includes[Index].Category;
3494 }
3495
3496 if (Cursor && *Cursor >= IncludesEndOffset)
3497 *Cursor += result.size() - IncludesBlockSize;
3498
3499 // If the #includes are out of order, we generate a single replacement fixing
3500 // the entire range of blocks. Otherwise, no replacement is generated.
3501 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3502 IncludesBeginOffset, IncludesBlockSize)))) {
3503 if (Cursor)
3504 *Cursor = OldCursor;
3505 return;
3506 }
3507
3508 auto Err = Replaces.add(tooling::Replacement(
3509 FileName, Includes.front().Offset, IncludesBlockSize, result));
3510 // FIXME: better error handling. For now, just skip the replacement for the
3511 // release version.
3512 if (Err) {
3513 llvm::errs() << toString(std::move(Err)) << "\n";
3514 assert(false);
3515 }
3516}
3517
3518tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
3520 StringRef FileName,
3521 tooling::Replacements &Replaces,
3522 unsigned *Cursor) {
3523 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3524 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
3525 .Default(0);
3526 unsigned SearchFrom = 0;
3528 SmallVector<IncludeDirective, 16> IncludesInBlock;
3529
3530 // In compiled files, consider the first #include to be the main #include of
3531 // the file if it is not a system #include. This ensures that the header
3532 // doesn't have hidden dependencies
3533 // (http://llvm.org/docs/CodingStandards.html#include-style).
3534 //
3535 // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3536 // cases where the first #include is unlikely to be the main header.
3537 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
3538 bool FirstIncludeBlock = true;
3539 bool MainIncludeFound = false;
3540 bool FormattingOff = false;
3541
3542 // '[' must be the first and '-' the last character inside [...].
3543 llvm::Regex RawStringRegex(
3544 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3545 SmallVector<StringRef, 2> RawStringMatches;
3546 std::string RawStringTermination = ")\"";
3547
3548 for (const auto Size = Code.size(); SearchFrom < Size;) {
3549 size_t Pos = SearchFrom;
3550 if (Code[SearchFrom] != '\n') {
3551 do { // Search for the first newline while skipping line splices.
3552 ++Pos;
3553 Pos = Code.find('\n', Pos);
3554 } while (Pos != StringRef::npos && Code[Pos - 1] == '\\');
3555 }
3556
3557 StringRef Line =
3558 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3559
3560 StringRef Trimmed = Line.trim();
3561
3562 // #includes inside raw string literals need to be ignored.
3563 // or we will sort the contents of the string.
3564 // Skip past until we think we are at the rawstring literal close.
3565 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3566 std::string CharSequence = RawStringMatches[1].str();
3567 RawStringTermination = ")" + CharSequence + "\"";
3568 FormattingOff = true;
3569 }
3570
3571 if (Trimmed.contains(RawStringTermination))
3572 FormattingOff = false;
3573
3574 bool IsBlockComment = false;
3575
3576 if (isClangFormatOff(Trimmed)) {
3577 FormattingOff = true;
3578 } else if (isClangFormatOn(Trimmed)) {
3579 FormattingOff = false;
3580 } else if (Trimmed.starts_with("/*")) {
3581 IsBlockComment = true;
3582 Pos = Code.find("*/", SearchFrom + 2);
3583 }
3584
3585 const bool EmptyLineSkipped =
3586 Trimmed.empty() &&
3587 (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
3588 Style.IncludeStyle.IncludeBlocks ==
3590
3591 bool MergeWithNextLine = Trimmed.ends_with("\\");
3592 if (!FormattingOff && !MergeWithNextLine) {
3593 if (!IsBlockComment &&
3594 tooling::HeaderIncludes::IncludeRegex.match(Trimmed, &Matches)) {
3595 StringRef IncludeName = Matches[2];
3596 if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {
3597 // #include with a start of a block comment, but without the end.
3598 // Need to keep all the lines until the end of the comment together.
3599 // FIXME: This is somehow simplified check that probably does not work
3600 // correctly if there are multiple comments on a line.
3601 Pos = Code.find("*/", SearchFrom);
3602 Line = Code.substr(
3603 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3604 }
3605 int Category = Categories.getIncludePriority(
3606 IncludeName,
3607 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
3608 int Priority = Categories.getSortIncludePriority(
3609 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3610 if (Category == 0)
3611 MainIncludeFound = true;
3612 IncludesInBlock.push_back(
3613 {IncludeName, Line, Prev, Category, Priority});
3614 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3615 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
3616 Replaces, Cursor);
3617 IncludesInBlock.clear();
3618 if (Trimmed.starts_with("#pragma hdrstop")) // Precompiled headers.
3619 FirstIncludeBlock = true;
3620 else
3621 FirstIncludeBlock = false;
3622 }
3623 }
3624 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3625 break;
3626
3627 if (!MergeWithNextLine)
3628 Prev = Pos + 1;
3629 SearchFrom = Pos + 1;
3630 }
3631 if (!IncludesInBlock.empty()) {
3632 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
3633 Cursor);
3634 }
3635 return Replaces;
3636}
3637
3638// Returns group number to use as a first order sort on imports. Gives
3639// std::numeric_limits<unsigned>::max() if the import does not match any given
3640// groups.
3641static unsigned findJavaImportGroup(const FormatStyle &Style,
3642 StringRef ImportIdentifier) {
3643 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3644 unsigned LongestMatchLength = 0;
3645 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3646 const std::string &GroupPrefix = Style.JavaImportGroups[I];
3647 if (ImportIdentifier.starts_with(GroupPrefix) &&
3648 GroupPrefix.length() > LongestMatchLength) {
3649 LongestMatchIndex = I;
3650 LongestMatchLength = GroupPrefix.length();
3651 }
3652 }
3653 return LongestMatchIndex;
3654}
3655
3656// Sorts and deduplicates a block of includes given by 'Imports' based on
3657// JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3658// Import declarations with the same text will be deduplicated. Between each
3659// import group, a newline is inserted, and within each import group, a
3660// lexicographic sort based on ASCII value is performed.
3661static void sortJavaImports(const FormatStyle &Style,
3662 const ArrayRef<JavaImportDirective> &Imports,
3663 ArrayRef<tooling::Range> Ranges, StringRef FileName,
3664 StringRef Code, tooling::Replacements &Replaces) {
3665 unsigned ImportsBeginOffset = Imports.front().Offset;
3666 unsigned ImportsEndOffset =
3667 Imports.back().Offset + Imports.back().Text.size();
3668 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3669 if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3670 return;
3671
3673 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3675 JavaImportGroups.reserve(Imports.size());
3676 for (const JavaImportDirective &Import : Imports)
3677 JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
3678
3679 bool StaticImportAfterNormalImport =
3680 Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
3681 sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3682 // Negating IsStatic to push static imports above non-static imports.
3683 return std::make_tuple(!Imports[LHSI].IsStatic ^
3684 StaticImportAfterNormalImport,
3685 JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
3686 std::make_tuple(!Imports[RHSI].IsStatic ^
3687 StaticImportAfterNormalImport,
3688 JavaImportGroups[RHSI], Imports[RHSI].Identifier);
3689 });
3690
3691 // Deduplicate imports.
3692 Indices.erase(llvm::unique(Indices,
3693 [&](unsigned LHSI, unsigned RHSI) {
3694 return Imports[LHSI].Text == Imports[RHSI].Text;
3695 }),
3696 Indices.end());
3697
3698 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3699 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
3700
3701 std::string result;
3702 for (unsigned Index : Indices) {
3703 if (!result.empty()) {
3704 result += "\n";
3705 if (CurrentIsStatic != Imports[Index].IsStatic ||
3706 CurrentImportGroup != JavaImportGroups[Index]) {
3707 result += "\n";
3708 }
3709 }
3710 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
3711 result += CommentLine;
3712 result += "\n";
3713 }
3714 result += Imports[Index].Text;
3715 CurrentIsStatic = Imports[Index].IsStatic;
3716 CurrentImportGroup = JavaImportGroups[Index];
3717 }
3718
3719 // If the imports are out of order, we generate a single replacement fixing
3720 // the entire block. Otherwise, no replacement is generated.
3721 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3722 Imports.front().Offset, ImportsBlockSize)))) {
3723 return;
3724 }
3725
3726 auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
3727 ImportsBlockSize, result));
3728 // FIXME: better error handling. For now, just skip the replacement for the
3729 // release version.
3730 if (Err) {
3731 llvm::errs() << toString(std::move(Err)) << "\n";
3732 assert(false);
3733 }
3734}
3735
3736namespace {
3737
3738const char JavaImportRegexPattern[] =
3739 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3740
3741} // anonymous namespace
3742
3743tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
3745 StringRef FileName,
3746 tooling::Replacements &Replaces) {
3747 unsigned Prev = 0;
3748 unsigned SearchFrom = 0;
3749 llvm::Regex ImportRegex(JavaImportRegexPattern);
3752 SmallVector<StringRef> AssociatedCommentLines;
3753
3754 bool FormattingOff = false;
3755
3756 for (;;) {
3757 auto Pos = Code.find('\n', SearchFrom);
3758 StringRef Line =
3759 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3760
3761 StringRef Trimmed = Line.trim();
3762 if (isClangFormatOff(Trimmed))
3763 FormattingOff = true;
3764 else if (isClangFormatOn(Trimmed))
3765 FormattingOff = false;
3766
3767 if (ImportRegex.match(Line, &Matches)) {
3768 if (FormattingOff) {
3769 // If at least one import line has formatting turned off, turn off
3770 // formatting entirely.
3771 return Replaces;
3772 }
3773 StringRef Static = Matches[1];
3774 StringRef Identifier = Matches[2];
3775 bool IsStatic = false;
3776 if (Static.contains("static"))
3777 IsStatic = true;
3778 ImportsInBlock.push_back(
3779 {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
3780 AssociatedCommentLines.clear();
3781 } else if (!Trimmed.empty() && !ImportsInBlock.empty()) {
3782 // Associating comments within the imports with the nearest import below
3783 AssociatedCommentLines.push_back(Line);
3784 }
3785 Prev = Pos + 1;
3786 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3787 break;
3788 SearchFrom = Pos + 1;
3789 }
3790 if (!ImportsInBlock.empty())
3791 sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
3792 return Replaces;
3793}
3794
3795bool isMpegTS(StringRef Code) {
3796 // MPEG transport streams use the ".ts" file extension. clang-format should
3797 // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3798 // 189 bytes - detect that and return.
3799 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3800}
3801
3802bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); }
3803
3804tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
3806 StringRef FileName, unsigned *Cursor) {
3807 tooling::Replacements Replaces;
3808 if (!Style.SortIncludes.Enabled || Style.DisableFormat)
3809 return Replaces;
3810 if (isLikelyXml(Code))
3811 return Replaces;
3812 if (Style.isJavaScript()) {
3813 if (isMpegTS(Code))
3814 return Replaces;
3815 return sortJavaScriptImports(Style, Code, Ranges, FileName);
3816 }
3817 if (Style.isJava())
3818 return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
3819 if (Style.isCpp())
3820 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
3821 return Replaces;
3822}
3823
3824template <typename T>
3826processReplacements(T ProcessFunc, StringRef Code,
3827 const tooling::Replacements &Replaces,
3828 const FormatStyle &Style) {
3829 if (Replaces.empty())
3830 return tooling::Replacements();
3831
3832 auto NewCode = applyAllReplacements(Code, Replaces);
3833 if (!NewCode)
3834 return NewCode.takeError();
3835 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
3836 StringRef FileName = Replaces.begin()->getFilePath();
3837
3838 tooling::Replacements FormatReplaces =
3839 ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
3840
3841 return Replaces.merge(FormatReplaces);
3842}
3843
3845formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
3846 const FormatStyle &Style) {
3847 // We need to use lambda function here since there are two versions of
3848 // `sortIncludes`.
3849 auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
3850 std::vector<tooling::Range> Ranges,
3851 StringRef FileName) -> tooling::Replacements {
3852 return sortIncludes(Style, Code, Ranges, FileName);
3853 };
3854 auto SortedReplaces =
3855 processReplacements(SortIncludes, Code, Replaces, Style);
3856 if (!SortedReplaces)
3857 return SortedReplaces.takeError();
3858
3859 // We need to use lambda function here since there are two versions of
3860 // `reformat`.
3861 auto Reformat = [](const FormatStyle &Style, StringRef Code,
3862 std::vector<tooling::Range> Ranges,
3863 StringRef FileName) -> tooling::Replacements {
3864 return reformat(Style, Code, Ranges, FileName);
3865 };
3866 return processReplacements(Reformat, Code, *SortedReplaces, Style);
3867}
3868
3869namespace {
3870
3871inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
3872 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
3873 Replace.getLength() == 0 &&
3875 Replace.getReplacementText());
3876}
3877
3878inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3879 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
3880 Replace.getLength() == 1;
3881}
3882
3883// FIXME: insert empty lines between newly created blocks.
3884tooling::Replacements
3885fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3886 const FormatStyle &Style) {
3887 if (!Style.isCpp())
3888 return Replaces;
3889
3890 tooling::Replacements HeaderInsertions;
3891 std::set<StringRef> HeadersToDelete;
3892 tooling::Replacements Result;
3893 for (const auto &R : Replaces) {
3894 if (isHeaderInsertion(R)) {
3895 // Replacements from \p Replaces must be conflict-free already, so we can
3896 // simply consume the error.
3897 consumeError(HeaderInsertions.add(R));
3898 } else if (isHeaderDeletion(R)) {
3899 HeadersToDelete.insert(R.getReplacementText());
3900 } else if (R.getOffset() == std::numeric_limits<unsigned>::max()) {
3901 llvm::errs() << "Insertions other than header #include insertion are "
3902 "not supported! "
3903 << R.getReplacementText() << "\n";
3904 } else {
3905 consumeError(Result.add(R));
3906 }
3907 }
3908 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3909 return Replaces;
3910
3911 StringRef FileName = Replaces.begin()->getFilePath();
3912 tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
3913
3914 for (const auto &Header : HeadersToDelete) {
3915 tooling::Replacements Replaces =
3916 Includes.remove(Header.trim("\"<>"), Header.starts_with("<"));
3917 for (const auto &R : Replaces) {
3918 auto Err = Result.add(R);
3919 if (Err) {
3920 // Ignore the deletion on conflict.
3921 llvm::errs() << "Failed to add header deletion replacement for "
3922 << Header << ": " << toString(std::move(Err)) << "\n";
3923 }
3924 }
3925 }
3926
3928 for (const auto &R : HeaderInsertions) {
3929 auto IncludeDirective = R.getReplacementText();
3930 bool Matched =
3931 tooling::HeaderIncludes::IncludeRegex.match(IncludeDirective, &Matches);
3932 assert(Matched && "Header insertion replacement must have replacement text "
3933 "'#include ...'");
3934 (void)Matched;
3935 auto IncludeName = Matches[2];
3936 auto Replace =
3937 Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"),
3939 if (Replace) {
3940 auto Err = Result.add(*Replace);
3941 if (Err) {
3942 consumeError(std::move(Err));
3943 unsigned NewOffset =
3944 Result.getShiftedCodePosition(Replace->getOffset());
3945 auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3946 Replace->getReplacementText());
3947 Result = Result.merge(tooling::Replacements(Shifted));
3948 }
3949 }
3950 }
3951 return Result;
3952}
3953
3954} // anonymous namespace
3955
3957cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
3958 const FormatStyle &Style) {
3959 // We need to use lambda function here since there are two versions of
3960 // `cleanup`.
3961 auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3963 StringRef FileName) -> tooling::Replacements {
3964 return cleanup(Style, Code, Ranges, FileName);
3965 };
3966 // Make header insertion replacements insert new headers into correct blocks.
3967 tooling::Replacements NewReplaces =
3968 fixCppIncludeInsertions(Code, Replaces, Style);
3969 return cantFail(processReplacements(Cleanup, Code, NewReplaces, Style));
3970}
3971
3972namespace internal {
3973std::pair<tooling::Replacements, unsigned>
3974reformat(const FormatStyle &Style, StringRef Code,
3975 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
3976 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3977 FormattingAttemptStatus *Status) {
3978 FormatStyle Expanded = Style;
3982 Expanded.InsertBraces = false;
3983 Expanded.RemoveBracesLLVM = false;
3984 Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
3985 Expanded.RemoveSemicolon = false;
3986 switch (Expanded.RequiresClausePosition) {
3987 case FormatStyle::RCPS_SingleLine:
3988 case FormatStyle::RCPS_WithPreceding:
3989 Expanded.IndentRequiresClause = false;
3990 break;
3991 default:
3992 break;
3993 }
3994
3995 if (Expanded.DisableFormat)
3996 return {tooling::Replacements(), 0};
3997 if (isLikelyXml(Code))
3998 return {tooling::Replacements(), 0};
3999 if (Expanded.isJavaScript() && isMpegTS(Code))
4000 return {tooling::Replacements(), 0};
4001
4002 // JSON only needs the formatting passing.
4003 if (Style.isJson()) {
4004 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
4005 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
4006 NextStartColumn, LastStartColumn);
4007 if (!Env)
4008 return {};
4009 // Perform the actual formatting pass.
4010 tooling::Replacements Replaces =
4011 Formatter(*Env, Style, Status).process().first;
4012 // add a replacement to remove the "x = " from the result.
4013 if (Code.starts_with("x = ")) {
4014 Replaces = Replaces.merge(
4016 }
4017 // apply the reformatting changes and the removal of "x = ".
4018 if (applyAllReplacements(Code, Replaces))
4019 return {Replaces, 0};
4020 return {tooling::Replacements(), 0};
4021 }
4022
4023 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
4024 NextStartColumn, LastStartColumn);
4025 if (!Env)
4026 return {};
4027
4029 const Environment &)>
4031
4033
4034 Passes.emplace_back([&](const Environment &Env) {
4035 return IntegerLiteralSeparatorFixer().process(Env, Expanded);
4036 });
4037
4038 Passes.emplace_back([&](const Environment &Env) {
4039 return NumericLiteralCaseFixer().process(Env, Expanded);
4040 });
4041
4042 if (Style.isCpp()) {
4043 if (Style.QualifierAlignment != FormatStyle::QAS_Leave)
4044 addQualifierAlignmentFixerPasses(Expanded, Passes);
4045
4046 if (Style.RemoveParentheses != FormatStyle::RPS_Leave) {
4047 FormatStyle S = Expanded;
4048 S.RemoveParentheses = Style.RemoveParentheses;
4049 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
4050 return ParensRemover(Env, S).process(/*SkipAnnotation=*/true);
4051 });
4052 }
4053
4054 if (Style.InsertBraces) {
4055 FormatStyle S = Expanded;
4056 S.InsertBraces = true;
4057 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
4058 return BracesInserter(Env, S).process(/*SkipAnnotation=*/true);
4059 });
4060 }
4061
4062 if (Style.RemoveBracesLLVM) {
4063 FormatStyle S = Expanded;
4064 S.RemoveBracesLLVM = true;
4065 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
4066 return BracesRemover(Env, S).process(/*SkipAnnotation=*/true);
4067 });
4068 }
4069
4070 if (Style.RemoveSemicolon) {
4071 FormatStyle S = Expanded;
4072 S.RemoveSemicolon = true;
4073 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
4074 return SemiRemover(Env, S).process();
4075 });
4076 }
4077
4078 if (Style.EnumTrailingComma != FormatStyle::ETC_Leave) {
4079 Passes.emplace_back([&](const Environment &Env) {
4080 return EnumTrailingCommaEditor(Env, Expanded)
4081 .process(/*SkipAnnotation=*/true);
4082 });
4083 }
4084
4085 if (Style.FixNamespaceComments) {
4086 Passes.emplace_back([&](const Environment &Env) {
4087 return NamespaceEndCommentsFixer(Env, Expanded).process();
4088 });
4089 }
4090
4091 if (Style.SortUsingDeclarations != FormatStyle::SUD_Never) {
4092 Passes.emplace_back([&](const Environment &Env) {
4093 return UsingDeclarationsSorter(Env, Expanded).process();
4094 });
4095 }
4096 }
4097
4098 if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave) {
4099 Passes.emplace_back([&](const Environment &Env) {
4100 return DefinitionBlockSeparator(Env, Expanded).process();
4101 });
4102 }
4103
4104 if (Style.Language == FormatStyle::LK_ObjC &&
4105 !Style.ObjCPropertyAttributeOrder.empty()) {
4106 Passes.emplace_back([&](const Environment &Env) {
4107 return ObjCPropertyAttributeOrderFixer(Env, Expanded).process();
4108 });
4109 }
4110
4111 if (Style.isJavaScript() &&
4112 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
4113 Passes.emplace_back([&](const Environment &Env) {
4114 return JavaScriptRequoter(Env, Expanded).process(/*SkipAnnotation=*/true);
4115 });
4116 }
4117
4118 Passes.emplace_back([&](const Environment &Env) {
4119 return Formatter(Env, Expanded, Status).process();
4120 });
4121
4122 if (Style.isJavaScript() &&
4123 Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped) {
4124 Passes.emplace_back([&](const Environment &Env) {
4125 return TrailingCommaInserter(Env, Expanded).process();
4126 });
4127 }
4128
4129 std::optional<std::string> CurrentCode;
4131 unsigned Penalty = 0;
4132 for (size_t I = 0, E = Passes.size(); I < E; ++I) {
4133 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
4134 auto NewCode = applyAllReplacements(
4135 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
4136 if (NewCode) {
4137 Fixes = Fixes.merge(PassFixes.first);
4138 Penalty += PassFixes.second;
4139 if (I + 1 < E) {
4140 CurrentCode = std::move(*NewCode);
4141 Env = Environment::make(
4142 *CurrentCode, FileName,
4144 FirstStartColumn, NextStartColumn, LastStartColumn);
4145 if (!Env)
4146 return {};
4147 }
4148 }
4149 }
4150
4151 if (Style.QualifierAlignment != FormatStyle::QAS_Leave) {
4152 // Don't make replacements that replace nothing. QualifierAlignment can
4153 // produce them if one of its early passes changes e.g. `const volatile` to
4154 // `volatile const` and then a later pass changes it back again.
4155 tooling::Replacements NonNoOpFixes;
4156 for (const tooling::Replacement &Fix : Fixes) {
4157 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4158 if (OriginalCode != Fix.getReplacementText()) {
4159 auto Err = NonNoOpFixes.add(Fix);
4160 if (Err) {
4161 llvm::errs() << "Error adding replacements : "
4162 << toString(std::move(Err)) << "\n";
4163 }
4164 }
4165 }
4166 Fixes = std::move(NonNoOpFixes);
4167 }
4168
4169 return {Fixes, Penalty};
4170}
4171} // namespace internal
4172
4173tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
4175 StringRef FileName,
4176 FormattingAttemptStatus *Status) {
4177 return internal::reformat(Style, Code, Ranges,
4178 /*FirstStartColumn=*/0,
4179 /*NextStartColumn=*/0,
4180 /*LastStartColumn=*/0, FileName, Status)
4181 .first;
4182}
4183
4184tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
4186 StringRef FileName) {
4187 // cleanups only apply to C++ (they mostly concern ctor commas etc.)
4188 if (Style.Language != FormatStyle::LK_Cpp)
4189 return tooling::Replacements();
4190 auto Env = Environment::make(Code, FileName, Ranges);
4191 if (!Env)
4192 return {};
4193 return Cleaner(*Env, Style).process().first;
4194}
4195
4196tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
4198 StringRef FileName, bool *IncompleteFormat) {
4200 auto Result = reformat(Style, Code, Ranges, FileName, &Status);
4201 if (!Status.FormatComplete)
4202 *IncompleteFormat = true;
4203 return Result;
4204}
4205
4207 StringRef Code,
4209 StringRef FileName) {
4210 auto Env = Environment::make(Code, FileName, Ranges);
4211 if (!Env)
4212 return {};
4213 return NamespaceEndCommentsFixer(*Env, Style).process().first;
4214}
4215
4217 StringRef Code,
4219 StringRef FileName) {
4220 auto Env = Environment::make(Code, FileName, Ranges);
4221 if (!Env)
4222 return {};
4223 return UsingDeclarationsSorter(*Env, Style).process().first;
4224}
4225
4226LangOptions getFormattingLangOpts(const FormatStyle &Style) {
4227 LangOptions LangOpts;
4228
4229 auto LexingStd = Style.Standard;
4230 if (LexingStd == FormatStyle::LS_Auto || LexingStd == FormatStyle::LS_Latest)
4231 LexingStd = FormatStyle::LS_Cpp20;
4232
4233 const bool SinceCpp11 = LexingStd >= FormatStyle::LS_Cpp11;
4234 const bool SinceCpp20 = LexingStd >= FormatStyle::LS_Cpp20;
4235
4236 switch (Style.Language) {
4237 case FormatStyle::LK_C:
4238 LangOpts.C11 = 1;
4239 LangOpts.C23 = 1;
4240 break;
4241 case FormatStyle::LK_Cpp:
4242 case FormatStyle::LK_ObjC:
4243 LangOpts.CXXOperatorNames = 1;
4244 LangOpts.CPlusPlus11 = SinceCpp11;
4245 LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
4246 LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
4247 LangOpts.CPlusPlus20 = SinceCpp20;
4248 [[fallthrough]];
4249 default:
4250 LangOpts.CPlusPlus = 1;
4251 }
4252
4253 LangOpts.Char8 = SinceCpp20;
4254 // Turning on digraphs in standards before C++0x is error-prone, because e.g.
4255 // the sequence "<::" will be unconditionally treated as "[:".
4256 // Cf. Lexer::LexTokenInternal.
4257 LangOpts.Digraphs = SinceCpp11;
4258
4259 LangOpts.LineComment = 1;
4260 LangOpts.Bool = 1;
4261 LangOpts.ObjC = 1;
4262 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
4263 LangOpts.DeclSpecKeyword = 1; // To get __declspec.
4264 LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
4265
4266 return LangOpts;
4267}
4268
4270 "Set coding style. <string> can be:\n"
4271 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4272 " Mozilla, WebKit.\n"
4273 "2. 'file' to load style configuration from a\n"
4274 " .clang-format file in one of the parent directories\n"
4275 " of the source file (for stdin, see --assume-filename).\n"
4276 " If no .clang-format file is found, falls back to\n"
4277 " --fallback-style.\n"
4278 " --style=file is the default.\n"
4279 "3. 'file:<format_file_path>' to explicitly specify\n"
4280 " the configuration file.\n"
4281 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4282 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4283
4284static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
4285 if (FileName.ends_with(".c"))
4286 return FormatStyle::LK_C;
4287 if (FileName.ends_with(".java"))
4288 return FormatStyle::LK_Java;
4289 if (FileName.ends_with_insensitive(".js") ||
4290 FileName.ends_with_insensitive(".mjs") ||
4291 FileName.ends_with_insensitive(".cjs") ||
4292 FileName.ends_with_insensitive(".ts")) {
4293 return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
4294 }
4295 if (FileName.ends_with(".m") || FileName.ends_with(".mm"))
4296 return FormatStyle::LK_ObjC;
4297 if (FileName.ends_with_insensitive(".proto") ||
4298 FileName.ends_with_insensitive(".protodevel")) {
4299 return FormatStyle::LK_Proto;
4300 }
4301 // txtpb is the canonical extension, and textproto is the legacy canonical
4302 // extension
4303 // https://protobuf.dev/reference/protobuf/textformat-spec/#text-format-files
4304 if (FileName.ends_with_insensitive(".txtpb") ||
4305 FileName.ends_with_insensitive(".textpb") ||
4306 FileName.ends_with_insensitive(".pb.txt") ||
4307 FileName.ends_with_insensitive(".textproto") ||
4308 FileName.ends_with_insensitive(".asciipb")) {
4309 return FormatStyle::LK_TextProto;
4310 }
4311 if (FileName.ends_with_insensitive(".td"))
4312 return FormatStyle::LK_TableGen;
4313 if (FileName.ends_with_insensitive(".cs"))
4314 return FormatStyle::LK_CSharp;
4315 if (FileName.ends_with_insensitive(".json") ||
4316 FileName.ends_with_insensitive(".ipynb")) {
4317 return FormatStyle::LK_Json;
4318 }
4319 if (FileName.ends_with_insensitive(".sv") ||
4320 FileName.ends_with_insensitive(".svh") ||
4321 FileName.ends_with_insensitive(".v") ||
4322 FileName.ends_with_insensitive(".vh")) {
4323 return FormatStyle::LK_Verilog;
4324 }
4325 return FormatStyle::LK_Cpp;
4326}
4327
4328static FormatStyle::LanguageKind getLanguageByComment(const Environment &Env) {
4329 const auto ID = Env.getFileID();
4330 const auto &SourceMgr = Env.getSourceManager();
4331
4332 LangOptions LangOpts;
4333 LangOpts.CPlusPlus = 1;
4334 LangOpts.LineComment = 1;
4335
4336 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);
4337 Lex.SetCommentRetentionState(true);
4338
4339 for (Token Tok; !Lex.LexFromRawLexer(Tok) && Tok.is(tok::comment);) {
4340 auto Text = StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
4341 Tok.getLength());
4342 if (!Text.consume_front("// clang-format Language:"))
4343 continue;
4344
4345 Text = Text.trim();
4346 if (Text == "C")
4347 return FormatStyle::LK_C;
4348 if (Text == "Cpp")
4349 return FormatStyle::LK_Cpp;
4350 if (Text == "ObjC")
4351 return FormatStyle::LK_ObjC;
4352 }
4353
4354 return FormatStyle::LK_None;
4355}
4356
4357FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
4358 const auto GuessedLanguage = getLanguageByFileName(FileName);
4359 if (GuessedLanguage == FormatStyle::LK_Cpp) {
4360 auto Extension = llvm::sys::path::extension(FileName);
4361 // If there's no file extension (or it's .h), we need to check the contents
4362 // of the code to see if it contains Objective-C.
4363 if (!Code.empty() && (Extension.empty() || Extension == ".h")) {
4364 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
4365 Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
4366 if (const auto Language = getLanguageByComment(Env);
4367 Language != FormatStyle::LK_None) {
4368 return Language;
4369 }
4370 ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
4371 Guesser.process();
4372 if (Guesser.isObjC())
4373 return FormatStyle::LK_ObjC;
4374 }
4375 }
4376 return GuessedLanguage;
4377}
4378
4379// Update StyleOptionHelpDescription above when changing this.
4380const char *DefaultFormatStyle = "file";
4381
4382const char *DefaultFallbackStyle = "LLVM";
4383
4384llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4385loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
4386 FormatStyle *Style, bool AllowUnknownOptions,
4387 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4388 bool IsDotHFile) {
4389 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4390 FS->getBufferForFile(ConfigFile.str());
4391 if (auto EC = Text.getError())
4392 return EC;
4393 if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions,
4394 DiagHandler, /*DiagHandlerCtx=*/nullptr,
4395 IsDotHFile)) {
4396 return EC;
4397 }
4398 return Text;
4399}
4400
4401Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
4402 StringRef FallbackStyleName, StringRef Code,
4403 llvm::vfs::FileSystem *FS,
4404 bool AllowUnknownOptions,
4405 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4406 FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
4407 FormatStyle FallbackStyle = getNoStyle();
4408 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
4409 return make_string_error("Invalid fallback style: " + FallbackStyleName);
4410
4411 SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1> ChildFormatTextToApply;
4412
4413 if (StyleName.starts_with("{")) {
4414 // Parse YAML/JSON style from the command line.
4415 StringRef Source = "<command-line>";
4416 if (std::error_code ec =
4417 parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
4418 AllowUnknownOptions, DiagHandler)) {
4419 return make_string_error("Error parsing -style: " + ec.message());
4420 }
4421
4422 if (!Style.InheritsParentConfig)
4423 return Style;
4424
4425 ChildFormatTextToApply.emplace_back(
4426 llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
4427 }
4428
4429 if (!FS)
4430 FS = llvm::vfs::getRealFileSystem().get();
4431 assert(FS);
4432
4433 const bool IsDotHFile = FileName.ends_with(".h");
4434
4435 // User provided clang-format file using -style=file:path/to/format/file.
4436 if (!Style.InheritsParentConfig &&
4437 StyleName.starts_with_insensitive("file:")) {
4438 auto ConfigFile = StyleName.substr(5);
4439 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4440 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4441 DiagHandler, IsDotHFile);
4442 if (auto EC = Text.getError()) {
4443 return make_string_error("Error reading " + ConfigFile + ": " +
4444 EC.message());
4445 }
4446
4447 LLVM_DEBUG(llvm::dbgs()
4448 << "Using configuration file " << ConfigFile << "\n");
4449
4450 if (!Style.InheritsParentConfig)
4451 return Style;
4452
4453 // Search for parent configs starting from the parent directory of
4454 // ConfigFile.
4455 FileName = ConfigFile;
4456 ChildFormatTextToApply.emplace_back(std::move(*Text));
4457 }
4458
4459 // If the style inherits the parent configuration it is a command line
4460 // configuration, which wants to inherit, so we have to skip the check of the
4461 // StyleName.
4462 if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
4463 if (!getPredefinedStyle(StyleName, Style.Language, &Style))
4464 return make_string_error("Invalid value for -style");
4465 if (!Style.InheritsParentConfig)
4466 return Style;
4467 }
4468
4470 if (std::error_code EC = FS->makeAbsolute(Path))
4471 return make_string_error(EC.message());
4472
4473 // Reset possible inheritance
4474 Style.InheritsParentConfig = false;
4475
4476 auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
4477
4478 auto applyChildFormatTexts = [&](FormatStyle *Style) {
4479 for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4480 auto EC =
4481 parseConfiguration(*MemBuf, Style, AllowUnknownOptions,
4482 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4483 // It was already correctly parsed.
4484 assert(!EC);
4485 static_cast<void>(EC);
4486 }
4487 };
4488
4489 // Look for .clang-format/_clang-format file in the file's parent directories.
4490 SmallVector<std::string, 2> FilesToLookFor;
4491 FilesToLookFor.push_back(".clang-format");
4492 FilesToLookFor.push_back("_clang-format");
4493
4494 SmallString<128> UnsuitableConfigFiles;
4495 for (StringRef Directory = Path; !Directory.empty();
4496 Directory = llvm::sys::path::parent_path(Directory)) {
4497 auto Status = FS->status(Directory);
4498 if (!Status ||
4499 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4500 continue;
4501 }
4502
4503 for (const auto &F : FilesToLookFor) {
4504 SmallString<128> ConfigFile(Directory);
4505
4506 llvm::sys::path::append(ConfigFile, F);
4507 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
4508
4509 Status = FS->status(ConfigFile);
4510 if (!Status ||
4511 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4512 continue;
4513 }
4514
4515 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4516 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4517 DiagHandler, IsDotHFile);
4518 if (auto EC = Text.getError()) {
4519 if (EC != ParseError::Unsuitable) {
4520 return make_string_error("Error reading " + ConfigFile + ": " +
4521 EC.message());
4522 }
4523 if (!UnsuitableConfigFiles.empty())
4524 UnsuitableConfigFiles.append(", ");
4525 UnsuitableConfigFiles.append(ConfigFile);
4526 continue;
4527 }
4528
4529 LLVM_DEBUG(llvm::dbgs()
4530 << "Using configuration file " << ConfigFile << "\n");
4531
4532 if (!Style.InheritsParentConfig) {
4533 if (!ChildFormatTextToApply.empty()) {
4534 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4535 applyChildFormatTexts(&Style);
4536 }
4537 return Style;
4538 }
4539
4540 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4541
4542 // Reset inheritance of style
4543 Style.InheritsParentConfig = false;
4544
4545 ChildFormatTextToApply.emplace_back(std::move(*Text));
4546
4547 // Breaking out of the inner loop, since we don't want to parse
4548 // .clang-format AND _clang-format, if both exist. Then we continue the
4549 // outer loop (parent directories) in search for the parent
4550 // configuration.
4551 break;
4552 }
4553 }
4554
4555 if (!UnsuitableConfigFiles.empty()) {
4556 return make_string_error("Configuration file(s) do(es) not support " +
4557 getLanguageName(Style.Language) + ": " +
4558 UnsuitableConfigFiles);
4559 }
4560
4561 if (!ChildFormatTextToApply.empty()) {
4562 LLVM_DEBUG(llvm::dbgs()
4563 << "Applying child configurations on fallback style\n");
4564 applyChildFormatTexts(&FallbackStyle);
4565 }
4566
4567 return FallbackStyle;
4568}
4569
4570static bool isClangFormatOnOff(StringRef Comment, bool On) {
4571 if (Comment == (On ? "/* clang-format on */" : "/* clang-format off */"))
4572 return true;
4573
4574 static const char ClangFormatOn[] = "// clang-format on";
4575 static const char ClangFormatOff[] = "// clang-format off";
4576 const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1;
4577
4578 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4579 (Comment.size() == Size || Comment[Size] == ':');
4580}
4581
4582bool isClangFormatOn(StringRef Comment) {
4583 return isClangFormatOnOff(Comment, /*On=*/true);
4584}
4585
4586bool isClangFormatOff(StringRef Comment) {
4587 return isClangFormatOnOff(Comment, /*On=*/false);
4588}
4589
4590} // namespace format
4591} // namespace clang
This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or removes empty lines sepa...
int8_t BraceCount
Number of optional braces to be inserted after this token: -1: a single left brace 0: no braces >0: n...
FormatToken()
Token Tok
The Token.
FormatToken * Next
The next token in the unwrapped line.
BracketAlignmentStyle
Definition Format.cpp:35
@ BAS_DontAlign
Definition Format.cpp:37
@ BAS_BlockIndent
Definition Format.cpp:39
@ BAS_Align
Definition Format.cpp:36
@ BAS_AlwaysBreak
Definition Format.cpp:38
Various functions to configurably format source code.
StringRef getLanguageName(FormatStyle::LanguageKind Language)
Definition Format.h:6076
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
Gets a predefined style for the specified language by name.
This file declares IntegerLiteralSeparatorFixer that fixes C++ integer literal separators.
This file declares NamespaceEndCommentsFixer, a TokenAnalyzer that fixes namespace end comments.
This file declares NumericLiteralCaseFixer that standardizes character case within numeric literals.
This file declares ObjCPropertyAttributeOrderFixer, a TokenAnalyzer that adjusts the order of attribu...
This file declares QualifierAlignmentFixer, a TokenAnalyzer that enforces either east or west const d...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file implements a sorter for JavaScript ES6 imports.
Implements a combinatorial exploration of all the different linebreaks unwrapped lines can be formatt...
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
static CharSourceRange getCharRange(SourceRange R)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition Lexer.h:78
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
Definition Lexer.h:236
void SetCommentRetentionState(bool Mode)
SetCommentRetentionMode - Change the comment retention mode of the lexer to the specified mode.
Definition Lexer.h:269
Token - This structure provides full information about a lexed token.
Definition Token.h:36
SourceManager & getSourceManager() const
static std::unique_ptr< Environment > make(StringRef Code, StringRef FileName, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn=0, unsigned NextStartColumn=0, unsigned LastStartColumn=0)
std::pair< tooling::Replacements, unsigned > process(const Environment &Env, const FormatStyle &Style)
static tok::TokenKind getTokenFromQualifier(const std::string &Qualifier)
std::pair< tooling::Replacements, unsigned > process(const Environment &Env, const FormatStyle &Style)
const char * name() const noexcept override
Definition Format.cpp:1477
std::string message(int EV) const override
Definition Format.cpp:1481
std::pair< tooling::Replacements, unsigned > process(bool SkipAnnotation=false)
static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF)
Infers whether the input is using CRLF.
static const llvm::Regex IncludeRegex
This class manages priorities of C++ include categories and calculates priorities for headers.
int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const
Returns the priority of the category which IncludeName belongs to.
int getSortIncludePriority(StringRef IncludeName, bool CheckMainHeader) const
A source range independent of the SourceManager.
Definition Replacement.h:44
A text replacement.
Definition Replacement.h:83
unsigned getLength() const
StringRef getReplacementText() const
unsigned getOffset() const
Maintains a set of replacements that are conflict-free.
std::vector< Range > getAffectedRanges() const
const_iterator begin() const
llvm::Error add(const Replacement &R)
Adds a new replacement R to the current set of replacements.
Replacements merge(const Replacements &Replaces) const
Merges Replaces into the current replacements.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
Definition Types.cpp:216
std::pair< tooling::Replacements, unsigned > reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, FormattingAttemptStatus *Status)
Reformats the given Ranges in the code fragment Code.
Definition Format.cpp:3974
void addQualifierAlignmentFixerPasses(const FormatStyle &Style, SmallVectorImpl< AnalyzerPass > &Passes)
static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded)
Definition Format.cpp:1603
static bool affectsRange(ArrayRef< tooling::Range > Ranges, unsigned Start, unsigned End)
Definition Format.cpp:3340
const char * getTokenTypeName(TokenType Type)
Determines the name of a token type.
FormatStyle getWebKitStyle()
Definition Format.cpp:2113
bool isLikelyXml(StringRef Code)
Definition Format.cpp:3802
static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName)
Definition Format.cpp:4284
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName, FormattingAttemptStatus *Status)
Definition Format.cpp:4173
const char * StyleOptionHelpDescription
Definition Format.cpp:4269
tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)
Definition Format.cpp:4216
static unsigned findJavaImportGroup(const FormatStyle &Style, StringRef ImportIdentifier)
Definition Format.cpp:3641
std::string replaceCRLF(const std::string &Code)
Definition Format.cpp:3381
std::error_code make_error_code(ParseError e)
Definition Format.cpp:1468
const char * DefaultFallbackStyle
Definition Format.cpp:4382
FormatStyle getClangFormatStyle()
Definition Format.cpp:2181
std::function< std::pair< tooling::Replacements, unsigned >(const Environment &)> AnalyzerPass
const char * DefaultFormatStyle
Definition Format.cpp:4380
static void replaceToken(const SourceManager &SourceMgr, tooling::Replacements &Fixes, const CharSourceRange &Range, std::string NewText)
FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language)
Definition Format.cpp:1880
std::string configurationAsText(const FormatStyle &Style)
Definition Format.cpp:2360
FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language)
Definition Format.cpp:2152
const std::error_category & getParseCategory()
Definition Format.cpp:1464
FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code)
Definition Format.cpp:4357
bool isMpegTS(StringRef Code)
Definition Format.cpp:3795
tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)
Definition Format.cpp:4206
static std::pair< unsigned, unsigned > FindCursorIndex(const ArrayRef< IncludeDirective > &Includes, const ArrayRef< unsigned > &Indices, unsigned Cursor)
Definition Format.cpp:3360
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)
Definition Format.cpp:4184
static FormatStyle::LanguageKind getLanguageByComment(const Environment &Env)
Definition Format.cpp:4328
FormatStyle getGNUStyle()
Definition Format.cpp:2137
bool isClangFormatOff(StringRef Comment)
Definition Format.cpp:4586
static bool isClangFormatOnOff(StringRef Comment, bool On)
Definition Format.cpp:4570
tooling::Replacements sortJavaScriptImports(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)
static void sortJavaImports(const FormatStyle &Style, const ArrayRef< JavaImportDirective > &Imports, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces)
Definition Format.cpp:3661
FormatStyle getMozillaStyle()
Definition Format.cpp:2087
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
Definition Format.cpp:2203
Expected< tooling::Replacements > cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)
Definition Format.cpp:3957
static void expandPresetsBraceWrapping(FormatStyle &Expanded)
Definition Format.cpp:1503
tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName, unsigned *Cursor)
Definition Format.cpp:3804
static void sortCppIncludes(const FormatStyle &Style, const ArrayRef< IncludeDirective > &Includes, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces, unsigned *Cursor)
Definition Format.cpp:3409
bool isClangFormatOn(StringRef Comment)
Definition Format.cpp:4582
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language)
Definition Format.cpp:1635
Expected< FormatStyle > getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyleName, StringRef Code, llvm::vfs::FileSystem *FS, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler)
Definition Format.cpp:4401
llvm::Error make_string_error(const Twine &Message)
Definition Format.cpp:1472
ParseError validateQualifierOrder(FormatStyle *Style)
Definition Format.cpp:2232
FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language)
Definition Format.cpp:2028
static void expandPresetsSpacesInParens(FormatStyle &Expanded)
Definition Format.cpp:1627
std::error_code parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt, bool IsDotHFile)
Definition Format.cpp:2264
Expected< tooling::Replacements > formatReplacements(StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)
Definition Format.cpp:3845
FormatStyle getNoStyle()
Definition Format.cpp:2195
LangOptions getFormattingLangOpts(const FormatStyle &Style)
Definition Format.cpp:4226
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler, bool IsDotHFile)
Definition Format.cpp:4385
static Expected< tooling::Replacements > processReplacements(T ProcessFunc, StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)
Definition Format.cpp:3826
std::vector< Range > calculateRangesAfterReplacements(const Replacements &Replaces, const std::vector< Range > &Ranges)
Calculates the new ranges after Replaces are applied.
The JSON file list parser is used to communicate input to InstallAPI.
std::vector< std::string > JavaImportGroups
A vector of prefixes ordered by the desired groups for Java imports.
Definition Format.h:3373
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
SortIncludesOptions SortIncludes
Controls if and how clang-format will sort #includes.
Definition Format.h:4634
@ LK_None
Do not use.
Definition Format.h:3512
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
int const char * function
Definition c++config.h:31
#define false
Definition stdbool.h:26
Represents the status of a formatting attempt.
Definition Format.h:5946
std::optional< FormatStyle > Get(LanguageKind Language) const
A wrapper around a Token storing information about the whitespace characters preceding it.
bool isNot(T Kind) const
unsigned NewlinesBefore
The number of newlines immediately before the Token.
SourceRange WhitespaceRange
The range of the whitespace immediately preceding the Token.
@ IBS_Preserve
Sort each #include block separately.
@ IBS_Regroup
Merge multiple #include blocks together and sort as one. Then split into groups based on category pri...
@ IBS_Merge
Merge multiple #include blocks together and sort as one.
static FormatStyle & element(IO &IO, std::vector< FormatStyle > &Seq, size_t Index)
Definition Format.cpp:1442
static size_t size(IO &IO, std::vector< FormatStyle > &Seq)
Definition Format.cpp:1439
static void mapping(IO &IO, FormatStyle &Style)
Definition Format.cpp:932
static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)
Definition Format.cpp:55
static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)
Definition Format.cpp:92
static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping)
Definition Format.cpp:192
static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base)
Definition Format.cpp:406
static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value)
Definition Format.cpp:425
static void mapping(IO &IO, FormatStyle::NumericLiteralCaseStyle &Value)
Definition Format.cpp:506
static void mapping(IO &IO, FormatStyle::RawStringFormat &Format)
Definition Format.cpp:572
static void mapping(IO &IO, FormatStyle::ShortCaseStatementsAlignmentStyle &Value)
Definition Format.cpp:106
static void mapping(IO &IO, FormatStyle::SortIncludesOptions &Value)
Definition Format.cpp:723
static void enumInput(IO &IO, FormatStyle::SortIncludesOptions &Value)
Definition Format.cpp:704
static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing)
Definition Format.cpp:766
static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space)
Definition Format.cpp:828
static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces)
Definition Format.cpp:841
static void mapping(IO &IO, FormatStyle::TrailingCommentsAlignmentStyle &Value)
Definition Format.cpp:898
static void enumInput(IO &IO, FormatStyle::TrailingCommentsAlignmentStyle &Value)
Definition Format.cpp:875
static void enumeration(IO &IO, BracketAlignmentStyle &Value)
Definition Format.cpp:215
static void enumeration(IO &IO, FormatStyle::ArrayInitializerAlignmentStyle &Value)
Definition Format.cpp:127
static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value)
Definition Format.cpp:118
static void enumeration(IO &IO, FormatStyle::BinPackParametersStyle &Value)
Definition Format.cpp:147
static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value)
Definition Format.cpp:159
static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value)
Definition Format.cpp:136
static void enumeration(IO &IO, FormatStyle::BitFieldColonSpacingStyle &Value)
Definition Format.cpp:168
static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value)
Definition Format.cpp:178
static void enumeration(IO &IO, FormatStyle::BraceWrappingAfterControlStatementStyle &Value)
Definition Format.cpp:231
static void enumeration(IO &IO, FormatStyle::BracedListStyle &Value)
Definition Format.cpp:315
static void enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value)
Definition Format.cpp:247
static void enumeration(IO &IO, FormatStyle::BreakBeforeInlineASMColonStyle &Value)
Definition Format.cpp:260
static void enumeration(IO &IO, FormatStyle::BreakBeforeNoexceptSpecifierStyle &Value)
Definition Format.cpp:47
static void enumeration(IO &IO, FormatStyle::BreakBinaryOperationsStyle &Value)
Definition Format.cpp:270
static void enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value)
Definition Format.cpp:281
static void enumeration(IO &IO, FormatStyle::BreakInheritanceListStyle &Value)
Definition Format.cpp:290
static void enumeration(IO &IO, FormatStyle::BreakTemplateDeclarationsStyle &Value)
Definition Format.cpp:301
static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value)
Definition Format.cpp:327
static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value)
Definition Format.cpp:337
static void enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value)
Definition Format.cpp:366
static void enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value)
Definition Format.cpp:377
static void enumeration(IO &IO, FormatStyle::EnumTrailingCommaStyle &Value)
Definition Format.cpp:387
static void enumeration(IO &IO, FormatStyle::EscapedNewlineAlignmentStyle &Value)
Definition Format.cpp:350
static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value)
Definition Format.cpp:396
static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value)
Definition Format.cpp:417
static void enumeration(IO &IO, FormatStyle::LambdaBodyIndentationKind &Value)
Definition Format.cpp:469
static void enumeration(IO &IO, FormatStyle::LanguageKind &Value)
Definition Format.cpp:433
static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value)
Definition Format.cpp:449
static void enumeration(IO &IO, FormatStyle::LineEndingStyle &Value)
Definition Format.cpp:477
static void enumeration(IO &IO, FormatStyle::NamespaceIndentationKind &Value)
Definition Format.cpp:487
static void enumeration(IO &IO, FormatStyle::NumericLiteralComponentStyle &Value)
Definition Format.cpp:497
static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value)
Definition Format.cpp:515
static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value)
Definition Format.cpp:553
static void enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value)
Definition Format.cpp:530
static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value)
Definition Format.cpp:540
static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value)
Definition Format.cpp:563
static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value)
Definition Format.cpp:594
static void enumeration(IO &IO, FormatStyle::ReflowCommentsStyle &Value)
Definition Format.cpp:582
static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value)
Definition Format.cpp:604
static void enumeration(IO &IO, FormatStyle::RequiresClausePositionStyle &Value)
Definition Format.cpp:614
static void enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value)
Definition Format.cpp:627
static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value)
Definition Format.cpp:635
static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value)
Definition Format.cpp:649
static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value)
Definition Format.cpp:657
static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value)
Definition Format.cpp:667
static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value)
Definition Format.cpp:679
static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value)
Definition Format.cpp:693
static void enumeration(IO &IO, FormatStyle::SortJavaStaticImportOptions &Value)
Definition Format.cpp:732
static void enumeration(IO &IO, FormatStyle::SortUsingDeclarationsOptions &Value)
Definition Format.cpp:741
static void enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value)
Definition Format.cpp:757
static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value)
Definition Format.cpp:787
static void enumeration(IO &IO, FormatStyle::SpaceInEmptyBracesStyle &Value)
Definition Format.cpp:808
static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value)
Definition Format.cpp:816
static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value)
Definition Format.cpp:851
static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value)
Definition Format.cpp:858
static void enumeration(IO &IO, FormatStyle::TrailingCommentsAlignmentKinds &Value)
Definition Format.cpp:866
static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value)
Definition Format.cpp:907
static void enumeration(IO &IO, FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value)
Definition Format.cpp:923