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
)
63 struct ScalarEnumerationTraits
<FormatStyle::BreakBeforeNoexceptSpecifierStyle
> {
65 enumeration(IO
&IO
, FormatStyle::BreakBeforeNoexceptSpecifierStyle
&Value
) {
66 IO
.enumCase(Value
, "Never", FormatStyle::BBNSS_Never
);
67 IO
.enumCase(Value
, "OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen
);
68 IO
.enumCase(Value
, "Always", FormatStyle::BBNSS_Always
);
72 template <> struct MappingTraits
<FormatStyle::AlignConsecutiveStyle
> {
73 static void enumInput(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
74 IO
.enumCase(Value
, "None",
75 FormatStyle::AlignConsecutiveStyle(
76 {/*Enabled=*/false, /*AcrossEmptyLines=*/false,
77 /*AcrossComments=*/false, /*AlignCompound=*/false,
78 /*PadOperators=*/true}));
79 IO
.enumCase(Value
, "Consecutive",
80 FormatStyle::AlignConsecutiveStyle(
81 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
82 /*AcrossComments=*/false, /*AlignCompound=*/false,
83 /*PadOperators=*/true}));
84 IO
.enumCase(Value
, "AcrossEmptyLines",
85 FormatStyle::AlignConsecutiveStyle(
86 {/*Enabled=*/true, /*AcrossEmptyLines=*/true,
87 /*AcrossComments=*/false, /*AlignCompound=*/false,
88 /*PadOperators=*/true}));
89 IO
.enumCase(Value
, "AcrossComments",
90 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true,
91 /*AcrossEmptyLines=*/false,
92 /*AcrossComments=*/true,
93 /*AlignCompound=*/false,
94 /*PadOperators=*/true}));
95 IO
.enumCase(Value
, "AcrossEmptyLinesAndComments",
96 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true,
97 /*AcrossEmptyLines=*/true,
98 /*AcrossComments=*/true,
99 /*AlignCompound=*/false,
100 /*PadOperators=*/true}));
102 // For backward compatibility.
103 IO
.enumCase(Value
, "true",
104 FormatStyle::AlignConsecutiveStyle(
105 {/*Enabled=*/true, /*AcrossEmptyLines=*/false,
106 /*AcrossComments=*/false, /*AlignCompound=*/false,
107 /*PadOperators=*/true}));
108 IO
.enumCase(Value
, "false",
109 FormatStyle::AlignConsecutiveStyle(
110 {/*Enabled=*/false, /*AcrossEmptyLines=*/false,
111 /*AcrossComments=*/false, /*AlignCompound=*/false,
112 /*PadOperators=*/true}));
115 static void mapping(IO
&IO
, FormatStyle::AlignConsecutiveStyle
&Value
) {
116 IO
.mapOptional("Enabled", Value
.Enabled
);
117 IO
.mapOptional("AcrossEmptyLines", Value
.AcrossEmptyLines
);
118 IO
.mapOptional("AcrossComments", Value
.AcrossComments
);
119 IO
.mapOptional("AlignCompound", Value
.AlignCompound
);
120 IO
.mapOptional("PadOperators", Value
.PadOperators
);
125 struct MappingTraits
<FormatStyle::ShortCaseStatementsAlignmentStyle
> {
126 static void mapping(IO
&IO
,
127 FormatStyle::ShortCaseStatementsAlignmentStyle
&Value
) {
128 IO
.mapOptional("Enabled", Value
.Enabled
);
129 IO
.mapOptional("AcrossEmptyLines", Value
.AcrossEmptyLines
);
130 IO
.mapOptional("AcrossComments", Value
.AcrossComments
);
131 IO
.mapOptional("AlignCaseColons", Value
.AlignCaseColons
);
136 struct ScalarEnumerationTraits
<FormatStyle::AttributeBreakingStyle
> {
137 static void enumeration(IO
&IO
, FormatStyle::AttributeBreakingStyle
&Value
) {
138 IO
.enumCase(Value
, "Always", FormatStyle::ABS_Always
);
139 IO
.enumCase(Value
, "Leave", FormatStyle::ABS_Leave
);
140 IO
.enumCase(Value
, "Never", FormatStyle::ABS_Never
);
145 struct ScalarEnumerationTraits
<FormatStyle::ArrayInitializerAlignmentStyle
> {
146 static void enumeration(IO
&IO
,
147 FormatStyle::ArrayInitializerAlignmentStyle
&Value
) {
148 IO
.enumCase(Value
, "None", FormatStyle::AIAS_None
);
149 IO
.enumCase(Value
, "Left", FormatStyle::AIAS_Left
);
150 IO
.enumCase(Value
, "Right", FormatStyle::AIAS_Right
);
154 template <> struct ScalarEnumerationTraits
<FormatStyle::BinaryOperatorStyle
> {
155 static void enumeration(IO
&IO
, FormatStyle::BinaryOperatorStyle
&Value
) {
156 IO
.enumCase(Value
, "All", FormatStyle::BOS_All
);
157 IO
.enumCase(Value
, "true", FormatStyle::BOS_All
);
158 IO
.enumCase(Value
, "None", FormatStyle::BOS_None
);
159 IO
.enumCase(Value
, "false", FormatStyle::BOS_None
);
160 IO
.enumCase(Value
, "NonAssignment", FormatStyle::BOS_NonAssignment
);
164 template <> struct ScalarEnumerationTraits
<FormatStyle::BinPackStyle
> {
165 static void enumeration(IO
&IO
, FormatStyle::BinPackStyle
&Value
) {
166 IO
.enumCase(Value
, "Auto", FormatStyle::BPS_Auto
);
167 IO
.enumCase(Value
, "Always", FormatStyle::BPS_Always
);
168 IO
.enumCase(Value
, "Never", FormatStyle::BPS_Never
);
173 struct ScalarEnumerationTraits
<FormatStyle::BitFieldColonSpacingStyle
> {
174 static void enumeration(IO
&IO
,
175 FormatStyle::BitFieldColonSpacingStyle
&Value
) {
176 IO
.enumCase(Value
, "Both", FormatStyle::BFCS_Both
);
177 IO
.enumCase(Value
, "None", FormatStyle::BFCS_None
);
178 IO
.enumCase(Value
, "Before", FormatStyle::BFCS_Before
);
179 IO
.enumCase(Value
, "After", FormatStyle::BFCS_After
);
183 template <> struct ScalarEnumerationTraits
<FormatStyle::BraceBreakingStyle
> {
184 static void enumeration(IO
&IO
, FormatStyle::BraceBreakingStyle
&Value
) {
185 IO
.enumCase(Value
, "Attach", FormatStyle::BS_Attach
);
186 IO
.enumCase(Value
, "Linux", FormatStyle::BS_Linux
);
187 IO
.enumCase(Value
, "Mozilla", FormatStyle::BS_Mozilla
);
188 IO
.enumCase(Value
, "Stroustrup", FormatStyle::BS_Stroustrup
);
189 IO
.enumCase(Value
, "Allman", FormatStyle::BS_Allman
);
190 IO
.enumCase(Value
, "Whitesmiths", FormatStyle::BS_Whitesmiths
);
191 IO
.enumCase(Value
, "GNU", FormatStyle::BS_GNU
);
192 IO
.enumCase(Value
, "WebKit", FormatStyle::BS_WebKit
);
193 IO
.enumCase(Value
, "Custom", FormatStyle::BS_Custom
);
197 template <> struct MappingTraits
<FormatStyle::BraceWrappingFlags
> {
198 static void mapping(IO
&IO
, FormatStyle::BraceWrappingFlags
&Wrapping
) {
199 IO
.mapOptional("AfterCaseLabel", Wrapping
.AfterCaseLabel
);
200 IO
.mapOptional("AfterClass", Wrapping
.AfterClass
);
201 IO
.mapOptional("AfterControlStatement", Wrapping
.AfterControlStatement
);
202 IO
.mapOptional("AfterEnum", Wrapping
.AfterEnum
);
203 IO
.mapOptional("AfterExternBlock", Wrapping
.AfterExternBlock
);
204 IO
.mapOptional("AfterFunction", Wrapping
.AfterFunction
);
205 IO
.mapOptional("AfterNamespace", Wrapping
.AfterNamespace
);
206 IO
.mapOptional("AfterObjCDeclaration", Wrapping
.AfterObjCDeclaration
);
207 IO
.mapOptional("AfterStruct", Wrapping
.AfterStruct
);
208 IO
.mapOptional("AfterUnion", Wrapping
.AfterUnion
);
209 IO
.mapOptional("BeforeCatch", Wrapping
.BeforeCatch
);
210 IO
.mapOptional("BeforeElse", Wrapping
.BeforeElse
);
211 IO
.mapOptional("BeforeLambdaBody", Wrapping
.BeforeLambdaBody
);
212 IO
.mapOptional("BeforeWhile", Wrapping
.BeforeWhile
);
213 IO
.mapOptional("IndentBraces", Wrapping
.IndentBraces
);
214 IO
.mapOptional("SplitEmptyFunction", Wrapping
.SplitEmptyFunction
);
215 IO
.mapOptional("SplitEmptyRecord", Wrapping
.SplitEmptyRecord
);
216 IO
.mapOptional("SplitEmptyNamespace", Wrapping
.SplitEmptyNamespace
);
220 template <> struct ScalarEnumerationTraits
<FormatStyle::BracketAlignmentStyle
> {
221 static void enumeration(IO
&IO
, FormatStyle::BracketAlignmentStyle
&Value
) {
222 IO
.enumCase(Value
, "Align", FormatStyle::BAS_Align
);
223 IO
.enumCase(Value
, "DontAlign", FormatStyle::BAS_DontAlign
);
224 IO
.enumCase(Value
, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak
);
225 IO
.enumCase(Value
, "BlockIndent", FormatStyle::BAS_BlockIndent
);
227 // For backward compatibility.
228 IO
.enumCase(Value
, "true", FormatStyle::BAS_Align
);
229 IO
.enumCase(Value
, "false", FormatStyle::BAS_DontAlign
);
234 struct ScalarEnumerationTraits
<
235 FormatStyle::BraceWrappingAfterControlStatementStyle
> {
238 FormatStyle::BraceWrappingAfterControlStatementStyle
&Value
) {
239 IO
.enumCase(Value
, "Never", FormatStyle::BWACS_Never
);
240 IO
.enumCase(Value
, "MultiLine", FormatStyle::BWACS_MultiLine
);
241 IO
.enumCase(Value
, "Always", FormatStyle::BWACS_Always
);
243 // For backward compatibility.
244 IO
.enumCase(Value
, "false", FormatStyle::BWACS_Never
);
245 IO
.enumCase(Value
, "true", FormatStyle::BWACS_Always
);
250 struct ScalarEnumerationTraits
<
251 FormatStyle::BreakBeforeConceptDeclarationsStyle
> {
253 enumeration(IO
&IO
, FormatStyle::BreakBeforeConceptDeclarationsStyle
&Value
) {
254 IO
.enumCase(Value
, "Never", FormatStyle::BBCDS_Never
);
255 IO
.enumCase(Value
, "Allowed", FormatStyle::BBCDS_Allowed
);
256 IO
.enumCase(Value
, "Always", FormatStyle::BBCDS_Always
);
258 // For backward compatibility.
259 IO
.enumCase(Value
, "true", FormatStyle::BBCDS_Always
);
260 IO
.enumCase(Value
, "false", FormatStyle::BBCDS_Allowed
);
265 struct ScalarEnumerationTraits
<FormatStyle::BreakBeforeInlineASMColonStyle
> {
266 static void enumeration(IO
&IO
,
267 FormatStyle::BreakBeforeInlineASMColonStyle
&Value
) {
268 IO
.enumCase(Value
, "Never", FormatStyle::BBIAS_Never
);
269 IO
.enumCase(Value
, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline
);
270 IO
.enumCase(Value
, "Always", FormatStyle::BBIAS_Always
);
275 struct ScalarEnumerationTraits
<FormatStyle::BreakConstructorInitializersStyle
> {
277 enumeration(IO
&IO
, FormatStyle::BreakConstructorInitializersStyle
&Value
) {
278 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BCIS_BeforeColon
);
279 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BCIS_BeforeComma
);
280 IO
.enumCase(Value
, "AfterColon", FormatStyle::BCIS_AfterColon
);
285 struct ScalarEnumerationTraits
<FormatStyle::BreakInheritanceListStyle
> {
286 static void enumeration(IO
&IO
,
287 FormatStyle::BreakInheritanceListStyle
&Value
) {
288 IO
.enumCase(Value
, "BeforeColon", FormatStyle::BILS_BeforeColon
);
289 IO
.enumCase(Value
, "BeforeComma", FormatStyle::BILS_BeforeComma
);
290 IO
.enumCase(Value
, "AfterColon", FormatStyle::BILS_AfterColon
);
291 IO
.enumCase(Value
, "AfterComma", FormatStyle::BILS_AfterComma
);
296 struct ScalarEnumerationTraits
<FormatStyle::BreakTemplateDeclarationsStyle
> {
297 static void enumeration(IO
&IO
,
298 FormatStyle::BreakTemplateDeclarationsStyle
&Value
) {
299 IO
.enumCase(Value
, "No", FormatStyle::BTDS_No
);
300 IO
.enumCase(Value
, "MultiLine", FormatStyle::BTDS_MultiLine
);
301 IO
.enumCase(Value
, "Yes", FormatStyle::BTDS_Yes
);
303 // For backward compatibility.
304 IO
.enumCase(Value
, "false", FormatStyle::BTDS_MultiLine
);
305 IO
.enumCase(Value
, "true", FormatStyle::BTDS_Yes
);
310 struct ScalarEnumerationTraits
<FormatStyle::DefinitionReturnTypeBreakingStyle
> {
312 enumeration(IO
&IO
, FormatStyle::DefinitionReturnTypeBreakingStyle
&Value
) {
313 IO
.enumCase(Value
, "None", FormatStyle::DRTBS_None
);
314 IO
.enumCase(Value
, "All", FormatStyle::DRTBS_All
);
315 IO
.enumCase(Value
, "TopLevel", FormatStyle::DRTBS_TopLevel
);
317 // For backward compatibility.
318 IO
.enumCase(Value
, "false", FormatStyle::DRTBS_None
);
319 IO
.enumCase(Value
, "true", FormatStyle::DRTBS_All
);
324 struct ScalarEnumerationTraits
<FormatStyle::EscapedNewlineAlignmentStyle
> {
325 static void enumeration(IO
&IO
,
326 FormatStyle::EscapedNewlineAlignmentStyle
&Value
) {
327 IO
.enumCase(Value
, "DontAlign", FormatStyle::ENAS_DontAlign
);
328 IO
.enumCase(Value
, "Left", FormatStyle::ENAS_Left
);
329 IO
.enumCase(Value
, "Right", FormatStyle::ENAS_Right
);
331 // For backward compatibility.
332 IO
.enumCase(Value
, "true", FormatStyle::ENAS_Left
);
333 IO
.enumCase(Value
, "false", FormatStyle::ENAS_Right
);
338 struct ScalarEnumerationTraits
<FormatStyle::EmptyLineAfterAccessModifierStyle
> {
340 enumeration(IO
&IO
, FormatStyle::EmptyLineAfterAccessModifierStyle
&Value
) {
341 IO
.enumCase(Value
, "Never", FormatStyle::ELAAMS_Never
);
342 IO
.enumCase(Value
, "Leave", FormatStyle::ELAAMS_Leave
);
343 IO
.enumCase(Value
, "Always", FormatStyle::ELAAMS_Always
);
348 struct ScalarEnumerationTraits
<
349 FormatStyle::EmptyLineBeforeAccessModifierStyle
> {
351 enumeration(IO
&IO
, FormatStyle::EmptyLineBeforeAccessModifierStyle
&Value
) {
352 IO
.enumCase(Value
, "Never", FormatStyle::ELBAMS_Never
);
353 IO
.enumCase(Value
, "Leave", FormatStyle::ELBAMS_Leave
);
354 IO
.enumCase(Value
, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock
);
355 IO
.enumCase(Value
, "Always", FormatStyle::ELBAMS_Always
);
360 struct ScalarEnumerationTraits
<FormatStyle::IndentExternBlockStyle
> {
361 static void enumeration(IO
&IO
, FormatStyle::IndentExternBlockStyle
&Value
) {
362 IO
.enumCase(Value
, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock
);
363 IO
.enumCase(Value
, "Indent", FormatStyle::IEBS_Indent
);
364 IO
.enumCase(Value
, "NoIndent", FormatStyle::IEBS_NoIndent
);
365 IO
.enumCase(Value
, "true", FormatStyle::IEBS_Indent
);
366 IO
.enumCase(Value
, "false", FormatStyle::IEBS_NoIndent
);
370 template <> struct MappingTraits
<FormatStyle::IntegerLiteralSeparatorStyle
> {
371 static void mapping(IO
&IO
, FormatStyle::IntegerLiteralSeparatorStyle
&Base
) {
372 IO
.mapOptional("Binary", Base
.Binary
);
373 IO
.mapOptional("BinaryMinDigits", Base
.BinaryMinDigits
);
374 IO
.mapOptional("Decimal", Base
.Decimal
);
375 IO
.mapOptional("DecimalMinDigits", Base
.DecimalMinDigits
);
376 IO
.mapOptional("Hex", Base
.Hex
);
377 IO
.mapOptional("HexMinDigits", Base
.HexMinDigits
);
381 template <> struct ScalarEnumerationTraits
<FormatStyle::JavaScriptQuoteStyle
> {
382 static void enumeration(IO
&IO
, FormatStyle::JavaScriptQuoteStyle
&Value
) {
383 IO
.enumCase(Value
, "Leave", FormatStyle::JSQS_Leave
);
384 IO
.enumCase(Value
, "Single", FormatStyle::JSQS_Single
);
385 IO
.enumCase(Value
, "Double", FormatStyle::JSQS_Double
);
389 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageKind
> {
390 static void enumeration(IO
&IO
, FormatStyle::LanguageKind
&Value
) {
391 IO
.enumCase(Value
, "Cpp", FormatStyle::LK_Cpp
);
392 IO
.enumCase(Value
, "Java", FormatStyle::LK_Java
);
393 IO
.enumCase(Value
, "JavaScript", FormatStyle::LK_JavaScript
);
394 IO
.enumCase(Value
, "ObjC", FormatStyle::LK_ObjC
);
395 IO
.enumCase(Value
, "Proto", FormatStyle::LK_Proto
);
396 IO
.enumCase(Value
, "TableGen", FormatStyle::LK_TableGen
);
397 IO
.enumCase(Value
, "TextProto", FormatStyle::LK_TextProto
);
398 IO
.enumCase(Value
, "CSharp", FormatStyle::LK_CSharp
);
399 IO
.enumCase(Value
, "Json", FormatStyle::LK_Json
);
400 IO
.enumCase(Value
, "Verilog", FormatStyle::LK_Verilog
);
404 template <> struct ScalarEnumerationTraits
<FormatStyle::LanguageStandard
> {
405 static void enumeration(IO
&IO
, FormatStyle::LanguageStandard
&Value
) {
406 IO
.enumCase(Value
, "c++03", FormatStyle::LS_Cpp03
);
407 IO
.enumCase(Value
, "C++03", FormatStyle::LS_Cpp03
); // Legacy alias
408 IO
.enumCase(Value
, "Cpp03", FormatStyle::LS_Cpp03
); // Legacy alias
410 IO
.enumCase(Value
, "c++11", FormatStyle::LS_Cpp11
);
411 IO
.enumCase(Value
, "C++11", FormatStyle::LS_Cpp11
); // Legacy alias
413 IO
.enumCase(Value
, "c++14", FormatStyle::LS_Cpp14
);
414 IO
.enumCase(Value
, "c++17", FormatStyle::LS_Cpp17
);
415 IO
.enumCase(Value
, "c++20", FormatStyle::LS_Cpp20
);
417 IO
.enumCase(Value
, "Latest", FormatStyle::LS_Latest
);
418 IO
.enumCase(Value
, "Cpp11", FormatStyle::LS_Latest
); // Legacy alias
419 IO
.enumCase(Value
, "Auto", FormatStyle::LS_Auto
);
424 struct ScalarEnumerationTraits
<FormatStyle::LambdaBodyIndentationKind
> {
425 static void enumeration(IO
&IO
,
426 FormatStyle::LambdaBodyIndentationKind
&Value
) {
427 IO
.enumCase(Value
, "Signature", FormatStyle::LBI_Signature
);
428 IO
.enumCase(Value
, "OuterScope", FormatStyle::LBI_OuterScope
);
432 template <> struct ScalarEnumerationTraits
<FormatStyle::LineEndingStyle
> {
433 static void enumeration(IO
&IO
, FormatStyle::LineEndingStyle
&Value
) {
434 IO
.enumCase(Value
, "LF", FormatStyle::LE_LF
);
435 IO
.enumCase(Value
, "CRLF", FormatStyle::LE_CRLF
);
436 IO
.enumCase(Value
, "DeriveLF", FormatStyle::LE_DeriveLF
);
437 IO
.enumCase(Value
, "DeriveCRLF", FormatStyle::LE_DeriveCRLF
);
442 struct ScalarEnumerationTraits
<FormatStyle::NamespaceIndentationKind
> {
443 static void enumeration(IO
&IO
,
444 FormatStyle::NamespaceIndentationKind
&Value
) {
445 IO
.enumCase(Value
, "None", FormatStyle::NI_None
);
446 IO
.enumCase(Value
, "Inner", FormatStyle::NI_Inner
);
447 IO
.enumCase(Value
, "All", FormatStyle::NI_All
);
451 template <> struct ScalarEnumerationTraits
<FormatStyle::OperandAlignmentStyle
> {
452 static void enumeration(IO
&IO
, FormatStyle::OperandAlignmentStyle
&Value
) {
453 IO
.enumCase(Value
, "DontAlign", FormatStyle::OAS_DontAlign
);
454 IO
.enumCase(Value
, "Align", FormatStyle::OAS_Align
);
455 IO
.enumCase(Value
, "AlignAfterOperator",
456 FormatStyle::OAS_AlignAfterOperator
);
458 // For backward compatibility.
459 IO
.enumCase(Value
, "true", FormatStyle::OAS_Align
);
460 IO
.enumCase(Value
, "false", FormatStyle::OAS_DontAlign
);
465 struct ScalarEnumerationTraits
<FormatStyle::PackConstructorInitializersStyle
> {
467 enumeration(IO
&IO
, FormatStyle::PackConstructorInitializersStyle
&Value
) {
468 IO
.enumCase(Value
, "Never", FormatStyle::PCIS_Never
);
469 IO
.enumCase(Value
, "BinPack", FormatStyle::PCIS_BinPack
);
470 IO
.enumCase(Value
, "CurrentLine", FormatStyle::PCIS_CurrentLine
);
471 IO
.enumCase(Value
, "NextLine", FormatStyle::PCIS_NextLine
);
472 IO
.enumCase(Value
, "NextLineOnly", FormatStyle::PCIS_NextLineOnly
);
476 template <> struct ScalarEnumerationTraits
<FormatStyle::PointerAlignmentStyle
> {
477 static void enumeration(IO
&IO
, FormatStyle::PointerAlignmentStyle
&Value
) {
478 IO
.enumCase(Value
, "Middle", FormatStyle::PAS_Middle
);
479 IO
.enumCase(Value
, "Left", FormatStyle::PAS_Left
);
480 IO
.enumCase(Value
, "Right", FormatStyle::PAS_Right
);
482 // For backward compatibility.
483 IO
.enumCase(Value
, "true", FormatStyle::PAS_Left
);
484 IO
.enumCase(Value
, "false", FormatStyle::PAS_Right
);
489 struct ScalarEnumerationTraits
<FormatStyle::PPDirectiveIndentStyle
> {
490 static void enumeration(IO
&IO
, FormatStyle::PPDirectiveIndentStyle
&Value
) {
491 IO
.enumCase(Value
, "None", FormatStyle::PPDIS_None
);
492 IO
.enumCase(Value
, "AfterHash", FormatStyle::PPDIS_AfterHash
);
493 IO
.enumCase(Value
, "BeforeHash", FormatStyle::PPDIS_BeforeHash
);
498 struct ScalarEnumerationTraits
<FormatStyle::QualifierAlignmentStyle
> {
499 static void enumeration(IO
&IO
, FormatStyle::QualifierAlignmentStyle
&Value
) {
500 IO
.enumCase(Value
, "Leave", FormatStyle::QAS_Leave
);
501 IO
.enumCase(Value
, "Left", FormatStyle::QAS_Left
);
502 IO
.enumCase(Value
, "Right", FormatStyle::QAS_Right
);
503 IO
.enumCase(Value
, "Custom", FormatStyle::QAS_Custom
);
508 struct MappingTraits
<
509 FormatStyle::SpaceBeforeParensCustom::AfterPlacementOperatorStyle
> {
512 FormatStyle::SpaceBeforeParensCustom::AfterPlacementOperatorStyle
514 IO
.enumCase(Value
, "Always",
515 FormatStyle::SpaceBeforeParensCustom::APO_Always
);
516 IO
.enumCase(Value
, "Never",
517 FormatStyle::SpaceBeforeParensCustom::APO_Never
);
518 IO
.enumCase(Value
, "Leave",
519 FormatStyle::SpaceBeforeParensCustom::APO_Leave
);
523 template <> struct MappingTraits
<FormatStyle::RawStringFormat
> {
524 static void mapping(IO
&IO
, FormatStyle::RawStringFormat
&Format
) {
525 IO
.mapOptional("Language", Format
.Language
);
526 IO
.mapOptional("Delimiters", Format
.Delimiters
);
527 IO
.mapOptional("EnclosingFunctions", Format
.EnclosingFunctions
);
528 IO
.mapOptional("CanonicalDelimiter", Format
.CanonicalDelimiter
);
529 IO
.mapOptional("BasedOnStyle", Format
.BasedOnStyle
);
534 struct ScalarEnumerationTraits
<FormatStyle::ReferenceAlignmentStyle
> {
535 static void enumeration(IO
&IO
, FormatStyle::ReferenceAlignmentStyle
&Value
) {
536 IO
.enumCase(Value
, "Pointer", FormatStyle::RAS_Pointer
);
537 IO
.enumCase(Value
, "Middle", FormatStyle::RAS_Middle
);
538 IO
.enumCase(Value
, "Left", FormatStyle::RAS_Left
);
539 IO
.enumCase(Value
, "Right", FormatStyle::RAS_Right
);
544 struct ScalarEnumerationTraits
<FormatStyle::RemoveParenthesesStyle
> {
545 static void enumeration(IO
&IO
, FormatStyle::RemoveParenthesesStyle
&Value
) {
546 IO
.enumCase(Value
, "Leave", FormatStyle::RPS_Leave
);
547 IO
.enumCase(Value
, "MultipleParentheses",
548 FormatStyle::RPS_MultipleParentheses
);
549 IO
.enumCase(Value
, "ReturnStatement", FormatStyle::RPS_ReturnStatement
);
554 struct ScalarEnumerationTraits
<FormatStyle::RequiresClausePositionStyle
> {
555 static void enumeration(IO
&IO
,
556 FormatStyle::RequiresClausePositionStyle
&Value
) {
557 IO
.enumCase(Value
, "OwnLine", FormatStyle::RCPS_OwnLine
);
558 IO
.enumCase(Value
, "WithPreceding", FormatStyle::RCPS_WithPreceding
);
559 IO
.enumCase(Value
, "WithFollowing", FormatStyle::RCPS_WithFollowing
);
560 IO
.enumCase(Value
, "SingleLine", FormatStyle::RCPS_SingleLine
);
565 struct ScalarEnumerationTraits
<FormatStyle::RequiresExpressionIndentationKind
> {
567 enumeration(IO
&IO
, FormatStyle::RequiresExpressionIndentationKind
&Value
) {
568 IO
.enumCase(Value
, "Keyword", FormatStyle::REI_Keyword
);
569 IO
.enumCase(Value
, "OuterScope", FormatStyle::REI_OuterScope
);
574 struct ScalarEnumerationTraits
<FormatStyle::ReturnTypeBreakingStyle
> {
575 static void enumeration(IO
&IO
, FormatStyle::ReturnTypeBreakingStyle
&Value
) {
576 IO
.enumCase(Value
, "None", FormatStyle::RTBS_None
);
577 IO
.enumCase(Value
, "All", FormatStyle::RTBS_All
);
578 IO
.enumCase(Value
, "TopLevel", FormatStyle::RTBS_TopLevel
);
579 IO
.enumCase(Value
, "TopLevelDefinitions",
580 FormatStyle::RTBS_TopLevelDefinitions
);
581 IO
.enumCase(Value
, "AllDefinitions", FormatStyle::RTBS_AllDefinitions
);
586 struct ScalarEnumerationTraits
<FormatStyle::SeparateDefinitionStyle
> {
587 static void enumeration(IO
&IO
, FormatStyle::SeparateDefinitionStyle
&Value
) {
588 IO
.enumCase(Value
, "Leave", FormatStyle::SDS_Leave
);
589 IO
.enumCase(Value
, "Always", FormatStyle::SDS_Always
);
590 IO
.enumCase(Value
, "Never", FormatStyle::SDS_Never
);
594 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortBlockStyle
> {
595 static void enumeration(IO
&IO
, FormatStyle::ShortBlockStyle
&Value
) {
596 IO
.enumCase(Value
, "Never", FormatStyle::SBS_Never
);
597 IO
.enumCase(Value
, "false", FormatStyle::SBS_Never
);
598 IO
.enumCase(Value
, "Always", FormatStyle::SBS_Always
);
599 IO
.enumCase(Value
, "true", FormatStyle::SBS_Always
);
600 IO
.enumCase(Value
, "Empty", FormatStyle::SBS_Empty
);
604 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortFunctionStyle
> {
605 static void enumeration(IO
&IO
, FormatStyle::ShortFunctionStyle
&Value
) {
606 IO
.enumCase(Value
, "None", FormatStyle::SFS_None
);
607 IO
.enumCase(Value
, "false", FormatStyle::SFS_None
);
608 IO
.enumCase(Value
, "All", FormatStyle::SFS_All
);
609 IO
.enumCase(Value
, "true", FormatStyle::SFS_All
);
610 IO
.enumCase(Value
, "Inline", FormatStyle::SFS_Inline
);
611 IO
.enumCase(Value
, "InlineOnly", FormatStyle::SFS_InlineOnly
);
612 IO
.enumCase(Value
, "Empty", FormatStyle::SFS_Empty
);
616 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortIfStyle
> {
617 static void enumeration(IO
&IO
, FormatStyle::ShortIfStyle
&Value
) {
618 IO
.enumCase(Value
, "Never", FormatStyle::SIS_Never
);
619 IO
.enumCase(Value
, "WithoutElse", FormatStyle::SIS_WithoutElse
);
620 IO
.enumCase(Value
, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf
);
621 IO
.enumCase(Value
, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse
);
623 // For backward compatibility.
624 IO
.enumCase(Value
, "Always", FormatStyle::SIS_OnlyFirstIf
);
625 IO
.enumCase(Value
, "false", FormatStyle::SIS_Never
);
626 IO
.enumCase(Value
, "true", FormatStyle::SIS_WithoutElse
);
630 template <> struct ScalarEnumerationTraits
<FormatStyle::ShortLambdaStyle
> {
631 static void enumeration(IO
&IO
, FormatStyle::ShortLambdaStyle
&Value
) {
632 IO
.enumCase(Value
, "None", FormatStyle::SLS_None
);
633 IO
.enumCase(Value
, "false", FormatStyle::SLS_None
);
634 IO
.enumCase(Value
, "Empty", FormatStyle::SLS_Empty
);
635 IO
.enumCase(Value
, "Inline", FormatStyle::SLS_Inline
);
636 IO
.enumCase(Value
, "All", FormatStyle::SLS_All
);
637 IO
.enumCase(Value
, "true", FormatStyle::SLS_All
);
641 template <> struct ScalarEnumerationTraits
<FormatStyle::SortIncludesOptions
> {
642 static void enumeration(IO
&IO
, FormatStyle::SortIncludesOptions
&Value
) {
643 IO
.enumCase(Value
, "Never", FormatStyle::SI_Never
);
644 IO
.enumCase(Value
, "CaseInsensitive", FormatStyle::SI_CaseInsensitive
);
645 IO
.enumCase(Value
, "CaseSensitive", FormatStyle::SI_CaseSensitive
);
647 // For backward compatibility.
648 IO
.enumCase(Value
, "false", FormatStyle::SI_Never
);
649 IO
.enumCase(Value
, "true", FormatStyle::SI_CaseSensitive
);
654 struct ScalarEnumerationTraits
<FormatStyle::SortJavaStaticImportOptions
> {
655 static void enumeration(IO
&IO
,
656 FormatStyle::SortJavaStaticImportOptions
&Value
) {
657 IO
.enumCase(Value
, "Before", FormatStyle::SJSIO_Before
);
658 IO
.enumCase(Value
, "After", FormatStyle::SJSIO_After
);
663 struct ScalarEnumerationTraits
<FormatStyle::SortUsingDeclarationsOptions
> {
664 static void enumeration(IO
&IO
,
665 FormatStyle::SortUsingDeclarationsOptions
&Value
) {
666 IO
.enumCase(Value
, "Never", FormatStyle::SUD_Never
);
667 IO
.enumCase(Value
, "Lexicographic", FormatStyle::SUD_Lexicographic
);
668 IO
.enumCase(Value
, "LexicographicNumeric",
669 FormatStyle::SUD_LexicographicNumeric
);
671 // For backward compatibility.
672 IO
.enumCase(Value
, "false", FormatStyle::SUD_Never
);
673 IO
.enumCase(Value
, "true", FormatStyle::SUD_LexicographicNumeric
);
678 struct ScalarEnumerationTraits
<FormatStyle::SpaceAroundPointerQualifiersStyle
> {
680 enumeration(IO
&IO
, FormatStyle::SpaceAroundPointerQualifiersStyle
&Value
) {
681 IO
.enumCase(Value
, "Default", FormatStyle::SAPQ_Default
);
682 IO
.enumCase(Value
, "Before", FormatStyle::SAPQ_Before
);
683 IO
.enumCase(Value
, "After", FormatStyle::SAPQ_After
);
684 IO
.enumCase(Value
, "Both", FormatStyle::SAPQ_Both
);
688 template <> struct MappingTraits
<FormatStyle::SpaceBeforeParensCustom
> {
689 static void mapping(IO
&IO
, FormatStyle::SpaceBeforeParensCustom
&Spacing
) {
690 IO
.mapOptional("AfterControlStatements", Spacing
.AfterControlStatements
);
691 IO
.mapOptional("AfterForeachMacros", Spacing
.AfterForeachMacros
);
692 IO
.mapOptional("AfterFunctionDefinitionName",
693 Spacing
.AfterFunctionDefinitionName
);
694 IO
.mapOptional("AfterFunctionDeclarationName",
695 Spacing
.AfterFunctionDeclarationName
);
696 IO
.mapOptional("AfterIfMacros", Spacing
.AfterIfMacros
);
697 IO
.mapOptional("AfterOverloadedOperator", Spacing
.AfterOverloadedOperator
);
698 IO
.mapOptional("AfterPlacementOperator", Spacing
.AfterPlacementOperator
);
699 IO
.mapOptional("AfterRequiresInClause", Spacing
.AfterRequiresInClause
);
700 IO
.mapOptional("AfterRequiresInExpression",
701 Spacing
.AfterRequiresInExpression
);
702 IO
.mapOptional("BeforeNonEmptyParentheses",
703 Spacing
.BeforeNonEmptyParentheses
);
708 struct ScalarEnumerationTraits
<FormatStyle::SpaceBeforeParensStyle
> {
709 static void enumeration(IO
&IO
, FormatStyle::SpaceBeforeParensStyle
&Value
) {
710 IO
.enumCase(Value
, "Never", FormatStyle::SBPO_Never
);
711 IO
.enumCase(Value
, "ControlStatements",
712 FormatStyle::SBPO_ControlStatements
);
713 IO
.enumCase(Value
, "ControlStatementsExceptControlMacros",
714 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
715 IO
.enumCase(Value
, "NonEmptyParentheses",
716 FormatStyle::SBPO_NonEmptyParentheses
);
717 IO
.enumCase(Value
, "Always", FormatStyle::SBPO_Always
);
718 IO
.enumCase(Value
, "Custom", FormatStyle::SBPO_Custom
);
720 // For backward compatibility.
721 IO
.enumCase(Value
, "false", FormatStyle::SBPO_Never
);
722 IO
.enumCase(Value
, "true", FormatStyle::SBPO_ControlStatements
);
723 IO
.enumCase(Value
, "ControlStatementsExceptForEachMacros",
724 FormatStyle::SBPO_ControlStatementsExceptControlMacros
);
728 template <> struct ScalarEnumerationTraits
<FormatStyle::SpacesInAnglesStyle
> {
729 static void enumeration(IO
&IO
, FormatStyle::SpacesInAnglesStyle
&Value
) {
730 IO
.enumCase(Value
, "Never", FormatStyle::SIAS_Never
);
731 IO
.enumCase(Value
, "Always", FormatStyle::SIAS_Always
);
732 IO
.enumCase(Value
, "Leave", FormatStyle::SIAS_Leave
);
734 // For backward compatibility.
735 IO
.enumCase(Value
, "false", FormatStyle::SIAS_Never
);
736 IO
.enumCase(Value
, "true", FormatStyle::SIAS_Always
);
740 template <> struct MappingTraits
<FormatStyle::SpacesInLineComment
> {
741 static void mapping(IO
&IO
, FormatStyle::SpacesInLineComment
&Space
) {
742 // Transform the maximum to signed, to parse "-1" correctly
743 int signedMaximum
= static_cast<int>(Space
.Maximum
);
744 IO
.mapOptional("Minimum", Space
.Minimum
);
745 IO
.mapOptional("Maximum", signedMaximum
);
746 Space
.Maximum
= static_cast<unsigned>(signedMaximum
);
748 if (Space
.Maximum
!= -1u)
749 Space
.Minimum
= std::min(Space
.Minimum
, Space
.Maximum
);
753 template <> struct MappingTraits
<FormatStyle::SpacesInParensCustom
> {
754 static void mapping(IO
&IO
, FormatStyle::SpacesInParensCustom
&Spaces
) {
755 IO
.mapOptional("InCStyleCasts", Spaces
.InCStyleCasts
);
756 IO
.mapOptional("InConditionalStatements", Spaces
.InConditionalStatements
);
757 IO
.mapOptional("InEmptyParentheses", Spaces
.InEmptyParentheses
);
758 IO
.mapOptional("Other", Spaces
.Other
);
762 template <> struct ScalarEnumerationTraits
<FormatStyle::SpacesInParensStyle
> {
763 static void enumeration(IO
&IO
, FormatStyle::SpacesInParensStyle
&Value
) {
764 IO
.enumCase(Value
, "Never", FormatStyle::SIPO_Never
);
765 IO
.enumCase(Value
, "Custom", FormatStyle::SIPO_Custom
);
769 template <> struct ScalarEnumerationTraits
<FormatStyle::TrailingCommaStyle
> {
770 static void enumeration(IO
&IO
, FormatStyle::TrailingCommaStyle
&Value
) {
771 IO
.enumCase(Value
, "None", FormatStyle::TCS_None
);
772 IO
.enumCase(Value
, "Wrapped", FormatStyle::TCS_Wrapped
);
777 struct ScalarEnumerationTraits
<FormatStyle::TrailingCommentsAlignmentKinds
> {
778 static void enumeration(IO
&IO
,
779 FormatStyle::TrailingCommentsAlignmentKinds
&Value
) {
780 IO
.enumCase(Value
, "Leave", FormatStyle::TCAS_Leave
);
781 IO
.enumCase(Value
, "Always", FormatStyle::TCAS_Always
);
782 IO
.enumCase(Value
, "Never", FormatStyle::TCAS_Never
);
786 template <> struct MappingTraits
<FormatStyle::TrailingCommentsAlignmentStyle
> {
787 static void enumInput(IO
&IO
,
788 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
789 IO
.enumCase(Value
, "Leave",
790 FormatStyle::TrailingCommentsAlignmentStyle(
791 {FormatStyle::TCAS_Leave
, 0}));
793 IO
.enumCase(Value
, "Always",
794 FormatStyle::TrailingCommentsAlignmentStyle(
795 {FormatStyle::TCAS_Always
, 0}));
797 IO
.enumCase(Value
, "Never",
798 FormatStyle::TrailingCommentsAlignmentStyle(
799 {FormatStyle::TCAS_Never
, 0}));
801 // For backwards compatibility
802 IO
.enumCase(Value
, "true",
803 FormatStyle::TrailingCommentsAlignmentStyle(
804 {FormatStyle::TCAS_Always
, 0}));
805 IO
.enumCase(Value
, "false",
806 FormatStyle::TrailingCommentsAlignmentStyle(
807 {FormatStyle::TCAS_Never
, 0}));
810 static void mapping(IO
&IO
,
811 FormatStyle::TrailingCommentsAlignmentStyle
&Value
) {
812 IO
.mapOptional("Kind", Value
.Kind
);
813 IO
.mapOptional("OverEmptyLines", Value
.OverEmptyLines
);
817 template <> struct ScalarEnumerationTraits
<FormatStyle::UseTabStyle
> {
818 static void enumeration(IO
&IO
, FormatStyle::UseTabStyle
&Value
) {
819 IO
.enumCase(Value
, "Never", FormatStyle::UT_Never
);
820 IO
.enumCase(Value
, "false", FormatStyle::UT_Never
);
821 IO
.enumCase(Value
, "Always", FormatStyle::UT_Always
);
822 IO
.enumCase(Value
, "true", FormatStyle::UT_Always
);
823 IO
.enumCase(Value
, "ForIndentation", FormatStyle::UT_ForIndentation
);
824 IO
.enumCase(Value
, "ForContinuationAndIndentation",
825 FormatStyle::UT_ForContinuationAndIndentation
);
826 IO
.enumCase(Value
, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces
);
830 template <> struct MappingTraits
<FormatStyle
> {
831 static void mapping(IO
&IO
, FormatStyle
&Style
) {
832 // When reading, read the language first, we need it for getPredefinedStyle.
833 IO
.mapOptional("Language", Style
.Language
);
835 StringRef BasedOnStyle
;
836 if (IO
.outputting()) {
837 StringRef Styles
[] = {"LLVM", "Google", "Chromium", "Mozilla",
838 "WebKit", "GNU", "Microsoft", "clang-format"};
839 for (StringRef StyleName
: Styles
) {
840 FormatStyle PredefinedStyle
;
841 if (getPredefinedStyle(StyleName
, Style
.Language
, &PredefinedStyle
) &&
842 Style
== PredefinedStyle
) {
843 IO
.mapOptional("# BasedOnStyle", StyleName
);
844 BasedOnStyle
= StyleName
;
849 IO
.mapOptional("BasedOnStyle", BasedOnStyle
);
850 if (!BasedOnStyle
.empty()) {
851 FormatStyle::LanguageKind OldLanguage
= Style
.Language
;
852 FormatStyle::LanguageKind Language
=
853 ((FormatStyle
*)IO
.getContext())->Language
;
854 if (!getPredefinedStyle(BasedOnStyle
, Language
, &Style
)) {
855 IO
.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle
));
858 Style
.Language
= OldLanguage
;
862 // Initialize some variables used in the parsing. The using logic is at the
865 // For backward compatibility:
866 // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was
867 // false unless BasedOnStyle was Google or Chromium whereas that of
868 // AllowAllConstructorInitializersOnNextLine was always true, so the
869 // equivalent default value of PackConstructorInitializers is PCIS_NextLine
870 // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options
871 // had a non-default value while PackConstructorInitializers has a default
872 // value, set the latter to an equivalent non-default value if needed.
873 const bool IsGoogleOrChromium
= BasedOnStyle
.equals_insensitive("google") ||
874 BasedOnStyle
.equals_insensitive("chromium");
875 bool OnCurrentLine
= IsGoogleOrChromium
;
876 bool OnNextLine
= true;
878 bool BreakBeforeInheritanceComma
= false;
879 bool BreakConstructorInitializersBeforeComma
= false;
881 bool DeriveLineEnding
= true;
882 bool UseCRLF
= false;
884 bool SpaceInEmptyParentheses
= false;
885 bool SpacesInConditionalStatement
= false;
886 bool SpacesInCStyleCastParentheses
= false;
887 bool SpacesInParentheses
= false;
889 // For backward compatibility.
890 if (!IO
.outputting()) {
891 IO
.mapOptional("AlignEscapedNewlinesLeft", Style
.AlignEscapedNewlines
);
892 IO
.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine
);
893 IO
.mapOptional("BreakBeforeInheritanceComma",
894 BreakBeforeInheritanceComma
);
895 IO
.mapOptional("BreakConstructorInitializersBeforeComma",
896 BreakConstructorInitializersBeforeComma
);
897 IO
.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
899 IO
.mapOptional("DeriveLineEnding", DeriveLineEnding
);
900 IO
.mapOptional("DerivePointerBinding", Style
.DerivePointerAlignment
);
901 IO
.mapOptional("IndentFunctionDeclarationAfterType",
902 Style
.IndentWrappedFunctionNames
);
903 IO
.mapOptional("IndentRequires", Style
.IndentRequiresClause
);
904 IO
.mapOptional("PointerBindsToType", Style
.PointerAlignment
);
905 IO
.mapOptional("SpaceAfterControlStatementKeyword",
906 Style
.SpaceBeforeParens
);
907 IO
.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses
);
908 IO
.mapOptional("SpacesInConditionalStatement",
909 SpacesInConditionalStatement
);
910 IO
.mapOptional("SpacesInCStyleCastParentheses",
911 SpacesInCStyleCastParentheses
);
912 IO
.mapOptional("SpacesInParentheses", SpacesInParentheses
);
913 IO
.mapOptional("UseCRLF", UseCRLF
);
916 IO
.mapOptional("AccessModifierOffset", Style
.AccessModifierOffset
);
917 IO
.mapOptional("AlignAfterOpenBracket", Style
.AlignAfterOpenBracket
);
918 IO
.mapOptional("AlignArrayOfStructures", Style
.AlignArrayOfStructures
);
919 IO
.mapOptional("AlignConsecutiveAssignments",
920 Style
.AlignConsecutiveAssignments
);
921 IO
.mapOptional("AlignConsecutiveBitFields",
922 Style
.AlignConsecutiveBitFields
);
923 IO
.mapOptional("AlignConsecutiveDeclarations",
924 Style
.AlignConsecutiveDeclarations
);
925 IO
.mapOptional("AlignConsecutiveMacros", Style
.AlignConsecutiveMacros
);
926 IO
.mapOptional("AlignConsecutiveShortCaseStatements",
927 Style
.AlignConsecutiveShortCaseStatements
);
928 IO
.mapOptional("AlignEscapedNewlines", Style
.AlignEscapedNewlines
);
929 IO
.mapOptional("AlignOperands", Style
.AlignOperands
);
930 IO
.mapOptional("AlignTrailingComments", Style
.AlignTrailingComments
);
931 IO
.mapOptional("AllowAllArgumentsOnNextLine",
932 Style
.AllowAllArgumentsOnNextLine
);
933 IO
.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
934 Style
.AllowAllParametersOfDeclarationOnNextLine
);
935 IO
.mapOptional("AllowBreakBeforeNoexceptSpecifier",
936 Style
.AllowBreakBeforeNoexceptSpecifier
);
937 IO
.mapOptional("AllowShortBlocksOnASingleLine",
938 Style
.AllowShortBlocksOnASingleLine
);
939 IO
.mapOptional("AllowShortCaseLabelsOnASingleLine",
940 Style
.AllowShortCaseLabelsOnASingleLine
);
941 IO
.mapOptional("AllowShortCompoundRequirementOnASingleLine",
942 Style
.AllowShortCompoundRequirementOnASingleLine
);
943 IO
.mapOptional("AllowShortEnumsOnASingleLine",
944 Style
.AllowShortEnumsOnASingleLine
);
945 IO
.mapOptional("AllowShortFunctionsOnASingleLine",
946 Style
.AllowShortFunctionsOnASingleLine
);
947 IO
.mapOptional("AllowShortIfStatementsOnASingleLine",
948 Style
.AllowShortIfStatementsOnASingleLine
);
949 IO
.mapOptional("AllowShortLambdasOnASingleLine",
950 Style
.AllowShortLambdasOnASingleLine
);
951 IO
.mapOptional("AllowShortLoopsOnASingleLine",
952 Style
.AllowShortLoopsOnASingleLine
);
953 IO
.mapOptional("AlwaysBreakAfterDefinitionReturnType",
954 Style
.AlwaysBreakAfterDefinitionReturnType
);
955 IO
.mapOptional("AlwaysBreakAfterReturnType",
956 Style
.AlwaysBreakAfterReturnType
);
957 IO
.mapOptional("AlwaysBreakBeforeMultilineStrings",
958 Style
.AlwaysBreakBeforeMultilineStrings
);
959 IO
.mapOptional("AlwaysBreakTemplateDeclarations",
960 Style
.AlwaysBreakTemplateDeclarations
);
961 IO
.mapOptional("AttributeMacros", Style
.AttributeMacros
);
962 IO
.mapOptional("BinPackArguments", Style
.BinPackArguments
);
963 IO
.mapOptional("BinPackParameters", Style
.BinPackParameters
);
964 IO
.mapOptional("BitFieldColonSpacing", Style
.BitFieldColonSpacing
);
965 IO
.mapOptional("BracedInitializerIndentWidth",
966 Style
.BracedInitializerIndentWidth
);
967 IO
.mapOptional("BraceWrapping", Style
.BraceWrapping
);
968 IO
.mapOptional("BreakAfterAttributes", Style
.BreakAfterAttributes
);
969 IO
.mapOptional("BreakAfterJavaFieldAnnotations",
970 Style
.BreakAfterJavaFieldAnnotations
);
971 IO
.mapOptional("BreakArrays", Style
.BreakArrays
);
972 IO
.mapOptional("BreakBeforeBinaryOperators",
973 Style
.BreakBeforeBinaryOperators
);
974 IO
.mapOptional("BreakBeforeConceptDeclarations",
975 Style
.BreakBeforeConceptDeclarations
);
976 IO
.mapOptional("BreakBeforeBraces", Style
.BreakBeforeBraces
);
977 IO
.mapOptional("BreakBeforeInlineASMColon",
978 Style
.BreakBeforeInlineASMColon
);
979 IO
.mapOptional("BreakBeforeTernaryOperators",
980 Style
.BreakBeforeTernaryOperators
);
981 IO
.mapOptional("BreakConstructorInitializers",
982 Style
.BreakConstructorInitializers
);
983 IO
.mapOptional("BreakInheritanceList", Style
.BreakInheritanceList
);
984 IO
.mapOptional("BreakStringLiterals", Style
.BreakStringLiterals
);
985 IO
.mapOptional("ColumnLimit", Style
.ColumnLimit
);
986 IO
.mapOptional("CommentPragmas", Style
.CommentPragmas
);
987 IO
.mapOptional("CompactNamespaces", Style
.CompactNamespaces
);
988 IO
.mapOptional("ConstructorInitializerIndentWidth",
989 Style
.ConstructorInitializerIndentWidth
);
990 IO
.mapOptional("ContinuationIndentWidth", Style
.ContinuationIndentWidth
);
991 IO
.mapOptional("Cpp11BracedListStyle", Style
.Cpp11BracedListStyle
);
992 IO
.mapOptional("DerivePointerAlignment", Style
.DerivePointerAlignment
);
993 IO
.mapOptional("DisableFormat", Style
.DisableFormat
);
994 IO
.mapOptional("EmptyLineAfterAccessModifier",
995 Style
.EmptyLineAfterAccessModifier
);
996 IO
.mapOptional("EmptyLineBeforeAccessModifier",
997 Style
.EmptyLineBeforeAccessModifier
);
998 IO
.mapOptional("ExperimentalAutoDetectBinPacking",
999 Style
.ExperimentalAutoDetectBinPacking
);
1000 IO
.mapOptional("FixNamespaceComments", Style
.FixNamespaceComments
);
1001 IO
.mapOptional("ForEachMacros", Style
.ForEachMacros
);
1002 IO
.mapOptional("IfMacros", Style
.IfMacros
);
1003 IO
.mapOptional("IncludeBlocks", Style
.IncludeStyle
.IncludeBlocks
);
1004 IO
.mapOptional("IncludeCategories", Style
.IncludeStyle
.IncludeCategories
);
1005 IO
.mapOptional("IncludeIsMainRegex", Style
.IncludeStyle
.IncludeIsMainRegex
);
1006 IO
.mapOptional("IncludeIsMainSourceRegex",
1007 Style
.IncludeStyle
.IncludeIsMainSourceRegex
);
1008 IO
.mapOptional("IndentAccessModifiers", Style
.IndentAccessModifiers
);
1009 IO
.mapOptional("IndentCaseBlocks", Style
.IndentCaseBlocks
);
1010 IO
.mapOptional("IndentCaseLabels", Style
.IndentCaseLabels
);
1011 IO
.mapOptional("IndentExternBlock", Style
.IndentExternBlock
);
1012 IO
.mapOptional("IndentGotoLabels", Style
.IndentGotoLabels
);
1013 IO
.mapOptional("IndentPPDirectives", Style
.IndentPPDirectives
);
1014 IO
.mapOptional("IndentRequiresClause", Style
.IndentRequiresClause
);
1015 IO
.mapOptional("IndentWidth", Style
.IndentWidth
);
1016 IO
.mapOptional("IndentWrappedFunctionNames",
1017 Style
.IndentWrappedFunctionNames
);
1018 IO
.mapOptional("InsertBraces", Style
.InsertBraces
);
1019 IO
.mapOptional("InsertNewlineAtEOF", Style
.InsertNewlineAtEOF
);
1020 IO
.mapOptional("InsertTrailingCommas", Style
.InsertTrailingCommas
);
1021 IO
.mapOptional("IntegerLiteralSeparator", Style
.IntegerLiteralSeparator
);
1022 IO
.mapOptional("JavaImportGroups", Style
.JavaImportGroups
);
1023 IO
.mapOptional("JavaScriptQuotes", Style
.JavaScriptQuotes
);
1024 IO
.mapOptional("JavaScriptWrapImports", Style
.JavaScriptWrapImports
);
1025 IO
.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
1026 Style
.KeepEmptyLinesAtTheStartOfBlocks
);
1027 IO
.mapOptional("KeepEmptyLinesAtEOF", Style
.KeepEmptyLinesAtEOF
);
1028 IO
.mapOptional("LambdaBodyIndentation", Style
.LambdaBodyIndentation
);
1029 IO
.mapOptional("LineEnding", Style
.LineEnding
);
1030 IO
.mapOptional("MacroBlockBegin", Style
.MacroBlockBegin
);
1031 IO
.mapOptional("MacroBlockEnd", Style
.MacroBlockEnd
);
1032 IO
.mapOptional("Macros", Style
.Macros
);
1033 IO
.mapOptional("MaxEmptyLinesToKeep", Style
.MaxEmptyLinesToKeep
);
1034 IO
.mapOptional("NamespaceIndentation", Style
.NamespaceIndentation
);
1035 IO
.mapOptional("NamespaceMacros", Style
.NamespaceMacros
);
1036 IO
.mapOptional("ObjCBinPackProtocolList", Style
.ObjCBinPackProtocolList
);
1037 IO
.mapOptional("ObjCBlockIndentWidth", Style
.ObjCBlockIndentWidth
);
1038 IO
.mapOptional("ObjCBreakBeforeNestedBlockParam",
1039 Style
.ObjCBreakBeforeNestedBlockParam
);
1040 IO
.mapOptional("ObjCSpaceAfterProperty", Style
.ObjCSpaceAfterProperty
);
1041 IO
.mapOptional("ObjCSpaceBeforeProtocolList",
1042 Style
.ObjCSpaceBeforeProtocolList
);
1043 IO
.mapOptional("PackConstructorInitializers",
1044 Style
.PackConstructorInitializers
);
1045 IO
.mapOptional("PenaltyBreakAssignment", Style
.PenaltyBreakAssignment
);
1046 IO
.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1047 Style
.PenaltyBreakBeforeFirstCallParameter
);
1048 IO
.mapOptional("PenaltyBreakComment", Style
.PenaltyBreakComment
);
1049 IO
.mapOptional("PenaltyBreakFirstLessLess",
1050 Style
.PenaltyBreakFirstLessLess
);
1051 IO
.mapOptional("PenaltyBreakOpenParenthesis",
1052 Style
.PenaltyBreakOpenParenthesis
);
1053 IO
.mapOptional("PenaltyBreakString", Style
.PenaltyBreakString
);
1054 IO
.mapOptional("PenaltyBreakTemplateDeclaration",
1055 Style
.PenaltyBreakTemplateDeclaration
);
1056 IO
.mapOptional("PenaltyExcessCharacter", Style
.PenaltyExcessCharacter
);
1057 IO
.mapOptional("PenaltyIndentedWhitespace",
1058 Style
.PenaltyIndentedWhitespace
);
1059 IO
.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1060 Style
.PenaltyReturnTypeOnItsOwnLine
);
1061 IO
.mapOptional("PointerAlignment", Style
.PointerAlignment
);
1062 IO
.mapOptional("PPIndentWidth", Style
.PPIndentWidth
);
1063 IO
.mapOptional("QualifierAlignment", Style
.QualifierAlignment
);
1064 // Default Order for Left/Right based Qualifier alignment.
1065 if (Style
.QualifierAlignment
== FormatStyle::QAS_Right
)
1066 Style
.QualifierOrder
= {"type", "const", "volatile"};
1067 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Left
)
1068 Style
.QualifierOrder
= {"const", "volatile", "type"};
1069 else if (Style
.QualifierAlignment
== FormatStyle::QAS_Custom
)
1070 IO
.mapOptional("QualifierOrder", Style
.QualifierOrder
);
1071 IO
.mapOptional("RawStringFormats", Style
.RawStringFormats
);
1072 IO
.mapOptional("ReferenceAlignment", Style
.ReferenceAlignment
);
1073 IO
.mapOptional("ReflowComments", Style
.ReflowComments
);
1074 IO
.mapOptional("RemoveBracesLLVM", Style
.RemoveBracesLLVM
);
1075 IO
.mapOptional("RemoveParentheses", Style
.RemoveParentheses
);
1076 IO
.mapOptional("RemoveSemicolon", Style
.RemoveSemicolon
);
1077 IO
.mapOptional("RequiresClausePosition", Style
.RequiresClausePosition
);
1078 IO
.mapOptional("RequiresExpressionIndentation",
1079 Style
.RequiresExpressionIndentation
);
1080 IO
.mapOptional("SeparateDefinitionBlocks", Style
.SeparateDefinitionBlocks
);
1081 IO
.mapOptional("ShortNamespaceLines", Style
.ShortNamespaceLines
);
1082 IO
.mapOptional("SortIncludes", Style
.SortIncludes
);
1083 IO
.mapOptional("SortJavaStaticImport", Style
.SortJavaStaticImport
);
1084 IO
.mapOptional("SortUsingDeclarations", Style
.SortUsingDeclarations
);
1085 IO
.mapOptional("SpaceAfterCStyleCast", Style
.SpaceAfterCStyleCast
);
1086 IO
.mapOptional("SpaceAfterLogicalNot", Style
.SpaceAfterLogicalNot
);
1087 IO
.mapOptional("SpaceAfterTemplateKeyword",
1088 Style
.SpaceAfterTemplateKeyword
);
1089 IO
.mapOptional("SpaceAroundPointerQualifiers",
1090 Style
.SpaceAroundPointerQualifiers
);
1091 IO
.mapOptional("SpaceBeforeAssignmentOperators",
1092 Style
.SpaceBeforeAssignmentOperators
);
1093 IO
.mapOptional("SpaceBeforeCaseColon", Style
.SpaceBeforeCaseColon
);
1094 IO
.mapOptional("SpaceBeforeCpp11BracedList",
1095 Style
.SpaceBeforeCpp11BracedList
);
1096 IO
.mapOptional("SpaceBeforeCtorInitializerColon",
1097 Style
.SpaceBeforeCtorInitializerColon
);
1098 IO
.mapOptional("SpaceBeforeInheritanceColon",
1099 Style
.SpaceBeforeInheritanceColon
);
1100 IO
.mapOptional("SpaceBeforeJsonColon", Style
.SpaceBeforeJsonColon
);
1101 IO
.mapOptional("SpaceBeforeParens", Style
.SpaceBeforeParens
);
1102 IO
.mapOptional("SpaceBeforeParensOptions", Style
.SpaceBeforeParensOptions
);
1103 IO
.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1104 Style
.SpaceBeforeRangeBasedForLoopColon
);
1105 IO
.mapOptional("SpaceBeforeSquareBrackets",
1106 Style
.SpaceBeforeSquareBrackets
);
1107 IO
.mapOptional("SpaceInEmptyBlock", Style
.SpaceInEmptyBlock
);
1108 IO
.mapOptional("SpacesBeforeTrailingComments",
1109 Style
.SpacesBeforeTrailingComments
);
1110 IO
.mapOptional("SpacesInAngles", Style
.SpacesInAngles
);
1111 IO
.mapOptional("SpacesInContainerLiterals",
1112 Style
.SpacesInContainerLiterals
);
1113 IO
.mapOptional("SpacesInLineCommentPrefix",
1114 Style
.SpacesInLineCommentPrefix
);
1115 IO
.mapOptional("SpacesInParens", Style
.SpacesInParens
);
1116 IO
.mapOptional("SpacesInParensOptions", Style
.SpacesInParensOptions
);
1117 IO
.mapOptional("SpacesInSquareBrackets", Style
.SpacesInSquareBrackets
);
1118 IO
.mapOptional("Standard", Style
.Standard
);
1119 IO
.mapOptional("StatementAttributeLikeMacros",
1120 Style
.StatementAttributeLikeMacros
);
1121 IO
.mapOptional("StatementMacros", Style
.StatementMacros
);
1122 IO
.mapOptional("TabWidth", Style
.TabWidth
);
1123 IO
.mapOptional("TypeNames", Style
.TypeNames
);
1124 IO
.mapOptional("TypenameMacros", Style
.TypenameMacros
);
1125 IO
.mapOptional("UseTab", Style
.UseTab
);
1126 IO
.mapOptional("VerilogBreakBetweenInstancePorts",
1127 Style
.VerilogBreakBetweenInstancePorts
);
1128 IO
.mapOptional("WhitespaceSensitiveMacros",
1129 Style
.WhitespaceSensitiveMacros
);
1131 // If AlwaysBreakAfterDefinitionReturnType was specified but
1132 // AlwaysBreakAfterReturnType was not, initialize the latter from the
1133 // former for backwards compatibility.
1134 if (Style
.AlwaysBreakAfterDefinitionReturnType
!= FormatStyle::DRTBS_None
&&
1135 Style
.AlwaysBreakAfterReturnType
== FormatStyle::RTBS_None
) {
1136 if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1137 FormatStyle::DRTBS_All
) {
1138 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1139 } else if (Style
.AlwaysBreakAfterDefinitionReturnType
==
1140 FormatStyle::DRTBS_TopLevel
) {
1141 Style
.AlwaysBreakAfterReturnType
=
1142 FormatStyle::RTBS_TopLevelDefinitions
;
1146 // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1147 // not, initialize the latter from the former for backwards compatibility.
1148 if (BreakBeforeInheritanceComma
&&
1149 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeColon
) {
1150 Style
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1153 // If BreakConstructorInitializersBeforeComma was specified but
1154 // BreakConstructorInitializers was not, initialize the latter from the
1155 // former for backwards compatibility.
1156 if (BreakConstructorInitializersBeforeComma
&&
1157 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
) {
1158 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1161 if (!IsGoogleOrChromium
) {
1162 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_BinPack
&&
1164 Style
.PackConstructorInitializers
= OnNextLine
1165 ? FormatStyle::PCIS_NextLine
1166 : FormatStyle::PCIS_CurrentLine
;
1168 } else if (Style
.PackConstructorInitializers
==
1169 FormatStyle::PCIS_NextLine
) {
1171 Style
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1172 else if (!OnNextLine
)
1173 Style
.PackConstructorInitializers
= FormatStyle::PCIS_CurrentLine
;
1176 if (Style
.LineEnding
== FormatStyle::LE_DeriveLF
) {
1177 if (!DeriveLineEnding
)
1178 Style
.LineEnding
= UseCRLF
? FormatStyle::LE_CRLF
: FormatStyle::LE_LF
;
1180 Style
.LineEnding
= FormatStyle::LE_DeriveCRLF
;
1183 if (Style
.SpacesInParens
!= FormatStyle::SIPO_Custom
&&
1184 (SpacesInParentheses
|| SpaceInEmptyParentheses
||
1185 SpacesInConditionalStatement
|| SpacesInCStyleCastParentheses
)) {
1186 if (SpacesInParentheses
) {
1187 // set all options except InCStyleCasts and InEmptyParentheses
1188 // to true for backward compatibility.
1189 Style
.SpacesInParensOptions
.InConditionalStatements
= true;
1190 Style
.SpacesInParensOptions
.InCStyleCasts
=
1191 SpacesInCStyleCastParentheses
;
1192 Style
.SpacesInParensOptions
.InEmptyParentheses
=
1193 SpaceInEmptyParentheses
;
1194 Style
.SpacesInParensOptions
.Other
= true;
1196 Style
.SpacesInParensOptions
= {};
1197 Style
.SpacesInParensOptions
.InConditionalStatements
=
1198 SpacesInConditionalStatement
;
1199 Style
.SpacesInParensOptions
.InCStyleCasts
=
1200 SpacesInCStyleCastParentheses
;
1201 Style
.SpacesInParensOptions
.InEmptyParentheses
=
1202 SpaceInEmptyParentheses
;
1204 Style
.SpacesInParens
= FormatStyle::SIPO_Custom
;
1209 // Allows to read vector<FormatStyle> while keeping default values.
1210 // IO.getContext() should contain a pointer to the FormatStyle structure, that
1211 // will be used to get default values for missing keys.
1212 // If the first element has no Language specified, it will be treated as the
1213 // default one for the following elements.
1214 template <> struct DocumentListTraits
<std::vector
<FormatStyle
>> {
1215 static size_t size(IO
&IO
, std::vector
<FormatStyle
> &Seq
) {
1218 static FormatStyle
&element(IO
&IO
, std::vector
<FormatStyle
> &Seq
,
1220 if (Index
>= Seq
.size()) {
1221 assert(Index
== Seq
.size());
1222 FormatStyle Template
;
1223 if (!Seq
.empty() && Seq
[0].Language
== FormatStyle::LK_None
) {
1226 Template
= *((const FormatStyle
*)IO
.getContext());
1227 Template
.Language
= FormatStyle::LK_None
;
1229 Seq
.resize(Index
+ 1, Template
);
1240 const std::error_category
&getParseCategory() {
1241 static const ParseErrorCategory C
{};
1244 std::error_code
make_error_code(ParseError e
) {
1245 return std::error_code(static_cast<int>(e
), getParseCategory());
1248 inline llvm::Error
make_string_error(const llvm::Twine
&Message
) {
1249 return llvm::make_error
<llvm::StringError
>(Message
,
1250 llvm::inconvertibleErrorCode());
1253 const char *ParseErrorCategory::name() const noexcept
{
1254 return "clang-format.parse_error";
1257 std::string
ParseErrorCategory::message(int EV
) const {
1258 switch (static_cast<ParseError
>(EV
)) {
1259 case ParseError::Success
:
1261 case ParseError::Error
:
1262 return "Invalid argument";
1263 case ParseError::Unsuitable
:
1264 return "Unsuitable";
1265 case ParseError::BinPackTrailingCommaConflict
:
1266 return "trailing comma insertion cannot be used with bin packing";
1267 case ParseError::InvalidQualifierSpecified
:
1268 return "Invalid qualifier specified in QualifierOrder";
1269 case ParseError::DuplicateQualifierSpecified
:
1270 return "Duplicate qualifier specified in QualifierOrder";
1271 case ParseError::MissingQualifierType
:
1272 return "Missing type in QualifierOrder";
1273 case ParseError::MissingQualifierOrder
:
1274 return "Missing QualifierOrder";
1276 llvm_unreachable("unexpected parse error");
1279 static void expandPresetsBraceWrapping(FormatStyle
&Expanded
) {
1280 if (Expanded
.BreakBeforeBraces
== FormatStyle::BS_Custom
)
1282 Expanded
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1283 /*AfterClass=*/false,
1284 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1285 /*AfterEnum=*/false,
1286 /*AfterFunction=*/false,
1287 /*AfterNamespace=*/false,
1288 /*AfterObjCDeclaration=*/false,
1289 /*AfterStruct=*/false,
1290 /*AfterUnion=*/false,
1291 /*AfterExternBlock=*/false,
1292 /*BeforeCatch=*/false,
1293 /*BeforeElse=*/false,
1294 /*BeforeLambdaBody=*/false,
1295 /*BeforeWhile=*/false,
1296 /*IndentBraces=*/false,
1297 /*SplitEmptyFunction=*/true,
1298 /*SplitEmptyRecord=*/true,
1299 /*SplitEmptyNamespace=*/true};
1300 switch (Expanded
.BreakBeforeBraces
) {
1301 case FormatStyle::BS_Linux
:
1302 Expanded
.BraceWrapping
.AfterClass
= true;
1303 Expanded
.BraceWrapping
.AfterFunction
= true;
1304 Expanded
.BraceWrapping
.AfterNamespace
= true;
1306 case FormatStyle::BS_Mozilla
:
1307 Expanded
.BraceWrapping
.AfterClass
= true;
1308 Expanded
.BraceWrapping
.AfterEnum
= true;
1309 Expanded
.BraceWrapping
.AfterFunction
= true;
1310 Expanded
.BraceWrapping
.AfterStruct
= true;
1311 Expanded
.BraceWrapping
.AfterUnion
= true;
1312 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1313 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1314 Expanded
.BraceWrapping
.SplitEmptyFunction
= true;
1315 Expanded
.BraceWrapping
.SplitEmptyRecord
= false;
1317 case FormatStyle::BS_Stroustrup
:
1318 Expanded
.BraceWrapping
.AfterFunction
= true;
1319 Expanded
.BraceWrapping
.BeforeCatch
= true;
1320 Expanded
.BraceWrapping
.BeforeElse
= true;
1322 case FormatStyle::BS_Allman
:
1323 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1324 Expanded
.BraceWrapping
.AfterClass
= true;
1325 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1326 Expanded
.BraceWrapping
.AfterEnum
= true;
1327 Expanded
.BraceWrapping
.AfterFunction
= true;
1328 Expanded
.BraceWrapping
.AfterNamespace
= true;
1329 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1330 Expanded
.BraceWrapping
.AfterStruct
= true;
1331 Expanded
.BraceWrapping
.AfterUnion
= true;
1332 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1333 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1334 Expanded
.BraceWrapping
.BeforeCatch
= true;
1335 Expanded
.BraceWrapping
.BeforeElse
= true;
1336 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1338 case FormatStyle::BS_Whitesmiths
:
1339 Expanded
.BraceWrapping
.AfterCaseLabel
= true;
1340 Expanded
.BraceWrapping
.AfterClass
= true;
1341 Expanded
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1342 Expanded
.BraceWrapping
.AfterEnum
= true;
1343 Expanded
.BraceWrapping
.AfterFunction
= true;
1344 Expanded
.BraceWrapping
.AfterNamespace
= true;
1345 Expanded
.BraceWrapping
.AfterObjCDeclaration
= true;
1346 Expanded
.BraceWrapping
.AfterStruct
= true;
1347 Expanded
.BraceWrapping
.AfterExternBlock
= true;
1348 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1349 Expanded
.BraceWrapping
.BeforeCatch
= true;
1350 Expanded
.BraceWrapping
.BeforeElse
= true;
1351 Expanded
.BraceWrapping
.BeforeLambdaBody
= true;
1353 case FormatStyle::BS_GNU
:
1354 Expanded
.BraceWrapping
= {
1355 /*AfterCaseLabel=*/true,
1356 /*AfterClass=*/true,
1357 /*AfterControlStatement=*/FormatStyle::BWACS_Always
,
1359 /*AfterFunction=*/true,
1360 /*AfterNamespace=*/true,
1361 /*AfterObjCDeclaration=*/true,
1362 /*AfterStruct=*/true,
1363 /*AfterUnion=*/true,
1364 /*AfterExternBlock=*/true,
1365 /*BeforeCatch=*/true,
1366 /*BeforeElse=*/true,
1367 /*BeforeLambdaBody=*/false,
1368 /*BeforeWhile=*/true,
1369 /*IndentBraces=*/true,
1370 /*SplitEmptyFunction=*/true,
1371 /*SplitEmptyRecord=*/true,
1372 /*SplitEmptyNamespace=*/true};
1373 Expanded
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1375 case FormatStyle::BS_WebKit
:
1376 Expanded
.BraceWrapping
.AfterFunction
= true;
1383 static void expandPresetsSpaceBeforeParens(FormatStyle
&Expanded
) {
1384 if (Expanded
.SpaceBeforeParens
== FormatStyle::SBPO_Custom
)
1387 Expanded
.SpaceBeforeParensOptions
= {};
1389 switch (Expanded
.SpaceBeforeParens
) {
1390 case FormatStyle::SBPO_Never
:
1391 Expanded
.SpaceBeforeParensOptions
.AfterPlacementOperator
=
1392 FormatStyle::SpaceBeforeParensCustom::APO_Never
;
1394 case FormatStyle::SBPO_ControlStatements
:
1395 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1396 Expanded
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1397 Expanded
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1399 case FormatStyle::SBPO_ControlStatementsExceptControlMacros
:
1400 Expanded
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1402 case FormatStyle::SBPO_NonEmptyParentheses
:
1403 Expanded
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
= true;
1405 case FormatStyle::SBPO_Always
:
1412 static void expandPresetsSpacesInParens(FormatStyle
&Expanded
) {
1413 if (Expanded
.SpacesInParens
== FormatStyle::SIPO_Custom
)
1415 assert(Expanded
.SpacesInParens
== FormatStyle::SIPO_Never
);
1417 Expanded
.SpacesInParensOptions
= {};
1420 FormatStyle
getLLVMStyle(FormatStyle::LanguageKind Language
) {
1421 FormatStyle LLVMStyle
;
1422 LLVMStyle
.InheritsParentConfig
= false;
1423 LLVMStyle
.Language
= Language
;
1424 LLVMStyle
.AccessModifierOffset
= -2;
1425 LLVMStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Right
;
1426 LLVMStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_Align
;
1427 LLVMStyle
.AlignArrayOfStructures
= FormatStyle::AIAS_None
;
1428 LLVMStyle
.AlignOperands
= FormatStyle::OAS_Align
;
1429 LLVMStyle
.AlignConsecutiveAssignments
= {};
1430 LLVMStyle
.AlignConsecutiveAssignments
.Enabled
= false;
1431 LLVMStyle
.AlignConsecutiveAssignments
.AcrossEmptyLines
= false;
1432 LLVMStyle
.AlignConsecutiveAssignments
.AcrossComments
= false;
1433 LLVMStyle
.AlignConsecutiveAssignments
.AlignCompound
= false;
1434 LLVMStyle
.AlignConsecutiveAssignments
.PadOperators
= true;
1435 LLVMStyle
.AlignConsecutiveBitFields
= {};
1436 LLVMStyle
.AlignConsecutiveDeclarations
= {};
1437 LLVMStyle
.AlignConsecutiveMacros
= {};
1438 LLVMStyle
.AlignConsecutiveShortCaseStatements
= {};
1439 LLVMStyle
.AlignTrailingComments
= {};
1440 LLVMStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Always
;
1441 LLVMStyle
.AlignTrailingComments
.OverEmptyLines
= 0;
1442 LLVMStyle
.AllowAllArgumentsOnNextLine
= true;
1443 LLVMStyle
.AllowAllParametersOfDeclarationOnNextLine
= true;
1444 LLVMStyle
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Never
;
1445 LLVMStyle
.AllowShortCaseLabelsOnASingleLine
= false;
1446 LLVMStyle
.AllowShortCompoundRequirementOnASingleLine
= true;
1447 LLVMStyle
.AllowShortEnumsOnASingleLine
= true;
1448 LLVMStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_All
;
1449 LLVMStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1450 LLVMStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_All
;
1451 LLVMStyle
.AllowShortLoopsOnASingleLine
= false;
1452 LLVMStyle
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_None
;
1453 LLVMStyle
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1454 LLVMStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1455 LLVMStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_MultiLine
;
1456 LLVMStyle
.AttributeMacros
.push_back("__capability");
1457 LLVMStyle
.BitFieldColonSpacing
= FormatStyle::BFCS_Both
;
1458 LLVMStyle
.BinPackArguments
= true;
1459 LLVMStyle
.BinPackParameters
= true;
1460 LLVMStyle
.BracedInitializerIndentWidth
= std::nullopt
;
1461 LLVMStyle
.BraceWrapping
= {/*AfterCaseLabel=*/false,
1462 /*AfterClass=*/false,
1463 /*AfterControlStatement=*/FormatStyle::BWACS_Never
,
1464 /*AfterEnum=*/false,
1465 /*AfterFunction=*/false,
1466 /*AfterNamespace=*/false,
1467 /*AfterObjCDeclaration=*/false,
1468 /*AfterStruct=*/false,
1469 /*AfterUnion=*/false,
1470 /*AfterExternBlock=*/false,
1471 /*BeforeCatch=*/false,
1472 /*BeforeElse=*/false,
1473 /*BeforeLambdaBody=*/false,
1474 /*BeforeWhile=*/false,
1475 /*IndentBraces=*/false,
1476 /*SplitEmptyFunction=*/true,
1477 /*SplitEmptyRecord=*/true,
1478 /*SplitEmptyNamespace=*/true};
1479 LLVMStyle
.BreakAfterAttributes
= FormatStyle::ABS_Leave
;
1480 LLVMStyle
.BreakAfterJavaFieldAnnotations
= false;
1481 LLVMStyle
.BreakArrays
= true;
1482 LLVMStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_None
;
1483 LLVMStyle
.BreakBeforeBraces
= FormatStyle::BS_Attach
;
1484 LLVMStyle
.BreakBeforeConceptDeclarations
= FormatStyle::BBCDS_Always
;
1485 LLVMStyle
.BreakBeforeInlineASMColon
= FormatStyle::BBIAS_OnlyMultiline
;
1486 LLVMStyle
.AllowBreakBeforeNoexceptSpecifier
= FormatStyle::BBNSS_Never
;
1487 LLVMStyle
.BreakBeforeTernaryOperators
= true;
1488 LLVMStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeColon
;
1489 LLVMStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeColon
;
1490 LLVMStyle
.BreakStringLiterals
= true;
1491 LLVMStyle
.ColumnLimit
= 80;
1492 LLVMStyle
.CommentPragmas
= "^ IWYU pragma:";
1493 LLVMStyle
.CompactNamespaces
= false;
1494 LLVMStyle
.ConstructorInitializerIndentWidth
= 4;
1495 LLVMStyle
.ContinuationIndentWidth
= 4;
1496 LLVMStyle
.Cpp11BracedListStyle
= true;
1497 LLVMStyle
.DerivePointerAlignment
= false;
1498 LLVMStyle
.DisableFormat
= false;
1499 LLVMStyle
.EmptyLineAfterAccessModifier
= FormatStyle::ELAAMS_Never
;
1500 LLVMStyle
.EmptyLineBeforeAccessModifier
= FormatStyle::ELBAMS_LogicalBlock
;
1501 LLVMStyle
.ExperimentalAutoDetectBinPacking
= false;
1502 LLVMStyle
.FixNamespaceComments
= true;
1503 LLVMStyle
.ForEachMacros
.push_back("foreach");
1504 LLVMStyle
.ForEachMacros
.push_back("Q_FOREACH");
1505 LLVMStyle
.ForEachMacros
.push_back("BOOST_FOREACH");
1506 LLVMStyle
.IfMacros
.push_back("KJ_IF_MAYBE");
1507 LLVMStyle
.IncludeStyle
.IncludeCategories
= {
1508 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1509 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1510 {".*", 1, 0, false}};
1511 LLVMStyle
.IncludeStyle
.IncludeIsMainRegex
= "(Test)?$";
1512 LLVMStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Preserve
;
1513 LLVMStyle
.IndentAccessModifiers
= false;
1514 LLVMStyle
.IndentCaseLabels
= false;
1515 LLVMStyle
.IndentCaseBlocks
= false;
1516 LLVMStyle
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1517 LLVMStyle
.IndentGotoLabels
= true;
1518 LLVMStyle
.IndentPPDirectives
= FormatStyle::PPDIS_None
;
1519 LLVMStyle
.IndentRequiresClause
= true;
1520 LLVMStyle
.IndentWidth
= 2;
1521 LLVMStyle
.IndentWrappedFunctionNames
= false;
1522 LLVMStyle
.InsertBraces
= false;
1523 LLVMStyle
.InsertNewlineAtEOF
= false;
1524 LLVMStyle
.InsertTrailingCommas
= FormatStyle::TCS_None
;
1525 LLVMStyle
.IntegerLiteralSeparator
= {
1526 /*Binary=*/0, /*BinaryMinDigits=*/0,
1527 /*Decimal=*/0, /*DecimalMinDigits=*/0,
1528 /*Hex=*/0, /*HexMinDigits=*/0};
1529 LLVMStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Leave
;
1530 LLVMStyle
.JavaScriptWrapImports
= true;
1531 LLVMStyle
.KeepEmptyLinesAtEOF
= false;
1532 LLVMStyle
.KeepEmptyLinesAtTheStartOfBlocks
= true;
1533 LLVMStyle
.LambdaBodyIndentation
= FormatStyle::LBI_Signature
;
1534 LLVMStyle
.LineEnding
= FormatStyle::LE_DeriveLF
;
1535 LLVMStyle
.MaxEmptyLinesToKeep
= 1;
1536 LLVMStyle
.NamespaceIndentation
= FormatStyle::NI_None
;
1537 LLVMStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Auto
;
1538 LLVMStyle
.ObjCBlockIndentWidth
= 2;
1539 LLVMStyle
.ObjCBreakBeforeNestedBlockParam
= true;
1540 LLVMStyle
.ObjCSpaceAfterProperty
= false;
1541 LLVMStyle
.ObjCSpaceBeforeProtocolList
= true;
1542 LLVMStyle
.PackConstructorInitializers
= FormatStyle::PCIS_BinPack
;
1543 LLVMStyle
.PointerAlignment
= FormatStyle::PAS_Right
;
1544 LLVMStyle
.PPIndentWidth
= -1;
1545 LLVMStyle
.QualifierAlignment
= FormatStyle::QAS_Leave
;
1546 LLVMStyle
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
1547 LLVMStyle
.ReflowComments
= true;
1548 LLVMStyle
.RemoveBracesLLVM
= false;
1549 LLVMStyle
.RemoveParentheses
= FormatStyle::RPS_Leave
;
1550 LLVMStyle
.RemoveSemicolon
= false;
1551 LLVMStyle
.RequiresClausePosition
= FormatStyle::RCPS_OwnLine
;
1552 LLVMStyle
.RequiresExpressionIndentation
= FormatStyle::REI_OuterScope
;
1553 LLVMStyle
.SeparateDefinitionBlocks
= FormatStyle::SDS_Leave
;
1554 LLVMStyle
.ShortNamespaceLines
= 1;
1555 LLVMStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1556 LLVMStyle
.SortJavaStaticImport
= FormatStyle::SJSIO_Before
;
1557 LLVMStyle
.SortUsingDeclarations
= FormatStyle::SUD_LexicographicNumeric
;
1558 LLVMStyle
.SpaceAfterCStyleCast
= false;
1559 LLVMStyle
.SpaceAfterLogicalNot
= false;
1560 LLVMStyle
.SpaceAfterTemplateKeyword
= true;
1561 LLVMStyle
.SpaceAroundPointerQualifiers
= FormatStyle::SAPQ_Default
;
1562 LLVMStyle
.SpaceBeforeCaseColon
= false;
1563 LLVMStyle
.SpaceBeforeCtorInitializerColon
= true;
1564 LLVMStyle
.SpaceBeforeInheritanceColon
= true;
1565 LLVMStyle
.SpaceBeforeJsonColon
= false;
1566 LLVMStyle
.SpaceBeforeParens
= FormatStyle::SBPO_ControlStatements
;
1567 LLVMStyle
.SpaceBeforeParensOptions
= {};
1568 LLVMStyle
.SpaceBeforeParensOptions
.AfterControlStatements
= true;
1569 LLVMStyle
.SpaceBeforeParensOptions
.AfterForeachMacros
= true;
1570 LLVMStyle
.SpaceBeforeParensOptions
.AfterIfMacros
= true;
1571 LLVMStyle
.SpaceBeforeRangeBasedForLoopColon
= true;
1572 LLVMStyle
.SpaceBeforeAssignmentOperators
= true;
1573 LLVMStyle
.SpaceBeforeCpp11BracedList
= false;
1574 LLVMStyle
.SpaceBeforeSquareBrackets
= false;
1575 LLVMStyle
.SpaceInEmptyBlock
= false;
1576 LLVMStyle
.SpacesBeforeTrailingComments
= 1;
1577 LLVMStyle
.SpacesInAngles
= FormatStyle::SIAS_Never
;
1578 LLVMStyle
.SpacesInContainerLiterals
= true;
1579 LLVMStyle
.SpacesInLineCommentPrefix
= {/*Minimum=*/1, /*Maximum=*/-1u};
1580 LLVMStyle
.SpacesInParens
= FormatStyle::SIPO_Never
;
1581 LLVMStyle
.SpacesInSquareBrackets
= false;
1582 LLVMStyle
.Standard
= FormatStyle::LS_Latest
;
1583 LLVMStyle
.StatementAttributeLikeMacros
.push_back("Q_EMIT");
1584 LLVMStyle
.StatementMacros
.push_back("Q_UNUSED");
1585 LLVMStyle
.StatementMacros
.push_back("QT_REQUIRE_VERSION");
1586 LLVMStyle
.TabWidth
= 8;
1587 LLVMStyle
.UseTab
= FormatStyle::UT_Never
;
1588 LLVMStyle
.VerilogBreakBetweenInstancePorts
= true;
1589 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("BOOST_PP_STRINGIZE");
1590 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("CF_SWIFT_NAME");
1591 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("NS_SWIFT_NAME");
1592 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("PP_STRINGIZE");
1593 LLVMStyle
.WhitespaceSensitiveMacros
.push_back("STRINGIZE");
1595 LLVMStyle
.PenaltyBreakAssignment
= prec::Assignment
;
1596 LLVMStyle
.PenaltyBreakComment
= 300;
1597 LLVMStyle
.PenaltyBreakFirstLessLess
= 120;
1598 LLVMStyle
.PenaltyBreakString
= 1000;
1599 LLVMStyle
.PenaltyExcessCharacter
= 1000000;
1600 LLVMStyle
.PenaltyReturnTypeOnItsOwnLine
= 60;
1601 LLVMStyle
.PenaltyBreakBeforeFirstCallParameter
= 19;
1602 LLVMStyle
.PenaltyBreakOpenParenthesis
= 0;
1603 LLVMStyle
.PenaltyBreakTemplateDeclaration
= prec::Relational
;
1604 LLVMStyle
.PenaltyIndentedWhitespace
= 0;
1606 // Defaults that differ when not C++.
1608 case FormatStyle::LK_TableGen
:
1609 LLVMStyle
.SpacesInContainerLiterals
= false;
1611 case FormatStyle::LK_Json
:
1612 LLVMStyle
.ColumnLimit
= 0;
1614 case FormatStyle::LK_Verilog
:
1615 LLVMStyle
.IndentCaseLabels
= true;
1616 LLVMStyle
.SpacesInContainerLiterals
= false;
1625 FormatStyle
getGoogleStyle(FormatStyle::LanguageKind Language
) {
1626 if (Language
== FormatStyle::LK_TextProto
) {
1627 FormatStyle GoogleStyle
= getGoogleStyle(FormatStyle::LK_Proto
);
1628 GoogleStyle
.Language
= FormatStyle::LK_TextProto
;
1633 FormatStyle GoogleStyle
= getLLVMStyle(Language
);
1635 GoogleStyle
.AccessModifierOffset
= -1;
1636 GoogleStyle
.AlignEscapedNewlines
= FormatStyle::ENAS_Left
;
1637 GoogleStyle
.AllowShortIfStatementsOnASingleLine
=
1638 FormatStyle::SIS_WithoutElse
;
1639 GoogleStyle
.AllowShortLoopsOnASingleLine
= true;
1640 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= true;
1641 GoogleStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1642 GoogleStyle
.DerivePointerAlignment
= true;
1643 GoogleStyle
.IncludeStyle
.IncludeCategories
= {{"^<ext/.*\\.h>", 2, 0, false},
1644 {"^<.*\\.h>", 1, 0, false},
1645 {"^<.*", 2, 0, false},
1646 {".*", 3, 0, false}};
1647 GoogleStyle
.IncludeStyle
.IncludeIsMainRegex
= "([-_](test|unittest))?$";
1648 GoogleStyle
.IncludeStyle
.IncludeBlocks
= tooling::IncludeStyle::IBS_Regroup
;
1649 GoogleStyle
.IndentCaseLabels
= true;
1650 GoogleStyle
.KeepEmptyLinesAtTheStartOfBlocks
= false;
1651 GoogleStyle
.ObjCBinPackProtocolList
= FormatStyle::BPS_Never
;
1652 GoogleStyle
.ObjCSpaceAfterProperty
= false;
1653 GoogleStyle
.ObjCSpaceBeforeProtocolList
= true;
1654 GoogleStyle
.PackConstructorInitializers
= FormatStyle::PCIS_NextLine
;
1655 GoogleStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1656 GoogleStyle
.RawStringFormats
= {
1658 FormatStyle::LK_Cpp
,
1669 /*EnclosingFunctionNames=*/
1671 /*CanonicalDelimiter=*/"",
1672 /*BasedOnStyle=*/"google",
1675 FormatStyle::LK_TextProto
,
1683 /*EnclosingFunctionNames=*/
1687 "PARSE_PARTIAL_TEXT_PROTO",
1691 "ParseTextProtoOrDie",
1693 "ParsePartialTestProto",
1695 /*CanonicalDelimiter=*/"pb",
1696 /*BasedOnStyle=*/"google",
1699 GoogleStyle
.SpacesBeforeTrailingComments
= 2;
1700 GoogleStyle
.Standard
= FormatStyle::LS_Auto
;
1702 GoogleStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1703 GoogleStyle
.PenaltyBreakBeforeFirstCallParameter
= 1;
1705 if (Language
== FormatStyle::LK_Java
) {
1706 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1707 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1708 GoogleStyle
.AlignTrailingComments
= {};
1709 GoogleStyle
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1710 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1711 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1712 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1713 GoogleStyle
.BreakBeforeBinaryOperators
= FormatStyle::BOS_NonAssignment
;
1714 GoogleStyle
.ColumnLimit
= 100;
1715 GoogleStyle
.SpaceAfterCStyleCast
= true;
1716 GoogleStyle
.SpacesBeforeTrailingComments
= 1;
1717 } else if (Language
== FormatStyle::LK_JavaScript
) {
1718 GoogleStyle
.AlignAfterOpenBracket
= FormatStyle::BAS_AlwaysBreak
;
1719 GoogleStyle
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1720 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1721 // TODO: still under discussion whether to switch to SLS_All.
1722 GoogleStyle
.AllowShortLambdasOnASingleLine
= FormatStyle::SLS_Empty
;
1723 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1724 GoogleStyle
.BreakBeforeTernaryOperators
= false;
1725 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1726 // commonly followed by overlong URLs.
1727 GoogleStyle
.CommentPragmas
= "(taze:|^/[ \t]*<|tslint:|@see)";
1728 // TODO: enable once decided, in particular re disabling bin packing.
1729 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1730 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1731 GoogleStyle
.MaxEmptyLinesToKeep
= 3;
1732 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1733 GoogleStyle
.SpacesInContainerLiterals
= false;
1734 GoogleStyle
.JavaScriptQuotes
= FormatStyle::JSQS_Single
;
1735 GoogleStyle
.JavaScriptWrapImports
= false;
1736 } else if (Language
== FormatStyle::LK_Proto
) {
1737 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1738 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1739 GoogleStyle
.SpacesInContainerLiterals
= false;
1740 GoogleStyle
.Cpp11BracedListStyle
= false;
1741 // This affects protocol buffer options specifications and text protos.
1742 // Text protos are currently mostly formatted inside C++ raw string literals
1743 // and often the current breaking behavior of string literals is not
1744 // beneficial there. Investigate turning this on once proper string reflow
1745 // has been implemented.
1746 GoogleStyle
.BreakStringLiterals
= false;
1747 } else if (Language
== FormatStyle::LK_ObjC
) {
1748 GoogleStyle
.AlwaysBreakBeforeMultilineStrings
= false;
1749 GoogleStyle
.ColumnLimit
= 100;
1750 // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1751 // relationship between ObjC standard library headers and other heades,
1753 GoogleStyle
.IncludeStyle
.IncludeBlocks
=
1754 tooling::IncludeStyle::IBS_Preserve
;
1755 } else if (Language
== FormatStyle::LK_CSharp
) {
1756 GoogleStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Empty
;
1757 GoogleStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1758 GoogleStyle
.BreakStringLiterals
= false;
1759 GoogleStyle
.ColumnLimit
= 100;
1760 GoogleStyle
.NamespaceIndentation
= FormatStyle::NI_All
;
1766 FormatStyle
getChromiumStyle(FormatStyle::LanguageKind Language
) {
1767 FormatStyle ChromiumStyle
= getGoogleStyle(Language
);
1769 // Disable include reordering across blocks in Chromium code.
1770 // - clang-format tries to detect that foo.h is the "main" header for
1771 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1772 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1773 // _private.cc, _impl.cc etc) in different permutations
1774 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1775 // better default for Chromium code.
1776 // - The default for .cc and .mm files is different (r357695) for Google style
1777 // for the same reason. The plan is to unify this again once the main
1778 // header detection works for Google's ObjC code, but this hasn't happened
1779 // yet. Since Chromium has some ObjC code, switching Chromium is blocked
1781 // - Finally, "If include reordering is harmful, put things in different
1782 // blocks to prevent it" has been a recommendation for a long time that
1783 // people are used to. We'll need a dev education push to change this to
1784 // "If include reordering is harmful, put things in a different block and
1785 // _prepend that with a comment_ to prevent it" before changing behavior.
1786 ChromiumStyle
.IncludeStyle
.IncludeBlocks
=
1787 tooling::IncludeStyle::IBS_Preserve
;
1789 if (Language
== FormatStyle::LK_Java
) {
1790 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
=
1791 FormatStyle::SIS_WithoutElse
;
1792 ChromiumStyle
.BreakAfterJavaFieldAnnotations
= true;
1793 ChromiumStyle
.ContinuationIndentWidth
= 8;
1794 ChromiumStyle
.IndentWidth
= 4;
1795 // See styleguide for import groups:
1796 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1797 ChromiumStyle
.JavaImportGroups
= {
1804 "com.google.android.apps.chrome",
1809 ChromiumStyle
.SortIncludes
= FormatStyle::SI_CaseSensitive
;
1810 } else if (Language
== FormatStyle::LK_JavaScript
) {
1811 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1812 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1814 ChromiumStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1815 ChromiumStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1816 ChromiumStyle
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1817 ChromiumStyle
.AllowShortLoopsOnASingleLine
= false;
1818 ChromiumStyle
.BinPackParameters
= false;
1819 ChromiumStyle
.DerivePointerAlignment
= false;
1820 if (Language
== FormatStyle::LK_ObjC
)
1821 ChromiumStyle
.ColumnLimit
= 80;
1823 return ChromiumStyle
;
1826 FormatStyle
getMozillaStyle() {
1827 FormatStyle MozillaStyle
= getLLVMStyle();
1828 MozillaStyle
.AllowAllParametersOfDeclarationOnNextLine
= false;
1829 MozillaStyle
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_Inline
;
1830 MozillaStyle
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_TopLevel
;
1831 MozillaStyle
.AlwaysBreakAfterDefinitionReturnType
=
1832 FormatStyle::DRTBS_TopLevel
;
1833 MozillaStyle
.AlwaysBreakTemplateDeclarations
= FormatStyle::BTDS_Yes
;
1834 MozillaStyle
.BinPackParameters
= false;
1835 MozillaStyle
.BinPackArguments
= false;
1836 MozillaStyle
.BreakBeforeBraces
= FormatStyle::BS_Mozilla
;
1837 MozillaStyle
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1838 MozillaStyle
.BreakInheritanceList
= FormatStyle::BILS_BeforeComma
;
1839 MozillaStyle
.ConstructorInitializerIndentWidth
= 2;
1840 MozillaStyle
.ContinuationIndentWidth
= 2;
1841 MozillaStyle
.Cpp11BracedListStyle
= false;
1842 MozillaStyle
.FixNamespaceComments
= false;
1843 MozillaStyle
.IndentCaseLabels
= true;
1844 MozillaStyle
.ObjCSpaceAfterProperty
= true;
1845 MozillaStyle
.ObjCSpaceBeforeProtocolList
= false;
1846 MozillaStyle
.PenaltyReturnTypeOnItsOwnLine
= 200;
1847 MozillaStyle
.PointerAlignment
= FormatStyle::PAS_Left
;
1848 MozillaStyle
.SpaceAfterTemplateKeyword
= false;
1849 return MozillaStyle
;
1852 FormatStyle
getWebKitStyle() {
1853 FormatStyle Style
= getLLVMStyle();
1854 Style
.AccessModifierOffset
= -4;
1855 Style
.AlignAfterOpenBracket
= FormatStyle::BAS_DontAlign
;
1856 Style
.AlignOperands
= FormatStyle::OAS_DontAlign
;
1857 Style
.AlignTrailingComments
= {};
1858 Style
.AlignTrailingComments
.Kind
= FormatStyle::TCAS_Never
;
1859 Style
.AllowShortBlocksOnASingleLine
= FormatStyle::SBS_Empty
;
1860 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1861 Style
.BreakBeforeBraces
= FormatStyle::BS_WebKit
;
1862 Style
.BreakConstructorInitializers
= FormatStyle::BCIS_BeforeComma
;
1863 Style
.Cpp11BracedListStyle
= false;
1864 Style
.ColumnLimit
= 0;
1865 Style
.FixNamespaceComments
= false;
1866 Style
.IndentWidth
= 4;
1867 Style
.NamespaceIndentation
= FormatStyle::NI_Inner
;
1868 Style
.ObjCBlockIndentWidth
= 4;
1869 Style
.ObjCSpaceAfterProperty
= true;
1870 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
1871 Style
.SpaceBeforeCpp11BracedList
= true;
1872 Style
.SpaceInEmptyBlock
= true;
1876 FormatStyle
getGNUStyle() {
1877 FormatStyle Style
= getLLVMStyle();
1878 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_All
;
1879 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_AllDefinitions
;
1880 Style
.BreakBeforeBinaryOperators
= FormatStyle::BOS_All
;
1881 Style
.BreakBeforeBraces
= FormatStyle::BS_GNU
;
1882 Style
.BreakBeforeTernaryOperators
= true;
1883 Style
.Cpp11BracedListStyle
= false;
1884 Style
.ColumnLimit
= 79;
1885 Style
.FixNamespaceComments
= false;
1886 Style
.SpaceBeforeParens
= FormatStyle::SBPO_Always
;
1887 Style
.Standard
= FormatStyle::LS_Cpp03
;
1891 FormatStyle
getMicrosoftStyle(FormatStyle::LanguageKind Language
) {
1892 FormatStyle Style
= getLLVMStyle(Language
);
1893 Style
.ColumnLimit
= 120;
1895 Style
.IndentWidth
= 4;
1896 Style
.UseTab
= FormatStyle::UT_Never
;
1897 Style
.BreakBeforeBraces
= FormatStyle::BS_Custom
;
1898 Style
.BraceWrapping
.AfterClass
= true;
1899 Style
.BraceWrapping
.AfterControlStatement
= FormatStyle::BWACS_Always
;
1900 Style
.BraceWrapping
.AfterEnum
= true;
1901 Style
.BraceWrapping
.AfterFunction
= true;
1902 Style
.BraceWrapping
.AfterNamespace
= true;
1903 Style
.BraceWrapping
.AfterObjCDeclaration
= true;
1904 Style
.BraceWrapping
.AfterStruct
= true;
1905 Style
.BraceWrapping
.AfterExternBlock
= true;
1906 Style
.IndentExternBlock
= FormatStyle::IEBS_AfterExternBlock
;
1907 Style
.BraceWrapping
.BeforeCatch
= true;
1908 Style
.BraceWrapping
.BeforeElse
= true;
1909 Style
.BraceWrapping
.BeforeWhile
= false;
1910 Style
.PenaltyReturnTypeOnItsOwnLine
= 1000;
1911 Style
.AllowShortEnumsOnASingleLine
= false;
1912 Style
.AllowShortFunctionsOnASingleLine
= FormatStyle::SFS_None
;
1913 Style
.AllowShortCaseLabelsOnASingleLine
= false;
1914 Style
.AllowShortIfStatementsOnASingleLine
= FormatStyle::SIS_Never
;
1915 Style
.AllowShortLoopsOnASingleLine
= false;
1916 Style
.AlwaysBreakAfterDefinitionReturnType
= FormatStyle::DRTBS_None
;
1917 Style
.AlwaysBreakAfterReturnType
= FormatStyle::RTBS_None
;
1921 FormatStyle
getClangFormatStyle() {
1922 FormatStyle Style
= getLLVMStyle();
1923 Style
.InsertBraces
= true;
1924 Style
.InsertNewlineAtEOF
= true;
1925 Style
.LineEnding
= FormatStyle::LE_LF
;
1926 Style
.RemoveBracesLLVM
= true;
1927 Style
.RemoveParentheses
= FormatStyle::RPS_ReturnStatement
;
1931 FormatStyle
getNoStyle() {
1932 FormatStyle NoStyle
= getLLVMStyle();
1933 NoStyle
.DisableFormat
= true;
1934 NoStyle
.SortIncludes
= FormatStyle::SI_Never
;
1935 NoStyle
.SortUsingDeclarations
= FormatStyle::SUD_Never
;
1939 bool getPredefinedStyle(StringRef Name
, FormatStyle::LanguageKind Language
,
1940 FormatStyle
*Style
) {
1941 if (Name
.equals_insensitive("llvm"))
1942 *Style
= getLLVMStyle(Language
);
1943 else if (Name
.equals_insensitive("chromium"))
1944 *Style
= getChromiumStyle(Language
);
1945 else if (Name
.equals_insensitive("mozilla"))
1946 *Style
= getMozillaStyle();
1947 else if (Name
.equals_insensitive("google"))
1948 *Style
= getGoogleStyle(Language
);
1949 else if (Name
.equals_insensitive("webkit"))
1950 *Style
= getWebKitStyle();
1951 else if (Name
.equals_insensitive("gnu"))
1952 *Style
= getGNUStyle();
1953 else if (Name
.equals_insensitive("microsoft"))
1954 *Style
= getMicrosoftStyle(Language
);
1955 else if (Name
.equals_insensitive("clang-format"))
1956 *Style
= getClangFormatStyle();
1957 else if (Name
.equals_insensitive("none"))
1958 *Style
= getNoStyle();
1959 else if (Name
.equals_insensitive("inheritparentconfig"))
1960 Style
->InheritsParentConfig
= true;
1964 Style
->Language
= Language
;
1968 ParseError
validateQualifierOrder(FormatStyle
*Style
) {
1969 // If its empty then it means don't do anything.
1970 if (Style
->QualifierOrder
.empty())
1971 return ParseError::MissingQualifierOrder
;
1973 // Ensure the list contains only currently valid qualifiers.
1974 for (const auto &Qualifier
: Style
->QualifierOrder
) {
1975 if (Qualifier
== "type")
1978 LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier
);
1979 if (token
== tok::identifier
)
1980 return ParseError::InvalidQualifierSpecified
;
1983 // Ensure the list is unique (no duplicates).
1984 std::set
<std::string
> UniqueQualifiers(Style
->QualifierOrder
.begin(),
1985 Style
->QualifierOrder
.end());
1986 if (Style
->QualifierOrder
.size() != UniqueQualifiers
.size()) {
1987 LLVM_DEBUG(llvm::dbgs()
1988 << "Duplicate Qualifiers " << Style
->QualifierOrder
.size()
1989 << " vs " << UniqueQualifiers
.size() << "\n");
1990 return ParseError::DuplicateQualifierSpecified
;
1993 // Ensure the list has 'type' in it.
1994 if (!llvm::is_contained(Style
->QualifierOrder
, "type"))
1995 return ParseError::MissingQualifierType
;
1997 return ParseError::Success
;
2000 std::error_code
parseConfiguration(llvm::MemoryBufferRef Config
,
2001 FormatStyle
*Style
, bool AllowUnknownOptions
,
2002 llvm::SourceMgr::DiagHandlerTy DiagHandler
,
2003 void *DiagHandlerCtxt
) {
2005 FormatStyle::LanguageKind Language
= Style
->Language
;
2006 assert(Language
!= FormatStyle::LK_None
);
2007 if (Config
.getBuffer().trim().empty())
2008 return make_error_code(ParseError::Success
);
2009 Style
->StyleSet
.Clear();
2010 std::vector
<FormatStyle
> Styles
;
2011 llvm::yaml::Input
Input(Config
, /*Ctxt=*/nullptr, DiagHandler
,
2013 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
2014 // values for the fields, keys for which are missing from the configuration.
2015 // Mapping also uses the context to get the language to find the correct
2017 Input
.setContext(Style
);
2018 Input
.setAllowUnknownKeys(AllowUnknownOptions
);
2021 return Input
.error();
2023 for (unsigned i
= 0; i
< Styles
.size(); ++i
) {
2024 // Ensures that only the first configuration can skip the Language option.
2025 if (Styles
[i
].Language
== FormatStyle::LK_None
&& i
!= 0)
2026 return make_error_code(ParseError::Error
);
2027 // Ensure that each language is configured at most once.
2028 for (unsigned j
= 0; j
< i
; ++j
) {
2029 if (Styles
[i
].Language
== Styles
[j
].Language
) {
2030 LLVM_DEBUG(llvm::dbgs()
2031 << "Duplicate languages in the config file on positions "
2032 << j
<< " and " << i
<< "\n");
2033 return make_error_code(ParseError::Error
);
2037 // Look for a suitable configuration starting from the end, so we can
2038 // find the configuration for the specific language first, and the default
2039 // configuration (which can only be at slot 0) after it.
2040 FormatStyle::FormatStyleSet StyleSet
;
2041 bool LanguageFound
= false;
2042 for (const FormatStyle
&Style
: llvm::reverse(Styles
)) {
2043 if (Style
.Language
!= FormatStyle::LK_None
)
2044 StyleSet
.Add(Style
);
2045 if (Style
.Language
== Language
)
2046 LanguageFound
= true;
2048 if (!LanguageFound
) {
2049 if (Styles
.empty() || Styles
[0].Language
!= FormatStyle::LK_None
)
2050 return make_error_code(ParseError::Unsuitable
);
2051 FormatStyle DefaultStyle
= Styles
[0];
2052 DefaultStyle
.Language
= Language
;
2053 StyleSet
.Add(std::move(DefaultStyle
));
2055 *Style
= *StyleSet
.Get(Language
);
2056 if (Style
->InsertTrailingCommas
!= FormatStyle::TCS_None
&&
2057 Style
->BinPackArguments
) {
2058 // See comment on FormatStyle::TSC_Wrapped.
2059 return make_error_code(ParseError::BinPackTrailingCommaConflict
);
2061 if (Style
->QualifierAlignment
!= FormatStyle::QAS_Leave
)
2062 return make_error_code(validateQualifierOrder(Style
));
2063 return make_error_code(ParseError::Success
);
2066 std::string
configurationAsText(const FormatStyle
&Style
) {
2068 llvm::raw_string_ostream
Stream(Text
);
2069 llvm::yaml::Output
Output(Stream
);
2070 // We use the same mapping method for input and output, so we need a non-const
2072 FormatStyle NonConstStyle
= Style
;
2073 expandPresetsBraceWrapping(NonConstStyle
);
2074 expandPresetsSpaceBeforeParens(NonConstStyle
);
2075 expandPresetsSpacesInParens(NonConstStyle
);
2076 Output
<< NonConstStyle
;
2078 return Stream
.str();
2081 std::optional
<FormatStyle
>
2082 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language
) const {
2084 return std::nullopt
;
2085 auto It
= Styles
->find(Language
);
2086 if (It
== Styles
->end())
2087 return std::nullopt
;
2088 FormatStyle Style
= It
->second
;
2089 Style
.StyleSet
= *this;
2093 void FormatStyle::FormatStyleSet::Add(FormatStyle Style
) {
2094 assert(Style
.Language
!= LK_None
&&
2095 "Cannot add a style for LK_None to a StyleSet");
2097 !Style
.StyleSet
.Styles
&&
2098 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2100 Styles
= std::make_shared
<MapType
>();
2101 (*Styles
)[Style
.Language
] = std::move(Style
);
2104 void FormatStyle::FormatStyleSet::Clear() { Styles
.reset(); }
2106 std::optional
<FormatStyle
>
2107 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language
) const {
2108 return StyleSet
.Get(Language
);
2113 class ParensRemover
: public TokenAnalyzer
{
2115 ParensRemover(const Environment
&Env
, const FormatStyle
&Style
)
2116 : TokenAnalyzer(Env
, Style
) {}
2118 std::pair
<tooling::Replacements
, unsigned>
2119 analyze(TokenAnnotator
&Annotator
,
2120 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2121 FormatTokenLexer
&Tokens
) override
{
2122 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2123 tooling::Replacements Result
;
2124 removeParens(AnnotatedLines
, Result
);
2129 void removeParens(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2130 tooling::Replacements
&Result
) {
2131 const auto &SourceMgr
= Env
.getSourceManager();
2132 for (auto *Line
: Lines
) {
2133 removeParens(Line
->Children
, Result
);
2134 if (!Line
->Affected
)
2136 for (const auto *Token
= Line
->First
; Token
&& !Token
->Finalized
;
2137 Token
= Token
->Next
) {
2138 if (!Token
->Optional
|| !Token
->isOneOf(tok::l_paren
, tok::r_paren
))
2140 auto *Next
= Token
->Next
;
2141 assert(Next
&& Next
->isNot(tok::eof
));
2142 SourceLocation Start
;
2143 if (Next
->NewlinesBefore
== 0) {
2144 Start
= Token
->Tok
.getLocation();
2145 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2147 Start
= Token
->WhitespaceRange
.getBegin();
2150 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2151 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, " ")));
2157 class BracesInserter
: public TokenAnalyzer
{
2159 BracesInserter(const Environment
&Env
, const FormatStyle
&Style
)
2160 : TokenAnalyzer(Env
, Style
) {}
2162 std::pair
<tooling::Replacements
, unsigned>
2163 analyze(TokenAnnotator
&Annotator
,
2164 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2165 FormatTokenLexer
&Tokens
) override
{
2166 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2167 tooling::Replacements Result
;
2168 insertBraces(AnnotatedLines
, Result
);
2173 void insertBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2174 tooling::Replacements
&Result
) {
2175 const auto &SourceMgr
= Env
.getSourceManager();
2176 int OpeningBraceSurplus
= 0;
2177 for (AnnotatedLine
*Line
: Lines
) {
2178 insertBraces(Line
->Children
, Result
);
2179 if (!Line
->Affected
&& OpeningBraceSurplus
== 0)
2181 for (FormatToken
*Token
= Line
->First
; Token
&& !Token
->Finalized
;
2182 Token
= Token
->Next
) {
2183 int BraceCount
= Token
->BraceCount
;
2184 if (BraceCount
== 0)
2187 if (BraceCount
< 0) {
2188 assert(BraceCount
== -1);
2189 if (!Line
->Affected
)
2191 Brace
= Token
->is(tok::comment
) ? "\n{" : "{";
2192 ++OpeningBraceSurplus
;
2194 if (OpeningBraceSurplus
== 0)
2196 if (OpeningBraceSurplus
< BraceCount
)
2197 BraceCount
= OpeningBraceSurplus
;
2198 Brace
= '\n' + std::string(BraceCount
, '}');
2199 OpeningBraceSurplus
-= BraceCount
;
2201 Token
->BraceCount
= 0;
2202 const auto Start
= Token
->Tok
.getEndLoc();
2203 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Start
, 0, Brace
)));
2206 assert(OpeningBraceSurplus
== 0);
2210 class BracesRemover
: public TokenAnalyzer
{
2212 BracesRemover(const Environment
&Env
, const FormatStyle
&Style
)
2213 : TokenAnalyzer(Env
, Style
) {}
2215 std::pair
<tooling::Replacements
, unsigned>
2216 analyze(TokenAnnotator
&Annotator
,
2217 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2218 FormatTokenLexer
&Tokens
) override
{
2219 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2220 tooling::Replacements Result
;
2221 removeBraces(AnnotatedLines
, Result
);
2226 void removeBraces(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2227 tooling::Replacements
&Result
) {
2228 const auto &SourceMgr
= Env
.getSourceManager();
2229 const auto End
= Lines
.end();
2230 for (auto I
= Lines
.begin(); I
!= End
; ++I
) {
2231 const auto Line
= *I
;
2232 removeBraces(Line
->Children
, Result
);
2233 if (!Line
->Affected
)
2235 const auto NextLine
= I
+ 1 == End
? nullptr : I
[1];
2236 for (auto Token
= Line
->First
; Token
&& !Token
->Finalized
;
2237 Token
= Token
->Next
) {
2238 if (!Token
->Optional
)
2240 if (!Token
->isOneOf(tok::l_brace
, tok::r_brace
))
2242 auto Next
= Token
->Next
;
2243 assert(Next
|| Token
== Line
->Last
);
2244 if (!Next
&& NextLine
)
2245 Next
= NextLine
->First
;
2246 SourceLocation Start
;
2247 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2248 Start
= Token
->Tok
.getLocation();
2249 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2251 Start
= Token
->WhitespaceRange
.getBegin();
2254 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2255 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2261 class SemiRemover
: public TokenAnalyzer
{
2263 SemiRemover(const Environment
&Env
, const FormatStyle
&Style
)
2264 : TokenAnalyzer(Env
, Style
) {}
2266 std::pair
<tooling::Replacements
, unsigned>
2267 analyze(TokenAnnotator
&Annotator
,
2268 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2269 FormatTokenLexer
&Tokens
) override
{
2270 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2271 tooling::Replacements Result
;
2272 removeSemi(AnnotatedLines
, Result
);
2277 void removeSemi(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2278 tooling::Replacements
&Result
) {
2279 const auto &SourceMgr
= Env
.getSourceManager();
2280 const auto End
= Lines
.end();
2281 for (auto I
= Lines
.begin(); I
!= End
; ++I
) {
2282 const auto Line
= *I
;
2283 removeSemi(Line
->Children
, Result
);
2284 if (!Line
->Affected
)
2286 const auto NextLine
= I
+ 1 == End
? nullptr : I
[1];
2287 for (auto Token
= Line
->First
; Token
&& !Token
->Finalized
;
2288 Token
= Token
->Next
) {
2289 if (!Token
->Optional
)
2291 if (Token
->isNot(tok::semi
))
2293 auto Next
= Token
->Next
;
2294 assert(Next
|| Token
== Line
->Last
);
2295 if (!Next
&& NextLine
)
2296 Next
= NextLine
->First
;
2297 SourceLocation Start
;
2298 if (Next
&& Next
->NewlinesBefore
== 0 && Next
->isNot(tok::eof
)) {
2299 Start
= Token
->Tok
.getLocation();
2300 Next
->WhitespaceRange
= Token
->WhitespaceRange
;
2302 Start
= Token
->WhitespaceRange
.getBegin();
2305 CharSourceRange::getCharRange(Start
, Token
->Tok
.getEndLoc());
2306 cantFail(Result
.add(tooling::Replacement(SourceMgr
, Range
, "")));
2312 class JavaScriptRequoter
: public TokenAnalyzer
{
2314 JavaScriptRequoter(const Environment
&Env
, const FormatStyle
&Style
)
2315 : TokenAnalyzer(Env
, Style
) {}
2317 std::pair
<tooling::Replacements
, unsigned>
2318 analyze(TokenAnnotator
&Annotator
,
2319 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2320 FormatTokenLexer
&Tokens
) override
{
2321 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2322 tooling::Replacements Result
;
2323 requoteJSStringLiteral(AnnotatedLines
, Result
);
2328 // Replaces double/single-quoted string literal as appropriate, re-escaping
2329 // the contents in the process.
2330 void requoteJSStringLiteral(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2331 tooling::Replacements
&Result
) {
2332 for (AnnotatedLine
*Line
: Lines
) {
2333 requoteJSStringLiteral(Line
->Children
, Result
);
2334 if (!Line
->Affected
)
2336 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2337 FormatTok
= FormatTok
->Next
) {
2338 StringRef Input
= FormatTok
->TokenText
;
2339 if (FormatTok
->Finalized
|| !FormatTok
->isStringLiteral() ||
2340 // NB: testing for not starting with a double quote to avoid
2341 // breaking `template strings`.
2342 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
&&
2343 !Input
.startswith("\"")) ||
2344 (Style
.JavaScriptQuotes
== FormatStyle::JSQS_Double
&&
2345 !Input
.startswith("\'"))) {
2349 // Change start and end quote.
2350 bool IsSingle
= Style
.JavaScriptQuotes
== FormatStyle::JSQS_Single
;
2351 SourceLocation Start
= FormatTok
->Tok
.getLocation();
2352 auto Replace
= [&](SourceLocation Start
, unsigned Length
,
2353 StringRef ReplacementText
) {
2354 auto Err
= Result
.add(tooling::Replacement(
2355 Env
.getSourceManager(), Start
, Length
, ReplacementText
));
2356 // FIXME: handle error. For now, print error message and skip the
2357 // replacement for release version.
2359 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
2363 Replace(Start
, 1, IsSingle
? "'" : "\"");
2364 Replace(FormatTok
->Tok
.getEndLoc().getLocWithOffset(-1), 1,
2365 IsSingle
? "'" : "\"");
2367 // Escape internal quotes.
2368 bool Escaped
= false;
2369 for (size_t i
= 1; i
< Input
.size() - 1; i
++) {
2372 if (!Escaped
&& i
+ 1 < Input
.size() &&
2373 ((IsSingle
&& Input
[i
+ 1] == '"') ||
2374 (!IsSingle
&& Input
[i
+ 1] == '\''))) {
2375 // Remove this \, it's escaping a " or ' that no longer needs
2377 Replace(Start
.getLocWithOffset(i
), 1, "");
2384 if (!Escaped
&& IsSingle
== (Input
[i
] == '\'')) {
2385 // Escape the quote.
2386 Replace(Start
.getLocWithOffset(i
), 0, "\\");
2400 class Formatter
: public TokenAnalyzer
{
2402 Formatter(const Environment
&Env
, const FormatStyle
&Style
,
2403 FormattingAttemptStatus
*Status
)
2404 : TokenAnalyzer(Env
, Style
), Status(Status
) {}
2406 std::pair
<tooling::Replacements
, unsigned>
2407 analyze(TokenAnnotator
&Annotator
,
2408 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2409 FormatTokenLexer
&Tokens
) override
{
2410 tooling::Replacements Result
;
2411 deriveLocalStyle(AnnotatedLines
);
2412 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2413 for (AnnotatedLine
*Line
: AnnotatedLines
)
2414 Annotator
.calculateFormattingInformation(*Line
);
2415 Annotator
.setCommentLineLevels(AnnotatedLines
);
2417 WhitespaceManager
Whitespaces(
2418 Env
.getSourceManager(), Style
,
2419 Style
.LineEnding
> FormatStyle::LE_CRLF
2420 ? WhitespaceManager::inputUsesCRLF(
2421 Env
.getSourceManager().getBufferData(Env
.getFileID()),
2422 Style
.LineEnding
== FormatStyle::LE_DeriveCRLF
)
2423 : Style
.LineEnding
== FormatStyle::LE_CRLF
);
2424 ContinuationIndenter
Indenter(Style
, Tokens
.getKeywords(),
2425 Env
.getSourceManager(), Whitespaces
, Encoding
,
2426 BinPackInconclusiveFunctions
);
2428 UnwrappedLineFormatter(&Indenter
, &Whitespaces
, Style
,
2429 Tokens
.getKeywords(), Env
.getSourceManager(),
2431 .format(AnnotatedLines
, /*DryRun=*/false,
2432 /*AdditionalIndent=*/0,
2433 /*FixBadIndentation=*/false,
2434 /*FirstStartColumn=*/Env
.getFirstStartColumn(),
2435 /*NextStartColumn=*/Env
.getNextStartColumn(),
2436 /*LastStartColumn=*/Env
.getLastStartColumn());
2437 for (const auto &R
: Whitespaces
.generateReplacements())
2439 return std::make_pair(Result
, 0);
2440 return std::make_pair(Result
, Penalty
);
2445 hasCpp03IncompatibleFormat(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2446 for (const AnnotatedLine
*Line
: Lines
) {
2447 if (hasCpp03IncompatibleFormat(Line
->Children
))
2449 for (FormatToken
*Tok
= Line
->First
->Next
; Tok
; Tok
= Tok
->Next
) {
2450 if (!Tok
->hasWhitespaceBefore()) {
2451 if (Tok
->is(tok::coloncolon
) && Tok
->Previous
->is(TT_TemplateOpener
))
2453 if (Tok
->is(TT_TemplateCloser
) &&
2454 Tok
->Previous
->is(TT_TemplateCloser
)) {
2463 int countVariableAlignments(const SmallVectorImpl
<AnnotatedLine
*> &Lines
) {
2464 int AlignmentDiff
= 0;
2465 for (const AnnotatedLine
*Line
: Lines
) {
2466 AlignmentDiff
+= countVariableAlignments(Line
->Children
);
2467 for (FormatToken
*Tok
= Line
->First
; Tok
&& Tok
->Next
; Tok
= Tok
->Next
) {
2468 if (Tok
->isNot(TT_PointerOrReference
))
2470 // Don't treat space in `void foo() &&` as evidence.
2471 if (const auto *Prev
= Tok
->getPreviousNonComment()) {
2472 if (Prev
->is(tok::r_paren
) && Prev
->MatchingParen
) {
2473 if (const auto *Func
=
2474 Prev
->MatchingParen
->getPreviousNonComment()) {
2475 if (Func
->isOneOf(TT_FunctionDeclarationName
, TT_StartOfName
,
2476 TT_OverloadedOperator
)) {
2482 bool SpaceBefore
= Tok
->hasWhitespaceBefore();
2483 bool SpaceAfter
= Tok
->Next
->hasWhitespaceBefore();
2484 if (SpaceBefore
&& !SpaceAfter
)
2486 if (!SpaceBefore
&& SpaceAfter
)
2490 return AlignmentDiff
;
2494 deriveLocalStyle(const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2495 bool HasBinPackedFunction
= false;
2496 bool HasOnePerLineFunction
= false;
2497 for (AnnotatedLine
*Line
: AnnotatedLines
) {
2498 if (!Line
->First
->Next
)
2500 FormatToken
*Tok
= Line
->First
->Next
;
2502 if (Tok
->is(PPK_BinPacked
))
2503 HasBinPackedFunction
= true;
2504 if (Tok
->is(PPK_OnePerLine
))
2505 HasOnePerLineFunction
= true;
2510 if (Style
.DerivePointerAlignment
) {
2511 const auto NetRightCount
= countVariableAlignments(AnnotatedLines
);
2512 if (NetRightCount
> 0)
2513 Style
.PointerAlignment
= FormatStyle::PAS_Right
;
2514 else if (NetRightCount
< 0)
2515 Style
.PointerAlignment
= FormatStyle::PAS_Left
;
2516 Style
.ReferenceAlignment
= FormatStyle::RAS_Pointer
;
2518 if (Style
.Standard
== FormatStyle::LS_Auto
) {
2519 Style
.Standard
= hasCpp03IncompatibleFormat(AnnotatedLines
)
2520 ? FormatStyle::LS_Latest
2521 : FormatStyle::LS_Cpp03
;
2523 BinPackInconclusiveFunctions
=
2524 HasBinPackedFunction
|| !HasOnePerLineFunction
;
2527 bool BinPackInconclusiveFunctions
;
2528 FormattingAttemptStatus
*Status
;
2531 /// TrailingCommaInserter inserts trailing commas into container literals.
2536 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2537 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2540 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2541 /// is conceptually incompatible with bin packing.
2542 class TrailingCommaInserter
: public TokenAnalyzer
{
2544 TrailingCommaInserter(const Environment
&Env
, const FormatStyle
&Style
)
2545 : TokenAnalyzer(Env
, Style
) {}
2547 std::pair
<tooling::Replacements
, unsigned>
2548 analyze(TokenAnnotator
&Annotator
,
2549 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2550 FormatTokenLexer
&Tokens
) override
{
2551 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2552 tooling::Replacements Result
;
2553 insertTrailingCommas(AnnotatedLines
, Result
);
2558 /// Inserts trailing commas in [] and {} initializers if they wrap over
2560 void insertTrailingCommas(SmallVectorImpl
<AnnotatedLine
*> &Lines
,
2561 tooling::Replacements
&Result
) {
2562 for (AnnotatedLine
*Line
: Lines
) {
2563 insertTrailingCommas(Line
->Children
, Result
);
2564 if (!Line
->Affected
)
2566 for (FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2567 FormatTok
= FormatTok
->Next
) {
2568 if (FormatTok
->NewlinesBefore
== 0)
2570 FormatToken
*Matching
= FormatTok
->MatchingParen
;
2571 if (!Matching
|| !FormatTok
->getPreviousNonComment())
2573 if (!(FormatTok
->is(tok::r_square
) &&
2574 Matching
->is(TT_ArrayInitializerLSquare
)) &&
2575 !(FormatTok
->is(tok::r_brace
) && Matching
->is(TT_DictLiteral
))) {
2578 FormatToken
*Prev
= FormatTok
->getPreviousNonComment();
2579 if (Prev
->is(tok::comma
) || Prev
->is(tok::semi
))
2581 // getEndLoc is not reliably set during re-lexing, use text length
2583 SourceLocation Start
=
2584 Prev
->Tok
.getLocation().getLocWithOffset(Prev
->TokenText
.size());
2585 // If inserting a comma would push the code over the column limit, skip
2586 // this location - it'd introduce an unstable formatting due to the
2588 unsigned ColumnNumber
=
2589 Env
.getSourceManager().getSpellingColumnNumber(Start
);
2590 if (ColumnNumber
> Style
.ColumnLimit
)
2592 // Comma insertions cannot conflict with each other, and this pass has a
2593 // clean set of Replacements, so the operation below cannot fail.
2594 cantFail(Result
.add(
2595 tooling::Replacement(Env
.getSourceManager(), Start
, 0, ",")));
2601 // This class clean up the erroneous/redundant code around the given ranges in
2603 class Cleaner
: public TokenAnalyzer
{
2605 Cleaner(const Environment
&Env
, const FormatStyle
&Style
)
2606 : TokenAnalyzer(Env
, Style
),
2607 DeletedTokens(FormatTokenLess(Env
.getSourceManager())) {}
2609 // FIXME: eliminate unused parameters.
2610 std::pair
<tooling::Replacements
, unsigned>
2611 analyze(TokenAnnotator
&Annotator
,
2612 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2613 FormatTokenLexer
&Tokens
) override
{
2614 // FIXME: in the current implementation the granularity of affected range
2615 // is an annotated line. However, this is not sufficient. Furthermore,
2616 // redundant code introduced by replacements does not necessarily
2617 // intercept with ranges of replacements that result in the redundancy.
2618 // To determine if some redundant code is actually introduced by
2619 // replacements(e.g. deletions), we need to come up with a more
2620 // sophisticated way of computing affected ranges.
2621 AffectedRangeMgr
.computeAffectedLines(AnnotatedLines
);
2623 checkEmptyNamespace(AnnotatedLines
);
2625 for (auto *Line
: AnnotatedLines
)
2628 return {generateFixes(), 0};
2632 void cleanupLine(AnnotatedLine
*Line
) {
2633 for (auto *Child
: Line
->Children
)
2636 if (Line
->Affected
) {
2637 cleanupRight(Line
->First
, tok::comma
, tok::comma
);
2638 cleanupRight(Line
->First
, TT_CtorInitializerColon
, tok::comma
);
2639 cleanupRight(Line
->First
, tok::l_paren
, tok::comma
);
2640 cleanupLeft(Line
->First
, tok::comma
, tok::r_paren
);
2641 cleanupLeft(Line
->First
, TT_CtorInitializerComma
, tok::l_brace
);
2642 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::l_brace
);
2643 cleanupLeft(Line
->First
, TT_CtorInitializerColon
, tok::equal
);
2647 bool containsOnlyComments(const AnnotatedLine
&Line
) {
2648 for (FormatToken
*Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
)
2649 if (Tok
->isNot(tok::comment
))
2654 // Iterate through all lines and remove any empty (nested) namespaces.
2655 void checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
) {
2656 std::set
<unsigned> DeletedLines
;
2657 for (unsigned i
= 0, e
= AnnotatedLines
.size(); i
!= e
; ++i
) {
2658 auto &Line
= *AnnotatedLines
[i
];
2659 if (Line
.startsWithNamespace())
2660 checkEmptyNamespace(AnnotatedLines
, i
, i
, DeletedLines
);
2663 for (auto Line
: DeletedLines
) {
2664 FormatToken
*Tok
= AnnotatedLines
[Line
]->First
;
2672 // The function checks if the namespace, which starts from \p CurrentLine, and
2673 // its nested namespaces are empty and delete them if they are empty. It also
2674 // sets \p NewLine to the last line checked.
2675 // Returns true if the current namespace is empty.
2676 bool checkEmptyNamespace(SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2677 unsigned CurrentLine
, unsigned &NewLine
,
2678 std::set
<unsigned> &DeletedLines
) {
2679 unsigned InitLine
= CurrentLine
, End
= AnnotatedLines
.size();
2680 if (Style
.BraceWrapping
.AfterNamespace
) {
2681 // If the left brace is in a new line, we should consume it first so that
2682 // it does not make the namespace non-empty.
2683 // FIXME: error handling if there is no left brace.
2684 if (!AnnotatedLines
[++CurrentLine
]->startsWith(tok::l_brace
)) {
2685 NewLine
= CurrentLine
;
2688 } else if (!AnnotatedLines
[CurrentLine
]->endsWith(tok::l_brace
)) {
2691 while (++CurrentLine
< End
) {
2692 if (AnnotatedLines
[CurrentLine
]->startsWith(tok::r_brace
))
2695 if (AnnotatedLines
[CurrentLine
]->startsWithNamespace()) {
2696 if (!checkEmptyNamespace(AnnotatedLines
, CurrentLine
, NewLine
,
2700 CurrentLine
= NewLine
;
2704 if (containsOnlyComments(*AnnotatedLines
[CurrentLine
]))
2707 // If there is anything other than comments or nested namespaces in the
2708 // current namespace, the namespace cannot be empty.
2709 NewLine
= CurrentLine
;
2713 NewLine
= CurrentLine
;
2714 if (CurrentLine
>= End
)
2717 // Check if the empty namespace is actually affected by changed ranges.
2718 if (!AffectedRangeMgr
.affectsCharSourceRange(CharSourceRange::getCharRange(
2719 AnnotatedLines
[InitLine
]->First
->Tok
.getLocation(),
2720 AnnotatedLines
[CurrentLine
]->Last
->Tok
.getEndLoc()))) {
2724 for (unsigned i
= InitLine
; i
<= CurrentLine
; ++i
)
2725 DeletedLines
.insert(i
);
2730 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2731 // of the token in the pair if the left token has \p LK token kind and the
2732 // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2733 // is deleted on match; otherwise, the right token is deleted.
2734 template <typename LeftKind
, typename RightKind
>
2735 void cleanupPair(FormatToken
*Start
, LeftKind LK
, RightKind RK
,
2737 auto NextNotDeleted
= [this](const FormatToken
&Tok
) -> FormatToken
* {
2738 for (auto *Res
= Tok
.Next
; Res
; Res
= Res
->Next
) {
2739 if (Res
->isNot(tok::comment
) &&
2740 DeletedTokens
.find(Res
) == DeletedTokens
.end()) {
2746 for (auto *Left
= Start
; Left
;) {
2747 auto *Right
= NextNotDeleted(*Left
);
2750 if (Left
->is(LK
) && Right
->is(RK
)) {
2751 deleteToken(DeleteLeft
? Left
: Right
);
2752 for (auto *Tok
= Left
->Next
; Tok
&& Tok
!= Right
; Tok
= Tok
->Next
)
2754 // If the right token is deleted, we should keep the left token
2755 // unchanged and pair it with the new right token.
2763 template <typename LeftKind
, typename RightKind
>
2764 void cleanupLeft(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2765 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/true);
2768 template <typename LeftKind
, typename RightKind
>
2769 void cleanupRight(FormatToken
*Start
, LeftKind LK
, RightKind RK
) {
2770 cleanupPair(Start
, LK
, RK
, /*DeleteLeft=*/false);
2773 // Delete the given token.
2774 inline void deleteToken(FormatToken
*Tok
) {
2776 DeletedTokens
.insert(Tok
);
2779 tooling::Replacements
generateFixes() {
2780 tooling::Replacements Fixes
;
2781 SmallVector
<FormatToken
*> Tokens
;
2782 std::copy(DeletedTokens
.begin(), DeletedTokens
.end(),
2783 std::back_inserter(Tokens
));
2785 // Merge multiple continuous token deletions into one big deletion so that
2786 // the number of replacements can be reduced. This makes computing affected
2787 // ranges more efficient when we run reformat on the changed code.
2789 while (Idx
< Tokens
.size()) {
2790 unsigned St
= Idx
, End
= Idx
;
2791 while ((End
+ 1) < Tokens
.size() && Tokens
[End
]->Next
== Tokens
[End
+ 1])
2793 auto SR
= CharSourceRange::getCharRange(Tokens
[St
]->Tok
.getLocation(),
2794 Tokens
[End
]->Tok
.getEndLoc());
2796 Fixes
.add(tooling::Replacement(Env
.getSourceManager(), SR
, ""));
2797 // FIXME: better error handling. for now just print error message and skip
2798 // for the release version.
2800 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
2801 assert(false && "Fixes must not conflict!");
2809 // Class for less-than inequality comparason for the set `RedundantTokens`.
2810 // We store tokens in the order they appear in the translation unit so that
2811 // we do not need to sort them in `generateFixes()`.
2812 struct FormatTokenLess
{
2813 FormatTokenLess(const SourceManager
&SM
) : SM(SM
) {}
2815 bool operator()(const FormatToken
*LHS
, const FormatToken
*RHS
) const {
2816 return SM
.isBeforeInTranslationUnit(LHS
->Tok
.getLocation(),
2817 RHS
->Tok
.getLocation());
2819 const SourceManager
&SM
;
2822 // Tokens to be deleted.
2823 std::set
<FormatToken
*, FormatTokenLess
> DeletedTokens
;
2826 class ObjCHeaderStyleGuesser
: public TokenAnalyzer
{
2828 ObjCHeaderStyleGuesser(const Environment
&Env
, const FormatStyle
&Style
)
2829 : TokenAnalyzer(Env
, Style
), IsObjC(false) {}
2831 std::pair
<tooling::Replacements
, unsigned>
2832 analyze(TokenAnnotator
&Annotator
,
2833 SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2834 FormatTokenLexer
&Tokens
) override
{
2835 assert(Style
.Language
== FormatStyle::LK_Cpp
);
2836 IsObjC
= guessIsObjC(Env
.getSourceManager(), AnnotatedLines
,
2837 Tokens
.getKeywords());
2838 tooling::Replacements Result
;
2842 bool isObjC() { return IsObjC
; }
2846 guessIsObjC(const SourceManager
&SourceManager
,
2847 const SmallVectorImpl
<AnnotatedLine
*> &AnnotatedLines
,
2848 const AdditionalKeywords
&Keywords
) {
2849 // Keep this array sorted, since we are binary searching over it.
2850 static constexpr llvm::StringLiteral FoundationIdentifiers
[] = {
2865 "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
2866 "FOUNDATION_EXTERN",
2867 "NSAffineTransform",
2869 "NSAttributedString",
2888 "NSInvocationOperation",
2892 "NSMutableAttributedString",
2893 "NSMutableCharacterSet",
2895 "NSMutableDictionary",
2896 "NSMutableIndexSet",
2897 "NSMutableOrderedSet",
2901 "NSNumberFormatter",
2905 "NSOperationQueuePriority",
2909 "NSQualityOfService",
2912 "NSRegularExpression",
2923 "NS_ASSUME_NONNULL_BEGIN",
2928 for (auto *Line
: AnnotatedLines
) {
2929 if (Line
->First
&& (Line
->First
->TokenText
.startswith("#") ||
2930 Line
->First
->TokenText
== "__pragma" ||
2931 Line
->First
->TokenText
== "_Pragma")) {
2934 for (const FormatToken
*FormatTok
= Line
->First
; FormatTok
;
2935 FormatTok
= FormatTok
->Next
) {
2936 if ((FormatTok
->Previous
&& FormatTok
->Previous
->is(tok::at
) &&
2937 (FormatTok
->Tok
.getObjCKeywordID() != tok::objc_not_keyword
||
2938 FormatTok
->isOneOf(tok::numeric_constant
, tok::l_square
,
2940 (FormatTok
->Tok
.isAnyIdentifier() &&
2941 std::binary_search(std::begin(FoundationIdentifiers
),
2942 std::end(FoundationIdentifiers
),
2943 FormatTok
->TokenText
)) ||
2944 FormatTok
->is(TT_ObjCStringLiteral
) ||
2945 FormatTok
->isOneOf(Keywords
.kw_NS_CLOSED_ENUM
, Keywords
.kw_NS_ENUM
,
2946 Keywords
.kw_NS_ERROR_ENUM
,
2947 Keywords
.kw_NS_OPTIONS
, TT_ObjCBlockLBrace
,
2948 TT_ObjCBlockLParen
, TT_ObjCDecl
, TT_ObjCForIn
,
2949 TT_ObjCMethodExpr
, TT_ObjCMethodSpecifier
,
2951 LLVM_DEBUG(llvm::dbgs()
2952 << "Detected ObjC at location "
2953 << FormatTok
->Tok
.getLocation().printToString(
2955 << " token: " << FormatTok
->TokenText
<< " token type: "
2956 << getTokenTypeName(FormatTok
->getType()) << "\n");
2959 if (guessIsObjC(SourceManager
, Line
->Children
, Keywords
))
2969 struct IncludeDirective
{
2977 struct JavaImportDirective
{
2978 StringRef Identifier
;
2981 SmallVector
<StringRef
> AssociatedCommentLines
;
2985 } // end anonymous namespace
2987 // Determines whether 'Ranges' intersects with ('Start', 'End').
2988 static bool affectsRange(ArrayRef
<tooling::Range
> Ranges
, unsigned Start
,
2990 for (const auto &Range
: Ranges
) {
2991 if (Range
.getOffset() < End
&&
2992 Range
.getOffset() + Range
.getLength() > Start
) {
2999 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
3000 // before sorting/deduplicating. Index is the index of the include under the
3001 // cursor in the original set of includes. If this include has duplicates, it is
3002 // the index of the first of the duplicates as the others are going to be
3003 // removed. OffsetToEOL describes the cursor's position relative to the end of
3004 // its current line.
3005 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
3006 static std::pair
<unsigned, unsigned>
3007 FindCursorIndex(const SmallVectorImpl
<IncludeDirective
> &Includes
,
3008 const SmallVectorImpl
<unsigned> &Indices
, unsigned Cursor
) {
3009 unsigned CursorIndex
= UINT_MAX
;
3010 unsigned OffsetToEOL
= 0;
3011 for (int i
= 0, e
= Includes
.size(); i
!= e
; ++i
) {
3012 unsigned Start
= Includes
[Indices
[i
]].Offset
;
3013 unsigned End
= Start
+ Includes
[Indices
[i
]].Text
.size();
3014 if (!(Cursor
>= Start
&& Cursor
< End
))
3016 CursorIndex
= Indices
[i
];
3017 OffsetToEOL
= End
- Cursor
;
3018 // Put the cursor on the only remaining #include among the duplicate
3020 while (--i
>= 0 && Includes
[CursorIndex
].Text
== Includes
[Indices
[i
]].Text
)
3024 return std::make_pair(CursorIndex
, OffsetToEOL
);
3027 // Replace all "\r\n" with "\n".
3028 std::string
replaceCRLF(const std::string
&Code
) {
3029 std::string NewCode
;
3030 size_t Pos
= 0, LastPos
= 0;
3033 Pos
= Code
.find("\r\n", LastPos
);
3034 if (Pos
== LastPos
) {
3038 if (Pos
== std::string::npos
) {
3039 NewCode
+= Code
.substr(LastPos
);
3042 NewCode
+= Code
.substr(LastPos
, Pos
- LastPos
) + "\n";
3044 } while (Pos
!= std::string::npos
);
3049 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
3050 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
3052 // #include directives with the same text will be deduplicated, and only the
3053 // first #include in the duplicate #includes remains. If the `Cursor` is
3054 // provided and put on a deleted #include, it will be moved to the remaining
3055 // #include in the duplicate #includes.
3056 static void sortCppIncludes(const FormatStyle
&Style
,
3057 const SmallVectorImpl
<IncludeDirective
> &Includes
,
3058 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
3059 StringRef Code
, tooling::Replacements
&Replaces
,
3061 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
3062 const unsigned IncludesBeginOffset
= Includes
.front().Offset
;
3063 const unsigned IncludesEndOffset
=
3064 Includes
.back().Offset
+ Includes
.back().Text
.size();
3065 const unsigned IncludesBlockSize
= IncludesEndOffset
- IncludesBeginOffset
;
3066 if (!affectsRange(Ranges
, IncludesBeginOffset
, IncludesEndOffset
))
3068 SmallVector
<unsigned, 16> Indices
=
3069 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Includes
.size()));
3071 if (Style
.SortIncludes
== FormatStyle::SI_CaseInsensitive
) {
3072 llvm::stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3073 const auto LHSFilenameLower
= Includes
[LHSI
].Filename
.lower();
3074 const auto RHSFilenameLower
= Includes
[RHSI
].Filename
.lower();
3075 return std::tie(Includes
[LHSI
].Priority
, LHSFilenameLower
,
3076 Includes
[LHSI
].Filename
) <
3077 std::tie(Includes
[RHSI
].Priority
, RHSFilenameLower
,
3078 Includes
[RHSI
].Filename
);
3081 llvm::stable_sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3082 return std::tie(Includes
[LHSI
].Priority
, Includes
[LHSI
].Filename
) <
3083 std::tie(Includes
[RHSI
].Priority
, Includes
[RHSI
].Filename
);
3087 // The index of the include on which the cursor will be put after
3088 // sorting/deduplicating.
3089 unsigned CursorIndex
;
3090 // The offset from cursor to the end of line.
3091 unsigned CursorToEOLOffset
;
3093 std::tie(CursorIndex
, CursorToEOLOffset
) =
3094 FindCursorIndex(Includes
, Indices
, *Cursor
);
3097 // Deduplicate #includes.
3098 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
3099 [&](unsigned LHSI
, unsigned RHSI
) {
3100 return Includes
[LHSI
].Text
.trim() ==
3101 Includes
[RHSI
].Text
.trim();
3105 int CurrentCategory
= Includes
.front().Category
;
3107 // If the #includes are out of order, we generate a single replacement fixing
3108 // the entire block. Otherwise, no replacement is generated.
3109 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
3110 // enough as additional newlines might be added or removed across #include
3111 // blocks. This we handle below by generating the updated #include blocks and
3112 // comparing it to the original.
3113 if (Indices
.size() == Includes
.size() && llvm::is_sorted(Indices
) &&
3114 Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Preserve
) {
3119 for (unsigned Index
: Indices
) {
3120 if (!result
.empty()) {
3122 if (Style
.IncludeStyle
.IncludeBlocks
==
3123 tooling::IncludeStyle::IBS_Regroup
&&
3124 CurrentCategory
!= Includes
[Index
].Category
) {
3128 result
+= Includes
[Index
].Text
;
3129 if (Cursor
&& CursorIndex
== Index
)
3130 *Cursor
= IncludesBeginOffset
+ result
.size() - CursorToEOLOffset
;
3131 CurrentCategory
= Includes
[Index
].Category
;
3134 if (Cursor
&& *Cursor
>= IncludesEndOffset
)
3135 *Cursor
+= result
.size() - IncludesBlockSize
;
3137 // If the #includes are out of order, we generate a single replacement fixing
3138 // the entire range of blocks. Otherwise, no replacement is generated.
3139 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
3140 IncludesBeginOffset
, IncludesBlockSize
)))) {
3144 auto Err
= Replaces
.add(tooling::Replacement(
3145 FileName
, Includes
.front().Offset
, IncludesBlockSize
, result
));
3146 // FIXME: better error handling. For now, just skip the replacement for the
3149 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
3154 tooling::Replacements
sortCppIncludes(const FormatStyle
&Style
, StringRef Code
,
3155 ArrayRef
<tooling::Range
> Ranges
,
3157 tooling::Replacements
&Replaces
,
3159 unsigned Prev
= llvm::StringSwitch
<size_t>(Code
)
3160 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
3162 unsigned SearchFrom
= 0;
3163 SmallVector
<StringRef
, 4> Matches
;
3164 SmallVector
<IncludeDirective
, 16> IncludesInBlock
;
3166 // In compiled files, consider the first #include to be the main #include of
3167 // the file if it is not a system #include. This ensures that the header
3168 // doesn't have hidden dependencies
3169 // (http://llvm.org/docs/CodingStandards.html#include-style).
3171 // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3172 // cases where the first #include is unlikely to be the main header.
3173 tooling::IncludeCategoryManager
Categories(Style
.IncludeStyle
, FileName
);
3174 bool FirstIncludeBlock
= true;
3175 bool MainIncludeFound
= false;
3176 bool FormattingOff
= false;
3178 // '[' must be the first and '-' the last character inside [...].
3179 llvm::Regex
RawStringRegex(
3180 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3181 SmallVector
<StringRef
, 2> RawStringMatches
;
3182 std::string RawStringTermination
= ")\"";
3185 auto Pos
= Code
.find('\n', SearchFrom
);
3187 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3189 StringRef Trimmed
= Line
.trim();
3191 // #includes inside raw string literals need to be ignored.
3192 // or we will sort the contents of the string.
3193 // Skip past until we think we are at the rawstring literal close.
3194 if (RawStringRegex
.match(Trimmed
, &RawStringMatches
)) {
3195 std::string CharSequence
= RawStringMatches
[1].str();
3196 RawStringTermination
= ")" + CharSequence
+ "\"";
3197 FormattingOff
= true;
3200 if (Trimmed
.contains(RawStringTermination
))
3201 FormattingOff
= false;
3203 if (isClangFormatOff(Trimmed
))
3204 FormattingOff
= true;
3205 else if (isClangFormatOn(Trimmed
))
3206 FormattingOff
= false;
3208 const bool EmptyLineSkipped
=
3210 (Style
.IncludeStyle
.IncludeBlocks
== tooling::IncludeStyle::IBS_Merge
||
3211 Style
.IncludeStyle
.IncludeBlocks
==
3212 tooling::IncludeStyle::IBS_Regroup
);
3214 bool MergeWithNextLine
= Trimmed
.endswith("\\");
3215 if (!FormattingOff
&& !MergeWithNextLine
) {
3216 if (tooling::HeaderIncludes::IncludeRegex
.match(Line
, &Matches
)) {
3217 StringRef IncludeName
= Matches
[2];
3218 if (Line
.contains("/*") && !Line
.contains("*/")) {
3219 // #include with a start of a block comment, but without the end.
3220 // Need to keep all the lines until the end of the comment together.
3221 // FIXME: This is somehow simplified check that probably does not work
3222 // correctly if there are multiple comments on a line.
3223 Pos
= Code
.find("*/", SearchFrom
);
3225 Prev
, (Pos
!= StringRef::npos
? Pos
+ 2 : Code
.size()) - Prev
);
3227 int Category
= Categories
.getIncludePriority(
3229 /*CheckMainHeader=*/!MainIncludeFound
&& FirstIncludeBlock
);
3230 int Priority
= Categories
.getSortIncludePriority(
3231 IncludeName
, !MainIncludeFound
&& FirstIncludeBlock
);
3233 MainIncludeFound
= true;
3234 IncludesInBlock
.push_back(
3235 {IncludeName
, Line
, Prev
, Category
, Priority
});
3236 } else if (!IncludesInBlock
.empty() && !EmptyLineSkipped
) {
3237 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
,
3239 IncludesInBlock
.clear();
3240 if (Trimmed
.startswith("#pragma hdrstop")) // Precompiled headers.
3241 FirstIncludeBlock
= true;
3243 FirstIncludeBlock
= false;
3246 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3249 if (!MergeWithNextLine
)
3251 SearchFrom
= Pos
+ 1;
3253 if (!IncludesInBlock
.empty()) {
3254 sortCppIncludes(Style
, IncludesInBlock
, Ranges
, FileName
, Code
, Replaces
,
3260 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
3261 // if the import does not match any given groups.
3262 static unsigned findJavaImportGroup(const FormatStyle
&Style
,
3263 StringRef ImportIdentifier
) {
3264 unsigned LongestMatchIndex
= UINT_MAX
;
3265 unsigned LongestMatchLength
= 0;
3266 for (unsigned I
= 0; I
< Style
.JavaImportGroups
.size(); I
++) {
3267 const std::string
&GroupPrefix
= Style
.JavaImportGroups
[I
];
3268 if (ImportIdentifier
.startswith(GroupPrefix
) &&
3269 GroupPrefix
.length() > LongestMatchLength
) {
3270 LongestMatchIndex
= I
;
3271 LongestMatchLength
= GroupPrefix
.length();
3274 return LongestMatchIndex
;
3277 // Sorts and deduplicates a block of includes given by 'Imports' based on
3278 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3279 // Import declarations with the same text will be deduplicated. Between each
3280 // import group, a newline is inserted, and within each import group, a
3281 // lexicographic sort based on ASCII value is performed.
3282 static void sortJavaImports(const FormatStyle
&Style
,
3283 const SmallVectorImpl
<JavaImportDirective
> &Imports
,
3284 ArrayRef
<tooling::Range
> Ranges
, StringRef FileName
,
3285 StringRef Code
, tooling::Replacements
&Replaces
) {
3286 unsigned ImportsBeginOffset
= Imports
.front().Offset
;
3287 unsigned ImportsEndOffset
=
3288 Imports
.back().Offset
+ Imports
.back().Text
.size();
3289 unsigned ImportsBlockSize
= ImportsEndOffset
- ImportsBeginOffset
;
3290 if (!affectsRange(Ranges
, ImportsBeginOffset
, ImportsEndOffset
))
3293 SmallVector
<unsigned, 16> Indices
=
3294 llvm::to_vector
<16>(llvm::seq
<unsigned>(0, Imports
.size()));
3295 SmallVector
<unsigned, 16> JavaImportGroups
;
3296 JavaImportGroups
.reserve(Imports
.size());
3297 for (const JavaImportDirective
&Import
: Imports
)
3298 JavaImportGroups
.push_back(findJavaImportGroup(Style
, Import
.Identifier
));
3300 bool StaticImportAfterNormalImport
=
3301 Style
.SortJavaStaticImport
== FormatStyle::SJSIO_After
;
3302 llvm::sort(Indices
, [&](unsigned LHSI
, unsigned RHSI
) {
3303 // Negating IsStatic to push static imports above non-static imports.
3304 return std::make_tuple(!Imports
[LHSI
].IsStatic
^
3305 StaticImportAfterNormalImport
,
3306 JavaImportGroups
[LHSI
], Imports
[LHSI
].Identifier
) <
3307 std::make_tuple(!Imports
[RHSI
].IsStatic
^
3308 StaticImportAfterNormalImport
,
3309 JavaImportGroups
[RHSI
], Imports
[RHSI
].Identifier
);
3312 // Deduplicate imports.
3313 Indices
.erase(std::unique(Indices
.begin(), Indices
.end(),
3314 [&](unsigned LHSI
, unsigned RHSI
) {
3315 return Imports
[LHSI
].Text
== Imports
[RHSI
].Text
;
3319 bool CurrentIsStatic
= Imports
[Indices
.front()].IsStatic
;
3320 unsigned CurrentImportGroup
= JavaImportGroups
[Indices
.front()];
3323 for (unsigned Index
: Indices
) {
3324 if (!result
.empty()) {
3326 if (CurrentIsStatic
!= Imports
[Index
].IsStatic
||
3327 CurrentImportGroup
!= JavaImportGroups
[Index
]) {
3331 for (StringRef CommentLine
: Imports
[Index
].AssociatedCommentLines
) {
3332 result
+= CommentLine
;
3335 result
+= Imports
[Index
].Text
;
3336 CurrentIsStatic
= Imports
[Index
].IsStatic
;
3337 CurrentImportGroup
= JavaImportGroups
[Index
];
3340 // If the imports are out of order, we generate a single replacement fixing
3341 // the entire block. Otherwise, no replacement is generated.
3342 if (replaceCRLF(result
) == replaceCRLF(std::string(Code
.substr(
3343 Imports
.front().Offset
, ImportsBlockSize
)))) {
3347 auto Err
= Replaces
.add(tooling::Replacement(FileName
, Imports
.front().Offset
,
3348 ImportsBlockSize
, result
));
3349 // FIXME: better error handling. For now, just skip the replacement for the
3352 llvm::errs() << llvm::toString(std::move(Err
)) << "\n";
3359 const char JavaImportRegexPattern
[] =
3360 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3362 } // anonymous namespace
3364 tooling::Replacements
sortJavaImports(const FormatStyle
&Style
, StringRef Code
,
3365 ArrayRef
<tooling::Range
> Ranges
,
3367 tooling::Replacements
&Replaces
) {
3369 unsigned SearchFrom
= 0;
3370 llvm::Regex
ImportRegex(JavaImportRegexPattern
);
3371 SmallVector
<StringRef
, 4> Matches
;
3372 SmallVector
<JavaImportDirective
, 16> ImportsInBlock
;
3373 SmallVector
<StringRef
> AssociatedCommentLines
;
3375 bool FormattingOff
= false;
3378 auto Pos
= Code
.find('\n', SearchFrom
);
3380 Code
.substr(Prev
, (Pos
!= StringRef::npos
? Pos
: Code
.size()) - Prev
);
3382 StringRef Trimmed
= Line
.trim();
3383 if (isClangFormatOff(Trimmed
))
3384 FormattingOff
= true;
3385 else if (isClangFormatOn(Trimmed
))
3386 FormattingOff
= false;
3388 if (ImportRegex
.match(Line
, &Matches
)) {
3389 if (FormattingOff
) {
3390 // If at least one import line has formatting turned off, turn off
3391 // formatting entirely.
3394 StringRef Static
= Matches
[1];
3395 StringRef Identifier
= Matches
[2];
3396 bool IsStatic
= false;
3397 if (Static
.contains("static"))
3399 ImportsInBlock
.push_back(
3400 {Identifier
, Line
, Prev
, AssociatedCommentLines
, IsStatic
});
3401 AssociatedCommentLines
.clear();
3402 } else if (Trimmed
.size() > 0 && !ImportsInBlock
.empty()) {
3403 // Associating comments within the imports with the nearest import below
3404 AssociatedCommentLines
.push_back(Line
);
3407 if (Pos
== StringRef::npos
|| Pos
+ 1 == Code
.size())
3409 SearchFrom
= Pos
+ 1;
3411 if (!ImportsInBlock
.empty())
3412 sortJavaImports(Style
, ImportsInBlock
, Ranges
, FileName
, Code
, Replaces
);
3416 bool isMpegTS(StringRef Code
) {
3417 // MPEG transport streams use the ".ts" file extension. clang-format should
3418 // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3419 // 189 bytes - detect that and return.
3420 return Code
.size() > 188 && Code
[0] == 0x47 && Code
[188] == 0x47;
3423 bool isLikelyXml(StringRef Code
) { return Code
.ltrim().startswith("<"); }
3425 tooling::Replacements
sortIncludes(const FormatStyle
&Style
, StringRef Code
,
3426 ArrayRef
<tooling::Range
> Ranges
,
3427 StringRef FileName
, unsigned *Cursor
) {
3428 tooling::Replacements Replaces
;
3429 if (!Style
.SortIncludes
|| Style
.DisableFormat
)
3431 if (isLikelyXml(Code
))
3433 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
&&
3437 if (Style
.Language
== FormatStyle::LanguageKind::LK_JavaScript
)
3438 return sortJavaScriptImports(Style
, Code
, Ranges
, FileName
);
3439 if (Style
.Language
== FormatStyle::LanguageKind::LK_Java
)
3440 return sortJavaImports(Style
, Code
, Ranges
, FileName
, Replaces
);
3441 sortCppIncludes(Style
, Code
, Ranges
, FileName
, Replaces
, Cursor
);
3445 template <typename T
>
3446 static llvm::Expected
<tooling::Replacements
>
3447 processReplacements(T ProcessFunc
, StringRef Code
,
3448 const tooling::Replacements
&Replaces
,
3449 const FormatStyle
&Style
) {
3450 if (Replaces
.empty())
3451 return tooling::Replacements();
3453 auto NewCode
= applyAllReplacements(Code
, Replaces
);
3455 return NewCode
.takeError();
3456 std::vector
<tooling::Range
> ChangedRanges
= Replaces
.getAffectedRanges();
3457 StringRef FileName
= Replaces
.begin()->getFilePath();
3459 tooling::Replacements FormatReplaces
=
3460 ProcessFunc(Style
, *NewCode
, ChangedRanges
, FileName
);
3462 return Replaces
.merge(FormatReplaces
);
3465 llvm::Expected
<tooling::Replacements
>
3466 formatReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3467 const FormatStyle
&Style
) {
3468 // We need to use lambda function here since there are two versions of
3470 auto SortIncludes
= [](const FormatStyle
&Style
, StringRef Code
,
3471 std::vector
<tooling::Range
> Ranges
,
3472 StringRef FileName
) -> tooling::Replacements
{
3473 return sortIncludes(Style
, Code
, Ranges
, FileName
);
3475 auto SortedReplaces
=
3476 processReplacements(SortIncludes
, Code
, Replaces
, Style
);
3477 if (!SortedReplaces
)
3478 return SortedReplaces
.takeError();
3480 // We need to use lambda function here since there are two versions of
3482 auto Reformat
= [](const FormatStyle
&Style
, StringRef Code
,
3483 std::vector
<tooling::Range
> Ranges
,
3484 StringRef FileName
) -> tooling::Replacements
{
3485 return reformat(Style
, Code
, Ranges
, FileName
);
3487 return processReplacements(Reformat
, Code
, *SortedReplaces
, Style
);
3492 inline bool isHeaderInsertion(const tooling::Replacement
&Replace
) {
3493 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 0 &&
3494 tooling::HeaderIncludes::IncludeRegex
.match(
3495 Replace
.getReplacementText());
3498 inline bool isHeaderDeletion(const tooling::Replacement
&Replace
) {
3499 return Replace
.getOffset() == UINT_MAX
&& Replace
.getLength() == 1;
3502 // FIXME: insert empty lines between newly created blocks.
3503 tooling::Replacements
3504 fixCppIncludeInsertions(StringRef Code
, const tooling::Replacements
&Replaces
,
3505 const FormatStyle
&Style
) {
3509 tooling::Replacements HeaderInsertions
;
3510 std::set
<llvm::StringRef
> HeadersToDelete
;
3511 tooling::Replacements Result
;
3512 for (const auto &R
: Replaces
) {
3513 if (isHeaderInsertion(R
)) {
3514 // Replacements from \p Replaces must be conflict-free already, so we can
3515 // simply consume the error.
3516 llvm::consumeError(HeaderInsertions
.add(R
));
3517 } else if (isHeaderDeletion(R
)) {
3518 HeadersToDelete
.insert(R
.getReplacementText());
3519 } else if (R
.getOffset() == UINT_MAX
) {
3520 llvm::errs() << "Insertions other than header #include insertion are "
3522 << R
.getReplacementText() << "\n";
3524 llvm::consumeError(Result
.add(R
));
3527 if (HeaderInsertions
.empty() && HeadersToDelete
.empty())
3530 StringRef FileName
= Replaces
.begin()->getFilePath();
3531 tooling::HeaderIncludes
Includes(FileName
, Code
, Style
.IncludeStyle
);
3533 for (const auto &Header
: HeadersToDelete
) {
3534 tooling::Replacements Replaces
=
3535 Includes
.remove(Header
.trim("\"<>"), Header
.startswith("<"));
3536 for (const auto &R
: Replaces
) {
3537 auto Err
= Result
.add(R
);
3539 // Ignore the deletion on conflict.
3540 llvm::errs() << "Failed to add header deletion replacement for "
3541 << Header
<< ": " << llvm::toString(std::move(Err
))
3547 llvm::SmallVector
<StringRef
, 4> Matches
;
3548 for (const auto &R
: HeaderInsertions
) {
3549 auto IncludeDirective
= R
.getReplacementText();
3551 tooling::HeaderIncludes::IncludeRegex
.match(IncludeDirective
, &Matches
);
3552 assert(Matched
&& "Header insertion replacement must have replacement text "
3555 auto IncludeName
= Matches
[2];
3557 Includes
.insert(IncludeName
.trim("\"<>"), IncludeName
.startswith("<"),
3558 tooling::IncludeDirective::Include
);
3560 auto Err
= Result
.add(*Replace
);
3562 llvm::consumeError(std::move(Err
));
3563 unsigned NewOffset
=
3564 Result
.getShiftedCodePosition(Replace
->getOffset());
3565 auto Shifted
= tooling::Replacement(FileName
, NewOffset
, 0,
3566 Replace
->getReplacementText());
3567 Result
= Result
.merge(tooling::Replacements(Shifted
));
3574 } // anonymous namespace
3576 llvm::Expected
<tooling::Replacements
>
3577 cleanupAroundReplacements(StringRef Code
, const tooling::Replacements
&Replaces
,
3578 const FormatStyle
&Style
) {
3579 // We need to use lambda function here since there are two versions of
3581 auto Cleanup
= [](const FormatStyle
&Style
, StringRef Code
,
3582 std::vector
<tooling::Range
> Ranges
,
3583 StringRef FileName
) -> tooling::Replacements
{
3584 return cleanup(Style
, Code
, Ranges
, FileName
);
3586 // Make header insertion replacements insert new headers into correct blocks.
3587 tooling::Replacements NewReplaces
=
3588 fixCppIncludeInsertions(Code
, Replaces
, Style
);
3589 return cantFail(processReplacements(Cleanup
, Code
, NewReplaces
, Style
));
3592 namespace internal
{
3593 std::pair
<tooling::Replacements
, unsigned>
3594 reformat(const FormatStyle
&Style
, StringRef Code
,
3595 ArrayRef
<tooling::Range
> Ranges
, unsigned FirstStartColumn
,
3596 unsigned NextStartColumn
, unsigned LastStartColumn
, StringRef FileName
,
3597 FormattingAttemptStatus
*Status
) {
3598 FormatStyle Expanded
= Style
;
3599 expandPresetsBraceWrapping(Expanded
);
3600 expandPresetsSpaceBeforeParens(Expanded
);
3601 expandPresetsSpacesInParens(Expanded
);
3602 Expanded
.InsertBraces
= false;
3603 Expanded
.RemoveBracesLLVM
= false;
3604 Expanded
.RemoveParentheses
= FormatStyle::RPS_Leave
;
3605 Expanded
.RemoveSemicolon
= false;
3606 switch (Expanded
.RequiresClausePosition
) {
3607 case FormatStyle::RCPS_SingleLine
:
3608 case FormatStyle::RCPS_WithPreceding
:
3609 Expanded
.IndentRequiresClause
= false;
3615 if (Expanded
.DisableFormat
)
3616 return {tooling::Replacements(), 0};
3617 if (isLikelyXml(Code
))
3618 return {tooling::Replacements(), 0};
3619 if (Expanded
.Language
== FormatStyle::LK_JavaScript
&& isMpegTS(Code
))
3620 return {tooling::Replacements(), 0};
3622 // JSON only needs the formatting passing.
3623 if (Style
.isJson()) {
3624 std::vector
<tooling::Range
> Ranges(1, tooling::Range(0, Code
.size()));
3625 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3626 NextStartColumn
, LastStartColumn
);
3629 // Perform the actual formatting pass.
3630 tooling::Replacements Replaces
=
3631 Formatter(*Env
, Style
, Status
).process().first
;
3632 // add a replacement to remove the "x = " from the result.
3633 Replaces
= Replaces
.merge(
3634 tooling::Replacements(tooling::Replacement(FileName
, 0, 4, "")));
3635 // apply the reformatting changes and the removal of "x = ".
3636 if (applyAllReplacements(Code
, Replaces
))
3637 return {Replaces
, 0};
3638 return {tooling::Replacements(), 0};
3641 auto Env
= Environment::make(Code
, FileName
, Ranges
, FirstStartColumn
,
3642 NextStartColumn
, LastStartColumn
);
3646 typedef std::function
<std::pair
<tooling::Replacements
, unsigned>(
3647 const Environment
&)>
3650 SmallVector
<AnalyzerPass
, 16> Passes
;
3652 Passes
.emplace_back([&](const Environment
&Env
) {
3653 return IntegerLiteralSeparatorFixer().process(Env
, Expanded
);
3656 if (Style
.isCpp()) {
3657 if (Style
.QualifierAlignment
!= FormatStyle::QAS_Leave
)
3658 addQualifierAlignmentFixerPasses(Expanded
, Passes
);
3660 if (Style
.RemoveParentheses
!= FormatStyle::RPS_Leave
) {
3661 FormatStyle S
= Expanded
;
3662 S
.RemoveParentheses
= Style
.RemoveParentheses
;
3663 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3664 return ParensRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3668 if (Style
.InsertBraces
) {
3669 FormatStyle S
= Expanded
;
3670 S
.InsertBraces
= true;
3671 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3672 return BracesInserter(Env
, S
).process(/*SkipAnnotation=*/true);
3676 if (Style
.RemoveBracesLLVM
) {
3677 FormatStyle S
= Expanded
;
3678 S
.RemoveBracesLLVM
= true;
3679 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3680 return BracesRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3684 if (Style
.RemoveSemicolon
) {
3685 FormatStyle S
= Expanded
;
3686 S
.RemoveSemicolon
= true;
3687 Passes
.emplace_back([&, S
= std::move(S
)](const Environment
&Env
) {
3688 return SemiRemover(Env
, S
).process(/*SkipAnnotation=*/true);
3692 if (Style
.FixNamespaceComments
) {
3693 Passes
.emplace_back([&](const Environment
&Env
) {
3694 return NamespaceEndCommentsFixer(Env
, Expanded
).process();
3698 if (Style
.SortUsingDeclarations
!= FormatStyle::SUD_Never
) {
3699 Passes
.emplace_back([&](const Environment
&Env
) {
3700 return UsingDeclarationsSorter(Env
, Expanded
).process();
3705 if (Style
.SeparateDefinitionBlocks
!= FormatStyle::SDS_Leave
) {
3706 Passes
.emplace_back([&](const Environment
&Env
) {
3707 return DefinitionBlockSeparator(Env
, Expanded
).process();
3711 if (Style
.isJavaScript() &&
3712 Style
.JavaScriptQuotes
!= FormatStyle::JSQS_Leave
) {
3713 Passes
.emplace_back([&](const Environment
&Env
) {
3714 return JavaScriptRequoter(Env
, Expanded
).process(/*SkipAnnotation=*/true);
3718 Passes
.emplace_back([&](const Environment
&Env
) {
3719 return Formatter(Env
, Expanded
, Status
).process();
3722 if (Style
.isJavaScript() &&
3723 Style
.InsertTrailingCommas
== FormatStyle::TCS_Wrapped
) {
3724 Passes
.emplace_back([&](const Environment
&Env
) {
3725 return TrailingCommaInserter(Env
, Expanded
).process();
3729 std::optional
<std::string
> CurrentCode
;
3730 tooling::Replacements Fixes
;
3731 unsigned Penalty
= 0;
3732 for (size_t I
= 0, E
= Passes
.size(); I
< E
; ++I
) {
3733 std::pair
<tooling::Replacements
, unsigned> PassFixes
= Passes
[I
](*Env
);
3734 auto NewCode
= applyAllReplacements(
3735 CurrentCode
? StringRef(*CurrentCode
) : Code
, PassFixes
.first
);
3737 Fixes
= Fixes
.merge(PassFixes
.first
);
3738 Penalty
+= PassFixes
.second
;
3740 CurrentCode
= std::move(*NewCode
);
3741 Env
= Environment::make(
3742 *CurrentCode
, FileName
,
3743 tooling::calculateRangesAfterReplacements(Fixes
, Ranges
),
3744 FirstStartColumn
, NextStartColumn
, LastStartColumn
);
3751 if (Style
.QualifierAlignment
!= FormatStyle::QAS_Leave
) {
3752 // Don't make replacements that replace nothing. QualifierAlignment can
3753 // produce them if one of its early passes changes e.g. `const volatile` to
3754 // `volatile const` and then a later pass changes it back again.
3755 tooling::Replacements NonNoOpFixes
;
3756 for (const tooling::Replacement
&Fix
: Fixes
) {
3757 StringRef OriginalCode
= Code
.substr(Fix
.getOffset(), Fix
.getLength());
3758 if (!OriginalCode
.equals(Fix
.getReplacementText())) {
3759 auto Err
= NonNoOpFixes
.add(Fix
);
3761 llvm::errs() << "Error adding replacements : "
3762 << llvm::toString(std::move(Err
)) << "\n";
3766 Fixes
= std::move(NonNoOpFixes
);
3769 return {Fixes
, Penalty
};
3771 } // namespace internal
3773 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3774 ArrayRef
<tooling::Range
> Ranges
,
3776 FormattingAttemptStatus
*Status
) {
3777 return internal::reformat(Style
, Code
, Ranges
,
3778 /*FirstStartColumn=*/0,
3779 /*NextStartColumn=*/0,
3780 /*LastStartColumn=*/0, FileName
, Status
)
3784 tooling::Replacements
cleanup(const FormatStyle
&Style
, StringRef Code
,
3785 ArrayRef
<tooling::Range
> Ranges
,
3786 StringRef FileName
) {
3787 // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3788 if (Style
.Language
!= FormatStyle::LK_Cpp
)
3789 return tooling::Replacements();
3790 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3793 return Cleaner(*Env
, Style
).process().first
;
3796 tooling::Replacements
reformat(const FormatStyle
&Style
, StringRef Code
,
3797 ArrayRef
<tooling::Range
> Ranges
,
3798 StringRef FileName
, bool *IncompleteFormat
) {
3799 FormattingAttemptStatus Status
;
3800 auto Result
= reformat(Style
, Code
, Ranges
, FileName
, &Status
);
3801 if (!Status
.FormatComplete
)
3802 *IncompleteFormat
= true;
3806 tooling::Replacements
fixNamespaceEndComments(const FormatStyle
&Style
,
3808 ArrayRef
<tooling::Range
> Ranges
,
3809 StringRef FileName
) {
3810 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3813 return NamespaceEndCommentsFixer(*Env
, Style
).process().first
;
3816 tooling::Replacements
sortUsingDeclarations(const FormatStyle
&Style
,
3818 ArrayRef
<tooling::Range
> Ranges
,
3819 StringRef FileName
) {
3820 auto Env
= Environment::make(Code
, FileName
, Ranges
);
3823 return UsingDeclarationsSorter(*Env
, Style
).process().first
;
3826 LangOptions
getFormattingLangOpts(const FormatStyle
&Style
) {
3827 LangOptions LangOpts
;
3829 FormatStyle::LanguageStandard LexingStd
= Style
.Standard
;
3830 if (LexingStd
== FormatStyle::LS_Auto
)
3831 LexingStd
= FormatStyle::LS_Latest
;
3832 if (LexingStd
== FormatStyle::LS_Latest
)
3833 LexingStd
= FormatStyle::LS_Cpp20
;
3834 LangOpts
.CPlusPlus
= 1;
3835 LangOpts
.CPlusPlus11
= LexingStd
>= FormatStyle::LS_Cpp11
;
3836 LangOpts
.CPlusPlus14
= LexingStd
>= FormatStyle::LS_Cpp14
;
3837 LangOpts
.CPlusPlus17
= LexingStd
>= FormatStyle::LS_Cpp17
;
3838 LangOpts
.CPlusPlus20
= LexingStd
>= FormatStyle::LS_Cpp20
;
3839 LangOpts
.Char8
= LexingStd
>= FormatStyle::LS_Cpp20
;
3840 // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3841 // the sequence "<::" will be unconditionally treated as "[:".
3842 // Cf. Lexer::LexTokenInternal.
3843 LangOpts
.Digraphs
= LexingStd
>= FormatStyle::LS_Cpp11
;
3845 LangOpts
.LineComment
= 1;
3846 bool AlternativeOperators
= Style
.isCpp();
3847 LangOpts
.CXXOperatorNames
= AlternativeOperators
? 1 : 0;
3850 LangOpts
.MicrosoftExt
= 1; // To get kw___try, kw___finally.
3851 LangOpts
.DeclSpecKeyword
= 1; // To get __declspec.
3852 LangOpts
.C99
= 1; // To get kw_restrict for non-underscore-prefixed restrict.
3856 const char *StyleOptionHelpDescription
=
3857 "Set coding style. <string> can be:\n"
3858 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3859 " Mozilla, WebKit.\n"
3860 "2. 'file' to load style configuration from a\n"
3861 " .clang-format file in one of the parent directories\n"
3862 " of the source file (for stdin, see --assume-filename).\n"
3863 " If no .clang-format file is found, falls back to\n"
3864 " --fallback-style.\n"
3865 " --style=file is the default.\n"
3866 "3. 'file:<format_file_path>' to explicitly specify\n"
3867 " the configuration file.\n"
3868 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3869 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3871 static FormatStyle::LanguageKind
getLanguageByFileName(StringRef FileName
) {
3872 if (FileName
.endswith(".java"))
3873 return FormatStyle::LK_Java
;
3874 if (FileName
.ends_with_insensitive(".js") ||
3875 FileName
.ends_with_insensitive(".mjs") ||
3876 FileName
.ends_with_insensitive(".ts")) {
3877 return FormatStyle::LK_JavaScript
; // (module) JavaScript or TypeScript.
3879 if (FileName
.endswith(".m") || FileName
.endswith(".mm"))
3880 return FormatStyle::LK_ObjC
;
3881 if (FileName
.ends_with_insensitive(".proto") ||
3882 FileName
.ends_with_insensitive(".protodevel")) {
3883 return FormatStyle::LK_Proto
;
3885 if (FileName
.ends_with_insensitive(".textpb") ||
3886 FileName
.ends_with_insensitive(".pb.txt") ||
3887 FileName
.ends_with_insensitive(".textproto") ||
3888 FileName
.ends_with_insensitive(".asciipb")) {
3889 return FormatStyle::LK_TextProto
;
3891 if (FileName
.ends_with_insensitive(".td"))
3892 return FormatStyle::LK_TableGen
;
3893 if (FileName
.ends_with_insensitive(".cs"))
3894 return FormatStyle::LK_CSharp
;
3895 if (FileName
.ends_with_insensitive(".json"))
3896 return FormatStyle::LK_Json
;
3897 if (FileName
.ends_with_insensitive(".sv") ||
3898 FileName
.ends_with_insensitive(".svh") ||
3899 FileName
.ends_with_insensitive(".v") ||
3900 FileName
.ends_with_insensitive(".vh")) {
3901 return FormatStyle::LK_Verilog
;
3903 return FormatStyle::LK_Cpp
;
3906 FormatStyle::LanguageKind
guessLanguage(StringRef FileName
, StringRef Code
) {
3907 const auto GuessedLanguage
= getLanguageByFileName(FileName
);
3908 if (GuessedLanguage
== FormatStyle::LK_Cpp
) {
3909 auto Extension
= llvm::sys::path::extension(FileName
);
3910 // If there's no file extension (or it's .h), we need to check the contents
3911 // of the code to see if it contains Objective-C.
3912 if (Extension
.empty() || Extension
== ".h") {
3913 auto NonEmptyFileName
= FileName
.empty() ? "guess.h" : FileName
;
3914 Environment
Env(Code
, NonEmptyFileName
, /*Ranges=*/{});
3915 ObjCHeaderStyleGuesser
Guesser(Env
, getLLVMStyle());
3917 if (Guesser
.isObjC())
3918 return FormatStyle::LK_ObjC
;
3921 return GuessedLanguage
;
3924 // Update StyleOptionHelpDescription above when changing this.
3925 const char *DefaultFormatStyle
= "file";
3927 const char *DefaultFallbackStyle
= "LLVM";
3929 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>
3930 loadAndParseConfigFile(StringRef ConfigFile
, llvm::vfs::FileSystem
*FS
,
3931 FormatStyle
*Style
, bool AllowUnknownOptions
) {
3932 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
3933 FS
->getBufferForFile(ConfigFile
.str());
3934 if (auto EC
= Text
.getError())
3936 if (auto EC
= parseConfiguration(*Text
.get(), Style
, AllowUnknownOptions
))
3941 llvm::Expected
<FormatStyle
> getStyle(StringRef StyleName
, StringRef FileName
,
3942 StringRef FallbackStyleName
,
3943 StringRef Code
, llvm::vfs::FileSystem
*FS
,
3944 bool AllowUnknownOptions
) {
3946 FS
= llvm::vfs::getRealFileSystem().get();
3947 FormatStyle Style
= getLLVMStyle(guessLanguage(FileName
, Code
));
3949 FormatStyle FallbackStyle
= getNoStyle();
3950 if (!getPredefinedStyle(FallbackStyleName
, Style
.Language
, &FallbackStyle
))
3951 return make_string_error("Invalid fallback style: " + FallbackStyleName
);
3953 llvm::SmallVector
<std::unique_ptr
<llvm::MemoryBuffer
>, 1>
3954 ChildFormatTextToApply
;
3956 if (StyleName
.startswith("{")) {
3957 // Parse YAML/JSON style from the command line.
3958 StringRef Source
= "<command-line>";
3959 if (std::error_code ec
=
3960 parseConfiguration(llvm::MemoryBufferRef(StyleName
, Source
), &Style
,
3961 AllowUnknownOptions
)) {
3962 return make_string_error("Error parsing -style: " + ec
.message());
3964 if (Style
.InheritsParentConfig
) {
3965 ChildFormatTextToApply
.emplace_back(
3966 llvm::MemoryBuffer::getMemBuffer(StyleName
, Source
, false));
3972 // User provided clang-format file using -style=file:path/to/format/file.
3973 if (!Style
.InheritsParentConfig
&&
3974 StyleName
.starts_with_insensitive("file:")) {
3975 auto ConfigFile
= StyleName
.substr(5);
3976 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
3977 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
);
3978 if (auto EC
= Text
.getError()) {
3979 return make_string_error("Error reading " + ConfigFile
+ ": " +
3983 LLVM_DEBUG(llvm::dbgs()
3984 << "Using configuration file " << ConfigFile
<< "\n");
3986 if (!Style
.InheritsParentConfig
)
3989 // Search for parent configs starting from the parent directory of
3991 FileName
= ConfigFile
;
3992 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
3995 // If the style inherits the parent configuration it is a command line
3996 // configuration, which wants to inherit, so we have to skip the check of the
3998 if (!Style
.InheritsParentConfig
&& !StyleName
.equals_insensitive("file")) {
3999 if (!getPredefinedStyle(StyleName
, Style
.Language
, &Style
))
4000 return make_string_error("Invalid value for -style");
4001 if (!Style
.InheritsParentConfig
)
4005 // Reset possible inheritance
4006 Style
.InheritsParentConfig
= false;
4008 // Look for .clang-format/_clang-format file in the file's parent directories.
4009 SmallString
<128> UnsuitableConfigFiles
;
4010 SmallString
<128> Path(FileName
);
4011 if (std::error_code EC
= FS
->makeAbsolute(Path
))
4012 return make_string_error(EC
.message());
4014 llvm::SmallVector
<std::string
, 2> FilesToLookFor
;
4015 FilesToLookFor
.push_back(".clang-format");
4016 FilesToLookFor
.push_back("_clang-format");
4018 auto dropDiagnosticHandler
= [](const llvm::SMDiagnostic
&, void *) {};
4020 auto applyChildFormatTexts
= [&](FormatStyle
*Style
) {
4021 for (const auto &MemBuf
: llvm::reverse(ChildFormatTextToApply
)) {
4022 auto EC
= parseConfiguration(*MemBuf
, Style
, AllowUnknownOptions
,
4023 dropDiagnosticHandler
);
4024 // It was already correctly parsed.
4026 static_cast<void>(EC
);
4030 for (StringRef Directory
= Path
; !Directory
.empty();
4031 Directory
= llvm::sys::path::parent_path(Directory
)) {
4033 auto Status
= FS
->status(Directory
);
4035 Status
->getType() != llvm::sys::fs::file_type::directory_file
) {
4039 for (const auto &F
: FilesToLookFor
) {
4040 SmallString
<128> ConfigFile(Directory
);
4042 llvm::sys::path::append(ConfigFile
, F
);
4043 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile
<< "...\n");
4045 Status
= FS
->status(ConfigFile
.str());
4048 (Status
->getType() == llvm::sys::fs::file_type::regular_file
)) {
4049 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Text
=
4050 loadAndParseConfigFile(ConfigFile
, FS
, &Style
, AllowUnknownOptions
);
4051 if (auto EC
= Text
.getError()) {
4052 if (EC
== ParseError::Unsuitable
) {
4053 if (!UnsuitableConfigFiles
.empty())
4054 UnsuitableConfigFiles
.append(", ");
4055 UnsuitableConfigFiles
.append(ConfigFile
);
4058 return make_string_error("Error reading " + ConfigFile
+ ": " +
4061 LLVM_DEBUG(llvm::dbgs()
4062 << "Using configuration file " << ConfigFile
<< "\n");
4064 if (!Style
.InheritsParentConfig
) {
4065 if (ChildFormatTextToApply
.empty())
4068 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4069 applyChildFormatTexts(&Style
);
4074 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4076 // Reset inheritance of style
4077 Style
.InheritsParentConfig
= false;
4079 ChildFormatTextToApply
.emplace_back(std::move(*Text
));
4081 // Breaking out of the inner loop, since we don't want to parse
4082 // .clang-format AND _clang-format, if both exist. Then we continue the
4083 // inner loop (parent directories) in search for the parent
4089 if (!UnsuitableConfigFiles
.empty()) {
4090 return make_string_error("Configuration file(s) do(es) not support " +
4091 getLanguageName(Style
.Language
) + ": " +
4092 UnsuitableConfigFiles
);
4095 if (!ChildFormatTextToApply
.empty()) {
4096 LLVM_DEBUG(llvm::dbgs()
4097 << "Applying child configurations on fallback style\n");
4098 applyChildFormatTexts(&FallbackStyle
);
4101 return FallbackStyle
;
4104 static bool isClangFormatOnOff(StringRef Comment
, bool On
) {
4105 if (Comment
== (On
? "/* clang-format on */" : "/* clang-format off */"))
4108 static const char ClangFormatOn
[] = "// clang-format on";
4109 static const char ClangFormatOff
[] = "// clang-format off";
4110 const unsigned Size
= (On
? sizeof ClangFormatOn
: sizeof ClangFormatOff
) - 1;
4112 return Comment
.startswith(On
? ClangFormatOn
: ClangFormatOff
) &&
4113 (Comment
.size() == Size
|| Comment
[Size
] == ':');
4116 bool isClangFormatOn(StringRef Comment
) {
4117 return isClangFormatOnOff(Comment
, /*On=*/true);
4120 bool isClangFormatOff(StringRef Comment
) {
4121 return isClangFormatOnOff(Comment
, /*On=*/false);
4124 } // namespace format
4125 } // namespace clang