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 "AffectedRangeManager.h"
17 #include "BreakableToken.h"
18 #include "ContinuationIndenter.h"
19 #include "DefinitionBlockSeparator.h"
20 #include "FormatInternal.h"
21 #include "FormatToken.h"
22 #include "FormatTokenLexer.h"
23 #include "IntegerLiteralSeparatorFixer.h"
24 #include "NamespaceEndCommentsFixer.h"
25 #include "QualifierAlignmentFixer.h"
26 #include "SortJavaScriptImports.h"
27 #include "TokenAnalyzer.h"
28 #include "TokenAnnotator.h"
29 #include "UnwrappedLineFormatter.h"
30 #include "UnwrappedLineParser.h"
31 #include "UsingDeclarationsSorter.h"
32 #include "WhitespaceManager.h"
33 #include "clang/Basic/Diagnostic.h"
34 #include "clang/Basic/DiagnosticOptions.h"
35 #include "clang/Basic/SourceManager.h"
36 #include "clang/Lex/Lexer.h"
37 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
38 #include "llvm/ADT/STLExtras.h"
39 #include "llvm/ADT/Sequence.h"
40 #include "llvm/ADT/StringRef.h"
41 #include "llvm/Support/Allocator.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/Regex.h"
45 #include "llvm/Support/VirtualFileSystem.h"
46 #include "llvm/Support/YAMLTraits.h"
52 #include <unordered_map>
54 #define DEBUG_TYPE "format-formatter"
56 using clang::format::FormatStyle
;
58 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat
)
62 template <> struct MappingTraits
<FormatStyle::AlignConsecutiveStyle
> {
63 static void enumInput(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
64 IO
.enumCase(Value
, "None",
65 FormatStyle::AlignConsecutiveStyle(
66 {/*Enabled=*/false, /*AcrossEmptyLines=*/false,
67 /*AcrossComments=*/false, /*AlignCompound=*/false,
68 /*PadOperators=*/true}));
69 IO
.enumCase(Value
, "Consecutive",
70 FormatStyle::AlignConsecutiveStyle(
71 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
72 /*AcrossComments=*/false, /*AlignCompound=*/false,
73 /*PadOperators=*/true}));
74 IO
.enumCase(Value
, "AcrossEmptyLines",
75 FormatStyle::AlignConsecutiveStyle(
76 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
77 /*AcrossComments=*/false, /*AlignCompound=*/false,
78 /*PadOperators=*/true}));
79 IO
.enumCase(Value
, "AcrossComments",
80 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true,
81 /*AcrossEmptyLines=*/false,
82 /*AcrossComments=*/true,
83 /*AlignCompound=*/false,
84 /*PadOperators=*/true}));
85 IO
.enumCase(Value
, "AcrossEmptyLinesAndComments",
86 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true,
87 /*AcrossEmptyLines=*/true,
88 /*AcrossComments=*/true,
89 /*AlignCompound=*/false,
90 /*PadOperators=*/true}));
92 // For backward compatibility.
93 IO
.enumCase(Value
, "true",
94 FormatStyle::AlignConsecutiveStyle(
95 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
96 /*AcrossComments=*/false, /*AlignCompound=*/false,
97 /*PadOperators=*/true}));
98 IO
.enumCase(Value
, "false",
99 FormatStyle::AlignConsecutiveStyle(
100 {/*Enabled=*/false, /*AcrossEmptyLines=*/false,
101 /*AcrossComments=*/false, /*AlignCompound=*/false,
102 /*PadOperators=*/true}));
105 static void mapping(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
106 IO
.mapOptional("Enabled", Value
.Enabled
);
107 IO
.mapOptional("AcrossEmptyLines", Value
.AcrossEmptyLines
);
108 IO
.mapOptional("AcrossComments", Value
.AcrossComments
);
109 IO
.mapOptional("AlignCompound", Value
.AlignCompound
);
110 IO
.mapOptional("PadOperators", Value
.PadOperators
);
115 struct ScalarEnumerationTraits
<FormatStyle::AttributeBreakingStyle
> {
116 static void enumeration(IO
&IO
, FormatStyle::AttributeBreakingStyle
&Value
) {
117 IO
.enumCase(Value
, "Always", FormatStyle::ABS_Always
);
118 IO
.enumCase(Value
, "Leave", FormatStyle::ABS_Leave
);
119 IO
.enumCase(Value
, "Never", FormatStyle::ABS_Never
);
124 struct ScalarEnumerationTraits
<FormatStyle::ArrayInitializerAlignmentStyle
> {
125 static void enumeration(IO
&IO
,
126 FormatStyle::ArrayInitializerAlignmentStyle
&Value
) {
127 IO
.enumCase(Value
, "None", FormatStyle::AIAS_None
);
128 IO
.enumCase(Value
, "Left", FormatStyle::AIAS_Left
);
129 IO
.enumCase(Value
, "Right", FormatStyle::AIAS_Right
);
133 template <> struct ScalarEnumerationTraits
<FormatStyle::BinaryOperatorStyle
> {
134 static void enumeration(IO
&IO
, FormatStyle::BinaryOperatorStyle
&Value
) {
135 IO
.enumCase(Value
, "All", FormatStyle::BOS_All
);
136 IO
.enumCase(Value
, "true", FormatStyle::BOS_All
);
137 IO
.enumCase(Value
, "None", FormatStyle::BOS_None
);
138 IO
.enumCase(Value
, "false", FormatStyle::BOS_None
);
139 IO
.enumCase(Value
, "NonAssignment", FormatStyle::BOS_NonAssignment
);
143 template <> struct ScalarEnumerationTraits
<FormatStyle::BinPackStyle
> {
144 static void enumeration(IO
&IO
, FormatStyle::BinPackStyle
&Value
) {
145 IO
.enumCase(Value
, "Auto", FormatStyle::BPS_Auto
);
146 IO
.enumCase(Value
, "Always", FormatStyle::BPS_Always
);
147 IO
.enumCase(Value
, "Never", FormatStyle::BPS_Never
);
152 struct ScalarEnumerationTraits
<FormatStyle::BitFieldColonSpacingStyle
> {
153 static void enumeration(IO
&IO
,
154 FormatStyle::BitFieldColonSpacingStyle
&Value
) {
155 IO
.enumCase(Value
, "Both", FormatStyle::BFCS_Both
);
156 IO
.enumCase(Value
, "None", FormatStyle::BFCS_None
);
157 IO
.enumCase(Value
, "Before", FormatStyle::BFCS_Before
);
158 IO
.enumCase(Value
, "After", FormatStyle::BFCS_After
);
162 template <> struct ScalarEnumerationTraits
<FormatStyle::BraceBreakingStyle
> {
163 static void enumeration(IO
&IO
, FormatStyle::BraceBreakingStyle
&Value
) {
164 IO
.enumCase(Value
, "Attach", FormatStyle::BS_Attach
);
165 IO
.enumCase(Value
, "Linux", FormatStyle::BS_Linux
);
166 IO
.enumCase(Value
, "Mozilla", FormatStyle::BS_Mozilla
);
167 IO
.enumCase(Value
, "Stroustrup", FormatStyle::BS_Stroustrup
);
168 IO
.enumCase(Value
, "Allman", FormatStyle::BS_Allman
);
169 IO
.enumCase(Value
, "Whitesmiths", FormatStyle::BS_Whitesmiths
);
170 IO
.enumCase(Value
, "GNU", FormatStyle::BS_GNU
);
171 IO
.enumCase(Value
, "WebKit", FormatStyle::BS_WebKit
);
172 IO
.enumCase(Value
, "Custom", FormatStyle::BS_Custom
);
176 template <> struct MappingTraits
<FormatStyle::BraceWrappingFlags
> {
177 static void mapping(IO
&IO
, FormatStyle::BraceWrappingFlags
&Wrapping
) {
178 IO
.mapOptional("AfterCaseLabel", Wrapping
.AfterCaseLabel
);
179 IO
.mapOptional("AfterClass", Wrapping
.AfterClass
);
180 IO
.mapOptional("AfterControlStatement", Wrapping
.AfterControlStatement
);
181 IO
.mapOptional("AfterEnum", Wrapping
.AfterEnum
);
182 IO
.mapOptional("AfterExternBlock", Wrapping
.AfterExternBlock
);
183 IO
.mapOptional("AfterFunction", Wrapping
.AfterFunction
);
184 IO
.mapOptional("AfterNamespace", Wrapping
.AfterNamespace
);
185 IO
.mapOptional("AfterObjCDeclaration", Wrapping
.AfterObjCDeclaration
);
186 IO
.mapOptional("AfterStruct", Wrapping
.AfterStruct
);
187 IO
.mapOptional("AfterUnion", Wrapping
.AfterUnion
);
188 IO
.mapOptional("BeforeCatch", Wrapping
.BeforeCatch
);
189 IO
.mapOptional("BeforeElse", Wrapping
.BeforeElse
);
190 IO
.mapOptional("BeforeLambdaBody", Wrapping
.BeforeLambdaBody
);
191 IO
.mapOptional("BeforeWhile", Wrapping
.BeforeWhile
);
192 IO
.mapOptional("IndentBraces", Wrapping
.IndentBraces
);
193 IO
.mapOptional("SplitEmptyFunction", Wrapping
.SplitEmptyFunction
);
194 IO
.mapOptional("SplitEmptyRecord", Wrapping
.SplitEmptyRecord
);
195 IO
.mapOptional("SplitEmptyNamespace", Wrapping
.SplitEmptyNamespace
);
199 template <> struct ScalarEnumerationTraits
<FormatStyle::BracketAlignmentStyle
> {
200 static void enumeration(IO
&IO
, FormatStyle::BracketAlignmentStyle
&Value
) {
201 IO
.enumCase(Value
, "Align", FormatStyle::BAS_Align
);
202 IO
.enumCase(Value
, "DontAlign", FormatStyle::BAS_DontAlign
);
203 IO
.enumCase(Value
, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak
);
204 IO
.enumCase(Value
, "BlockIndent", FormatStyle::BAS_BlockIndent
);
206 // For backward compatibility.
207 IO
.enumCase(Value
, "true", FormatStyle::BAS_Align
);
208 IO
.enumCase(Value
, "false", FormatStyle::BAS_DontAlign
);
213 struct ScalarEnumerationTraits
<
214 FormatStyle::BraceWrappingAfterControlStatementStyle
> {
217 FormatStyle::BraceWrappingAfterControlStatementStyle
&Value
) {
218 IO
.enumCase(Value
, "Never", FormatStyle::BWACS_Never
);
219 IO
.enumCase(Value
, "MultiLine", FormatStyle::BWACS_MultiLine
);
220 IO
.enumCase(Value
, "Always", FormatStyle::BWACS_Always
);
222 // For backward compatibility.
223 IO
.enumCase(Value
, "false", FormatStyle::BWACS_Never
);
224 IO
.enumCase(Value
, "true", FormatStyle::BWACS_Always
);
229 struct ScalarEnumerationTraits
<
230 FormatStyle::BreakBeforeConceptDeclarationsStyle
> {
232 enumeration(IO
&IO
, FormatStyle::BreakBeforeConceptDeclarationsStyle
&Value
) {
233 IO
.enumCase(Value
, "Never", FormatStyle::BBCDS_Never
);
234 IO
.enumCase(Value
, "Allowed", FormatStyle::BBCDS_Allowed
);
235 IO
.enumCase(Value
, "Always", FormatStyle::BBCDS_Always
);
237 // For backward compatibility.
238 IO
.enumCase(Value
, "true", FormatStyle::BBCDS_Always
);
239 IO
.enumCase(Value
, "false", FormatStyle::BBCDS_Allowed
);
244 struct ScalarEnumerationTraits
<FormatStyle::BreakBeforeInlineASMColonStyle
> {
245 static void enumeration(IO
&IO
,
246 FormatStyle::BreakBeforeInlineASMColonStyle
&Value
) {
247 IO
.enumCase(Value
, "Never", FormatStyle::BBIAS_Never
);
248 IO
.enumCase(Value
, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline
);
249 IO
.enumCase(Value
, "Always", FormatStyle::BBIAS_Always
);
253 struct ScalarEnumerationTraits
<FormatStyle::BreakConstructorInitializersStyle
> {
255 enumeration(IO
&IO
, FormatStyle::BreakConstructorInitializersStyle
&Value
) {
256 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BCIS_BeforeColon
);
257 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BCIS_BeforeComma
);
258 IO
.enumCase(Value
, "AfterColon", FormatStyle::BCIS_AfterColon
);
263 struct ScalarEnumerationTraits
<FormatStyle::BreakInheritanceListStyle
> {
264 static void enumeration(IO
&IO
,
265 FormatStyle::BreakInheritanceListStyle
&Value
) {
266 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BILS_BeforeColon
);
267 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BILS_BeforeComma
);
268 IO
.enumCase(Value
, "AfterColon", FormatStyle::BILS_AfterColon
);
269 IO
.enumCase(Value
, "AfterComma", FormatStyle::BILS_AfterComma
);
274 struct ScalarEnumerationTraits
<FormatStyle::BreakTemplateDeclarationsStyle
> {
275 static void enumeration(IO
&IO
,
276 FormatStyle::BreakTemplateDeclarationsStyle
&Value
) {
277 IO
.enumCase(Value
, "No", FormatStyle::BTDS_No
);
278 IO
.enumCase(Value
, "MultiLine", FormatStyle::BTDS_MultiLine
);
279 IO
.enumCase(Value
, "Yes", FormatStyle::BTDS_Yes
);
281 // For backward compatibility.
282 IO
.enumCase(Value
, "false", FormatStyle::BTDS_MultiLine
);
283 IO
.enumCase(Value
, "true", FormatStyle::BTDS_Yes
);
288 struct ScalarEnumerationTraits
<FormatStyle::DefinitionReturnTypeBreakingStyle
> {
290 enumeration(IO
&IO
, FormatStyle::DefinitionReturnTypeBreakingStyle
&Value
) {
291 IO
.enumCase(Value
, "None", FormatStyle::DRTBS_None
);
292 IO
.enumCase(Value
, "All", FormatStyle::DRTBS_All
);
293 IO
.enumCase(Value
, "TopLevel", FormatStyle::DRTBS_TopLevel
);
295 // For backward compatibility.
296 IO
.enumCase(Value
, "false", FormatStyle::DRTBS_None
);
297 IO
.enumCase(Value
, "true", FormatStyle::DRTBS_All
);
302 struct ScalarEnumerationTraits
<FormatStyle::EscapedNewlineAlignmentStyle
> {
303 static void enumeration(IO
&IO
,
304 FormatStyle::EscapedNewlineAlignmentStyle
&Value
) {
305 IO
.enumCase(Value
, "DontAlign", FormatStyle::ENAS_DontAlign
);
306 IO
.enumCase(Value
, "Left", FormatStyle::ENAS_Left
);
307 IO
.enumCase(Value
, "Right", FormatStyle::ENAS_Right
);
309 // For backward compatibility.
310 IO
.enumCase(Value
, "true", FormatStyle::ENAS_Left
);
311 IO
.enumCase(Value
, "false", FormatStyle::ENAS_Right
);
316 struct ScalarEnumerationTraits
<FormatStyle::EmptyLineAfterAccessModifierStyle
> {
318 enumeration(IO
&IO
, FormatStyle::EmptyLineAfterAccessModifierStyle
&Value
) {
319 IO
.enumCase(Value
, "Never", FormatStyle::ELAAMS_Never
);
320 IO
.enumCase(Value
, "Leave", FormatStyle::ELAAMS_Leave
);
321 IO
.enumCase(Value
, "Always", FormatStyle::ELAAMS_Always
);
326 struct ScalarEnumerationTraits
<
327 FormatStyle::EmptyLineBeforeAccessModifierStyle
> {
329 enumeration(IO
&IO
, FormatStyle::EmptyLineBeforeAccessModifierStyle
&Value
) {
330 IO
.enumCase(Value
, "Never", FormatStyle::ELBAMS_Never
);
331 IO
.enumCase(Value
, "Leave", FormatStyle::ELBAMS_Leave
);
332 IO
.enumCase(Value
, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock
);
333 IO
.enumCase(Value
, "Always", FormatStyle::ELBAMS_Always
);
338 struct ScalarEnumerationTraits
<FormatStyle::IndentExternBlockStyle
> {
339 static void enumeration(IO
&IO
, FormatStyle::IndentExternBlockStyle
&Value
) {
340 IO
.enumCase(Value
, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock
);
341 IO
.enumCase(Value
, "Indent", FormatStyle::IEBS_Indent
);
342 IO
.enumCase(Value
, "NoIndent", FormatStyle::IEBS_NoIndent
);
343 IO
.enumCase(Value
, "true", FormatStyle::IEBS_Indent
);
344 IO
.enumCase(Value
, "false", FormatStyle::IEBS_NoIndent
);
348 template <> struct MappingTraits
<FormatStyle::IntegerLiteralSeparatorStyle
> {
349 static void mapping(IO
&IO
, FormatStyle::IntegerLiteralSeparatorStyle
&Base
) {
350 IO
.mapOptional("Binary", Base
.Binary
);
351 IO
.mapOptional("BinaryMinDigits", Base
.BinaryMinDigits
);
352 IO
.mapOptional("Decimal", Base
.Decimal
);
353 IO
.mapOptional("DecimalMinDigits", Base
.DecimalMinDigits
);
354 IO
.mapOptional("Hex", Base
.Hex
);
355 IO
.mapOptional("HexMinDigits", Base
.HexMinDigits
);
359 template <> struct ScalarEnumerationTraits
<FormatStyle::JavaScriptQuoteStyle
> {
360 static void enumeration(IO
&IO
, FormatStyle::JavaScriptQuoteStyle
&Value
) {
361 IO
.enumCase(Value
, "Leave", FormatStyle::JSQS_Leave
);
362 IO
.enumCase(Value
, "Single", FormatStyle::JSQS_Single
);
363 IO
.enumCase(Value
, "Double", FormatStyle::JSQS_Double
);
367 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageKind
> {
368 static void enumeration(IO
&IO
, FormatStyle::LanguageKind
&Value
) {
369 IO
.enumCase(Value
, "Cpp", FormatStyle::LK_Cpp
);
370 IO
.enumCase(Value
, "Java", FormatStyle::LK_Java
);
371 IO
.enumCase(Value
, "JavaScript", FormatStyle::LK_JavaScript
);
372 IO
.enumCase(Value
, "ObjC", FormatStyle::LK_ObjC
);
373 IO
.enumCase(Value
, "Proto", FormatStyle::LK_Proto
);
374 IO
.enumCase(Value
, "TableGen", FormatStyle::LK_TableGen
);
375 IO
.enumCase(Value
, "TextProto", FormatStyle::LK_TextProto
);
376 IO
.enumCase(Value
, "CSharp", FormatStyle::LK_CSharp
);
377 IO
.enumCase(Value
, "Json", FormatStyle::LK_Json
);
378 IO
.enumCase(Value
, "Verilog", FormatStyle::LK_Verilog
);
382 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageStandard
> {
383 static void enumeration(IO
&IO
, FormatStyle::LanguageStandard
&Value
) {
384 IO
.enumCase(Value
, "c++03", FormatStyle::LS_Cpp03
);
385 IO
.enumCase(Value
, "C++03", FormatStyle::LS_Cpp03
); // Legacy alias
386 IO
.enumCase(Value
, "Cpp03", FormatStyle::LS_Cpp03
); // Legacy alias
388 IO
.enumCase(Value
, "c++11", FormatStyle::LS_Cpp11
);
389 IO
.enumCase(Value
, "C++11", FormatStyle::LS_Cpp11
); // Legacy alias
391 IO
.enumCase(Value
, "c++14", FormatStyle::LS_Cpp14
);
392 IO
.enumCase(Value
, "c++17", FormatStyle::LS_Cpp17
);
393 IO
.enumCase(Value
, "c++20", FormatStyle::LS_Cpp20
);
395 IO
.enumCase(Value
, "Latest", FormatStyle::LS_Latest
);
396 IO
.enumCase(Value
, "Cpp11", FormatStyle::LS_Latest
); // Legacy alias
397 IO
.enumCase(Value
, "Auto", FormatStyle::LS_Auto
);
402 struct ScalarEnumerationTraits
<FormatStyle::LambdaBodyIndentationKind
> {
403 static void enumeration(IO
&IO
,
404 FormatStyle::LambdaBodyIndentationKind
&Value
) {
405 IO
.enumCase(Value
, "Signature", FormatStyle::LBI_Signature
);
406 IO
.enumCase(Value
, "OuterScope", FormatStyle::LBI_OuterScope
);
410 template <> struct ScalarEnumerationTraits
<FormatStyle::LineEndingStyle
> {
411 static void enumeration(IO
&IO
, FormatStyle::LineEndingStyle
&Value
) {
412 IO
.enumCase(Value
, "LF", FormatStyle::LE_LF
);
413 IO
.enumCase(Value
, "CRLF", FormatStyle::LE_CRLF
);
414 IO
.enumCase(Value
, "DeriveLF", FormatStyle::LE_DeriveLF
);
415 IO
.enumCase(Value
, "DeriveCRLF", FormatStyle::LE_DeriveCRLF
);
420 struct ScalarEnumerationTraits
<FormatStyle::NamespaceIndentationKind
> {
421 static void enumeration(IO
&IO
,
422 FormatStyle::NamespaceIndentationKind
&Value
) {
423 IO
.enumCase(Value
, "None", FormatStyle::NI_None
);
424 IO
.enumCase(Value
, "Inner", FormatStyle::NI_Inner
);
425 IO
.enumCase(Value
, "All", FormatStyle::NI_All
);
429 template <> struct ScalarEnumerationTraits
<FormatStyle::OperandAlignmentStyle
> {
430 static void enumeration(IO
&IO
, FormatStyle::OperandAlignmentStyle
&Value
) {
431 IO
.enumCase(Value
, "DontAlign", FormatStyle::OAS_DontAlign
);
432 IO
.enumCase(Value
, "Align", FormatStyle::OAS_Align
);
433 IO
.enumCase(Value
, "AlignAfterOperator",
434 FormatStyle::OAS_AlignAfterOperator
);
436 // For backward compatibility.
437 IO
.enumCase(Value
, "true", FormatStyle::OAS_Align
);
438 IO
.enumCase(Value
, "false", FormatStyle::OAS_DontAlign
);
443 struct ScalarEnumerationTraits
<FormatStyle::PackConstructorInitializersStyle
> {
445 enumeration(IO
&IO
, FormatStyle::PackConstructorInitializersStyle
&Value
) {
446 IO
.enumCase(Value
, "Never", FormatStyle::PCIS_Never
);
447 IO
.enumCase(Value
, "BinPack", FormatStyle::PCIS_BinPack
);
448 IO
.enumCase(Value
, "CurrentLine", FormatStyle::PCIS_CurrentLine
);
449 IO
.enumCase(Value
, "NextLine", FormatStyle::PCIS_NextLine
);
450 IO
.enumCase(Value
, "NextLineOnly", FormatStyle::PCIS_NextLineOnly
);
454 template <> struct ScalarEnumerationTraits
<FormatStyle::PointerAlignmentStyle
> {
455 static void enumeration(IO
&IO
, FormatStyle::PointerAlignmentStyle
&Value
) {
456 IO
.enumCase(Value
, "Middle", FormatStyle::PAS_Middle
);
457 IO
.enumCase(Value
, "Left", FormatStyle::PAS_Left
);
458 IO
.enumCase(Value
, "Right", FormatStyle::PAS_Right
);
460 // For backward compatibility.
461 IO
.enumCase(Value
, "true", FormatStyle::PAS_Left
);
462 IO
.enumCase(Value
, "false", FormatStyle::PAS_Right
);
467 struct ScalarEnumerationTraits
<FormatStyle::PPDirectiveIndentStyle
> {
468 static void enumeration(IO
&IO
, FormatStyle::PPDirectiveIndentStyle
&Value
) {
469 IO
.enumCase(Value
, "None", FormatStyle::PPDIS_None
);
470 IO
.enumCase(Value
, "AfterHash", FormatStyle::PPDIS_AfterHash
);
471 IO
.enumCase(Value
, "BeforeHash", FormatStyle::PPDIS_BeforeHash
);
476 struct ScalarEnumerationTraits
<FormatStyle::QualifierAlignmentStyle
> {
477 static void enumeration(IO
&IO
, FormatStyle::QualifierAlignmentStyle
&Value
) {
478 IO
.enumCase(Value
, "Leave", FormatStyle::QAS_Leave
);
479 IO
.enumCase(Value
, "Left", FormatStyle::QAS_Left
);
480 IO
.enumCase(Value
, "Right", FormatStyle::QAS_Right
);
481 IO
.enumCase(Value
, "Custom", FormatStyle::QAS_Custom
);
485 template <> struct MappingTraits
<FormatStyle::RawStringFormat
> {
486 static void mapping(IO
&IO
, FormatStyle::RawStringFormat
&Format
) {
487 IO
.mapOptional("Language", Format
.Language
);
488 IO
.mapOptional("Delimiters", Format
.Delimiters
);
489 IO
.mapOptional("EnclosingFunctions", Format
.EnclosingFunctions
);
490 IO
.mapOptional("CanonicalDelimiter", Format
.CanonicalDelimiter
);
491 IO
.mapOptional("BasedOnStyle", Format
.BasedOnStyle
);
496 struct ScalarEnumerationTraits
<FormatStyle::ReferenceAlignmentStyle
> {
497 static void enumeration(IO
&IO
, FormatStyle::ReferenceAlignmentStyle
&Value
) {
498 IO
.enumCase(Value
, "Pointer", FormatStyle::RAS_Pointer
);
499 IO
.enumCase(Value
, "Middle", FormatStyle::RAS_Middle
);
500 IO
.enumCase(Value
, "Left", FormatStyle::RAS_Left
);
501 IO
.enumCase(Value
, "Right", FormatStyle::RAS_Right
);
506 struct ScalarEnumerationTraits
<FormatStyle::RequiresClausePositionStyle
> {
507 static void enumeration(IO
&IO
,
508 FormatStyle::RequiresClausePositionStyle
&Value
) {
509 IO
.enumCase(Value
, "OwnLine", FormatStyle::RCPS_OwnLine
);
510 IO
.enumCase(Value
, "WithPreceding", FormatStyle::RCPS_WithPreceding
);
511 IO
.enumCase(Value
, "WithFollowing", FormatStyle::RCPS_WithFollowing
);
512 IO
.enumCase(Value
, "SingleLine", FormatStyle::RCPS_SingleLine
);
517 struct ScalarEnumerationTraits
<FormatStyle::RequiresExpressionIndentationKind
> {
519 enumeration(IO
&IO
, FormatStyle::RequiresExpressionIndentationKind
&Value
) {
520 IO
.enumCase(Value
, "Keyword", FormatStyle::REI_Keyword
);
521 IO
.enumCase(Value
, "OuterScope", FormatStyle::REI_OuterScope
);
526 struct ScalarEnumerationTraits
<FormatStyle::ReturnTypeBreakingStyle
> {
527 static void enumeration(IO
&IO
, FormatStyle::ReturnTypeBreakingStyle
&Value
) {
528 IO
.enumCase(Value
, "None", FormatStyle::RTBS_None
);
529 IO
.enumCase(Value
, "All", FormatStyle::RTBS_All
);
530 IO
.enumCase(Value
, "TopLevel", FormatStyle::RTBS_TopLevel
);
531 IO
.enumCase(Value
, "TopLevelDefinitions",
532 FormatStyle::RTBS_TopLevelDefinitions
);
533 IO
.enumCase(Value
, "AllDefinitions", FormatStyle::RTBS_AllDefinitions
);
538 struct ScalarEnumerationTraits
<FormatStyle::SeparateDefinitionStyle
> {
539 static void enumeration(IO
&IO
, FormatStyle::SeparateDefinitionStyle
&Value
) {
540 IO
.enumCase(Value
, "Leave", FormatStyle::SDS_Leave
);
541 IO
.enumCase(Value
, "Always", FormatStyle::SDS_Always
);
542 IO
.enumCase(Value
, "Never", FormatStyle::SDS_Never
);
546 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortBlockStyle
> {
547 static void enumeration(IO
&IO
, FormatStyle::ShortBlockStyle
&Value
) {
548 IO
.enumCase(Value
, "Never", FormatStyle::SBS_Never
);
549 IO
.enumCase(Value
, "false", FormatStyle::SBS_Never
);
550 IO
.enumCase(Value
, "Always", FormatStyle::SBS_Always
);
551 IO
.enumCase(Value
, "true", FormatStyle::SBS_Always
);
552 IO
.enumCase(Value
, "Empty", FormatStyle::SBS_Empty
);
556 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortFunctionStyle
> {
557 static void enumeration(IO
&IO
, FormatStyle::ShortFunctionStyle
&Value
) {
558 IO
.enumCase(Value
, "None", FormatStyle::SFS_None
);
559 IO
.enumCase(Value
, "false", FormatStyle::SFS_None
);
560 IO
.enumCase(Value
, "All", FormatStyle::SFS_All
);
561 IO
.enumCase(Value
, "true", FormatStyle::SFS_All
);
562 IO
.enumCase(Value
, "Inline", FormatStyle::SFS_Inline
);
563 IO
.enumCase(Value
, "InlineOnly", FormatStyle::SFS_InlineOnly
);
564 IO
.enumCase(Value
, "Empty", FormatStyle::SFS_Empty
);
568 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortIfStyle
> {
569 static void enumeration(IO
&IO
, FormatStyle::ShortIfStyle
&Value
) {
570 IO
.enumCase(Value
, "Never", FormatStyle::SIS_Never
);
571 IO
.enumCase(Value
, "WithoutElse", FormatStyle::SIS_WithoutElse
);
572 IO
.enumCase(Value
, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf
);
573 IO
.enumCase(Value
, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse
);
575 // For backward compatibility.
576 IO
.enumCase(Value
, "Always", FormatStyle::SIS_OnlyFirstIf
);
577 IO
.enumCase(Value
, "false", FormatStyle::SIS_Never
);
578 IO
.enumCase(Value
, "true", FormatStyle::SIS_WithoutElse
);
582 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortLambdaStyle
> {
583 static void enumeration(IO
&IO
, FormatStyle::ShortLambdaStyle
&Value
) {
584 IO
.enumCase(Value
, "None", FormatStyle::SLS_None
);
585 IO
.enumCase(Value
, "false", FormatStyle::SLS_None
);
586 IO
.enumCase(Value
, "Empty", FormatStyle::SLS_Empty
);
587 IO
.enumCase(Value
, "Inline", FormatStyle::SLS_Inline
);
588 IO
.enumCase(Value
, "All", FormatStyle::SLS_All
);
589 IO
.enumCase(Value
, "true", FormatStyle::SLS_All
);
593 template <> struct ScalarEnumerationTraits
<FormatStyle::SortIncludesOptions
> {
594 static void enumeration(IO
&IO
, FormatStyle::SortIncludesOptions
&Value
) {
595 IO
.enumCase(Value
, "Never", FormatStyle::SI_Never
);
596 IO
.enumCase(Value
, "CaseInsensitive", FormatStyle::SI_CaseInsensitive
);
597 IO
.enumCase(Value
, "CaseSensitive", FormatStyle::SI_CaseSensitive
);
599 // For backward compatibility.
600 IO
.enumCase(Value
, "false", FormatStyle::SI_Never
);
601 IO
.enumCase(Value
, "true", FormatStyle::SI_CaseSensitive
);
606 struct ScalarEnumerationTraits
<FormatStyle::SortJavaStaticImportOptions
> {
607 static void enumeration(IO
&IO
,
608 FormatStyle::SortJavaStaticImportOptions
&Value
) {
609 IO
.enumCase(Value
, "Before", FormatStyle::SJSIO_Before
);
610 IO
.enumCase(Value
, "After", FormatStyle::SJSIO_After
);
615 struct ScalarEnumerationTraits
<FormatStyle::SortUsingDeclarationsOptions
> {
616 static void enumeration(IO
&IO
,
617 FormatStyle::SortUsingDeclarationsOptions
&Value
) {
618 IO
.enumCase(Value
, "Never", FormatStyle::SUD_Never
);
619 IO
.enumCase(Value
, "Lexicographic", FormatStyle::SUD_Lexicographic
);
620 IO
.enumCase(Value
, "LexicographicNumeric",
621 FormatStyle::SUD_LexicographicNumeric
);
623 // For backward compatibility.
624 IO
.enumCase(Value
, "false", FormatStyle::SUD_Never
);
625 IO
.enumCase(Value
, "true", FormatStyle::SUD_LexicographicNumeric
);
630 struct ScalarEnumerationTraits
<FormatStyle::SpaceAroundPointerQualifiersStyle
> {
632 enumeration(IO
&IO
, FormatStyle::SpaceAroundPointerQualifiersStyle
&Value
) {
633 IO
.enumCase(Value
, "Default", FormatStyle::SAPQ_Default
);
634 IO
.enumCase(Value
, "Before", FormatStyle::SAPQ_Before
);
635 IO
.enumCase(Value
, "After", FormatStyle::SAPQ_After
);
636 IO
.enumCase(Value
, "Both", FormatStyle::SAPQ_Both
);
640 template <> struct MappingTraits
<FormatStyle::SpaceBeforeParensCustom
> {
641 static void mapping(IO
&IO
, FormatStyle::SpaceBeforeParensCustom
&Spacing
) {
642 IO
.mapOptional("AfterControlStatements", Spacing
.AfterControlStatements
);
643 IO
.mapOptional("AfterForeachMacros", Spacing
.AfterForeachMacros
);
644 IO
.mapOptional("AfterFunctionDefinitionName",
645 Spacing
.AfterFunctionDefinitionName
);
646 IO
.mapOptional("AfterFunctionDeclarationName",
647 Spacing
.AfterFunctionDeclarationName
);
648 IO
.mapOptional("AfterIfMacros", Spacing
.AfterIfMacros
);
649 IO
.mapOptional("AfterOverloadedOperator", Spacing
.AfterOverloadedOperator
);
650 IO
.mapOptional("AfterRequiresInClause", Spacing
.AfterRequiresInClause
);
651 IO
.mapOptional("AfterRequiresInExpression",
652 Spacing
.AfterRequiresInExpression
);
653 IO
.mapOptional("BeforeNonEmptyParentheses",
654 Spacing
.BeforeNonEmptyParentheses
);
659 struct ScalarEnumerationTraits
<FormatStyle::SpaceBeforeParensStyle
> {
660 static void enumeration(IO
&IO
, FormatStyle::SpaceBeforeParensStyle
&Value
) {
661 IO
.enumCase(Value
, "Never", FormatStyle::SBPO_Never
);
662 IO
.enumCase(Value
, "ControlStatements",
663 FormatStyle::SBPO_ControlStatements
);
664 IO
.enumCase(Value
, "ControlStatementsExceptControlMacros",
665 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
666 IO
.enumCase(Value
, "NonEmptyParentheses",
667 FormatStyle::SBPO_NonEmptyParentheses
);
668 IO
.enumCase(Value
, "Always", FormatStyle::SBPO_Always
);
669 IO
.enumCase(Value
, "Custom", FormatStyle::SBPO_Custom
);
671 // For backward compatibility.
672 IO
.enumCase(Value
, "false", FormatStyle::SBPO_Never
);
673 IO
.enumCase(Value
, "true", FormatStyle::SBPO_ControlStatements
);
674 IO
.enumCase(Value
, "ControlStatementsExceptForEachMacros",
675 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
679 template <> struct ScalarEnumerationTraits
<FormatStyle::SpacesInAnglesStyle
> {
680 static void enumeration(IO
&IO
, FormatStyle::SpacesInAnglesStyle
&Value
) {
681 IO
.enumCase(Value
, "Never", FormatStyle::SIAS_Never
);
682 IO
.enumCase(Value
, "Always", FormatStyle::SIAS_Always
);
683 IO
.enumCase(Value
, "Leave", FormatStyle::SIAS_Leave
);
685 // For backward compatibility.
686 IO
.enumCase(Value
, "false", FormatStyle::SIAS_Never
);
687 IO
.enumCase(Value
, "true", FormatStyle::SIAS_Always
);
691 template <> struct MappingTraits
<FormatStyle::SpacesInLineComment
> {
692 static void mapping(IO
&IO
, FormatStyle::SpacesInLineComment
&Space
) {
693 // Transform the maximum to signed, to parse "-1" correctly
694 int signedMaximum
= static_cast<int>(Space
.Maximum
);
695 IO
.mapOptional("Minimum", Space
.Minimum
);
696 IO
.mapOptional("Maximum", signedMaximum
);
697 Space
.Maximum
= static_cast<unsigned>(signedMaximum
);
699 if (Space
.Maximum
!= -1u)
700 Space
.Minimum
= std::min(Space
.Minimum
, Space
.Maximum
);
704 template <> struct ScalarEnumerationTraits
<FormatStyle::TrailingCommaStyle
> {
705 static void enumeration(IO
&IO
, FormatStyle::TrailingCommaStyle
&Value
) {
706 IO
.enumCase(Value
, "None", FormatStyle::TCS_None
);
707 IO
.enumCase(Value
, "Wrapped", FormatStyle::TCS_Wrapped
);
712 struct ScalarEnumerationTraits
<FormatStyle::TrailingCommentsAlignmentKinds
> {
713 static void enumeration(IO
&IO
,
714 FormatStyle::TrailingCommentsAlignmentKinds
&Value
) {
715 IO
.enumCase(Value
, "Leave", FormatStyle::TCAS_Leave
);
716 IO
.enumCase(Value
, "Always", FormatStyle::TCAS_Always
);
717 IO
.enumCase(Value
, "Never", FormatStyle::TCAS_Never
);
721 template <> struct MappingTraits
<FormatStyle::TrailingCommentsAlignmentStyle
> {
722 static void enumInput(IO
&IO
,
723 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
724 IO
.enumCase(Value
, "Leave",
725 FormatStyle::TrailingCommentsAlignmentStyle(
726 {FormatStyle::TCAS_Leave
, 0}));
728 IO
.enumCase(Value
, "Always",
729 FormatStyle::TrailingCommentsAlignmentStyle(
730 {FormatStyle::TCAS_Always
, 0}));
732 IO
.enumCase(Value
, "Never",
733 FormatStyle::TrailingCommentsAlignmentStyle(
734 {FormatStyle::TCAS_Never
, 0}));
736 // For backwards compatibility
737 IO
.enumCase(Value
, "true",
738 FormatStyle::TrailingCommentsAlignmentStyle(
739 {FormatStyle::TCAS_Always
, 0}));
740 IO
.enumCase(Value
, "false",
741 FormatStyle::TrailingCommentsAlignmentStyle(
742 {FormatStyle::TCAS_Never
, 0}));
745 static void mapping(IO
&IO
,
746 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
747 IO
.mapOptional("Kind", Value
.Kind
);
748 IO
.mapOptional("OverEmptyLines", Value
.OverEmptyLines
);
752 template <> struct ScalarEnumerationTraits
<FormatStyle::UseTabStyle
> {
753 static void enumeration(IO
&IO
, FormatStyle::UseTabStyle
&Value
) {
754 IO
.enumCase(Value
, "Never", FormatStyle::UT_Never
);
755 IO
.enumCase(Value
, "false", FormatStyle::UT_Never
);
756 IO
.enumCase(Value
, "Always", FormatStyle::UT_Always
);
757 IO
.enumCase(Value
, "true", FormatStyle::UT_Always
);
758 IO
.enumCase(Value
, "ForIndentation", FormatStyle::UT_ForIndentation
);
759 IO
.enumCase(Value
, "ForContinuationAndIndentation",
760 FormatStyle::UT_ForContinuationAndIndentation
);
761 IO
.enumCase(Value
, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces
);
765 template <> struct MappingTraits
<FormatStyle
> {
766 static void mapping(IO
&IO
, FormatStyle
&Style
) {
767 // When reading, read the language first, we need it for getPredefinedStyle.
768 IO
.mapOptional("Language", Style
.Language
);
770 StringRef BasedOnStyle
;
771 if (IO
.outputting()) {
772 StringRef Styles
[] = {"LLVM", "Google", "Chromium", "Mozilla",
773 "WebKit", "GNU", "Microsoft"};
774 for (StringRef StyleName
: Styles
) {
775 FormatStyle PredefinedStyle
;
776 if (getPredefinedStyle(StyleName
, Style
.Language
, &PredefinedStyle
) &&
777 Style
== PredefinedStyle
) {
778 IO
.mapOptional("# BasedOnStyle", StyleName
);
779 BasedOnStyle
= StyleName
;
784 IO
.mapOptional("BasedOnStyle", BasedOnStyle
);
785 if (!BasedOnStyle
.empty()) {
786 FormatStyle::LanguageKind OldLanguage
= Style
.Language
;
787 FormatStyle::LanguageKind Language
=
788 ((FormatStyle
*)IO
.getContext())->Language
;
789 if (!getPredefinedStyle(BasedOnStyle
, Language
, &Style
)) {
790 IO
.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle
));
793 Style
.Language
= OldLanguage
;
797 // Initialize some variables used in the parsing. The using logic is at the
800 // For backward compatibility:
801 // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was
802 // false unless BasedOnStyle was Google or Chromium whereas that of
803 // AllowAllConstructorInitializersOnNextLine was always true, so the
804 // equivalent default value of PackConstructorInitializers is PCIS_NextLine
805 // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options
806 // had a non-default value while PackConstructorInitializers has a default
807 // value, set the latter to an equivalent non-default value if needed.
808 const bool IsGoogleOrChromium
= BasedOnStyle
.equals_insensitive("google") ||
809 BasedOnStyle
.equals_insensitive("chromium");
810 bool OnCurrentLine
= IsGoogleOrChromium
;
811 bool OnNextLine
= true;
813 bool BreakBeforeInheritanceComma
= false;
814 bool BreakConstructorInitializersBeforeComma
= false;
816 bool DeriveLineEnding
= true;
817 bool UseCRLF
= false;
819 // For backward compatibility.
820 if (!IO
.outputting()) {
821 IO
.mapOptional("AlignEscapedNewlinesLeft", Style
.AlignEscapedNewlines
);
822 IO
.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine
);
823 IO
.mapOptional("BreakBeforeInheritanceComma",
824 BreakBeforeInheritanceComma
);
825 IO
.mapOptional("BreakConstructorInitializersBeforeComma",
826 BreakConstructorInitializersBeforeComma
);
827 IO
.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
829 IO
.mapOptional("DeriveLineEnding", DeriveLineEnding
);
830 IO
.mapOptional("DerivePointerBinding", Style
.DerivePointerAlignment
);
831 IO
.mapOptional("IndentFunctionDeclarationAfterType",
832 Style
.IndentWrappedFunctionNames
);
833 IO
.mapOptional("IndentRequires", Style
.IndentRequiresClause
);
834 IO
.mapOptional("PointerBindsToType", Style
.PointerAlignment
);
835 IO
.mapOptional("SpaceAfterControlStatementKeyword",
836 Style
.SpaceBeforeParens
);
837 IO
.mapOptional("UseCRLF", UseCRLF
);
840 IO
.mapOptional("AccessModifierOffset", Style
.AccessModifierOffset
);
841 IO
.mapOptional("AlignAfterOpenBracket", Style
.AlignAfterOpenBracket
);
842 IO
.mapOptional("AlignArrayOfStructures", Style
.AlignArrayOfStructures
);
843 IO
.mapOptional("AlignConsecutiveAssignments",
844 Style
.AlignConsecutiveAssignments
);
845 IO
.mapOptional("AlignConsecutiveBitFields",
846 Style
.AlignConsecutiveBitFields
);
847 IO
.mapOptional("AlignConsecutiveDeclarations",
848 Style
.AlignConsecutiveDeclarations
);
849 IO
.mapOptional("AlignConsecutiveMacros", Style
.AlignConsecutiveMacros
);
850 IO
.mapOptional("AlignEscapedNewlines", Style
.AlignEscapedNewlines
);
851 IO
.mapOptional("AlignOperands", Style
.AlignOperands
);
852 IO
.mapOptional("AlignTrailingComments", Style
.AlignTrailingComments
);
853 IO
.mapOptional("AllowAllArgumentsOnNextLine",
854 Style
.AllowAllArgumentsOnNextLine
);
855 IO
.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
856 Style
.AllowAllParametersOfDeclarationOnNextLine
);
857 IO
.mapOptional("AllowShortBlocksOnASingleLine",
858 Style
.AllowShortBlocksOnASingleLine
);
859 IO
.mapOptional("AllowShortCaseLabelsOnASingleLine",
860 Style
.AllowShortCaseLabelsOnASingleLine
);
861 IO
.mapOptional("AllowShortEnumsOnASingleLine",
862 Style
.AllowShortEnumsOnASingleLine
);
863 IO
.mapOptional("AllowShortFunctionsOnASingleLine",
864 Style
.AllowShortFunctionsOnASingleLine
);
865 IO
.mapOptional("AllowShortIfStatementsOnASingleLine",
866 Style
.AllowShortIfStatementsOnASingleLine
);
867 IO
.mapOptional("AllowShortLambdasOnASingleLine",
868 Style
.AllowShortLambdasOnASingleLine
);
869 IO
.mapOptional("AllowShortLoopsOnASingleLine",
870 Style
.AllowShortLoopsOnASingleLine
);
871 IO
.mapOptional("AlwaysBreakAfterDefinitionReturnType",
872 Style
.AlwaysBreakAfterDefinitionReturnType
);
873 IO
.mapOptional("AlwaysBreakAfterReturnType",
874 Style
.AlwaysBreakAfterReturnType
);
875 IO
.mapOptional("AlwaysBreakBeforeMultilineStrings",
876 Style
.AlwaysBreakBeforeMultilineStrings
);
877 IO
.mapOptional("AlwaysBreakTemplateDeclarations",
878 Style
.AlwaysBreakTemplateDeclarations
);
879 IO
.mapOptional("AttributeMacros", Style
.AttributeMacros
);
880 IO
.mapOptional("BinPackArguments", Style
.BinPackArguments
);
881 IO
.mapOptional("BinPackParameters", Style
.BinPackParameters
);
882 IO
.mapOptional("BitFieldColonSpacing", Style
.BitFieldColonSpacing
);
883 IO
.mapOptional("BracedInitializerIndentWidth",
884 Style
.BracedInitializerIndentWidth
);
885 IO
.mapOptional("BraceWrapping", Style
.BraceWrapping
);
886 IO
.mapOptional("BreakAfterAttributes", Style
.BreakAfterAttributes
);
887 IO
.mapOptional("BreakAfterJavaFieldAnnotations",
888 Style
.BreakAfterJavaFieldAnnotations
);
889 IO
.mapOptional("BreakArrays", Style
.BreakArrays
);
890 IO
.mapOptional("BreakBeforeBinaryOperators",
891 Style
.BreakBeforeBinaryOperators
);
892 IO
.mapOptional("BreakBeforeConceptDeclarations",
893 Style
.BreakBeforeConceptDeclarations
);
894 IO
.mapOptional("BreakBeforeBraces", Style
.BreakBeforeBraces
);
895 IO
.mapOptional("BreakBeforeInlineASMColon",
896 Style
.BreakBeforeInlineASMColon
);
897 IO
.mapOptional("BreakBeforeTernaryOperators",
898 Style
.BreakBeforeTernaryOperators
);
899 IO
.mapOptional("BreakConstructorInitializers",
900 Style
.BreakConstructorInitializers
);
901 IO
.mapOptional("BreakInheritanceList", Style
.BreakInheritanceList
);
902 IO
.mapOptional("BreakStringLiterals", Style
.BreakStringLiterals
);
903 IO
.mapOptional("ColumnLimit", Style
.ColumnLimit
);
904 IO
.mapOptional("CommentPragmas", Style
.CommentPragmas
);
905 IO
.mapOptional("CompactNamespaces", Style
.CompactNamespaces
);
906 IO
.mapOptional("ConstructorInitializerIndentWidth",
907 Style
.ConstructorInitializerIndentWidth
);
908 IO
.mapOptional("ContinuationIndentWidth", Style
.ContinuationIndentWidth
);
909 IO
.mapOptional("Cpp11BracedListStyle", Style
.Cpp11BracedListStyle
);
910 IO
.mapOptional("DerivePointerAlignment", Style
.DerivePointerAlignment
);
911 IO
.mapOptional("DisableFormat", Style
.DisableFormat
);
912 IO
.mapOptional("EmptyLineAfterAccessModifier",
913 Style
.EmptyLineAfterAccessModifier
);
914 IO
.mapOptional("EmptyLineBeforeAccessModifier",
915 Style
.EmptyLineBeforeAccessModifier
);
916 IO
.mapOptional("ExperimentalAutoDetectBinPacking",
917 Style
.ExperimentalAutoDetectBinPacking
);
918 IO
.mapOptional("FixNamespaceComments", Style
.FixNamespaceComments
);
919 IO
.mapOptional("ForEachMacros", Style
.ForEachMacros
);
920 IO
.mapOptional("IfMacros", Style
.IfMacros
);
921 IO
.mapOptional("IncludeBlocks", Style
.IncludeStyle
.IncludeBlocks
);
922 IO
.mapOptional("IncludeCategories", Style
.IncludeStyle
.IncludeCategories
);
923 IO
.mapOptional("IncludeIsMainRegex", Style
.IncludeStyle
.IncludeIsMainRegex
);
924 IO
.mapOptional("IncludeIsMainSourceRegex",
925 Style
.IncludeStyle
.IncludeIsMainSourceRegex
);
926 IO
.mapOptional("IndentAccessModifiers", Style
.IndentAccessModifiers
);
927 IO
.mapOptional("IndentCaseBlocks", Style
.IndentCaseBlocks
);
928 IO
.mapOptional("IndentCaseLabels", Style
.IndentCaseLabels
);
929 IO
.mapOptional("IndentExternBlock", Style
.IndentExternBlock
);
930 IO
.mapOptional("IndentGotoLabels", Style
.IndentGotoLabels
);
931 IO
.mapOptional("IndentPPDirectives", Style
.IndentPPDirectives
);
932 IO
.mapOptional("IndentRequiresClause", Style
.IndentRequiresClause
);
933 IO
.mapOptional("IndentWidth", Style
.IndentWidth
);
934 IO
.mapOptional("IndentWrappedFunctionNames",
935 Style
.IndentWrappedFunctionNames
);
936 IO
.mapOptional("InsertBraces", Style
.InsertBraces
);
937 IO
.mapOptional("InsertNewlineAtEOF", Style
.InsertNewlineAtEOF
);
938 IO
.mapOptional("InsertTrailingCommas", Style
.InsertTrailingCommas
);
939 IO
.mapOptional("IntegerLiteralSeparator", Style
.IntegerLiteralSeparator
);
940 IO
.mapOptional("JavaImportGroups", Style
.JavaImportGroups
);
941 IO
.mapOptional("JavaScriptQuotes", Style
.JavaScriptQuotes
);
942 IO
.mapOptional("JavaScriptWrapImports", Style
.JavaScriptWrapImports
);
943 IO
.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
944 Style
.KeepEmptyLinesAtTheStartOfBlocks
);
945 IO
.mapOptional("KeepEmptyLinesAtEOF", Style
.KeepEmptyLinesAtEOF
);
946 IO
.mapOptional("LambdaBodyIndentation", Style
.LambdaBodyIndentation
);
947 IO
.mapOptional("LineEnding", Style
.LineEnding
);
948 IO
.mapOptional("MacroBlockBegin", Style
.MacroBlockBegin
);
949 IO
.mapOptional("MacroBlockEnd", Style
.MacroBlockEnd
);
950 IO
.mapOptional("MaxEmptyLinesToKeep", Style
.MaxEmptyLinesToKeep
);
951 IO
.mapOptional("NamespaceIndentation", Style
.NamespaceIndentation
);
952 IO
.mapOptional("NamespaceMacros", Style
.NamespaceMacros
);
953 IO
.mapOptional("ObjCBinPackProtocolList", Style
.ObjCBinPackProtocolList
);
954 IO
.mapOptional("ObjCBlockIndentWidth", Style
.ObjCBlockIndentWidth
);
955 IO
.mapOptional("ObjCBreakBeforeNestedBlockParam",
956 Style
.ObjCBreakBeforeNestedBlockParam
);
957 IO
.mapOptional("ObjCSpaceAfterProperty", Style
.ObjCSpaceAfterProperty
);
958 IO
.mapOptional("ObjCSpaceBeforeProtocolList",
959 Style
.ObjCSpaceBeforeProtocolList
);
960 IO
.mapOptional("PackConstructorInitializers",
961 Style
.PackConstructorInitializers
);
962 IO
.mapOptional("PenaltyBreakAssignment", Style
.PenaltyBreakAssignment
);
963 IO
.mapOptional("PenaltyBreakBeforeFirstCallParameter",
964 Style
.PenaltyBreakBeforeFirstCallParameter
);
965 IO
.mapOptional("PenaltyBreakComment", Style
.PenaltyBreakComment
);
966 IO
.mapOptional("PenaltyBreakFirstLessLess",
967 Style
.PenaltyBreakFirstLessLess
);
968 IO
.mapOptional("PenaltyBreakOpenParenthesis",
969 Style
.PenaltyBreakOpenParenthesis
);
970 IO
.mapOptional("PenaltyBreakString", Style
.PenaltyBreakString
);
971 IO
.mapOptional("PenaltyBreakTemplateDeclaration",
972 Style
.PenaltyBreakTemplateDeclaration
);
973 IO
.mapOptional("PenaltyExcessCharacter", Style
.PenaltyExcessCharacter
);
974 IO
.mapOptional("PenaltyIndentedWhitespace",
975 Style
.PenaltyIndentedWhitespace
);
976 IO
.mapOptional("PenaltyReturnTypeOnItsOwnLine",
977 Style
.PenaltyReturnTypeOnItsOwnLine
);
978 IO
.mapOptional("PointerAlignment", Style
.PointerAlignment
);
979 IO
.mapOptional("PPIndentWidth", Style
.PPIndentWidth
);
980 IO
.mapOptional("QualifierAlignment", Style
.QualifierAlignment
);
981 // Default Order for Left/Right based Qualifier alignment.
982 if (Style
.QualifierAlignment
== FormatStyle::QAS_Right
)
983 Style
.QualifierOrder
= {"type", "const", "volatile"};
984 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Left
)
985 Style
.QualifierOrder
= {"const", "volatile", "type"};
986 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Custom
)
987 IO
.mapOptional("QualifierOrder", Style
.QualifierOrder
);
988 IO
.mapOptional("RawStringFormats", Style
.RawStringFormats
);
989 IO
.mapOptional("ReferenceAlignment", Style
.ReferenceAlignment
);
990 IO
.mapOptional("ReflowComments", Style
.ReflowComments
);
991 IO
.mapOptional("RemoveBracesLLVM", Style
.RemoveBracesLLVM
);
992 IO
.mapOptional("RemoveSemicolon", Style
.RemoveSemicolon
);
993 IO
.mapOptional("RequiresClausePosition", Style
.RequiresClausePosition
);
994 IO
.mapOptional("RequiresExpressionIndentation",
995 Style
.RequiresExpressionIndentation
);
996 IO
.mapOptional("SeparateDefinitionBlocks", Style
.SeparateDefinitionBlocks
);
997 IO
.mapOptional("ShortNamespaceLines", Style
.ShortNamespaceLines
);
998 IO
.mapOptional("SortIncludes", Style
.SortIncludes
);
999 IO
.mapOptional("SortJavaStaticImport", Style
.SortJavaStaticImport
);
1000 IO
.mapOptional("SortUsingDeclarations", Style
.SortUsingDeclarations
);
1001 IO
.mapOptional("SpaceAfterCStyleCast", Style
.SpaceAfterCStyleCast
);
1002 IO
.mapOptional("SpaceAfterLogicalNot", Style
.SpaceAfterLogicalNot
);
1003 IO
.mapOptional("SpaceAfterTemplateKeyword",
1004 Style
.SpaceAfterTemplateKeyword
);
1005 IO
.mapOptional("SpaceAroundPointerQualifiers",
1006 Style
.SpaceAroundPointerQualifiers
);
1007 IO
.mapOptional("SpaceBeforeAssignmentOperators",
1008 Style
.SpaceBeforeAssignmentOperators
);
1009 IO
.mapOptional("SpaceBeforeCaseColon", Style
.SpaceBeforeCaseColon
);
1010 IO
.mapOptional("SpaceBeforeCpp11BracedList",
1011 Style
.SpaceBeforeCpp11BracedList
);
1012 IO
.mapOptional("SpaceBeforeCtorInitializerColon",
1013 Style
.SpaceBeforeCtorInitializerColon
);
1014 IO
.mapOptional("SpaceBeforeInheritanceColon",
1015 Style
.SpaceBeforeInheritanceColon
);
1016 IO
.mapOptional("SpaceBeforeJsonColon", Style
.SpaceBeforeJsonColon
);
1017 IO
.mapOptional("SpaceBeforeParens", Style
.SpaceBeforeParens
);
1018 IO
.mapOptional("SpaceBeforeParensOptions", Style
.SpaceBeforeParensOptions
);
1019 IO
.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1020 Style
.SpaceBeforeRangeBasedForLoopColon
);
1021 IO
.mapOptional("SpaceBeforeSquareBrackets",
1022 Style
.SpaceBeforeSquareBrackets
);
1023 IO
.mapOptional("SpaceInEmptyBlock", Style
.SpaceInEmptyBlock
);
1024 IO
.mapOptional("SpaceInEmptyParentheses", Style
.SpaceInEmptyParentheses
);
1025 IO
.mapOptional("SpacesBeforeTrailingComments",
1026 Style
.SpacesBeforeTrailingComments
);
1027 IO
.mapOptional("SpacesInAngles", Style
.SpacesInAngles
);
1028 IO
.mapOptional("SpacesInConditionalStatement",
1029 Style
.SpacesInConditionalStatement
);
1030 IO
.mapOptional("SpacesInContainerLiterals",
1031 Style
.SpacesInContainerLiterals
);
1032 IO
.mapOptional("SpacesInCStyleCastParentheses",
1033 Style
.SpacesInCStyleCastParentheses
);
1034 IO
.mapOptional("SpacesInLineCommentPrefix",
1035 Style
.SpacesInLineCommentPrefix
);
1036 IO
.mapOptional("SpacesInParentheses", Style
.SpacesInParentheses
);
1037 IO
.mapOptional("SpacesInSquareBrackets", Style
.SpacesInSquareBrackets
);
1038 IO
.mapOptional("Standard", Style
.Standard
);
1039 IO
.mapOptional("StatementAttributeLikeMacros",
1040 Style
.StatementAttributeLikeMacros
);
1041 IO
.mapOptional("StatementMacros", Style
.StatementMacros
);
1042 IO
.mapOptional("TabWidth", Style
.TabWidth
);
1043 IO
.mapOptional("TypenameMacros", Style
.TypenameMacros
);
1044 IO
.mapOptional("UseTab", Style
.UseTab
);
1045 IO
.mapOptional("VerilogBreakBetweenInstancePorts",
1046 Style
.VerilogBreakBetweenInstancePorts
);
1047 IO
.mapOptional("WhitespaceSensitiveMacros",
1048 Style
.WhitespaceSensitiveMacros
);
1049 IO
.mapOptional("Macros", Style
.Macros
);
1051 // If AlwaysBreakAfterDefinitionReturnType was specified but
1052 // AlwaysBreakAfterReturnType was not, initialize the latter from the
1053 // former for backwards compatibility.
1054 if (Style
.AlwaysBreakAfterDefinitionReturnType
!= FormatStyle::DRTBS_None
&&
1055 Style
.AlwaysBreakAfterReturnType
== FormatStyle::RTBS_None
) {
1056 if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1057 FormatStyle::DRTBS_All
) {
1058 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1059 } else if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1060 FormatStyle::DRTBS_TopLevel
) {
1061 Style
.AlwaysBreakAfterReturnType
=
1062 FormatStyle::RTBS_TopLevelDefinitions
;
1066 // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1067 // not, initialize the latter from the former for backwards compatibility.
1068 if (BreakBeforeInheritanceComma
&&
1069 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeColon
) {
1070 Style
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1073 // If BreakConstructorInitializersBeforeComma was specified but
1074 // BreakConstructorInitializers was not, initialize the latter from the
1075 // former for backwards compatibility.
1076 if (BreakConstructorInitializersBeforeComma
&&
1077 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
) {
1078 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1081 if (!IsGoogleOrChromium
) {
1082 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_BinPack
&&
1084 Style
.PackConstructorInitializers
= OnNextLine
1085 ? FormatStyle::PCIS_NextLine
1086 : FormatStyle::PCIS_CurrentLine
;
1088 } else if (Style
.PackConstructorInitializers
==
1089 FormatStyle::PCIS_NextLine
) {
1091 Style
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1092 else if (!OnNextLine
)
1093 Style
.PackConstructorInitializers
= FormatStyle::PCIS_CurrentLine
;
1096 if (Style
.LineEnding
== FormatStyle::LE_DeriveLF
) {
1097 if (!DeriveLineEnding
)
1098 Style
.LineEnding
= UseCRLF
? FormatStyle::LE_CRLF
: FormatStyle::LE_LF
;
1100 Style
.LineEnding
= FormatStyle::LE_DeriveCRLF
;
1105 // Allows to read vector<FormatStyle> while keeping default values.
1106 // IO.getContext() should contain a pointer to the FormatStyle structure, that
1107 // will be used to get default values for missing keys.
1108 // If the first element has no Language specified, it will be treated as the
1109 // default one for the following elements.
1110 template <> struct DocumentListTraits
<std::vector
<FormatStyle
>> {
1111 static size_t size(IO
&IO
, std::vector
<FormatStyle
> &Seq
) {
1114 static FormatStyle
&element(IO
&IO
, std::vector
<FormatStyle
> &Seq
,
1116 if (Index
>= Seq
.size()) {
1117 assert(Index
== Seq
.size());
1118 FormatStyle Template
;
1119 if (!Seq
.empty() && Seq
[0].Language
== FormatStyle::LK_None
) {
1122 Template
= *((const FormatStyle
*)IO
.getContext());
1123 Template
.Language
= FormatStyle::LK_None
;
1125 Seq
.resize(Index
+ 1, Template
);
1136 const std::error_category
&getParseCategory() {
1137 static const ParseErrorCategory C
{};
1140 std::error_code
make_error_code(ParseError e
) {
1141 return std::error_code(static_cast<int>(e
), getParseCategory());
1144 inline llvm::Error
make_string_error(const llvm::Twine
&Message
) {
1145 return llvm::make_error
<llvm::StringError
>(Message
,
1146 llvm::inconvertibleErrorCode());
1149 const char *ParseErrorCategory::name() const noexcept
{
1150 return "clang-format.parse_error";
1153 std::string
ParseErrorCategory::message(int EV
) const {
1154 switch (static_cast<ParseError
>(EV
)) {
1155 case ParseError::Success
:
1157 case ParseError::Error
:
1158 return "Invalid argument";
1159 case ParseError::Unsuitable
:
1160 return "Unsuitable";
1161 case ParseError::BinPackTrailingCommaConflict
:
1162 return "trailing comma insertion cannot be used with bin packing";
1163 case ParseError::InvalidQualifierSpecified
:
1164 return "Invalid qualifier specified in QualifierOrder";
1165 case ParseError::DuplicateQualifierSpecified
:
1166 return "Duplicate qualifier specified in QualifierOrder";
1167 case ParseError::MissingQualifierType
:
1168 return "Missing type in QualifierOrder";
1169 case ParseError::MissingQualifierOrder
:
1170 return "Missing QualifierOrder";
1172 llvm_unreachable("unexpected parse error");
1175 static void expandPresetsBraceWrapping(FormatStyle
&Expanded
) {
1176 if (Expanded
.BreakBeforeBraces
== FormatStyle::BS_Custom
)
1178 Expanded
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1179 /*AfterClass=*/false,
1180 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1181 /*AfterEnum=*/false,
1182 /*AfterFunction=*/false,
1183 /*AfterNamespace=*/false,
1184 /*AfterObjCDeclaration=*/false,
1185 /*AfterStruct=*/false,
1186 /*AfterUnion=*/false,
1187 /*AfterExternBlock=*/false,
1188 /*BeforeCatch=*/false,
1189 /*BeforeElse=*/false,
1190 /*BeforeLambdaBody=*/false,
1191 /*BeforeWhile=*/false,
1192 /*IndentBraces=*/false,
1193 /*SplitEmptyFunction=*/true,
1194 /*SplitEmptyRecord=*/true,
1195 /*SplitEmptyNamespace=*/true};
1196 switch (Expanded
.BreakBeforeBraces
) {
1197 case FormatStyle::BS_Linux
:
1198 Expanded
.BraceWrapping
.AfterClass
= true;
1199 Expanded
.BraceWrapping
.AfterFunction
= true;
1200 Expanded
.BraceWrapping
.AfterNamespace
= true;
1202 case FormatStyle::BS_Mozilla
:
1203 Expanded
.BraceWrapping
.AfterClass
= true;
1204 Expanded
.BraceWrapping
.AfterEnum
= true;
1205 Expanded
.BraceWrapping
.AfterFunction
= true;
1206 Expanded
.BraceWrapping
.AfterStruct
= true;
1207 Expanded
.BraceWrapping
.AfterUnion
= true;
1208 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1209 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1210 Expanded
.BraceWrapping
.SplitEmptyFunction
= true;
1211 Expanded
.BraceWrapping
.SplitEmptyRecord
= false;
1213 case FormatStyle::BS_Stroustrup
:
1214 Expanded
.BraceWrapping
.AfterFunction
= true;
1215 Expanded
.BraceWrapping
.BeforeCatch
= true;
1216 Expanded
.BraceWrapping
.BeforeElse
= true;
1218 case FormatStyle::BS_Allman
:
1219 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1220 Expanded
.BraceWrapping
.AfterClass
= true;
1221 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1222 Expanded
.BraceWrapping
.AfterEnum
= true;
1223 Expanded
.BraceWrapping
.AfterFunction
= true;
1224 Expanded
.BraceWrapping
.AfterNamespace
= true;
1225 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1226 Expanded
.BraceWrapping
.AfterStruct
= true;
1227 Expanded
.BraceWrapping
.AfterUnion
= true;
1228 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1229 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1230 Expanded
.BraceWrapping
.BeforeCatch
= true;
1231 Expanded
.BraceWrapping
.BeforeElse
= true;
1232 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1234 case FormatStyle::BS_Whitesmiths
:
1235 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1236 Expanded
.BraceWrapping
.AfterClass
= true;
1237 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1238 Expanded
.BraceWrapping
.AfterEnum
= true;
1239 Expanded
.BraceWrapping
.AfterFunction
= true;
1240 Expanded
.BraceWrapping
.AfterNamespace
= true;
1241 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1242 Expanded
.BraceWrapping
.AfterStruct
= true;
1243 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1244 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1245 Expanded
.BraceWrapping
.BeforeCatch
= true;
1246 Expanded
.BraceWrapping
.BeforeElse
= true;
1247 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1249 case FormatStyle::BS_GNU
:
1250 Expanded
.BraceWrapping
= {
1251 /*AfterCaseLabel=*/true,
1252 /*AfterClass=*/true,
1253 /*AfterControlStatement=*/FormatStyle::BWACS_Always
,
1255 /*AfterFunction=*/true,
1256 /*AfterNamespace=*/true,
1257 /*AfterObjCDeclaration=*/true,
1258 /*AfterStruct=*/true,
1259 /*AfterUnion=*/true,
1260 /*AfterExternBlock=*/true,
1261 /*BeforeCatch=*/true,
1262 /*BeforeElse=*/true,
1263 /*BeforeLambdaBody=*/false,
1264 /*BeforeWhile=*/true,
1265 /*IndentBraces=*/true,
1266 /*SplitEmptyFunction=*/true,
1267 /*SplitEmptyRecord=*/true,
1268 /*SplitEmptyNamespace=*/true};
1269 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1271 case FormatStyle::BS_WebKit
:
1272 Expanded
.BraceWrapping
.AfterFunction
= true;
1279 static void expandPresetsSpaceBeforeParens(FormatStyle
&Expanded
) {
1280 if (Expanded
.SpaceBeforeParens
== FormatStyle::SBPO_Custom
)
1283 Expanded
.SpaceBeforeParensOptions
= {};
1285 switch (Expanded
.SpaceBeforeParens
) {
1286 case FormatStyle::SBPO_Never
:
1288 case FormatStyle::SBPO_ControlStatements
:
1289 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1290 Expanded
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1291 Expanded
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1293 case FormatStyle::SBPO_ControlStatementsExceptControlMacros
:
1294 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1296 case FormatStyle::SBPO_NonEmptyParentheses
:
1297 Expanded
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
= true;
1299 case FormatStyle::SBPO_Always
:
1306 FormatStyle
getLLVMStyle(FormatStyle::LanguageKind Language
) {
1307 FormatStyle LLVMStyle
;
1308 LLVMStyle
.InheritsParentConfig
= false;
1309 LLVMStyle
.Language
= Language
;
1310 LLVMStyle
.AccessModifierOffset
= -2;
1311 LLVMStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Right
;
1312 LLVMStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_Align
;
1313 LLVMStyle
.AlignArrayOfStructures
= FormatStyle::AIAS_None
;
1314 LLVMStyle
.AlignOperands
= FormatStyle::OAS_Align
;
1315 LLVMStyle
.AlignConsecutiveAssignments
= {};
1316 LLVMStyle
.AlignConsecutiveAssignments
.Enabled
= false;
1317 LLVMStyle
.AlignConsecutiveAssignments
.AcrossEmptyLines
= false;
1318 LLVMStyle
.AlignConsecutiveAssignments
.AcrossComments
= false;
1319 LLVMStyle
.AlignConsecutiveAssignments
.AlignCompound
= false;
1320 LLVMStyle
.AlignConsecutiveAssignments
.PadOperators
= true;
1321 LLVMStyle
.AlignConsecutiveBitFields
= {};
1322 LLVMStyle
.AlignConsecutiveDeclarations
= {};
1323 LLVMStyle
.AlignConsecutiveMacros
= {};
1324 LLVMStyle
.AlignTrailingComments
= {};
1325 LLVMStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Always
;
1326 LLVMStyle
.AlignTrailingComments
.OverEmptyLines
= 0;
1327 LLVMStyle
.AllowAllArgumentsOnNextLine
= true;
1328 LLVMStyle
.AllowAllParametersOfDeclarationOnNextLine
= true;
1329 LLVMStyle
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Never
;
1330 LLVMStyle
.AllowShortCaseLabelsOnASingleLine
= false;
1331 LLVMStyle
.AllowShortEnumsOnASingleLine
= true;
1332 LLVMStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_All
;
1333 LLVMStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1334 LLVMStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_All
;
1335 LLVMStyle
.AllowShortLoopsOnASingleLine
= false;
1336 LLVMStyle
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_None
;
1337 LLVMStyle
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1338 LLVMStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1339 LLVMStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_MultiLine
;
1340 LLVMStyle
.AttributeMacros
.push_back("__capability");
1341 LLVMStyle
.BitFieldColonSpacing
= FormatStyle::BFCS_Both
;
1342 LLVMStyle
.BinPackArguments
= true;
1343 LLVMStyle
.BinPackParameters
= true;
1344 LLVMStyle
.BracedInitializerIndentWidth
= std::nullopt
;
1345 LLVMStyle
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1346 /*AfterClass=*/false,
1347 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1348 /*AfterEnum=*/false,
1349 /*AfterFunction=*/false,
1350 /*AfterNamespace=*/false,
1351 /*AfterObjCDeclaration=*/false,
1352 /*AfterStruct=*/false,
1353 /*AfterUnion=*/false,
1354 /*AfterExternBlock=*/false,
1355 /*BeforeCatch=*/false,
1356 /*BeforeElse=*/false,
1357 /*BeforeLambdaBody=*/false,
1358 /*BeforeWhile=*/false,
1359 /*IndentBraces=*/false,
1360 /*SplitEmptyFunction=*/true,
1361 /*SplitEmptyRecord=*/true,
1362 /*SplitEmptyNamespace=*/true};
1363 LLVMStyle
.BreakAfterAttributes
= FormatStyle::ABS_Never
;
1364 LLVMStyle
.BreakAfterJavaFieldAnnotations
= false;
1365 LLVMStyle
.BreakArrays
= true;
1366 LLVMStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_None
;
1367 LLVMStyle
.BreakBeforeBraces
= FormatStyle::BS_Attach
;
1368 LLVMStyle
.BreakBeforeConceptDeclarations
= FormatStyle::BBCDS_Always
;
1369 LLVMStyle
.BreakBeforeInlineASMColon
= FormatStyle::BBIAS_OnlyMultiline
;
1370 LLVMStyle
.BreakBeforeTernaryOperators
= true;
1371 LLVMStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeColon
;
1372 LLVMStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeColon
;
1373 LLVMStyle
.BreakStringLiterals
= true;
1374 LLVMStyle
.ColumnLimit
= 80;
1375 LLVMStyle
.CommentPragmas
= "^ IWYU pragma:";
1376 LLVMStyle
.CompactNamespaces
= false;
1377 LLVMStyle
.ConstructorInitializerIndentWidth
= 4;
1378 LLVMStyle
.ContinuationIndentWidth
= 4;
1379 LLVMStyle
.Cpp11BracedListStyle
= true;
1380 LLVMStyle
.DerivePointerAlignment
= false;
1381 LLVMStyle
.DisableFormat
= false;
1382 LLVMStyle
.EmptyLineAfterAccessModifier
= FormatStyle::ELAAMS_Never
;
1383 LLVMStyle
.EmptyLineBeforeAccessModifier
= FormatStyle::ELBAMS_LogicalBlock
;
1384 LLVMStyle
.ExperimentalAutoDetectBinPacking
= false;
1385 LLVMStyle
.FixNamespaceComments
= true;
1386 LLVMStyle
.ForEachMacros
.push_back("foreach");
1387 LLVMStyle
.ForEachMacros
.push_back("Q_FOREACH");
1388 LLVMStyle
.ForEachMacros
.push_back("BOOST_FOREACH");
1389 LLVMStyle
.IfMacros
.push_back("KJ_IF_MAYBE");
1390 LLVMStyle
.IncludeStyle
.IncludeCategories
= {
1391 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1392 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1393 {".*", 1, 0, false}};
1394 LLVMStyle
.IncludeStyle
.IncludeIsMainRegex
= "(Test)?$";
1395 LLVMStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Preserve
;
1396 LLVMStyle
.IndentAccessModifiers
= false;
1397 LLVMStyle
.IndentCaseLabels
= false;
1398 LLVMStyle
.IndentCaseBlocks
= false;
1399 LLVMStyle
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1400 LLVMStyle
.IndentGotoLabels
= true;
1401 LLVMStyle
.IndentPPDirectives
= FormatStyle::PPDIS_None
;
1402 LLVMStyle
.IndentRequiresClause
= true;
1403 LLVMStyle
.IndentWidth
= 2;
1404 LLVMStyle
.IndentWrappedFunctionNames
= false;
1405 LLVMStyle
.InsertBraces
= false;
1406 LLVMStyle
.InsertNewlineAtEOF
= false;
1407 LLVMStyle
.InsertTrailingCommas
= FormatStyle::TCS_None
;
1408 LLVMStyle
.IntegerLiteralSeparator
= {
1409 /*Binary=*/0, /*BinaryMinDigits=*/0,
1410 /*Decimal=*/0, /*DecimalMinDigits=*/0,
1411 /*Hex=*/0, /*HexMinDigits=*/0};
1412 LLVMStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Leave
;
1413 LLVMStyle
.JavaScriptWrapImports
= true;
1414 LLVMStyle
.KeepEmptyLinesAtEOF
= false;
1415 LLVMStyle
.KeepEmptyLinesAtTheStartOfBlocks
= true;
1416 LLVMStyle
.LambdaBodyIndentation
= FormatStyle::LBI_Signature
;
1417 LLVMStyle
.LineEnding
= FormatStyle::LE_DeriveLF
;
1418 LLVMStyle
.MaxEmptyLinesToKeep
= 1;
1419 LLVMStyle
.NamespaceIndentation
= FormatStyle::NI_None
;
1420 LLVMStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Auto
;
1421 LLVMStyle
.ObjCBlockIndentWidth
= 2;
1422 LLVMStyle
.ObjCBreakBeforeNestedBlockParam
= true;
1423 LLVMStyle
.ObjCSpaceAfterProperty
= false;
1424 LLVMStyle
.ObjCSpaceBeforeProtocolList
= true;
1425 LLVMStyle
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1426 LLVMStyle
.PointerAlignment
= FormatStyle::PAS_Right
;
1427 LLVMStyle
.PPIndentWidth
= -1;
1428 LLVMStyle
.QualifierAlignment
= FormatStyle::QAS_Leave
;
1429 LLVMStyle
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
1430 LLVMStyle
.ReflowComments
= true;
1431 LLVMStyle
.RemoveBracesLLVM
= false;
1432 LLVMStyle
.RemoveSemicolon
= false;
1433 LLVMStyle
.RequiresClausePosition
= FormatStyle::RCPS_OwnLine
;
1434 LLVMStyle
.RequiresExpressionIndentation
= FormatStyle::REI_OuterScope
;
1435 LLVMStyle
.SeparateDefinitionBlocks
= FormatStyle::SDS_Leave
;
1436 LLVMStyle
.ShortNamespaceLines
= 1;
1437 LLVMStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1438 LLVMStyle
.SortJavaStaticImport
= FormatStyle::SJSIO_Before
;
1439 LLVMStyle
.SortUsingDeclarations
= FormatStyle::SUD_LexicographicNumeric
;
1440 LLVMStyle
.SpaceAfterCStyleCast
= false;
1441 LLVMStyle
.SpaceAfterLogicalNot
= false;
1442 LLVMStyle
.SpaceAfterTemplateKeyword
= true;
1443 LLVMStyle
.SpaceAroundPointerQualifiers
= FormatStyle::SAPQ_Default
;
1444 LLVMStyle
.SpaceBeforeCaseColon
= false;
1445 LLVMStyle
.SpaceBeforeCtorInitializerColon
= true;
1446 LLVMStyle
.SpaceBeforeInheritanceColon
= true;
1447 LLVMStyle
.SpaceBeforeJsonColon
= false;
1448 LLVMStyle
.SpaceBeforeParens
= FormatStyle::SBPO_ControlStatements
;
1449 LLVMStyle
.SpaceBeforeParensOptions
= {};
1450 LLVMStyle
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1451 LLVMStyle
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1452 LLVMStyle
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1453 LLVMStyle
.SpaceBeforeRangeBasedForLoopColon
= true;
1454 LLVMStyle
.SpaceBeforeAssignmentOperators
= true;
1455 LLVMStyle
.SpaceBeforeCpp11BracedList
= false;
1456 LLVMStyle
.SpaceBeforeSquareBrackets
= false;
1457 LLVMStyle
.SpaceInEmptyBlock
= false;
1458 LLVMStyle
.SpaceInEmptyParentheses
= false;
1459 LLVMStyle
.SpacesBeforeTrailingComments
= 1;
1460 LLVMStyle
.SpacesInAngles
= FormatStyle::SIAS_Never
;
1461 LLVMStyle
.SpacesInContainerLiterals
= true;
1462 LLVMStyle
.SpacesInCStyleCastParentheses
= false;
1463 LLVMStyle
.SpacesInLineCommentPrefix
= {/*Minimum=*/1, /*Maximum=*/-1u};
1464 LLVMStyle
.SpacesInParentheses
= false;
1465 LLVMStyle
.SpacesInSquareBrackets
= false;
1466 LLVMStyle
.SpacesInConditionalStatement
= false;
1467 LLVMStyle
.Standard
= FormatStyle::LS_Latest
;
1468 LLVMStyle
.StatementAttributeLikeMacros
.push_back("Q_EMIT");
1469 LLVMStyle
.StatementMacros
.push_back("Q_UNUSED");
1470 LLVMStyle
.StatementMacros
.push_back("QT_REQUIRE_VERSION");
1471 LLVMStyle
.TabWidth
= 8;
1472 LLVMStyle
.UseTab
= FormatStyle::UT_Never
;
1473 LLVMStyle
.VerilogBreakBetweenInstancePorts
= true;
1474 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("BOOST_PP_STRINGIZE");
1475 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("CF_SWIFT_NAME");
1476 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("NS_SWIFT_NAME");
1477 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("PP_STRINGIZE");
1478 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("STRINGIZE");
1480 LLVMStyle
.PenaltyBreakAssignment
= prec::Assignment
;
1481 LLVMStyle
.PenaltyBreakComment
= 300;
1482 LLVMStyle
.PenaltyBreakFirstLessLess
= 120;
1483 LLVMStyle
.PenaltyBreakString
= 1000;
1484 LLVMStyle
.PenaltyExcessCharacter
= 1000000;
1485 LLVMStyle
.PenaltyReturnTypeOnItsOwnLine
= 60;
1486 LLVMStyle
.PenaltyBreakBeforeFirstCallParameter
= 19;
1487 LLVMStyle
.PenaltyBreakOpenParenthesis
= 0;
1488 LLVMStyle
.PenaltyBreakTemplateDeclaration
= prec::Relational
;
1489 LLVMStyle
.PenaltyIndentedWhitespace
= 0;
1491 // Defaults that differ when not C++.
1493 case FormatStyle::LK_TableGen
:
1494 LLVMStyle
.SpacesInContainerLiterals
= false;
1496 case FormatStyle::LK_Json
:
1497 LLVMStyle
.ColumnLimit
= 0;
1499 case FormatStyle::LK_Verilog
:
1500 LLVMStyle
.IndentCaseLabels
= true;
1501 LLVMStyle
.SpacesInContainerLiterals
= false;
1510 FormatStyle
getGoogleStyle(FormatStyle::LanguageKind Language
) {
1511 if (Language
== FormatStyle::LK_TextProto
) {
1512 FormatStyle GoogleStyle
= getGoogleStyle(FormatStyle::LK_Proto
);
1513 GoogleStyle
.Language
= FormatStyle::LK_TextProto
;
1518 FormatStyle GoogleStyle
= getLLVMStyle(Language
);
1520 GoogleStyle
.AccessModifierOffset
= -1;
1521 GoogleStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Left
;
1522 GoogleStyle
.AllowShortIfStatementsOnASingleLine
=
1523 FormatStyle::SIS_WithoutElse
;
1524 GoogleStyle
.AllowShortLoopsOnASingleLine
= true;
1525 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= true;
1526 GoogleStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1527 GoogleStyle
.DerivePointerAlignment
= true;
1528 GoogleStyle
.IncludeStyle
.IncludeCategories
= {{"^<ext/.*\\.h>", 2, 0, false},
1529 {"^<.*\\.h>", 1, 0, false},
1530 {"^<.*", 2, 0, false},
1531 {".*", 3, 0, false}};
1532 GoogleStyle
.IncludeStyle
.IncludeIsMainRegex
= "([-_](test|unittest))?$";
1533 GoogleStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Regroup
;
1534 GoogleStyle
.IndentCaseLabels
= true;
1535 GoogleStyle
.KeepEmptyLinesAtTheStartOfBlocks
= false;
1536 GoogleStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Never
;
1537 GoogleStyle
.ObjCSpaceAfterProperty
= false;
1538 GoogleStyle
.ObjCSpaceBeforeProtocolList
= true;
1539 GoogleStyle
.PackConstructorInitializers
= FormatStyle::PCIS_NextLine
;
1540 GoogleStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1541 GoogleStyle
.RawStringFormats
= {
1543 FormatStyle::LK_Cpp
,
1554 /*EnclosingFunctionNames=*/
1556 /*CanonicalDelimiter=*/"",
1557 /*BasedOnStyle=*/"google",
1560 FormatStyle::LK_TextProto
,
1568 /*EnclosingFunctionNames=*/
1572 "PARSE_PARTIAL_TEXT_PROTO",
1576 "ParseTextProtoOrDie",
1578 "ParsePartialTestProto",
1580 /*CanonicalDelimiter=*/"pb",
1581 /*BasedOnStyle=*/"google",
1584 GoogleStyle
.SpacesBeforeTrailingComments
= 2;
1585 GoogleStyle
.Standard
= FormatStyle::LS_Auto
;
1587 GoogleStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1588 GoogleStyle
.PenaltyBreakBeforeFirstCallParameter
= 1;
1590 if (Language
== FormatStyle::LK_Java
) {
1591 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1592 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1593 GoogleStyle
.AlignTrailingComments
= {};
1594 GoogleStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1595 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1596 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1597 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1598 GoogleStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_NonAssignment
;
1599 GoogleStyle
.ColumnLimit
= 100;
1600 GoogleStyle
.SpaceAfterCStyleCast
= true;
1601 GoogleStyle
.SpacesBeforeTrailingComments
= 1;
1602 } else if (Language
== FormatStyle::LK_JavaScript
) {
1603 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_AlwaysBreak
;
1604 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1605 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1606 // TODO: still under discussion whether to switch to SLS_All.
1607 GoogleStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_Empty
;
1608 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1609 GoogleStyle
.BreakBeforeTernaryOperators
= false;
1610 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1611 // commonly followed by overlong URLs.
1612 GoogleStyle
.CommentPragmas
= "(taze:|^/[ \t]*<|tslint:|@see)";
1613 // TODO: enable once decided, in particular re disabling bin packing.
1614 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1615 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1616 GoogleStyle
.MaxEmptyLinesToKeep
= 3;
1617 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1618 GoogleStyle
.SpacesInContainerLiterals
= false;
1619 GoogleStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Single
;
1620 GoogleStyle
.JavaScriptWrapImports
= false;
1621 } else if (Language
== FormatStyle::LK_Proto
) {
1622 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1623 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1624 GoogleStyle
.SpacesInContainerLiterals
= false;
1625 GoogleStyle
.Cpp11BracedListStyle
= false;
1626 // This affects protocol buffer options specifications and text protos.
1627 // Text protos are currently mostly formatted inside C++ raw string literals
1628 // and often the current breaking behavior of string literals is not
1629 // beneficial there. Investigate turning this on once proper string reflow
1630 // has been implemented.
1631 GoogleStyle
.BreakStringLiterals
= false;
1632 } else if (Language
== FormatStyle::LK_ObjC
) {
1633 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1634 GoogleStyle
.ColumnLimit
= 100;
1635 // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1636 // relationship between ObjC standard library headers and other heades,
1638 GoogleStyle
.IncludeStyle
.IncludeBlocks
=
1639 tooling::IncludeStyle::IBS_Preserve
;
1640 } else if (Language
== FormatStyle::LK_CSharp
) {
1641 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1642 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1643 GoogleStyle
.BreakStringLiterals
= false;
1644 GoogleStyle
.ColumnLimit
= 100;
1645 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1651 FormatStyle
getChromiumStyle(FormatStyle::LanguageKind Language
) {
1652 FormatStyle ChromiumStyle
= getGoogleStyle(Language
);
1654 // Disable include reordering across blocks in Chromium code.
1655 // - clang-format tries to detect that foo.h is the "main" header for
1656 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1657 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1658 // _private.cc, _impl.cc etc) in different permutations
1659 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1660 // better default for Chromium code.
1661 // - The default for .cc and .mm files is different (r357695) for Google style
1662 // for the same reason. The plan is to unify this again once the main
1663 // header detection works for Google's ObjC code, but this hasn't happened
1664 // yet. Since Chromium has some ObjC code, switching Chromium is blocked
1666 // - Finally, "If include reordering is harmful, put things in different
1667 // blocks to prevent it" has been a recommendation for a long time that
1668 // people are used to. We'll need a dev education push to change this to
1669 // "If include reordering is harmful, put things in a different block and
1670 // _prepend that with a comment_ to prevent it" before changing behavior.
1671 ChromiumStyle
.IncludeStyle
.IncludeBlocks
=
1672 tooling::IncludeStyle::IBS_Preserve
;
1674 if (Language
== FormatStyle::LK_Java
) {
1675 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
=
1676 FormatStyle::SIS_WithoutElse
;
1677 ChromiumStyle
.BreakAfterJavaFieldAnnotations
= true;
1678 ChromiumStyle
.ContinuationIndentWidth
= 8;
1679 ChromiumStyle
.IndentWidth
= 4;
1680 // See styleguide for import groups:
1681 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1682 ChromiumStyle
.JavaImportGroups
= {
1689 "com.google.android.apps.chrome",
1694 ChromiumStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1695 } else if (Language
== FormatStyle::LK_JavaScript
) {
1696 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1697 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1699 ChromiumStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1700 ChromiumStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1701 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1702 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1703 ChromiumStyle
.BinPackParameters
= false;
1704 ChromiumStyle
.DerivePointerAlignment
= false;
1705 if (Language
== FormatStyle::LK_ObjC
)
1706 ChromiumStyle
.ColumnLimit
= 80;
1708 return ChromiumStyle
;
1711 FormatStyle
getMozillaStyle() {
1712 FormatStyle MozillaStyle
= getLLVMStyle();
1713 MozillaStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1714 MozillaStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1715 MozillaStyle
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_TopLevel
;
1716 MozillaStyle
.AlwaysBreakAfterDefinitionReturnType
=
1717 FormatStyle::DRTBS_TopLevel
;
1718 MozillaStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1719 MozillaStyle
.BinPackParameters
= false;
1720 MozillaStyle
.BinPackArguments
= false;
1721 MozillaStyle
.BreakBeforeBraces
= FormatStyle::BS_Mozilla
;
1722 MozillaStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1723 MozillaStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1724 MozillaStyle
.ConstructorInitializerIndentWidth
= 2;
1725 MozillaStyle
.ContinuationIndentWidth
= 2;
1726 MozillaStyle
.Cpp11BracedListStyle
= false;
1727 MozillaStyle
.FixNamespaceComments
= false;
1728 MozillaStyle
.IndentCaseLabels
= true;
1729 MozillaStyle
.ObjCSpaceAfterProperty
= true;
1730 MozillaStyle
.ObjCSpaceBeforeProtocolList
= false;
1731 MozillaStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1732 MozillaStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1733 MozillaStyle
.SpaceAfterTemplateKeyword
= false;
1734 return MozillaStyle
;
1737 FormatStyle
getWebKitStyle() {
1738 FormatStyle Style
= getLLVMStyle();
1739 Style
.AccessModifierOffset
= -4;
1740 Style
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1741 Style
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1742 Style
.AlignTrailingComments
= {};
1743 Style
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1744 Style
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Empty
;
1745 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1746 Style
.BreakBeforeBraces
= FormatStyle::BS_WebKit
;
1747 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1748 Style
.Cpp11BracedListStyle
= false;
1749 Style
.ColumnLimit
= 0;
1750 Style
.FixNamespaceComments
= false;
1751 Style
.IndentWidth
= 4;
1752 Style
.NamespaceIndentation
= FormatStyle::NI_Inner
;
1753 Style
.ObjCBlockIndentWidth
= 4;
1754 Style
.ObjCSpaceAfterProperty
= true;
1755 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
1756 Style
.SpaceBeforeCpp11BracedList
= true;
1757 Style
.SpaceInEmptyBlock
= true;
1761 FormatStyle
getGNUStyle() {
1762 FormatStyle Style
= getLLVMStyle();
1763 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_All
;
1764 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1765 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1766 Style
.BreakBeforeBraces
= FormatStyle::BS_GNU
;
1767 Style
.BreakBeforeTernaryOperators
= true;
1768 Style
.Cpp11BracedListStyle
= false;
1769 Style
.ColumnLimit
= 79;
1770 Style
.FixNamespaceComments
= false;
1771 Style
.SpaceBeforeParens
= FormatStyle::SBPO_Always
;
1772 Style
.Standard
= FormatStyle::LS_Cpp03
;
1776 FormatStyle
getMicrosoftStyle(FormatStyle::LanguageKind Language
) {
1777 FormatStyle Style
= getLLVMStyle(Language
);
1778 Style
.ColumnLimit
= 120;
1780 Style
.IndentWidth
= 4;
1781 Style
.UseTab
= FormatStyle::UT_Never
;
1782 Style
.BreakBeforeBraces
= FormatStyle::BS_Custom
;
1783 Style
.BraceWrapping
.AfterClass
= true;
1784 Style
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1785 Style
.BraceWrapping
.AfterEnum
= true;
1786 Style
.BraceWrapping
.AfterFunction
= true;
1787 Style
.BraceWrapping
.AfterNamespace
= true;
1788 Style
.BraceWrapping
.AfterObjCDeclaration
= true;
1789 Style
.BraceWrapping
.AfterStruct
= true;
1790 Style
.BraceWrapping
.AfterExternBlock
= true;
1791 Style
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1792 Style
.BraceWrapping
.BeforeCatch
= true;
1793 Style
.BraceWrapping
.BeforeElse
= true;
1794 Style
.BraceWrapping
.BeforeWhile
= false;
1795 Style
.PenaltyReturnTypeOnItsOwnLine
= 1000;
1796 Style
.AllowShortEnumsOnASingleLine
= false;
1797 Style
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_None
;
1798 Style
.AllowShortCaseLabelsOnASingleLine
= false;
1799 Style
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1800 Style
.AllowShortLoopsOnASingleLine
= false;
1801 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1802 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_None
;
1806 FormatStyle
getNoStyle() {
1807 FormatStyle NoStyle
= getLLVMStyle();
1808 NoStyle
.DisableFormat
= true;
1809 NoStyle
.SortIncludes
= FormatStyle::SI_Never
;
1810 NoStyle
.SortUsingDeclarations
= FormatStyle::SUD_Never
;
1814 bool getPredefinedStyle(StringRef Name
, FormatStyle::LanguageKind Language
,
1815 FormatStyle
*Style
) {
1816 if (Name
.equals_insensitive("llvm"))
1817 *Style
= getLLVMStyle(Language
);
1818 else if (Name
.equals_insensitive("chromium"))
1819 *Style
= getChromiumStyle(Language
);
1820 else if (Name
.equals_insensitive("mozilla"))
1821 *Style
= getMozillaStyle();
1822 else if (Name
.equals_insensitive("google"))
1823 *Style
= getGoogleStyle(Language
);
1824 else if (Name
.equals_insensitive("webkit"))
1825 *Style
= getWebKitStyle();
1826 else if (Name
.equals_insensitive("gnu"))
1827 *Style
= getGNUStyle();
1828 else if (Name
.equals_insensitive("microsoft"))
1829 *Style
= getMicrosoftStyle(Language
);
1830 else if (Name
.equals_insensitive("none"))
1831 *Style
= getNoStyle();
1832 else if (Name
.equals_insensitive("inheritparentconfig"))
1833 Style
->InheritsParentConfig
= true;
1837 Style
->Language
= Language
;
1841 ParseError
validateQualifierOrder(FormatStyle
*Style
) {
1842 // If its empty then it means don't do anything.
1843 if (Style
->QualifierOrder
.empty())
1844 return ParseError::MissingQualifierOrder
;
1846 // Ensure the list contains only currently valid qualifiers.
1847 for (const auto &Qualifier
: Style
->QualifierOrder
) {
1848 if (Qualifier
== "type")
1851 LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier
);
1852 if (token
== tok::identifier
)
1853 return ParseError::InvalidQualifierSpecified
;
1856 // Ensure the list is unique (no duplicates).
1857 std::set
<std::string
> UniqueQualifiers(Style
->QualifierOrder
.begin(),
1858 Style
->QualifierOrder
.end());
1859 if (Style
->QualifierOrder
.size() != UniqueQualifiers
.size()) {
1860 LLVM_DEBUG(llvm::dbgs()
1861 << "Duplicate Qualifiers " << Style
->QualifierOrder
.size()
1862 << " vs " << UniqueQualifiers
.size() << "\n");
1863 return ParseError::DuplicateQualifierSpecified
;
1866 // Ensure the list has 'type' in it.
1867 if (!llvm::is_contained(Style
->QualifierOrder
, "type"))
1868 return ParseError::MissingQualifierType
;
1870 return ParseError::Success
;
1873 std::error_code
parseConfiguration(llvm::MemoryBufferRef Config
,
1874 FormatStyle
*Style
, bool AllowUnknownOptions
,
1875 llvm::SourceMgr::DiagHandlerTy DiagHandler
,
1876 void *DiagHandlerCtxt
) {
1878 FormatStyle::LanguageKind Language
= Style
->Language
;
1879 assert(Language
!= FormatStyle::LK_None
);
1880 if (Config
.getBuffer().trim().empty())
1881 return make_error_code(ParseError::Success
);
1882 Style
->StyleSet
.Clear();
1883 std::vector
<FormatStyle
> Styles
;
1884 llvm::yaml::Input
Input(Config
, /*Ctxt=*/nullptr, DiagHandler
,
1886 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
1887 // values for the fields, keys for which are missing from the configuration.
1888 // Mapping also uses the context to get the language to find the correct
1890 Input
.setContext(Style
);
1891 Input
.setAllowUnknownKeys(AllowUnknownOptions
);
1894 return Input
.error();
1896 for (unsigned i
= 0; i
< Styles
.size(); ++i
) {
1897 // Ensures that only the first configuration can skip the Language option.
1898 if (Styles
[i
].Language
== FormatStyle::LK_None
&& i
!= 0)
1899 return make_error_code(ParseError::Error
);
1900 // Ensure that each language is configured at most once.
1901 for (unsigned j
= 0; j
< i
; ++j
) {
1902 if (Styles
[i
].Language
== Styles
[j
].Language
) {
1903 LLVM_DEBUG(llvm::dbgs()
1904 << "Duplicate languages in the config file on positions "
1905 << j
<< " and " << i
<< "\n");
1906 return make_error_code(ParseError::Error
);
1910 // Look for a suitable configuration starting from the end, so we can
1911 // find the configuration for the specific language first, and the default
1912 // configuration (which can only be at slot 0) after it.
1913 FormatStyle::FormatStyleSet StyleSet
;
1914 bool LanguageFound
= false;
1915 for (const FormatStyle
&Style
: llvm::reverse(Styles
)) {
1916 if (Style
.Language
!= FormatStyle::LK_None
)
1917 StyleSet
.Add(Style
);
1918 if (Style
.Language
== Language
)
1919 LanguageFound
= true;
1921 if (!LanguageFound
) {
1922 if (Styles
.empty() || Styles
[0].Language
!= FormatStyle::LK_None
)
1923 return make_error_code(ParseError::Unsuitable
);
1924 FormatStyle DefaultStyle
= Styles
[0];
1925 DefaultStyle
.Language
= Language
;
1926 StyleSet
.Add(std::move(DefaultStyle
));
1928 *Style
= *StyleSet
.Get(Language
);
1929 if (Style
->InsertTrailingCommas
!= FormatStyle::TCS_None
&&
1930 Style
->BinPackArguments
) {
1931 // See comment on FormatStyle::TSC_Wrapped.
1932 return make_error_code(ParseError::BinPackTrailingCommaConflict
);
1934 if (Style
->QualifierAlignment
!= FormatStyle::QAS_Leave
)
1935 return make_error_code(validateQualifierOrder(Style
));
1936 return make_error_code(ParseError::Success
);
1939 std::string
configurationAsText(const FormatStyle
&Style
) {
1941 llvm::raw_string_ostream
Stream(Text
);
1942 llvm::yaml::Output
Output(Stream
);
1943 // We use the same mapping method for input and output, so we need a non-const
1945 FormatStyle NonConstStyle
= Style
;
1946 expandPresetsBraceWrapping(NonConstStyle
);
1947 expandPresetsSpaceBeforeParens(NonConstStyle
);
1948 Output
<< NonConstStyle
;
1950 return Stream
.str();
1953 std::optional
<FormatStyle
>
1954 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language
) const {
1956 return std::nullopt
;
1957 auto It
= Styles
->find(Language
);
1958 if (It
== Styles
->end())
1959 return std::nullopt
;
1960 FormatStyle Style
= It
->second
;
1961 Style
.StyleSet
= *this;
1965 void FormatStyle::FormatStyleSet::Add(FormatStyle Style
) {
1966 assert(Style
.Language
!= LK_None
&&
1967 "Cannot add a style for LK_None to a StyleSet");
1969 !Style
.StyleSet
.Styles
&&
1970 "Cannot add a style associated with an existing StyleSet to a StyleSet");
1972 Styles
= std::make_shared
<MapType
>();
1973 (*Styles
)[Style
.Language
] = std::move(Style
);
1976 void FormatStyle::FormatStyleSet::Clear() { Styles
.reset(); }
1978 std::optional
<FormatStyle
>
1979 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language
) const {
1980 return StyleSet
.Get(Language
);
1985 class BracesInserter
: public TokenAnalyzer
{
1987 BracesInserter(const Environment
&Env
, const FormatStyle
&Style
)
1988 : TokenAnalyzer(Env
, Style
) {}
1990 std::pair
<tooling::Replacements
, unsigned>
1991 analyze(TokenAnnotator
&Annotator
,
1992 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
1993 FormatTokenLexer
&Tokens
) override
{
1994 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
1995 tooling::Replacements Result
;
1996 insertBraces(AnnotatedLines
, Result
);
2001 void insertBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2002 tooling::Replacements
&Result
) {
2003 const auto &SourceMgr
= Env
.getSourceManager();
2004 int OpeningBraceSurplus
= 0;
2005 for (AnnotatedLine
*Line
: Lines
) {
2006 insertBraces(Line
->Children
, Result
);
2007 if (!Line
->Affected
&& OpeningBraceSurplus
== 0)
2009 for (FormatToken
*Token
= Line
->First
; Token
&& !Token
->Finalized
;
2010 Token
= Token
->Next
) {
2011 int BraceCount
= Token
->BraceCount
;
2012 if (BraceCount
== 0)
2015 if (BraceCount
< 0) {
2016 assert(BraceCount
== -1);
2017 if (!Line
->Affected
)
2019 Brace
= Token
->is(tok::comment
) ? "\n{" : "{";
2020 ++OpeningBraceSurplus
;
2022 if (OpeningBraceSurplus
== 0)
2024 if (OpeningBraceSurplus
< BraceCount
)
2025 BraceCount
= OpeningBraceSurplus
;
2026 Brace
= '\n' + std::string(BraceCount
, '}');
2027 OpeningBraceSurplus
-= BraceCount
;
2029 Token
->BraceCount
= 0;
2030 const auto Start
= Token
->Tok
.getEndLoc();
2031 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Start
, 0, Brace
)));
2034 assert(OpeningBraceSurplus
== 0);
2038 class BracesRemover
: public TokenAnalyzer
{
2040 BracesRemover(const Environment
&Env
, const FormatStyle
&Style
)
2041 : TokenAnalyzer(Env
, Style
) {}
2043 std::pair
<tooling::Replacements
, unsigned>
2044 analyze(TokenAnnotator
&Annotator
,
2045 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2046 FormatTokenLexer
&Tokens
) override
{
2047 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2048 tooling::Replacements Result
;
2049 removeBraces(AnnotatedLines
, Result
);
2054 void removeBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2055 tooling::Replacements
&Result
) {
2056 const auto &SourceMgr
= Env
.getSourceManager();
2057 const auto End
= Lines
.end();
2058 for (auto I
= Lines
.begin(); I
!= End
; ++I
) {
2059 const auto Line
= *I
;
2060 removeBraces(Line
->Children
, Result
);
2061 if (!Line
->Affected
)
2063 const auto NextLine
= I
+ 1 == End
? nullptr : I
[1];
2064 for (auto Token
= Line
->First
; Token
&& !Token
->Finalized
;
2065 Token
= Token
->Next
) {
2066 if (!Token
->Optional
)
2068 if (!Token
->isOneOf(tok::l_brace
, tok::r_brace
))
2070 auto Next
= Token
->Next
;
2071 assert(Next
|| Token
== Line
->Last
);
2072 if (!Next
&& NextLine
)
2073 Next
= NextLine
->First
;
2074 SourceLocation Start
;
2075 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2076 Start
= Token
->Tok
.getLocation();
2077 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2079 Start
= Token
->WhitespaceRange
.getBegin();
2082 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2083 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2089 class SemiRemover
: public TokenAnalyzer
{
2091 SemiRemover(const Environment
&Env
, const FormatStyle
&Style
)
2092 : TokenAnalyzer(Env
, Style
) {}
2094 std::pair
<tooling::Replacements
, unsigned>
2095 analyze(TokenAnnotator
&Annotator
,
2096 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2097 FormatTokenLexer
&Tokens
) override
{
2098 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2099 tooling::Replacements Result
;
2100 removeSemi(AnnotatedLines
, Result
);
2105 void removeSemi(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2106 tooling::Replacements
&Result
) {
2107 const auto &SourceMgr
= Env
.getSourceManager();
2108 const auto End
= Lines
.end();
2109 for (auto I
= Lines
.begin(); I
!= End
; ++I
) {
2110 const auto Line
= *I
;
2111 removeSemi(Line
->Children
, Result
);
2112 if (!Line
->Affected
)
2114 const auto NextLine
= I
+ 1 == End
? nullptr : I
[1];
2115 for (auto Token
= Line
->First
; Token
&& !Token
->Finalized
;
2116 Token
= Token
->Next
) {
2117 if (!Token
->Optional
)
2119 if (Token
->isNot(tok::semi
))
2121 auto Next
= Token
->Next
;
2122 assert(Next
|| Token
== Line
->Last
);
2123 if (!Next
&& NextLine
)
2124 Next
= NextLine
->First
;
2125 SourceLocation Start
;
2126 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2127 Start
= Token
->Tok
.getLocation();
2128 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2130 Start
= Token
->WhitespaceRange
.getBegin();
2133 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2134 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2140 class JavaScriptRequoter
: public TokenAnalyzer
{
2142 JavaScriptRequoter(const Environment
&Env
, const FormatStyle
&Style
)
2143 : TokenAnalyzer(Env
, Style
) {}
2145 std::pair
<tooling::Replacements
, unsigned>
2146 analyze(TokenAnnotator
&Annotator
,
2147 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2148 FormatTokenLexer
&Tokens
) override
{
2149 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2150 tooling::Replacements Result
;
2151 requoteJSStringLiteral(AnnotatedLines
, Result
);
2156 // Replaces double/single-quoted string literal as appropriate, re-escaping
2157 // the contents in the process.
2158 void requoteJSStringLiteral(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2159 tooling::Replacements
&Result
) {
2160 for (AnnotatedLine
*Line
: Lines
) {
2161 requoteJSStringLiteral(Line
->Children
, Result
);
2162 if (!Line
->Affected
)
2164 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2165 FormatTok
= FormatTok
->Next
) {
2166 StringRef Input
= FormatTok
->TokenText
;
2167 if (FormatTok
->Finalized
|| !FormatTok
->isStringLiteral() ||
2168 // NB: testing for not starting with a double quote to avoid
2169 // breaking `template strings`.
2170 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
&&
2171 !Input
.startswith("\"")) ||
2172 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Double
&&
2173 !Input
.startswith("\'"))) {
2177 // Change start and end quote.
2178 bool IsSingle
= Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
;
2179 SourceLocation Start
= FormatTok
->Tok
.getLocation();
2180 auto Replace
= [&](SourceLocation Start
, unsigned Length
,
2181 StringRef ReplacementText
) {
2182 auto Err
= Result
.add(tooling::Replacement(
2183 Env
.getSourceManager(), Start
, Length
, ReplacementText
));
2184 // FIXME: handle error. For now, print error message and skip the
2185 // replacement for release version.
2187 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
2191 Replace(Start
, 1, IsSingle
? "'" : "\"");
2192 Replace(FormatTok
->Tok
.getEndLoc().getLocWithOffset(-1), 1,
2193 IsSingle
? "'" : "\"");
2195 // Escape internal quotes.
2196 bool Escaped
= false;
2197 for (size_t i
= 1; i
< Input
.size() - 1; i
++) {
2200 if (!Escaped
&& i
+ 1 < Input
.size() &&
2201 ((IsSingle
&& Input
[i
+ 1] == '"') ||
2202 (!IsSingle
&& Input
[i
+ 1] == '\''))) {
2203 // Remove this \, it's escaping a " or ' that no longer needs
2205 Replace(Start
.getLocWithOffset(i
), 1, "");
2212 if (!Escaped
&& IsSingle
== (Input
[i
] == '\'')) {
2213 // Escape the quote.
2214 Replace(Start
.getLocWithOffset(i
), 0, "\\");
2228 class Formatter
: public TokenAnalyzer
{
2230 Formatter(const Environment
&Env
, const FormatStyle
&Style
,
2231 FormattingAttemptStatus
*Status
)
2232 : TokenAnalyzer(Env
, Style
), Status(Status
) {}
2234 std::pair
<tooling::Replacements
, unsigned>
2235 analyze(TokenAnnotator
&Annotator
,
2236 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2237 FormatTokenLexer
&Tokens
) override
{
2238 tooling::Replacements Result
;
2239 deriveLocalStyle(AnnotatedLines
);
2240 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2241 for (AnnotatedLine
*Line
: AnnotatedLines
)
2242 Annotator
.calculateFormattingInformation(*Line
);
2243 Annotator
.setCommentLineLevels(AnnotatedLines
);
2245 WhitespaceManager
Whitespaces(
2246 Env
.getSourceManager(), Style
,
2247 Style
.LineEnding
> FormatStyle::LE_CRLF
2248 ? WhitespaceManager::inputUsesCRLF(
2249 Env
.getSourceManager().getBufferData(Env
.getFileID()),
2250 Style
.LineEnding
== FormatStyle::LE_DeriveCRLF
)
2251 : Style
.LineEnding
== FormatStyle::LE_CRLF
);
2252 ContinuationIndenter
Indenter(Style
, Tokens
.getKeywords(),
2253 Env
.getSourceManager(), Whitespaces
, Encoding
,
2254 BinPackInconclusiveFunctions
);
2256 UnwrappedLineFormatter(&Indenter
, &Whitespaces
, Style
,
2257 Tokens
.getKeywords(), Env
.getSourceManager(),
2259 .format(AnnotatedLines
, /*DryRun=*/false,
2260 /*AdditionalIndent=*/0,
2261 /*FixBadIndentation=*/false,
2262 /*FirstStartColumn=*/Env
.getFirstStartColumn(),
2263 /*NextStartColumn=*/Env
.getNextStartColumn(),
2264 /*LastStartColumn=*/Env
.getLastStartColumn());
2265 for (const auto &R
: Whitespaces
.generateReplacements())
2267 return std::make_pair(Result
, 0);
2268 return std::make_pair(Result
, Penalty
);
2273 hasCpp03IncompatibleFormat(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2274 for (const AnnotatedLine
*Line
: Lines
) {
2275 if (hasCpp03IncompatibleFormat(Line
->Children
))
2277 for (FormatToken
*Tok
= Line
->First
->Next
; Tok
; Tok
= Tok
->Next
) {
2278 if (!Tok
->hasWhitespaceBefore()) {
2279 if (Tok
->is(tok::coloncolon
) && Tok
->Previous
->is(TT_TemplateOpener
))
2281 if (Tok
->is(TT_TemplateCloser
) &&
2282 Tok
->Previous
->is(TT_TemplateCloser
)) {
2291 int countVariableAlignments(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2292 int AlignmentDiff
= 0;
2293 for (const AnnotatedLine
*Line
: Lines
) {
2294 AlignmentDiff
+= countVariableAlignments(Line
->Children
);
2295 for (FormatToken
*Tok
= Line
->First
; Tok
&& Tok
->Next
; Tok
= Tok
->Next
) {
2296 if (!Tok
->is(TT_PointerOrReference
))
2298 // Don't treat space in `void foo() &&` as evidence.
2299 if (const auto *Prev
= Tok
->getPreviousNonComment()) {
2300 if (Prev
->is(tok::r_paren
) && Prev
->MatchingParen
) {
2301 if (const auto *Func
=
2302 Prev
->MatchingParen
->getPreviousNonComment()) {
2303 if (Func
->isOneOf(TT_FunctionDeclarationName
, TT_StartOfName
,
2304 TT_OverloadedOperator
)) {
2310 bool SpaceBefore
= Tok
->hasWhitespaceBefore();
2311 bool SpaceAfter
= Tok
->Next
->hasWhitespaceBefore();
2312 if (SpaceBefore
&& !SpaceAfter
)
2314 if (!SpaceBefore
&& SpaceAfter
)
2318 return AlignmentDiff
;
2322 deriveLocalStyle(const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2323 bool HasBinPackedFunction
= false;
2324 bool HasOnePerLineFunction
= false;
2325 for (AnnotatedLine
*Line
: AnnotatedLines
) {
2326 if (!Line
->First
->Next
)
2328 FormatToken
*Tok
= Line
->First
->Next
;
2330 if (Tok
->is(PPK_BinPacked
))
2331 HasBinPackedFunction
= true;
2332 if (Tok
->is(PPK_OnePerLine
))
2333 HasOnePerLineFunction
= true;
2338 if (Style
.DerivePointerAlignment
) {
2339 const auto NetRightCount
= countVariableAlignments(AnnotatedLines
);
2340 if (NetRightCount
> 0)
2341 Style
.PointerAlignment
= FormatStyle::PAS_Right
;
2342 else if (NetRightCount
< 0)
2343 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
2344 Style
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
2346 if (Style
.Standard
== FormatStyle::LS_Auto
) {
2347 Style
.Standard
= hasCpp03IncompatibleFormat(AnnotatedLines
)
2348 ? FormatStyle::LS_Latest
2349 : FormatStyle::LS_Cpp03
;
2351 BinPackInconclusiveFunctions
=
2352 HasBinPackedFunction
|| !HasOnePerLineFunction
;
2355 bool BinPackInconclusiveFunctions
;
2356 FormattingAttemptStatus
*Status
;
2359 /// TrailingCommaInserter inserts trailing commas into container literals.
2364 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2365 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2368 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2369 /// is conceptually incompatible with bin packing.
2370 class TrailingCommaInserter
: public TokenAnalyzer
{
2372 TrailingCommaInserter(const Environment
&Env
, const FormatStyle
&Style
)
2373 : TokenAnalyzer(Env
, Style
) {}
2375 std::pair
<tooling::Replacements
, unsigned>
2376 analyze(TokenAnnotator
&Annotator
,
2377 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2378 FormatTokenLexer
&Tokens
) override
{
2379 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2380 tooling::Replacements Result
;
2381 insertTrailingCommas(AnnotatedLines
, Result
);
2386 /// Inserts trailing commas in [] and {} initializers if they wrap over
2388 void insertTrailingCommas(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2389 tooling::Replacements
&Result
) {
2390 for (AnnotatedLine
*Line
: Lines
) {
2391 insertTrailingCommas(Line
->Children
, Result
);
2392 if (!Line
->Affected
)
2394 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2395 FormatTok
= FormatTok
->Next
) {
2396 if (FormatTok
->NewlinesBefore
== 0)
2398 FormatToken
*Matching
= FormatTok
->MatchingParen
;
2399 if (!Matching
|| !FormatTok
->getPreviousNonComment())
2401 if (!(FormatTok
->is(tok::r_square
) &&
2402 Matching
->is(TT_ArrayInitializerLSquare
)) &&
2403 !(FormatTok
->is(tok::r_brace
) && Matching
->is(TT_DictLiteral
))) {
2406 FormatToken
*Prev
= FormatTok
->getPreviousNonComment();
2407 if (Prev
->is(tok::comma
) || Prev
->is(tok::semi
))
2409 // getEndLoc is not reliably set during re-lexing, use text length
2411 SourceLocation Start
=
2412 Prev
->Tok
.getLocation().getLocWithOffset(Prev
->TokenText
.size());
2413 // If inserting a comma would push the code over the column limit, skip
2414 // this location - it'd introduce an unstable formatting due to the
2416 unsigned ColumnNumber
=
2417 Env
.getSourceManager().getSpellingColumnNumber(Start
);
2418 if (ColumnNumber
> Style
.ColumnLimit
)
2420 // Comma insertions cannot conflict with each other, and this pass has a
2421 // clean set of Replacements, so the operation below cannot fail.
2422 cantFail(Result
.add(
2423 tooling::Replacement(Env
.getSourceManager(), Start
, 0, ",")));
2429 // This class clean up the erroneous/redundant code around the given ranges in
2431 class Cleaner
: public TokenAnalyzer
{
2433 Cleaner(const Environment
&Env
, const FormatStyle
&Style
)
2434 : TokenAnalyzer(Env
, Style
),
2435 DeletedTokens(FormatTokenLess(Env
.getSourceManager())) {}
2437 // FIXME: eliminate unused parameters.
2438 std::pair
<tooling::Replacements
, unsigned>
2439 analyze(TokenAnnotator
&Annotator
,
2440 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2441 FormatTokenLexer
&Tokens
) override
{
2442 // FIXME: in the current implementation the granularity of affected range
2443 // is an annotated line. However, this is not sufficient. Furthermore,
2444 // redundant code introduced by replacements does not necessarily
2445 // intercept with ranges of replacements that result in the redundancy.
2446 // To determine if some redundant code is actually introduced by
2447 // replacements(e.g. deletions), we need to come up with a more
2448 // sophisticated way of computing affected ranges.
2449 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2451 checkEmptyNamespace(AnnotatedLines
);
2453 for (auto *Line
: AnnotatedLines
)
2456 return {generateFixes(), 0};
2460 void cleanupLine(AnnotatedLine
*Line
) {
2461 for (auto *Child
: Line
->Children
)
2464 if (Line
->Affected
) {
2465 cleanupRight(Line
->First
, tok::comma
, tok::comma
);
2466 cleanupRight(Line
->First
, TT_CtorInitializerColon
, tok::comma
);
2467 cleanupRight(Line
->First
, tok::l_paren
, tok::comma
);
2468 cleanupLeft(Line
->First
, tok::comma
, tok::r_paren
);
2469 cleanupLeft(Line
->First
, TT_CtorInitializerComma
, tok::l_brace
);
2470 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::l_brace
);
2471 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::equal
);
2475 bool containsOnlyComments(const AnnotatedLine
&Line
) {
2476 for (FormatToken
*Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
)
2477 if (Tok
->isNot(tok::comment
))
2482 // Iterate through all lines and remove any empty (nested) namespaces.
2483 void checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2484 std::set
<unsigned> DeletedLines
;
2485 for (unsigned i
= 0, e
= AnnotatedLines
.size(); i
!= e
; ++i
) {
2486 auto &Line
= *AnnotatedLines
[i
];
2487 if (Line
.startsWithNamespace())
2488 checkEmptyNamespace(AnnotatedLines
, i
, i
, DeletedLines
);
2491 for (auto Line
: DeletedLines
) {
2492 FormatToken
*Tok
= AnnotatedLines
[Line
]->First
;
2500 // The function checks if the namespace, which starts from \p CurrentLine, and
2501 // its nested namespaces are empty and delete them if they are empty. It also
2502 // sets \p NewLine to the last line checked.
2503 // Returns true if the current namespace is empty.
2504 bool checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2505 unsigned CurrentLine
, unsigned &NewLine
,
2506 std::set
<unsigned> &DeletedLines
) {
2507 unsigned InitLine
= CurrentLine
, End
= AnnotatedLines
.size();
2508 if (Style
.BraceWrapping
.AfterNamespace
) {
2509 // If the left brace is in a new line, we should consume it first so that
2510 // it does not make the namespace non-empty.
2511 // FIXME: error handling if there is no left brace.
2512 if (!AnnotatedLines
[++CurrentLine
]->startsWith(tok::l_brace
)) {
2513 NewLine
= CurrentLine
;
2516 } else if (!AnnotatedLines
[CurrentLine
]->endsWith(tok::l_brace
)) {
2519 while (++CurrentLine
< End
) {
2520 if (AnnotatedLines
[CurrentLine
]->startsWith(tok::r_brace
))
2523 if (AnnotatedLines
[CurrentLine
]->startsWithNamespace()) {
2524 if (!checkEmptyNamespace(AnnotatedLines
, CurrentLine
, NewLine
,
2528 CurrentLine
= NewLine
;
2532 if (containsOnlyComments(*AnnotatedLines
[CurrentLine
]))
2535 // If there is anything other than comments or nested namespaces in the
2536 // current namespace, the namespace cannot be empty.
2537 NewLine
= CurrentLine
;
2541 NewLine
= CurrentLine
;
2542 if (CurrentLine
>= End
)
2545 // Check if the empty namespace is actually affected by changed ranges.
2546 if (!AffectedRangeMgr
.affectsCharSourceRange(CharSourceRange::getCharRange(
2547 AnnotatedLines
[InitLine
]->First
->Tok
.getLocation(),
2548 AnnotatedLines
[CurrentLine
]->Last
->Tok
.getEndLoc()))) {
2552 for (unsigned i
= InitLine
; i
<= CurrentLine
; ++i
)
2553 DeletedLines
.insert(i
);
2558 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2559 // of the token in the pair if the left token has \p LK token kind and the
2560 // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2561 // is deleted on match; otherwise, the right token is deleted.
2562 template <typename LeftKind
, typename RightKind
>
2563 void cleanupPair(FormatToken
*Start
, LeftKind LK
, RightKind RK
,
2565 auto NextNotDeleted
= [this](const FormatToken
&Tok
) -> FormatToken
* {
2566 for (auto *Res
= Tok
.Next
; Res
; Res
= Res
->Next
) {
2567 if (!Res
->is(tok::comment
) &&
2568 DeletedTokens
.find(Res
) == DeletedTokens
.end()) {
2574 for (auto *Left
= Start
; Left
;) {
2575 auto *Right
= NextNotDeleted(*Left
);
2578 if (Left
->is(LK
) && Right
->is(RK
)) {
2579 deleteToken(DeleteLeft
? Left
: Right
);
2580 for (auto *Tok
= Left
->Next
; Tok
&& Tok
!= Right
; Tok
= Tok
->Next
)
2582 // If the right token is deleted, we should keep the left token
2583 // unchanged and pair it with the new right token.
2591 template <typename LeftKind
, typename RightKind
>
2592 void cleanupLeft(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2593 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/true);
2596 template <typename LeftKind
, typename RightKind
>
2597 void cleanupRight(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2598 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/false);
2601 // Delete the given token.
2602 inline void deleteToken(FormatToken
*Tok
) {
2604 DeletedTokens
.insert(Tok
);
2607 tooling::Replacements
generateFixes() {
2608 tooling::Replacements Fixes
;
2609 SmallVector
<FormatToken
*> Tokens
;
2610 std::copy(DeletedTokens
.begin(), DeletedTokens
.end(),
2611 std::back_inserter(Tokens
));
2613 // Merge multiple continuous token deletions into one big deletion so that
2614 // the number of replacements can be reduced. This makes computing affected
2615 // ranges more efficient when we run reformat on the changed code.
2617 while (Idx
< Tokens
.size()) {
2618 unsigned St
= Idx
, End
= Idx
;
2619 while ((End
+ 1) < Tokens
.size() && Tokens
[End
]->Next
== Tokens
[End
+ 1])
2621 auto SR
= CharSourceRange::getCharRange(Tokens
[St
]->Tok
.getLocation(),
2622 Tokens
[End
]->Tok
.getEndLoc());
2624 Fixes
.add(tooling::Replacement(Env
.getSourceManager(), SR
, ""));
2625 // FIXME: better error handling. for now just print error message and skip
2626 // for the release version.
2628 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
2629 assert(false && "Fixes must not conflict!");
2637 // Class for less-than inequality comparason for the set `RedundantTokens`.
2638 // We store tokens in the order they appear in the translation unit so that
2639 // we do not need to sort them in `generateFixes()`.
2640 struct FormatTokenLess
{
2641 FormatTokenLess(const SourceManager
&SM
) : SM(SM
) {}
2643 bool operator()(const FormatToken
*LHS
, const FormatToken
*RHS
) const {
2644 return SM
.isBeforeInTranslationUnit(LHS
->Tok
.getLocation(),
2645 RHS
->Tok
.getLocation());
2647 const SourceManager
&SM
;
2650 // Tokens to be deleted.
2651 std::set
<FormatToken
*, FormatTokenLess
> DeletedTokens
;
2654 class ObjCHeaderStyleGuesser
: public TokenAnalyzer
{
2656 ObjCHeaderStyleGuesser(const Environment
&Env
, const FormatStyle
&Style
)
2657 : TokenAnalyzer(Env
, Style
), IsObjC(false) {}
2659 std::pair
<tooling::Replacements
, unsigned>
2660 analyze(TokenAnnotator
&Annotator
,
2661 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2662 FormatTokenLexer
&Tokens
) override
{
2663 assert(Style
.Language
== FormatStyle::LK_Cpp
);
2664 IsObjC
= guessIsObjC(Env
.getSourceManager(), AnnotatedLines
,
2665 Tokens
.getKeywords());
2666 tooling::Replacements Result
;
2670 bool isObjC() { return IsObjC
; }
2674 guessIsObjC(const SourceManager
&SourceManager
,
2675 const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2676 const AdditionalKeywords
&Keywords
) {
2677 // Keep this array sorted, since we are binary searching over it.
2678 static constexpr llvm::StringLiteral FoundationIdentifiers
[] = {
2693 "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
2694 "FOUNDATION_EXTERN",
2695 "NSAffineTransform",
2697 "NSAttributedString",
2716 "NSInvocationOperation",
2720 "NSMutableAttributedString",
2721 "NSMutableCharacterSet",
2723 "NSMutableDictionary",
2724 "NSMutableIndexSet",
2725 "NSMutableOrderedSet",
2729 "NSNumberFormatter",
2733 "NSOperationQueuePriority",
2737 "NSQualityOfService",
2740 "NSRegularExpression",
2751 "NS_ASSUME_NONNULL_BEGIN",
2756 for (auto *Line
: AnnotatedLines
) {
2757 if (Line
->First
&& (Line
->First
->TokenText
.startswith("#") ||
2758 Line
->First
->TokenText
== "__pragma" ||
2759 Line
->First
->TokenText
== "_Pragma")) {
2762 for (const FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2763 FormatTok
= FormatTok
->Next
) {
2764 if ((FormatTok
->Previous
&& FormatTok
->Previous
->is(tok::at
) &&
2765 (FormatTok
->Tok
.getObjCKeywordID() != tok::objc_not_keyword
||
2766 FormatTok
->isOneOf(tok::numeric_constant
, tok::l_square
,
2768 (FormatTok
->Tok
.isAnyIdentifier() &&
2769 std::binary_search(std::begin(FoundationIdentifiers
),
2770 std::end(FoundationIdentifiers
),
2771 FormatTok
->TokenText
)) ||
2772 FormatTok
->is(TT_ObjCStringLiteral
) ||
2773 FormatTok
->isOneOf(Keywords
.kw_NS_CLOSED_ENUM
, Keywords
.kw_NS_ENUM
,
2774 Keywords
.kw_NS_ERROR_ENUM
,
2775 Keywords
.kw_NS_OPTIONS
, TT_ObjCBlockLBrace
,
2776 TT_ObjCBlockLParen
, TT_ObjCDecl
, TT_ObjCForIn
,
2777 TT_ObjCMethodExpr
, TT_ObjCMethodSpecifier
,
2779 LLVM_DEBUG(llvm::dbgs()
2780 << "Detected ObjC at location "
2781 << FormatTok
->Tok
.getLocation().printToString(
2783 << " token: " << FormatTok
->TokenText
<< " token type: "
2784 << getTokenTypeName(FormatTok
->getType()) << "\n");
2787 if (guessIsObjC(SourceManager
, Line
->Children
, Keywords
))
2797 struct IncludeDirective
{
2805 struct JavaImportDirective
{
2806 StringRef Identifier
;
2809 SmallVector
<StringRef
> AssociatedCommentLines
;
2813 } // end anonymous namespace
2815 // Determines whether 'Ranges' intersects with ('Start', 'End').
2816 static bool affectsRange(ArrayRef
<tooling::Range
> Ranges
, unsigned Start
,
2818 for (const auto &Range
: Ranges
) {
2819 if (Range
.getOffset() < End
&&
2820 Range
.getOffset() + Range
.getLength() > Start
) {
2827 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
2828 // before sorting/deduplicating. Index is the index of the include under the
2829 // cursor in the original set of includes. If this include has duplicates, it is
2830 // the index of the first of the duplicates as the others are going to be
2831 // removed. OffsetToEOL describes the cursor's position relative to the end of
2832 // its current line.
2833 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
2834 static std::pair
<unsigned, unsigned>
2835 FindCursorIndex(const SmallVectorImpl
<IncludeDirective
> &Includes
,
2836 const SmallVectorImpl
<unsigned> &Indices
, unsigned Cursor
) {
2837 unsigned CursorIndex
= UINT_MAX
;
2838 unsigned OffsetToEOL
= 0;
2839 for (int i
= 0, e
= Includes
.size(); i
!= e
; ++i
) {
2840 unsigned Start
= Includes
[Indices
[i
]].Offset
;
2841 unsigned End
= Start
+ Includes
[Indices
[i
]].Text
.size();
2842 if (!(Cursor
>= Start
&& Cursor
< End
))
2844 CursorIndex
= Indices
[i
];
2845 OffsetToEOL
= End
- Cursor
;
2846 // Put the cursor on the only remaining #include among the duplicate
2848 while (--i
>= 0 && Includes
[CursorIndex
].Text
== Includes
[Indices
[i
]].Text
)
2852 return std::make_pair(CursorIndex
, OffsetToEOL
);
2855 // Replace all "\r\n" with "\n".
2856 std::string
replaceCRLF(const std::string
&Code
) {
2857 std::string NewCode
;
2858 size_t Pos
= 0, LastPos
= 0;
2861 Pos
= Code
.find("\r\n", LastPos
);
2862 if (Pos
== LastPos
) {
2866 if (Pos
== std::string::npos
) {
2867 NewCode
+= Code
.substr(LastPos
);
2870 NewCode
+= Code
.substr(LastPos
, Pos
- LastPos
) + "\n";
2872 } while (Pos
!= std::string::npos
);
2877 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
2878 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
2880 // #include directives with the same text will be deduplicated, and only the
2881 // first #include in the duplicate #includes remains. If the `Cursor` is
2882 // provided and put on a deleted #include, it will be moved to the remaining
2883 // #include in the duplicate #includes.
2884 static void sortCppIncludes(const FormatStyle
&Style
,
2885 const SmallVectorImpl
<IncludeDirective
> &Includes
,
2886 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
2887 StringRef Code
, tooling::Replacements
&Replaces
,
2889 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
2890 const unsigned IncludesBeginOffset
= Includes
.front().Offset
;
2891 const unsigned IncludesEndOffset
=
2892 Includes
.back().Offset
+ Includes
.back().Text
.size();
2893 const unsigned IncludesBlockSize
= IncludesEndOffset
- IncludesBeginOffset
;
2894 if (!affectsRange(Ranges
, IncludesBeginOffset
, IncludesEndOffset
))
2896 SmallVector
<unsigned, 16> Indices
=
2897 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Includes
.size()));
2899 if (Style
.SortIncludes
== FormatStyle::SI_CaseInsensitive
) {
2900 llvm::stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
2901 const auto LHSFilenameLower
= Includes
[LHSI
].Filename
.lower();
2902 const auto RHSFilenameLower
= Includes
[RHSI
].Filename
.lower();
2903 return std::tie(Includes
[LHSI
].Priority
, LHSFilenameLower
,
2904 Includes
[LHSI
].Filename
) <
2905 std::tie(Includes
[RHSI
].Priority
, RHSFilenameLower
,
2906 Includes
[RHSI
].Filename
);
2909 llvm::stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
2910 return std::tie(Includes
[LHSI
].Priority
, Includes
[LHSI
].Filename
) <
2911 std::tie(Includes
[RHSI
].Priority
, Includes
[RHSI
].Filename
);
2915 // The index of the include on which the cursor will be put after
2916 // sorting/deduplicating.
2917 unsigned CursorIndex
;
2918 // The offset from cursor to the end of line.
2919 unsigned CursorToEOLOffset
;
2921 std::tie(CursorIndex
, CursorToEOLOffset
) =
2922 FindCursorIndex(Includes
, Indices
, *Cursor
);
2925 // Deduplicate #includes.
2926 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
2927 [&](unsigned LHSI
, unsigned RHSI
) {
2928 return Includes
[LHSI
].Text
.trim() ==
2929 Includes
[RHSI
].Text
.trim();
2933 int CurrentCategory
= Includes
.front().Category
;
2935 // If the #includes are out of order, we generate a single replacement fixing
2936 // the entire block. Otherwise, no replacement is generated.
2937 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
2938 // enough as additional newlines might be added or removed across #include
2939 // blocks. This we handle below by generating the updated #include blocks and
2940 // comparing it to the original.
2941 if (Indices
.size() == Includes
.size() && llvm::is_sorted(Indices
) &&
2942 Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Preserve
) {
2947 for (unsigned Index
: Indices
) {
2948 if (!result
.empty()) {
2950 if (Style
.IncludeStyle
.IncludeBlocks
==
2951 tooling::IncludeStyle::IBS_Regroup
&&
2952 CurrentCategory
!= Includes
[Index
].Category
) {
2956 result
+= Includes
[Index
].Text
;
2957 if (Cursor
&& CursorIndex
== Index
)
2958 *Cursor
= IncludesBeginOffset
+ result
.size() - CursorToEOLOffset
;
2959 CurrentCategory
= Includes
[Index
].Category
;
2962 if (Cursor
&& *Cursor
>= IncludesEndOffset
)
2963 *Cursor
+= result
.size() - IncludesBlockSize
;
2965 // If the #includes are out of order, we generate a single replacement fixing
2966 // the entire range of blocks. Otherwise, no replacement is generated.
2967 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
2968 IncludesBeginOffset
, IncludesBlockSize
)))) {
2972 auto Err
= Replaces
.add(tooling::Replacement(
2973 FileName
, Includes
.front().Offset
, IncludesBlockSize
, result
));
2974 // FIXME: better error handling. For now, just skip the replacement for the
2977 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
2982 tooling::Replacements
sortCppIncludes(const FormatStyle
&Style
, StringRef Code
,
2983 ArrayRef
<tooling::Range
> Ranges
,
2985 tooling::Replacements
&Replaces
,
2987 unsigned Prev
= llvm::StringSwitch
<size_t>(Code
)
2988 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
2990 unsigned SearchFrom
= 0;
2991 SmallVector
<StringRef
, 4> Matches
;
2992 SmallVector
<IncludeDirective
, 16> IncludesInBlock
;
2994 // In compiled files, consider the first #include to be the main #include of
2995 // the file if it is not a system #include. This ensures that the header
2996 // doesn't have hidden dependencies
2997 // (http://llvm.org/docs/CodingStandards.html#include-style).
2999 // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3000 // cases where the first #include is unlikely to be the main header.
3001 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
3002 bool FirstIncludeBlock
= true;
3003 bool MainIncludeFound
= false;
3004 bool FormattingOff
= false;
3006 // '[' must be the first and '-' the last character inside [...].
3007 llvm::Regex
RawStringRegex(
3008 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3009 SmallVector
<StringRef
, 2> RawStringMatches
;
3010 std::string RawStringTermination
= ")\"";
3013 auto Pos
= Code
.find('\n', SearchFrom
);
3015 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3017 StringRef Trimmed
= Line
.trim();
3019 // #includes inside raw string literals need to be ignored.
3020 // or we will sort the contents of the string.
3021 // Skip past until we think we are at the rawstring literal close.
3022 if (RawStringRegex
.match(Trimmed
, &RawStringMatches
)) {
3023 std::string CharSequence
= RawStringMatches
[1].str();
3024 RawStringTermination
= ")" + CharSequence
+ "\"";
3025 FormattingOff
= true;
3028 if (Trimmed
.contains(RawStringTermination
))
3029 FormattingOff
= false;
3031 if (isClangFormatOff(Trimmed
))
3032 FormattingOff
= true;
3033 else if (isClangFormatOn(Trimmed
))
3034 FormattingOff
= false;
3036 const bool EmptyLineSkipped
=
3038 (Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Merge
||
3039 Style
.IncludeStyle
.IncludeBlocks
==
3040 tooling::IncludeStyle::IBS_Regroup
);
3042 bool MergeWithNextLine
= Trimmed
.endswith("\\");
3043 if (!FormattingOff
&& !MergeWithNextLine
) {
3044 if (tooling::HeaderIncludes::IncludeRegex
.match(Line
, &Matches
)) {
3045 StringRef IncludeName
= Matches
[2];
3046 if (Line
.contains("/*") && !Line
.contains("*/")) {
3047 // #include with a start of a block comment, but without the end.
3048 // Need to keep all the lines until the end of the comment together.
3049 // FIXME: This is somehow simplified check that probably does not work
3050 // correctly if there are multiple comments on a line.
3051 Pos
= Code
.find("*/", SearchFrom
);
3053 Prev
, (Pos
!= StringRef::npos
? Pos
+ 2 : Code
.size()) - Prev
);
3055 int Category
= Categories
.getIncludePriority(
3057 /*CheckMainHeader=*/!MainIncludeFound
&& FirstIncludeBlock
);
3058 int Priority
= Categories
.getSortIncludePriority(
3059 IncludeName
, !MainIncludeFound
&& FirstIncludeBlock
);
3061 MainIncludeFound
= true;
3062 IncludesInBlock
.push_back(
3063 {IncludeName
, Line
, Prev
, Category
, Priority
});
3064 } else if (!IncludesInBlock
.empty() && !EmptyLineSkipped
) {
3065 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
,
3067 IncludesInBlock
.clear();
3068 if (Trimmed
.startswith("#pragma hdrstop")) // Precompiled headers.
3069 FirstIncludeBlock
= true;
3071 FirstIncludeBlock
= false;
3074 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3077 if (!MergeWithNextLine
)
3079 SearchFrom
= Pos
+ 1;
3081 if (!IncludesInBlock
.empty()) {
3082 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
, Replaces
,
3088 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
3089 // if the import does not match any given groups.
3090 static unsigned findJavaImportGroup(const FormatStyle
&Style
,
3091 StringRef ImportIdentifier
) {
3092 unsigned LongestMatchIndex
= UINT_MAX
;
3093 unsigned LongestMatchLength
= 0;
3094 for (unsigned I
= 0; I
< Style
.JavaImportGroups
.size(); I
++) {
3095 const std::string
&GroupPrefix
= Style
.JavaImportGroups
[I
];
3096 if (ImportIdentifier
.startswith(GroupPrefix
) &&
3097 GroupPrefix
.length() > LongestMatchLength
) {
3098 LongestMatchIndex
= I
;
3099 LongestMatchLength
= GroupPrefix
.length();
3102 return LongestMatchIndex
;
3105 // Sorts and deduplicates a block of includes given by 'Imports' based on
3106 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3107 // Import declarations with the same text will be deduplicated. Between each
3108 // import group, a newline is inserted, and within each import group, a
3109 // lexicographic sort based on ASCII value is performed.
3110 static void sortJavaImports(const FormatStyle
&Style
,
3111 const SmallVectorImpl
<JavaImportDirective
> &Imports
,
3112 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
3113 StringRef Code
, tooling::Replacements
&Replaces
) {
3114 unsigned ImportsBeginOffset
= Imports
.front().Offset
;
3115 unsigned ImportsEndOffset
=
3116 Imports
.back().Offset
+ Imports
.back().Text
.size();
3117 unsigned ImportsBlockSize
= ImportsEndOffset
- ImportsBeginOffset
;
3118 if (!affectsRange(Ranges
, ImportsBeginOffset
, ImportsEndOffset
))
3121 SmallVector
<unsigned, 16> Indices
=
3122 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Imports
.size()));
3123 SmallVector
<unsigned, 16> JavaImportGroups
;
3124 JavaImportGroups
.reserve(Imports
.size());
3125 for (const JavaImportDirective
&Import
: Imports
)
3126 JavaImportGroups
.push_back(findJavaImportGroup(Style
, Import
.Identifier
));
3128 bool StaticImportAfterNormalImport
=
3129 Style
.SortJavaStaticImport
== FormatStyle::SJSIO_After
;
3130 llvm::sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3131 // Negating IsStatic to push static imports above non-static imports.
3132 return std::make_tuple(!Imports
[LHSI
].IsStatic
^
3133 StaticImportAfterNormalImport
,
3134 JavaImportGroups
[LHSI
], Imports
[LHSI
].Identifier
) <
3135 std::make_tuple(!Imports
[RHSI
].IsStatic
^
3136 StaticImportAfterNormalImport
,
3137 JavaImportGroups
[RHSI
], Imports
[RHSI
].Identifier
);
3140 // Deduplicate imports.
3141 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
3142 [&](unsigned LHSI
, unsigned RHSI
) {
3143 return Imports
[LHSI
].Text
== Imports
[RHSI
].Text
;
3147 bool CurrentIsStatic
= Imports
[Indices
.front()].IsStatic
;
3148 unsigned CurrentImportGroup
= JavaImportGroups
[Indices
.front()];
3151 for (unsigned Index
: Indices
) {
3152 if (!result
.empty()) {
3154 if (CurrentIsStatic
!= Imports
[Index
].IsStatic
||
3155 CurrentImportGroup
!= JavaImportGroups
[Index
]) {
3159 for (StringRef CommentLine
: Imports
[Index
].AssociatedCommentLines
) {
3160 result
+= CommentLine
;
3163 result
+= Imports
[Index
].Text
;
3164 CurrentIsStatic
= Imports
[Index
].IsStatic
;
3165 CurrentImportGroup
= JavaImportGroups
[Index
];
3168 // If the imports are out of order, we generate a single replacement fixing
3169 // the entire block. Otherwise, no replacement is generated.
3170 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
3171 Imports
.front().Offset
, ImportsBlockSize
)))) {
3175 auto Err
= Replaces
.add(tooling::Replacement(FileName
, Imports
.front().Offset
,
3176 ImportsBlockSize
, result
));
3177 // FIXME: better error handling. For now, just skip the replacement for the
3180 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
3187 const char JavaImportRegexPattern
[] =
3188 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3190 } // anonymous namespace
3192 tooling::Replacements
sortJavaImports(const FormatStyle
&Style
, StringRef Code
,
3193 ArrayRef
<tooling::Range
> Ranges
,
3195 tooling::Replacements
&Replaces
) {
3197 unsigned SearchFrom
= 0;
3198 llvm::Regex
ImportRegex(JavaImportRegexPattern
);
3199 SmallVector
<StringRef
, 4> Matches
;
3200 SmallVector
<JavaImportDirective
, 16> ImportsInBlock
;
3201 SmallVector
<StringRef
> AssociatedCommentLines
;
3203 bool FormattingOff
= false;
3206 auto Pos
= Code
.find('\n', SearchFrom
);
3208 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3210 StringRef Trimmed
= Line
.trim();
3211 if (isClangFormatOff(Trimmed
))
3212 FormattingOff
= true;
3213 else if (isClangFormatOn(Trimmed
))
3214 FormattingOff
= false;
3216 if (ImportRegex
.match(Line
, &Matches
)) {
3217 if (FormattingOff
) {
3218 // If at least one import line has formatting turned off, turn off
3219 // formatting entirely.
3222 StringRef Static
= Matches
[1];
3223 StringRef Identifier
= Matches
[2];
3224 bool IsStatic
= false;
3225 if (Static
.contains("static"))
3227 ImportsInBlock
.push_back(
3228 {Identifier
, Line
, Prev
, AssociatedCommentLines
, IsStatic
});
3229 AssociatedCommentLines
.clear();
3230 } else if (Trimmed
.size() > 0 && !ImportsInBlock
.empty()) {
3231 // Associating comments within the imports with the nearest import below
3232 AssociatedCommentLines
.push_back(Line
);
3235 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3237 SearchFrom
= Pos
+ 1;
3239 if (!ImportsInBlock
.empty())
3240 sortJavaImports(Style
, ImportsInBlock
, Ranges
, FileName
, Code
, Replaces
);
3244 bool isMpegTS(StringRef Code
) {
3245 // MPEG transport streams use the ".ts" file extension. clang-format should
3246 // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3247 // 189 bytes - detect that and return.
3248 return Code
.size() > 188 && Code
[0] == 0x47 && Code
[188] == 0x47;
3251 bool isLikelyXml(StringRef Code
) { return Code
.ltrim().startswith("<"); }
3253 tooling::Replacements
sortIncludes(const FormatStyle
&Style
, StringRef Code
,
3254 ArrayRef
<tooling::Range
> Ranges
,
3255 StringRef FileName
, unsigned *Cursor
) {
3256 tooling::Replacements Replaces
;
3257 if (!Style
.SortIncludes
|| Style
.DisableFormat
)
3259 if (isLikelyXml(Code
))
3261 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
&&
3265 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
)
3266 return sortJavaScriptImports(Style
, Code
, Ranges
, FileName
);
3267 if (Style
.Language
== FormatStyle::LanguageKind::LK_Java
)
3268 return sortJavaImports(Style
, Code
, Ranges
, FileName
, Replaces
);
3269 sortCppIncludes(Style
, Code
, Ranges
, FileName
, Replaces
, Cursor
);
3273 template <typename T
>
3274 static llvm::Expected
<tooling::Replacements
>
3275 processReplacements(T ProcessFunc
, StringRef Code
,
3276 const tooling::Replacements
&Replaces
,
3277 const FormatStyle
&Style
) {
3278 if (Replaces
.empty())
3279 return tooling::Replacements();
3281 auto NewCode
= applyAllReplacements(Code
, Replaces
);
3283 return NewCode
.takeError();
3284 std::vector
<tooling::Range
> ChangedRanges
= Replaces
.getAffectedRanges();
3285 StringRef FileName
= Replaces
.begin()->getFilePath();
3287 tooling::Replacements FormatReplaces
=
3288 ProcessFunc(Style
, *NewCode
, ChangedRanges
, FileName
);
3290 return Replaces
.merge(FormatReplaces
);
3293 llvm::Expected
<tooling::Replacements
>
3294 formatReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3295 const FormatStyle
&Style
) {
3296 // We need to use lambda function here since there are two versions of
3298 auto SortIncludes
= [](const FormatStyle
&Style
, StringRef Code
,
3299 std::vector
<tooling::Range
> Ranges
,
3300 StringRef FileName
) -> tooling::Replacements
{
3301 return sortIncludes(Style
, Code
, Ranges
, FileName
);
3303 auto SortedReplaces
=
3304 processReplacements(SortIncludes
, Code
, Replaces
, Style
);
3305 if (!SortedReplaces
)
3306 return SortedReplaces
.takeError();
3308 // We need to use lambda function here since there are two versions of
3310 auto Reformat
= [](const FormatStyle
&Style
, StringRef Code
,
3311 std::vector
<tooling::Range
> Ranges
,
3312 StringRef FileName
) -> tooling::Replacements
{
3313 return reformat(Style
, Code
, Ranges
, FileName
);
3315 return processReplacements(Reformat
, Code
, *SortedReplaces
, Style
);
3320 inline bool isHeaderInsertion(const tooling::Replacement
&Replace
) {
3321 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 0 &&
3322 tooling::HeaderIncludes::IncludeRegex
.match(
3323 Replace
.getReplacementText());
3326 inline bool isHeaderDeletion(const tooling::Replacement
&Replace
) {
3327 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 1;
3330 // FIXME: insert empty lines between newly created blocks.
3331 tooling::Replacements
3332 fixCppIncludeInsertions(StringRef Code
, const tooling::Replacements
&Replaces
,
3333 const FormatStyle
&Style
) {
3337 tooling::Replacements HeaderInsertions
;
3338 std::set
<llvm::StringRef
> HeadersToDelete
;
3339 tooling::Replacements Result
;
3340 for (const auto &R
: Replaces
) {
3341 if (isHeaderInsertion(R
)) {
3342 // Replacements from \p Replaces must be conflict-free already, so we can
3343 // simply consume the error.
3344 llvm::consumeError(HeaderInsertions
.add(R
));
3345 } else if (isHeaderDeletion(R
)) {
3346 HeadersToDelete
.insert(R
.getReplacementText());
3347 } else if (R
.getOffset() == UINT_MAX
) {
3348 llvm::errs() << "Insertions other than header #include insertion are "
3350 << R
.getReplacementText() << "\n";
3352 llvm::consumeError(Result
.add(R
));
3355 if (HeaderInsertions
.empty() && HeadersToDelete
.empty())
3358 StringRef FileName
= Replaces
.begin()->getFilePath();
3359 tooling::HeaderIncludes
Includes(FileName
, Code
, Style
.IncludeStyle
);
3361 for (const auto &Header
: HeadersToDelete
) {
3362 tooling::Replacements Replaces
=
3363 Includes
.remove(Header
.trim("\"<>"), Header
.startswith("<"));
3364 for (const auto &R
: Replaces
) {
3365 auto Err
= Result
.add(R
);
3367 // Ignore the deletion on conflict.
3368 llvm::errs() << "Failed to add header deletion replacement for "
3369 << Header
<< ": " << llvm::toString(std::move(Err
))
3375 llvm::SmallVector
<StringRef
, 4> Matches
;
3376 for (const auto &R
: HeaderInsertions
) {
3377 auto IncludeDirective
= R
.getReplacementText();
3379 tooling::HeaderIncludes::IncludeRegex
.match(IncludeDirective
, &Matches
);
3380 assert(Matched
&& "Header insertion replacement must have replacement text "
3383 auto IncludeName
= Matches
[2];
3385 Includes
.insert(IncludeName
.trim("\"<>"), IncludeName
.startswith("<"),
3386 tooling::IncludeDirective::Include
);
3388 auto Err
= Result
.add(*Replace
);
3390 llvm::consumeError(std::move(Err
));
3391 unsigned NewOffset
=
3392 Result
.getShiftedCodePosition(Replace
->getOffset());
3393 auto Shifted
= tooling::Replacement(FileName
, NewOffset
, 0,
3394 Replace
->getReplacementText());
3395 Result
= Result
.merge(tooling::Replacements(Shifted
));
3402 } // anonymous namespace
3404 llvm::Expected
<tooling::Replacements
>
3405 cleanupAroundReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3406 const FormatStyle
&Style
) {
3407 // We need to use lambda function here since there are two versions of
3409 auto Cleanup
= [](const FormatStyle
&Style
, StringRef Code
,
3410 std::vector
<tooling::Range
> Ranges
,
3411 StringRef FileName
) -> tooling::Replacements
{
3412 return cleanup(Style
, Code
, Ranges
, FileName
);
3414 // Make header insertion replacements insert new headers into correct blocks.
3415 tooling::Replacements NewReplaces
=
3416 fixCppIncludeInsertions(Code
, Replaces
, Style
);
3417 return cantFail(processReplacements(Cleanup
, Code
, NewReplaces
, Style
));
3420 namespace internal
{
3421 std::pair
<tooling::Replacements
, unsigned>
3422 reformat(const FormatStyle
&Style
, StringRef Code
,
3423 ArrayRef
<tooling::Range
> Ranges
, unsigned FirstStartColumn
,
3424 unsigned NextStartColumn
, unsigned LastStartColumn
, StringRef FileName
,
3425 FormattingAttemptStatus
*Status
) {
3426 FormatStyle Expanded
= Style
;
3427 expandPresetsBraceWrapping(Expanded
);
3428 expandPresetsSpaceBeforeParens(Expanded
);
3429 Expanded
.InsertBraces
= false;
3430 Expanded
.RemoveBracesLLVM
= false;
3431 Expanded
.RemoveSemicolon
= false;
3432 switch (Expanded
.RequiresClausePosition
) {
3433 case FormatStyle::RCPS_SingleLine
:
3434 case FormatStyle::RCPS_WithPreceding
:
3435 Expanded
.IndentRequiresClause
= false;
3441 if (Expanded
.DisableFormat
)
3442 return {tooling::Replacements(), 0};
3443 if (isLikelyXml(Code
))
3444 return {tooling::Replacements(), 0};
3445 if (Expanded
.Language
== FormatStyle::LK_JavaScript
&& isMpegTS(Code
))
3446 return {tooling::Replacements(), 0};
3448 // JSON only needs the formatting passing.
3449 if (Style
.isJson()) {
3450 std::vector
<tooling::Range
> Ranges(1, tooling::Range(0, Code
.size()));
3451 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3452 NextStartColumn
, LastStartColumn
);
3455 // Perform the actual formatting pass.
3456 tooling::Replacements Replaces
=
3457 Formatter(*Env
, Style
, Status
).process().first
;
3458 // add a replacement to remove the "x = " from the result.
3459 Replaces
= Replaces
.merge(
3460 tooling::Replacements(tooling::Replacement(FileName
, 0, 4, "")));
3461 // apply the reformatting changes and the removal of "x = ".
3462 if (applyAllReplacements(Code
, Replaces
))
3463 return {Replaces
, 0};
3464 return {tooling::Replacements(), 0};
3467 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3468 NextStartColumn
, LastStartColumn
);
3472 typedef std::function
<std::pair
<tooling::Replacements
, unsigned>(
3473 const Environment
&)>
3475 SmallVector
<AnalyzerPass
, 8> Passes
;
3477 Passes
.emplace_back([&](const Environment
&Env
) {
3478 return IntegerLiteralSeparatorFixer().process(Env
, Expanded
);
3481 if (Style
.isCpp()) {
3482 if (Style
.QualifierAlignment
!= FormatStyle::QAS_Leave
) {
3483 Passes
.emplace_back([&](const Environment
&Env
) {
3484 return QualifierAlignmentFixer(Env
, Expanded
, Code
, Ranges
,
3485 FirstStartColumn
, NextStartColumn
,
3486 LastStartColumn
, FileName
)
3491 if (Style
.InsertBraces
) {
3492 FormatStyle S
= Expanded
;
3493 S
.InsertBraces
= true;
3494 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3495 return BracesInserter(Env
, S
).process(/*SkipAnnotation=*/true);
3499 if (Style
.RemoveBracesLLVM
) {
3500 FormatStyle S
= Expanded
;
3501 S
.RemoveBracesLLVM
= true;
3502 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3503 return BracesRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3507 if (Style
.RemoveSemicolon
) {
3508 FormatStyle S
= Expanded
;
3509 S
.RemoveSemicolon
= true;
3510 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3511 return SemiRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3515 if (Style
.FixNamespaceComments
) {
3516 Passes
.emplace_back([&](const Environment
&Env
) {
3517 return NamespaceEndCommentsFixer(Env
, Expanded
).process();
3521 if (Style
.SortUsingDeclarations
!= FormatStyle::SUD_Never
) {
3522 Passes
.emplace_back([&](const Environment
&Env
) {
3523 return UsingDeclarationsSorter(Env
, Expanded
).process();
3528 if (Style
.SeparateDefinitionBlocks
!= FormatStyle::SDS_Leave
) {
3529 Passes
.emplace_back([&](const Environment
&Env
) {
3530 return DefinitionBlockSeparator(Env
, Expanded
).process();
3534 if (Style
.isJavaScript() &&
3535 Style
.JavaScriptQuotes
!= FormatStyle::JSQS_Leave
) {
3536 Passes
.emplace_back([&](const Environment
&Env
) {
3537 return JavaScriptRequoter(Env
, Expanded
).process(/*SkipAnnotation=*/true);
3541 Passes
.emplace_back([&](const Environment
&Env
) {
3542 return Formatter(Env
, Expanded
, Status
).process();
3545 if (Style
.isJavaScript() &&
3546 Style
.InsertTrailingCommas
== FormatStyle::TCS_Wrapped
) {
3547 Passes
.emplace_back([&](const Environment
&Env
) {
3548 return TrailingCommaInserter(Env
, Expanded
).process();
3552 std::optional
<std::string
> CurrentCode
;
3553 tooling::Replacements Fixes
;
3554 unsigned Penalty
= 0;
3555 for (size_t I
= 0, E
= Passes
.size(); I
< E
; ++I
) {
3556 std::pair
<tooling::Replacements
, unsigned> PassFixes
= Passes
[I
](*Env
);
3557 auto NewCode
= applyAllReplacements(
3558 CurrentCode
? StringRef(*CurrentCode
) : Code
, PassFixes
.first
);
3560 Fixes
= Fixes
.merge(PassFixes
.first
);
3561 Penalty
+= PassFixes
.second
;
3563 CurrentCode
= std::move(*NewCode
);
3564 Env
= Environment::make(
3565 *CurrentCode
, FileName
,
3566 tooling::calculateRangesAfterReplacements(Fixes
, Ranges
),
3567 FirstStartColumn
, NextStartColumn
, LastStartColumn
);
3574 return {Fixes
, Penalty
};
3576 } // namespace internal
3578 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3579 ArrayRef
<tooling::Range
> Ranges
,
3581 FormattingAttemptStatus
*Status
) {
3582 return internal::reformat(Style
, Code
, Ranges
,
3583 /*FirstStartColumn=*/0,
3584 /*NextStartColumn=*/0,
3585 /*LastStartColumn=*/0, FileName
, Status
)
3589 tooling::Replacements
cleanup(const FormatStyle
&Style
, StringRef Code
,
3590 ArrayRef
<tooling::Range
> Ranges
,
3591 StringRef FileName
) {
3592 // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3593 if (Style
.Language
!= FormatStyle::LK_Cpp
)
3594 return tooling::Replacements();
3595 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3598 return Cleaner(*Env
, Style
).process().first
;
3601 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3602 ArrayRef
<tooling::Range
> Ranges
,
3603 StringRef FileName
, bool *IncompleteFormat
) {
3604 FormattingAttemptStatus Status
;
3605 auto Result
= reformat(Style
, Code
, Ranges
, FileName
, &Status
);
3606 if (!Status
.FormatComplete
)
3607 *IncompleteFormat
= true;
3611 tooling::Replacements
fixNamespaceEndComments(const FormatStyle
&Style
,
3613 ArrayRef
<tooling::Range
> Ranges
,
3614 StringRef FileName
) {
3615 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3618 return NamespaceEndCommentsFixer(*Env
, Style
).process().first
;
3621 tooling::Replacements
separateDefinitionBlocks(const FormatStyle
&Style
,
3623 ArrayRef
<tooling::Range
> Ranges
,
3624 StringRef FileName
) {
3625 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3628 return DefinitionBlockSeparator(*Env
, Style
).process().first
;
3631 tooling::Replacements
sortUsingDeclarations(const FormatStyle
&Style
,
3633 ArrayRef
<tooling::Range
> Ranges
,
3634 StringRef FileName
) {
3635 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3638 return UsingDeclarationsSorter(*Env
, Style
).process().first
;
3641 LangOptions
getFormattingLangOpts(const FormatStyle
&Style
) {
3642 LangOptions LangOpts
;
3644 FormatStyle::LanguageStandard LexingStd
= Style
.Standard
;
3645 if (LexingStd
== FormatStyle::LS_Auto
)
3646 LexingStd
= FormatStyle::LS_Latest
;
3647 if (LexingStd
== FormatStyle::LS_Latest
)
3648 LexingStd
= FormatStyle::LS_Cpp20
;
3649 LangOpts
.CPlusPlus
= 1;
3650 LangOpts
.CPlusPlus11
= LexingStd
>= FormatStyle::LS_Cpp11
;
3651 LangOpts
.CPlusPlus14
= LexingStd
>= FormatStyle::LS_Cpp14
;
3652 LangOpts
.CPlusPlus17
= LexingStd
>= FormatStyle::LS_Cpp17
;
3653 LangOpts
.CPlusPlus20
= LexingStd
>= FormatStyle::LS_Cpp20
;
3654 LangOpts
.Char8
= LexingStd
>= FormatStyle::LS_Cpp20
;
3655 // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3656 // the sequence "<::" will be unconditionally treated as "[:".
3657 // Cf. Lexer::LexTokenInternal.
3658 LangOpts
.Digraphs
= LexingStd
>= FormatStyle::LS_Cpp11
;
3660 LangOpts
.LineComment
= 1;
3661 bool AlternativeOperators
= Style
.isCpp();
3662 LangOpts
.CXXOperatorNames
= AlternativeOperators
? 1 : 0;
3665 LangOpts
.MicrosoftExt
= 1; // To get kw___try, kw___finally.
3666 LangOpts
.DeclSpecKeyword
= 1; // To get __declspec.
3667 LangOpts
.C99
= 1; // To get kw_restrict for non-underscore-prefixed restrict.
3671 const char *StyleOptionHelpDescription
=
3672 "Set coding style. <string> can be:\n"
3673 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3674 " Mozilla, WebKit.\n"
3675 "2. 'file' to load style configuration from a\n"
3676 " .clang-format file in one of the parent directories\n"
3677 " of the source file (for stdin, see --assume-filename).\n"
3678 " If no .clang-format file is found, falls back to\n"
3679 " --fallback-style.\n"
3680 " --style=file is the default.\n"
3681 "3. 'file:<format_file_path>' to explicitly specify\n"
3682 " the configuration file.\n"
3683 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3684 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3686 static FormatStyle::LanguageKind
getLanguageByFileName(StringRef FileName
) {
3687 if (FileName
.endswith(".java"))
3688 return FormatStyle::LK_Java
;
3689 if (FileName
.ends_with_insensitive(".js") ||
3690 FileName
.ends_with_insensitive(".mjs") ||
3691 FileName
.ends_with_insensitive(".ts")) {
3692 return FormatStyle::LK_JavaScript
; // (module) JavaScript or TypeScript.
3694 if (FileName
.endswith(".m") || FileName
.endswith(".mm"))
3695 return FormatStyle::LK_ObjC
;
3696 if (FileName
.ends_with_insensitive(".proto") ||
3697 FileName
.ends_with_insensitive(".protodevel")) {
3698 return FormatStyle::LK_Proto
;
3700 if (FileName
.ends_with_insensitive(".textpb") ||
3701 FileName
.ends_with_insensitive(".pb.txt") ||
3702 FileName
.ends_with_insensitive(".textproto") ||
3703 FileName
.ends_with_insensitive(".asciipb")) {
3704 return FormatStyle::LK_TextProto
;
3706 if (FileName
.ends_with_insensitive(".td"))
3707 return FormatStyle::LK_TableGen
;
3708 if (FileName
.ends_with_insensitive(".cs"))
3709 return FormatStyle::LK_CSharp
;
3710 if (FileName
.ends_with_insensitive(".json"))
3711 return FormatStyle::LK_Json
;
3712 if (FileName
.ends_with_insensitive(".sv") ||
3713 FileName
.ends_with_insensitive(".svh") ||
3714 FileName
.ends_with_insensitive(".v") ||
3715 FileName
.ends_with_insensitive(".vh")) {
3716 return FormatStyle::LK_Verilog
;
3718 return FormatStyle::LK_Cpp
;
3721 FormatStyle::LanguageKind
guessLanguage(StringRef FileName
, StringRef Code
) {
3722 const auto GuessedLanguage
= getLanguageByFileName(FileName
);
3723 if (GuessedLanguage
== FormatStyle::LK_Cpp
) {
3724 auto Extension
= llvm::sys::path::extension(FileName
);
3725 // If there's no file extension (or it's .h), we need to check the contents
3726 // of the code to see if it contains Objective-C.
3727 if (Extension
.empty() || Extension
== ".h") {
3728 auto NonEmptyFileName
= FileName
.empty() ? "guess.h" : FileName
;
3729 Environment
Env(Code
, NonEmptyFileName
, /*Ranges=*/{});
3730 ObjCHeaderStyleGuesser
Guesser(Env
, getLLVMStyle());
3732 if (Guesser
.isObjC())
3733 return FormatStyle::LK_ObjC
;
3736 return GuessedLanguage
;
3739 // Update StyleOptionHelpDescription above when changing this.
3740 const char *DefaultFormatStyle
= "file";
3742 const char *DefaultFallbackStyle
= "LLVM";
3744 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>
3745 loadAndParseConfigFile(StringRef ConfigFile
, llvm::vfs::FileSystem
*FS
,
3746 FormatStyle
*Style
, bool AllowUnknownOptions
) {
3747 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
3748 FS
->getBufferForFile(ConfigFile
.str());
3749 if (auto EC
= Text
.getError())
3751 if (auto EC
= parseConfiguration(*Text
.get(), Style
, AllowUnknownOptions
))
3756 llvm::Expected
<FormatStyle
> getStyle(StringRef StyleName
, StringRef FileName
,
3757 StringRef FallbackStyleName
,
3758 StringRef Code
, llvm::vfs::FileSystem
*FS
,
3759 bool AllowUnknownOptions
) {
3761 FS
= llvm::vfs::getRealFileSystem().get();
3762 FormatStyle Style
= getLLVMStyle(guessLanguage(FileName
, Code
));
3764 FormatStyle FallbackStyle
= getNoStyle();
3765 if (!getPredefinedStyle(FallbackStyleName
, Style
.Language
, &FallbackStyle
))
3766 return make_string_error("Invalid fallback style \"" + FallbackStyleName
);
3768 llvm::SmallVector
<std::unique_ptr
<llvm::MemoryBuffer
>, 1>
3769 ChildFormatTextToApply
;
3771 if (StyleName
.startswith("{")) {
3772 // Parse YAML/JSON style from the command line.
3773 StringRef Source
= "<command-line>";
3774 if (std::error_code ec
=
3775 parseConfiguration(llvm::MemoryBufferRef(StyleName
, Source
), &Style
,
3776 AllowUnknownOptions
)) {
3777 return make_string_error("Error parsing -style: " + ec
.message());
3779 if (Style
.InheritsParentConfig
) {
3780 ChildFormatTextToApply
.emplace_back(
3781 llvm::MemoryBuffer::getMemBuffer(StyleName
, Source
, false));
3787 // User provided clang-format file using -style=file:path/to/format/file.
3788 if (!Style
.InheritsParentConfig
&&
3789 StyleName
.starts_with_insensitive("file:")) {
3790 auto ConfigFile
= StyleName
.substr(5);
3791 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
3792 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
);
3793 if (auto EC
= Text
.getError()) {
3794 return make_string_error("Error reading " + ConfigFile
+ ": " +
3798 LLVM_DEBUG(llvm::dbgs()
3799 << "Using configuration file " << ConfigFile
<< "\n");
3801 if (!Style
.InheritsParentConfig
)
3804 // Search for parent configs starting from the parent directory of
3806 FileName
= ConfigFile
;
3807 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
3810 // If the style inherits the parent configuration it is a command line
3811 // configuration, which wants to inherit, so we have to skip the check of the
3813 if (!Style
.InheritsParentConfig
&& !StyleName
.equals_insensitive("file")) {
3814 if (!getPredefinedStyle(StyleName
, Style
.Language
, &Style
))
3815 return make_string_error("Invalid value for -style");
3816 if (!Style
.InheritsParentConfig
)
3820 // Reset possible inheritance
3821 Style
.InheritsParentConfig
= false;
3823 // Look for .clang-format/_clang-format file in the file's parent directories.
3824 SmallString
<128> UnsuitableConfigFiles
;
3825 SmallString
<128> Path(FileName
);
3826 if (std::error_code EC
= FS
->makeAbsolute(Path
))
3827 return make_string_error(EC
.message());
3829 llvm::SmallVector
<std::string
, 2> FilesToLookFor
;
3830 FilesToLookFor
.push_back(".clang-format");
3831 FilesToLookFor
.push_back("_clang-format");
3833 auto dropDiagnosticHandler
= [](const llvm::SMDiagnostic
&, void *) {};
3835 auto applyChildFormatTexts
= [&](FormatStyle
*Style
) {
3836 for (const auto &MemBuf
: llvm::reverse(ChildFormatTextToApply
)) {
3837 auto EC
= parseConfiguration(*MemBuf
, Style
, AllowUnknownOptions
,
3838 dropDiagnosticHandler
);
3839 // It was already correctly parsed.
3841 static_cast<void>(EC
);
3845 for (StringRef Directory
= Path
; !Directory
.empty();
3846 Directory
= llvm::sys::path::parent_path(Directory
)) {
3848 auto Status
= FS
->status(Directory
);
3850 Status
->getType() != llvm::sys::fs::file_type::directory_file
) {
3854 for (const auto &F
: FilesToLookFor
) {
3855 SmallString
<128> ConfigFile(Directory
);
3857 llvm::sys::path::append(ConfigFile
, F
);
3858 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile
<< "...\n");
3860 Status
= FS
->status(ConfigFile
.str());
3863 (Status
->getType() == llvm::sys::fs::file_type::regular_file
)) {
3864 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
3865 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
);
3866 if (auto EC
= Text
.getError()) {
3867 if (EC
== ParseError::Unsuitable
) {
3868 if (!UnsuitableConfigFiles
.empty())
3869 UnsuitableConfigFiles
.append(", ");
3870 UnsuitableConfigFiles
.append(ConfigFile
);
3873 return make_string_error("Error reading " + ConfigFile
+ ": " +
3876 LLVM_DEBUG(llvm::dbgs()
3877 << "Using configuration file " << ConfigFile
<< "\n");
3879 if (!Style
.InheritsParentConfig
) {
3880 if (ChildFormatTextToApply
.empty())
3883 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
3884 applyChildFormatTexts(&Style
);
3889 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
3891 // Reset inheritance of style
3892 Style
.InheritsParentConfig
= false;
3894 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
3896 // Breaking out of the inner loop, since we don't want to parse
3897 // .clang-format AND _clang-format, if both exist. Then we continue the
3898 // inner loop (parent directories) in search for the parent
3904 if (!UnsuitableConfigFiles
.empty()) {
3905 return make_string_error("Configuration file(s) do(es) not support " +
3906 getLanguageName(Style
.Language
) + ": " +
3907 UnsuitableConfigFiles
);
3910 if (!ChildFormatTextToApply
.empty()) {
3911 LLVM_DEBUG(llvm::dbgs()
3912 << "Applying child configurations on fallback style\n");
3913 applyChildFormatTexts(&FallbackStyle
);
3916 return FallbackStyle
;
3919 static bool isClangFormatOnOff(StringRef Comment
, bool On
) {
3920 if (Comment
== (On
? "/* clang-format on */" : "/* clang-format off */"))
3923 static const char ClangFormatOn
[] = "// clang-format on";
3924 static const char ClangFormatOff
[] = "// clang-format off";
3925 const unsigned Size
= (On
? sizeof ClangFormatOn
: sizeof ClangFormatOff
) - 1;
3927 return Comment
.startswith(On
? ClangFormatOn
: ClangFormatOff
) &&
3928 (Comment
.size() == Size
|| Comment
[Size
] == ':');
3931 bool isClangFormatOn(StringRef Comment
) {
3932 return isClangFormatOnOff(Comment
, /*On=*/true);
3935 bool isClangFormatOff(StringRef Comment
) {
3936 return isClangFormatOnOff(Comment
, /*On=*/false);
3939 } // namespace format
3940 } // namespace clang