1 //===--- Format.cpp - Format C++ code -------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file implements functions declared in Format.h. This will be
11 /// split into separate files as we go.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Format/Format.h"
16 #include "DefinitionBlockSeparator.h"
17 #include "IntegerLiteralSeparatorFixer.h"
18 #include "NamespaceEndCommentsFixer.h"
19 #include "ObjCPropertyAttributeOrderFixer.h"
20 #include "QualifierAlignmentFixer.h"
21 #include "SortJavaScriptImports.h"
22 #include "UnwrappedLineFormatter.h"
23 #include "UsingDeclarationsSorter.h"
24 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
25 #include "llvm/ADT/Sequence.h"
27 #define DEBUG_TYPE "format-formatter"
29 using clang::format::FormatStyle
;
31 LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat
)
36 struct ScalarEnumerationTraits
<FormatStyle::BreakBeforeNoexceptSpecifierStyle
> {
38 enumeration(IO
&IO
, FormatStyle::BreakBeforeNoexceptSpecifierStyle
&Value
) {
39 IO
.enumCase(Value
, "Never", FormatStyle::BBNSS_Never
);
40 IO
.enumCase(Value
, "OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen
);
41 IO
.enumCase(Value
, "Always", FormatStyle::BBNSS_Always
);
45 template <> struct MappingTraits
<FormatStyle::AlignConsecutiveStyle
> {
46 static void enumInput(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
47 IO
.enumCase(Value
, "None", FormatStyle::AlignConsecutiveStyle({}));
48 IO
.enumCase(Value
, "Consecutive",
49 FormatStyle::AlignConsecutiveStyle(
50 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
51 /*AcrossComments=*/false, /*AlignCompound=*/false,
52 /*AlignFunctionDeclarations=*/true,
53 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
54 IO
.enumCase(Value
, "AcrossEmptyLines",
55 FormatStyle::AlignConsecutiveStyle(
56 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
57 /*AcrossComments=*/false, /*AlignCompound=*/false,
58 /*AlignFunctionDeclarations=*/true,
59 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
60 IO
.enumCase(Value
, "AcrossComments",
61 FormatStyle::AlignConsecutiveStyle(
62 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
63 /*AcrossComments=*/true, /*AlignCompound=*/false,
64 /*AlignFunctionDeclarations=*/true,
65 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
66 IO
.enumCase(Value
, "AcrossEmptyLinesAndComments",
67 FormatStyle::AlignConsecutiveStyle(
68 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
69 /*AcrossComments=*/true, /*AlignCompound=*/false,
70 /*AlignFunctionDeclarations=*/true,
71 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
73 // For backward compatibility.
74 IO
.enumCase(Value
, "true",
75 FormatStyle::AlignConsecutiveStyle(
76 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
77 /*AcrossComments=*/false, /*AlignCompound=*/false,
78 /*AlignFunctionDeclarations=*/true,
79 /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
80 IO
.enumCase(Value
, "false", FormatStyle::AlignConsecutiveStyle({}));
83 static void mapping(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
84 IO
.mapOptional("Enabled", Value
.Enabled
);
85 IO
.mapOptional("AcrossEmptyLines", Value
.AcrossEmptyLines
);
86 IO
.mapOptional("AcrossComments", Value
.AcrossComments
);
87 IO
.mapOptional("AlignCompound", Value
.AlignCompound
);
88 IO
.mapOptional("AlignFunctionDeclarations",
89 Value
.AlignFunctionDeclarations
);
90 IO
.mapOptional("AlignFunctionPointers", Value
.AlignFunctionPointers
);
91 IO
.mapOptional("PadOperators", Value
.PadOperators
);
96 struct MappingTraits
<FormatStyle::ShortCaseStatementsAlignmentStyle
> {
97 static void mapping(IO
&IO
,
98 FormatStyle::ShortCaseStatementsAlignmentStyle
&Value
) {
99 IO
.mapOptional("Enabled", Value
.Enabled
);
100 IO
.mapOptional("AcrossEmptyLines", Value
.AcrossEmptyLines
);
101 IO
.mapOptional("AcrossComments", Value
.AcrossComments
);
102 IO
.mapOptional("AlignCaseArrows", Value
.AlignCaseArrows
);
103 IO
.mapOptional("AlignCaseColons", Value
.AlignCaseColons
);
108 struct ScalarEnumerationTraits
<FormatStyle::AttributeBreakingStyle
> {
109 static void enumeration(IO
&IO
, FormatStyle::AttributeBreakingStyle
&Value
) {
110 IO
.enumCase(Value
, "Always", FormatStyle::ABS_Always
);
111 IO
.enumCase(Value
, "Leave", FormatStyle::ABS_Leave
);
112 IO
.enumCase(Value
, "Never", FormatStyle::ABS_Never
);
117 struct ScalarEnumerationTraits
<FormatStyle::ArrayInitializerAlignmentStyle
> {
118 static void enumeration(IO
&IO
,
119 FormatStyle::ArrayInitializerAlignmentStyle
&Value
) {
120 IO
.enumCase(Value
, "None", FormatStyle::AIAS_None
);
121 IO
.enumCase(Value
, "Left", FormatStyle::AIAS_Left
);
122 IO
.enumCase(Value
, "Right", FormatStyle::AIAS_Right
);
126 template <> struct ScalarEnumerationTraits
<FormatStyle::BinaryOperatorStyle
> {
127 static void enumeration(IO
&IO
, FormatStyle::BinaryOperatorStyle
&Value
) {
128 IO
.enumCase(Value
, "All", FormatStyle::BOS_All
);
129 IO
.enumCase(Value
, "true", FormatStyle::BOS_All
);
130 IO
.enumCase(Value
, "None", FormatStyle::BOS_None
);
131 IO
.enumCase(Value
, "false", FormatStyle::BOS_None
);
132 IO
.enumCase(Value
, "NonAssignment", FormatStyle::BOS_NonAssignment
);
137 struct ScalarEnumerationTraits
<FormatStyle::BinPackParametersStyle
> {
138 static void enumeration(IO
&IO
, FormatStyle::BinPackParametersStyle
&Value
) {
139 IO
.enumCase(Value
, "BinPack", FormatStyle::BPPS_BinPack
);
140 IO
.enumCase(Value
, "OnePerLine", FormatStyle::BPPS_OnePerLine
);
141 IO
.enumCase(Value
, "AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine
);
143 // For backward compatibility.
144 IO
.enumCase(Value
, "true", FormatStyle::BPPS_BinPack
);
145 IO
.enumCase(Value
, "false", FormatStyle::BPPS_OnePerLine
);
149 template <> struct ScalarEnumerationTraits
<FormatStyle::BinPackStyle
> {
150 static void enumeration(IO
&IO
, FormatStyle::BinPackStyle
&Value
) {
151 IO
.enumCase(Value
, "Auto", FormatStyle::BPS_Auto
);
152 IO
.enumCase(Value
, "Always", FormatStyle::BPS_Always
);
153 IO
.enumCase(Value
, "Never", FormatStyle::BPS_Never
);
158 struct ScalarEnumerationTraits
<FormatStyle::BitFieldColonSpacingStyle
> {
159 static void enumeration(IO
&IO
,
160 FormatStyle::BitFieldColonSpacingStyle
&Value
) {
161 IO
.enumCase(Value
, "Both", FormatStyle::BFCS_Both
);
162 IO
.enumCase(Value
, "None", FormatStyle::BFCS_None
);
163 IO
.enumCase(Value
, "Before", FormatStyle::BFCS_Before
);
164 IO
.enumCase(Value
, "After", FormatStyle::BFCS_After
);
168 template <> struct ScalarEnumerationTraits
<FormatStyle::BraceBreakingStyle
> {
169 static void enumeration(IO
&IO
, FormatStyle::BraceBreakingStyle
&Value
) {
170 IO
.enumCase(Value
, "Attach", FormatStyle::BS_Attach
);
171 IO
.enumCase(Value
, "Linux", FormatStyle::BS_Linux
);
172 IO
.enumCase(Value
, "Mozilla", FormatStyle::BS_Mozilla
);
173 IO
.enumCase(Value
, "Stroustrup", FormatStyle::BS_Stroustrup
);
174 IO
.enumCase(Value
, "Allman", FormatStyle::BS_Allman
);
175 IO
.enumCase(Value
, "Whitesmiths", FormatStyle::BS_Whitesmiths
);
176 IO
.enumCase(Value
, "GNU", FormatStyle::BS_GNU
);
177 IO
.enumCase(Value
, "WebKit", FormatStyle::BS_WebKit
);
178 IO
.enumCase(Value
, "Custom", FormatStyle::BS_Custom
);
182 template <> struct MappingTraits
<FormatStyle::BraceWrappingFlags
> {
183 static void mapping(IO
&IO
, FormatStyle::BraceWrappingFlags
&Wrapping
) {
184 IO
.mapOptional("AfterCaseLabel", Wrapping
.AfterCaseLabel
);
185 IO
.mapOptional("AfterClass", Wrapping
.AfterClass
);
186 IO
.mapOptional("AfterControlStatement", Wrapping
.AfterControlStatement
);
187 IO
.mapOptional("AfterEnum", Wrapping
.AfterEnum
);
188 IO
.mapOptional("AfterExternBlock", Wrapping
.AfterExternBlock
);
189 IO
.mapOptional("AfterFunction", Wrapping
.AfterFunction
);
190 IO
.mapOptional("AfterNamespace", Wrapping
.AfterNamespace
);
191 IO
.mapOptional("AfterObjCDeclaration", Wrapping
.AfterObjCDeclaration
);
192 IO
.mapOptional("AfterStruct", Wrapping
.AfterStruct
);
193 IO
.mapOptional("AfterUnion", Wrapping
.AfterUnion
);
194 IO
.mapOptional("BeforeCatch", Wrapping
.BeforeCatch
);
195 IO
.mapOptional("BeforeElse", Wrapping
.BeforeElse
);
196 IO
.mapOptional("BeforeLambdaBody", Wrapping
.BeforeLambdaBody
);
197 IO
.mapOptional("BeforeWhile", Wrapping
.BeforeWhile
);
198 IO
.mapOptional("IndentBraces", Wrapping
.IndentBraces
);
199 IO
.mapOptional("SplitEmptyFunction", Wrapping
.SplitEmptyFunction
);
200 IO
.mapOptional("SplitEmptyRecord", Wrapping
.SplitEmptyRecord
);
201 IO
.mapOptional("SplitEmptyNamespace", Wrapping
.SplitEmptyNamespace
);
205 template <> struct ScalarEnumerationTraits
<FormatStyle::BracketAlignmentStyle
> {
206 static void enumeration(IO
&IO
, FormatStyle::BracketAlignmentStyle
&Value
) {
207 IO
.enumCase(Value
, "Align", FormatStyle::BAS_Align
);
208 IO
.enumCase(Value
, "DontAlign", FormatStyle::BAS_DontAlign
);
209 IO
.enumCase(Value
, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak
);
210 IO
.enumCase(Value
, "BlockIndent", FormatStyle::BAS_BlockIndent
);
212 // For backward compatibility.
213 IO
.enumCase(Value
, "true", FormatStyle::BAS_Align
);
214 IO
.enumCase(Value
, "false", FormatStyle::BAS_DontAlign
);
219 struct ScalarEnumerationTraits
<
220 FormatStyle::BraceWrappingAfterControlStatementStyle
> {
223 FormatStyle::BraceWrappingAfterControlStatementStyle
&Value
) {
224 IO
.enumCase(Value
, "Never", FormatStyle::BWACS_Never
);
225 IO
.enumCase(Value
, "MultiLine", FormatStyle::BWACS_MultiLine
);
226 IO
.enumCase(Value
, "Always", FormatStyle::BWACS_Always
);
228 // For backward compatibility.
229 IO
.enumCase(Value
, "false", FormatStyle::BWACS_Never
);
230 IO
.enumCase(Value
, "true", FormatStyle::BWACS_Always
);
235 struct ScalarEnumerationTraits
<
236 FormatStyle::BreakBeforeConceptDeclarationsStyle
> {
238 enumeration(IO
&IO
, FormatStyle::BreakBeforeConceptDeclarationsStyle
&Value
) {
239 IO
.enumCase(Value
, "Never", FormatStyle::BBCDS_Never
);
240 IO
.enumCase(Value
, "Allowed", FormatStyle::BBCDS_Allowed
);
241 IO
.enumCase(Value
, "Always", FormatStyle::BBCDS_Always
);
243 // For backward compatibility.
244 IO
.enumCase(Value
, "true", FormatStyle::BBCDS_Always
);
245 IO
.enumCase(Value
, "false", FormatStyle::BBCDS_Allowed
);
250 struct ScalarEnumerationTraits
<FormatStyle::BreakBeforeInlineASMColonStyle
> {
251 static void enumeration(IO
&IO
,
252 FormatStyle::BreakBeforeInlineASMColonStyle
&Value
) {
253 IO
.enumCase(Value
, "Never", FormatStyle::BBIAS_Never
);
254 IO
.enumCase(Value
, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline
);
255 IO
.enumCase(Value
, "Always", FormatStyle::BBIAS_Always
);
260 struct ScalarEnumerationTraits
<FormatStyle::BreakBinaryOperationsStyle
> {
261 static void enumeration(IO
&IO
,
262 FormatStyle::BreakBinaryOperationsStyle
&Value
) {
263 IO
.enumCase(Value
, "Never", FormatStyle::BBO_Never
);
264 IO
.enumCase(Value
, "OnePerLine", FormatStyle::BBO_OnePerLine
);
265 IO
.enumCase(Value
, "RespectPrecedence", FormatStyle::BBO_RespectPrecedence
);
270 struct ScalarEnumerationTraits
<FormatStyle::BreakConstructorInitializersStyle
> {
272 enumeration(IO
&IO
, FormatStyle::BreakConstructorInitializersStyle
&Value
) {
273 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BCIS_BeforeColon
);
274 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BCIS_BeforeComma
);
275 IO
.enumCase(Value
, "AfterColon", FormatStyle::BCIS_AfterColon
);
280 struct ScalarEnumerationTraits
<FormatStyle::BreakInheritanceListStyle
> {
281 static void enumeration(IO
&IO
,
282 FormatStyle::BreakInheritanceListStyle
&Value
) {
283 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BILS_BeforeColon
);
284 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BILS_BeforeComma
);
285 IO
.enumCase(Value
, "AfterColon", FormatStyle::BILS_AfterColon
);
286 IO
.enumCase(Value
, "AfterComma", FormatStyle::BILS_AfterComma
);
291 struct ScalarEnumerationTraits
<FormatStyle::BreakTemplateDeclarationsStyle
> {
292 static void enumeration(IO
&IO
,
293 FormatStyle::BreakTemplateDeclarationsStyle
&Value
) {
294 IO
.enumCase(Value
, "Leave", FormatStyle::BTDS_Leave
);
295 IO
.enumCase(Value
, "No", FormatStyle::BTDS_No
);
296 IO
.enumCase(Value
, "MultiLine", FormatStyle::BTDS_MultiLine
);
297 IO
.enumCase(Value
, "Yes", FormatStyle::BTDS_Yes
);
299 // For backward compatibility.
300 IO
.enumCase(Value
, "false", FormatStyle::BTDS_MultiLine
);
301 IO
.enumCase(Value
, "true", FormatStyle::BTDS_Yes
);
305 template <> struct ScalarEnumerationTraits
<FormatStyle::DAGArgStyle
> {
306 static void enumeration(IO
&IO
, FormatStyle::DAGArgStyle
&Value
) {
307 IO
.enumCase(Value
, "DontBreak", FormatStyle::DAS_DontBreak
);
308 IO
.enumCase(Value
, "BreakElements", FormatStyle::DAS_BreakElements
);
309 IO
.enumCase(Value
, "BreakAll", FormatStyle::DAS_BreakAll
);
314 struct ScalarEnumerationTraits
<FormatStyle::DefinitionReturnTypeBreakingStyle
> {
316 enumeration(IO
&IO
, FormatStyle::DefinitionReturnTypeBreakingStyle
&Value
) {
317 IO
.enumCase(Value
, "None", FormatStyle::DRTBS_None
);
318 IO
.enumCase(Value
, "All", FormatStyle::DRTBS_All
);
319 IO
.enumCase(Value
, "TopLevel", FormatStyle::DRTBS_TopLevel
);
321 // For backward compatibility.
322 IO
.enumCase(Value
, "false", FormatStyle::DRTBS_None
);
323 IO
.enumCase(Value
, "true", FormatStyle::DRTBS_All
);
328 struct ScalarEnumerationTraits
<FormatStyle::EscapedNewlineAlignmentStyle
> {
329 static void enumeration(IO
&IO
,
330 FormatStyle::EscapedNewlineAlignmentStyle
&Value
) {
331 IO
.enumCase(Value
, "DontAlign", FormatStyle::ENAS_DontAlign
);
332 IO
.enumCase(Value
, "Left", FormatStyle::ENAS_Left
);
333 IO
.enumCase(Value
, "LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine
);
334 IO
.enumCase(Value
, "Right", FormatStyle::ENAS_Right
);
336 // For backward compatibility.
337 IO
.enumCase(Value
, "true", FormatStyle::ENAS_Left
);
338 IO
.enumCase(Value
, "false", FormatStyle::ENAS_Right
);
343 struct ScalarEnumerationTraits
<FormatStyle::EmptyLineAfterAccessModifierStyle
> {
345 enumeration(IO
&IO
, FormatStyle::EmptyLineAfterAccessModifierStyle
&Value
) {
346 IO
.enumCase(Value
, "Never", FormatStyle::ELAAMS_Never
);
347 IO
.enumCase(Value
, "Leave", FormatStyle::ELAAMS_Leave
);
348 IO
.enumCase(Value
, "Always", FormatStyle::ELAAMS_Always
);
353 struct ScalarEnumerationTraits
<
354 FormatStyle::EmptyLineBeforeAccessModifierStyle
> {
356 enumeration(IO
&IO
, FormatStyle::EmptyLineBeforeAccessModifierStyle
&Value
) {
357 IO
.enumCase(Value
, "Never", FormatStyle::ELBAMS_Never
);
358 IO
.enumCase(Value
, "Leave", FormatStyle::ELBAMS_Leave
);
359 IO
.enumCase(Value
, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock
);
360 IO
.enumCase(Value
, "Always", FormatStyle::ELBAMS_Always
);
365 struct ScalarEnumerationTraits
<FormatStyle::IndentExternBlockStyle
> {
366 static void enumeration(IO
&IO
, FormatStyle::IndentExternBlockStyle
&Value
) {
367 IO
.enumCase(Value
, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock
);
368 IO
.enumCase(Value
, "Indent", FormatStyle::IEBS_Indent
);
369 IO
.enumCase(Value
, "NoIndent", FormatStyle::IEBS_NoIndent
);
370 IO
.enumCase(Value
, "true", FormatStyle::IEBS_Indent
);
371 IO
.enumCase(Value
, "false", FormatStyle::IEBS_NoIndent
);
375 template <> struct MappingTraits
<FormatStyle::IntegerLiteralSeparatorStyle
> {
376 static void mapping(IO
&IO
, FormatStyle::IntegerLiteralSeparatorStyle
&Base
) {
377 IO
.mapOptional("Binary", Base
.Binary
);
378 IO
.mapOptional("BinaryMinDigits", Base
.BinaryMinDigits
);
379 IO
.mapOptional("Decimal", Base
.Decimal
);
380 IO
.mapOptional("DecimalMinDigits", Base
.DecimalMinDigits
);
381 IO
.mapOptional("Hex", Base
.Hex
);
382 IO
.mapOptional("HexMinDigits", Base
.HexMinDigits
);
386 template <> struct ScalarEnumerationTraits
<FormatStyle::JavaScriptQuoteStyle
> {
387 static void enumeration(IO
&IO
, FormatStyle::JavaScriptQuoteStyle
&Value
) {
388 IO
.enumCase(Value
, "Leave", FormatStyle::JSQS_Leave
);
389 IO
.enumCase(Value
, "Single", FormatStyle::JSQS_Single
);
390 IO
.enumCase(Value
, "Double", FormatStyle::JSQS_Double
);
394 template <> struct MappingTraits
<FormatStyle::KeepEmptyLinesStyle
> {
395 static void mapping(IO
&IO
, FormatStyle::KeepEmptyLinesStyle
&Value
) {
396 IO
.mapOptional("AtEndOfFile", Value
.AtEndOfFile
);
397 IO
.mapOptional("AtStartOfBlock", Value
.AtStartOfBlock
);
398 IO
.mapOptional("AtStartOfFile", Value
.AtStartOfFile
);
402 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageKind
> {
403 static void enumeration(IO
&IO
, FormatStyle::LanguageKind
&Value
) {
404 IO
.enumCase(Value
, "Cpp", FormatStyle::LK_Cpp
);
405 IO
.enumCase(Value
, "Java", FormatStyle::LK_Java
);
406 IO
.enumCase(Value
, "JavaScript", FormatStyle::LK_JavaScript
);
407 IO
.enumCase(Value
, "ObjC", FormatStyle::LK_ObjC
);
408 IO
.enumCase(Value
, "Proto", FormatStyle::LK_Proto
);
409 IO
.enumCase(Value
, "TableGen", FormatStyle::LK_TableGen
);
410 IO
.enumCase(Value
, "TextProto", FormatStyle::LK_TextProto
);
411 IO
.enumCase(Value
, "CSharp", FormatStyle::LK_CSharp
);
412 IO
.enumCase(Value
, "Json", FormatStyle::LK_Json
);
413 IO
.enumCase(Value
, "Verilog", FormatStyle::LK_Verilog
);
417 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageStandard
> {
418 static void enumeration(IO
&IO
, FormatStyle::LanguageStandard
&Value
) {
419 IO
.enumCase(Value
, "c++03", FormatStyle::LS_Cpp03
);
420 IO
.enumCase(Value
, "C++03", FormatStyle::LS_Cpp03
); // Legacy alias
421 IO
.enumCase(Value
, "Cpp03", FormatStyle::LS_Cpp03
); // Legacy alias
423 IO
.enumCase(Value
, "c++11", FormatStyle::LS_Cpp11
);
424 IO
.enumCase(Value
, "C++11", FormatStyle::LS_Cpp11
); // Legacy alias
426 IO
.enumCase(Value
, "c++14", FormatStyle::LS_Cpp14
);
427 IO
.enumCase(Value
, "c++17", FormatStyle::LS_Cpp17
);
428 IO
.enumCase(Value
, "c++20", FormatStyle::LS_Cpp20
);
430 IO
.enumCase(Value
, "Latest", FormatStyle::LS_Latest
);
431 IO
.enumCase(Value
, "Cpp11", FormatStyle::LS_Latest
); // Legacy alias
432 IO
.enumCase(Value
, "Auto", FormatStyle::LS_Auto
);
437 struct ScalarEnumerationTraits
<FormatStyle::LambdaBodyIndentationKind
> {
438 static void enumeration(IO
&IO
,
439 FormatStyle::LambdaBodyIndentationKind
&Value
) {
440 IO
.enumCase(Value
, "Signature", FormatStyle::LBI_Signature
);
441 IO
.enumCase(Value
, "OuterScope", FormatStyle::LBI_OuterScope
);
445 template <> struct ScalarEnumerationTraits
<FormatStyle::LineEndingStyle
> {
446 static void enumeration(IO
&IO
, FormatStyle::LineEndingStyle
&Value
) {
447 IO
.enumCase(Value
, "LF", FormatStyle::LE_LF
);
448 IO
.enumCase(Value
, "CRLF", FormatStyle::LE_CRLF
);
449 IO
.enumCase(Value
, "DeriveLF", FormatStyle::LE_DeriveLF
);
450 IO
.enumCase(Value
, "DeriveCRLF", FormatStyle::LE_DeriveCRLF
);
455 struct ScalarEnumerationTraits
<FormatStyle::NamespaceIndentationKind
> {
456 static void enumeration(IO
&IO
,
457 FormatStyle::NamespaceIndentationKind
&Value
) {
458 IO
.enumCase(Value
, "None", FormatStyle::NI_None
);
459 IO
.enumCase(Value
, "Inner", FormatStyle::NI_Inner
);
460 IO
.enumCase(Value
, "All", FormatStyle::NI_All
);
464 template <> struct ScalarEnumerationTraits
<FormatStyle::OperandAlignmentStyle
> {
465 static void enumeration(IO
&IO
, FormatStyle::OperandAlignmentStyle
&Value
) {
466 IO
.enumCase(Value
, "DontAlign", FormatStyle::OAS_DontAlign
);
467 IO
.enumCase(Value
, "Align", FormatStyle::OAS_Align
);
468 IO
.enumCase(Value
, "AlignAfterOperator",
469 FormatStyle::OAS_AlignAfterOperator
);
471 // For backward compatibility.
472 IO
.enumCase(Value
, "true", FormatStyle::OAS_Align
);
473 IO
.enumCase(Value
, "false", FormatStyle::OAS_DontAlign
);
478 struct ScalarEnumerationTraits
<FormatStyle::PackConstructorInitializersStyle
> {
480 enumeration(IO
&IO
, FormatStyle::PackConstructorInitializersStyle
&Value
) {
481 IO
.enumCase(Value
, "Never", FormatStyle::PCIS_Never
);
482 IO
.enumCase(Value
, "BinPack", FormatStyle::PCIS_BinPack
);
483 IO
.enumCase(Value
, "CurrentLine", FormatStyle::PCIS_CurrentLine
);
484 IO
.enumCase(Value
, "NextLine", FormatStyle::PCIS_NextLine
);
485 IO
.enumCase(Value
, "NextLineOnly", FormatStyle::PCIS_NextLineOnly
);
489 template <> struct ScalarEnumerationTraits
<FormatStyle::PointerAlignmentStyle
> {
490 static void enumeration(IO
&IO
, FormatStyle::PointerAlignmentStyle
&Value
) {
491 IO
.enumCase(Value
, "Middle", FormatStyle::PAS_Middle
);
492 IO
.enumCase(Value
, "Left", FormatStyle::PAS_Left
);
493 IO
.enumCase(Value
, "Right", FormatStyle::PAS_Right
);
495 // For backward compatibility.
496 IO
.enumCase(Value
, "true", FormatStyle::PAS_Left
);
497 IO
.enumCase(Value
, "false", FormatStyle::PAS_Right
);
502 struct ScalarEnumerationTraits
<FormatStyle::PPDirectiveIndentStyle
> {
503 static void enumeration(IO
&IO
, FormatStyle::PPDirectiveIndentStyle
&Value
) {
504 IO
.enumCase(Value
, "None", FormatStyle::PPDIS_None
);
505 IO
.enumCase(Value
, "AfterHash", FormatStyle::PPDIS_AfterHash
);
506 IO
.enumCase(Value
, "BeforeHash", FormatStyle::PPDIS_BeforeHash
);
511 struct ScalarEnumerationTraits
<FormatStyle::QualifierAlignmentStyle
> {
512 static void enumeration(IO
&IO
, FormatStyle::QualifierAlignmentStyle
&Value
) {
513 IO
.enumCase(Value
, "Leave", FormatStyle::QAS_Leave
);
514 IO
.enumCase(Value
, "Left", FormatStyle::QAS_Left
);
515 IO
.enumCase(Value
, "Right", FormatStyle::QAS_Right
);
516 IO
.enumCase(Value
, "Custom", FormatStyle::QAS_Custom
);
520 template <> struct MappingTraits
<FormatStyle::RawStringFormat
> {
521 static void mapping(IO
&IO
, FormatStyle::RawStringFormat
&Format
) {
522 IO
.mapOptional("Language", Format
.Language
);
523 IO
.mapOptional("Delimiters", Format
.Delimiters
);
524 IO
.mapOptional("EnclosingFunctions", Format
.EnclosingFunctions
);
525 IO
.mapOptional("CanonicalDelimiter", Format
.CanonicalDelimiter
);
526 IO
.mapOptional("BasedOnStyle", Format
.BasedOnStyle
);
530 template <> struct ScalarEnumerationTraits
<FormatStyle::ReflowCommentsStyle
> {
531 static void enumeration(IO
&IO
, FormatStyle::ReflowCommentsStyle
&Value
) {
532 IO
.enumCase(Value
, "Never", FormatStyle::RCS_Never
);
533 IO
.enumCase(Value
, "IndentOnly", FormatStyle::RCS_IndentOnly
);
534 IO
.enumCase(Value
, "Always", FormatStyle::RCS_Always
);
535 // For backward compatibility:
536 IO
.enumCase(Value
, "false", FormatStyle::RCS_Never
);
537 IO
.enumCase(Value
, "true", FormatStyle::RCS_Always
);
542 struct ScalarEnumerationTraits
<FormatStyle::ReferenceAlignmentStyle
> {
543 static void enumeration(IO
&IO
, FormatStyle::ReferenceAlignmentStyle
&Value
) {
544 IO
.enumCase(Value
, "Pointer", FormatStyle::RAS_Pointer
);
545 IO
.enumCase(Value
, "Middle", FormatStyle::RAS_Middle
);
546 IO
.enumCase(Value
, "Left", FormatStyle::RAS_Left
);
547 IO
.enumCase(Value
, "Right", FormatStyle::RAS_Right
);
552 struct ScalarEnumerationTraits
<FormatStyle::RemoveParenthesesStyle
> {
553 static void enumeration(IO
&IO
, FormatStyle::RemoveParenthesesStyle
&Value
) {
554 IO
.enumCase(Value
, "Leave", FormatStyle::RPS_Leave
);
555 IO
.enumCase(Value
, "MultipleParentheses",
556 FormatStyle::RPS_MultipleParentheses
);
557 IO
.enumCase(Value
, "ReturnStatement", FormatStyle::RPS_ReturnStatement
);
562 struct ScalarEnumerationTraits
<FormatStyle::RequiresClausePositionStyle
> {
563 static void enumeration(IO
&IO
,
564 FormatStyle::RequiresClausePositionStyle
&Value
) {
565 IO
.enumCase(Value
, "OwnLine", FormatStyle::RCPS_OwnLine
);
566 IO
.enumCase(Value
, "OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace
);
567 IO
.enumCase(Value
, "WithPreceding", FormatStyle::RCPS_WithPreceding
);
568 IO
.enumCase(Value
, "WithFollowing", FormatStyle::RCPS_WithFollowing
);
569 IO
.enumCase(Value
, "SingleLine", FormatStyle::RCPS_SingleLine
);
574 struct ScalarEnumerationTraits
<FormatStyle::RequiresExpressionIndentationKind
> {
576 enumeration(IO
&IO
, FormatStyle::RequiresExpressionIndentationKind
&Value
) {
577 IO
.enumCase(Value
, "Keyword", FormatStyle::REI_Keyword
);
578 IO
.enumCase(Value
, "OuterScope", FormatStyle::REI_OuterScope
);
583 struct ScalarEnumerationTraits
<FormatStyle::ReturnTypeBreakingStyle
> {
584 static void enumeration(IO
&IO
, FormatStyle::ReturnTypeBreakingStyle
&Value
) {
585 IO
.enumCase(Value
, "None", FormatStyle::RTBS_None
);
586 IO
.enumCase(Value
, "Automatic", FormatStyle::RTBS_Automatic
);
587 IO
.enumCase(Value
, "ExceptShortType", FormatStyle::RTBS_ExceptShortType
);
588 IO
.enumCase(Value
, "All", FormatStyle::RTBS_All
);
589 IO
.enumCase(Value
, "TopLevel", FormatStyle::RTBS_TopLevel
);
590 IO
.enumCase(Value
, "TopLevelDefinitions",
591 FormatStyle::RTBS_TopLevelDefinitions
);
592 IO
.enumCase(Value
, "AllDefinitions", FormatStyle::RTBS_AllDefinitions
);
597 struct ScalarEnumerationTraits
<FormatStyle::SeparateDefinitionStyle
> {
598 static void enumeration(IO
&IO
, FormatStyle::SeparateDefinitionStyle
&Value
) {
599 IO
.enumCase(Value
, "Leave", FormatStyle::SDS_Leave
);
600 IO
.enumCase(Value
, "Always", FormatStyle::SDS_Always
);
601 IO
.enumCase(Value
, "Never", FormatStyle::SDS_Never
);
605 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortBlockStyle
> {
606 static void enumeration(IO
&IO
, FormatStyle::ShortBlockStyle
&Value
) {
607 IO
.enumCase(Value
, "Never", FormatStyle::SBS_Never
);
608 IO
.enumCase(Value
, "false", FormatStyle::SBS_Never
);
609 IO
.enumCase(Value
, "Always", FormatStyle::SBS_Always
);
610 IO
.enumCase(Value
, "true", FormatStyle::SBS_Always
);
611 IO
.enumCase(Value
, "Empty", FormatStyle::SBS_Empty
);
615 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortFunctionStyle
> {
616 static void enumeration(IO
&IO
, FormatStyle::ShortFunctionStyle
&Value
) {
617 IO
.enumCase(Value
, "None", FormatStyle::SFS_None
);
618 IO
.enumCase(Value
, "false", FormatStyle::SFS_None
);
619 IO
.enumCase(Value
, "All", FormatStyle::SFS_All
);
620 IO
.enumCase(Value
, "true", FormatStyle::SFS_All
);
621 IO
.enumCase(Value
, "Inline", FormatStyle::SFS_Inline
);
622 IO
.enumCase(Value
, "InlineOnly", FormatStyle::SFS_InlineOnly
);
623 IO
.enumCase(Value
, "Empty", FormatStyle::SFS_Empty
);
627 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortIfStyle
> {
628 static void enumeration(IO
&IO
, FormatStyle::ShortIfStyle
&Value
) {
629 IO
.enumCase(Value
, "Never", FormatStyle::SIS_Never
);
630 IO
.enumCase(Value
, "WithoutElse", FormatStyle::SIS_WithoutElse
);
631 IO
.enumCase(Value
, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf
);
632 IO
.enumCase(Value
, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse
);
634 // For backward compatibility.
635 IO
.enumCase(Value
, "Always", FormatStyle::SIS_OnlyFirstIf
);
636 IO
.enumCase(Value
, "false", FormatStyle::SIS_Never
);
637 IO
.enumCase(Value
, "true", FormatStyle::SIS_WithoutElse
);
641 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortLambdaStyle
> {
642 static void enumeration(IO
&IO
, FormatStyle::ShortLambdaStyle
&Value
) {
643 IO
.enumCase(Value
, "None", FormatStyle::SLS_None
);
644 IO
.enumCase(Value
, "false", FormatStyle::SLS_None
);
645 IO
.enumCase(Value
, "Empty", FormatStyle::SLS_Empty
);
646 IO
.enumCase(Value
, "Inline", FormatStyle::SLS_Inline
);
647 IO
.enumCase(Value
, "All", FormatStyle::SLS_All
);
648 IO
.enumCase(Value
, "true", FormatStyle::SLS_All
);
652 template <> struct ScalarEnumerationTraits
<FormatStyle::SortIncludesOptions
> {
653 static void enumeration(IO
&IO
, FormatStyle::SortIncludesOptions
&Value
) {
654 IO
.enumCase(Value
, "Never", FormatStyle::SI_Never
);
655 IO
.enumCase(Value
, "CaseInsensitive", FormatStyle::SI_CaseInsensitive
);
656 IO
.enumCase(Value
, "CaseSensitive", FormatStyle::SI_CaseSensitive
);
658 // For backward compatibility.
659 IO
.enumCase(Value
, "false", FormatStyle::SI_Never
);
660 IO
.enumCase(Value
, "true", FormatStyle::SI_CaseSensitive
);
665 struct ScalarEnumerationTraits
<FormatStyle::SortJavaStaticImportOptions
> {
666 static void enumeration(IO
&IO
,
667 FormatStyle::SortJavaStaticImportOptions
&Value
) {
668 IO
.enumCase(Value
, "Before", FormatStyle::SJSIO_Before
);
669 IO
.enumCase(Value
, "After", FormatStyle::SJSIO_After
);
674 struct ScalarEnumerationTraits
<FormatStyle::SortUsingDeclarationsOptions
> {
675 static void enumeration(IO
&IO
,
676 FormatStyle::SortUsingDeclarationsOptions
&Value
) {
677 IO
.enumCase(Value
, "Never", FormatStyle::SUD_Never
);
678 IO
.enumCase(Value
, "Lexicographic", FormatStyle::SUD_Lexicographic
);
679 IO
.enumCase(Value
, "LexicographicNumeric",
680 FormatStyle::SUD_LexicographicNumeric
);
682 // For backward compatibility.
683 IO
.enumCase(Value
, "false", FormatStyle::SUD_Never
);
684 IO
.enumCase(Value
, "true", FormatStyle::SUD_LexicographicNumeric
);
689 struct ScalarEnumerationTraits
<FormatStyle::SpaceAroundPointerQualifiersStyle
> {
691 enumeration(IO
&IO
, FormatStyle::SpaceAroundPointerQualifiersStyle
&Value
) {
692 IO
.enumCase(Value
, "Default", FormatStyle::SAPQ_Default
);
693 IO
.enumCase(Value
, "Before", FormatStyle::SAPQ_Before
);
694 IO
.enumCase(Value
, "After", FormatStyle::SAPQ_After
);
695 IO
.enumCase(Value
, "Both", FormatStyle::SAPQ_Both
);
699 template <> struct MappingTraits
<FormatStyle::SpaceBeforeParensCustom
> {
700 static void mapping(IO
&IO
, FormatStyle::SpaceBeforeParensCustom
&Spacing
) {
701 IO
.mapOptional("AfterControlStatements", Spacing
.AfterControlStatements
);
702 IO
.mapOptional("AfterForeachMacros", Spacing
.AfterForeachMacros
);
703 IO
.mapOptional("AfterFunctionDefinitionName",
704 Spacing
.AfterFunctionDefinitionName
);
705 IO
.mapOptional("AfterFunctionDeclarationName",
706 Spacing
.AfterFunctionDeclarationName
);
707 IO
.mapOptional("AfterIfMacros", Spacing
.AfterIfMacros
);
708 IO
.mapOptional("AfterOverloadedOperator", Spacing
.AfterOverloadedOperator
);
709 IO
.mapOptional("AfterPlacementOperator", Spacing
.AfterPlacementOperator
);
710 IO
.mapOptional("AfterRequiresInClause", Spacing
.AfterRequiresInClause
);
711 IO
.mapOptional("AfterRequiresInExpression",
712 Spacing
.AfterRequiresInExpression
);
713 IO
.mapOptional("BeforeNonEmptyParentheses",
714 Spacing
.BeforeNonEmptyParentheses
);
719 struct ScalarEnumerationTraits
<FormatStyle::SpaceBeforeParensStyle
> {
720 static void enumeration(IO
&IO
, FormatStyle::SpaceBeforeParensStyle
&Value
) {
721 IO
.enumCase(Value
, "Never", FormatStyle::SBPO_Never
);
722 IO
.enumCase(Value
, "ControlStatements",
723 FormatStyle::SBPO_ControlStatements
);
724 IO
.enumCase(Value
, "ControlStatementsExceptControlMacros",
725 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
726 IO
.enumCase(Value
, "NonEmptyParentheses",
727 FormatStyle::SBPO_NonEmptyParentheses
);
728 IO
.enumCase(Value
, "Always", FormatStyle::SBPO_Always
);
729 IO
.enumCase(Value
, "Custom", FormatStyle::SBPO_Custom
);
731 // For backward compatibility.
732 IO
.enumCase(Value
, "false", FormatStyle::SBPO_Never
);
733 IO
.enumCase(Value
, "true", FormatStyle::SBPO_ControlStatements
);
734 IO
.enumCase(Value
, "ControlStatementsExceptForEachMacros",
735 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
739 template <> struct ScalarEnumerationTraits
<FormatStyle::SpacesInAnglesStyle
> {
740 static void enumeration(IO
&IO
, FormatStyle::SpacesInAnglesStyle
&Value
) {
741 IO
.enumCase(Value
, "Never", FormatStyle::SIAS_Never
);
742 IO
.enumCase(Value
, "Always", FormatStyle::SIAS_Always
);
743 IO
.enumCase(Value
, "Leave", FormatStyle::SIAS_Leave
);
745 // For backward compatibility.
746 IO
.enumCase(Value
, "false", FormatStyle::SIAS_Never
);
747 IO
.enumCase(Value
, "true", FormatStyle::SIAS_Always
);
751 template <> struct MappingTraits
<FormatStyle::SpacesInLineComment
> {
752 static void mapping(IO
&IO
, FormatStyle::SpacesInLineComment
&Space
) {
753 // Transform the maximum to signed, to parse "-1" correctly
754 int signedMaximum
= static_cast<int>(Space
.Maximum
);
755 IO
.mapOptional("Minimum", Space
.Minimum
);
756 IO
.mapOptional("Maximum", signedMaximum
);
757 Space
.Maximum
= static_cast<unsigned>(signedMaximum
);
759 if (Space
.Maximum
!= -1u)
760 Space
.Minimum
= std::min(Space
.Minimum
, Space
.Maximum
);
764 template <> struct MappingTraits
<FormatStyle::SpacesInParensCustom
> {
765 static void mapping(IO
&IO
, FormatStyle::SpacesInParensCustom
&Spaces
) {
766 IO
.mapOptional("ExceptDoubleParentheses", Spaces
.ExceptDoubleParentheses
);
767 IO
.mapOptional("InCStyleCasts", Spaces
.InCStyleCasts
);
768 IO
.mapOptional("InConditionalStatements", Spaces
.InConditionalStatements
);
769 IO
.mapOptional("InEmptyParentheses", Spaces
.InEmptyParentheses
);
770 IO
.mapOptional("Other", Spaces
.Other
);
774 template <> struct ScalarEnumerationTraits
<FormatStyle::SpacesInParensStyle
> {
775 static void enumeration(IO
&IO
, FormatStyle::SpacesInParensStyle
&Value
) {
776 IO
.enumCase(Value
, "Never", FormatStyle::SIPO_Never
);
777 IO
.enumCase(Value
, "Custom", FormatStyle::SIPO_Custom
);
781 template <> struct ScalarEnumerationTraits
<FormatStyle::TrailingCommaStyle
> {
782 static void enumeration(IO
&IO
, FormatStyle::TrailingCommaStyle
&Value
) {
783 IO
.enumCase(Value
, "None", FormatStyle::TCS_None
);
784 IO
.enumCase(Value
, "Wrapped", FormatStyle::TCS_Wrapped
);
789 struct ScalarEnumerationTraits
<FormatStyle::TrailingCommentsAlignmentKinds
> {
790 static void enumeration(IO
&IO
,
791 FormatStyle::TrailingCommentsAlignmentKinds
&Value
) {
792 IO
.enumCase(Value
, "Leave", FormatStyle::TCAS_Leave
);
793 IO
.enumCase(Value
, "Always", FormatStyle::TCAS_Always
);
794 IO
.enumCase(Value
, "Never", FormatStyle::TCAS_Never
);
798 template <> struct MappingTraits
<FormatStyle::TrailingCommentsAlignmentStyle
> {
799 static void enumInput(IO
&IO
,
800 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
801 IO
.enumCase(Value
, "Leave",
802 FormatStyle::TrailingCommentsAlignmentStyle(
803 {FormatStyle::TCAS_Leave
, 0}));
805 IO
.enumCase(Value
, "Always",
806 FormatStyle::TrailingCommentsAlignmentStyle(
807 {FormatStyle::TCAS_Always
, 0}));
809 IO
.enumCase(Value
, "Never",
810 FormatStyle::TrailingCommentsAlignmentStyle(
811 {FormatStyle::TCAS_Never
, 0}));
813 // For backwards compatibility
814 IO
.enumCase(Value
, "true",
815 FormatStyle::TrailingCommentsAlignmentStyle(
816 {FormatStyle::TCAS_Always
, 0}));
817 IO
.enumCase(Value
, "false",
818 FormatStyle::TrailingCommentsAlignmentStyle(
819 {FormatStyle::TCAS_Never
, 0}));
822 static void mapping(IO
&IO
,
823 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
824 IO
.mapOptional("Kind", Value
.Kind
);
825 IO
.mapOptional("OverEmptyLines", Value
.OverEmptyLines
);
829 template <> struct ScalarEnumerationTraits
<FormatStyle::UseTabStyle
> {
830 static void enumeration(IO
&IO
, FormatStyle::UseTabStyle
&Value
) {
831 IO
.enumCase(Value
, "Never", FormatStyle::UT_Never
);
832 IO
.enumCase(Value
, "false", FormatStyle::UT_Never
);
833 IO
.enumCase(Value
, "Always", FormatStyle::UT_Always
);
834 IO
.enumCase(Value
, "true", FormatStyle::UT_Always
);
835 IO
.enumCase(Value
, "ForIndentation", FormatStyle::UT_ForIndentation
);
836 IO
.enumCase(Value
, "ForContinuationAndIndentation",
837 FormatStyle::UT_ForContinuationAndIndentation
);
838 IO
.enumCase(Value
, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces
);
842 template <> struct MappingTraits
<FormatStyle
> {
843 static void mapping(IO
&IO
, FormatStyle
&Style
) {
844 // When reading, read the language first, we need it for getPredefinedStyle.
845 IO
.mapOptional("Language", Style
.Language
);
847 StringRef BasedOnStyle
;
848 if (IO
.outputting()) {
849 StringRef Styles
[] = {"LLVM", "Google", "Chromium", "Mozilla",
850 "WebKit", "GNU", "Microsoft", "clang-format"};
851 for (StringRef StyleName
: Styles
) {
852 FormatStyle PredefinedStyle
;
853 if (getPredefinedStyle(StyleName
, Style
.Language
, &PredefinedStyle
) &&
854 Style
== PredefinedStyle
) {
855 BasedOnStyle
= StyleName
;
860 IO
.mapOptional("BasedOnStyle", BasedOnStyle
);
861 if (!BasedOnStyle
.empty()) {
862 FormatStyle::LanguageKind OldLanguage
= Style
.Language
;
863 FormatStyle::LanguageKind Language
=
864 ((FormatStyle
*)IO
.getContext())->Language
;
865 if (!getPredefinedStyle(BasedOnStyle
, Language
, &Style
)) {
866 IO
.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle
));
869 Style
.Language
= OldLanguage
;
873 // Initialize some variables used in the parsing. The using logic is at the
876 // For backward compatibility:
877 // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was
878 // false unless BasedOnStyle was Google or Chromium whereas that of
879 // AllowAllConstructorInitializersOnNextLine was always true, so the
880 // equivalent default value of PackConstructorInitializers is PCIS_NextLine
881 // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options
882 // had a non-default value while PackConstructorInitializers has a default
883 // value, set the latter to an equivalent non-default value if needed.
884 const bool IsGoogleOrChromium
= BasedOnStyle
.equals_insensitive("google") ||
885 BasedOnStyle
.equals_insensitive("chromium");
886 bool OnCurrentLine
= IsGoogleOrChromium
;
887 bool OnNextLine
= true;
889 bool BreakBeforeInheritanceComma
= false;
890 bool BreakConstructorInitializersBeforeComma
= false;
892 bool DeriveLineEnding
= true;
893 bool UseCRLF
= false;
895 bool SpaceInEmptyParentheses
= false;
896 bool SpacesInConditionalStatement
= false;
897 bool SpacesInCStyleCastParentheses
= false;
898 bool SpacesInParentheses
= false;
900 // For backward compatibility.
901 if (!IO
.outputting()) {
902 IO
.mapOptional("AlignEscapedNewlinesLeft", Style
.AlignEscapedNewlines
);
903 IO
.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine
);
904 IO
.mapOptional("AlwaysBreakAfterReturnType", Style
.BreakAfterReturnType
);
905 IO
.mapOptional("AlwaysBreakTemplateDeclarations",
906 Style
.BreakTemplateDeclarations
);
907 IO
.mapOptional("BreakBeforeInheritanceComma",
908 BreakBeforeInheritanceComma
);
909 IO
.mapOptional("BreakConstructorInitializersBeforeComma",
910 BreakConstructorInitializersBeforeComma
);
911 IO
.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
913 IO
.mapOptional("DeriveLineEnding", DeriveLineEnding
);
914 IO
.mapOptional("DerivePointerBinding", Style
.DerivePointerAlignment
);
915 IO
.mapOptional("KeepEmptyLinesAtEOF", Style
.KeepEmptyLines
.AtEndOfFile
);
916 IO
.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
917 Style
.KeepEmptyLines
.AtStartOfBlock
);
918 IO
.mapOptional("IndentFunctionDeclarationAfterType",
919 Style
.IndentWrappedFunctionNames
);
920 IO
.mapOptional("IndentRequires", Style
.IndentRequiresClause
);
921 IO
.mapOptional("PointerBindsToType", Style
.PointerAlignment
);
922 IO
.mapOptional("SpaceAfterControlStatementKeyword",
923 Style
.SpaceBeforeParens
);
924 IO
.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses
);
925 IO
.mapOptional("SpacesInConditionalStatement",
926 SpacesInConditionalStatement
);
927 IO
.mapOptional("SpacesInCStyleCastParentheses",
928 SpacesInCStyleCastParentheses
);
929 IO
.mapOptional("SpacesInParentheses", SpacesInParentheses
);
930 IO
.mapOptional("UseCRLF", UseCRLF
);
933 IO
.mapOptional("AccessModifierOffset", Style
.AccessModifierOffset
);
934 IO
.mapOptional("AlignAfterOpenBracket", Style
.AlignAfterOpenBracket
);
935 IO
.mapOptional("AlignArrayOfStructures", Style
.AlignArrayOfStructures
);
936 IO
.mapOptional("AlignConsecutiveAssignments",
937 Style
.AlignConsecutiveAssignments
);
938 IO
.mapOptional("AlignConsecutiveBitFields",
939 Style
.AlignConsecutiveBitFields
);
940 IO
.mapOptional("AlignConsecutiveDeclarations",
941 Style
.AlignConsecutiveDeclarations
);
942 IO
.mapOptional("AlignConsecutiveMacros", Style
.AlignConsecutiveMacros
);
943 IO
.mapOptional("AlignConsecutiveShortCaseStatements",
944 Style
.AlignConsecutiveShortCaseStatements
);
945 IO
.mapOptional("AlignConsecutiveTableGenBreakingDAGArgColons",
946 Style
.AlignConsecutiveTableGenBreakingDAGArgColons
);
947 IO
.mapOptional("AlignConsecutiveTableGenCondOperatorColons",
948 Style
.AlignConsecutiveTableGenCondOperatorColons
);
949 IO
.mapOptional("AlignConsecutiveTableGenDefinitionColons",
950 Style
.AlignConsecutiveTableGenDefinitionColons
);
951 IO
.mapOptional("AlignEscapedNewlines", Style
.AlignEscapedNewlines
);
952 IO
.mapOptional("AlignOperands", Style
.AlignOperands
);
953 IO
.mapOptional("AlignTrailingComments", Style
.AlignTrailingComments
);
954 IO
.mapOptional("AllowAllArgumentsOnNextLine",
955 Style
.AllowAllArgumentsOnNextLine
);
956 IO
.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
957 Style
.AllowAllParametersOfDeclarationOnNextLine
);
958 IO
.mapOptional("AllowBreakBeforeNoexceptSpecifier",
959 Style
.AllowBreakBeforeNoexceptSpecifier
);
960 IO
.mapOptional("AllowShortBlocksOnASingleLine",
961 Style
.AllowShortBlocksOnASingleLine
);
962 IO
.mapOptional("AllowShortCaseExpressionOnASingleLine",
963 Style
.AllowShortCaseExpressionOnASingleLine
);
964 IO
.mapOptional("AllowShortCaseLabelsOnASingleLine",
965 Style
.AllowShortCaseLabelsOnASingleLine
);
966 IO
.mapOptional("AllowShortCompoundRequirementOnASingleLine",
967 Style
.AllowShortCompoundRequirementOnASingleLine
);
968 IO
.mapOptional("AllowShortEnumsOnASingleLine",
969 Style
.AllowShortEnumsOnASingleLine
);
970 IO
.mapOptional("AllowShortFunctionsOnASingleLine",
971 Style
.AllowShortFunctionsOnASingleLine
);
972 IO
.mapOptional("AllowShortIfStatementsOnASingleLine",
973 Style
.AllowShortIfStatementsOnASingleLine
);
974 IO
.mapOptional("AllowShortLambdasOnASingleLine",
975 Style
.AllowShortLambdasOnASingleLine
);
976 IO
.mapOptional("AllowShortLoopsOnASingleLine",
977 Style
.AllowShortLoopsOnASingleLine
);
978 IO
.mapOptional("AlwaysBreakAfterDefinitionReturnType",
979 Style
.AlwaysBreakAfterDefinitionReturnType
);
980 IO
.mapOptional("AlwaysBreakBeforeMultilineStrings",
981 Style
.AlwaysBreakBeforeMultilineStrings
);
982 IO
.mapOptional("AttributeMacros", Style
.AttributeMacros
);
983 IO
.mapOptional("BinPackArguments", Style
.BinPackArguments
);
984 IO
.mapOptional("BinPackParameters", Style
.BinPackParameters
);
985 IO
.mapOptional("BitFieldColonSpacing", Style
.BitFieldColonSpacing
);
986 IO
.mapOptional("BracedInitializerIndentWidth",
987 Style
.BracedInitializerIndentWidth
);
988 IO
.mapOptional("BraceWrapping", Style
.BraceWrapping
);
989 IO
.mapOptional("BreakAdjacentStringLiterals",
990 Style
.BreakAdjacentStringLiterals
);
991 IO
.mapOptional("BreakAfterAttributes", Style
.BreakAfterAttributes
);
992 IO
.mapOptional("BreakAfterJavaFieldAnnotations",
993 Style
.BreakAfterJavaFieldAnnotations
);
994 IO
.mapOptional("BreakAfterReturnType", Style
.BreakAfterReturnType
);
995 IO
.mapOptional("BreakArrays", Style
.BreakArrays
);
996 IO
.mapOptional("BreakBeforeBinaryOperators",
997 Style
.BreakBeforeBinaryOperators
);
998 IO
.mapOptional("BreakBeforeConceptDeclarations",
999 Style
.BreakBeforeConceptDeclarations
);
1000 IO
.mapOptional("BreakBeforeBraces", Style
.BreakBeforeBraces
);
1001 IO
.mapOptional("BreakBeforeInlineASMColon",
1002 Style
.BreakBeforeInlineASMColon
);
1003 IO
.mapOptional("BreakBeforeTernaryOperators",
1004 Style
.BreakBeforeTernaryOperators
);
1005 IO
.mapOptional("BreakBinaryOperations", Style
.BreakBinaryOperations
);
1006 IO
.mapOptional("BreakConstructorInitializers",
1007 Style
.BreakConstructorInitializers
);
1008 IO
.mapOptional("BreakFunctionDefinitionParameters",
1009 Style
.BreakFunctionDefinitionParameters
);
1010 IO
.mapOptional("BreakInheritanceList", Style
.BreakInheritanceList
);
1011 IO
.mapOptional("BreakStringLiterals", Style
.BreakStringLiterals
);
1012 IO
.mapOptional("BreakTemplateDeclarations",
1013 Style
.BreakTemplateDeclarations
);
1014 IO
.mapOptional("ColumnLimit", Style
.ColumnLimit
);
1015 IO
.mapOptional("CommentPragmas", Style
.CommentPragmas
);
1016 IO
.mapOptional("CompactNamespaces", Style
.CompactNamespaces
);
1017 IO
.mapOptional("ConstructorInitializerIndentWidth",
1018 Style
.ConstructorInitializerIndentWidth
);
1019 IO
.mapOptional("ContinuationIndentWidth", Style
.ContinuationIndentWidth
);
1020 IO
.mapOptional("Cpp11BracedListStyle", Style
.Cpp11BracedListStyle
);
1021 IO
.mapOptional("DerivePointerAlignment", Style
.DerivePointerAlignment
);
1022 IO
.mapOptional("DisableFormat", Style
.DisableFormat
);
1023 IO
.mapOptional("EmptyLineAfterAccessModifier",
1024 Style
.EmptyLineAfterAccessModifier
);
1025 IO
.mapOptional("EmptyLineBeforeAccessModifier",
1026 Style
.EmptyLineBeforeAccessModifier
);
1027 IO
.mapOptional("ExperimentalAutoDetectBinPacking",
1028 Style
.ExperimentalAutoDetectBinPacking
);
1029 IO
.mapOptional("FixNamespaceComments", Style
.FixNamespaceComments
);
1030 IO
.mapOptional("ForEachMacros", Style
.ForEachMacros
);
1031 IO
.mapOptional("IfMacros", Style
.IfMacros
);
1032 IO
.mapOptional("IncludeBlocks", Style
.IncludeStyle
.IncludeBlocks
);
1033 IO
.mapOptional("IncludeCategories", Style
.IncludeStyle
.IncludeCategories
);
1034 IO
.mapOptional("IncludeIsMainRegex", Style
.IncludeStyle
.IncludeIsMainRegex
);
1035 IO
.mapOptional("IncludeIsMainSourceRegex",
1036 Style
.IncludeStyle
.IncludeIsMainSourceRegex
);
1037 IO
.mapOptional("IndentAccessModifiers", Style
.IndentAccessModifiers
);
1038 IO
.mapOptional("IndentCaseBlocks", Style
.IndentCaseBlocks
);
1039 IO
.mapOptional("IndentCaseLabels", Style
.IndentCaseLabels
);
1040 IO
.mapOptional("IndentExternBlock", Style
.IndentExternBlock
);
1041 IO
.mapOptional("IndentGotoLabels", Style
.IndentGotoLabels
);
1042 IO
.mapOptional("IndentPPDirectives", Style
.IndentPPDirectives
);
1043 IO
.mapOptional("IndentRequiresClause", Style
.IndentRequiresClause
);
1044 IO
.mapOptional("IndentWidth", Style
.IndentWidth
);
1045 IO
.mapOptional("IndentWrappedFunctionNames",
1046 Style
.IndentWrappedFunctionNames
);
1047 IO
.mapOptional("InsertBraces", Style
.InsertBraces
);
1048 IO
.mapOptional("InsertNewlineAtEOF", Style
.InsertNewlineAtEOF
);
1049 IO
.mapOptional("InsertTrailingCommas", Style
.InsertTrailingCommas
);
1050 IO
.mapOptional("IntegerLiteralSeparator", Style
.IntegerLiteralSeparator
);
1051 IO
.mapOptional("JavaImportGroups", Style
.JavaImportGroups
);
1052 IO
.mapOptional("JavaScriptQuotes", Style
.JavaScriptQuotes
);
1053 IO
.mapOptional("JavaScriptWrapImports", Style
.JavaScriptWrapImports
);
1054 IO
.mapOptional("KeepEmptyLines", Style
.KeepEmptyLines
);
1055 IO
.mapOptional("KeepFormFeed", Style
.KeepFormFeed
);
1056 IO
.mapOptional("LambdaBodyIndentation", Style
.LambdaBodyIndentation
);
1057 IO
.mapOptional("LineEnding", Style
.LineEnding
);
1058 IO
.mapOptional("MacroBlockBegin", Style
.MacroBlockBegin
);
1059 IO
.mapOptional("MacroBlockEnd", Style
.MacroBlockEnd
);
1060 IO
.mapOptional("Macros", Style
.Macros
);
1061 IO
.mapOptional("MainIncludeChar", Style
.IncludeStyle
.MainIncludeChar
);
1062 IO
.mapOptional("MaxEmptyLinesToKeep", Style
.MaxEmptyLinesToKeep
);
1063 IO
.mapOptional("NamespaceIndentation", Style
.NamespaceIndentation
);
1064 IO
.mapOptional("NamespaceMacros", Style
.NamespaceMacros
);
1065 IO
.mapOptional("ObjCBinPackProtocolList", Style
.ObjCBinPackProtocolList
);
1066 IO
.mapOptional("ObjCBlockIndentWidth", Style
.ObjCBlockIndentWidth
);
1067 IO
.mapOptional("ObjCBreakBeforeNestedBlockParam",
1068 Style
.ObjCBreakBeforeNestedBlockParam
);
1069 IO
.mapOptional("ObjCPropertyAttributeOrder",
1070 Style
.ObjCPropertyAttributeOrder
);
1071 IO
.mapOptional("ObjCSpaceAfterProperty", Style
.ObjCSpaceAfterProperty
);
1072 IO
.mapOptional("ObjCSpaceBeforeProtocolList",
1073 Style
.ObjCSpaceBeforeProtocolList
);
1074 IO
.mapOptional("PackConstructorInitializers",
1075 Style
.PackConstructorInitializers
);
1076 IO
.mapOptional("PenaltyBreakAssignment", Style
.PenaltyBreakAssignment
);
1077 IO
.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1078 Style
.PenaltyBreakBeforeFirstCallParameter
);
1079 IO
.mapOptional("PenaltyBreakComment", Style
.PenaltyBreakComment
);
1080 IO
.mapOptional("PenaltyBreakFirstLessLess",
1081 Style
.PenaltyBreakFirstLessLess
);
1082 IO
.mapOptional("PenaltyBreakOpenParenthesis",
1083 Style
.PenaltyBreakOpenParenthesis
);
1084 IO
.mapOptional("PenaltyBreakScopeResolution",
1085 Style
.PenaltyBreakScopeResolution
);
1086 IO
.mapOptional("PenaltyBreakString", Style
.PenaltyBreakString
);
1087 IO
.mapOptional("PenaltyBreakTemplateDeclaration",
1088 Style
.PenaltyBreakTemplateDeclaration
);
1089 IO
.mapOptional("PenaltyExcessCharacter", Style
.PenaltyExcessCharacter
);
1090 IO
.mapOptional("PenaltyIndentedWhitespace",
1091 Style
.PenaltyIndentedWhitespace
);
1092 IO
.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1093 Style
.PenaltyReturnTypeOnItsOwnLine
);
1094 IO
.mapOptional("PointerAlignment", Style
.PointerAlignment
);
1095 IO
.mapOptional("PPIndentWidth", Style
.PPIndentWidth
);
1096 IO
.mapOptional("QualifierAlignment", Style
.QualifierAlignment
);
1097 // Default Order for Left/Right based Qualifier alignment.
1098 if (Style
.QualifierAlignment
== FormatStyle::QAS_Right
)
1099 Style
.QualifierOrder
= {"type", "const", "volatile"};
1100 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Left
)
1101 Style
.QualifierOrder
= {"const", "volatile", "type"};
1102 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Custom
)
1103 IO
.mapOptional("QualifierOrder", Style
.QualifierOrder
);
1104 IO
.mapOptional("RawStringFormats", Style
.RawStringFormats
);
1105 IO
.mapOptional("ReferenceAlignment", Style
.ReferenceAlignment
);
1106 IO
.mapOptional("ReflowComments", Style
.ReflowComments
);
1107 IO
.mapOptional("RemoveBracesLLVM", Style
.RemoveBracesLLVM
);
1108 IO
.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1109 Style
.RemoveEmptyLinesInUnwrappedLines
);
1110 IO
.mapOptional("RemoveParentheses", Style
.RemoveParentheses
);
1111 IO
.mapOptional("RemoveSemicolon", Style
.RemoveSemicolon
);
1112 IO
.mapOptional("RequiresClausePosition", Style
.RequiresClausePosition
);
1113 IO
.mapOptional("RequiresExpressionIndentation",
1114 Style
.RequiresExpressionIndentation
);
1115 IO
.mapOptional("SeparateDefinitionBlocks", Style
.SeparateDefinitionBlocks
);
1116 IO
.mapOptional("ShortNamespaceLines", Style
.ShortNamespaceLines
);
1117 IO
.mapOptional("SkipMacroDefinitionBody", Style
.SkipMacroDefinitionBody
);
1118 IO
.mapOptional("SortIncludes", Style
.SortIncludes
);
1119 IO
.mapOptional("SortJavaStaticImport", Style
.SortJavaStaticImport
);
1120 IO
.mapOptional("SortUsingDeclarations", Style
.SortUsingDeclarations
);
1121 IO
.mapOptional("SpaceAfterCStyleCast", Style
.SpaceAfterCStyleCast
);
1122 IO
.mapOptional("SpaceAfterLogicalNot", Style
.SpaceAfterLogicalNot
);
1123 IO
.mapOptional("SpaceAfterTemplateKeyword",
1124 Style
.SpaceAfterTemplateKeyword
);
1125 IO
.mapOptional("SpaceAroundPointerQualifiers",
1126 Style
.SpaceAroundPointerQualifiers
);
1127 IO
.mapOptional("SpaceBeforeAssignmentOperators",
1128 Style
.SpaceBeforeAssignmentOperators
);
1129 IO
.mapOptional("SpaceBeforeCaseColon", Style
.SpaceBeforeCaseColon
);
1130 IO
.mapOptional("SpaceBeforeCpp11BracedList",
1131 Style
.SpaceBeforeCpp11BracedList
);
1132 IO
.mapOptional("SpaceBeforeCtorInitializerColon",
1133 Style
.SpaceBeforeCtorInitializerColon
);
1134 IO
.mapOptional("SpaceBeforeInheritanceColon",
1135 Style
.SpaceBeforeInheritanceColon
);
1136 IO
.mapOptional("SpaceBeforeJsonColon", Style
.SpaceBeforeJsonColon
);
1137 IO
.mapOptional("SpaceBeforeParens", Style
.SpaceBeforeParens
);
1138 IO
.mapOptional("SpaceBeforeParensOptions", Style
.SpaceBeforeParensOptions
);
1139 IO
.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1140 Style
.SpaceBeforeRangeBasedForLoopColon
);
1141 IO
.mapOptional("SpaceBeforeSquareBrackets",
1142 Style
.SpaceBeforeSquareBrackets
);
1143 IO
.mapOptional("SpaceInEmptyBlock", Style
.SpaceInEmptyBlock
);
1144 IO
.mapOptional("SpacesBeforeTrailingComments",
1145 Style
.SpacesBeforeTrailingComments
);
1146 IO
.mapOptional("SpacesInAngles", Style
.SpacesInAngles
);
1147 IO
.mapOptional("SpacesInContainerLiterals",
1148 Style
.SpacesInContainerLiterals
);
1149 IO
.mapOptional("SpacesInLineCommentPrefix",
1150 Style
.SpacesInLineCommentPrefix
);
1151 IO
.mapOptional("SpacesInParens", Style
.SpacesInParens
);
1152 IO
.mapOptional("SpacesInParensOptions", Style
.SpacesInParensOptions
);
1153 IO
.mapOptional("SpacesInSquareBrackets", Style
.SpacesInSquareBrackets
);
1154 IO
.mapOptional("Standard", Style
.Standard
);
1155 IO
.mapOptional("StatementAttributeLikeMacros",
1156 Style
.StatementAttributeLikeMacros
);
1157 IO
.mapOptional("StatementMacros", Style
.StatementMacros
);
1158 IO
.mapOptional("TableGenBreakingDAGArgOperators",
1159 Style
.TableGenBreakingDAGArgOperators
);
1160 IO
.mapOptional("TableGenBreakInsideDAGArg",
1161 Style
.TableGenBreakInsideDAGArg
);
1162 IO
.mapOptional("TabWidth", Style
.TabWidth
);
1163 IO
.mapOptional("TemplateNames", Style
.TemplateNames
);
1164 IO
.mapOptional("TypeNames", Style
.TypeNames
);
1165 IO
.mapOptional("TypenameMacros", Style
.TypenameMacros
);
1166 IO
.mapOptional("UseTab", Style
.UseTab
);
1167 IO
.mapOptional("VerilogBreakBetweenInstancePorts",
1168 Style
.VerilogBreakBetweenInstancePorts
);
1169 IO
.mapOptional("WhitespaceSensitiveMacros",
1170 Style
.WhitespaceSensitiveMacros
);
1172 // If AlwaysBreakAfterDefinitionReturnType was specified but
1173 // BreakAfterReturnType was not, initialize the latter from the former for
1174 // backwards compatibility.
1175 if (Style
.AlwaysBreakAfterDefinitionReturnType
!= FormatStyle::DRTBS_None
&&
1176 Style
.BreakAfterReturnType
== FormatStyle::RTBS_None
) {
1177 if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1178 FormatStyle::DRTBS_All
) {
1179 Style
.BreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1180 } else if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1181 FormatStyle::DRTBS_TopLevel
) {
1182 Style
.BreakAfterReturnType
= FormatStyle::RTBS_TopLevelDefinitions
;
1186 // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1187 // not, initialize the latter from the former for backwards compatibility.
1188 if (BreakBeforeInheritanceComma
&&
1189 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeColon
) {
1190 Style
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1193 // If BreakConstructorInitializersBeforeComma was specified but
1194 // BreakConstructorInitializers was not, initialize the latter from the
1195 // former for backwards compatibility.
1196 if (BreakConstructorInitializersBeforeComma
&&
1197 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
) {
1198 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1201 if (!IsGoogleOrChromium
) {
1202 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_BinPack
&&
1204 Style
.PackConstructorInitializers
= OnNextLine
1205 ? FormatStyle::PCIS_NextLine
1206 : FormatStyle::PCIS_CurrentLine
;
1208 } else if (Style
.PackConstructorInitializers
==
1209 FormatStyle::PCIS_NextLine
) {
1211 Style
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1212 else if (!OnNextLine
)
1213 Style
.PackConstructorInitializers
= FormatStyle::PCIS_CurrentLine
;
1216 if (Style
.LineEnding
== FormatStyle::LE_DeriveLF
) {
1217 if (!DeriveLineEnding
)
1218 Style
.LineEnding
= UseCRLF
? FormatStyle::LE_CRLF
: FormatStyle::LE_LF
;
1220 Style
.LineEnding
= FormatStyle::LE_DeriveCRLF
;
1223 if (Style
.SpacesInParens
!= FormatStyle::SIPO_Custom
&&
1224 (SpacesInParentheses
|| SpaceInEmptyParentheses
||
1225 SpacesInConditionalStatement
|| SpacesInCStyleCastParentheses
)) {
1226 if (SpacesInParentheses
) {
1227 // For backward compatibility.
1228 Style
.SpacesInParensOptions
.ExceptDoubleParentheses
= false;
1229 Style
.SpacesInParensOptions
.InConditionalStatements
= true;
1230 Style
.SpacesInParensOptions
.InCStyleCasts
=
1231 SpacesInCStyleCastParentheses
;
1232 Style
.SpacesInParensOptions
.InEmptyParentheses
=
1233 SpaceInEmptyParentheses
;
1234 Style
.SpacesInParensOptions
.Other
= true;
1236 Style
.SpacesInParensOptions
= {};
1237 Style
.SpacesInParensOptions
.InConditionalStatements
=
1238 SpacesInConditionalStatement
;
1239 Style
.SpacesInParensOptions
.InCStyleCasts
=
1240 SpacesInCStyleCastParentheses
;
1241 Style
.SpacesInParensOptions
.InEmptyParentheses
=
1242 SpaceInEmptyParentheses
;
1244 Style
.SpacesInParens
= FormatStyle::SIPO_Custom
;
1249 // Allows to read vector<FormatStyle> while keeping default values.
1250 // IO.getContext() should contain a pointer to the FormatStyle structure, that
1251 // will be used to get default values for missing keys.
1252 // If the first element has no Language specified, it will be treated as the
1253 // default one for the following elements.
1254 template <> struct DocumentListTraits
<std::vector
<FormatStyle
>> {
1255 static size_t size(IO
&IO
, std::vector
<FormatStyle
> &Seq
) {
1258 static FormatStyle
&element(IO
&IO
, std::vector
<FormatStyle
> &Seq
,
1260 if (Index
>= Seq
.size()) {
1261 assert(Index
== Seq
.size());
1262 FormatStyle Template
;
1263 if (!Seq
.empty() && Seq
[0].Language
== FormatStyle::LK_None
) {
1266 Template
= *((const FormatStyle
*)IO
.getContext());
1267 Template
.Language
= FormatStyle::LK_None
;
1269 Seq
.resize(Index
+ 1, Template
);
1280 const std::error_category
&getParseCategory() {
1281 static const ParseErrorCategory C
{};
1284 std::error_code
make_error_code(ParseError e
) {
1285 return std::error_code(static_cast<int>(e
), getParseCategory());
1288 inline llvm::Error
make_string_error(const Twine
&Message
) {
1289 return llvm::make_error
<llvm::StringError
>(Message
,
1290 llvm::inconvertibleErrorCode());
1293 const char *ParseErrorCategory::name() const noexcept
{
1294 return "clang-format.parse_error";
1297 std::string
ParseErrorCategory::message(int EV
) const {
1298 switch (static_cast<ParseError
>(EV
)) {
1299 case ParseError::Success
:
1301 case ParseError::Error
:
1302 return "Invalid argument";
1303 case ParseError::Unsuitable
:
1304 return "Unsuitable";
1305 case ParseError::BinPackTrailingCommaConflict
:
1306 return "trailing comma insertion cannot be used with bin packing";
1307 case ParseError::InvalidQualifierSpecified
:
1308 return "Invalid qualifier specified in QualifierOrder";
1309 case ParseError::DuplicateQualifierSpecified
:
1310 return "Duplicate qualifier specified in QualifierOrder";
1311 case ParseError::MissingQualifierType
:
1312 return "Missing type in QualifierOrder";
1313 case ParseError::MissingQualifierOrder
:
1314 return "Missing QualifierOrder";
1316 llvm_unreachable("unexpected parse error");
1319 static void expandPresetsBraceWrapping(FormatStyle
&Expanded
) {
1320 if (Expanded
.BreakBeforeBraces
== FormatStyle::BS_Custom
)
1322 Expanded
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1323 /*AfterClass=*/false,
1324 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1325 /*AfterEnum=*/false,
1326 /*AfterFunction=*/false,
1327 /*AfterNamespace=*/false,
1328 /*AfterObjCDeclaration=*/false,
1329 /*AfterStruct=*/false,
1330 /*AfterUnion=*/false,
1331 /*AfterExternBlock=*/false,
1332 /*BeforeCatch=*/false,
1333 /*BeforeElse=*/false,
1334 /*BeforeLambdaBody=*/false,
1335 /*BeforeWhile=*/false,
1336 /*IndentBraces=*/false,
1337 /*SplitEmptyFunction=*/true,
1338 /*SplitEmptyRecord=*/true,
1339 /*SplitEmptyNamespace=*/true};
1340 switch (Expanded
.BreakBeforeBraces
) {
1341 case FormatStyle::BS_Linux
:
1342 Expanded
.BraceWrapping
.AfterClass
= true;
1343 Expanded
.BraceWrapping
.AfterFunction
= true;
1344 Expanded
.BraceWrapping
.AfterNamespace
= true;
1346 case FormatStyle::BS_Mozilla
:
1347 Expanded
.BraceWrapping
.AfterClass
= true;
1348 Expanded
.BraceWrapping
.AfterEnum
= true;
1349 Expanded
.BraceWrapping
.AfterFunction
= true;
1350 Expanded
.BraceWrapping
.AfterStruct
= true;
1351 Expanded
.BraceWrapping
.AfterUnion
= true;
1352 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1353 Expanded
.BraceWrapping
.SplitEmptyFunction
= true;
1354 Expanded
.BraceWrapping
.SplitEmptyRecord
= false;
1356 case FormatStyle::BS_Stroustrup
:
1357 Expanded
.BraceWrapping
.AfterFunction
= true;
1358 Expanded
.BraceWrapping
.BeforeCatch
= true;
1359 Expanded
.BraceWrapping
.BeforeElse
= true;
1361 case FormatStyle::BS_Allman
:
1362 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1363 Expanded
.BraceWrapping
.AfterClass
= true;
1364 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1365 Expanded
.BraceWrapping
.AfterEnum
= true;
1366 Expanded
.BraceWrapping
.AfterFunction
= true;
1367 Expanded
.BraceWrapping
.AfterNamespace
= true;
1368 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1369 Expanded
.BraceWrapping
.AfterStruct
= true;
1370 Expanded
.BraceWrapping
.AfterUnion
= true;
1371 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1372 Expanded
.BraceWrapping
.BeforeCatch
= true;
1373 Expanded
.BraceWrapping
.BeforeElse
= true;
1374 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1376 case FormatStyle::BS_Whitesmiths
:
1377 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1378 Expanded
.BraceWrapping
.AfterClass
= true;
1379 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1380 Expanded
.BraceWrapping
.AfterEnum
= true;
1381 Expanded
.BraceWrapping
.AfterFunction
= true;
1382 Expanded
.BraceWrapping
.AfterNamespace
= true;
1383 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1384 Expanded
.BraceWrapping
.AfterStruct
= true;
1385 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1386 Expanded
.BraceWrapping
.BeforeCatch
= true;
1387 Expanded
.BraceWrapping
.BeforeElse
= true;
1388 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1390 case FormatStyle::BS_GNU
:
1391 Expanded
.BraceWrapping
= {
1392 /*AfterCaseLabel=*/true,
1393 /*AfterClass=*/true,
1394 /*AfterControlStatement=*/FormatStyle::BWACS_Always
,
1396 /*AfterFunction=*/true,
1397 /*AfterNamespace=*/true,
1398 /*AfterObjCDeclaration=*/true,
1399 /*AfterStruct=*/true,
1400 /*AfterUnion=*/true,
1401 /*AfterExternBlock=*/true,
1402 /*BeforeCatch=*/true,
1403 /*BeforeElse=*/true,
1404 /*BeforeLambdaBody=*/false,
1405 /*BeforeWhile=*/true,
1406 /*IndentBraces=*/true,
1407 /*SplitEmptyFunction=*/true,
1408 /*SplitEmptyRecord=*/true,
1409 /*SplitEmptyNamespace=*/true};
1411 case FormatStyle::BS_WebKit
:
1412 Expanded
.BraceWrapping
.AfterFunction
= true;
1419 static void expandPresetsSpaceBeforeParens(FormatStyle
&Expanded
) {
1420 if (Expanded
.SpaceBeforeParens
== FormatStyle::SBPO_Custom
)
1423 Expanded
.SpaceBeforeParensOptions
= {};
1424 Expanded
.SpaceBeforeParensOptions
.AfterPlacementOperator
= true;
1426 switch (Expanded
.SpaceBeforeParens
) {
1427 case FormatStyle::SBPO_ControlStatements
:
1428 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1429 Expanded
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1430 Expanded
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1432 case FormatStyle::SBPO_ControlStatementsExceptControlMacros
:
1433 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1435 case FormatStyle::SBPO_NonEmptyParentheses
:
1436 Expanded
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
= true;
1443 static void expandPresetsSpacesInParens(FormatStyle
&Expanded
) {
1444 if (Expanded
.SpacesInParens
== FormatStyle::SIPO_Custom
)
1446 assert(Expanded
.SpacesInParens
== FormatStyle::SIPO_Never
);
1448 Expanded
.SpacesInParensOptions
= {};
1451 FormatStyle
getLLVMStyle(FormatStyle::LanguageKind Language
) {
1452 FormatStyle LLVMStyle
;
1453 LLVMStyle
.AccessModifierOffset
= -2;
1454 LLVMStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_Align
;
1455 LLVMStyle
.AlignArrayOfStructures
= FormatStyle::AIAS_None
;
1456 LLVMStyle
.AlignConsecutiveAssignments
= {};
1457 LLVMStyle
.AlignConsecutiveAssignments
.PadOperators
= true;
1458 LLVMStyle
.AlignConsecutiveBitFields
= {};
1459 LLVMStyle
.AlignConsecutiveDeclarations
= {};
1460 LLVMStyle
.AlignConsecutiveDeclarations
.AlignFunctionDeclarations
= true;
1461 LLVMStyle
.AlignConsecutiveMacros
= {};
1462 LLVMStyle
.AlignConsecutiveShortCaseStatements
= {};
1463 LLVMStyle
.AlignConsecutiveTableGenBreakingDAGArgColons
= {};
1464 LLVMStyle
.AlignConsecutiveTableGenCondOperatorColons
= {};
1465 LLVMStyle
.AlignConsecutiveTableGenDefinitionColons
= {};
1466 LLVMStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Right
;
1467 LLVMStyle
.AlignOperands
= FormatStyle::OAS_Align
;
1468 LLVMStyle
.AlignTrailingComments
= {};
1469 LLVMStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Always
;
1470 LLVMStyle
.AlignTrailingComments
.OverEmptyLines
= 0;
1471 LLVMStyle
.AllowAllArgumentsOnNextLine
= true;
1472 LLVMStyle
.AllowAllParametersOfDeclarationOnNextLine
= true;
1473 LLVMStyle
.AllowBreakBeforeNoexceptSpecifier
= FormatStyle::BBNSS_Never
;
1474 LLVMStyle
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Never
;
1475 LLVMStyle
.AllowShortCaseExpressionOnASingleLine
= true;
1476 LLVMStyle
.AllowShortCaseLabelsOnASingleLine
= false;
1477 LLVMStyle
.AllowShortCompoundRequirementOnASingleLine
= true;
1478 LLVMStyle
.AllowShortEnumsOnASingleLine
= true;
1479 LLVMStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_All
;
1480 LLVMStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1481 LLVMStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_All
;
1482 LLVMStyle
.AllowShortLoopsOnASingleLine
= false;
1483 LLVMStyle
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1484 LLVMStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1485 LLVMStyle
.AttributeMacros
.push_back("__capability");
1486 LLVMStyle
.BinPackArguments
= true;
1487 LLVMStyle
.BinPackParameters
= FormatStyle::BPPS_BinPack
;
1488 LLVMStyle
.BitFieldColonSpacing
= FormatStyle::BFCS_Both
;
1489 LLVMStyle
.BracedInitializerIndentWidth
= std::nullopt
;
1490 LLVMStyle
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1491 /*AfterClass=*/false,
1492 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1493 /*AfterEnum=*/false,
1494 /*AfterFunction=*/false,
1495 /*AfterNamespace=*/false,
1496 /*AfterObjCDeclaration=*/false,
1497 /*AfterStruct=*/false,
1498 /*AfterUnion=*/false,
1499 /*AfterExternBlock=*/false,
1500 /*BeforeCatch=*/false,
1501 /*BeforeElse=*/false,
1502 /*BeforeLambdaBody=*/false,
1503 /*BeforeWhile=*/false,
1504 /*IndentBraces=*/false,
1505 /*SplitEmptyFunction=*/true,
1506 /*SplitEmptyRecord=*/true,
1507 /*SplitEmptyNamespace=*/true};
1508 LLVMStyle
.BreakAdjacentStringLiterals
= true;
1509 LLVMStyle
.BreakAfterAttributes
= FormatStyle::ABS_Leave
;
1510 LLVMStyle
.BreakAfterJavaFieldAnnotations
= false;
1511 LLVMStyle
.BreakAfterReturnType
= FormatStyle::RTBS_None
;
1512 LLVMStyle
.BreakArrays
= true;
1513 LLVMStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_None
;
1514 LLVMStyle
.BreakBeforeBraces
= FormatStyle::BS_Attach
;
1515 LLVMStyle
.BreakBeforeConceptDeclarations
= FormatStyle::BBCDS_Always
;
1516 LLVMStyle
.BreakBeforeInlineASMColon
= FormatStyle::BBIAS_OnlyMultiline
;
1517 LLVMStyle
.BreakBeforeTernaryOperators
= true;
1518 LLVMStyle
.BreakBinaryOperations
= FormatStyle::BBO_Never
;
1519 LLVMStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeColon
;
1520 LLVMStyle
.BreakFunctionDefinitionParameters
= false;
1521 LLVMStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeColon
;
1522 LLVMStyle
.BreakStringLiterals
= true;
1523 LLVMStyle
.BreakTemplateDeclarations
= FormatStyle::BTDS_MultiLine
;
1524 LLVMStyle
.ColumnLimit
= 80;
1525 LLVMStyle
.CommentPragmas
= "^ IWYU pragma:";
1526 LLVMStyle
.CompactNamespaces
= false;
1527 LLVMStyle
.ConstructorInitializerIndentWidth
= 4;
1528 LLVMStyle
.ContinuationIndentWidth
= 4;
1529 LLVMStyle
.Cpp11BracedListStyle
= true;
1530 LLVMStyle
.DerivePointerAlignment
= false;
1531 LLVMStyle
.DisableFormat
= false;
1532 LLVMStyle
.EmptyLineAfterAccessModifier
= FormatStyle::ELAAMS_Never
;
1533 LLVMStyle
.EmptyLineBeforeAccessModifier
= FormatStyle::ELBAMS_LogicalBlock
;
1534 LLVMStyle
.ExperimentalAutoDetectBinPacking
= false;
1535 LLVMStyle
.FixNamespaceComments
= true;
1536 LLVMStyle
.ForEachMacros
.push_back("foreach");
1537 LLVMStyle
.ForEachMacros
.push_back("Q_FOREACH");
1538 LLVMStyle
.ForEachMacros
.push_back("BOOST_FOREACH");
1539 LLVMStyle
.IfMacros
.push_back("KJ_IF_MAYBE");
1540 LLVMStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Preserve
;
1541 LLVMStyle
.IncludeStyle
.IncludeCategories
= {
1542 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1543 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1544 {".*", 1, 0, false}};
1545 LLVMStyle
.IncludeStyle
.IncludeIsMainRegex
= "(Test)?$";
1546 LLVMStyle
.IncludeStyle
.MainIncludeChar
= tooling::IncludeStyle::MICD_Quote
;
1547 LLVMStyle
.IndentAccessModifiers
= false;
1548 LLVMStyle
.IndentCaseBlocks
= false;
1549 LLVMStyle
.IndentCaseLabels
= false;
1550 LLVMStyle
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1551 LLVMStyle
.IndentGotoLabels
= true;
1552 LLVMStyle
.IndentPPDirectives
= FormatStyle::PPDIS_None
;
1553 LLVMStyle
.IndentRequiresClause
= true;
1554 LLVMStyle
.IndentWidth
= 2;
1555 LLVMStyle
.IndentWrappedFunctionNames
= false;
1556 LLVMStyle
.InheritsParentConfig
= false;
1557 LLVMStyle
.InsertBraces
= false;
1558 LLVMStyle
.InsertNewlineAtEOF
= false;
1559 LLVMStyle
.InsertTrailingCommas
= FormatStyle::TCS_None
;
1560 LLVMStyle
.IntegerLiteralSeparator
= {
1561 /*Binary=*/0, /*BinaryMinDigits=*/0,
1562 /*Decimal=*/0, /*DecimalMinDigits=*/0,
1563 /*Hex=*/0, /*HexMinDigits=*/0};
1564 LLVMStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Leave
;
1565 LLVMStyle
.JavaScriptWrapImports
= true;
1566 LLVMStyle
.KeepEmptyLines
= {
1567 /*AtEndOfFile=*/false,
1568 /*AtStartOfBlock=*/true,
1569 /*AtStartOfFile=*/true,
1571 LLVMStyle
.KeepFormFeed
= false;
1572 LLVMStyle
.LambdaBodyIndentation
= FormatStyle::LBI_Signature
;
1573 LLVMStyle
.Language
= Language
;
1574 LLVMStyle
.LineEnding
= FormatStyle::LE_DeriveLF
;
1575 LLVMStyle
.MaxEmptyLinesToKeep
= 1;
1576 LLVMStyle
.NamespaceIndentation
= FormatStyle::NI_None
;
1577 LLVMStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Auto
;
1578 LLVMStyle
.ObjCBlockIndentWidth
= 2;
1579 LLVMStyle
.ObjCBreakBeforeNestedBlockParam
= true;
1580 LLVMStyle
.ObjCSpaceAfterProperty
= false;
1581 LLVMStyle
.ObjCSpaceBeforeProtocolList
= true;
1582 LLVMStyle
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1583 LLVMStyle
.PointerAlignment
= FormatStyle::PAS_Right
;
1584 LLVMStyle
.PPIndentWidth
= -1;
1585 LLVMStyle
.QualifierAlignment
= FormatStyle::QAS_Leave
;
1586 LLVMStyle
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
1587 LLVMStyle
.ReflowComments
= FormatStyle::RCS_Always
;
1588 LLVMStyle
.RemoveBracesLLVM
= false;
1589 LLVMStyle
.RemoveEmptyLinesInUnwrappedLines
= false;
1590 LLVMStyle
.RemoveParentheses
= FormatStyle::RPS_Leave
;
1591 LLVMStyle
.RemoveSemicolon
= false;
1592 LLVMStyle
.RequiresClausePosition
= FormatStyle::RCPS_OwnLine
;
1593 LLVMStyle
.RequiresExpressionIndentation
= FormatStyle::REI_OuterScope
;
1594 LLVMStyle
.SeparateDefinitionBlocks
= FormatStyle::SDS_Leave
;
1595 LLVMStyle
.ShortNamespaceLines
= 1;
1596 LLVMStyle
.SkipMacroDefinitionBody
= false;
1597 LLVMStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1598 LLVMStyle
.SortJavaStaticImport
= FormatStyle::SJSIO_Before
;
1599 LLVMStyle
.SortUsingDeclarations
= FormatStyle::SUD_LexicographicNumeric
;
1600 LLVMStyle
.SpaceAfterCStyleCast
= false;
1601 LLVMStyle
.SpaceAfterLogicalNot
= false;
1602 LLVMStyle
.SpaceAfterTemplateKeyword
= true;
1603 LLVMStyle
.SpaceAroundPointerQualifiers
= FormatStyle::SAPQ_Default
;
1604 LLVMStyle
.SpaceBeforeAssignmentOperators
= true;
1605 LLVMStyle
.SpaceBeforeCaseColon
= false;
1606 LLVMStyle
.SpaceBeforeCpp11BracedList
= false;
1607 LLVMStyle
.SpaceBeforeCtorInitializerColon
= true;
1608 LLVMStyle
.SpaceBeforeInheritanceColon
= true;
1609 LLVMStyle
.SpaceBeforeJsonColon
= false;
1610 LLVMStyle
.SpaceBeforeParens
= FormatStyle::SBPO_ControlStatements
;
1611 LLVMStyle
.SpaceBeforeParensOptions
= {};
1612 LLVMStyle
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1613 LLVMStyle
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1614 LLVMStyle
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1615 LLVMStyle
.SpaceBeforeRangeBasedForLoopColon
= true;
1616 LLVMStyle
.SpaceBeforeSquareBrackets
= false;
1617 LLVMStyle
.SpaceInEmptyBlock
= false;
1618 LLVMStyle
.SpacesBeforeTrailingComments
= 1;
1619 LLVMStyle
.SpacesInAngles
= FormatStyle::SIAS_Never
;
1620 LLVMStyle
.SpacesInContainerLiterals
= true;
1621 LLVMStyle
.SpacesInLineCommentPrefix
= {/*Minimum=*/1, /*Maximum=*/-1u};
1622 LLVMStyle
.SpacesInParens
= FormatStyle::SIPO_Never
;
1623 LLVMStyle
.SpacesInSquareBrackets
= false;
1624 LLVMStyle
.Standard
= FormatStyle::LS_Latest
;
1625 LLVMStyle
.StatementAttributeLikeMacros
.push_back("Q_EMIT");
1626 LLVMStyle
.StatementMacros
.push_back("Q_UNUSED");
1627 LLVMStyle
.StatementMacros
.push_back("QT_REQUIRE_VERSION");
1628 LLVMStyle
.TableGenBreakingDAGArgOperators
= {};
1629 LLVMStyle
.TableGenBreakInsideDAGArg
= FormatStyle::DAS_DontBreak
;
1630 LLVMStyle
.TabWidth
= 8;
1631 LLVMStyle
.UseTab
= FormatStyle::UT_Never
;
1632 LLVMStyle
.VerilogBreakBetweenInstancePorts
= true;
1633 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("BOOST_PP_STRINGIZE");
1634 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("CF_SWIFT_NAME");
1635 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("NS_SWIFT_NAME");
1636 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("PP_STRINGIZE");
1637 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("STRINGIZE");
1639 LLVMStyle
.PenaltyBreakAssignment
= prec::Assignment
;
1640 LLVMStyle
.PenaltyBreakBeforeFirstCallParameter
= 19;
1641 LLVMStyle
.PenaltyBreakComment
= 300;
1642 LLVMStyle
.PenaltyBreakFirstLessLess
= 120;
1643 LLVMStyle
.PenaltyBreakOpenParenthesis
= 0;
1644 LLVMStyle
.PenaltyBreakScopeResolution
= 500;
1645 LLVMStyle
.PenaltyBreakString
= 1000;
1646 LLVMStyle
.PenaltyBreakTemplateDeclaration
= prec::Relational
;
1647 LLVMStyle
.PenaltyExcessCharacter
= 1'000'000;
1648 LLVMStyle
.PenaltyIndentedWhitespace
= 0;
1649 LLVMStyle
.PenaltyReturnTypeOnItsOwnLine
= 60;
1651 // Defaults that differ when not C++.
1653 case FormatStyle::LK_TableGen
:
1654 LLVMStyle
.SpacesInContainerLiterals
= false;
1656 case FormatStyle::LK_Json
:
1657 LLVMStyle
.ColumnLimit
= 0;
1659 case FormatStyle::LK_Verilog
:
1660 LLVMStyle
.IndentCaseLabels
= true;
1661 LLVMStyle
.SpacesInContainerLiterals
= false;
1670 FormatStyle
getGoogleStyle(FormatStyle::LanguageKind Language
) {
1671 if (Language
== FormatStyle::LK_TextProto
) {
1672 FormatStyle GoogleStyle
= getGoogleStyle(FormatStyle::LK_Proto
);
1673 GoogleStyle
.Language
= FormatStyle::LK_TextProto
;
1678 FormatStyle GoogleStyle
= getLLVMStyle(Language
);
1680 GoogleStyle
.AccessModifierOffset
= -1;
1681 GoogleStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Left
;
1682 GoogleStyle
.AllowShortIfStatementsOnASingleLine
=
1683 FormatStyle::SIS_WithoutElse
;
1684 GoogleStyle
.AllowShortLoopsOnASingleLine
= true;
1685 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= true;
1686 GoogleStyle
.BreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1687 GoogleStyle
.DerivePointerAlignment
= true;
1688 GoogleStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Regroup
;
1689 GoogleStyle
.IncludeStyle
.IncludeCategories
= {{"^<ext/.*\\.h>", 2, 0, false},
1690 {"^<.*\\.h>", 1, 0, false},
1691 {"^<.*", 2, 0, false},
1692 {".*", 3, 0, false}};
1693 GoogleStyle
.IncludeStyle
.IncludeIsMainRegex
= "([-_](test|unittest))?$";
1694 GoogleStyle
.IndentCaseLabels
= true;
1695 GoogleStyle
.KeepEmptyLines
.AtStartOfBlock
= false;
1696 GoogleStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Never
;
1697 GoogleStyle
.ObjCSpaceAfterProperty
= false;
1698 GoogleStyle
.ObjCSpaceBeforeProtocolList
= true;
1699 GoogleStyle
.PackConstructorInitializers
= FormatStyle::PCIS_NextLine
;
1700 GoogleStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1701 GoogleStyle
.RawStringFormats
= {
1703 FormatStyle::LK_Cpp
,
1714 /*EnclosingFunctionNames=*/
1716 /*CanonicalDelimiter=*/"",
1717 /*BasedOnStyle=*/"google",
1720 FormatStyle::LK_TextProto
,
1728 /*EnclosingFunctionNames=*/
1732 "PARSE_PARTIAL_TEXT_PROTO",
1736 "ParseTextProtoOrDie",
1738 "ParsePartialTestProto",
1740 /*CanonicalDelimiter=*/"pb",
1741 /*BasedOnStyle=*/"google",
1745 GoogleStyle
.SpacesBeforeTrailingComments
= 2;
1746 GoogleStyle
.Standard
= FormatStyle::LS_Auto
;
1748 GoogleStyle
.PenaltyBreakBeforeFirstCallParameter
= 1;
1749 GoogleStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1751 if (Language
== FormatStyle::LK_Java
) {
1752 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1753 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1754 GoogleStyle
.AlignTrailingComments
= {};
1755 GoogleStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1756 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1757 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1758 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1759 GoogleStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_NonAssignment
;
1760 GoogleStyle
.ColumnLimit
= 100;
1761 GoogleStyle
.SpaceAfterCStyleCast
= true;
1762 GoogleStyle
.SpacesBeforeTrailingComments
= 1;
1763 } else if (Language
== FormatStyle::LK_JavaScript
) {
1764 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_AlwaysBreak
;
1765 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1766 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1767 // TODO: still under discussion whether to switch to SLS_All.
1768 GoogleStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_Empty
;
1769 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1770 GoogleStyle
.BreakBeforeTernaryOperators
= false;
1771 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1772 // commonly followed by overlong URLs.
1773 GoogleStyle
.CommentPragmas
= "(taze:|^/[ \t]*<|tslint:|@see)";
1774 // TODO: enable once decided, in particular re disabling bin packing.
1775 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1776 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1777 GoogleStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Single
;
1778 GoogleStyle
.JavaScriptWrapImports
= false;
1779 GoogleStyle
.MaxEmptyLinesToKeep
= 3;
1780 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1781 GoogleStyle
.SpacesInContainerLiterals
= false;
1782 } else if (Language
== FormatStyle::LK_Proto
) {
1783 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1784 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1785 // This affects protocol buffer options specifications and text protos.
1786 // Text protos are currently mostly formatted inside C++ raw string literals
1787 // and often the current breaking behavior of string literals is not
1788 // beneficial there. Investigate turning this on once proper string reflow
1789 // has been implemented.
1790 GoogleStyle
.BreakStringLiterals
= false;
1791 GoogleStyle
.Cpp11BracedListStyle
= false;
1792 GoogleStyle
.SpacesInContainerLiterals
= false;
1793 } else if (Language
== FormatStyle::LK_ObjC
) {
1794 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1795 GoogleStyle
.ColumnLimit
= 100;
1796 // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1797 // relationship between ObjC standard library headers and other heades,
1799 GoogleStyle
.IncludeStyle
.IncludeBlocks
=
1800 tooling::IncludeStyle::IBS_Preserve
;
1801 } else if (Language
== FormatStyle::LK_CSharp
) {
1802 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1803 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1804 GoogleStyle
.BreakStringLiterals
= false;
1805 GoogleStyle
.ColumnLimit
= 100;
1806 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1812 FormatStyle
getChromiumStyle(FormatStyle::LanguageKind Language
) {
1813 FormatStyle ChromiumStyle
= getGoogleStyle(Language
);
1815 // Disable include reordering across blocks in Chromium code.
1816 // - clang-format tries to detect that foo.h is the "main" header for
1817 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1818 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1819 // _private.cc, _impl.cc etc) in different permutations
1820 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1821 // better default for Chromium code.
1822 // - The default for .cc and .mm files is different (r357695) for Google style
1823 // for the same reason. The plan is to unify this again once the main
1824 // header detection works for Google's ObjC code, but this hasn't happened
1825 // yet. Since Chromium has some ObjC code, switching Chromium is blocked
1827 // - Finally, "If include reordering is harmful, put things in different
1828 // blocks to prevent it" has been a recommendation for a long time that
1829 // people are used to. We'll need a dev education push to change this to
1830 // "If include reordering is harmful, put things in a different block and
1831 // _prepend that with a comment_ to prevent it" before changing behavior.
1832 ChromiumStyle
.IncludeStyle
.IncludeBlocks
=
1833 tooling::IncludeStyle::IBS_Preserve
;
1835 if (Language
== FormatStyle::LK_Java
) {
1836 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
=
1837 FormatStyle::SIS_WithoutElse
;
1838 ChromiumStyle
.BreakAfterJavaFieldAnnotations
= true;
1839 ChromiumStyle
.ContinuationIndentWidth
= 8;
1840 ChromiumStyle
.IndentWidth
= 4;
1841 // See styleguide for import groups:
1842 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1843 ChromiumStyle
.JavaImportGroups
= {
1850 "com.google.android.apps.chrome",
1855 ChromiumStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1856 } else if (Language
== FormatStyle::LK_JavaScript
) {
1857 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1858 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1860 ChromiumStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1861 ChromiumStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1862 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1863 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1864 ChromiumStyle
.BinPackParameters
= FormatStyle::BPPS_OnePerLine
;
1865 ChromiumStyle
.DerivePointerAlignment
= false;
1866 if (Language
== FormatStyle::LK_ObjC
)
1867 ChromiumStyle
.ColumnLimit
= 80;
1869 return ChromiumStyle
;
1872 FormatStyle
getMozillaStyle() {
1873 FormatStyle MozillaStyle
= getLLVMStyle();
1874 MozillaStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1875 MozillaStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1876 MozillaStyle
.AlwaysBreakAfterDefinitionReturnType
=
1877 FormatStyle::DRTBS_TopLevel
;
1878 MozillaStyle
.BinPackArguments
= false;
1879 MozillaStyle
.BinPackParameters
= FormatStyle::BPPS_OnePerLine
;
1880 MozillaStyle
.BreakAfterReturnType
= FormatStyle::RTBS_TopLevel
;
1881 MozillaStyle
.BreakBeforeBraces
= FormatStyle::BS_Mozilla
;
1882 MozillaStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1883 MozillaStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1884 MozillaStyle
.BreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1885 MozillaStyle
.ConstructorInitializerIndentWidth
= 2;
1886 MozillaStyle
.ContinuationIndentWidth
= 2;
1887 MozillaStyle
.Cpp11BracedListStyle
= false;
1888 MozillaStyle
.FixNamespaceComments
= false;
1889 MozillaStyle
.IndentCaseLabels
= true;
1890 MozillaStyle
.ObjCSpaceAfterProperty
= true;
1891 MozillaStyle
.ObjCSpaceBeforeProtocolList
= false;
1892 MozillaStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1893 MozillaStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1894 MozillaStyle
.SpaceAfterTemplateKeyword
= false;
1895 return MozillaStyle
;
1898 FormatStyle
getWebKitStyle() {
1899 FormatStyle Style
= getLLVMStyle();
1900 Style
.AccessModifierOffset
= -4;
1901 Style
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1902 Style
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1903 Style
.AlignTrailingComments
= {};
1904 Style
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1905 Style
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Empty
;
1906 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1907 Style
.BreakBeforeBraces
= FormatStyle::BS_WebKit
;
1908 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1909 Style
.ColumnLimit
= 0;
1910 Style
.Cpp11BracedListStyle
= false;
1911 Style
.FixNamespaceComments
= false;
1912 Style
.IndentWidth
= 4;
1913 Style
.NamespaceIndentation
= FormatStyle::NI_Inner
;
1914 Style
.ObjCBlockIndentWidth
= 4;
1915 Style
.ObjCSpaceAfterProperty
= true;
1916 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
1917 Style
.SpaceBeforeCpp11BracedList
= true;
1918 Style
.SpaceInEmptyBlock
= true;
1922 FormatStyle
getGNUStyle() {
1923 FormatStyle Style
= getLLVMStyle();
1924 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_All
;
1925 Style
.BreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1926 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1927 Style
.BreakBeforeBraces
= FormatStyle::BS_GNU
;
1928 Style
.BreakBeforeTernaryOperators
= true;
1929 Style
.ColumnLimit
= 79;
1930 Style
.Cpp11BracedListStyle
= false;
1931 Style
.FixNamespaceComments
= false;
1932 Style
.KeepFormFeed
= true;
1933 Style
.SpaceBeforeParens
= FormatStyle::SBPO_Always
;
1937 FormatStyle
getMicrosoftStyle(FormatStyle::LanguageKind Language
) {
1938 FormatStyle Style
= getLLVMStyle(Language
);
1939 Style
.ColumnLimit
= 120;
1941 Style
.IndentWidth
= 4;
1942 Style
.UseTab
= FormatStyle::UT_Never
;
1943 Style
.BreakBeforeBraces
= FormatStyle::BS_Custom
;
1944 Style
.BraceWrapping
.AfterClass
= true;
1945 Style
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1946 Style
.BraceWrapping
.AfterEnum
= true;
1947 Style
.BraceWrapping
.AfterFunction
= true;
1948 Style
.BraceWrapping
.AfterNamespace
= true;
1949 Style
.BraceWrapping
.AfterObjCDeclaration
= true;
1950 Style
.BraceWrapping
.AfterStruct
= true;
1951 Style
.BraceWrapping
.AfterExternBlock
= true;
1952 Style
.BraceWrapping
.BeforeCatch
= true;
1953 Style
.BraceWrapping
.BeforeElse
= true;
1954 Style
.BraceWrapping
.BeforeWhile
= false;
1955 Style
.PenaltyReturnTypeOnItsOwnLine
= 1000;
1956 Style
.AllowShortEnumsOnASingleLine
= false;
1957 Style
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_None
;
1958 Style
.AllowShortCaseLabelsOnASingleLine
= false;
1959 Style
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1960 Style
.AllowShortLoopsOnASingleLine
= false;
1961 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1962 Style
.BreakAfterReturnType
= FormatStyle::RTBS_None
;
1966 FormatStyle
getClangFormatStyle() {
1967 FormatStyle Style
= getLLVMStyle();
1968 Style
.InsertBraces
= true;
1969 Style
.InsertNewlineAtEOF
= true;
1970 Style
.IntegerLiteralSeparator
.Decimal
= 3;
1971 Style
.IntegerLiteralSeparator
.DecimalMinDigits
= 5;
1972 Style
.LineEnding
= FormatStyle::LE_LF
;
1973 Style
.RemoveBracesLLVM
= true;
1974 Style
.RemoveEmptyLinesInUnwrappedLines
= true;
1975 Style
.RemoveParentheses
= FormatStyle::RPS_ReturnStatement
;
1976 Style
.RemoveSemicolon
= true;
1980 FormatStyle
getNoStyle() {
1981 FormatStyle NoStyle
= getLLVMStyle();
1982 NoStyle
.DisableFormat
= true;
1983 NoStyle
.SortIncludes
= FormatStyle::SI_Never
;
1984 NoStyle
.SortUsingDeclarations
= FormatStyle::SUD_Never
;
1988 bool getPredefinedStyle(StringRef Name
, FormatStyle::LanguageKind Language
,
1989 FormatStyle
*Style
) {
1990 if (Name
.equals_insensitive("llvm"))
1991 *Style
= getLLVMStyle(Language
);
1992 else if (Name
.equals_insensitive("chromium"))
1993 *Style
= getChromiumStyle(Language
);
1994 else if (Name
.equals_insensitive("mozilla"))
1995 *Style
= getMozillaStyle();
1996 else if (Name
.equals_insensitive("google"))
1997 *Style
= getGoogleStyle(Language
);
1998 else if (Name
.equals_insensitive("webkit"))
1999 *Style
= getWebKitStyle();
2000 else if (Name
.equals_insensitive("gnu"))
2001 *Style
= getGNUStyle();
2002 else if (Name
.equals_insensitive("microsoft"))
2003 *Style
= getMicrosoftStyle(Language
);
2004 else if (Name
.equals_insensitive("clang-format"))
2005 *Style
= getClangFormatStyle();
2006 else if (Name
.equals_insensitive("none"))
2007 *Style
= getNoStyle();
2008 else if (Name
.equals_insensitive("inheritparentconfig"))
2009 Style
->InheritsParentConfig
= true;
2013 Style
->Language
= Language
;
2017 ParseError
validateQualifierOrder(FormatStyle
*Style
) {
2018 // If its empty then it means don't do anything.
2019 if (Style
->QualifierOrder
.empty())
2020 return ParseError::MissingQualifierOrder
;
2022 // Ensure the list contains only currently valid qualifiers.
2023 for (const auto &Qualifier
: Style
->QualifierOrder
) {
2024 if (Qualifier
== "type")
2027 LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier
);
2028 if (token
== tok::identifier
)
2029 return ParseError::InvalidQualifierSpecified
;
2032 // Ensure the list is unique (no duplicates).
2033 std::set
<std::string
> UniqueQualifiers(Style
->QualifierOrder
.begin(),
2034 Style
->QualifierOrder
.end());
2035 if (Style
->QualifierOrder
.size() != UniqueQualifiers
.size()) {
2036 LLVM_DEBUG(llvm::dbgs()
2037 << "Duplicate Qualifiers " << Style
->QualifierOrder
.size()
2038 << " vs " << UniqueQualifiers
.size() << "\n");
2039 return ParseError::DuplicateQualifierSpecified
;
2042 // Ensure the list has 'type' in it.
2043 if (!llvm::is_contained(Style
->QualifierOrder
, "type"))
2044 return ParseError::MissingQualifierType
;
2046 return ParseError::Success
;
2049 std::error_code
parseConfiguration(llvm::MemoryBufferRef Config
,
2050 FormatStyle
*Style
, bool AllowUnknownOptions
,
2051 llvm::SourceMgr::DiagHandlerTy DiagHandler
,
2052 void *DiagHandlerCtxt
) {
2054 FormatStyle::LanguageKind Language
= Style
->Language
;
2055 assert(Language
!= FormatStyle::LK_None
);
2056 if (Config
.getBuffer().trim().empty())
2057 return make_error_code(ParseError::Success
);
2058 Style
->StyleSet
.Clear();
2059 std::vector
<FormatStyle
> Styles
;
2060 llvm::yaml::Input
Input(Config
, /*Ctxt=*/nullptr, DiagHandler
,
2062 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
2063 // values for the fields, keys for which are missing from the configuration.
2064 // Mapping also uses the context to get the language to find the correct
2066 Input
.setContext(Style
);
2067 Input
.setAllowUnknownKeys(AllowUnknownOptions
);
2070 return Input
.error();
2072 for (unsigned i
= 0; i
< Styles
.size(); ++i
) {
2073 // Ensures that only the first configuration can skip the Language option.
2074 if (Styles
[i
].Language
== FormatStyle::LK_None
&& i
!= 0)
2075 return make_error_code(ParseError::Error
);
2076 // Ensure that each language is configured at most once.
2077 for (unsigned j
= 0; j
< i
; ++j
) {
2078 if (Styles
[i
].Language
== Styles
[j
].Language
) {
2079 LLVM_DEBUG(llvm::dbgs()
2080 << "Duplicate languages in the config file on positions "
2081 << j
<< " and " << i
<< "\n");
2082 return make_error_code(ParseError::Error
);
2086 // Look for a suitable configuration starting from the end, so we can
2087 // find the configuration for the specific language first, and the default
2088 // configuration (which can only be at slot 0) after it.
2089 FormatStyle::FormatStyleSet StyleSet
;
2090 bool LanguageFound
= false;
2091 for (const FormatStyle
&Style
: llvm::reverse(Styles
)) {
2092 if (Style
.Language
!= FormatStyle::LK_None
)
2093 StyleSet
.Add(Style
);
2094 if (Style
.Language
== Language
)
2095 LanguageFound
= true;
2097 if (!LanguageFound
) {
2098 if (Styles
.empty() || Styles
[0].Language
!= FormatStyle::LK_None
)
2099 return make_error_code(ParseError::Unsuitable
);
2100 FormatStyle DefaultStyle
= Styles
[0];
2101 DefaultStyle
.Language
= Language
;
2102 StyleSet
.Add(std::move(DefaultStyle
));
2104 *Style
= *StyleSet
.Get(Language
);
2105 if (Style
->InsertTrailingCommas
!= FormatStyle::TCS_None
&&
2106 Style
->BinPackArguments
) {
2107 // See comment on FormatStyle::TSC_Wrapped.
2108 return make_error_code(ParseError::BinPackTrailingCommaConflict
);
2110 if (Style
->QualifierAlignment
!= FormatStyle::QAS_Leave
)
2111 return make_error_code(validateQualifierOrder(Style
));
2112 return make_error_code(ParseError::Success
);
2115 std::string
configurationAsText(const FormatStyle
&Style
) {
2117 llvm::raw_string_ostream
Stream(Text
);
2118 llvm::yaml::Output
Output(Stream
);
2119 // We use the same mapping method for input and output, so we need a non-const
2121 FormatStyle NonConstStyle
= Style
;
2122 expandPresetsBraceWrapping(NonConstStyle
);
2123 expandPresetsSpaceBeforeParens(NonConstStyle
);
2124 expandPresetsSpacesInParens(NonConstStyle
);
2125 Output
<< NonConstStyle
;
2127 return Stream
.str();
2130 std::optional
<FormatStyle
>
2131 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language
) const {
2133 return std::nullopt
;
2134 auto It
= Styles
->find(Language
);
2135 if (It
== Styles
->end())
2136 return std::nullopt
;
2137 FormatStyle Style
= It
->second
;
2138 Style
.StyleSet
= *this;
2142 void FormatStyle::FormatStyleSet::Add(FormatStyle Style
) {
2143 assert(Style
.Language
!= LK_None
&&
2144 "Cannot add a style for LK_None to a StyleSet");
2146 !Style
.StyleSet
.Styles
&&
2147 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2149 Styles
= std::make_shared
<MapType
>();
2150 (*Styles
)[Style
.Language
] = std::move(Style
);
2153 void FormatStyle::FormatStyleSet::Clear() { Styles
.reset(); }
2155 std::optional
<FormatStyle
>
2156 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language
) const {
2157 return StyleSet
.Get(Language
);
2162 class ParensRemover
: public TokenAnalyzer
{
2164 ParensRemover(const Environment
&Env
, const FormatStyle
&Style
)
2165 : TokenAnalyzer(Env
, Style
) {}
2167 std::pair
<tooling::Replacements
, unsigned>
2168 analyze(TokenAnnotator
&Annotator
,
2169 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2170 FormatTokenLexer
&Tokens
) override
{
2171 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2172 tooling::Replacements Result
;
2173 removeParens(AnnotatedLines
, Result
);
2178 void removeParens(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2179 tooling::Replacements
&Result
) {
2180 const auto &SourceMgr
= Env
.getSourceManager();
2181 for (auto *Line
: Lines
) {
2182 if (!Line
->Children
.empty())
2183 removeParens(Line
->Children
, Result
);
2184 if (!Line
->Affected
)
2186 for (const auto *Token
= Line
->First
; Token
&& !Token
->Finalized
;
2187 Token
= Token
->Next
) {
2188 if (!Token
->Optional
|| !Token
->isOneOf(tok::l_paren
, tok::r_paren
))
2190 auto *Next
= Token
->Next
;
2191 assert(Next
&& Next
->isNot(tok::eof
));
2192 SourceLocation Start
;
2193 if (Next
->NewlinesBefore
== 0) {
2194 Start
= Token
->Tok
.getLocation();
2195 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2197 Start
= Token
->WhitespaceRange
.getBegin();
2200 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2201 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, " ")));
2207 class BracesInserter
: public TokenAnalyzer
{
2209 BracesInserter(const Environment
&Env
, const FormatStyle
&Style
)
2210 : TokenAnalyzer(Env
, Style
) {}
2212 std::pair
<tooling::Replacements
, unsigned>
2213 analyze(TokenAnnotator
&Annotator
,
2214 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2215 FormatTokenLexer
&Tokens
) override
{
2216 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2217 tooling::Replacements Result
;
2218 insertBraces(AnnotatedLines
, Result
);
2223 void insertBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2224 tooling::Replacements
&Result
) {
2225 const auto &SourceMgr
= Env
.getSourceManager();
2226 int OpeningBraceSurplus
= 0;
2227 for (AnnotatedLine
*Line
: Lines
) {
2228 if (!Line
->Children
.empty())
2229 insertBraces(Line
->Children
, Result
);
2230 if (!Line
->Affected
&& OpeningBraceSurplus
== 0)
2232 for (FormatToken
*Token
= Line
->First
; Token
&& !Token
->Finalized
;
2233 Token
= Token
->Next
) {
2234 int BraceCount
= Token
->BraceCount
;
2235 if (BraceCount
== 0)
2238 if (BraceCount
< 0) {
2239 assert(BraceCount
== -1);
2240 if (!Line
->Affected
)
2242 Brace
= Token
->is(tok::comment
) ? "\n{" : "{";
2243 ++OpeningBraceSurplus
;
2245 if (OpeningBraceSurplus
== 0)
2247 if (OpeningBraceSurplus
< BraceCount
)
2248 BraceCount
= OpeningBraceSurplus
;
2249 Brace
= '\n' + std::string(BraceCount
, '}');
2250 OpeningBraceSurplus
-= BraceCount
;
2252 Token
->BraceCount
= 0;
2253 const auto Start
= Token
->Tok
.getEndLoc();
2254 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Start
, 0, Brace
)));
2257 assert(OpeningBraceSurplus
== 0);
2261 class BracesRemover
: public TokenAnalyzer
{
2263 BracesRemover(const Environment
&Env
, const FormatStyle
&Style
)
2264 : TokenAnalyzer(Env
, Style
) {}
2266 std::pair
<tooling::Replacements
, unsigned>
2267 analyze(TokenAnnotator
&Annotator
,
2268 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2269 FormatTokenLexer
&Tokens
) override
{
2270 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2271 tooling::Replacements Result
;
2272 removeBraces(AnnotatedLines
, Result
);
2277 void removeBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2278 tooling::Replacements
&Result
) {
2279 const auto &SourceMgr
= Env
.getSourceManager();
2280 const auto *End
= Lines
.end();
2281 for (const auto *I
= Lines
.begin(); I
!= End
; ++I
) {
2282 const auto &Line
= *I
;
2283 if (!Line
->Children
.empty())
2284 removeBraces(Line
->Children
, Result
);
2285 if (!Line
->Affected
)
2287 const auto *NextLine
= I
+ 1 == End
? nullptr : I
[1];
2288 for (const auto *Token
= Line
->First
; Token
&& !Token
->Finalized
;
2289 Token
= Token
->Next
) {
2290 if (!Token
->Optional
)
2292 if (!Token
->isOneOf(tok::l_brace
, tok::r_brace
))
2294 auto *Next
= Token
->Next
;
2295 assert(Next
|| Token
== Line
->Last
);
2296 if (!Next
&& NextLine
)
2297 Next
= NextLine
->First
;
2298 SourceLocation Start
;
2299 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2300 Start
= Token
->Tok
.getLocation();
2301 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2303 Start
= Token
->WhitespaceRange
.getBegin();
2306 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2307 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2313 class SemiRemover
: public TokenAnalyzer
{
2315 SemiRemover(const Environment
&Env
, const FormatStyle
&Style
)
2316 : TokenAnalyzer(Env
, Style
) {}
2318 std::pair
<tooling::Replacements
, unsigned>
2319 analyze(TokenAnnotator
&Annotator
,
2320 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2321 FormatTokenLexer
&Tokens
) override
{
2322 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2323 tooling::Replacements Result
;
2324 removeSemi(Annotator
, AnnotatedLines
, Result
);
2329 void removeSemi(TokenAnnotator
&Annotator
,
2330 SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2331 tooling::Replacements
&Result
) {
2332 auto PrecededByFunctionRBrace
= [](const FormatToken
&Tok
) {
2333 const auto *Prev
= Tok
.Previous
;
2334 if (!Prev
|| Prev
->isNot(tok::r_brace
))
2336 const auto *LBrace
= Prev
->MatchingParen
;
2337 return LBrace
&& LBrace
->is(TT_FunctionLBrace
);
2339 const auto &SourceMgr
= Env
.getSourceManager();
2340 const auto *End
= Lines
.end();
2341 for (const auto *I
= Lines
.begin(); I
!= End
; ++I
) {
2342 const auto &Line
= *I
;
2343 if (!Line
->Children
.empty())
2344 removeSemi(Annotator
, Line
->Children
, Result
);
2345 if (!Line
->Affected
)
2347 Annotator
.calculateFormattingInformation(*Line
);
2348 const auto *NextLine
= I
+ 1 == End
? nullptr : I
[1];
2349 for (const auto *Token
= Line
->First
; Token
&& !Token
->Finalized
;
2350 Token
= Token
->Next
) {
2351 if (Token
->isNot(tok::semi
) ||
2352 (!Token
->Optional
&& !PrecededByFunctionRBrace(*Token
))) {
2355 auto *Next
= Token
->Next
;
2356 assert(Next
|| Token
== Line
->Last
);
2357 if (!Next
&& NextLine
)
2358 Next
= NextLine
->First
;
2359 SourceLocation Start
;
2360 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2361 Start
= Token
->Tok
.getLocation();
2362 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2364 Start
= Token
->WhitespaceRange
.getBegin();
2367 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2368 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2374 class JavaScriptRequoter
: public TokenAnalyzer
{
2376 JavaScriptRequoter(const Environment
&Env
, const FormatStyle
&Style
)
2377 : TokenAnalyzer(Env
, Style
) {}
2379 std::pair
<tooling::Replacements
, unsigned>
2380 analyze(TokenAnnotator
&Annotator
,
2381 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2382 FormatTokenLexer
&Tokens
) override
{
2383 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2384 tooling::Replacements Result
;
2385 requoteJSStringLiteral(AnnotatedLines
, Result
);
2390 // Replaces double/single-quoted string literal as appropriate, re-escaping
2391 // the contents in the process.
2392 void requoteJSStringLiteral(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2393 tooling::Replacements
&Result
) {
2394 for (AnnotatedLine
*Line
: Lines
) {
2395 requoteJSStringLiteral(Line
->Children
, Result
);
2396 if (!Line
->Affected
)
2398 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2399 FormatTok
= FormatTok
->Next
) {
2400 StringRef Input
= FormatTok
->TokenText
;
2401 if (FormatTok
->Finalized
|| !FormatTok
->isStringLiteral() ||
2402 // NB: testing for not starting with a double quote to avoid
2403 // breaking `template strings`.
2404 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
&&
2405 !Input
.starts_with("\"")) ||
2406 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Double
&&
2407 !Input
.starts_with("\'"))) {
2411 // Change start and end quote.
2412 bool IsSingle
= Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
;
2413 SourceLocation Start
= FormatTok
->Tok
.getLocation();
2414 auto Replace
= [&](SourceLocation Start
, unsigned Length
,
2415 StringRef ReplacementText
) {
2416 auto Err
= Result
.add(tooling::Replacement(
2417 Env
.getSourceManager(), Start
, Length
, ReplacementText
));
2418 // FIXME: handle error. For now, print error message and skip the
2419 // replacement for release version.
2421 llvm::errs() << toString(std::move(Err
)) << "\n";
2425 Replace(Start
, 1, IsSingle
? "'" : "\"");
2426 Replace(FormatTok
->Tok
.getEndLoc().getLocWithOffset(-1), 1,
2427 IsSingle
? "'" : "\"");
2429 // Escape internal quotes.
2430 bool Escaped
= false;
2431 for (size_t i
= 1; i
< Input
.size() - 1; i
++) {
2434 if (!Escaped
&& i
+ 1 < Input
.size() &&
2435 ((IsSingle
&& Input
[i
+ 1] == '"') ||
2436 (!IsSingle
&& Input
[i
+ 1] == '\''))) {
2437 // Remove this \, it's escaping a " or ' that no longer needs
2439 Replace(Start
.getLocWithOffset(i
), 1, "");
2446 if (!Escaped
&& IsSingle
== (Input
[i
] == '\'')) {
2447 // Escape the quote.
2448 Replace(Start
.getLocWithOffset(i
), 0, "\\");
2462 class Formatter
: public TokenAnalyzer
{
2464 Formatter(const Environment
&Env
, const FormatStyle
&Style
,
2465 FormattingAttemptStatus
*Status
)
2466 : TokenAnalyzer(Env
, Style
), Status(Status
) {}
2468 std::pair
<tooling::Replacements
, unsigned>
2469 analyze(TokenAnnotator
&Annotator
,
2470 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2471 FormatTokenLexer
&Tokens
) override
{
2472 tooling::Replacements Result
;
2473 deriveLocalStyle(AnnotatedLines
);
2474 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2475 for (AnnotatedLine
*Line
: AnnotatedLines
)
2476 Annotator
.calculateFormattingInformation(*Line
);
2477 Annotator
.setCommentLineLevels(AnnotatedLines
);
2479 WhitespaceManager
Whitespaces(
2480 Env
.getSourceManager(), Style
,
2481 Style
.LineEnding
> FormatStyle::LE_CRLF
2482 ? WhitespaceManager::inputUsesCRLF(
2483 Env
.getSourceManager().getBufferData(Env
.getFileID()),
2484 Style
.LineEnding
== FormatStyle::LE_DeriveCRLF
)
2485 : Style
.LineEnding
== FormatStyle::LE_CRLF
);
2486 ContinuationIndenter
Indenter(Style
, Tokens
.getKeywords(),
2487 Env
.getSourceManager(), Whitespaces
, Encoding
,
2488 BinPackInconclusiveFunctions
);
2490 UnwrappedLineFormatter(&Indenter
, &Whitespaces
, Style
,
2491 Tokens
.getKeywords(), Env
.getSourceManager(),
2493 .format(AnnotatedLines
, /*DryRun=*/false,
2494 /*AdditionalIndent=*/0,
2495 /*FixBadIndentation=*/false,
2496 /*FirstStartColumn=*/Env
.getFirstStartColumn(),
2497 /*NextStartColumn=*/Env
.getNextStartColumn(),
2498 /*LastStartColumn=*/Env
.getLastStartColumn());
2499 for (const auto &R
: Whitespaces
.generateReplacements())
2501 return std::make_pair(Result
, 0);
2502 return std::make_pair(Result
, Penalty
);
2507 hasCpp03IncompatibleFormat(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2508 for (const AnnotatedLine
*Line
: Lines
) {
2509 if (hasCpp03IncompatibleFormat(Line
->Children
))
2511 for (FormatToken
*Tok
= Line
->First
->Next
; Tok
; Tok
= Tok
->Next
) {
2512 if (!Tok
->hasWhitespaceBefore()) {
2513 if (Tok
->is(tok::coloncolon
) && Tok
->Previous
->is(TT_TemplateOpener
))
2515 if (Tok
->is(TT_TemplateCloser
) &&
2516 Tok
->Previous
->is(TT_TemplateCloser
)) {
2525 int countVariableAlignments(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2526 int AlignmentDiff
= 0;
2527 for (const AnnotatedLine
*Line
: Lines
) {
2528 AlignmentDiff
+= countVariableAlignments(Line
->Children
);
2529 for (FormatToken
*Tok
= Line
->First
; Tok
&& Tok
->Next
; Tok
= Tok
->Next
) {
2530 if (Tok
->isNot(TT_PointerOrReference
))
2532 // Don't treat space in `void foo() &&` as evidence.
2533 if (const auto *Prev
= Tok
->getPreviousNonComment()) {
2534 if (Prev
->is(tok::r_paren
) && Prev
->MatchingParen
) {
2535 if (const auto *Func
=
2536 Prev
->MatchingParen
->getPreviousNonComment()) {
2537 if (Func
->isOneOf(TT_FunctionDeclarationName
, TT_StartOfName
,
2538 TT_OverloadedOperator
)) {
2544 bool SpaceBefore
= Tok
->hasWhitespaceBefore();
2545 bool SpaceAfter
= Tok
->Next
->hasWhitespaceBefore();
2546 if (SpaceBefore
&& !SpaceAfter
)
2548 if (!SpaceBefore
&& SpaceAfter
)
2552 return AlignmentDiff
;
2556 deriveLocalStyle(const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2557 bool HasBinPackedFunction
= false;
2558 bool HasOnePerLineFunction
= false;
2559 for (AnnotatedLine
*Line
: AnnotatedLines
) {
2560 if (!Line
->First
->Next
)
2562 FormatToken
*Tok
= Line
->First
->Next
;
2564 if (Tok
->is(PPK_BinPacked
))
2565 HasBinPackedFunction
= true;
2566 if (Tok
->is(PPK_OnePerLine
))
2567 HasOnePerLineFunction
= true;
2572 if (Style
.DerivePointerAlignment
) {
2573 const auto NetRightCount
= countVariableAlignments(AnnotatedLines
);
2574 if (NetRightCount
> 0)
2575 Style
.PointerAlignment
= FormatStyle::PAS_Right
;
2576 else if (NetRightCount
< 0)
2577 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
2578 Style
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
2580 if (Style
.Standard
== FormatStyle::LS_Auto
) {
2581 Style
.Standard
= hasCpp03IncompatibleFormat(AnnotatedLines
)
2582 ? FormatStyle::LS_Latest
2583 : FormatStyle::LS_Cpp03
;
2585 BinPackInconclusiveFunctions
=
2586 HasBinPackedFunction
|| !HasOnePerLineFunction
;
2589 bool BinPackInconclusiveFunctions
;
2590 FormattingAttemptStatus
*Status
;
2593 /// TrailingCommaInserter inserts trailing commas into container literals.
2598 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2599 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2602 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2603 /// is conceptually incompatible with bin packing.
2604 class TrailingCommaInserter
: public TokenAnalyzer
{
2606 TrailingCommaInserter(const Environment
&Env
, const FormatStyle
&Style
)
2607 : TokenAnalyzer(Env
, Style
) {}
2609 std::pair
<tooling::Replacements
, unsigned>
2610 analyze(TokenAnnotator
&Annotator
,
2611 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2612 FormatTokenLexer
&Tokens
) override
{
2613 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2614 tooling::Replacements Result
;
2615 insertTrailingCommas(AnnotatedLines
, Result
);
2620 /// Inserts trailing commas in [] and {} initializers if they wrap over
2622 void insertTrailingCommas(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2623 tooling::Replacements
&Result
) {
2624 for (AnnotatedLine
*Line
: Lines
) {
2625 insertTrailingCommas(Line
->Children
, Result
);
2626 if (!Line
->Affected
)
2628 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2629 FormatTok
= FormatTok
->Next
) {
2630 if (FormatTok
->NewlinesBefore
== 0)
2632 FormatToken
*Matching
= FormatTok
->MatchingParen
;
2633 if (!Matching
|| !FormatTok
->getPreviousNonComment())
2635 if (!(FormatTok
->is(tok::r_square
) &&
2636 Matching
->is(TT_ArrayInitializerLSquare
)) &&
2637 !(FormatTok
->is(tok::r_brace
) && Matching
->is(TT_DictLiteral
))) {
2640 FormatToken
*Prev
= FormatTok
->getPreviousNonComment();
2641 if (Prev
->is(tok::comma
) || Prev
->is(tok::semi
))
2643 // getEndLoc is not reliably set during re-lexing, use text length
2645 SourceLocation Start
=
2646 Prev
->Tok
.getLocation().getLocWithOffset(Prev
->TokenText
.size());
2647 // If inserting a comma would push the code over the column limit, skip
2648 // this location - it'd introduce an unstable formatting due to the
2650 unsigned ColumnNumber
=
2651 Env
.getSourceManager().getSpellingColumnNumber(Start
);
2652 if (ColumnNumber
> Style
.ColumnLimit
)
2654 // Comma insertions cannot conflict with each other, and this pass has a
2655 // clean set of Replacements, so the operation below cannot fail.
2656 cantFail(Result
.add(
2657 tooling::Replacement(Env
.getSourceManager(), Start
, 0, ",")));
2663 // This class clean up the erroneous/redundant code around the given ranges in
2665 class Cleaner
: public TokenAnalyzer
{
2667 Cleaner(const Environment
&Env
, const FormatStyle
&Style
)
2668 : TokenAnalyzer(Env
, Style
),
2669 DeletedTokens(FormatTokenLess(Env
.getSourceManager())) {}
2671 // FIXME: eliminate unused parameters.
2672 std::pair
<tooling::Replacements
, unsigned>
2673 analyze(TokenAnnotator
&Annotator
,
2674 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2675 FormatTokenLexer
&Tokens
) override
{
2676 // FIXME: in the current implementation the granularity of affected range
2677 // is an annotated line. However, this is not sufficient. Furthermore,
2678 // redundant code introduced by replacements does not necessarily
2679 // intercept with ranges of replacements that result in the redundancy.
2680 // To determine if some redundant code is actually introduced by
2681 // replacements(e.g. deletions), we need to come up with a more
2682 // sophisticated way of computing affected ranges.
2683 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2685 checkEmptyNamespace(AnnotatedLines
);
2687 for (auto *Line
: AnnotatedLines
)
2690 return {generateFixes(), 0};
2694 void cleanupLine(AnnotatedLine
*Line
) {
2695 for (auto *Child
: Line
->Children
)
2698 if (Line
->Affected
) {
2699 cleanupRight(Line
->First
, tok::comma
, tok::comma
);
2700 cleanupRight(Line
->First
, TT_CtorInitializerColon
, tok::comma
);
2701 cleanupRight(Line
->First
, tok::l_paren
, tok::comma
);
2702 cleanupLeft(Line
->First
, tok::comma
, tok::r_paren
);
2703 cleanupLeft(Line
->First
, TT_CtorInitializerComma
, tok::l_brace
);
2704 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::l_brace
);
2705 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::equal
);
2709 bool containsOnlyComments(const AnnotatedLine
&Line
) {
2710 for (FormatToken
*Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
)
2711 if (Tok
->isNot(tok::comment
))
2716 // Iterate through all lines and remove any empty (nested) namespaces.
2717 void checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2718 std::set
<unsigned> DeletedLines
;
2719 for (unsigned i
= 0, e
= AnnotatedLines
.size(); i
!= e
; ++i
) {
2720 auto &Line
= *AnnotatedLines
[i
];
2721 if (Line
.startsWithNamespace())
2722 checkEmptyNamespace(AnnotatedLines
, i
, i
, DeletedLines
);
2725 for (auto Line
: DeletedLines
) {
2726 FormatToken
*Tok
= AnnotatedLines
[Line
]->First
;
2734 // The function checks if the namespace, which starts from \p CurrentLine, and
2735 // its nested namespaces are empty and delete them if they are empty. It also
2736 // sets \p NewLine to the last line checked.
2737 // Returns true if the current namespace is empty.
2738 bool checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2739 unsigned CurrentLine
, unsigned &NewLine
,
2740 std::set
<unsigned> &DeletedLines
) {
2741 unsigned InitLine
= CurrentLine
, End
= AnnotatedLines
.size();
2742 if (Style
.BraceWrapping
.AfterNamespace
) {
2743 // If the left brace is in a new line, we should consume it first so that
2744 // it does not make the namespace non-empty.
2745 // FIXME: error handling if there is no left brace.
2746 if (!AnnotatedLines
[++CurrentLine
]->startsWith(tok::l_brace
)) {
2747 NewLine
= CurrentLine
;
2750 } else if (!AnnotatedLines
[CurrentLine
]->endsWith(tok::l_brace
)) {
2753 while (++CurrentLine
< End
) {
2754 if (AnnotatedLines
[CurrentLine
]->startsWith(tok::r_brace
))
2757 if (AnnotatedLines
[CurrentLine
]->startsWithNamespace()) {
2758 if (!checkEmptyNamespace(AnnotatedLines
, CurrentLine
, NewLine
,
2762 CurrentLine
= NewLine
;
2766 if (containsOnlyComments(*AnnotatedLines
[CurrentLine
]))
2769 // If there is anything other than comments or nested namespaces in the
2770 // current namespace, the namespace cannot be empty.
2771 NewLine
= CurrentLine
;
2775 NewLine
= CurrentLine
;
2776 if (CurrentLine
>= End
)
2779 // Check if the empty namespace is actually affected by changed ranges.
2780 if (!AffectedRangeMgr
.affectsCharSourceRange(CharSourceRange::getCharRange(
2781 AnnotatedLines
[InitLine
]->First
->Tok
.getLocation(),
2782 AnnotatedLines
[CurrentLine
]->Last
->Tok
.getEndLoc()))) {
2786 for (unsigned i
= InitLine
; i
<= CurrentLine
; ++i
)
2787 DeletedLines
.insert(i
);
2792 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2793 // of the token in the pair if the left token has \p LK token kind and the
2794 // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2795 // is deleted on match; otherwise, the right token is deleted.
2796 template <typename LeftKind
, typename RightKind
>
2797 void cleanupPair(FormatToken
*Start
, LeftKind LK
, RightKind RK
,
2799 auto NextNotDeleted
= [this](const FormatToken
&Tok
) -> FormatToken
* {
2800 for (auto *Res
= Tok
.Next
; Res
; Res
= Res
->Next
) {
2801 if (Res
->isNot(tok::comment
) &&
2802 DeletedTokens
.find(Res
) == DeletedTokens
.end()) {
2808 for (auto *Left
= Start
; Left
;) {
2809 auto *Right
= NextNotDeleted(*Left
);
2812 if (Left
->is(LK
) && Right
->is(RK
)) {
2813 deleteToken(DeleteLeft
? Left
: Right
);
2814 for (auto *Tok
= Left
->Next
; Tok
&& Tok
!= Right
; Tok
= Tok
->Next
)
2816 // If the right token is deleted, we should keep the left token
2817 // unchanged and pair it with the new right token.
2825 template <typename LeftKind
, typename RightKind
>
2826 void cleanupLeft(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2827 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/true);
2830 template <typename LeftKind
, typename RightKind
>
2831 void cleanupRight(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2832 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/false);
2835 // Delete the given token.
2836 inline void deleteToken(FormatToken
*Tok
) {
2838 DeletedTokens
.insert(Tok
);
2841 tooling::Replacements
generateFixes() {
2842 tooling::Replacements Fixes
;
2843 SmallVector
<FormatToken
*> Tokens
;
2844 std::copy(DeletedTokens
.begin(), DeletedTokens
.end(),
2845 std::back_inserter(Tokens
));
2847 // Merge multiple continuous token deletions into one big deletion so that
2848 // the number of replacements can be reduced. This makes computing affected
2849 // ranges more efficient when we run reformat on the changed code.
2851 while (Idx
< Tokens
.size()) {
2852 unsigned St
= Idx
, End
= Idx
;
2853 while ((End
+ 1) < Tokens
.size() && Tokens
[End
]->Next
== Tokens
[End
+ 1])
2855 auto SR
= CharSourceRange::getCharRange(Tokens
[St
]->Tok
.getLocation(),
2856 Tokens
[End
]->Tok
.getEndLoc());
2858 Fixes
.add(tooling::Replacement(Env
.getSourceManager(), SR
, ""));
2859 // FIXME: better error handling. for now just print error message and skip
2860 // for the release version.
2862 llvm::errs() << toString(std::move(Err
)) << "\n";
2863 assert(false && "Fixes must not conflict!");
2871 // Class for less-than inequality comparason for the set `RedundantTokens`.
2872 // We store tokens in the order they appear in the translation unit so that
2873 // we do not need to sort them in `generateFixes()`.
2874 struct FormatTokenLess
{
2875 FormatTokenLess(const SourceManager
&SM
) : SM(SM
) {}
2877 bool operator()(const FormatToken
*LHS
, const FormatToken
*RHS
) const {
2878 return SM
.isBeforeInTranslationUnit(LHS
->Tok
.getLocation(),
2879 RHS
->Tok
.getLocation());
2881 const SourceManager
&SM
;
2884 // Tokens to be deleted.
2885 std::set
<FormatToken
*, FormatTokenLess
> DeletedTokens
;
2888 class ObjCHeaderStyleGuesser
: public TokenAnalyzer
{
2890 ObjCHeaderStyleGuesser(const Environment
&Env
, const FormatStyle
&Style
)
2891 : TokenAnalyzer(Env
, Style
), IsObjC(false) {}
2893 std::pair
<tooling::Replacements
, unsigned>
2894 analyze(TokenAnnotator
&Annotator
,
2895 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2896 FormatTokenLexer
&Tokens
) override
{
2897 assert(Style
.Language
== FormatStyle::LK_Cpp
);
2898 IsObjC
= guessIsObjC(Env
.getSourceManager(), AnnotatedLines
,
2899 Tokens
.getKeywords());
2900 tooling::Replacements Result
;
2904 bool isObjC() { return IsObjC
; }
2908 guessIsObjC(const SourceManager
&SourceManager
,
2909 const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2910 const AdditionalKeywords
&Keywords
) {
2911 // Keep this array sorted, since we are binary searching over it.
2912 static constexpr llvm::StringLiteral FoundationIdentifiers
[] = {
2927 "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
2928 "FOUNDATION_EXTERN",
2929 "NSAffineTransform",
2931 "NSAttributedString",
2950 "NSInvocationOperation",
2954 "NSMutableAttributedString",
2955 "NSMutableCharacterSet",
2957 "NSMutableDictionary",
2958 "NSMutableIndexSet",
2959 "NSMutableOrderedSet",
2963 "NSNumberFormatter",
2967 "NSOperationQueuePriority",
2971 "NSQualityOfService",
2974 "NSRegularExpression",
2985 "NS_ASSUME_NONNULL_BEGIN",
2990 for (auto *Line
: AnnotatedLines
) {
2991 if (Line
->First
&& (Line
->First
->TokenText
.starts_with("#") ||
2992 Line
->First
->TokenText
== "__pragma" ||
2993 Line
->First
->TokenText
== "_Pragma")) {
2996 for (const FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2997 FormatTok
= FormatTok
->Next
) {
2998 if ((FormatTok
->Previous
&& FormatTok
->Previous
->is(tok::at
) &&
2999 (FormatTok
->Tok
.getObjCKeywordID() != tok::objc_not_keyword
||
3000 FormatTok
->isOneOf(tok::numeric_constant
, tok::l_square
,
3002 (FormatTok
->Tok
.isAnyIdentifier() &&
3003 std::binary_search(std::begin(FoundationIdentifiers
),
3004 std::end(FoundationIdentifiers
),
3005 FormatTok
->TokenText
)) ||
3006 FormatTok
->is(TT_ObjCStringLiteral
) ||
3007 FormatTok
->isOneOf(Keywords
.kw_NS_CLOSED_ENUM
, Keywords
.kw_NS_ENUM
,
3008 Keywords
.kw_NS_ERROR_ENUM
,
3009 Keywords
.kw_NS_OPTIONS
, TT_ObjCBlockLBrace
,
3010 TT_ObjCBlockLParen
, TT_ObjCDecl
, TT_ObjCForIn
,
3011 TT_ObjCMethodExpr
, TT_ObjCMethodSpecifier
,
3013 LLVM_DEBUG(llvm::dbgs()
3014 << "Detected ObjC at location "
3015 << FormatTok
->Tok
.getLocation().printToString(
3017 << " token: " << FormatTok
->TokenText
<< " token type: "
3018 << getTokenTypeName(FormatTok
->getType()) << "\n");
3022 if (guessIsObjC(SourceManager
, Line
->Children
, Keywords
))
3031 struct IncludeDirective
{
3039 struct JavaImportDirective
{
3040 StringRef Identifier
;
3043 SmallVector
<StringRef
> AssociatedCommentLines
;
3047 } // end anonymous namespace
3049 // Determines whether 'Ranges' intersects with ('Start', 'End').
3050 static bool affectsRange(ArrayRef
<tooling::Range
> Ranges
, unsigned Start
,
3052 for (const auto &Range
: Ranges
) {
3053 if (Range
.getOffset() < End
&&
3054 Range
.getOffset() + Range
.getLength() > Start
) {
3061 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
3062 // before sorting/deduplicating. Index is the index of the include under the
3063 // cursor in the original set of includes. If this include has duplicates, it is
3064 // the index of the first of the duplicates as the others are going to be
3065 // removed. OffsetToEOL describes the cursor's position relative to the end of
3066 // its current line.
3067 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
3068 static std::pair
<unsigned, unsigned>
3069 FindCursorIndex(const SmallVectorImpl
<IncludeDirective
> &Includes
,
3070 const SmallVectorImpl
<unsigned> &Indices
, unsigned Cursor
) {
3071 unsigned CursorIndex
= UINT_MAX
;
3072 unsigned OffsetToEOL
= 0;
3073 for (int i
= 0, e
= Includes
.size(); i
!= e
; ++i
) {
3074 unsigned Start
= Includes
[Indices
[i
]].Offset
;
3075 unsigned End
= Start
+ Includes
[Indices
[i
]].Text
.size();
3076 if (!(Cursor
>= Start
&& Cursor
< End
))
3078 CursorIndex
= Indices
[i
];
3079 OffsetToEOL
= End
- Cursor
;
3080 // Put the cursor on the only remaining #include among the duplicate
3082 while (--i
>= 0 && Includes
[CursorIndex
].Text
== Includes
[Indices
[i
]].Text
)
3086 return std::make_pair(CursorIndex
, OffsetToEOL
);
3089 // Replace all "\r\n" with "\n".
3090 std::string
replaceCRLF(const std::string
&Code
) {
3091 std::string NewCode
;
3092 size_t Pos
= 0, LastPos
= 0;
3095 Pos
= Code
.find("\r\n", LastPos
);
3096 if (Pos
== LastPos
) {
3100 if (Pos
== std::string::npos
) {
3101 NewCode
+= Code
.substr(LastPos
);
3104 NewCode
+= Code
.substr(LastPos
, Pos
- LastPos
) + "\n";
3106 } while (Pos
!= std::string::npos
);
3111 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
3112 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
3114 // #include directives with the same text will be deduplicated, and only the
3115 // first #include in the duplicate #includes remains. If the `Cursor` is
3116 // provided and put on a deleted #include, it will be moved to the remaining
3117 // #include in the duplicate #includes.
3118 static void sortCppIncludes(const FormatStyle
&Style
,
3119 const SmallVectorImpl
<IncludeDirective
> &Includes
,
3120 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
3121 StringRef Code
, tooling::Replacements
&Replaces
,
3123 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
3124 const unsigned IncludesBeginOffset
= Includes
.front().Offset
;
3125 const unsigned IncludesEndOffset
=
3126 Includes
.back().Offset
+ Includes
.back().Text
.size();
3127 const unsigned IncludesBlockSize
= IncludesEndOffset
- IncludesBeginOffset
;
3128 if (!affectsRange(Ranges
, IncludesBeginOffset
, IncludesEndOffset
))
3130 SmallVector
<unsigned, 16> Indices
=
3131 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Includes
.size()));
3133 if (Style
.SortIncludes
== FormatStyle::SI_CaseInsensitive
) {
3134 stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3135 const auto LHSFilenameLower
= Includes
[LHSI
].Filename
.lower();
3136 const auto RHSFilenameLower
= Includes
[RHSI
].Filename
.lower();
3137 return std::tie(Includes
[LHSI
].Priority
, LHSFilenameLower
,
3138 Includes
[LHSI
].Filename
) <
3139 std::tie(Includes
[RHSI
].Priority
, RHSFilenameLower
,
3140 Includes
[RHSI
].Filename
);
3143 stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3144 return std::tie(Includes
[LHSI
].Priority
, Includes
[LHSI
].Filename
) <
3145 std::tie(Includes
[RHSI
].Priority
, Includes
[RHSI
].Filename
);
3149 // The index of the include on which the cursor will be put after
3150 // sorting/deduplicating.
3151 unsigned CursorIndex
;
3152 // The offset from cursor to the end of line.
3153 unsigned CursorToEOLOffset
;
3155 std::tie(CursorIndex
, CursorToEOLOffset
) =
3156 FindCursorIndex(Includes
, Indices
, *Cursor
);
3159 // Deduplicate #includes.
3160 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
3161 [&](unsigned LHSI
, unsigned RHSI
) {
3162 return Includes
[LHSI
].Text
.trim() ==
3163 Includes
[RHSI
].Text
.trim();
3167 int CurrentCategory
= Includes
.front().Category
;
3169 // If the #includes are out of order, we generate a single replacement fixing
3170 // the entire block. Otherwise, no replacement is generated.
3171 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
3172 // enough as additional newlines might be added or removed across #include
3173 // blocks. This we handle below by generating the updated #include blocks and
3174 // comparing it to the original.
3175 if (Indices
.size() == Includes
.size() && is_sorted(Indices
) &&
3176 Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Preserve
) {
3180 const auto OldCursor
= Cursor
? *Cursor
: 0;
3182 for (unsigned Index
: Indices
) {
3183 if (!result
.empty()) {
3185 if (Style
.IncludeStyle
.IncludeBlocks
==
3186 tooling::IncludeStyle::IBS_Regroup
&&
3187 CurrentCategory
!= Includes
[Index
].Category
) {
3191 result
+= Includes
[Index
].Text
;
3192 if (Cursor
&& CursorIndex
== Index
)
3193 *Cursor
= IncludesBeginOffset
+ result
.size() - CursorToEOLOffset
;
3194 CurrentCategory
= Includes
[Index
].Category
;
3197 if (Cursor
&& *Cursor
>= IncludesEndOffset
)
3198 *Cursor
+= result
.size() - IncludesBlockSize
;
3200 // If the #includes are out of order, we generate a single replacement fixing
3201 // the entire range of blocks. Otherwise, no replacement is generated.
3202 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
3203 IncludesBeginOffset
, IncludesBlockSize
)))) {
3205 *Cursor
= OldCursor
;
3209 auto Err
= Replaces
.add(tooling::Replacement(
3210 FileName
, Includes
.front().Offset
, IncludesBlockSize
, result
));
3211 // FIXME: better error handling. For now, just skip the replacement for the
3214 llvm::errs() << toString(std::move(Err
)) << "\n";
3219 tooling::Replacements
sortCppIncludes(const FormatStyle
&Style
, StringRef Code
,
3220 ArrayRef
<tooling::Range
> Ranges
,
3222 tooling::Replacements
&Replaces
,
3224 unsigned Prev
= llvm::StringSwitch
<size_t>(Code
)
3225 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
3227 unsigned SearchFrom
= 0;
3228 SmallVector
<StringRef
, 4> Matches
;
3229 SmallVector
<IncludeDirective
, 16> IncludesInBlock
;
3231 // In compiled files, consider the first #include to be the main #include of
3232 // the file if it is not a system #include. This ensures that the header
3233 // doesn't have hidden dependencies
3234 // (http://llvm.org/docs/CodingStandards.html#include-style).
3236 // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3237 // cases where the first #include is unlikely to be the main header.
3238 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
3239 bool FirstIncludeBlock
= true;
3240 bool MainIncludeFound
= false;
3241 bool FormattingOff
= false;
3243 // '[' must be the first and '-' the last character inside [...].
3244 llvm::Regex
RawStringRegex(
3245 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3246 SmallVector
<StringRef
, 2> RawStringMatches
;
3247 std::string RawStringTermination
= ")\"";
3250 auto Pos
= Code
.find('\n', SearchFrom
);
3252 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3254 StringRef Trimmed
= Line
.trim();
3256 // #includes inside raw string literals need to be ignored.
3257 // or we will sort the contents of the string.
3258 // Skip past until we think we are at the rawstring literal close.
3259 if (RawStringRegex
.match(Trimmed
, &RawStringMatches
)) {
3260 std::string CharSequence
= RawStringMatches
[1].str();
3261 RawStringTermination
= ")" + CharSequence
+ "\"";
3262 FormattingOff
= true;
3265 if (Trimmed
.contains(RawStringTermination
))
3266 FormattingOff
= false;
3268 bool IsBlockComment
= false;
3270 if (isClangFormatOff(Trimmed
)) {
3271 FormattingOff
= true;
3272 } else if (isClangFormatOn(Trimmed
)) {
3273 FormattingOff
= false;
3274 } else if (Trimmed
.starts_with("/*")) {
3275 IsBlockComment
= true;
3276 Pos
= Code
.find("*/", SearchFrom
+ 2);
3279 const bool EmptyLineSkipped
=
3281 (Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Merge
||
3282 Style
.IncludeStyle
.IncludeBlocks
==
3283 tooling::IncludeStyle::IBS_Regroup
);
3285 bool MergeWithNextLine
= Trimmed
.ends_with("\\");
3286 if (!FormattingOff
&& !MergeWithNextLine
) {
3287 if (!IsBlockComment
&&
3288 tooling::HeaderIncludes::IncludeRegex
.match(Trimmed
, &Matches
)) {
3289 StringRef IncludeName
= Matches
[2];
3290 if (Trimmed
.contains("/*") && !Trimmed
.contains("*/")) {
3291 // #include with a start of a block comment, but without the end.
3292 // Need to keep all the lines until the end of the comment together.
3293 // FIXME: This is somehow simplified check that probably does not work
3294 // correctly if there are multiple comments on a line.
3295 Pos
= Code
.find("*/", SearchFrom
);
3297 Prev
, (Pos
!= StringRef::npos
? Pos
+ 2 : Code
.size()) - Prev
);
3299 int Category
= Categories
.getIncludePriority(
3301 /*CheckMainHeader=*/!MainIncludeFound
&& FirstIncludeBlock
);
3302 int Priority
= Categories
.getSortIncludePriority(
3303 IncludeName
, !MainIncludeFound
&& FirstIncludeBlock
);
3305 MainIncludeFound
= true;
3306 IncludesInBlock
.push_back(
3307 {IncludeName
, Line
, Prev
, Category
, Priority
});
3308 } else if (!IncludesInBlock
.empty() && !EmptyLineSkipped
) {
3309 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
,
3311 IncludesInBlock
.clear();
3312 if (Trimmed
.starts_with("#pragma hdrstop")) // Precompiled headers.
3313 FirstIncludeBlock
= true;
3315 FirstIncludeBlock
= false;
3318 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3321 if (!MergeWithNextLine
)
3323 SearchFrom
= Pos
+ 1;
3325 if (!IncludesInBlock
.empty()) {
3326 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
, Replaces
,
3332 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
3333 // if the import does not match any given groups.
3334 static unsigned findJavaImportGroup(const FormatStyle
&Style
,
3335 StringRef ImportIdentifier
) {
3336 unsigned LongestMatchIndex
= UINT_MAX
;
3337 unsigned LongestMatchLength
= 0;
3338 for (unsigned I
= 0; I
< Style
.JavaImportGroups
.size(); I
++) {
3339 const std::string
&GroupPrefix
= Style
.JavaImportGroups
[I
];
3340 if (ImportIdentifier
.starts_with(GroupPrefix
) &&
3341 GroupPrefix
.length() > LongestMatchLength
) {
3342 LongestMatchIndex
= I
;
3343 LongestMatchLength
= GroupPrefix
.length();
3346 return LongestMatchIndex
;
3349 // Sorts and deduplicates a block of includes given by 'Imports' based on
3350 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3351 // Import declarations with the same text will be deduplicated. Between each
3352 // import group, a newline is inserted, and within each import group, a
3353 // lexicographic sort based on ASCII value is performed.
3354 static void sortJavaImports(const FormatStyle
&Style
,
3355 const SmallVectorImpl
<JavaImportDirective
> &Imports
,
3356 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
3357 StringRef Code
, tooling::Replacements
&Replaces
) {
3358 unsigned ImportsBeginOffset
= Imports
.front().Offset
;
3359 unsigned ImportsEndOffset
=
3360 Imports
.back().Offset
+ Imports
.back().Text
.size();
3361 unsigned ImportsBlockSize
= ImportsEndOffset
- ImportsBeginOffset
;
3362 if (!affectsRange(Ranges
, ImportsBeginOffset
, ImportsEndOffset
))
3365 SmallVector
<unsigned, 16> Indices
=
3366 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Imports
.size()));
3367 SmallVector
<unsigned, 16> JavaImportGroups
;
3368 JavaImportGroups
.reserve(Imports
.size());
3369 for (const JavaImportDirective
&Import
: Imports
)
3370 JavaImportGroups
.push_back(findJavaImportGroup(Style
, Import
.Identifier
));
3372 bool StaticImportAfterNormalImport
=
3373 Style
.SortJavaStaticImport
== FormatStyle::SJSIO_After
;
3374 sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3375 // Negating IsStatic to push static imports above non-static imports.
3376 return std::make_tuple(!Imports
[LHSI
].IsStatic
^
3377 StaticImportAfterNormalImport
,
3378 JavaImportGroups
[LHSI
], Imports
[LHSI
].Identifier
) <
3379 std::make_tuple(!Imports
[RHSI
].IsStatic
^
3380 StaticImportAfterNormalImport
,
3381 JavaImportGroups
[RHSI
], Imports
[RHSI
].Identifier
);
3384 // Deduplicate imports.
3385 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
3386 [&](unsigned LHSI
, unsigned RHSI
) {
3387 return Imports
[LHSI
].Text
== Imports
[RHSI
].Text
;
3391 bool CurrentIsStatic
= Imports
[Indices
.front()].IsStatic
;
3392 unsigned CurrentImportGroup
= JavaImportGroups
[Indices
.front()];
3395 for (unsigned Index
: Indices
) {
3396 if (!result
.empty()) {
3398 if (CurrentIsStatic
!= Imports
[Index
].IsStatic
||
3399 CurrentImportGroup
!= JavaImportGroups
[Index
]) {
3403 for (StringRef CommentLine
: Imports
[Index
].AssociatedCommentLines
) {
3404 result
+= CommentLine
;
3407 result
+= Imports
[Index
].Text
;
3408 CurrentIsStatic
= Imports
[Index
].IsStatic
;
3409 CurrentImportGroup
= JavaImportGroups
[Index
];
3412 // If the imports are out of order, we generate a single replacement fixing
3413 // the entire block. Otherwise, no replacement is generated.
3414 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
3415 Imports
.front().Offset
, ImportsBlockSize
)))) {
3419 auto Err
= Replaces
.add(tooling::Replacement(FileName
, Imports
.front().Offset
,
3420 ImportsBlockSize
, result
));
3421 // FIXME: better error handling. For now, just skip the replacement for the
3424 llvm::errs() << toString(std::move(Err
)) << "\n";
3431 const char JavaImportRegexPattern
[] =
3432 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3434 } // anonymous namespace
3436 tooling::Replacements
sortJavaImports(const FormatStyle
&Style
, StringRef Code
,
3437 ArrayRef
<tooling::Range
> Ranges
,
3439 tooling::Replacements
&Replaces
) {
3441 unsigned SearchFrom
= 0;
3442 llvm::Regex
ImportRegex(JavaImportRegexPattern
);
3443 SmallVector
<StringRef
, 4> Matches
;
3444 SmallVector
<JavaImportDirective
, 16> ImportsInBlock
;
3445 SmallVector
<StringRef
> AssociatedCommentLines
;
3447 bool FormattingOff
= false;
3450 auto Pos
= Code
.find('\n', SearchFrom
);
3452 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3454 StringRef Trimmed
= Line
.trim();
3455 if (isClangFormatOff(Trimmed
))
3456 FormattingOff
= true;
3457 else if (isClangFormatOn(Trimmed
))
3458 FormattingOff
= false;
3460 if (ImportRegex
.match(Line
, &Matches
)) {
3461 if (FormattingOff
) {
3462 // If at least one import line has formatting turned off, turn off
3463 // formatting entirely.
3466 StringRef Static
= Matches
[1];
3467 StringRef Identifier
= Matches
[2];
3468 bool IsStatic
= false;
3469 if (Static
.contains("static"))
3471 ImportsInBlock
.push_back(
3472 {Identifier
, Line
, Prev
, AssociatedCommentLines
, IsStatic
});
3473 AssociatedCommentLines
.clear();
3474 } else if (Trimmed
.size() > 0 && !ImportsInBlock
.empty()) {
3475 // Associating comments within the imports with the nearest import below
3476 AssociatedCommentLines
.push_back(Line
);
3479 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3481 SearchFrom
= Pos
+ 1;
3483 if (!ImportsInBlock
.empty())
3484 sortJavaImports(Style
, ImportsInBlock
, Ranges
, FileName
, Code
, Replaces
);
3488 bool isMpegTS(StringRef Code
) {
3489 // MPEG transport streams use the ".ts" file extension. clang-format should
3490 // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3491 // 189 bytes - detect that and return.
3492 return Code
.size() > 188 && Code
[0] == 0x47 && Code
[188] == 0x47;
3495 bool isLikelyXml(StringRef Code
) { return Code
.ltrim().starts_with("<"); }
3497 tooling::Replacements
sortIncludes(const FormatStyle
&Style
, StringRef Code
,
3498 ArrayRef
<tooling::Range
> Ranges
,
3499 StringRef FileName
, unsigned *Cursor
) {
3500 tooling::Replacements Replaces
;
3501 if (!Style
.SortIncludes
|| Style
.DisableFormat
)
3503 if (isLikelyXml(Code
))
3505 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
&&
3509 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
)
3510 return sortJavaScriptImports(Style
, Code
, Ranges
, FileName
);
3511 if (Style
.Language
== FormatStyle::LanguageKind::LK_Java
)
3512 return sortJavaImports(Style
, Code
, Ranges
, FileName
, Replaces
);
3513 sortCppIncludes(Style
, Code
, Ranges
, FileName
, Replaces
, Cursor
);
3517 template <typename T
>
3518 static Expected
<tooling::Replacements
>
3519 processReplacements(T ProcessFunc
, StringRef Code
,
3520 const tooling::Replacements
&Replaces
,
3521 const FormatStyle
&Style
) {
3522 if (Replaces
.empty())
3523 return tooling::Replacements();
3525 auto NewCode
= applyAllReplacements(Code
, Replaces
);
3527 return NewCode
.takeError();
3528 std::vector
<tooling::Range
> ChangedRanges
= Replaces
.getAffectedRanges();
3529 StringRef FileName
= Replaces
.begin()->getFilePath();
3531 tooling::Replacements FormatReplaces
=
3532 ProcessFunc(Style
, *NewCode
, ChangedRanges
, FileName
);
3534 return Replaces
.merge(FormatReplaces
);
3537 Expected
<tooling::Replacements
>
3538 formatReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3539 const FormatStyle
&Style
) {
3540 // We need to use lambda function here since there are two versions of
3542 auto SortIncludes
= [](const FormatStyle
&Style
, StringRef Code
,
3543 std::vector
<tooling::Range
> Ranges
,
3544 StringRef FileName
) -> tooling::Replacements
{
3545 return sortIncludes(Style
, Code
, Ranges
, FileName
);
3547 auto SortedReplaces
=
3548 processReplacements(SortIncludes
, Code
, Replaces
, Style
);
3549 if (!SortedReplaces
)
3550 return SortedReplaces
.takeError();
3552 // We need to use lambda function here since there are two versions of
3554 auto Reformat
= [](const FormatStyle
&Style
, StringRef Code
,
3555 std::vector
<tooling::Range
> Ranges
,
3556 StringRef FileName
) -> tooling::Replacements
{
3557 return reformat(Style
, Code
, Ranges
, FileName
);
3559 return processReplacements(Reformat
, Code
, *SortedReplaces
, Style
);
3564 inline bool isHeaderInsertion(const tooling::Replacement
&Replace
) {
3565 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 0 &&
3566 tooling::HeaderIncludes::IncludeRegex
.match(
3567 Replace
.getReplacementText());
3570 inline bool isHeaderDeletion(const tooling::Replacement
&Replace
) {
3571 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 1;
3574 // FIXME: insert empty lines between newly created blocks.
3575 tooling::Replacements
3576 fixCppIncludeInsertions(StringRef Code
, const tooling::Replacements
&Replaces
,
3577 const FormatStyle
&Style
) {
3581 tooling::Replacements HeaderInsertions
;
3582 std::set
<StringRef
> HeadersToDelete
;
3583 tooling::Replacements Result
;
3584 for (const auto &R
: Replaces
) {
3585 if (isHeaderInsertion(R
)) {
3586 // Replacements from \p Replaces must be conflict-free already, so we can
3587 // simply consume the error.
3588 consumeError(HeaderInsertions
.add(R
));
3589 } else if (isHeaderDeletion(R
)) {
3590 HeadersToDelete
.insert(R
.getReplacementText());
3591 } else if (R
.getOffset() == UINT_MAX
) {
3592 llvm::errs() << "Insertions other than header #include insertion are "
3594 << R
.getReplacementText() << "\n";
3596 consumeError(Result
.add(R
));
3599 if (HeaderInsertions
.empty() && HeadersToDelete
.empty())
3602 StringRef FileName
= Replaces
.begin()->getFilePath();
3603 tooling::HeaderIncludes
Includes(FileName
, Code
, Style
.IncludeStyle
);
3605 for (const auto &Header
: HeadersToDelete
) {
3606 tooling::Replacements Replaces
=
3607 Includes
.remove(Header
.trim("\"<>"), Header
.starts_with("<"));
3608 for (const auto &R
: Replaces
) {
3609 auto Err
= Result
.add(R
);
3611 // Ignore the deletion on conflict.
3612 llvm::errs() << "Failed to add header deletion replacement for "
3613 << Header
<< ": " << toString(std::move(Err
)) << "\n";
3618 SmallVector
<StringRef
, 4> Matches
;
3619 for (const auto &R
: HeaderInsertions
) {
3620 auto IncludeDirective
= R
.getReplacementText();
3622 tooling::HeaderIncludes::IncludeRegex
.match(IncludeDirective
, &Matches
);
3623 assert(Matched
&& "Header insertion replacement must have replacement text "
3626 auto IncludeName
= Matches
[2];
3628 Includes
.insert(IncludeName
.trim("\"<>"), IncludeName
.starts_with("<"),
3629 tooling::IncludeDirective::Include
);
3631 auto Err
= Result
.add(*Replace
);
3633 consumeError(std::move(Err
));
3634 unsigned NewOffset
=
3635 Result
.getShiftedCodePosition(Replace
->getOffset());
3636 auto Shifted
= tooling::Replacement(FileName
, NewOffset
, 0,
3637 Replace
->getReplacementText());
3638 Result
= Result
.merge(tooling::Replacements(Shifted
));
3645 } // anonymous namespace
3647 Expected
<tooling::Replacements
>
3648 cleanupAroundReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3649 const FormatStyle
&Style
) {
3650 // We need to use lambda function here since there are two versions of
3652 auto Cleanup
= [](const FormatStyle
&Style
, StringRef Code
,
3653 ArrayRef
<tooling::Range
> Ranges
,
3654 StringRef FileName
) -> tooling::Replacements
{
3655 return cleanup(Style
, Code
, Ranges
, FileName
);
3657 // Make header insertion replacements insert new headers into correct blocks.
3658 tooling::Replacements NewReplaces
=
3659 fixCppIncludeInsertions(Code
, Replaces
, Style
);
3660 return cantFail(processReplacements(Cleanup
, Code
, NewReplaces
, Style
));
3663 namespace internal
{
3664 std::pair
<tooling::Replacements
, unsigned>
3665 reformat(const FormatStyle
&Style
, StringRef Code
,
3666 ArrayRef
<tooling::Range
> Ranges
, unsigned FirstStartColumn
,
3667 unsigned NextStartColumn
, unsigned LastStartColumn
, StringRef FileName
,
3668 FormattingAttemptStatus
*Status
) {
3669 FormatStyle Expanded
= Style
;
3670 expandPresetsBraceWrapping(Expanded
);
3671 expandPresetsSpaceBeforeParens(Expanded
);
3672 expandPresetsSpacesInParens(Expanded
);
3673 Expanded
.InsertBraces
= false;
3674 Expanded
.RemoveBracesLLVM
= false;
3675 Expanded
.RemoveParentheses
= FormatStyle::RPS_Leave
;
3676 Expanded
.RemoveSemicolon
= false;
3677 switch (Expanded
.RequiresClausePosition
) {
3678 case FormatStyle::RCPS_SingleLine
:
3679 case FormatStyle::RCPS_WithPreceding
:
3680 Expanded
.IndentRequiresClause
= false;
3686 if (Expanded
.DisableFormat
)
3687 return {tooling::Replacements(), 0};
3688 if (isLikelyXml(Code
))
3689 return {tooling::Replacements(), 0};
3690 if (Expanded
.Language
== FormatStyle::LK_JavaScript
&& isMpegTS(Code
))
3691 return {tooling::Replacements(), 0};
3693 // JSON only needs the formatting passing.
3694 if (Style
.isJson()) {
3695 std::vector
<tooling::Range
> Ranges(1, tooling::Range(0, Code
.size()));
3696 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3697 NextStartColumn
, LastStartColumn
);
3700 // Perform the actual formatting pass.
3701 tooling::Replacements Replaces
=
3702 Formatter(*Env
, Style
, Status
).process().first
;
3703 // add a replacement to remove the "x = " from the result.
3704 Replaces
= Replaces
.merge(
3705 tooling::Replacements(tooling::Replacement(FileName
, 0, 4, "")));
3706 // apply the reformatting changes and the removal of "x = ".
3707 if (applyAllReplacements(Code
, Replaces
))
3708 return {Replaces
, 0};
3709 return {tooling::Replacements(), 0};
3712 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3713 NextStartColumn
, LastStartColumn
);
3717 typedef std::function
<std::pair
<tooling::Replacements
, unsigned>(
3718 const Environment
&)>
3721 SmallVector
<AnalyzerPass
, 16> Passes
;
3723 Passes
.emplace_back([&](const Environment
&Env
) {
3724 return IntegerLiteralSeparatorFixer().process(Env
, Expanded
);
3727 if (Style
.isCpp()) {
3728 if (Style
.QualifierAlignment
!= FormatStyle::QAS_Leave
)
3729 addQualifierAlignmentFixerPasses(Expanded
, Passes
);
3731 if (Style
.RemoveParentheses
!= FormatStyle::RPS_Leave
) {
3732 FormatStyle S
= Expanded
;
3733 S
.RemoveParentheses
= Style
.RemoveParentheses
;
3734 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3735 return ParensRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3739 if (Style
.InsertBraces
) {
3740 FormatStyle S
= Expanded
;
3741 S
.InsertBraces
= true;
3742 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3743 return BracesInserter(Env
, S
).process(/*SkipAnnotation=*/true);
3747 if (Style
.RemoveBracesLLVM
) {
3748 FormatStyle S
= Expanded
;
3749 S
.RemoveBracesLLVM
= true;
3750 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3751 return BracesRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3755 if (Style
.RemoveSemicolon
) {
3756 FormatStyle S
= Expanded
;
3757 S
.RemoveSemicolon
= true;
3758 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3759 return SemiRemover(Env
, S
).process();
3763 if (Style
.FixNamespaceComments
) {
3764 Passes
.emplace_back([&](const Environment
&Env
) {
3765 return NamespaceEndCommentsFixer(Env
, Expanded
).process();
3769 if (Style
.SortUsingDeclarations
!= FormatStyle::SUD_Never
) {
3770 Passes
.emplace_back([&](const Environment
&Env
) {
3771 return UsingDeclarationsSorter(Env
, Expanded
).process();
3776 if (Style
.SeparateDefinitionBlocks
!= FormatStyle::SDS_Leave
) {
3777 Passes
.emplace_back([&](const Environment
&Env
) {
3778 return DefinitionBlockSeparator(Env
, Expanded
).process();
3782 if (Style
.Language
== FormatStyle::LK_ObjC
&&
3783 !Style
.ObjCPropertyAttributeOrder
.empty()) {
3784 Passes
.emplace_back([&](const Environment
&Env
) {
3785 return ObjCPropertyAttributeOrderFixer(Env
, Expanded
).process();
3789 if (Style
.isJavaScript() &&
3790 Style
.JavaScriptQuotes
!= FormatStyle::JSQS_Leave
) {
3791 Passes
.emplace_back([&](const Environment
&Env
) {
3792 return JavaScriptRequoter(Env
, Expanded
).process(/*SkipAnnotation=*/true);
3796 Passes
.emplace_back([&](const Environment
&Env
) {
3797 return Formatter(Env
, Expanded
, Status
).process();
3800 if (Style
.isJavaScript() &&
3801 Style
.InsertTrailingCommas
== FormatStyle::TCS_Wrapped
) {
3802 Passes
.emplace_back([&](const Environment
&Env
) {
3803 return TrailingCommaInserter(Env
, Expanded
).process();
3807 std::optional
<std::string
> CurrentCode
;
3808 tooling::Replacements Fixes
;
3809 unsigned Penalty
= 0;
3810 for (size_t I
= 0, E
= Passes
.size(); I
< E
; ++I
) {
3811 std::pair
<tooling::Replacements
, unsigned> PassFixes
= Passes
[I
](*Env
);
3812 auto NewCode
= applyAllReplacements(
3813 CurrentCode
? StringRef(*CurrentCode
) : Code
, PassFixes
.first
);
3815 Fixes
= Fixes
.merge(PassFixes
.first
);
3816 Penalty
+= PassFixes
.second
;
3818 CurrentCode
= std::move(*NewCode
);
3819 Env
= Environment::make(
3820 *CurrentCode
, FileName
,
3821 tooling::calculateRangesAfterReplacements(Fixes
, Ranges
),
3822 FirstStartColumn
, NextStartColumn
, LastStartColumn
);
3829 if (Style
.QualifierAlignment
!= FormatStyle::QAS_Leave
) {
3830 // Don't make replacements that replace nothing. QualifierAlignment can
3831 // produce them if one of its early passes changes e.g. `const volatile` to
3832 // `volatile const` and then a later pass changes it back again.
3833 tooling::Replacements NonNoOpFixes
;
3834 for (const tooling::Replacement
&Fix
: Fixes
) {
3835 StringRef OriginalCode
= Code
.substr(Fix
.getOffset(), Fix
.getLength());
3836 if (OriginalCode
!= Fix
.getReplacementText()) {
3837 auto Err
= NonNoOpFixes
.add(Fix
);
3839 llvm::errs() << "Error adding replacements : "
3840 << toString(std::move(Err
)) << "\n";
3844 Fixes
= std::move(NonNoOpFixes
);
3847 return {Fixes
, Penalty
};
3849 } // namespace internal
3851 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3852 ArrayRef
<tooling::Range
> Ranges
,
3854 FormattingAttemptStatus
*Status
) {
3855 return internal::reformat(Style
, Code
, Ranges
,
3856 /*FirstStartColumn=*/0,
3857 /*NextStartColumn=*/0,
3858 /*LastStartColumn=*/0, FileName
, Status
)
3862 tooling::Replacements
cleanup(const FormatStyle
&Style
, StringRef Code
,
3863 ArrayRef
<tooling::Range
> Ranges
,
3864 StringRef FileName
) {
3865 // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3866 if (Style
.Language
!= FormatStyle::LK_Cpp
)
3867 return tooling::Replacements();
3868 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3871 return Cleaner(*Env
, Style
).process().first
;
3874 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3875 ArrayRef
<tooling::Range
> Ranges
,
3876 StringRef FileName
, bool *IncompleteFormat
) {
3877 FormattingAttemptStatus Status
;
3878 auto Result
= reformat(Style
, Code
, Ranges
, FileName
, &Status
);
3879 if (!Status
.FormatComplete
)
3880 *IncompleteFormat
= true;
3884 tooling::Replacements
fixNamespaceEndComments(const FormatStyle
&Style
,
3886 ArrayRef
<tooling::Range
> Ranges
,
3887 StringRef FileName
) {
3888 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3891 return NamespaceEndCommentsFixer(*Env
, Style
).process().first
;
3894 tooling::Replacements
sortUsingDeclarations(const FormatStyle
&Style
,
3896 ArrayRef
<tooling::Range
> Ranges
,
3897 StringRef FileName
) {
3898 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3901 return UsingDeclarationsSorter(*Env
, Style
).process().first
;
3904 LangOptions
getFormattingLangOpts(const FormatStyle
&Style
) {
3905 LangOptions LangOpts
;
3907 FormatStyle::LanguageStandard LexingStd
= Style
.Standard
;
3908 if (LexingStd
== FormatStyle::LS_Auto
)
3909 LexingStd
= FormatStyle::LS_Latest
;
3910 if (LexingStd
== FormatStyle::LS_Latest
)
3911 LexingStd
= FormatStyle::LS_Cpp20
;
3912 LangOpts
.CPlusPlus
= 1;
3913 LangOpts
.CPlusPlus11
= LexingStd
>= FormatStyle::LS_Cpp11
;
3914 LangOpts
.CPlusPlus14
= LexingStd
>= FormatStyle::LS_Cpp14
;
3915 LangOpts
.CPlusPlus17
= LexingStd
>= FormatStyle::LS_Cpp17
;
3916 LangOpts
.CPlusPlus20
= LexingStd
>= FormatStyle::LS_Cpp20
;
3917 LangOpts
.Char8
= LexingStd
>= FormatStyle::LS_Cpp20
;
3918 // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3919 // the sequence "<::" will be unconditionally treated as "[:".
3920 // Cf. Lexer::LexTokenInternal.
3921 LangOpts
.Digraphs
= LexingStd
>= FormatStyle::LS_Cpp11
;
3923 LangOpts
.LineComment
= 1;
3924 LangOpts
.CXXOperatorNames
= Style
.isCpp();
3927 LangOpts
.MicrosoftExt
= 1; // To get kw___try, kw___finally.
3928 LangOpts
.DeclSpecKeyword
= 1; // To get __declspec.
3929 LangOpts
.C99
= 1; // To get kw_restrict for non-underscore-prefixed restrict.
3933 const char *StyleOptionHelpDescription
=
3934 "Set coding style. <string> can be:\n"
3935 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3936 " Mozilla, WebKit.\n"
3937 "2. 'file' to load style configuration from a\n"
3938 " .clang-format file in one of the parent directories\n"
3939 " of the source file (for stdin, see --assume-filename).\n"
3940 " If no .clang-format file is found, falls back to\n"
3941 " --fallback-style.\n"
3942 " --style=file is the default.\n"
3943 "3. 'file:<format_file_path>' to explicitly specify\n"
3944 " the configuration file.\n"
3945 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3946 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3948 static FormatStyle::LanguageKind
getLanguageByFileName(StringRef FileName
) {
3949 if (FileName
.ends_with(".java"))
3950 return FormatStyle::LK_Java
;
3951 if (FileName
.ends_with_insensitive(".js") ||
3952 FileName
.ends_with_insensitive(".mjs") ||
3953 FileName
.ends_with_insensitive(".cjs") ||
3954 FileName
.ends_with_insensitive(".ts")) {
3955 return FormatStyle::LK_JavaScript
; // (module) JavaScript or TypeScript.
3957 if (FileName
.ends_with(".m") || FileName
.ends_with(".mm"))
3958 return FormatStyle::LK_ObjC
;
3959 if (FileName
.ends_with_insensitive(".proto") ||
3960 FileName
.ends_with_insensitive(".protodevel")) {
3961 return FormatStyle::LK_Proto
;
3963 // txtpb is the canonical extension, and textproto is the legacy canonical
3965 // https://protobuf.dev/reference/protobuf/textformat-spec/#text-format-files
3966 if (FileName
.ends_with_insensitive(".txtpb") ||
3967 FileName
.ends_with_insensitive(".textpb") ||
3968 FileName
.ends_with_insensitive(".pb.txt") ||
3969 FileName
.ends_with_insensitive(".textproto") ||
3970 FileName
.ends_with_insensitive(".asciipb")) {
3971 return FormatStyle::LK_TextProto
;
3973 if (FileName
.ends_with_insensitive(".td"))
3974 return FormatStyle::LK_TableGen
;
3975 if (FileName
.ends_with_insensitive(".cs"))
3976 return FormatStyle::LK_CSharp
;
3977 if (FileName
.ends_with_insensitive(".json"))
3978 return FormatStyle::LK_Json
;
3979 if (FileName
.ends_with_insensitive(".sv") ||
3980 FileName
.ends_with_insensitive(".svh") ||
3981 FileName
.ends_with_insensitive(".v") ||
3982 FileName
.ends_with_insensitive(".vh")) {
3983 return FormatStyle::LK_Verilog
;
3985 return FormatStyle::LK_Cpp
;
3988 FormatStyle::LanguageKind
guessLanguage(StringRef FileName
, StringRef Code
) {
3989 const auto GuessedLanguage
= getLanguageByFileName(FileName
);
3990 if (GuessedLanguage
== FormatStyle::LK_Cpp
) {
3991 auto Extension
= llvm::sys::path::extension(FileName
);
3992 // If there's no file extension (or it's .h), we need to check the contents
3993 // of the code to see if it contains Objective-C.
3994 if (!Code
.empty() && (Extension
.empty() || Extension
== ".h")) {
3995 auto NonEmptyFileName
= FileName
.empty() ? "guess.h" : FileName
;
3996 Environment
Env(Code
, NonEmptyFileName
, /*Ranges=*/{});
3997 ObjCHeaderStyleGuesser
Guesser(Env
, getLLVMStyle());
3999 if (Guesser
.isObjC())
4000 return FormatStyle::LK_ObjC
;
4003 return GuessedLanguage
;
4006 // Update StyleOptionHelpDescription above when changing this.
4007 const char *DefaultFormatStyle
= "file";
4009 const char *DefaultFallbackStyle
= "LLVM";
4011 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>
4012 loadAndParseConfigFile(StringRef ConfigFile
, llvm::vfs::FileSystem
*FS
,
4013 FormatStyle
*Style
, bool AllowUnknownOptions
,
4014 llvm::SourceMgr::DiagHandlerTy DiagHandler
) {
4015 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
4016 FS
->getBufferForFile(ConfigFile
.str());
4017 if (auto EC
= Text
.getError())
4019 if (auto EC
= parseConfiguration(*Text
.get(), Style
, AllowUnknownOptions
,
4026 Expected
<FormatStyle
> getStyle(StringRef StyleName
, StringRef FileName
,
4027 StringRef FallbackStyleName
, StringRef Code
,
4028 llvm::vfs::FileSystem
*FS
,
4029 bool AllowUnknownOptions
,
4030 llvm::SourceMgr::DiagHandlerTy DiagHandler
) {
4031 FormatStyle Style
= getLLVMStyle(guessLanguage(FileName
, Code
));
4032 FormatStyle FallbackStyle
= getNoStyle();
4033 if (!getPredefinedStyle(FallbackStyleName
, Style
.Language
, &FallbackStyle
))
4034 return make_string_error("Invalid fallback style: " + FallbackStyleName
);
4036 SmallVector
<std::unique_ptr
<llvm::MemoryBuffer
>, 1> ChildFormatTextToApply
;
4038 if (StyleName
.starts_with("{")) {
4039 // Parse YAML/JSON style from the command line.
4040 StringRef Source
= "<command-line>";
4041 if (std::error_code ec
=
4042 parseConfiguration(llvm::MemoryBufferRef(StyleName
, Source
), &Style
,
4043 AllowUnknownOptions
, DiagHandler
)) {
4044 return make_string_error("Error parsing -style: " + ec
.message());
4047 if (!Style
.InheritsParentConfig
)
4050 ChildFormatTextToApply
.emplace_back(
4051 llvm::MemoryBuffer::getMemBuffer(StyleName
, Source
, false));
4055 FS
= llvm::vfs::getRealFileSystem().get();
4058 // User provided clang-format file using -style=file:path/to/format/file.
4059 if (!Style
.InheritsParentConfig
&&
4060 StyleName
.starts_with_insensitive("file:")) {
4061 auto ConfigFile
= StyleName
.substr(5);
4062 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
4063 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
,
4065 if (auto EC
= Text
.getError()) {
4066 return make_string_error("Error reading " + ConfigFile
+ ": " +
4070 LLVM_DEBUG(llvm::dbgs()
4071 << "Using configuration file " << ConfigFile
<< "\n");
4073 if (!Style
.InheritsParentConfig
)
4076 // Search for parent configs starting from the parent directory of
4078 FileName
= ConfigFile
;
4079 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
4082 // If the style inherits the parent configuration it is a command line
4083 // configuration, which wants to inherit, so we have to skip the check of the
4085 if (!Style
.InheritsParentConfig
&& !StyleName
.equals_insensitive("file")) {
4086 if (!getPredefinedStyle(StyleName
, Style
.Language
, &Style
))
4087 return make_string_error("Invalid value for -style");
4088 if (!Style
.InheritsParentConfig
)
4092 SmallString
<128> Path(FileName
);
4093 if (std::error_code EC
= FS
->makeAbsolute(Path
))
4094 return make_string_error(EC
.message());
4096 // Reset possible inheritance
4097 Style
.InheritsParentConfig
= false;
4099 auto dropDiagnosticHandler
= [](const llvm::SMDiagnostic
&, void *) {};
4101 auto applyChildFormatTexts
= [&](FormatStyle
*Style
) {
4102 for (const auto &MemBuf
: llvm::reverse(ChildFormatTextToApply
)) {
4104 parseConfiguration(*MemBuf
, Style
, AllowUnknownOptions
,
4105 DiagHandler
? DiagHandler
: dropDiagnosticHandler
);
4106 // It was already correctly parsed.
4108 static_cast<void>(EC
);
4112 // Look for .clang-format/_clang-format file in the file's parent directories.
4113 SmallVector
<std::string
, 2> FilesToLookFor
;
4114 FilesToLookFor
.push_back(".clang-format");
4115 FilesToLookFor
.push_back("_clang-format");
4117 SmallString
<128> UnsuitableConfigFiles
;
4118 for (StringRef Directory
= Path
; !Directory
.empty();
4119 Directory
= llvm::sys::path::parent_path(Directory
)) {
4120 auto Status
= FS
->status(Directory
);
4122 Status
->getType() != llvm::sys::fs::file_type::directory_file
) {
4126 for (const auto &F
: FilesToLookFor
) {
4127 SmallString
<128> ConfigFile(Directory
);
4129 llvm::sys::path::append(ConfigFile
, F
);
4130 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile
<< "...\n");
4132 Status
= FS
->status(ConfigFile
);
4134 Status
->getType() != llvm::sys::fs::file_type::regular_file
) {
4138 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
4139 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
,
4141 if (auto EC
= Text
.getError()) {
4142 if (EC
!= ParseError::Unsuitable
) {
4143 return make_string_error("Error reading " + ConfigFile
+ ": " +
4146 if (!UnsuitableConfigFiles
.empty())
4147 UnsuitableConfigFiles
.append(", ");
4148 UnsuitableConfigFiles
.append(ConfigFile
);
4152 LLVM_DEBUG(llvm::dbgs()
4153 << "Using configuration file " << ConfigFile
<< "\n");
4155 if (!Style
.InheritsParentConfig
) {
4156 if (!ChildFormatTextToApply
.empty()) {
4157 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4158 applyChildFormatTexts(&Style
);
4163 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4165 // Reset inheritance of style
4166 Style
.InheritsParentConfig
= false;
4168 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
4170 // Breaking out of the inner loop, since we don't want to parse
4171 // .clang-format AND _clang-format, if both exist. Then we continue the
4172 // outer loop (parent directories) in search for the parent
4178 if (!UnsuitableConfigFiles
.empty()) {
4179 return make_string_error("Configuration file(s) do(es) not support " +
4180 getLanguageName(Style
.Language
) + ": " +
4181 UnsuitableConfigFiles
);
4184 if (!ChildFormatTextToApply
.empty()) {
4185 LLVM_DEBUG(llvm::dbgs()
4186 << "Applying child configurations on fallback style\n");
4187 applyChildFormatTexts(&FallbackStyle
);
4190 return FallbackStyle
;
4193 static bool isClangFormatOnOff(StringRef Comment
, bool On
) {
4194 if (Comment
== (On
? "/* clang-format on */" : "/* clang-format off */"))
4197 static const char ClangFormatOn
[] = "// clang-format on";
4198 static const char ClangFormatOff
[] = "// clang-format off";
4199 const unsigned Size
= (On
? sizeof ClangFormatOn
: sizeof ClangFormatOff
) - 1;
4201 return Comment
.starts_with(On
? ClangFormatOn
: ClangFormatOff
) &&
4202 (Comment
.size() == Size
|| Comment
[Size
] == ':');
4205 bool isClangFormatOn(StringRef Comment
) {
4206 return isClangFormatOnOff(Comment
, /*On=*/true);
4209 bool isClangFormatOff(StringRef Comment
) {
4210 return isClangFormatOnOff(Comment
, /*On=*/false);
4213 } // namespace format
4214 } // namespace clang