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