clang: lib/Format/Format.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
25#include "llvm/ADT/Sequence.h"
26
27#define DEBUG_TYPE "format-formatter"
28
30
31LLVM_YAML_IS_SEQUENCE_VECTOR(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", FormatStyle::AlignConsecutiveStyle({}));
48 IO.enumCase(Value, "Consecutive",
49 FormatStyle::AlignConsecutiveStyle(
50 {true, false,
51 false, false,
52 true,
53 false, true}));
54 IO.enumCase(Value, "AcrossEmptyLines",
55 FormatStyle::AlignConsecutiveStyle(
56 {true, true,
57 false, false,
58 true,
59 false, true}));
60 IO.enumCase(Value, "AcrossComments",
61 FormatStyle::AlignConsecutiveStyle(
62 {true, false,
63 true, false,
64 true,
65 false, true}));
66 IO.enumCase(Value, "AcrossEmptyLinesAndComments",
67 FormatStyle::AlignConsecutiveStyle(
68 {true, true,
69 true, false,
70 true,
71 false, true}));
72
73
74 IO.enumCase(Value, "true",
75 FormatStyle::AlignConsecutiveStyle(
76 {true, false,
77 false, false,
78 true,
79 false, true}));
80 IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));
81 }
82
83 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
84 IO.mapOptional("Enabled", Value.Enabled);
85 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
86 IO.mapOptional("AcrossComments", Value.AcrossComments);
87 IO.mapOptional("AlignCompound", Value.AlignCompound);
88 IO.mapOptional("AlignFunctionDeclarations",
89 Value.AlignFunctionDeclarations);
90 IO.mapOptional("AlignFunctionPointers", Value.AlignFunctionPointers);
91 IO.mapOptional("PadOperators", Value.PadOperators);
92 }
93};
94
95template <>
96struct MappingTraits<FormatStyle::ShortCaseStatementsAlignmentStyle> {
98 FormatStyle::ShortCaseStatementsAlignmentStyle &Value) {
99 IO.mapOptional("Enabled", Value.Enabled);
100 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
101 IO.mapOptional("AcrossComments", Value.AcrossComments);
102 IO.mapOptional("AlignCaseArrows", Value.AlignCaseArrows);
103 IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);
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> {
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 <>
137struct ScalarEnumerationTraits<FormatStyle::BinPackParametersStyle> {
138 static void enumeration(IO &IO, FormatStyle::BinPackParametersStyle &Value) {
139 IO.enumCase(Value, "BinPack", FormatStyle::BPPS_BinPack);
140 IO.enumCase(Value, "OnePerLine", FormatStyle::BPPS_OnePerLine);
141 IO.enumCase(Value, "AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine);
142
143
144 IO.enumCase(Value, "true", FormatStyle::BPPS_BinPack);
145 IO.enumCase(Value, "false", FormatStyle::BPPS_OnePerLine);
146 }
147};
148
149template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
151 IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
152 IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
153 IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
154 }
155};
156
157template <>
158struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
160 FormatStyle::BitFieldColonSpacingStyle &Value) {
161 IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);
162 IO.enumCase(Value, "None", FormatStyle::BFCS_None);
163 IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);
164 IO.enumCase(Value, "After", FormatStyle::BFCS_After);
165 }
166};
167
168template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
169 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
170 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
171 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
172 IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
173 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
174 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
175 IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
176 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
177 IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
178 IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
179 }
180};
181
182template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
183 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
184 IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
185 IO.mapOptional("AfterClass", Wrapping.AfterClass);
186 IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
187 IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
188 IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
189 IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
190 IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
191 IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
192 IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
193 IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
194 IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
195 IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
196 IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
197 IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
198 IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
199 IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
200 IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
201 IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
202 }
203};
204
205template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
206 static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {
207 IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
208 IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
209 IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
210 IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent);
211
212
213 IO.enumCase(Value, "true", FormatStyle::BAS_Align);
214 IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);
215 }
216};
217
218template <>
219struct ScalarEnumerationTraits<
220 FormatStyle::BraceWrappingAfterControlStatementStyle> {
221 static void
223 FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {
224 IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);
225 IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);
226 IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
227
228
229 IO.enumCase(Value, "false", FormatStyle::BWACS_Never);
230 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
231 }
232};
233
234template <>
235struct ScalarEnumerationTraits<
236 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
237 static void
238 enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value) {
239 IO.enumCase(Value, "Never", FormatStyle::BBCDS_Never);
240 IO.enumCase(Value, "Allowed", FormatStyle::BBCDS_Allowed);
241 IO.enumCase(Value, "Always", FormatStyle::BBCDS_Always);
242
243
244 IO.enumCase(Value, "true", FormatStyle::BBCDS_Always);
245 IO.enumCase(Value, "false", FormatStyle::BBCDS_Allowed);
246 }
247};
248
249template <>
250struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
252 FormatStyle::BreakBeforeInlineASMColonStyle &Value) {
253 IO.enumCase(Value, "Never", FormatStyle::BBIAS_Never);
254 IO.enumCase(Value, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
255 IO.enumCase(Value, "Always", FormatStyle::BBIAS_Always);
256 }
257};
258
259template <>
260struct ScalarEnumerationTraits<FormatStyle::BreakBinaryOperationsStyle> {
262 FormatStyle::BreakBinaryOperationsStyle &Value) {
263 IO.enumCase(Value, "Never", FormatStyle::BBO_Never);
264 IO.enumCase(Value, "OnePerLine", FormatStyle::BBO_OnePerLine);
265 IO.enumCase(Value, "RespectPrecedence", FormatStyle::BBO_RespectPrecedence);
266 }
267};
268
269template <>
270struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
271 static void
272 enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
273 IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
274 IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
275 IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
276 }
277};
278
279template <>
280struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
282 FormatStyle::BreakInheritanceListStyle &Value) {
283 IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
284 IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
285 IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
286 IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
287 }
288};
289
290template <>
291struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
293 FormatStyle::BreakTemplateDeclarationsStyle &Value) {
294 IO.enumCase(Value, "Leave", FormatStyle::BTDS_Leave);
295 IO.enumCase(Value, "No", FormatStyle::BTDS_No);
296 IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
297 IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
298
299
300 IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
301 IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
302 }
303};
304
305template <> struct ScalarEnumerationTraits<FormatStyle::DAGArgStyle> {
307 IO.enumCase(Value, "DontBreak", FormatStyle::DAS_DontBreak);
308 IO.enumCase(Value, "BreakElements", FormatStyle::DAS_BreakElements);
309 IO.enumCase(Value, "BreakAll", FormatStyle::DAS_BreakAll);
310 }
311};
312
313template <>
314struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
315 static void
316 enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
317 IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
318 IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
319 IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
320
321
322 IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
323 IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
324 }
325};
326
327template <>
328struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
330 FormatStyle::EscapedNewlineAlignmentStyle &Value) {
331 IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
332 IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
333 IO.enumCase(Value, "LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);
334 IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
335
336
337 IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
338 IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
339 }
340};
341
342template <>
343struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
344 static void
345 enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
346 IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
347 IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
348 IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
349 }
350};
351
352template <>
353struct ScalarEnumerationTraits<
354 FormatStyle::EmptyLineBeforeAccessModifierStyle> {
355 static void
356 enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
357 IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
358 IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
359 IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
360 IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
361 }
362};
363
364template <>
365struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
366 static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
367 IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
368 IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
369 IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
370 IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
371 IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
372 }
373};
374
375template <> struct MappingTraits<FormatStyle::IntegerLiteralSeparatorStyle> {
376 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base) {
377 IO.mapOptional("Binary", Base.Binary);
378 IO.mapOptional("BinaryMinDigits", Base.BinaryMinDigits);
379 IO.mapOptional("Decimal", Base.Decimal);
380 IO.mapOptional("DecimalMinDigits", Base.DecimalMinDigits);
381 IO.mapOptional("Hex", Base.Hex);
382 IO.mapOptional("HexMinDigits", Base.HexMinDigits);
383 }
384};
385
386template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
387 static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
388 IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
389 IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
390 IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
391 }
392};
393
394template <> struct MappingTraits<FormatStyle::KeepEmptyLinesStyle> {
395 static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value) {
396 IO.mapOptional("AtEndOfFile", Value.AtEndOfFile);
397 IO.mapOptional("AtStartOfBlock", Value.AtStartOfBlock);
398 IO.mapOptional("AtStartOfFile", Value.AtStartOfFile);
399 }
400};
401
402template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
404 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
405 IO.enumCase(Value, "Java", FormatStyle::LK_Java);
406 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
407 IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
408 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
409 IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
410 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
411 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
412 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
413 IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
414 }
415};
416
417template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
419 IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);
420 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);
421 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03);
422
423 IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);
424 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);
425
426 IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);
427 IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);
428 IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);
429
430 IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);
431 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest);
432 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
433 }
434};
435
436template <>
437struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> {
439 FormatStyle::LambdaBodyIndentationKind &Value) {
440 IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature);
441 IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope);
442 }
443};
444
445template <> struct ScalarEnumerationTraits<FormatStyle::LineEndingStyle> {
447 IO.enumCase(Value, "LF", FormatStyle::LE_LF);
448 IO.enumCase(Value, "CRLF", FormatStyle::LE_CRLF);
449 IO.enumCase(Value, "DeriveLF", FormatStyle::LE_DeriveLF);
450 IO.enumCase(Value, "DeriveCRLF", FormatStyle::LE_DeriveCRLF);
451 }
452};
453
454template <>
455struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
457 FormatStyle::NamespaceIndentationKind &Value) {
458 IO.enumCase(Value, "None", FormatStyle::NI_None);
459 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
460 IO.enumCase(Value, "All", FormatStyle::NI_All);
461 }
462};
463
464template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
465 static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
466 IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
467 IO.enumCase(Value, "Align", FormatStyle::OAS_Align);
468 IO.enumCase(Value, "AlignAfterOperator",
469 FormatStyle::OAS_AlignAfterOperator);
470
471
472 IO.enumCase(Value, "true", FormatStyle::OAS_Align);
473 IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);
474 }
475};
476
477template <>
478struct ScalarEnumerationTraits<FormatStyle::PackConstructorInitializersStyle> {
479 static void
480 enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value) {
481 IO.enumCase(Value, "Never", FormatStyle::PCIS_Never);
482 IO.enumCase(Value, "BinPack", FormatStyle::PCIS_BinPack);
483 IO.enumCase(Value, "CurrentLine", FormatStyle::PCIS_CurrentLine);
484 IO.enumCase(Value, "NextLine", FormatStyle::PCIS_NextLine);
485 IO.enumCase(Value, "NextLineOnly", FormatStyle::PCIS_NextLineOnly);
486 }
487};
488
489template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
490 static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
491 IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
492 IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
493 IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
494
495
496 IO.enumCase(Value, "true", FormatStyle::PAS_Left);
497 IO.enumCase(Value, "false", FormatStyle::PAS_Right);
498 }
499};
500
501template <>
502struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
503 static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
504 IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
505 IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
506 IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
507 }
508};
509
510template <>
511struct ScalarEnumerationTraits<FormatStyle::QualifierAlignmentStyle> {
512 static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value) {
513 IO.enumCase(Value, "Leave", FormatStyle::QAS_Leave);
514 IO.enumCase(Value, "Left", FormatStyle::QAS_Left);
515 IO.enumCase(Value, "Right", FormatStyle::QAS_Right);
516 IO.enumCase(Value, "Custom", FormatStyle::QAS_Custom);
517 }
518};
519
520template <> struct MappingTraits<FormatStyle::RawStringFormat> {
521 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
522 IO.mapOptional("Language", Format.Language);
523 IO.mapOptional("Delimiters", Format.Delimiters);
524 IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
525 IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
526 IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
527 }
528};
529
530template <> struct ScalarEnumerationTraits<FormatStyle::ReflowCommentsStyle> {
531 static void enumeration(IO &IO, FormatStyle::ReflowCommentsStyle &Value) {
532 IO.enumCase(Value, "Never", FormatStyle::RCS_Never);
533 IO.enumCase(Value, "IndentOnly", FormatStyle::RCS_IndentOnly);
534 IO.enumCase(Value, "Always", FormatStyle::RCS_Always);
535
536 IO.enumCase(Value, "false", FormatStyle::RCS_Never);
537 IO.enumCase(Value, "true", FormatStyle::RCS_Always);
538 }
539};
540
541template <>
542struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> {
543 static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) {
544 IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer);
545 IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle);
546 IO.enumCase(Value, "Left", FormatStyle::RAS_Left);
547 IO.enumCase(Value, "Right", FormatStyle::RAS_Right);
548 }
549};
550
551template <>
552struct ScalarEnumerationTraits<FormatStyle::RemoveParenthesesStyle> {
553 static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value) {
554 IO.enumCase(Value, "Leave", FormatStyle::RPS_Leave);
555 IO.enumCase(Value, "MultipleParentheses",
556 FormatStyle::RPS_MultipleParentheses);
557 IO.enumCase(Value, "ReturnStatement", FormatStyle::RPS_ReturnStatement);
558 }
559};
560
561template <>
562struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> {
564 FormatStyle::RequiresClausePositionStyle &Value) {
565 IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine);
566 IO.enumCase(Value, "OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace);
567 IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding);
568 IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing);
569 IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine);
570 }
571};
572
573template <>
574struct ScalarEnumerationTraits<FormatStyle::RequiresExpressionIndentationKind> {
575 static void
576 enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value) {
577 IO.enumCase(Value, "Keyword", FormatStyle::REI_Keyword);
578 IO.enumCase(Value, "OuterScope", FormatStyle::REI_OuterScope);
579 }
580};
581
582template <>
583struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
584 static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
585 IO.enumCase(Value, "None", FormatStyle::RTBS_None);
586 IO.enumCase(Value, "Automatic", FormatStyle::RTBS_Automatic);
587 IO.enumCase(Value, "ExceptShortType", FormatStyle::RTBS_ExceptShortType);
588 IO.enumCase(Value, "All", FormatStyle::RTBS_All);
589 IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
590 IO.enumCase(Value, "TopLevelDefinitions",
591 FormatStyle::RTBS_TopLevelDefinitions);
592 IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
593 }
594};
595
596template <>
597struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> {
598 static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) {
599 IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave);
600 IO.enumCase(Value, "Always", FormatStyle::SDS_Always);
601 IO.enumCase(Value, "Never", FormatStyle::SDS_Never);
602 }
603};
604
605template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
607 IO.enumCase(Value, "Never", FormatStyle::SBS_Never);
608 IO.enumCase(Value, "false", FormatStyle::SBS_Never);
609 IO.enumCase(Value, "Always", FormatStyle::SBS_Always);
610 IO.enumCase(Value, "true", FormatStyle::SBS_Always);
611 IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);
612 }
613};
614
615template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
616 static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
617 IO.enumCase(Value, "None", FormatStyle::SFS_None);
618 IO.enumCase(Value, "false", FormatStyle::SFS_None);
619 IO.enumCase(Value, "All", FormatStyle::SFS_All);
620 IO.enumCase(Value, "true", FormatStyle::SFS_All);
621 IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
622 IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
623 IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
624 }
625};
626
627template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
629 IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
630 IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
631 IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
632 IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
633
634
635 IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
636 IO.enumCase(Value, "false", FormatStyle::SIS_Never);
637 IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
638 }
639};
640
641template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
643 IO.enumCase(Value, "None", FormatStyle::SLS_None);
644 IO.enumCase(Value, "false", FormatStyle::SLS_None);
645 IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
646 IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
647 IO.enumCase(Value, "All", FormatStyle::SLS_All);
648 IO.enumCase(Value, "true", FormatStyle::SLS_All);
649 }
650};
651
652template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {
653 static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {
654 IO.enumCase(Value, "Never", FormatStyle::SI_Never);
655 IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);
656 IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);
657
658
659 IO.enumCase(Value, "false", FormatStyle::SI_Never);
660 IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);
661 }
662};
663
664template <>
665struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
667 FormatStyle::SortJavaStaticImportOptions &Value) {
668 IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
669 IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
670 }
671};
672
673template <>
674struct ScalarEnumerationTraits<FormatStyle::SortUsingDeclarationsOptions> {
676 FormatStyle::SortUsingDeclarationsOptions &Value) {
677 IO.enumCase(Value, "Never", FormatStyle::SUD_Never);
678 IO.enumCase(Value, "Lexicographic", FormatStyle::SUD_Lexicographic);
679 IO.enumCase(Value, "LexicographicNumeric",
680 FormatStyle::SUD_LexicographicNumeric);
681
682
683 IO.enumCase(Value, "false", FormatStyle::SUD_Never);
684 IO.enumCase(Value, "true", FormatStyle::SUD_LexicographicNumeric);
685 }
686};
687
688template <>
689struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
690 static void
691 enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
692 IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
693 IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
694 IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
695 IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
696 }
697};
698
699template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> {
700 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
701 IO.mapOptional("AfterControlStatements", Spacing.AfterControlStatements);
702 IO.mapOptional("AfterForeachMacros", Spacing.AfterForeachMacros);
703 IO.mapOptional("AfterFunctionDefinitionName",
704 Spacing.AfterFunctionDefinitionName);
705 IO.mapOptional("AfterFunctionDeclarationName",
706 Spacing.AfterFunctionDeclarationName);
707 IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
708 IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
709 IO.mapOptional("AfterPlacementOperator", Spacing.AfterPlacementOperator);
710 IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause);
711 IO.mapOptional("AfterRequiresInExpression",
712 Spacing.AfterRequiresInExpression);
713 IO.mapOptional("BeforeNonEmptyParentheses",
714 Spacing.BeforeNonEmptyParentheses);
715 }
716};
717
718template <>
719struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> {
720 static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value) {
721 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
722 IO.enumCase(Value, "ControlStatements",
723 FormatStyle::SBPO_ControlStatements);
724 IO.enumCase(Value, "ControlStatementsExceptControlMacros",
725 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
726 IO.enumCase(Value, "NonEmptyParentheses",
727 FormatStyle::SBPO_NonEmptyParentheses);
728 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
729 IO.enumCase(Value, "Custom", FormatStyle::SBPO_Custom);
730
731
732 IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
733 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
734 IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
735 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
736 }
737};
738
739template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
740 static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
741 IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
742 IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
743 IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
744
745
746 IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
747 IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
748 }
749};
750
751template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
752 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
753
754 int signedMaximum = static_cast<int>(Space.Maximum);
755 IO.mapOptional("Minimum", Space.Minimum);
756 IO.mapOptional("Maximum", signedMaximum);
757 Space.Maximum = static_cast<unsigned>(signedMaximum);
758
759 if (Space.Maximum != -1u)
760 Space.Minimum = std::min(Space.Minimum, Space.Maximum);
761 }
762};
763
764template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
765 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
766 IO.mapOptional("ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
767 IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
768 IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
769 IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
770 IO.mapOptional("Other", Spaces.Other);
771 }
772};
773
774template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensStyle> {
775 static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value) {
776 IO.enumCase(Value, "Never", FormatStyle::SIPO_Never);
777 IO.enumCase(Value, "Custom", FormatStyle::SIPO_Custom);
778 }
779};
780
781template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {
782 static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {
783 IO.enumCase(Value, "None", FormatStyle::TCS_None);
784 IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);
785 }
786};
787
788template <>
789struct ScalarEnumerationTraits<FormatStyle::TrailingCommentsAlignmentKinds> {
791 FormatStyle::TrailingCommentsAlignmentKinds &Value) {
792 IO.enumCase(Value, "Leave", FormatStyle::TCAS_Leave);
793 IO.enumCase(Value, "Always", FormatStyle::TCAS_Always);
794 IO.enumCase(Value, "Never", FormatStyle::TCAS_Never);
795 }
796};
797
798template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> {
800 FormatStyle::TrailingCommentsAlignmentStyle &Value) {
801 IO.enumCase(Value, "Leave",
802 FormatStyle::TrailingCommentsAlignmentStyle(
803 {FormatStyle::TCAS_Leave, 0}));
804
805 IO.enumCase(Value, "Always",
806 FormatStyle::TrailingCommentsAlignmentStyle(
807 {FormatStyle::TCAS_Always, 0}));
808
809 IO.enumCase(Value, "Never",
810 FormatStyle::TrailingCommentsAlignmentStyle(
811 {FormatStyle::TCAS_Never, 0}));
812
813
814 IO.enumCase(Value, "true",
815 FormatStyle::TrailingCommentsAlignmentStyle(
816 {FormatStyle::TCAS_Always, 0}));
817 IO.enumCase(Value, "false",
818 FormatStyle::TrailingCommentsAlignmentStyle(
819 {FormatStyle::TCAS_Never, 0}));
820 }
821
823 FormatStyle::TrailingCommentsAlignmentStyle &Value) {
824 IO.mapOptional("Kind", Value.Kind);
825 IO.mapOptional("OverEmptyLines", Value.OverEmptyLines);
826 }
827};
828
829template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
831 IO.enumCase(Value, "Never", FormatStyle::UT_Never);
832 IO.enumCase(Value, "false", FormatStyle::UT_Never);
833 IO.enumCase(Value, "Always", FormatStyle::UT_Always);
834 IO.enumCase(Value, "true", FormatStyle::UT_Always);
835 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
836 IO.enumCase(Value, "ForContinuationAndIndentation",
837 FormatStyle::UT_ForContinuationAndIndentation);
838 IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
839 }
840};
841
842template <>
843struct ScalarEnumerationTraits<
844 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
845 static void
847 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value) {
848 IO.enumCase(Value, "Never", FormatStyle::WNBWELS_Never);
849 IO.enumCase(Value, "Always", FormatStyle::WNBWELS_Always);
850 IO.enumCase(Value, "Leave", FormatStyle::WNBWELS_Leave);
851 }
852};
853
856
857 IO.mapOptional("Language", Style.Language);
858
859 StringRef BasedOnStyle;
860 if (IO.outputting()) {
861 StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla",
862 "WebKit", "GNU", "Microsoft", "clang-format"};
863 for (StringRef StyleName : Styles) {
865 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
866 Style == PredefinedStyle) {
867 BasedOnStyle = StyleName;
868 break;
869 }
870 }
871 } else {
872 IO.mapOptional("BasedOnStyle", BasedOnStyle);
873 if (!BasedOnStyle.empty()) {
874 FormatStyle::LanguageKind OldLanguage = Style.Language;
875 FormatStyle::LanguageKind Language =
876 ((FormatStyle *)IO.getContext())->Language;
877 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
878 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
879 return;
880 }
881 Style.Language = OldLanguage;
882 }
883 }
884
885
886
887
888
889
890
891
892
893
894
895
896 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive("google") ||
897 BasedOnStyle.equals_insensitive("chromium");
898 bool OnCurrentLine = IsGoogleOrChromium;
899 bool OnNextLine = true;
900
901 bool BreakBeforeInheritanceComma = false;
902 bool BreakConstructorInitializersBeforeComma = false;
903
904 bool DeriveLineEnding = true;
905 bool UseCRLF = false;
906
907 bool SpaceInEmptyParentheses = false;
908 bool SpacesInConditionalStatement = false;
909 bool SpacesInCStyleCastParentheses = false;
910 bool SpacesInParentheses = false;
911
912
913 if (!IO.outputting()) {
915 IO.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine);
917 IO.mapOptional("AlwaysBreakTemplateDeclarations",
919 IO.mapOptional("BreakBeforeInheritanceComma",
920 BreakBeforeInheritanceComma);
921 IO.mapOptional("BreakConstructorInitializersBeforeComma",
922 BreakConstructorInitializersBeforeComma);
923 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
924 OnCurrentLine);
925 IO.mapOptional("DeriveLineEnding", DeriveLineEnding);
928 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
930 IO.mapOptional("IndentFunctionDeclarationAfterType",
933 IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
934 IO.mapOptional("SpaceAfterControlStatementKeyword",
936 IO.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses);
937 IO.mapOptional("SpacesInConditionalStatement",
938 SpacesInConditionalStatement);
939 IO.mapOptional("SpacesInCStyleCastParentheses",
940 SpacesInCStyleCastParentheses);
941 IO.mapOptional("SpacesInParentheses", SpacesInParentheses);
942 IO.mapOptional("UseCRLF", UseCRLF);
943 }
944
948 IO.mapOptional("AlignConsecutiveAssignments",
950 IO.mapOptional("AlignConsecutiveBitFields",
952 IO.mapOptional("AlignConsecutiveDeclarations",
955 IO.mapOptional("AlignConsecutiveShortCaseStatements",
957 IO.mapOptional("AlignConsecutiveTableGenBreakingDAGArgColons",
959 IO.mapOptional("AlignConsecutiveTableGenCondOperatorColons",
961 IO.mapOptional("AlignConsecutiveTableGenDefinitionColons",
964 IO.mapOptional("AlignOperands", Style.AlignOperands);
966 IO.mapOptional("AllowAllArgumentsOnNextLine",
968 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
970 IO.mapOptional("AllowBreakBeforeNoexceptSpecifier",
972 IO.mapOptional("AllowShortBlocksOnASingleLine",
974 IO.mapOptional("AllowShortCaseExpressionOnASingleLine",
976 IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
978 IO.mapOptional("AllowShortCompoundRequirementOnASingleLine",
980 IO.mapOptional("AllowShortEnumsOnASingleLine",
982 IO.mapOptional("AllowShortFunctionsOnASingleLine",
984 IO.mapOptional("AllowShortIfStatementsOnASingleLine",
986 IO.mapOptional("AllowShortLambdasOnASingleLine",
988 IO.mapOptional("AllowShortLoopsOnASingleLine",
990 IO.mapOptional("AllowShortNamespacesOnASingleLine",
992 IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
994 IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
996 IO.mapOptional("AttributeMacros", Style.AttributeMacros);
1000 IO.mapOptional("BracedInitializerIndentWidth",
1002 IO.mapOptional("BraceWrapping", Style.BraceWrapping);
1003 IO.mapOptional("BreakAdjacentStringLiterals",
1006 IO.mapOptional("BreakAfterJavaFieldAnnotations",
1009 IO.mapOptional("BreakArrays", Style.BreakArrays);
1010 IO.mapOptional("BreakBeforeBinaryOperators",
1012 IO.mapOptional("BreakBeforeConceptDeclarations",
1015 IO.mapOptional("BreakBeforeInlineASMColon",
1017 IO.mapOptional("BreakBeforeTernaryOperators",
1020 IO.mapOptional("BreakConstructorInitializers",
1022 IO.mapOptional("BreakFunctionDefinitionParameters",
1026 IO.mapOptional("BreakTemplateDeclarations",
1028 IO.mapOptional("ColumnLimit", Style.ColumnLimit);
1029 IO.mapOptional("CommentPragmas", Style.CommentPragmas);
1031 IO.mapOptional("ConstructorInitializerIndentWidth",
1036 IO.mapOptional("DisableFormat", Style.DisableFormat);
1037 IO.mapOptional("EmptyLineAfterAccessModifier",
1039 IO.mapOptional("EmptyLineBeforeAccessModifier",
1041 IO.mapOptional("ExperimentalAutoDetectBinPacking",
1044 IO.mapOptional("ForEachMacros", Style.ForEachMacros);
1045 IO.mapOptional("IfMacros", Style.IfMacros);
1049 IO.mapOptional("IncludeIsMainSourceRegex",
1059 IO.mapOptional("IndentWidth", Style.IndentWidth);
1060 IO.mapOptional("IndentWrappedFunctionNames",
1062 IO.mapOptional("InsertBraces", Style.InsertBraces);
1069 IO.mapOptional("KeepEmptyLines", Style.KeepEmptyLines);
1070 IO.mapOptional("KeepFormFeed", Style.KeepFormFeed);
1072 IO.mapOptional("LineEnding", Style.LineEnding);
1073 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
1074 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
1075 IO.mapOptional("Macros", Style.Macros);
1079 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
1082 IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
1084 IO.mapOptional("ObjCPropertyAttributeOrder",
1087 IO.mapOptional("ObjCSpaceBeforeProtocolList",
1089 IO.mapOptional("PackConstructorInitializers",
1092 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1095 IO.mapOptional("PenaltyBreakFirstLessLess",
1097 IO.mapOptional("PenaltyBreakOpenParenthesis",
1099 IO.mapOptional("PenaltyBreakScopeResolution",
1102 IO.mapOptional("PenaltyBreakTemplateDeclaration",
1105 IO.mapOptional("PenaltyIndentedWhitespace",
1107 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1110 IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
1112
1114 Style.QualifierOrder = {"type", "const", "volatile"};
1116 Style.QualifierOrder = {"const", "volatile", "type"};
1118 IO.mapOptional("QualifierOrder", Style.QualifierOrder);
1121 IO.mapOptional("ReflowComments", Style.ReflowComments);
1123 IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1126 IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
1128 IO.mapOptional("RequiresExpressionIndentation",
1133 IO.mapOptional("SortIncludes", Style.SortIncludes);
1138 IO.mapOptional("SpaceAfterTemplateKeyword",
1140 IO.mapOptional("SpaceAroundPointerQualifiers",
1142 IO.mapOptional("SpaceBeforeAssignmentOperators",
1145 IO.mapOptional("SpaceBeforeCpp11BracedList",
1147 IO.mapOptional("SpaceBeforeCtorInitializerColon",
1149 IO.mapOptional("SpaceBeforeInheritanceColon",
1154 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1156 IO.mapOptional("SpaceBeforeSquareBrackets",
1159 IO.mapOptional("SpacesBeforeTrailingComments",
1161 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
1162 IO.mapOptional("SpacesInContainerLiterals",
1164 IO.mapOptional("SpacesInLineCommentPrefix",
1166 IO.mapOptional("SpacesInParens", Style.SpacesInParens);
1169 IO.mapOptional("Standard", Style.Standard);
1170 IO.mapOptional("StatementAttributeLikeMacros",
1172 IO.mapOptional("StatementMacros", Style.StatementMacros);
1173 IO.mapOptional("TableGenBreakingDAGArgOperators",
1175 IO.mapOptional("TableGenBreakInsideDAGArg",
1177 IO.mapOptional("TabWidth", Style.TabWidth);
1178 IO.mapOptional("TemplateNames", Style.TemplateNames);
1179 IO.mapOptional("TypeNames", Style.TypeNames);
1180 IO.mapOptional("TypenameMacros", Style.TypenameMacros);
1181 IO.mapOptional("UseTab", Style.UseTab);
1183 IO.mapOptional("VerilogBreakBetweenInstancePorts",
1185 IO.mapOptional("WhitespaceSensitiveMacros",
1187 IO.mapOptional("WrapNamespaceBodyWithEmptyLines",
1189
1190
1191
1192
1196 FormatStyle::DRTBS_All) {
1199 FormatStyle::DRTBS_TopLevel) {
1201 }
1202 }
1203
1204
1205
1206 if (BreakBeforeInheritanceComma &&
1209 }
1210
1211
1212
1213
1214 if (BreakConstructorInitializersBeforeComma &&
1217 }
1218
1219 if (!IsGoogleOrChromium) {
1221 OnCurrentLine) {
1223 ? FormatStyle::PCIS_NextLine
1224 : FormatStyle::PCIS_CurrentLine;
1225 }
1227 FormatStyle::PCIS_NextLine) {
1228 if (!OnCurrentLine)
1230 else if (!OnNextLine)
1232 }
1233
1234 if (Style.LineEnding == FormatStyle::LE_DeriveLF) {
1235 if (!DeriveLineEnding)
1236 Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1237 else if (UseCRLF)
1238 Style.LineEnding = FormatStyle::LE_DeriveCRLF;
1239 }
1240
1241 if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
1242 (SpacesInParentheses || SpaceInEmptyParentheses ||
1243 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1244 if (SpacesInParentheses) {
1245
1249 SpacesInCStyleCastParentheses;
1251 SpaceInEmptyParentheses;
1253 } else {
1256 SpacesInConditionalStatement;
1258 SpacesInCStyleCastParentheses;
1260 SpaceInEmptyParentheses;
1261 }
1263 }
1264 }
1265};
1266
1267
1268
1269
1270
1271
1272template <> struct DocumentListTraits<std::vector> {
1273 static size_t size(IO &IO, std::vector &Seq) {
1274 return Seq.size();
1275 }
1277 size_t Index) {
1278 if (Index >= Seq.size()) {
1279 assert(Index == Seq.size());
1281 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1282 Template = Seq[0];
1283 } else {
1284 Template = *((const FormatStyle *)IO.getContext());
1285 Template.Language = FormatStyle::LK_None;
1286 }
1287 Seq.resize(Index + 1, Template);
1288 }
1289 return Seq[Index];
1290 }
1291};
1292}
1293}
1294
1295namespace clang {
1296namespace format {
1297
1300 return C;
1301}
1303 return std::error_code(static_cast<int>(e), getParseCategory());
1304}
1305
1307 return llvm::make_errorllvm::StringError(Message,
1308 llvm::inconvertibleErrorCode());
1309}
1310
1312 return "clang-format.parse_error";
1313}
1314
1316 switch (static_cast<ParseError>(EV)) {
1318 return "Success";
1320 return "Invalid argument";
1322 return "Unsuitable";
1324 return "trailing comma insertion cannot be used with bin packing";
1326 return "Invalid qualifier specified in QualifierOrder";
1328 return "Duplicate qualifier specified in QualifierOrder";
1330 return "Missing type in QualifierOrder";
1332 return "Missing QualifierOrder";
1333 }
1334 llvm_unreachable("unexpected parse error");
1335}
1336
1339 return;
1340 Expanded.BraceWrapping = {false,
1341 false,
1343 false,
1344 false,
1345 false,
1346 false,
1347 false,
1348 false,
1349 false,
1350 false,
1351 false,
1352 false,
1353 false,
1354 false,
1355 true,
1356 true,
1357 true};
1363 break;
1373 break;
1378 break;
1393 break;
1407 break;
1410 true,
1411 true,
1413 true,
1414 true,
1415 true,
1416 true,
1417 true,
1418 true,
1419 true,
1420 true,
1421 true,
1422 false,
1423 true,
1424 true,
1425 true,
1426 true,
1427 true};
1428 break;
1431 break;
1432 default:
1433 break;
1434 }
1435}
1436
1439 return;
1440
1443
1449 break;
1452 break;
1455 break;
1456 default:
1457 break;
1458 }
1459}
1460
1463 return;
1465
1467}
1468
1509 LLVMStyle.BraceWrapping = {false,
1510 false,
1512 false,
1513 false,
1514 false,
1515 false,
1516 false,
1517 false,
1518 false,
1519 false,
1520 false,
1521 false,
1522 false,
1523 false,
1524 true,
1525 true,
1526 true};
1557 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1558 LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
1561 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1562 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1563 {".*", 1, 0, false}};
1581 0, 0,
1582 0, 0,
1583 0, 0};
1587 false,
1588 true,
1589 true,
1590 };
1647 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1659
1671
1672
1676 break;
1679 break;
1683 break;
1684 default:
1685 break;
1686 }
1687
1688 return LLVMStyle;
1689}
1690
1695
1696 return GoogleStyle;
1697 }
1698
1700
1711 {"^<.*\\.h>", 1, 0, false},
1712 {"^<.*", 2, 0, false},
1713 {".*", 3, 0, false}};
1723 {
1725
1726 {
1727 "cc",
1728 "CC",
1729 "cpp",
1730 "Cpp",
1731 "CPP",
1732 "c++",
1733 "C++",
1734 },
1735
1736 {},
1737 "",
1738 "google",
1739 },
1740 {
1742
1743 {
1744 "pb",
1745 "PB",
1746 "proto",
1747 "PROTO",
1748 },
1749
1750 {
1751 "EqualsProto",
1752 "EquivToProto",
1753 "PARSE_PARTIAL_TEXT_PROTO",
1754 "PARSE_TEST_PROTO",
1755 "PARSE_TEXT_PROTO",
1756 "ParseTextOrDie",
1757 "ParseTextProtoOrDie",
1758 "ParseTestProto",
1759 "ParsePartialTestProto",
1760 },
1761 "pb",
1762 "google",
1763 },
1764 };
1765
1768
1771
1788
1792
1793
1794 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1795
1796
1797
1806
1807
1808
1809
1810
1817
1818
1819
1828 }
1829
1830 return GoogleStyle;
1831}
1832
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1855
1862
1863
1865 "android",
1866 "androidx",
1867 "com",
1868 "dalvik",
1869 "junit",
1870 "org",
1871 "com.google.android.apps.chrome",
1872 "org.chromium",
1873 "java",
1874 "javax",
1875 };
1880 } else {
1889 }
1890 return ChromiumStyle;
1891}
1892
1916 return MozillaStyle;
1917}
1918
1940 return Style;
1941}
1942
1955 return Style;
1956}
1957
1984 return Style;
1985}
1986
1998 return Style;
1999}
2000
2006 return NoStyle;
2007}
2008
2011 if (Name.equals_insensitive("llvm"))
2013 else if (Name.equals_insensitive("chromium"))
2015 else if (Name.equals_insensitive("mozilla"))
2017 else if (Name.equals_insensitive("google"))
2019 else if (Name.equals_insensitive("webkit"))
2021 else if (Name.equals_insensitive("gnu"))
2023 else if (Name.equals_insensitive("microsoft"))
2025 else if (Name.equals_insensitive("clang-format"))
2027 else if (Name.equals_insensitive("none"))
2029 else if (Name.equals_insensitive("inheritparentconfig"))
2031 else
2032 return false;
2033
2035 return true;
2036}
2037
2039
2042
2043
2044 for (const auto &Qualifier : Style->QualifierOrder) {
2045 if (Qualifier == "type")
2046 continue;
2047 auto token =
2049 if (token == tok::identifier)
2051 }
2052
2053
2054 std::setstd::string UniqueQualifiers(Style->QualifierOrder.begin(),
2056 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2057 LLVM_DEBUG(llvm::dbgs()
2058 << "Duplicate Qualifiers " << Style->QualifierOrder.size()
2059 << " vs " << UniqueQualifiers.size() << "\n");
2061 }
2062
2063
2064 if (!llvm::is_contained(Style->QualifierOrder, "type"))
2066
2068}
2069
2071 FormatStyle *Style, bool AllowUnknownOptions,
2072 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2073 void *DiagHandlerCtxt) {
2074 assert(Style);
2077 if (Config.getBuffer().trim().empty())
2079 Style->StyleSet.Clear();
2080 std::vector Styles;
2081 llvm::yaml::Input Input(Config, nullptr, DiagHandler,
2082 DiagHandlerCtxt);
2083
2084
2085
2086
2087 Input.setContext(Style);
2088 Input.setAllowUnknownKeys(AllowUnknownOptions);
2089 Input >> Styles;
2090 if (Input.error())
2091 return Input.error();
2092
2093 for (unsigned i = 0; i < Styles.size(); ++i) {
2094
2097
2098 for (unsigned j = 0; j < i; ++j) {
2100 LLVM_DEBUG(llvm::dbgs()
2101 << "Duplicate languages in the config file on positions "
2102 << j << " and " << i << "\n");
2104 }
2105 }
2106 }
2107
2108
2109
2111 bool LanguageFound = false;
2112 for (const FormatStyle &Style : llvm::reverse(Styles)) {
2114 StyleSet.Add(Style);
2116 LanguageFound = true;
2117 }
2118 if (!LanguageFound) {
2123 StyleSet.Add(std::move(DefaultStyle));
2124 }
2128
2130 }
2134}
2135
2137 std::string Text;
2138 llvm::raw_string_ostream Stream(Text);
2139 llvm::yaml::Output Output(Stream);
2140
2141
2146 Output << NonConstStyle;
2147
2148 return Stream.str();
2149}
2150
2151std::optional
2153 if (!Styles)
2154 return std::nullopt;
2155 auto It = Styles->find(Language);
2156 if (It == Styles->end())
2157 return std::nullopt;
2159 Style.StyleSet = *this;
2160 return Style;
2161}
2162
2165 "Cannot add a style for LK_None to a StyleSet");
2166 assert(
2167 !Style.StyleSet.Styles &&
2168 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2169 if (!Styles)
2170 Styles = std::make_shared();
2171 (*Styles)[Style.Language] = std::move(Style);
2172}
2173
2175
2176std::optional
2179}
2180
2181namespace {
2182
2184public:
2187
2188 std::pair<tooling::Replacements, unsigned>
2189 analyze(TokenAnnotator &Annotator,
2191 FormatTokenLexer &Tokens) override {
2192 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2194 removeParens(AnnotatedLines, Result);
2195 return {Result, 0};
2196 }
2197
2198private:
2199 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2200 tooling::Replacements &Result) {
2201 const auto &SourceMgr = Env.getSourceManager();
2202 for (auto *Line : Lines) {
2203 if (!Line->Children.empty())
2204 removeParens(Line->Children, Result);
2205 if (!Line->Affected)
2206 continue;
2207 for (const auto *Token = Line->First; Token && !Token->Finalized;
2208 Token = Token->Next) {
2209 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2210 continue;
2211 auto *Next = Token->Next;
2212 assert(Next && Next->isNot(tok::eof));
2213 SourceLocation Start;
2214 if (Next->NewlinesBefore == 0) {
2215 Start = Token->Tok.getLocation();
2216 Next->WhitespaceRange = Token->WhitespaceRange;
2217 } else {
2218 Start = Token->WhitespaceRange.getBegin();
2219 }
2220 const auto &Range =
2221 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2222 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, " ")));
2223 }
2224 }
2225 }
2226};
2227
2228class BracesInserter : public TokenAnalyzer {
2229public:
2230 BracesInserter(const Environment &Env, const FormatStyle &Style)
2231 : TokenAnalyzer(Env, Style) {}
2232
2233 std::pair<tooling::Replacements, unsigned>
2234 analyze(TokenAnnotator &Annotator,
2235 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2236 FormatTokenLexer &Tokens) override {
2237 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2238 tooling::Replacements Result;
2239 insertBraces(AnnotatedLines, Result);
2240 return {Result, 0};
2241 }
2242
2243private:
2244 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2245 tooling::Replacements &Result) {
2246 const auto &SourceMgr = Env.getSourceManager();
2247 int OpeningBraceSurplus = 0;
2248 for (AnnotatedLine *Line : Lines) {
2249 if (!Line->Children.empty())
2250 insertBraces(Line->Children, Result);
2251 if (!Line->Affected && OpeningBraceSurplus == 0)
2252 continue;
2253 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2254 Token = Token->Next) {
2255 int BraceCount = Token->BraceCount;
2256 if (BraceCount == 0)
2257 continue;
2258 std::string Brace;
2259 if (BraceCount < 0) {
2260 assert(BraceCount == -1);
2261 if (!Line->Affected)
2262 break;
2263 Brace = Token->is(tok::comment) ? "\n{" : "{";
2264 ++OpeningBraceSurplus;
2265 } else {
2266 if (OpeningBraceSurplus == 0)
2267 break;
2268 if (OpeningBraceSurplus < BraceCount)
2269 BraceCount = OpeningBraceSurplus;
2270 Brace = '\n' + std::string(BraceCount, '}');
2271 OpeningBraceSurplus -= BraceCount;
2272 }
2273 Token->BraceCount = 0;
2274 const auto Start = Token->Tok.getEndLoc();
2275 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
2276 }
2277 }
2278 assert(OpeningBraceSurplus == 0);
2279 }
2280};
2281
2282class BracesRemover : public TokenAnalyzer {
2283public:
2284 BracesRemover(const Environment &Env, const FormatStyle &Style)
2285 : TokenAnalyzer(Env, Style) {}
2286
2287 std::pair<tooling::Replacements, unsigned>
2288 analyze(TokenAnnotator &Annotator,
2289 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2290 FormatTokenLexer &Tokens) override {
2291 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2292 tooling::Replacements Result;
2293 removeBraces(AnnotatedLines, Result);
2294 return {Result, 0};
2295 }
2296
2297private:
2298 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2299 tooling::Replacements &Result) {
2300 const auto &SourceMgr = Env.getSourceManager();
2301 const auto *End = Lines.end();
2302 for (const auto *I = Lines.begin(); I != End; ++I) {
2303 const auto &Line = *I;
2304 if (!Line->Children.empty())
2305 removeBraces(Line->Children, Result);
2306 if (!Line->Affected)
2307 continue;
2308 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2309 for (const auto *Token = Line->First; Token && !Token->Finalized;
2310 Token = Token->Next) {
2311 if (!Token->Optional)
2312 continue;
2313 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2314 continue;
2315 auto *Next = Token->Next;
2316 assert(Next || Token == Line->Last);
2317 if (!Next && NextLine)
2318 Next = NextLine->First;
2319 SourceLocation Start;
2320 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2321 Start = Token->Tok.getLocation();
2322 Next->WhitespaceRange = Token->WhitespaceRange;
2323 } else {
2324 Start = Token->WhitespaceRange.getBegin();
2325 }
2326 const auto &Range =
2327 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2328 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2329 }
2330 }
2331 }
2332};
2333
2334class SemiRemover : public TokenAnalyzer {
2335public:
2336 SemiRemover(const Environment &Env, const FormatStyle &Style)
2337 : TokenAnalyzer(Env, Style) {}
2338
2339 std::pair<tooling::Replacements, unsigned>
2340 analyze(TokenAnnotator &Annotator,
2341 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2342 FormatTokenLexer &Tokens) override {
2343 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2344 tooling::Replacements Result;
2345 removeSemi(Annotator, AnnotatedLines, Result);
2346 return {Result, 0};
2347 }
2348
2349private:
2350 void removeSemi(TokenAnnotator &Annotator,
2351 SmallVectorImpl<AnnotatedLine *> &Lines,
2352 tooling::Replacements &Result) {
2353 auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {
2354 const auto *Prev = Tok.Previous;
2355 if (!Prev || Prev->isNot(tok::r_brace))
2356 return false;
2357 const auto *LBrace = Prev->MatchingParen;
2358 return LBrace && LBrace->is(TT_FunctionLBrace);
2359 };
2360 const auto &SourceMgr = Env.getSourceManager();
2361 const auto *End = Lines.end();
2362 for (const auto *I = Lines.begin(); I != End; ++I) {
2363 const auto &Line = *I;
2364 if (!Line->Children.empty())
2365 removeSemi(Annotator, Line->Children, Result);
2366 if (!Line->Affected)
2367 continue;
2368 Annotator.calculateFormattingInformation(*Line);
2369 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2370 for (const auto *Token = Line->First; Token && !Token->Finalized;
2371 Token = Token->Next) {
2372 if (Token->isNot(tok::semi) ||
2373 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2374 continue;
2375 }
2376 auto *Next = Token->Next;
2377 assert(Next || Token == Line->Last);
2378 if (!Next && NextLine)
2379 Next = NextLine->First;
2380 SourceLocation Start;
2381 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2382 Start = Token->Tok.getLocation();
2383 Next->WhitespaceRange = Token->WhitespaceRange;
2384 } else {
2385 Start = Token->WhitespaceRange.getBegin();
2386 }
2387 const auto &Range =
2388 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2389 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2390 }
2391 }
2392 }
2393};
2394
2395class JavaScriptRequoter : public TokenAnalyzer {
2396public:
2397 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
2398 : TokenAnalyzer(Env, Style) {}
2399
2400 std::pair<tooling::Replacements, unsigned>
2401 analyze(TokenAnnotator &Annotator,
2402 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2403 FormatTokenLexer &Tokens) override {
2404 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2405 tooling::Replacements Result;
2406 requoteJSStringLiteral(AnnotatedLines, Result);
2407 return {Result, 0};
2408 }
2409
2410private:
2411
2412
2413 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2414 tooling::Replacements &Result) {
2415 for (AnnotatedLine *Line : Lines) {
2416 requoteJSStringLiteral(Line->Children, Result);
2417 if (!Line->Affected)
2418 continue;
2419 for (FormatToken *FormatTok = Line->First; FormatTok;
2420 FormatTok = FormatTok->Next) {
2421 StringRef Input = FormatTok->TokenText;
2422 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2423
2424
2426 !Input.starts_with("\"")) ||
2428 !Input.starts_with("\'"))) {
2429 continue;
2430 }
2431
2432
2433 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
2434 SourceLocation Start = FormatTok->Tok.getLocation();
2435 auto Replace = [&](SourceLocation Start, unsigned Length,
2436 StringRef ReplacementText) {
2437 auto Err = Result.add(tooling::Replacement(
2438 Env.getSourceManager(), Start, Length, ReplacementText));
2439
2440
2441 if (Err) {
2442 llvm::errs() << toString(std::move(Err)) << "\n";
2443 assert(false);
2444 }
2445 };
2446 Replace(Start, 1, IsSingle ? "'" : "\"");
2447 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2448 IsSingle ? "'" : "\"");
2449
2450
2451 bool Escaped = false;
2452 for (size_t i = 1; i < Input.size() - 1; i++) {
2453 switch (Input[i]) {
2454 case '\\':
2455 if (!Escaped && i + 1 < Input.size() &&
2456 ((IsSingle && Input[i + 1] == '"') ||
2457 (!IsSingle && Input[i + 1] == '\''))) {
2458
2459
2460 Replace(Start.getLocWithOffset(i), 1, "");
2461 continue;
2462 }
2463 Escaped = !Escaped;
2464 break;
2465 case '\"':
2466 case '\'':
2467 if (!Escaped && IsSingle == (Input[i] == '\'')) {
2468
2469 Replace(Start.getLocWithOffset(i), 0, "\\");
2470 }
2471 Escaped = false;
2472 break;
2473 default:
2474 Escaped = false;
2475 break;
2476 }
2477 }
2478 }
2479 }
2480 }
2481};
2482
2483class Formatter : public TokenAnalyzer {
2484public:
2485 Formatter(const Environment &Env, const FormatStyle &Style,
2486 FormattingAttemptStatus *Status)
2487 : TokenAnalyzer(Env, Style), Status(Status) {}
2488
2489 std::pair<tooling::Replacements, unsigned>
2490 analyze(TokenAnnotator &Annotator,
2491 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2492 FormatTokenLexer &Tokens) override {
2493 tooling::Replacements Result;
2494 deriveLocalStyle(AnnotatedLines);
2495 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2496 for (AnnotatedLine *Line : AnnotatedLines)
2497 Annotator.calculateFormattingInformation(*Line);
2498 Annotator.setCommentLineLevels(AnnotatedLines);
2499
2500 WhitespaceManager Whitespaces(
2501 Env.getSourceManager(), Style,
2502 Style.LineEnding > FormatStyle::LE_CRLF
2503 ? WhitespaceManager::inputUsesCRLF(
2504 Env.getSourceManager().getBufferData(Env.getFileID()),
2505 Style.LineEnding == FormatStyle::LE_DeriveCRLF)
2506 : Style.LineEnding == FormatStyle::LE_CRLF);
2507 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
2508 Env.getSourceManager(), Whitespaces, Encoding,
2509 BinPackInconclusiveFunctions);
2510 unsigned Penalty =
2511 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
2512 Tokens.getKeywords(), Env.getSourceManager(),
2513 Status)
2514 .format(AnnotatedLines, false,
2515 0,
2516 false,
2517 Env.getFirstStartColumn(),
2518 Env.getNextStartColumn(),
2519 Env.getLastStartColumn());
2520 for (const auto &R : Whitespaces.generateReplacements())
2521 if (Result.add(R))
2522 return std::make_pair(Result, 0);
2523 return std::make_pair(Result, Penalty);
2524 }
2525
2526private:
2527 bool
2528 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2529 for (const AnnotatedLine *Line : Lines) {
2530 if (hasCpp03IncompatibleFormat(Line->Children))
2531 return true;
2532 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2533 if (!Tok->hasWhitespaceBefore()) {
2534 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2535 return true;
2536 if (Tok->is(TT_TemplateCloser) &&
2537 Tok->Previous->is(TT_TemplateCloser)) {
2538 return true;
2539 }
2540 }
2541 }
2542 }
2543 return false;
2544 }
2545
2546 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2547 int AlignmentDiff = 0;
2548 for (const AnnotatedLine *Line : Lines) {
2549 AlignmentDiff += countVariableAlignments(Line->Children);
2550 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2551 if (Tok->isNot(TT_PointerOrReference))
2552 continue;
2553
2554 if (const auto *Prev = Tok->getPreviousNonComment()) {
2555 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2556 if (const auto *Func =
2557 Prev->MatchingParen->getPreviousNonComment()) {
2558 if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2559 TT_OverloadedOperator)) {
2560 continue;
2561 }
2562 }
2563 }
2564 }
2565 bool SpaceBefore = Tok->hasWhitespaceBefore();
2566 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2567 if (SpaceBefore && !SpaceAfter)
2568 ++AlignmentDiff;
2569 if (!SpaceBefore && SpaceAfter)
2570 --AlignmentDiff;
2571 }
2572 }
2573 return AlignmentDiff;
2574 }
2575
2576 void
2577 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2578 bool HasBinPackedFunction = false;
2579 bool HasOnePerLineFunction = false;
2580 for (AnnotatedLine *Line : AnnotatedLines) {
2581 if (!Line->First->Next)
2582 continue;
2583 FormatToken *Tok = Line->First->Next;
2584 while (Tok->Next) {
2585 if (Tok->is(PPK_BinPacked))
2586 HasBinPackedFunction = true;
2587 if (Tok->is(PPK_OnePerLine))
2588 HasOnePerLineFunction = true;
2589
2590 Tok = Tok->Next;
2591 }
2592 }
2594 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2595 if (NetRightCount > 0)
2597 else if (NetRightCount < 0)
2600 }
2601 if (Style.Standard == FormatStyle::LS_Auto) {
2602 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2603 ? FormatStyle::LS_Latest
2604 : FormatStyle::LS_Cpp03;
2605 }
2606 BinPackInconclusiveFunctions =
2607 HasBinPackedFunction || !HasOnePerLineFunction;
2608 }
2609
2610 bool BinPackInconclusiveFunctions;
2611 FormattingAttemptStatus *Status;
2612};
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625class TrailingCommaInserter : public TokenAnalyzer {
2626public:
2627 TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2628 : TokenAnalyzer(Env, Style) {}
2629
2630 std::pair<tooling::Replacements, unsigned>
2631 analyze(TokenAnnotator &Annotator,
2632 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2633 FormatTokenLexer &Tokens) override {
2634 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2635 tooling::Replacements Result;
2636 insertTrailingCommas(AnnotatedLines, Result);
2637 return {Result, 0};
2638 }
2639
2640private:
2641
2642
2643 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2644 tooling::Replacements &Result) {
2645 for (AnnotatedLine *Line : Lines) {
2646 insertTrailingCommas(Line->Children, Result);
2647 if (!Line->Affected)
2648 continue;
2649 for (FormatToken *FormatTok = Line->First; FormatTok;
2650 FormatTok = FormatTok->Next) {
2651 if (FormatTok->NewlinesBefore == 0)
2652 continue;
2653 FormatToken *Matching = FormatTok->MatchingParen;
2654 if (!Matching || !FormatTok->getPreviousNonComment())
2655 continue;
2656 if (!(FormatTok->is(tok::r_square) &&
2657 Matching->is(TT_ArrayInitializerLSquare)) &&
2658 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2659 continue;
2660 }
2661 FormatToken *Prev = FormatTok->getPreviousNonComment();
2662 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2663 continue;
2664
2665
2666 SourceLocation Start =
2667 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2668
2669
2670
2671 unsigned ColumnNumber =
2672 Env.getSourceManager().getSpellingColumnNumber(Start);
2674 continue;
2675
2676
2677 cantFail(Result.add(
2678 tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2679 }
2680 }
2681 }
2682};
2683
2684
2685
2686class Cleaner : public TokenAnalyzer {
2687public:
2688 Cleaner(const Environment &Env, const FormatStyle &Style)
2689 : TokenAnalyzer(Env, Style),
2690 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2691
2692
2693 std::pair<tooling::Replacements, unsigned>
2694 analyze(TokenAnnotator &Annotator,
2695 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2696 FormatTokenLexer &Tokens) override {
2697
2698
2699
2700
2701
2702
2703
2704 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2705
2706 checkEmptyNamespace(AnnotatedLines);
2707
2708 for (auto *Line : AnnotatedLines)
2709 cleanupLine(Line);
2710
2711 return {generateFixes(), 0};
2712 }
2713
2714private:
2715 void cleanupLine(AnnotatedLine *Line) {
2716 for (auto *Child : Line->Children)
2717 cleanupLine(Child);
2718
2719 if (Line->Affected) {
2720 cleanupRight(Line->First, tok::comma, tok::comma);
2721 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2722 cleanupRight(Line->First, tok::l_paren, tok::comma);
2723 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2724 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2725 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2726 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2727 }
2728 }
2729
2730 bool containsOnlyComments(const AnnotatedLine &Line) {
2731 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2732 if (Tok->isNot(tok::comment))
2733 return false;
2734 return true;
2735 }
2736
2737
2738 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2739 std::set DeletedLines;
2740 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2741 auto &Line = *AnnotatedLines[i];
2742 if (Line.startsWithNamespace())
2743 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2744 }
2745
2746 for (auto Line : DeletedLines) {
2747 FormatToken *Tok = AnnotatedLines[Line]->First;
2748 while (Tok) {
2749 deleteToken(Tok);
2750 Tok = Tok->Next;
2751 }
2752 }
2753 }
2754
2755
2756
2757
2758
2759 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2760 unsigned CurrentLine, unsigned &NewLine,
2761 std::set &DeletedLines) {
2762 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2764
2765
2766
2767 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2769 return false;
2770 }
2771 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2772 return false;
2773 }
2774 while (++CurrentLine < End) {
2775 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2776 break;
2777
2778 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2779 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
2780 DeletedLines)) {
2781 return false;
2782 }
2784 continue;
2785 }
2786
2787 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2788 continue;
2789
2790
2791
2793 return false;
2794 }
2795
2797 if (CurrentLine >= End)
2798 return false;
2799
2800
2801 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2802 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2803 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2804 return false;
2805 }
2806
2807 for (unsigned i = InitLine; i <= CurrentLine; ++i)
2808 DeletedLines.insert(i);
2809
2810 return true;
2811 }
2812
2813
2814
2815
2816
2817 template <typename LeftKind, typename RightKind>
2818 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2819 bool DeleteLeft) {
2820 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
2821 for (auto *Res = Tok.Next; Res; Res = Res->Next) {
2822 if (Res->isNot(tok::comment) &&
2823 DeletedTokens.find(Res) == DeletedTokens.end()) {
2824 return Res;
2825 }
2826 }
2827 return nullptr;
2828 };
2829 for (auto *Left = Start; Left;) {
2830 auto *Right = NextNotDeleted(*Left);
2831 if (!Right)
2832 break;
2833 if (Left->is(LK) && Right->is(RK)) {
2834 deleteToken(DeleteLeft ? Left : Right);
2835 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2836 deleteToken(Tok);
2837
2838
2839 if (!DeleteLeft)
2840 continue;
2841 }
2843 }
2844 }
2845
2846 template <typename LeftKind, typename RightKind>
2847 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2848 cleanupPair(Start, LK, RK, true);
2849 }
2850
2851 template <typename LeftKind, typename RightKind>
2852 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2853 cleanupPair(Start, LK, RK, false);
2854 }
2855
2856
2857 inline void deleteToken(FormatToken *Tok) {
2858 if (Tok)
2859 DeletedTokens.insert(Tok);
2860 }
2861
2862 tooling::Replacements generateFixes() {
2863 tooling::Replacements Fixes;
2864 SmallVector<FormatToken *> Tokens;
2865 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2866 std::back_inserter(Tokens));
2867
2868
2869
2870
2871 unsigned Idx = 0;
2872 while (Idx < Tokens.size()) {
2873 unsigned St = Idx, End = Idx;
2874 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2875 ++End;
2876 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2877 Tokens[End]->Tok.getEndLoc());
2878 auto Err =
2879 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2880
2881
2882 if (Err) {
2883 llvm::errs() << toString(std::move(Err)) << "\n";
2884 assert(false && "Fixes must not conflict!");
2885 }
2886 Idx = End + 1;
2887 }
2888
2889 return Fixes;
2890 }
2891
2892
2893
2894
2895 struct FormatTokenLess {
2896 FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2897
2898 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2899 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2900 RHS->Tok.getLocation());
2901 }
2903 };
2904
2905
2906 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2907};
2908
2909class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2910public:
2911 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2912 : TokenAnalyzer(Env, Style), IsObjC(false) {}
2913
2914 std::pair<tooling::Replacements, unsigned>
2915 analyze(TokenAnnotator &Annotator,
2916 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2917 FormatTokenLexer &Tokens) override {
2918 assert(Style.Language == FormatStyle::LK_Cpp);
2919 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2920 Tokens.getKeywords());
2921 tooling::Replacements Result;
2922 return {Result, 0};
2923 }
2924
2925 bool isObjC() { return IsObjC; }
2926
2927private:
2928 static bool
2929 guessIsObjC(const SourceManager &SourceManager,
2930 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2931 const AdditionalKeywords &Keywords) {
2932
2933 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2934 "CGFloat",
2935 "CGPoint",
2936 "CGPointMake",
2937 "CGPointZero",
2938 "CGRect",
2939 "CGRectEdge",
2940 "CGRectInfinite",
2941 "CGRectMake",
2942 "CGRectNull",
2943 "CGRectZero",
2944 "CGSize",
2945 "CGSizeMake",
2946 "CGVector",
2947 "CGVectorMake",
2948 "FOUNDATION_EXPORT",
2949 "FOUNDATION_EXTERN",
2950 "NSAffineTransform",
2951 "NSArray",
2952 "NSAttributedString",
2953 "NSBlockOperation",
2954 "NSBundle",
2955 "NSCache",
2956 "NSCalendar",
2957 "NSCharacterSet",
2958 "NSCountedSet",
2959 "NSData",
2960 "NSDataDetector",
2961 "NSDecimal",
2962 "NSDecimalNumber",
2963 "NSDictionary",
2964 "NSEdgeInsets",
2965 "NSError",
2966 "NSErrorDomain",
2967 "NSHashTable",
2968 "NSIndexPath",
2969 "NSIndexSet",
2970 "NSInteger",
2971 "NSInvocationOperation",
2972 "NSLocale",
2973 "NSMapTable",
2974 "NSMutableArray",
2975 "NSMutableAttributedString",
2976 "NSMutableCharacterSet",
2977 "NSMutableData",
2978 "NSMutableDictionary",
2979 "NSMutableIndexSet",
2980 "NSMutableOrderedSet",
2981 "NSMutableSet",
2982 "NSMutableString",
2983 "NSNumber",
2984 "NSNumberFormatter",
2985 "NSObject",
2986 "NSOperation",
2987 "NSOperationQueue",
2988 "NSOperationQueuePriority",
2989 "NSOrderedSet",
2990 "NSPoint",
2991 "NSPointerArray",
2992 "NSQualityOfService",
2993 "NSRange",
2994 "NSRect",
2995 "NSRegularExpression",
2996 "NSSet",
2997 "NSSize",
2998 "NSString",
2999 "NSTimeZone",
3000 "NSUInteger",
3001 "NSURL",
3002 "NSURLComponents",
3003 "NSURLQueryItem",
3004 "NSUUID",
3005 "NSValue",
3006 "NS_ASSUME_NONNULL_BEGIN",
3007 "UIImage",
3008 "UIView",
3009 };
3010
3011 for (auto *Line : AnnotatedLines) {
3012 if (Line->First && (Line->First->TokenText.starts_with("#") ||
3013 Line->First->TokenText == "__pragma" ||
3014 Line->First->TokenText == "_Pragma")) {
3015 continue;
3016 }
3017 for (const FormatToken *FormatTok = Line->First; FormatTok;
3018 FormatTok = FormatTok->Next) {
3019 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3020 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3021 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3022 tok::l_brace))) ||
3023 (FormatTok->Tok.isAnyIdentifier() &&
3024 std::binary_search(std::begin(FoundationIdentifiers),
3025 std::end(FoundationIdentifiers),
3026 FormatTok->TokenText)) ||
3027 FormatTok->is(TT_ObjCStringLiteral) ||
3028 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3029 Keywords.kw_NS_ERROR_ENUM,
3030 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3031 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3032 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3033 TT_ObjCProperty)) {
3034 LLVM_DEBUG(llvm::dbgs()
3035 << "Detected ObjC at location "
3036 << FormatTok->Tok.getLocation().printToString(
3037 SourceManager)
3038 << " token: " << FormatTok->TokenText << " token type: "
3040 return true;
3041 }
3042 }
3043 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3044 return true;
3045 }
3046 return false;
3047 }
3048
3049 bool IsObjC;
3050};
3051
3055 unsigned Offset;
3058};
3059
3060struct JavaImportDirective {
3062 StringRef Text;
3063 unsigned Offset;
3066};
3067
3068}
3069
3070
3072 unsigned End) {
3073 for (const auto &Range : Ranges) {
3074 if (Range.getOffset() < End &&
3075 Range.getOffset() + Range.getLength() > Start) {
3076 return true;
3077 }
3078 }
3079 return false;
3080}
3081
3082
3083
3084
3085
3086
3087
3088
3089static std::pair<unsigned, unsigned>
3092 unsigned CursorIndex = UINT_MAX;
3093 unsigned OffsetToEOL = 0;
3094 for (int i = 0, e = Includes.size(); i != e; ++i) {
3095 unsigned Start = Includes[Indices[i]].Offset;
3096 unsigned End = Start + Includes[Indices[i]].Text.size();
3097 if (!(Cursor >= Start && Cursor < End))
3098 continue;
3099 CursorIndex = Indices[i];
3100 OffsetToEOL = End - Cursor;
3101
3102
3103 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
3104 CursorIndex = i;
3105 break;
3106 }
3107 return std::make_pair(CursorIndex, OffsetToEOL);
3108}
3109
3110
3112 std::string NewCode;
3113 size_t Pos = 0, LastPos = 0;
3114
3115 do {
3116 Pos = Code.find("\r\n", LastPos);
3117 if (Pos == LastPos) {
3118 ++LastPos;
3119 continue;
3120 }
3121 if (Pos == std:🧵:npos) {
3122 NewCode += Code.substr(LastPos);
3123 break;
3124 }
3125 NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
3126 LastPos = Pos + 2;
3127 } while (Pos != std:🧵:npos);
3128
3129 return NewCode;
3130}
3131
3132
3133
3134
3135
3136
3137
3138
3143 unsigned *Cursor) {
3145 const unsigned IncludesBeginOffset = Includes.front().Offset;
3146 const unsigned IncludesEndOffset =
3147 Includes.back().Offset + Includes.back().Text.size();
3148 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3149 if ((Ranges, IncludesBeginOffset, IncludesEndOffset))
3150 return;
3152 llvm::to_vector<16>(llvm::seq(0, Includes.size()));
3153
3155 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3156 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3157 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3158 return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
3160 std::tie(Includes[RHSI].Priority, RHSFilenameLower,
3162 });
3163 } else {
3164 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3165 return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
3167 });
3168 }
3169
3170
3171
3172 unsigned CursorIndex;
3173
3174 unsigned CursorToEOLOffset;
3175 if (Cursor) {
3176 std::tie(CursorIndex, CursorToEOLOffset) =
3178 }
3179
3180
3181 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3182 [&](unsigned LHSI, unsigned RHSI) {
3183 return Includes[LHSI].Text.trim() ==
3184 Includes[RHSI].Text.trim();
3185 }),
3186 Indices.end());
3187
3188 int CurrentCategory = Includes.front().Category;
3189
3190
3191
3192
3193
3194
3195
3196 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3198 return;
3199 }
3200
3201 const auto OldCursor = Cursor ? *Cursor : 0;
3202 std::string result;
3203 for (unsigned Index : Indices) {
3204 if (!result.empty()) {
3205 result += "\n";
3208 CurrentCategory != Includes[Index].Category) {
3209 result += "\n";
3210 }
3211 }
3212 result += Includes[Index].Text;
3213 if (Cursor && CursorIndex == Index)
3214 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3215 CurrentCategory = Includes[Index].Category;
3216 }
3217
3218 if (Cursor && *Cursor >= IncludesEndOffset)
3219 *Cursor += result.size() - IncludesBlockSize;
3220
3221
3222
3224 IncludesBeginOffset, IncludesBlockSize)))) {
3225 if (Cursor)
3226 *Cursor = OldCursor;
3227 return;
3228 }
3229
3231 FileName, Includes.front().Offset, IncludesBlockSize, result));
3232
3233
3234 if (Err) {
3235 llvm::errs() << toString(std::move(Err)) << "\n";
3236 assert(false);
3237 }
3238}
3239
3244 unsigned *Cursor) {
3245 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3246 .StartsWith("\xEF\xBB\xBF", 3)
3247 .Default(0);
3248 unsigned SearchFrom = 0;
3251
3252
3253
3254
3255
3256
3257
3258
3260 bool FirstIncludeBlock = true;
3261 bool MainIncludeFound = false;
3262 bool FormattingOff = false;
3263
3264
3265 llvm::Regex RawStringRegex(
3266 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3268 std::string RawStringTermination = ")\"";
3269
3270 for (const auto Size = Code.size(); SearchFrom < Size;) {
3271 size_t Pos = SearchFrom;
3272 if (Code[SearchFrom] != '\n') {
3273 do {
3274 ++Pos;
3275 Pos = Code.find('\n', Pos);
3276 } while (Pos != StringRef::npos && Code[Pos - 1] == '\\');
3277 }
3278
3279 StringRef Line =
3280 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3281
3282 StringRef Trimmed = Line.trim();
3283
3284
3285
3286
3287 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3288 std::string CharSequence = RawStringMatches[1].str();
3289 RawStringTermination = ")" + CharSequence + "\"";
3290 FormattingOff = true;
3291 }
3292
3293 if (Trimmed.contains(RawStringTermination))
3294 FormattingOff = false;
3295
3296 bool IsBlockComment = false;
3297
3299 FormattingOff = true;
3301 FormattingOff = false;
3302 } else if (Trimmed.starts_with("/*")) {
3303 IsBlockComment = true;
3304 Pos = Code.find("*/", SearchFrom + 2);
3305 }
3306
3307 const bool EmptyLineSkipped =
3308 Trimmed.empty() &&
3312
3313 bool MergeWithNextLine = Trimmed.ends_with("\\");
3314 if (!FormattingOff && !MergeWithNextLine) {
3315 if (!IsBlockComment &&
3317 StringRef IncludeName = Matches[2];
3318 if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {
3319
3320
3321
3322
3323 Pos = Code.find("*/", SearchFrom);
3324 Line = Code.substr(
3325 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3326 }
3328 IncludeName,
3329 !MainIncludeFound && FirstIncludeBlock);
3331 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3333 MainIncludeFound = true;
3334 IncludesInBlock.push_back(
3336 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3338 Replaces, Cursor);
3339 IncludesInBlock.clear();
3340 if (Trimmed.starts_with("#pragma hdrstop"))
3341 FirstIncludeBlock = true;
3342 else
3343 FirstIncludeBlock = false;
3344 }
3345 }
3346 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3347 break;
3348
3349 if (!MergeWithNextLine)
3350 Prev = Pos + 1;
3351 SearchFrom = Pos + 1;
3352 }
3353 if (!IncludesInBlock.empty()) {
3355 Cursor);
3356 }
3357 return Replaces;
3358}
3359
3360
3361
3363 StringRef ImportIdentifier) {
3364 unsigned LongestMatchIndex = UINT_MAX;
3365 unsigned LongestMatchLength = 0;
3366 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3368 if (ImportIdentifier.starts_with(GroupPrefix) &&
3369 GroupPrefix.length() > LongestMatchLength) {
3370 LongestMatchIndex = I;
3371 LongestMatchLength = GroupPrefix.length();
3372 }
3373 }
3374 return LongestMatchIndex;
3375}
3376
3377
3378
3379
3380
3381
3386 unsigned ImportsBeginOffset = Imports.front().Offset;
3387 unsigned ImportsEndOffset =
3388 Imports.back().Offset + Imports.back().Text.size();
3389 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3390 if ((Ranges, ImportsBeginOffset, ImportsEndOffset))
3391 return;
3392
3394 llvm::to_vector<16>(llvm::seq(0, Imports.size()));
3397 for (const JavaImportDirective &Import : Imports)
3399
3400 bool StaticImportAfterNormalImport =
3402 sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3403
3404 return std::make_tuple(!Imports[LHSI].IsStatic ^
3405 StaticImportAfterNormalImport,
3407 std::make_tuple(!Imports[RHSI].IsStatic ^
3408 StaticImportAfterNormalImport,
3410 });
3411
3412
3413 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3414 [&](unsigned LHSI, unsigned RHSI) {
3415 return Imports[LHSI].Text == Imports[RHSI].Text;
3416 }),
3417 Indices.end());
3418
3419 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3420 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
3421
3422 std::string result;
3423 for (unsigned Index : Indices) {
3424 if (!result.empty()) {
3425 result += "\n";
3426 if (CurrentIsStatic != Imports[Index].IsStatic ||
3428 result += "\n";
3429 }
3430 }
3432 result += CommentLine;
3433 result += "\n";
3434 }
3435 result += Imports[Index].Text;
3436 CurrentIsStatic = Imports[Index].IsStatic;
3438 }
3439
3440
3441
3443 Imports.front().Offset, ImportsBlockSize)))) {
3444 return;
3445 }
3446
3448 ImportsBlockSize, result));
3449
3450
3451 if (Err) {
3452 llvm::errs() << toString(std::move(Err)) << "\n";
3453 assert(false);
3454 }
3455}
3456
3457namespace {
3458
3459const char JavaImportRegexPattern[] =
3460 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3461
3462}
3463
3468 unsigned Prev = 0;
3469 unsigned SearchFrom = 0;
3470 llvm::Regex ImportRegex(JavaImportRegexPattern);
3474
3475 bool FormattingOff = false;
3476
3477 for (;;) {
3478 auto Pos = Code.find('\n', SearchFrom);
3479 StringRef Line =
3480 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3481
3482 StringRef Trimmed = Line.trim();
3484 FormattingOff = true;
3486 FormattingOff = false;
3487
3488 if (ImportRegex.match(Line, &Matches)) {
3489 if (FormattingOff) {
3490
3491
3492 return Replaces;
3493 }
3494 StringRef Static = Matches[1];
3497 if (Static.contains("static"))
3499 ImportsInBlock.push_back(
3502 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3503
3505 }
3506 Prev = Pos + 1;
3507 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3508 break;
3509 SearchFrom = Pos + 1;
3510 }
3511 if (!ImportsInBlock.empty())
3513 return Replaces;
3514}
3515
3517
3518
3519
3520 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3521}
3522
3523bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); }
3524
3527 StringRef FileName, unsigned *Cursor) {
3530 return Replaces;
3532 return Replaces;
3535 return Replaces;
3536 }
3542 return Replaces;
3543}
3544
3545template
3550 if (Replaces.empty())
3552
3553 auto NewCode = applyAllReplacements(Code, Replaces);
3554 if (!NewCode)
3555 return NewCode.takeError();
3556 std::vectortooling::Range ChangedRanges = Replaces.getAffectedRanges();
3557 StringRef FileName = Replaces.begin()->getFilePath();
3558
3560 ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
3561
3562 return Replaces.merge(FormatReplaces);
3563}
3564
3568
3569
3571 std::vectortooling::Range Ranges,
3574 };
3575 auto SortedReplaces =
3577 if (!SortedReplaces)
3578 return SortedReplaces.takeError();
3579
3580
3581
3582 auto Reformat = [](const FormatStyle &Style, StringRef Code,
3583 std::vectortooling::Range Ranges,
3586 };
3588}
3589
3590namespace {
3591
3596}
3597
3598inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3599 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
3600}
3601
3602
3603tooling::Replacements
3604fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3606 if (!Style.isCpp())
3607 return Replaces;
3608
3609 tooling::Replacements HeaderInsertions;
3610 std::set HeadersToDelete;
3611 tooling::Replacements Result;
3612 for (const auto &R : Replaces) {
3613 if (isHeaderInsertion(R)) {
3614
3615
3616 consumeError(HeaderInsertions.add(R));
3617 } else if (isHeaderDeletion(R)) {
3618 HeadersToDelete.insert(R.getReplacementText());
3619 } else if (R.getOffset() == UINT_MAX) {
3620 llvm::errs() << "Insertions other than header #include insertion are "
3621 "not supported! "
3622 << R.getReplacementText() << "\n";
3623 } else {
3624 consumeError(Result.add(R));
3625 }
3626 }
3627 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3628 return Replaces;
3629
3630 StringRef FileName = Replaces.begin()->getFilePath();
3632
3633 for (const auto &Header : HeadersToDelete) {
3634 tooling::Replacements Replaces =
3635 Includes.remove(Header.trim("\"<>"), Header.starts_with("<"));
3636 for (const auto &R : Replaces) {
3637 auto Err = Result.add(R);
3638 if (Err) {
3639
3640 llvm::errs() << "Failed to add header deletion replacement for "
3641 << Header << ": " << toString(std::move(Err)) << "\n";
3642 }
3643 }
3644 }
3645
3646 SmallVector<StringRef, 4> Matches;
3647 for (const auto &R : HeaderInsertions) {
3649 bool Matched =
3651 assert(Matched && "Header insertion replacement must have replacement text "
3652 "'#include ...'");
3653 (void)Matched;
3654 auto IncludeName = Matches[2];
3655 auto Replace =
3656 Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"),
3658 if (Replace) {
3659 auto Err = Result.add(*Replace);
3660 if (Err) {
3661 consumeError(std::move(Err));
3662 unsigned NewOffset =
3663 Result.getShiftedCodePosition(Replace->getOffset());
3664 auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3665 Replace->getReplacementText());
3666 Result = Result.merge(tooling::Replacements(Shifted));
3667 }
3668 }
3669 }
3671}
3672
3673}
3674
3675Expectedtooling::Replacements
3678
3679
3680 auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3684 };
3685
3687 fixCppIncludeInsertions(Code, Replaces, Style);
3688 return cantFail(processReplacements(Cleanup, Code, NewReplaces, Style));
3689}
3690
3691namespace internal {
3692std::pair<tooling::Replacements, unsigned>
3695 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3706 case FormatStyle::RCPS_SingleLine:
3707 case FormatStyle::RCPS_WithPreceding:
3709 break;
3710 default:
3711 break;
3712 }
3713
3718 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
3720
3721
3722 if (Style.isJson()) {
3723 std::vectortooling::Range Ranges(1, tooling::Range(0, Code.size()));
3724 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3725 NextStartColumn, LastStartColumn);
3726 if ()
3727 return {};
3728
3730 Formatter(*Env, Style, Status).process().first;
3731
3732 Replaces = Replaces.merge(
3734
3735 if (applyAllReplacements(Code, Replaces))
3736 return {Replaces, 0};
3738 }
3739
3740 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3741 NextStartColumn, LastStartColumn);
3742 if ()
3743 return {};
3744
3745 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3748
3750
3753 });
3754
3755 if (Style.isCpp()) {
3758
3762 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3763 return ParensRemover(Env, S).process(true);
3764 });
3765 }
3766
3769 S.InsertBraces = true;
3770 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3771 return BracesInserter(Env, S).process(true);
3772 });
3773 }
3774
3777 S.RemoveBracesLLVM = true;
3778 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3779 return BracesRemover(Env, S).process(true);
3780 });
3781 }
3782
3785 S.RemoveSemicolon = true;
3786 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3787 return SemiRemover(Env, S).process();
3788 });
3789 }
3790
3794 });
3795 }
3796
3800 });
3801 }
3802 }
3803
3807 });
3808 }
3809
3810 if (Style.Language == FormatStyle::LK_ObjC &&
3814 });
3815 }
3816
3820 return JavaScriptRequoter(Env, Expanded).process(true);
3821 });
3822 }
3823
3825 return Formatter(Env, Expanded, Status).process();
3826 });
3827
3831 return TrailingCommaInserter(Env, Expanded).process();
3832 });
3833 }
3834
3835 std::optionalstd::string CurrentCode;
3837 unsigned Penalty = 0;
3838 for (size_t I = 0, E = Passes.size(); I < E; ++I) {
3839 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3840 auto NewCode = applyAllReplacements(
3841 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3842 if (NewCode) {
3843 Fixes = Fixes.merge(PassFixes.first);
3844 Penalty += PassFixes.second;
3845 if (I + 1 < E) {
3846 CurrentCode = std::move(*NewCode);
3847 Env = Environment::make(
3849 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3850 FirstStartColumn, NextStartColumn, LastStartColumn);
3851 if ()
3852 return {};
3853 }
3854 }
3855 }
3856
3858
3859
3860
3863 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3864 if (OriginalCode != Fix.getReplacementText()) {
3865 auto Err = NonNoOpFixes.add(Fix);
3866 if (Err) {
3867 llvm::errs() << "Error adding replacements : "
3868 << toString(std::move(Err)) << "\n";
3869 }
3870 }
3871 }
3872 Fixes = std::move(NonNoOpFixes);
3873 }
3874
3875 return {Fixes, Penalty};
3876}
3877}
3878
3884 0,
3885 0,
3886 0, FileName, Status)
3887 .first;
3888}
3889
3893
3897 if ()
3898 return {};
3899 return Cleaner(*Env, Style).process().first;
3900}
3901
3904 StringRef FileName, bool *IncompleteFormat) {
3907 if (!Status.FormatComplete)
3908 *IncompleteFormat = true;
3910}
3911
3913 StringRef Code,
3917 if ()
3918 return {};
3920}
3921
3923 StringRef Code,
3927 if ()
3928 return {};
3930}
3931
3934
3940 LangOpts.CPlusPlus = 1;
3946
3947
3948
3950
3951 LangOpts.LineComment = 1;
3952 LangOpts.CXXOperatorNames = Style.isCpp();
3953 LangOpts.Bool = 1;
3954 LangOpts.ObjC = 1;
3955 LangOpts.MicrosoftExt = 1;
3956 LangOpts.DeclSpecKeyword = 1;
3957 LangOpts.C99 = 1;
3958 return LangOpts;
3959}
3960
3962 "Set coding style. can be:\n"
3963 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3964 " Mozilla, WebKit.\n"
3965 "2. 'file' to load style configuration from a\n"
3966 " .clang-format file in one of the parent directories\n"
3967 " of the source file (for stdin, see --assume-filename).\n"
3968 " If no .clang-format file is found, falls back to\n"
3969 " --fallback-style.\n"
3970 " --style=file is the default.\n"
3971 "3. 'file:<format_file_path>' to explicitly specify\n"
3972 " the configuration file.\n"
3973 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3974 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3975
3977 if (FileName.ends_with(".java"))
3979 if (FileName.ends_with_insensitive(".js") ||
3980 FileName.ends_with_insensitive(".mjs") ||
3981 FileName.ends_with_insensitive(".cjs") ||
3982 FileName.ends_with_insensitive(".ts")) {
3984 }
3987 if (FileName.ends_with_insensitive(".proto") ||
3988 FileName.ends_with_insensitive(".protodevel")) {
3990 }
3991
3992
3993
3994 if (FileName.ends_with_insensitive(".txtpb") ||
3995 FileName.ends_with_insensitive(".textpb") ||
3996 FileName.ends_with_insensitive(".pb.txt") ||
3997 FileName.ends_with_insensitive(".textproto") ||
3998 FileName.ends_with_insensitive(".asciipb")) {
4000 }
4001 if (FileName.ends_with_insensitive(".td"))
4003 if (FileName.ends_with_insensitive(".cs"))
4005 if (FileName.ends_with_insensitive(".json"))
4007 if (FileName.ends_with_insensitive(".sv") ||
4008 FileName.ends_with_insensitive(".svh") ||
4009 FileName.ends_with_insensitive(".v") ||
4010 FileName.ends_with_insensitive(".vh")) {
4012 }
4014}
4015
4019 auto Extension = llvm::sys::path::extension(FileName);
4020
4021
4022 if (!Code.empty() && (Extension.empty() || Extension == ".h")) {
4023 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
4024 Environment Env(Code, NonEmptyFileName, {});
4026 Guesser.process();
4027 if (Guesser.isObjC())
4029 }
4030 }
4031 return GuessedLanguage;
4032}
4033
4034
4036
4038
4039llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer>
4041 FormatStyle *Style, bool AllowUnknownOptions,
4042 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4043 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =
4044 FS->getBufferForFile(ConfigFile.str());
4045 if (auto EC = Text.getError())
4046 return EC;
4048 DiagHandler)) {
4049 return EC;
4050 }
4051 return Text;
4052}
4053
4055 StringRef FallbackStyleName, StringRef Code,
4056 llvm::vfs::FileSystem *FS,
4057 bool AllowUnknownOptions,
4058 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4062 return make_string_error("Invalid fallback style: " + FallbackStyleName);
4063
4065
4066 if (StyleName.starts_with("{")) {
4067
4068 StringRef Source = "";
4069 if (std::error_code ec =
4070 parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
4071 AllowUnknownOptions, DiagHandler)) {
4072 return make_string_error("Error parsing -style: " + ec.message());
4073 }
4074
4076 return Style;
4077
4078 ChildFormatTextToApply.emplace_back(
4079 llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
4080 }
4081
4082 if (!FS)
4083 FS = llvm::vfs::getRealFileSystem().get();
4084 assert(FS);
4085
4086
4088 StyleName.starts_with_insensitive("file:")) {
4089 auto ConfigFile = StyleName.substr(5);
4090 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =
4092 DiagHandler);
4093 if (auto EC = Text.getError()) {
4095 EC.message());
4096 }
4097
4098 LLVM_DEBUG(llvm::dbgs()
4099 << "Using configuration file " << ConfigFile << "\n");
4100
4102 return Style;
4103
4104
4105
4107 ChildFormatTextToApply.emplace_back(std::move(*Text));
4108 }
4109
4110
4111
4112
4117 return Style;
4118 }
4119
4121 if (std::error_code EC = FS->makeAbsolute(Path))
4123
4124
4126
4127 auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
4128
4129 auto applyChildFormatTexts = [&](FormatStyle *Style) {
4130 for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4131 auto EC =
4133 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4134
4135 assert(!EC);
4136 static_cast<void>(EC);
4137 }
4138 };
4139
4140
4142 FilesToLookFor.push_back(".clang-format");
4143 FilesToLookFor.push_back("_clang-format");
4144
4146 for (StringRef Directory = Path; !Directory.empty();
4147 Directory = llvm::sys::path::parent_path(Directory)) {
4148 auto Status = FS->status(Directory);
4149 if (!Status ||
4150 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4151 continue;
4152 }
4153
4154 for (const auto &F : FilesToLookFor) {
4156
4157 llvm::sys::path::append(ConfigFile, F);
4158 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
4159
4160 Status = FS->status(ConfigFile);
4161 if (!Status ||
4162 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4163 continue;
4164 }
4165
4166 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =
4168 DiagHandler);
4169 if (auto EC = Text.getError()) {
4172 EC.message());
4173 }
4174 if (!UnsuitableConfigFiles.empty())
4175 UnsuitableConfigFiles.append(", ");
4176 UnsuitableConfigFiles.append(ConfigFile);
4177 continue;
4178 }
4179
4180 LLVM_DEBUG(llvm::dbgs()
4181 << "Using configuration file " << ConfigFile << "\n");
4182
4184 if (!ChildFormatTextToApply.empty()) {
4185 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4186 applyChildFormatTexts(&Style);
4187 }
4188 return Style;
4189 }
4190
4191 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4192
4193
4195
4196 ChildFormatTextToApply.emplace_back(std::move(*Text));
4197
4198
4199
4200
4201
4202 break;
4203 }
4204 }
4205
4206 if (!UnsuitableConfigFiles.empty()) {
4207 return make_string_error("Configuration file(s) do(es) not support " +
4209 UnsuitableConfigFiles);
4210 }
4211
4212 if (!ChildFormatTextToApply.empty()) {
4213 LLVM_DEBUG(llvm::dbgs()
4214 << "Applying child configurations on fallback style\n");
4215 applyChildFormatTexts(&FallbackStyle);
4216 }
4217
4218 return FallbackStyle;
4219}
4220
4222 if (Comment == (On ? "/* clang-format on */" : "/* clang-format off */"))
4223 return true;
4224
4225 static const char ClangFormatOn[] = "// clang-format on";
4226 static const char ClangFormatOff[] = "// clang-format off";
4227 const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1;
4228
4229 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4230 (Comment.size() == Size || Comment[Size] == ':');
4231}
4232
4235}
4236
4239}
4240
4241}
4242}
This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or removes empty lines sepa...
SmallVector< StringRef > AssociatedCommentLines
Various functions to configurably format source code.
This file declares IntegerLiteralSeparatorFixer that fixes C++ integer literal separators.
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...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
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...
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
std::string message(int EV) const override
std::pair< tooling::Replacements, unsigned > process(bool SkipAnnotation=false)
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).
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.
const char * StyleOptionHelpDescription
Description to be used for help text for a llvm::cl option for specifying format style.
void addQualifierAlignmentFixerPasses(const FormatStyle &Style, SmallVectorImpl< AnalyzerPass > &Passes)
static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded)
const char * DefaultFallbackStyle
The suggested predefined style to use as the fallback style in getStyle.
static bool affectsRange(ArrayRef< tooling::Range > Ranges, unsigned Start, unsigned End)
const char * getTokenTypeName(TokenType Type)
Determines the name of a token type.
FormatStyle getWebKitStyle()
Returns a format style complying with Webkit's style guide: http://www.webkit.org/coding/coding-style...
bool isLikelyXml(StringRef Code)
static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName)
static unsigned findJavaImportGroup(const FormatStyle &Style, StringRef ImportIdentifier)
std::string replaceCRLF(const std::string &Code)
std::error_code make_error_code(ParseError e)
FormatStyle getClangFormatStyle()
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...
FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with one of Google's style guides: http://google-styleguide....
std::string configurationAsText(const FormatStyle &Style)
Gets configuration in a YAML string.
FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with Microsoft style guide: https://docs.microsoft....
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.
const std::error_category & getParseCategory()
tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")
Fix namespace end comments in the given Ranges in Code.
FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code)
Expected< FormatStyle > getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyle, StringRef Code="", llvm::vfs::FileSystem *FS=nullptr, bool AllowUnknownOptions=false, llvm::SourceMgr::DiagHandlerTy DiagHandler=nullptr)
Construct a FormatStyle based on StyleName.
bool isMpegTS(StringRef Code)
@ DuplicateQualifierSpecified
@ BinPackTrailingCommaConflict
@ InvalidQualifierSpecified
static std::pair< unsigned, unsigned > FindCursorIndex(const ArrayRef< IncludeDirective > &Includes, const ArrayRef< unsigned > &Indices, unsigned Cursor)
const char * DefaultFormatStyle
The suggested format style to use by default.
FormatStyle getGNUStyle()
Returns a format style complying with GNU Coding Standards: http://www.gnu.org/prep/standards/standar...
bool isClangFormatOff(StringRef Comment)
LangOptions getFormattingLangOpts(const FormatStyle &Style=getLLVMStyle())
Returns the LangOpts that the formatter expects you to set.
static bool isClangFormatOnOff(StringRef Comment, bool On)
tooling::Replacements sortJavaScriptImports(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)
static void sortJavaImports(const FormatStyle &Style, const ArrayRef< JavaImportDirective > &Imports, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces)
FormatStyle getMozillaStyle()
Returns a format style complying with Mozilla's style guide: https://firefox-source-docs....
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
Gets a predefined style for the specified language by name.
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...
static void expandPresetsBraceWrapping(FormatStyle &Expanded)
static void sortCppIncludes(const FormatStyle &Style, const ArrayRef< IncludeDirective > &Includes, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces, unsigned *Cursor)
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="", FormattingAttemptStatus *Status=nullptr)
Reformats the given Ranges in Code.
bool isClangFormatOn(StringRef Comment)
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler)
tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")
Sort consecutive using declarations in the given Ranges in Code.
llvm::Error make_string_error(const Twine &Message)
ParseError validateQualifierOrder(FormatStyle *Style)
FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with Chromium's style guide: http://www.chromium....
static void expandPresetsSpacesInParens(FormatStyle &Expanded)
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")
Clean up any erroneous/redundant code in the given Ranges in Code.
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,...
FormatStyle getNoStyle()
Returns style indicating formatting should be not applied at all.
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.
static Expected< tooling::Replacements > processReplacements(T ProcessFunc, StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)
StringRef getLanguageName(FormatStyle::LanguageKind Language)
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.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
bool PadOperators
Only for AlignConsecutiveAssignments.
bool AlignFunctionDeclarations
Only for AlignConsecutiveDeclarations.
bool SplitEmptyRecord
If false, empty record (e.g.
bool AfterClass
Wrap class definitions.
bool AfterCaseLabel
Wrap case labels.
bool AfterStruct
Wrap struct definitions.
bool BeforeLambdaBody
Wrap lambda block.
bool AfterUnion
Wrap union definitions.
bool AfterEnum
Wrap enum definitions.
bool AfterObjCDeclaration
Wrap ObjC definitions (interfaces, implementations...).
bool BeforeElse
Wrap before else.
bool AfterNamespace
Wrap namespace definitions.
bool BeforeWhile
Wrap before while.
BraceWrappingAfterControlStatementStyle AfterControlStatement
Wrap control statements (if/for/while/switch/..).
bool AfterFunction
Wrap function definitions.
bool BeforeCatch
Wrap before catch.
bool SplitEmptyFunction
If false, empty function body can be put on a single line.
bool AfterExternBlock
Wrap extern blocks.
void Add(FormatStyle Style)
std::optional< FormatStyle > Get(FormatStyle::LanguageKind Language) const
int8_t DecimalMinDigits
Format separators in decimal literals with a minimum number of digits.
int8_t Decimal
Format separators in decimal literals.
bool AtEndOfFile
Keep empty lines at end of file.
bool AtStartOfBlock
Keep empty lines at start of a block.
bool AfterControlStatements
If true, put space between control statement keywords (for/if/while...) and opening parentheses.
bool AfterForeachMacros
If true, put space between foreach macros and opening parentheses.
bool BeforeNonEmptyParentheses
If true, put a space before opening parentheses only if the parentheses are not empty.
bool AfterIfMacros
If true, put space between if macros and opening parentheses.
bool AfterPlacementOperator
If true, put a space between operator new/delete and opening parenthesis.
bool ExceptDoubleParentheses
Override any of the following options to prevent addition of space when both opening and closing pare...
bool Other
Put a space in parentheses not covered by preceding options.
bool InEmptyParentheses
Insert a space in empty parentheses, i.e.
bool InCStyleCasts
Put a space in C style casts.
bool InConditionalStatements
Put a space in parentheses only inside conditional statements (for/if/while/switch....
The FormatStyle is used to configure the formatting to follow specific guidelines.
bool SpaceBeforeInheritanceColon
If false, spaces will be removed before inheritance colon.
unsigned ContinuationIndentWidth
Indent width for line continuations.
bool AlwaysBreakBeforeMultilineStrings
This option is renamed to BreakAfterReturnType.
LanguageStandard Standard
Parse and format C++ constructs compatible with this standard.
bool BreakAdjacentStringLiterals
Break between adjacent string literals.
ReturnTypeBreakingStyle BreakAfterReturnType
The function declaration return type breaking style to use.
LanguageKind
Supported languages.
@ LK_CSharp
Should be used for C#.
@ LK_Java
Should be used for Java.
@ LK_Cpp
Should be used for C, C++.
@ LK_JavaScript
Should be used for JavaScript.
@ LK_ObjC
Should be used for Objective-C, Objective-C++.
@ LK_Verilog
Should be used for Verilog and SystemVerilog.
@ LK_TableGen
Should be used for TableGen code.
@ LK_Proto
Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).
@ LK_Json
Should be used for JSON.
@ LK_TextProto
Should be used for Protocol Buffer messages in text format (https://developers.google....
bool Cpp11BracedListStyle
If true, format braced lists as best suited for C++11 braced lists.
SortIncludesOptions SortIncludes
Controls if and how clang-format will sort #includes.
BreakInheritanceListStyle BreakInheritanceList
The inheritance list style to use.
unsigned IndentWidth
The number of columns to use for indentation.
std::vector< std::string > AttributeMacros
This option is renamed to BreakTemplateDeclarations.
@ SLS_All
Merge all lambdas fitting on a single line.
@ SLS_Empty
Only merge empty lambdas.
@ SDS_Leave
Leave definition blocks as they are.
bool IndentRequiresClause
Indent the requires clause in a template.
SpacesInAnglesStyle SpacesInAngles
The SpacesInAnglesStyle to use for template argument lists.
bool KeepFormFeed
This option is deprecated.
bool IndentCaseLabels
Indent case labels one level from the switch statement.
std::vector< RawStringFormat > RawStringFormats
Defines hints for detecting supported languages code blocks in raw strings.
std::vector< std::string > VariableTemplates
A vector of non-keyword identifiers that should be interpreted as variable template names.
@ SJSIO_Before
Static imports are placed before non-static imports.
@ SJSIO_After
Static imports are placed after non-static imports.
PPDirectiveIndentStyle IndentPPDirectives
The preprocessor directive indenting style to use.
bool RemoveSemicolon
Remove semicolons after the closing braces of functions and constructors/destructors.
std::vector< std::string > Macros
A list of macros of the form = .
bool SpaceBeforeJsonColon
If true, a space will be added before a JSON colon.
@ TCS_None
Do not insert trailing commas.
unsigned PenaltyBreakBeforeFirstCallParameter
The penalty for breaking a function call after call(.
bool SpaceBeforeCtorInitializerColon
If false, spaces will be removed before constructor initializer colon.
@ BPPS_OnePerLine
Put all parameters on the current line if they fit.
@ BPPS_BinPack
Bin-pack parameters.
BinaryOperatorStyle BreakBeforeBinaryOperators
The way to wrap binary operators.
@ SI_Never
Includes are never sorted.
@ SI_CaseSensitive
Includes are sorted in an ASCIIbetical or case sensitive fashion.
@ SI_CaseInsensitive
Includes are sorted in an alphabetical or case insensitive fashion.
bool IndentExportBlock
If true, clang-format will indent the body of an export { ... } block.
@ BPS_Never
Never bin-pack parameters.
@ BPS_Auto
Automatically determine parameter bin-packing behavior.
BitFieldColonSpacingStyle BitFieldColonSpacing
The BitFieldColonSpacingStyle to use for bitfields.
@ RCS_Always
Apply indentation rules and reflow long comments into new lines, trying to obey the ColumnLimit.
@ ELBAMS_LogicalBlock
Add empty line only when access modifier starts a new logical block.
unsigned SpacesBeforeTrailingComments
If true, spaces may be inserted into ().
@ BCIS_BeforeColon
Break constructor initializers before the colon and after the commas.
@ BCIS_BeforeComma
Break constructor initializers before the colon and commas, and align the commas with the colon.
@ IEBS_AfterExternBlock
Backwards compatible with AfterExternBlock's indenting.
bool IndentCaseBlocks
Indent case label blocks one level from the case label.
bool InsertBraces
Insert braces after control statements (if, else, for, do, and while) in C++ unless the control state...
BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations
The concept declaration style to use.
BreakTemplateDeclarationsStyle BreakTemplateDeclarations
The template declaration breaking style to use.
bool DerivePointerAlignment
This option is deprecated.
@ BOS_All
Break before operators.
@ BOS_None
Break after operators.
@ BOS_NonAssignment
Break before operators that aren't assignments.
@ LE_DeriveLF
Use \n unless the input has more lines ending in \r\n.
bool SpacesInSquareBrackets
If true, spaces will be inserted after [ and before ].
bool IndentWrappedFunctionNames
Indent if a function definition or declaration is wrapped after the type.
AlignConsecutiveStyle AlignConsecutiveTableGenBreakingDAGArgColons
Style of aligning consecutive TableGen DAGArg operator colons.
WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines
Wrap namespace body with empty lines.
bool FixNamespaceComments
If true, clang-format adds missing namespace end comments for namespaces and fixes invalid existing o...
bool ObjCSpaceBeforeProtocolList
Add a space in front of an Objective-C protocol list, i.e.
@ TCAS_Never
Don't align trailing comments but other formatter applies.
@ TCAS_Always
Align trailing comments.
RemoveParenthesesStyle RemoveParentheses
Remove redundant parentheses.
std::string MacroBlockBegin
A regular expression matching macros that start a block.
bool SpaceInEmptyBlock
If true, spaces will be inserted into {}.
LanguageKind Language
Language, this format style is targeted at.
@ SIPO_Custom
Configure each individual space in parentheses in SpacesInParensOptions.
@ SIPO_Never
Never put a space in parentheses.
bool RemoveBracesLLVM
Remove optional braces of control statements (if, else, for, and while) in C++ according to the LLVM ...
@ BAS_DontAlign
Don't align, instead use ContinuationIndentWidth, e.g.:
@ BAS_AlwaysBreak
Always break after an open bracket, if the parameters don't fit on a single line, e....
@ BAS_Align
Align parameters on the open bracket, e.g.:
@ BBIAS_OnlyMultiline
Break before inline ASM colon if the line length is longer than column limit.
bool VerilogBreakBetweenInstancePorts
For Verilog, put each port on its own line in module instantiations.
unsigned TabWidth
The number of columns used for tab stops.
@ PPDIS_None
Does not indent any directives.
@ LBI_Signature
Align lambda body relative to the lambda signature.
std::vector< std::string > JavaImportGroups
A vector of prefixes ordered by the desired groups for Java imports.
bool AllowShortCaseLabelsOnASingleLine
If true, short case labels will be contracted to a single line.
unsigned PenaltyBreakFirstLessLess
The penalty for breaking before the first <<.
std::vector< std::string > StatementAttributeLikeMacros
Macros which are ignored in front of a statement, as if they were an attribute.
unsigned ObjCBlockIndentWidth
The number of characters to use for indentation of ObjC blocks.
bool AllowShortLoopsOnASingleLine
If true, while (true) continue; can be put on a single line.
int AccessModifierOffset
The extra indent or outdent of access modifiers, e.g.
std::vector< std::string > QualifierOrder
The order in which the qualifiers appear.
bool AllowShortEnumsOnASingleLine
Allow short enums on a single line.
@ SBS_Empty
Only merge empty blocks.
@ SBS_Never
Never merge blocks into a single line.
std::optional< FormatStyle > GetLanguageStyle(LanguageKind Language) const
std::vector< std::string > IfMacros
A vector of macros that should be interpreted as conditionals instead of as function calls.
NamespaceIndentationKind NamespaceIndentation
The indentation used for namespaces.
bool BreakArrays
If true, clang-format will always break after a Json array [ otherwise it will scan until the closing...
bool BreakAfterJavaFieldAnnotations
Break after each annotation on a field in Java files.
@ SIS_WithoutElse
Put short ifs on the same line only if there is no else statement.
@ SIS_Never
Never put short ifs on the same line.
std::optional< unsigned > BracedInitializerIndentWidth
The number of columns to use to indent the contents of braced init lists.
std::vector< std::string > ObjCPropertyAttributeOrder
The order in which ObjC property attributes should appear.
bool ExperimentalAutoDetectBinPacking
If true, clang-format detects whether function calls and definitions are formatted with one parameter...
bool ObjCBreakBeforeNestedBlockParam
Break parameters list into lines when there is nested block parameters in a function call.
OperandAlignmentStyle AlignOperands
If true, horizontally align operands of binary and ternary expressions.
unsigned PenaltyBreakOpenParenthesis
The penalty for breaking after (.
@ BTDS_MultiLine
Force break after template declaration only when the following declaration spans multiple lines.
@ BTDS_Yes
Always break after template declaration.
bool AllowShortCompoundRequirementOnASingleLine
Allow short compound requirement on a single line.
friend std::error_code parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
Parse configuration from YAML-formatted text.
SpacesInParensStyle SpacesInParens
If true, spaces will be inserted after ( and before ).
SpacesInParensCustom SpacesInParensOptions
Control of individual spaces in parentheses.
std::vector< std::string > ForEachMacros
A vector of macros that should be interpreted as foreach loops instead of as function calls.
ReferenceAlignmentStyle ReferenceAlignment
Reference alignment style (overrides PointerAlignment for references).
BreakBinaryOperationsStyle BreakBinaryOperations
The break binary operations style to use.
AlignConsecutiveStyle AlignConsecutiveTableGenDefinitionColons
Style of aligning consecutive TableGen definition colons.
TrailingCommaStyle InsertTrailingCommas
If set to TCS_Wrapped will insert trailing commas in container literals (arrays and objects) that wra...
unsigned PenaltyBreakTemplateDeclaration
The penalty for breaking after template declaration.
SpaceBeforeParensCustom SpaceBeforeParensOptions
Control of individual space before parentheses.
BreakConstructorInitializersStyle BreakConstructorInitializers
The break constructor initializers style to use.
bool RemoveEmptyLinesInUnwrappedLines
Remove empty lines within unwrapped lines.
bool BreakStringLiterals
Allow breaking string literals when formatting.
bool SpaceAfterLogicalNot
If true, a space is inserted after the logical not operator (!).
@ SBPO_Custom
Configure each individual space before parentheses in SpaceBeforeParensOptions.
@ SBPO_NonEmptyParentheses
Put a space before opening parentheses only if the parentheses are not empty.
@ SBPO_ControlStatementsExceptControlMacros
Same as SBPO_ControlStatements except this option doesn't apply to ForEach and If macros.
@ SBPO_ControlStatements
Put a space before opening parentheses only after control statement keywords (for/if/while....
@ SBPO_Always
Always put a space before opening parentheses, except when it's prohibited by the syntax rules (in fu...
@ PCIS_BinPack
Bin-pack constructor initializers.
@ PCIS_NextLine
Same as PCIS_CurrentLine except that if all constructor initializers do not fit on the current line,...
std::vector< std::string > TypeNames
A vector of non-keyword identifiers that should be interpreted as type names.
bool ObjCSpaceAfterProperty
Add a space after @property in Objective-C, i.e.
BraceBreakingStyle BreakBeforeBraces
The brace breaking style to use.
@ BILS_BeforeColon
Break inheritance list before the colon and after the commas.
@ BILS_BeforeComma
Break inheritance list before the colon and commas, and align the commas with the colon.
unsigned PenaltyExcessCharacter
The penalty for each character outside of the column limit.
std::vector< std::string > WhitespaceSensitiveMacros
A vector of macros which are whitespace-sensitive and should not be touched.
std::vector< std::string > TemplateNames
A vector of non-keyword identifiers that should be interpreted as template names.
@ DAS_DontBreak
Never break inside DAGArg.
unsigned ConstructorInitializerIndentWidth
This option is deprecated.
@ BBNSS_Never
No line break allowed.
bool CompactNamespaces
If true, consecutive namespace declarations will be on the same line.
@ RCPS_OwnLine
Always put the requires clause on its own line (possibly followed by a semicolon).
LanguageStandard
Supported language standards for parsing and formatting C++ constructs.
@ LS_Cpp17
Parse and format as C++17.
@ LS_Latest
Parse and format using the latest supported language version.
@ LS_Cpp11
Parse and format as C++11.
@ LS_Auto
Automatic detection based on the input.
@ LS_Cpp14
Parse and format as C++14.
@ LS_Cpp20
Parse and format as C++20.
@ BWACS_Always
Always wrap braces after a control statement.
@ BWACS_Never
Never wrap braces after a control statement.
RequiresClausePositionStyle RequiresClausePosition
The position of the requires clause.
@ JSQS_Single
Always use single quotes.
@ JSQS_Leave
Leave string quotes as they are.
bool SpaceAfterCStyleCast
If true, a space is inserted after C style casts.
AlignConsecutiveStyle AlignConsecutiveBitFields
Style of aligning consecutive bit fields.
int PPIndentWidth
The number of columns to use for indentation of preprocessor statements.
AlignConsecutiveStyle AlignConsecutiveDeclarations
Style of aligning consecutive declarations.
IntegerLiteralSeparatorStyle IntegerLiteralSeparator
Format integer literal separators (' for C++ and _ for C#, Java, and JavaScript).
SpaceAroundPointerQualifiersStyle SpaceAroundPointerQualifiers
Defines in which cases to put a space before or after pointer qualifiers.
DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType
The function definition return type breaking style to use.
bool SpaceBeforeAssignmentOperators
If false, spaces will be removed before assignment operators.
BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon
The inline ASM colon style to use.
@ WNBWELS_Leave
Keep existing newlines at the beginning and the end of namespace body.
@ BS_Mozilla
Like Attach, but break before braces on enum, function, and record definitions.
@ BS_Whitesmiths
Like Allman but always indent braces and line up code with braces.
@ BS_Allman
Always break before braces.
@ BS_Stroustrup
Like Attach, but break before function definitions, catch, and else.
@ BS_Linux
Like Attach, but break before braces on function, namespace and class definitions.
@ BS_WebKit
Like Attach, but break before functions.
@ BS_Custom
Configure each individual brace in BraceWrapping.
@ BS_GNU
Always break before braces and add an extra level of indentation to braces of control statements,...
@ BS_Attach
Always attach braces to surrounding context.
@ ABS_Leave
Leave the line breaking after attributes as is.
bool BinPackArguments
If false, a function call's arguments will either be all on the same line or will have one line each.
ShortLambdaStyle AllowShortLambdasOnASingleLine
Dependent on the value, auto lambda []() { return 0; } can be put on a single line.
unsigned PenaltyBreakScopeResolution
The penalty for breaking after ::.
unsigned PenaltyReturnTypeOnItsOwnLine
Penalty for putting the return type of a function onto its own line.
@ BFCS_Both
Add one space on each side of the :
PointerAlignmentStyle PointerAlignment
Pointer and reference alignment style.
@ SFS_Inline
Only merge functions defined inside a class.
@ SFS_All
Merge all functions fitting on a single line.
@ SFS_Empty
Only merge empty functions.
@ SFS_None
Never merge functions into a single line.
bool BreakFunctionDefinitionParameters
If true, clang-format will always break before function definition parameters.
@ REI_OuterScope
Align requires expression body relative to the indentation level of the outer scope the requires expr...
PackConstructorInitializersStyle PackConstructorInitializers
The pack constructor initializers style to use.
@ BBCDS_Always
Always break before concept, putting it in the line after the template declaration.
ReflowCommentsStyle ReflowComments
Comment reformatting style.
KeepEmptyLinesStyle KeepEmptyLines
Which empty lines are kept.
bool AllowAllParametersOfDeclarationOnNextLine
This option is deprecated.
BracketAlignmentStyle AlignAfterOpenBracket
If true, horizontally aligns arguments after an open bracket.
AlignConsecutiveStyle AlignConsecutiveTableGenCondOperatorColons
Style of aligning consecutive TableGen cond operator colons.
BinPackParametersStyle BinPackParameters
The bin pack parameters style to use.
bool AllowShortCaseExpressionOnASingleLine
Whether to merge a short switch labeled rule into a single line.
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
bool SpaceBeforeSquareBrackets
If true, spaces will be before [.
BinPackStyle ObjCBinPackProtocolList
Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...
ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements
Style of aligning consecutive short case labels.
EscapedNewlineAlignmentStyle AlignEscapedNewlines
Options for aligning backslashes in escaped newlines.
SpacesInLineComment SpacesInLineCommentPrefix
How many spaces are allowed at the start of a line comment.
std::string CommentPragmas
A regular expression that describes comments with special meaning, which should not be split into lin...
bool isJavaScript() const
DAGArgStyle TableGenBreakInsideDAGArg
The styles of the line break inside the DAGArg in TableGen.
JavaScriptQuoteStyle JavaScriptQuotes
The JavaScriptQuoteStyle to use for JavaScript strings.
bool SpacesInContainerLiterals
If true, spaces will be inserted around if/for/switch/while conditions.
SortJavaStaticImportOptions SortJavaStaticImport
When sorting Java imports, by default static imports are placed before non-static imports.
@ SAPQ_Default
Don't ensure spaces around pointer qualifiers and use PointerAlignment instead.
bool SpaceBeforeRangeBasedForLoopColon
If false, spaces will be removed before range-based for loop colon.
bool DisableFormat
Disables formatting completely.
@ ELAAMS_Never
Remove all empty lines after access modifiers.
@ DRTBS_All
Always break after the return type.
@ DRTBS_TopLevel
Always break after the return types of top-level functions.
@ DRTBS_None
Break after return type automatically.
bool AllowShortNamespacesOnASingleLine
If true, namespace a { class b; } can be put on a single line.
std::vector< std::string > NamespaceMacros
A vector of macros which are used to open namespace blocks.
AttributeBreakingStyle BreakAfterAttributes
Break after a group of C++11 attributes before variable or function (including constructor/destructor...
TrailingCommentsAlignmentStyle AlignTrailingComments
Control of trailing comments.
@ AIAS_None
Don't align array initializer columns.
LambdaBodyIndentationKind LambdaBodyIndentation
The indentation style of lambda bodies.
QualifierAlignmentStyle QualifierAlignment
Different ways to arrange specifiers and qualifiers (e.g.
@ BBO_Never
Don't break binary operations.
bool IndentGotoLabels
Indent goto labels.
BraceWrappingFlags BraceWrapping
Control of individual brace wrapping cases.
@ ENAS_Left
Align escaped newlines as far left as possible.
@ ENAS_Right
Align escaped newlines in the right-most column.
AlignConsecutiveStyle AlignConsecutiveMacros
Style of aligning consecutive macro definitions.
std::vector< std::string > StatementMacros
A vector of macros that should be interpreted as complete statements.
@ SIAS_Never
Remove spaces after < and before >.
@ SUD_LexicographicNumeric
Using declarations are sorted in the order defined as follows: Split the strings by :: and discard an...
@ SUD_Never
Using declarations are never sorted.
AlignConsecutiveStyle AlignConsecutiveAssignments
Style of aligning consecutive assignments.
ShortIfStyle AllowShortIfStatementsOnASingleLine
Dependent on the value, if (a) return; can be put on a single line.
@ RPS_Leave
Do not remove parentheses.
@ RPS_ReturnStatement
Also remove parentheses enclosing the expression in a return/co_return statement.
std::vector< std::string > TableGenBreakingDAGArgOperators
Works only when TableGenBreakInsideDAGArg is not DontBreak.
EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier
Defines in which cases to put empty line before access modifiers.
bool SpaceBeforeCaseColon
If false, spaces will be removed before case colon.
BreakBeforeNoexceptSpecifierStyle AllowBreakBeforeNoexceptSpecifier
Controls if there could be a line break before a noexcept specifier.
bool JavaScriptWrapImports
Whether to wrap JavaScript import/export statements.
bool SkipMacroDefinitionBody
Do not format macro definition body.
unsigned PenaltyBreakAssignment
The penalty for breaking around an assignment operator.
@ PAS_Left
Align pointer to the left.
@ PAS_Right
Align pointer to the right.
unsigned PenaltyBreakString
The penalty for each line break introduced inside a string literal.
RequiresExpressionIndentationKind RequiresExpressionIndentation
The indentation used for requires expression bodies.
bool SpaceAfterTemplateKeyword
If true, a space will be inserted after the template keyword.
unsigned PenaltyIndentedWhitespace
Penalty for each character of whitespace indentation (counted relative to leading non-whitespace colu...
ArrayInitializerAlignmentStyle AlignArrayOfStructures
If not None, when using initialization for an array of structs aligns the fields into columns.
@ NI_None
Don't indent in namespaces.
@ NI_All
Indent in all namespaces.
@ NI_Inner
Indent only in inner namespaces (nested in other namespaces).
ShortBlockStyle AllowShortBlocksOnASingleLine
Dependent on the value, while (true) { continue; } can be put on a single line.
std::string MacroBlockEnd
A regular expression matching macros that end a block.
ShortFunctionStyle AllowShortFunctionsOnASingleLine
Dependent on the value, int f() { return 0; } can be put on a single line.
bool AllowAllArgumentsOnNextLine
If a function call or braced initializer list doesn't fit on a line, allow putting all arguments onto...
unsigned PenaltyBreakComment
The penalty for each line break introduced inside a comment.
bool InheritsParentConfig
@ RTBS_TopLevel
Always break after the return types of top-level functions.
@ RTBS_None
This is deprecated. See Automatic below.
@ RTBS_AllDefinitions
Always break after the return type of function definitions.
@ RAS_Pointer
Align reference like PointerAlignment.
EmptyLineAfterAccessModifierStyle EmptyLineAfterAccessModifier
Defines when to put an empty line after access modifiers.
bool IndentAccessModifiers
Specify whether access modifiers should have their own indentation level.
bool InsertNewlineAtEOF
Insert a newline at end of file if missing.
SpaceBeforeParensStyle SpaceBeforeParens
Defines in which cases to put a space before opening parentheses.
bool SpaceBeforeCpp11BracedList
If true, a space will be inserted before a C++11 braced list used to initialize an object (after the ...
UseTabStyle UseTab
The way to use tab characters in the resulting file.
@ QAS_Leave
Don't change specifiers/qualifiers to either Left or Right alignment (default).
std::vector< std::string > TypenameMacros
A vector of macros that should be interpreted as type declarations instead of as function calls.
@ OAS_Align
Horizontally align operands of binary and ternary expressions.
@ OAS_DontAlign
Do not align operands of binary and ternary expressions.
LineEndingStyle LineEnding
Line ending style (\n or \r\n) to use.
bool BreakBeforeTernaryOperators
If true, ternary operators will be placed after line breaks.
unsigned ShortNamespaceLines
The maximal number of unwrapped lines that a short namespace spans.
SortUsingDeclarationsOptions SortUsingDeclarations
Controls if and how clang-format will sort using declarations.
IndentExternBlockStyle IndentExternBlock
IndentExternBlockStyle is the type of indenting of extern blocks.
SeparateDefinitionStyle SeparateDefinitionBlocks
Specifies the use of empty lines to separate definition blocks, including classes,...
tooling::IncludeStyle IncludeStyle
unsigned ColumnLimit
The column limit.
Represents the status of a formatting attempt.
static FormatStyle & element(IO &IO, std::vector< FormatStyle > &Seq, size_t Index)
static size_t size(IO &IO, std::vector< FormatStyle > &Seq)
static void mapping(IO &IO, FormatStyle &Style)
static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)
static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)
static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping)
static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base)
static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value)
static void mapping(IO &IO, FormatStyle::RawStringFormat &Format)
static void mapping(IO &IO, FormatStyle::ShortCaseStatementsAlignmentStyle &Value)
static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing)
static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces)
static void enumeration(IO &IO, FormatStyle::ArrayInitializerAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value)
static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value)
static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value)
static void enumeration(IO &IO, FormatStyle::BitFieldColonSpacingStyle &Value)
static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value)
static void enumeration(IO &IO, FormatStyle::BraceWrappingAfterControlStatementStyle &Value)
static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakBeforeInlineASMColonStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakBeforeNoexceptSpecifierStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakBinaryOperationsStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakInheritanceListStyle &Value)
static void enumeration(IO &IO, FormatStyle::BreakTemplateDeclarationsStyle &Value)
static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value)
static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value)
static void enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value)
static void enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value)
static void enumeration(IO &IO, FormatStyle::EscapedNewlineAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value)
static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value)
static void enumeration(IO &IO, FormatStyle::LambdaBodyIndentationKind &Value)
static void enumeration(IO &IO, FormatStyle::LanguageKind &Value)
static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value)
static void enumeration(IO &IO, FormatStyle::LineEndingStyle &Value)
static void enumeration(IO &IO, FormatStyle::NamespaceIndentationKind &Value)
static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value)
static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value)
static void enumeration(IO &IO, FormatStyle::RequiresClausePositionStyle &Value)
static void enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value)
static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value)
static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value)
static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value)
static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value)
static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value)
static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value)
static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value)
static void enumeration(IO &IO, FormatStyle::SortJavaStaticImportOptions &Value)
static void enumeration(IO &IO, FormatStyle::SortUsingDeclarationsOptions &Value)
static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value)
static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value)
static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value)
static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value)
static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value)
static void enumeration(IO &IO, FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value)