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