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