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