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