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("IndentExternBlock", Style.IndentExternBlock);
1055 IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
1056 IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
1057 IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause);
1058 IO.mapOptional("IndentWidth", Style.IndentWidth);
1059 IO.mapOptional("IndentWrappedFunctionNames",
1061 IO.mapOptional("InsertBraces", Style.InsertBraces);
1062 IO.mapOptional("InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1063 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
1064 IO.mapOptional("IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1065 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
1066 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
1067 IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
1068 IO.mapOptional("KeepEmptyLines", Style.KeepEmptyLines);
1069 IO.mapOptional("KeepFormFeed", Style.KeepFormFeed);
1070 IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
1071 IO.mapOptional("LineEnding", Style.LineEnding);
1072 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
1073 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
1074 IO.mapOptional("Macros", Style.Macros);
1075 IO.mapOptional("MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1076 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1077 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
1078 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
1079 IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1080 IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1081 IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
1083 IO.mapOptional("ObjCPropertyAttributeOrder",
1085 IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1086 IO.mapOptional("ObjCSpaceBeforeProtocolList",
1088 IO.mapOptional("PackConstructorInitializers",
1090 IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1091 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1093 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
1094 IO.mapOptional("PenaltyBreakFirstLessLess",
1096 IO.mapOptional("PenaltyBreakOpenParenthesis",
1098 IO.mapOptional("PenaltyBreakScopeResolution",
1100 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
1101 IO.mapOptional("PenaltyBreakTemplateDeclaration",
1103 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1104 IO.mapOptional("PenaltyIndentedWhitespace",
1106 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1108 IO.mapOptional("PointerAlignment", Style.PointerAlignment);
1109 IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
1110 IO.mapOptional("QualifierAlignment", Style.QualifierAlignment);
1111 // Default Order for Left/Right based Qualifier alignment.
1112 if (Style.QualifierAlignment == FormatStyle::QAS_Right)
1113 Style.QualifierOrder = {"type", "const", "volatile"};
1114 else if (Style.QualifierAlignment == FormatStyle::QAS_Left)
1115 Style.QualifierOrder = {"const", "volatile", "type"};
1116 else if (Style.QualifierAlignment == FormatStyle::QAS_Custom)
1117 IO.mapOptional("QualifierOrder", Style.QualifierOrder);
1118 IO.mapOptional("RawStringFormats", Style.RawStringFormats);
1119 IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
1120 IO.mapOptional("ReflowComments", Style.ReflowComments);
1121 IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
1122 IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1124 IO.mapOptional("RemoveParentheses", Style.RemoveParentheses);
1125 IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
1126 IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
1127 IO.mapOptional("RequiresExpressionIndentation",
1129 IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1130 IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
1131 IO.mapOptional("SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1132 IO.mapOptional("SortIncludes", Style.SortIncludes);
1133 IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
1134 IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
1135 IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1136 IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1137 IO.mapOptional("SpaceAfterTemplateKeyword",
1139 IO.mapOptional("SpaceAroundPointerQualifiers",
1141 IO.mapOptional("SpaceBeforeAssignmentOperators",
1143 IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1144 IO.mapOptional("SpaceBeforeCpp11BracedList",
1146 IO.mapOptional("SpaceBeforeCtorInitializerColon",
1148 IO.mapOptional("SpaceBeforeInheritanceColon",
1150 IO.mapOptional("SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1151 IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
1152 IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1153 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1155 IO.mapOptional("SpaceBeforeSquareBrackets",
1157 IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
1158 IO.mapOptional("SpacesBeforeTrailingComments",
1160 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
1161 IO.mapOptional("SpacesInContainerLiterals",
1163 IO.mapOptional("SpacesInLineCommentPrefix",
1165 IO.mapOptional("SpacesInParens", Style.SpacesInParens);
1166 IO.mapOptional("SpacesInParensOptions", Style.SpacesInParensOptions);
1167 IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1168 IO.mapOptional("Standard", Style.Standard);
1169 IO.mapOptional("StatementAttributeLikeMacros",
1171 IO.mapOptional("StatementMacros", Style.StatementMacros);
1172 IO.mapOptional("TableGenBreakingDAGArgOperators",
1174 IO.mapOptional("TableGenBreakInsideDAGArg",
1176 IO.mapOptional("TabWidth", Style.TabWidth);
1177 IO.mapOptional("TemplateNames", Style.TemplateNames);
1178 IO.mapOptional("TypeNames", Style.TypeNames);
1179 IO.mapOptional("TypenameMacros", Style.TypenameMacros);
1180 IO.mapOptional("UseTab", Style.UseTab);
1181 IO.mapOptional("VariableTemplates", Style.VariableTemplates);
1182 IO.mapOptional("VerilogBreakBetweenInstancePorts",
1184 IO.mapOptional("WhitespaceSensitiveMacros",
1186 IO.mapOptional("WrapNamespaceBodyWithEmptyLines",
1188
1189 // If AlwaysBreakAfterDefinitionReturnType was specified but
1190 // BreakAfterReturnType was not, initialize the latter from the former for
1191 // backwards compatibility.
1192 if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
1193 Style.BreakAfterReturnType == FormatStyle::RTBS_None) {
1195 FormatStyle::DRTBS_All) {
1196 Style.BreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1197 } else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1198 FormatStyle::DRTBS_TopLevel) {
1199 Style.BreakAfterReturnType = FormatStyle::RTBS_TopLevelDefinitions;
1200 }
1201 }
1202
1203 // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1204 // not, initialize the latter from the former for backwards compatibility.
1205 if (BreakBeforeInheritanceComma &&
1206 Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) {
1207 Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1208 }
1209
1210 // If BreakConstructorInitializersBeforeComma was specified but
1211 // BreakConstructorInitializers was not, initialize the latter from the
1212 // former for backwards compatibility.
1213 if (BreakConstructorInitializersBeforeComma &&
1214 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon) {
1215 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1216 }
1217
1218 if (!IsGoogleOrChromium) {
1219 if (Style.PackConstructorInitializers == FormatStyle::PCIS_BinPack &&
1220 OnCurrentLine) {
1221 Style.PackConstructorInitializers = OnNextLine
1222 ? FormatStyle::PCIS_NextLine
1223 : FormatStyle::PCIS_CurrentLine;
1224 }
1225 } else if (Style.PackConstructorInitializers ==
1226 FormatStyle::PCIS_NextLine) {
1227 if (!OnCurrentLine)
1228 Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1229 else if (!OnNextLine)
1230 Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine;
1231 }
1232
1233 if (Style.LineEnding == FormatStyle::LE_DeriveLF) {
1234 if (!DeriveLineEnding)
1235 Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1236 else if (UseCRLF)
1237 Style.LineEnding = FormatStyle::LE_DeriveCRLF;
1238 }
1239
1240 if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
1241 (SpacesInParentheses || SpaceInEmptyParentheses ||
1242 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1243 if (SpacesInParentheses) {
1244 // For backward compatibility.
1248 SpacesInCStyleCastParentheses;
1250 SpaceInEmptyParentheses;
1251 Style.SpacesInParensOptions.Other = true;
1252 } else {
1253 Style.SpacesInParensOptions = {};
1255 SpacesInConditionalStatement;
1257 SpacesInCStyleCastParentheses;
1259 SpaceInEmptyParentheses;
1260 }
1261 Style.SpacesInParens = FormatStyle::SIPO_Custom;
1262 }
1263 }
1264};
1265
1266// Allows to read vector<FormatStyle> while keeping default values.
1267// IO.getContext() should contain a pointer to the FormatStyle structure, that
1268// will be used to get default values for missing keys.
1269// If the first element has no Language specified, it will be treated as the
1270// default one for the following elements.
1271template <> struct DocumentListTraits<std::vector<FormatStyle>> {
1272 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1273 return Seq.size();
1274 }
1275 static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
1276 size_t Index) {
1277 if (Index >= Seq.size()) {
1278 assert(Index == Seq.size());
1279 FormatStyle Template;
1280 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1281 Template = Seq[0];
1282 } else {
1283 Template = *((const FormatStyle *)IO.getContext());
1284 Template.Language = FormatStyle::LK_None;
1285 }
1286 Seq.resize(Index + 1, Template);
1287 }
1288 return Seq[Index];
1289 }
1290};
1291} // namespace yaml
1292} // namespace llvm
1293
1294namespace clang {
1295namespace format {
1296
1297const std::error_category &getParseCategory() {
1298 static const ParseErrorCategory C{};
1299 return C;
1300}
1301std::error_code make_error_code(ParseError e) {
1302 return std::error_code(static_cast<int>(e), getParseCategory());
1303}
1304
1305inline llvm::Error make_string_error(const Twine &Message) {
1306 return llvm::make_error<llvm::StringError>(Message,
1307 llvm::inconvertibleErrorCode());
1308}
1309
1310const char *ParseErrorCategory::name() const noexcept {
1311 return "clang-format.parse_error";
1312}
1313
1314std::string ParseErrorCategory::message(int EV) const {
1315 switch (static_cast<ParseError>(EV)) {
1317 return "Success";
1318 case ParseError::Error:
1319 return "Invalid argument";
1321 return "Unsuitable";
1323 return "trailing comma insertion cannot be used with bin packing";
1325 return "Invalid qualifier specified in QualifierOrder";
1327 return "Duplicate qualifier specified in QualifierOrder";
1329 return "Missing type in QualifierOrder";
1331 return "Missing QualifierOrder";
1332 }
1333 llvm_unreachable("unexpected parse error");
1334}
1335
1338 return;
1339 Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
1340 /*AfterClass=*/false,
1341 /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1342 /*AfterEnum=*/false,
1343 /*AfterFunction=*/false,
1344 /*AfterNamespace=*/false,
1345 /*AfterObjCDeclaration=*/false,
1346 /*AfterStruct=*/false,
1347 /*AfterUnion=*/false,
1348 /*AfterExternBlock=*/false,
1349 /*BeforeCatch=*/false,
1350 /*BeforeElse=*/false,
1351 /*BeforeLambdaBody=*/false,
1352 /*BeforeWhile=*/false,
1353 /*IndentBraces=*/false,
1354 /*SplitEmptyFunction=*/true,
1355 /*SplitEmptyRecord=*/true,
1356 /*SplitEmptyNamespace=*/true};
1357 switch (Expanded.BreakBeforeBraces) {
1359 Expanded.BraceWrapping.AfterClass = true;
1360 Expanded.BraceWrapping.AfterFunction = true;
1361 Expanded.BraceWrapping.AfterNamespace = true;
1362 break;
1364 Expanded.BraceWrapping.AfterClass = true;
1365 Expanded.BraceWrapping.AfterEnum = true;
1366 Expanded.BraceWrapping.AfterFunction = true;
1367 Expanded.BraceWrapping.AfterStruct = true;
1368 Expanded.BraceWrapping.AfterUnion = true;
1369 Expanded.BraceWrapping.AfterExternBlock = true;
1370 Expanded.BraceWrapping.SplitEmptyFunction = true;
1371 Expanded.BraceWrapping.SplitEmptyRecord = false;
1372 break;
1374 Expanded.BraceWrapping.AfterFunction = true;
1375 Expanded.BraceWrapping.BeforeCatch = true;
1376 Expanded.BraceWrapping.BeforeElse = true;
1377 break;
1379 Expanded.BraceWrapping.AfterCaseLabel = true;
1380 Expanded.BraceWrapping.AfterClass = true;
1382 Expanded.BraceWrapping.AfterEnum = true;
1383 Expanded.BraceWrapping.AfterFunction = true;
1384 Expanded.BraceWrapping.AfterNamespace = true;
1385 Expanded.BraceWrapping.AfterObjCDeclaration = true;
1386 Expanded.BraceWrapping.AfterStruct = true;
1387 Expanded.BraceWrapping.AfterUnion = true;
1388 Expanded.BraceWrapping.AfterExternBlock = true;
1389 Expanded.BraceWrapping.BeforeCatch = true;
1390 Expanded.BraceWrapping.BeforeElse = true;
1391 Expanded.BraceWrapping.BeforeLambdaBody = true;
1392 break;
1394 Expanded.BraceWrapping.AfterCaseLabel = true;
1395 Expanded.BraceWrapping.AfterClass = true;
1397 Expanded.BraceWrapping.AfterEnum = true;
1398 Expanded.BraceWrapping.AfterFunction = true;
1399 Expanded.BraceWrapping.AfterNamespace = true;
1400 Expanded.BraceWrapping.AfterObjCDeclaration = true;
1401 Expanded.BraceWrapping.AfterStruct = true;
1402 Expanded.BraceWrapping.AfterExternBlock = true;
1403 Expanded.BraceWrapping.BeforeCatch = true;
1404 Expanded.BraceWrapping.BeforeElse = true;
1405 Expanded.BraceWrapping.BeforeLambdaBody = true;
1406 break;
1408 Expanded.BraceWrapping = {
1409 /*AfterCaseLabel=*/true,
1410 /*AfterClass=*/true,
1411 /*AfterControlStatement=*/FormatStyle::BWACS_Always,
1412 /*AfterEnum=*/true,
1413 /*AfterFunction=*/true,
1414 /*AfterNamespace=*/true,
1415 /*AfterObjCDeclaration=*/true,
1416 /*AfterStruct=*/true,
1417 /*AfterUnion=*/true,
1418 /*AfterExternBlock=*/true,
1419 /*BeforeCatch=*/true,
1420 /*BeforeElse=*/true,
1421 /*BeforeLambdaBody=*/false,
1422 /*BeforeWhile=*/true,
1423 /*IndentBraces=*/true,
1424 /*SplitEmptyFunction=*/true,
1425 /*SplitEmptyRecord=*/true,
1426 /*SplitEmptyNamespace=*/true};
1427 break;
1429 Expanded.BraceWrapping.AfterFunction = true;
1430 break;
1431 default:
1432 break;
1433 }
1434}
1435
1438 return;
1439 // Reset all flags
1440 Expanded.SpaceBeforeParensOptions = {};
1442
1443 switch (Expanded.SpaceBeforeParens) {
1448 break;
1451 break;
1454 break;
1455 default:
1456 break;
1457 }
1458}
1459
1462 return;
1463 assert(Expanded.SpacesInParens == FormatStyle::SIPO_Never);
1464 // Reset all flags
1465 Expanded.SpacesInParensOptions = {};
1466}
1467
1469 FormatStyle LLVMStyle;
1470 LLVMStyle.AccessModifierOffset = -2;
1473 LLVMStyle.AlignConsecutiveAssignments = {};
1475 LLVMStyle.AlignConsecutiveBitFields = {};
1476 LLVMStyle.AlignConsecutiveDeclarations = {};
1478 LLVMStyle.AlignConsecutiveMacros = {};
1485 LLVMStyle.AlignTrailingComments = {};
1488 LLVMStyle.AllowAllArgumentsOnNextLine = true;
1493 LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
1495 LLVMStyle.AllowShortEnumsOnASingleLine = true;
1499 LLVMStyle.AllowShortLoopsOnASingleLine = false;
1500 LLVMStyle.AllowShortNamespacesOnASingleLine = false;
1502 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
1503 LLVMStyle.AttributeMacros.push_back("__capability");
1504 LLVMStyle.BinPackArguments = true;
1507 LLVMStyle.BracedInitializerIndentWidth = std::nullopt;
1508 LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
1509 /*AfterClass=*/false,
1510 /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1511 /*AfterEnum=*/false,
1512 /*AfterFunction=*/false,
1513 /*AfterNamespace=*/false,
1514 /*AfterObjCDeclaration=*/false,
1515 /*AfterStruct=*/false,
1516 /*AfterUnion=*/false,
1517 /*AfterExternBlock=*/false,
1518 /*BeforeCatch=*/false,
1519 /*BeforeElse=*/false,
1520 /*BeforeLambdaBody=*/false,
1521 /*BeforeWhile=*/false,
1522 /*IndentBraces=*/false,
1523 /*SplitEmptyFunction=*/true,
1524 /*SplitEmptyRecord=*/true,
1525 /*SplitEmptyNamespace=*/true};
1526 LLVMStyle.BreakAdjacentStringLiterals = true;
1528 LLVMStyle.BreakAfterJavaFieldAnnotations = false;
1530 LLVMStyle.BreakArrays = true;
1535 LLVMStyle.BreakBeforeTernaryOperators = true;
1538 LLVMStyle.BreakFunctionDefinitionParameters = false;
1540 LLVMStyle.BreakStringLiterals = true;
1542 LLVMStyle.ColumnLimit = 80;
1543 LLVMStyle.CommentPragmas = "^ IWYU pragma:";
1544 LLVMStyle.CompactNamespaces = false;
1546 LLVMStyle.ContinuationIndentWidth = 4;
1547 LLVMStyle.Cpp11BracedListStyle = true;
1548 LLVMStyle.DerivePointerAlignment = false;
1549 LLVMStyle.DisableFormat = false;
1552 LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1553 LLVMStyle.FixNamespaceComments = true;
1554 LLVMStyle.ForEachMacros.push_back("foreach");
1555 LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1556 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1557 LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
1559 LLVMStyle.IncludeStyle.IncludeCategories = {
1560 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1561 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1562 {".*", 1, 0, false}};
1563 LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1565 LLVMStyle.IndentAccessModifiers = false;
1566 LLVMStyle.IndentCaseBlocks = false;
1567 LLVMStyle.IndentCaseLabels = false;
1569 LLVMStyle.IndentGotoLabels = true;
1571 LLVMStyle.IndentRequiresClause = true;
1572 LLVMStyle.IndentWidth = 2;
1573 LLVMStyle.IndentWrappedFunctionNames = false;
1574 LLVMStyle.InheritsParentConfig = false;
1575 LLVMStyle.InsertBraces = false;
1576 LLVMStyle.InsertNewlineAtEOF = false;
1578 LLVMStyle.IntegerLiteralSeparator = {
1579 /*Binary=*/0, /*BinaryMinDigits=*/0,
1580 /*Decimal=*/0, /*DecimalMinDigits=*/0,
1581 /*Hex=*/0, /*HexMinDigits=*/0};
1583 LLVMStyle.JavaScriptWrapImports = true;
1584 LLVMStyle.KeepEmptyLines = {
1585 /*AtEndOfFile=*/false,
1586 /*AtStartOfBlock=*/true,
1587 /*AtStartOfFile=*/true,
1588 };
1589 LLVMStyle.KeepFormFeed = false;
1591 LLVMStyle.Language = Language;
1593 LLVMStyle.MaxEmptyLinesToKeep = 1;
1596 LLVMStyle.ObjCBlockIndentWidth = 2;
1597 LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1598 LLVMStyle.ObjCSpaceAfterProperty = false;
1599 LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1602 LLVMStyle.PPIndentWidth = -1;
1606 LLVMStyle.RemoveBracesLLVM = false;
1607 LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false;
1609 LLVMStyle.RemoveSemicolon = false;
1613 LLVMStyle.ShortNamespaceLines = 1;
1614 LLVMStyle.SkipMacroDefinitionBody = false;
1618 LLVMStyle.SpaceAfterCStyleCast = false;
1619 LLVMStyle.SpaceAfterLogicalNot = false;
1620 LLVMStyle.SpaceAfterTemplateKeyword = true;
1622 LLVMStyle.SpaceBeforeAssignmentOperators = true;
1623 LLVMStyle.SpaceBeforeCaseColon = false;
1624 LLVMStyle.SpaceBeforeCpp11BracedList = false;
1625 LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1626 LLVMStyle.SpaceBeforeInheritanceColon = true;
1627 LLVMStyle.SpaceBeforeJsonColon = false;
1629 LLVMStyle.SpaceBeforeParensOptions = {};
1632 LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true;
1633 LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1634 LLVMStyle.SpaceBeforeSquareBrackets = false;
1635 LLVMStyle.SpaceInEmptyBlock = false;
1636 LLVMStyle.SpacesBeforeTrailingComments = 1;
1638 LLVMStyle.SpacesInContainerLiterals = true;
1639 LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
1641 LLVMStyle.SpacesInSquareBrackets = false;
1642 LLVMStyle.Standard = FormatStyle::LS_Latest;
1643 LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1644 LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1645 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1646 LLVMStyle.TableGenBreakingDAGArgOperators = {};
1648 LLVMStyle.TabWidth = 8;
1649 LLVMStyle.UseTab = FormatStyle::UT_Never;
1650 LLVMStyle.VerilogBreakBetweenInstancePorts = true;
1651 LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1652 LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1653 LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1654 LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1655 LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1657
1660 LLVMStyle.PenaltyBreakComment = 300;
1661 LLVMStyle.PenaltyBreakFirstLessLess = 120;
1662 LLVMStyle.PenaltyBreakOpenParenthesis = 0;
1663 LLVMStyle.PenaltyBreakScopeResolution = 500;
1664 LLVMStyle.PenaltyBreakString = 1000;
1666 LLVMStyle.PenaltyExcessCharacter = 1'000'000;
1667 LLVMStyle.PenaltyIndentedWhitespace = 0;
1668 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1669
1670 // Defaults that differ when not C++.
1671 switch (Language) {
1673 LLVMStyle.SpacesInContainerLiterals = false;
1674 break;
1676 LLVMStyle.ColumnLimit = 0;
1677 break;
1679 LLVMStyle.IndentCaseLabels = true;
1680 LLVMStyle.SpacesInContainerLiterals = false;
1681 break;
1682 default:
1683 break;
1684 }
1685
1686 return LLVMStyle;
1687}
1688
1692 GoogleStyle.Language = FormatStyle::LK_TextProto;
1693
1694 return GoogleStyle;
1695 }
1696
1697 FormatStyle GoogleStyle = getLLVMStyle(Language);
1698
1699 GoogleStyle.AccessModifierOffset = -1;
1703 GoogleStyle.AllowShortLoopsOnASingleLine = true;
1704 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1706 GoogleStyle.DerivePointerAlignment = true;
1708 GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1709 {"^<.*\\.h>", 1, 0, false},
1710 {"^<.*", 2, 0, false},
1711 {".*", 3, 0, false}};
1712 GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1713 GoogleStyle.IndentCaseLabels = true;
1714 GoogleStyle.KeepEmptyLines.AtStartOfBlock = false;
1716 GoogleStyle.ObjCSpaceAfterProperty = false;
1717 GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1720 GoogleStyle.RawStringFormats = {
1721 {
1723 /*Delimiters=*/
1724 {
1725 "cc",
1726 "CC",
1727 "cpp",
1728 "Cpp",
1729 "CPP",
1730 "c++",
1731 "C++",
1732 },
1733 /*EnclosingFunctionNames=*/
1734 {},
1735 /*CanonicalDelimiter=*/"",
1736 /*BasedOnStyle=*/"google",
1737 },
1738 {
1740 /*Delimiters=*/
1741 {
1742 "pb",
1743 "PB",
1744 "proto",
1745 "PROTO",
1746 },
1747 /*EnclosingFunctionNames=*/
1748 {
1749 "EqualsProto",
1750 "EquivToProto",
1751 "PARSE_PARTIAL_TEXT_PROTO",
1752 "PARSE_TEST_PROTO",
1753 "PARSE_TEXT_PROTO",
1754 "ParseTextOrDie",
1755 "ParseTextProtoOrDie",
1756 "ParseTestProto",
1757 "ParsePartialTestProto",
1758 },
1759 /*CanonicalDelimiter=*/"pb",
1760 /*BasedOnStyle=*/"google",
1761 },
1762 };
1763
1764 GoogleStyle.SpacesBeforeTrailingComments = 2;
1765 GoogleStyle.Standard = FormatStyle::LS_Auto;
1766
1768 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1769
1773 GoogleStyle.AlignTrailingComments = {};
1777 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1779 GoogleStyle.ColumnLimit = 100;
1780 GoogleStyle.SpaceAfterCStyleCast = true;
1781 GoogleStyle.SpacesBeforeTrailingComments = 1;
1782 } else if (Language == FormatStyle::LK_JavaScript) {
1786 // TODO: still under discussion whether to switch to SLS_All.
1788 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1789 GoogleStyle.BreakBeforeTernaryOperators = false;
1790 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1791 // commonly followed by overlong URLs.
1792 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1793 // TODO: enable once decided, in particular re disabling bin packing.
1794 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1795 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1797 GoogleStyle.JavaScriptWrapImports = false;
1798 GoogleStyle.MaxEmptyLinesToKeep = 3;
1800 GoogleStyle.SpacesInContainerLiterals = false;
1801 } else if (Language == FormatStyle::LK_Proto) {
1803 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1804 // This affects protocol buffer options specifications and text protos.
1805 // Text protos are currently mostly formatted inside C++ raw string literals
1806 // and often the current breaking behavior of string literals is not
1807 // beneficial there. Investigate turning this on once proper string reflow
1808 // has been implemented.
1809 GoogleStyle.BreakStringLiterals = false;
1810 GoogleStyle.Cpp11BracedListStyle = false;
1811 GoogleStyle.SpacesInContainerLiterals = false;
1812 } else if (Language == FormatStyle::LK_ObjC) {
1813 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1814 GoogleStyle.ColumnLimit = 100;
1815 // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1816 // relationship between ObjC standard library headers and other heades,
1817 // #imports, etc.)
1818 GoogleStyle.IncludeStyle.IncludeBlocks =
1820 } else if (Language == FormatStyle::LK_CSharp) {
1823 GoogleStyle.BreakStringLiterals = false;
1824 GoogleStyle.ColumnLimit = 100;
1826 }
1827
1828 return GoogleStyle;
1829}
1830
1832 FormatStyle ChromiumStyle = getGoogleStyle(Language);
1833
1834 // Disable include reordering across blocks in Chromium code.
1835 // - clang-format tries to detect that foo.h is the "main" header for
1836 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1837 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1838 // _private.cc, _impl.cc etc) in different permutations
1839 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1840 // better default for Chromium code.
1841 // - The default for .cc and .mm files is different (r357695) for Google style
1842 // for the same reason. The plan is to unify this again once the main
1843 // header detection works for Google's ObjC code, but this hasn't happened
1844 // yet. Since Chromium has some ObjC code, switching Chromium is blocked
1845 // on that.
1846 // - Finally, "If include reordering is harmful, put things in different
1847 // blocks to prevent it" has been a recommendation for a long time that
1848 // people are used to. We'll need a dev education push to change this to
1849 // "If include reordering is harmful, put things in a different block and
1850 // _prepend that with a comment_ to prevent it" before changing behavior.
1851 ChromiumStyle.IncludeStyle.IncludeBlocks =
1853
1857 ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
1858 ChromiumStyle.ContinuationIndentWidth = 8;
1859 ChromiumStyle.IndentWidth = 4;
1860 // See styleguide for import groups:
1861 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1862 ChromiumStyle.JavaImportGroups = {
1863 "android",
1864 "androidx",
1865 "com",
1866 "dalvik",
1867 "junit",
1868 "org",
1869 "com.google.android.apps.chrome",
1870 "org.chromium",
1871 "java",
1872 "javax",
1873 };
1875 } else if (Language == FormatStyle::LK_JavaScript) {
1877 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1878 } else {
1879 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1882 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1884 ChromiumStyle.DerivePointerAlignment = false;
1886 ChromiumStyle.ColumnLimit = 80;
1887 }
1888 return ChromiumStyle;
1889}
1890
1892 FormatStyle MozillaStyle = getLLVMStyle();
1893 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1897 MozillaStyle.BinPackArguments = false;
1904 MozillaStyle.ConstructorInitializerIndentWidth = 2;
1905 MozillaStyle.ContinuationIndentWidth = 2;
1906 MozillaStyle.Cpp11BracedListStyle = false;
1907 MozillaStyle.FixNamespaceComments = false;
1908 MozillaStyle.IndentCaseLabels = true;
1909 MozillaStyle.ObjCSpaceAfterProperty = true;
1910 MozillaStyle.ObjCSpaceBeforeProtocolList = false;
1911 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1913 MozillaStyle.SpaceAfterTemplateKeyword = false;
1914 return MozillaStyle;
1915}
1916
1918 FormatStyle Style = getLLVMStyle();
1919 Style.AccessModifierOffset = -4;
1922 Style.AlignTrailingComments = {};
1928 Style.ColumnLimit = 0;
1929 Style.Cpp11BracedListStyle = false;
1930 Style.FixNamespaceComments = false;
1931 Style.IndentWidth = 4;
1933 Style.ObjCBlockIndentWidth = 4;
1934 Style.ObjCSpaceAfterProperty = true;
1936 Style.SpaceBeforeCpp11BracedList = true;
1937 Style.SpaceInEmptyBlock = true;
1938 return Style;
1939}
1940
1942 FormatStyle Style = getLLVMStyle();
1947 Style.BreakBeforeTernaryOperators = true;
1948 Style.ColumnLimit = 79;
1949 Style.Cpp11BracedListStyle = false;
1950 Style.FixNamespaceComments = false;
1951 Style.KeepFormFeed = true;
1953 return Style;
1954}
1955
1958 Style.ColumnLimit = 120;
1959 Style.TabWidth = 4;
1960 Style.IndentWidth = 4;
1963 Style.BraceWrapping.AfterClass = true;
1965 Style.BraceWrapping.AfterEnum = true;
1966 Style.BraceWrapping.AfterFunction = true;
1967 Style.BraceWrapping.AfterNamespace = true;
1969 Style.BraceWrapping.AfterStruct = true;
1970 Style.BraceWrapping.AfterExternBlock = true;
1971 Style.BraceWrapping.BeforeCatch = true;
1972 Style.BraceWrapping.BeforeElse = true;
1973 Style.BraceWrapping.BeforeWhile = false;
1974 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
1975 Style.AllowShortEnumsOnASingleLine = false;
1979 Style.AllowShortLoopsOnASingleLine = false;
1982 return Style;
1983}
1984
1986 FormatStyle Style = getLLVMStyle();
1987 Style.InsertBraces = true;
1988 Style.InsertNewlineAtEOF = true;
1992 Style.RemoveBracesLLVM = true;
1995 Style.RemoveSemicolon = true;
1996 return Style;
1997}
1998
2000 FormatStyle NoStyle = getLLVMStyle();
2001 NoStyle.DisableFormat = true;
2004 return NoStyle;
2005}
2006
2008 FormatStyle *Style) {
2009 if (Name.equals_insensitive("llvm"))
2010 *Style = getLLVMStyle(Language);
2011 else if (Name.equals_insensitive("chromium"))
2012 *Style = getChromiumStyle(Language);
2013 else if (Name.equals_insensitive("mozilla"))
2014 *Style = getMozillaStyle();
2015 else if (Name.equals_insensitive("google"))
2016 *Style = getGoogleStyle(Language);
2017 else if (Name.equals_insensitive("webkit"))
2018 *Style = getWebKitStyle();
2019 else if (Name.equals_insensitive("gnu"))
2020 *Style = getGNUStyle();
2021 else if (Name.equals_insensitive("microsoft"))
2022 *Style = getMicrosoftStyle(Language);
2023 else if (Name.equals_insensitive("clang-format"))
2024 *Style = getClangFormatStyle();
2025 else if (Name.equals_insensitive("none"))
2026 *Style = getNoStyle();
2027 else if (Name.equals_insensitive("inheritparentconfig"))
2028 Style->InheritsParentConfig = true;
2029 else
2030 return false;
2031
2032 Style->Language = Language;
2033 return true;
2034}
2035
2037 // If its empty then it means don't do anything.
2038 if (Style->QualifierOrder.empty())
2040
2041 // Ensure the list contains only currently valid qualifiers.
2042 for (const auto &Qualifier : Style->QualifierOrder) {
2043 if (Qualifier == "type")
2044 continue;
2045 auto token =
2047 if (token == tok::identifier)
2049 }
2050
2051 // Ensure the list is unique (no duplicates).
2052 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2053 Style->QualifierOrder.end());
2054 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2055 LLVM_DEBUG(llvm::dbgs()
2056 << "Duplicate Qualifiers " << Style->QualifierOrder.size()
2057 << " vs " << UniqueQualifiers.size() << "\n");
2059 }
2060
2061 // Ensure the list has 'type' in it.
2062 if (!llvm::is_contained(Style->QualifierOrder, "type"))
2064
2065 return ParseError::Success;
2066}
2067
2068std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
2069 FormatStyle *Style, bool AllowUnknownOptions,
2070 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2071 void *DiagHandlerCtxt) {
2072 assert(Style);
2074 assert(Language != FormatStyle::LK_None);
2075 if (Config.getBuffer().trim().empty())
2077 Style->StyleSet.Clear();
2078 std::vector<FormatStyle> Styles;
2079 llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
2080 DiagHandlerCtxt);
2081 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
2082 // values for the fields, keys for which are missing from the configuration.
2083 // Mapping also uses the context to get the language to find the correct
2084 // base style.
2085 Input.setContext(Style);
2086 Input.setAllowUnknownKeys(AllowUnknownOptions);
2087 Input >> Styles;
2088 if (Input.error())
2089 return Input.error();
2090
2091 for (unsigned i = 0; i < Styles.size(); ++i) {
2092 // Ensures that only the first configuration can skip the Language option.
2093 if (Styles[i].Language == FormatStyle::LK_None && i != 0)
2095 // Ensure that each language is configured at most once.
2096 for (unsigned j = 0; j < i; ++j) {
2097 if (Styles[i].Language == Styles[j].Language) {
2098 LLVM_DEBUG(llvm::dbgs()
2099 << "Duplicate languages in the config file on positions "
2100 << j << " and " << i << "\n");
2102 }
2103 }
2104 }
2105 // Look for a suitable configuration starting from the end, so we can
2106 // find the configuration for the specific language first, and the default
2107 // configuration (which can only be at slot 0) after it.
2109 bool LanguageFound = false;
2110 for (const FormatStyle &Style : llvm::reverse(Styles)) {
2111 if (Style.Language != FormatStyle::LK_None)
2112 StyleSet.Add(Style);
2113 if (Style.Language == Language)
2114 LanguageFound = true;
2115 }
2116 if (!LanguageFound) {
2117 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
2119 FormatStyle DefaultStyle = Styles[0];
2120 DefaultStyle.Language = Language;
2121 StyleSet.Add(std::move(DefaultStyle));
2122 }
2123 *Style = *StyleSet.Get(Language);
2125 Style->BinPackArguments) {
2126 // See comment on FormatStyle::TSC_Wrapped.
2128 }
2132}
2133
2134std::string configurationAsText(const FormatStyle &Style) {
2135 std::string Text;
2136 llvm::raw_string_ostream Stream(Text);
2137 llvm::yaml::Output Output(Stream);
2138 // We use the same mapping method for input and output, so we need a non-const
2139 // reference here.
2140 FormatStyle NonConstStyle = Style;
2141 expandPresetsBraceWrapping(NonConstStyle);
2142 expandPresetsSpaceBeforeParens(NonConstStyle);
2143 expandPresetsSpacesInParens(NonConstStyle);
2144 Output << NonConstStyle;
2145
2146 return Stream.str();
2147}
2148
2149std::optional<FormatStyle>
2151 if (!Styles)
2152 return std::nullopt;
2153 auto It = Styles->find(Language);
2154 if (It == Styles->end())
2155 return std::nullopt;
2156 FormatStyle Style = It->second;
2157 Style.StyleSet = *this;
2158 return Style;
2159}
2160
2162 assert(Style.Language != LK_None &&
2163 "Cannot add a style for LK_None to a StyleSet");
2164 assert(
2165 !Style.StyleSet.Styles &&
2166 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2167 if (!Styles)
2168 Styles = std::make_shared<MapType>();
2169 (*Styles)[Style.Language] = std::move(Style);
2170}
2171
2172void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
2173
2174std::optional<FormatStyle>
2176 return StyleSet.Get(Language);
2177}
2178
2179namespace {
2180
2181class ParensRemover : public TokenAnalyzer {
2182public:
2183 ParensRemover(const Environment &Env, const FormatStyle &Style)
2184 : TokenAnalyzer(Env, Style) {}
2185
2186 std::pair<tooling::Replacements, unsigned>
2187 analyze(TokenAnnotator &Annotator,
2188 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2189 FormatTokenLexer &Tokens) override {
2190 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2191 tooling::Replacements Result;
2192 removeParens(AnnotatedLines, Result);
2193 return {Result, 0};
2194 }
2195
2196private:
2197 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2198 tooling::Replacements &Result) {
2199 const auto &SourceMgr = Env.getSourceManager();
2200 for (auto *Line : Lines) {
2201 if (!Line->Children.empty())
2202 removeParens(Line->Children, Result);
2203 if (!Line->Affected)
2204 continue;
2205 for (const auto *Token = Line->First; Token && !Token->Finalized;
2206 Token = Token->Next) {
2207 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2208 continue;
2209 auto *Next = Token->Next;
2210 assert(Next && Next->isNot(tok::eof));
2211 SourceLocation Start;
2212 if (Next->NewlinesBefore == 0) {
2213 Start = Token->Tok.getLocation();
2214 Next->WhitespaceRange = Token->WhitespaceRange;
2215 } else {
2216 Start = Token->WhitespaceRange.getBegin();
2217 }
2218 const auto &Range =
2219 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2220 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, " ")));
2221 }
2222 }
2223 }
2224};
2225
2226class BracesInserter : public TokenAnalyzer {
2227public:
2228 BracesInserter(const Environment &Env, const FormatStyle &Style)
2229 : TokenAnalyzer(Env, Style) {}
2230
2231 std::pair<tooling::Replacements, unsigned>
2232 analyze(TokenAnnotator &Annotator,
2233 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2234 FormatTokenLexer &Tokens) override {
2235 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2236 tooling::Replacements Result;
2237 insertBraces(AnnotatedLines, Result);
2238 return {Result, 0};
2239 }
2240
2241private:
2242 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2243 tooling::Replacements &Result) {
2244 const auto &SourceMgr = Env.getSourceManager();
2245 int OpeningBraceSurplus = 0;
2246 for (AnnotatedLine *Line : Lines) {
2247 if (!Line->Children.empty())
2248 insertBraces(Line->Children, Result);
2249 if (!Line->Affected && OpeningBraceSurplus == 0)
2250 continue;
2251 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2252 Token = Token->Next) {
2253 int BraceCount = Token->BraceCount;
2254 if (BraceCount == 0)
2255 continue;
2256 std::string Brace;
2257 if (BraceCount < 0) {
2258 assert(BraceCount == -1);
2259 if (!Line->Affected)
2260 break;
2261 Brace = Token->is(tok::comment) ? "\n{" : "{";
2262 ++OpeningBraceSurplus;
2263 } else {
2264 if (OpeningBraceSurplus == 0)
2265 break;
2266 if (OpeningBraceSurplus < BraceCount)
2267 BraceCount = OpeningBraceSurplus;
2268 Brace = '\n' + std::string(BraceCount, '}');
2269 OpeningBraceSurplus -= BraceCount;
2270 }
2271 Token->BraceCount = 0;
2272 const auto Start = Token->Tok.getEndLoc();
2273 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
2274 }
2275 }
2276 assert(OpeningBraceSurplus == 0);
2277 }
2278};
2279
2280class BracesRemover : public TokenAnalyzer {
2281public:
2282 BracesRemover(const Environment &Env, const FormatStyle &Style)
2283 : TokenAnalyzer(Env, Style) {}
2284
2285 std::pair<tooling::Replacements, unsigned>
2286 analyze(TokenAnnotator &Annotator,
2287 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2288 FormatTokenLexer &Tokens) override {
2289 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2290 tooling::Replacements Result;
2291 removeBraces(AnnotatedLines, Result);
2292 return {Result, 0};
2293 }
2294
2295private:
2296 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2297 tooling::Replacements &Result) {
2298 const auto &SourceMgr = Env.getSourceManager();
2299 const auto *End = Lines.end();
2300 for (const auto *I = Lines.begin(); I != End; ++I) {
2301 const auto &Line = *I;
2302 if (!Line->Children.empty())
2303 removeBraces(Line->Children, Result);
2304 if (!Line->Affected)
2305 continue;
2306 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2307 for (const auto *Token = Line->First; Token && !Token->Finalized;
2308 Token = Token->Next) {
2309 if (!Token->Optional)
2310 continue;
2311 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2312 continue;
2313 auto *Next = Token->Next;
2314 assert(Next || Token == Line->Last);
2315 if (!Next && NextLine)
2316 Next = NextLine->First;
2317 SourceLocation Start;
2318 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2319 Start = Token->Tok.getLocation();
2320 Next->WhitespaceRange = Token->WhitespaceRange;
2321 } else {
2322 Start = Token->WhitespaceRange.getBegin();
2323 }
2324 const auto &Range =
2325 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2326 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2327 }
2328 }
2329 }
2330};
2331
2332class SemiRemover : public TokenAnalyzer {
2333public:
2334 SemiRemover(const Environment &Env, const FormatStyle &Style)
2335 : TokenAnalyzer(Env, Style) {}
2336
2337 std::pair<tooling::Replacements, unsigned>
2338 analyze(TokenAnnotator &Annotator,
2339 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2340 FormatTokenLexer &Tokens) override {
2341 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2342 tooling::Replacements Result;
2343 removeSemi(Annotator, AnnotatedLines, Result);
2344 return {Result, 0};
2345 }
2346
2347private:
2348 void removeSemi(TokenAnnotator &Annotator,
2349 SmallVectorImpl<AnnotatedLine *> &Lines,
2350 tooling::Replacements &Result) {
2351 auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {
2352 const auto *Prev = Tok.Previous;
2353 if (!Prev || Prev->isNot(tok::r_brace))
2354 return false;
2355 const auto *LBrace = Prev->MatchingParen;
2356 return LBrace && LBrace->is(TT_FunctionLBrace);
2357 };
2358 const auto &SourceMgr = Env.getSourceManager();
2359 const auto *End = Lines.end();
2360 for (const auto *I = Lines.begin(); I != End; ++I) {
2361 const auto &Line = *I;
2362 if (!Line->Children.empty())
2363 removeSemi(Annotator, Line->Children, Result);
2364 if (!Line->Affected)
2365 continue;
2366 Annotator.calculateFormattingInformation(*Line);
2367 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2368 for (const auto *Token = Line->First; Token && !Token->Finalized;
2369 Token = Token->Next) {
2370 if (Token->isNot(tok::semi) ||
2371 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2372 continue;
2373 }
2374 auto *Next = Token->Next;
2375 assert(Next || Token == Line->Last);
2376 if (!Next && NextLine)
2377 Next = NextLine->First;
2378 SourceLocation Start;
2379 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2380 Start = Token->Tok.getLocation();
2381 Next->WhitespaceRange = Token->WhitespaceRange;
2382 } else {
2383 Start = Token->WhitespaceRange.getBegin();
2384 }
2385 const auto &Range =
2386 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2387 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2388 }
2389 }
2390 }
2391};
2392
2393class JavaScriptRequoter : public TokenAnalyzer {
2394public:
2395 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
2396 : TokenAnalyzer(Env, Style) {}
2397
2398 std::pair<tooling::Replacements, unsigned>
2399 analyze(TokenAnnotator &Annotator,
2400 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2401 FormatTokenLexer &Tokens) override {
2402 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2403 tooling::Replacements Result;
2404 requoteJSStringLiteral(AnnotatedLines, Result);
2405 return {Result, 0};
2406 }
2407
2408private:
2409 // Replaces double/single-quoted string literal as appropriate, re-escaping
2410 // the contents in the process.
2411 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2412 tooling::Replacements &Result) {
2413 for (AnnotatedLine *Line : Lines) {
2414 requoteJSStringLiteral(Line->Children, Result);
2415 if (!Line->Affected)
2416 continue;
2417 for (FormatToken *FormatTok = Line->First; FormatTok;
2418 FormatTok = FormatTok->Next) {
2419 StringRef Input = FormatTok->TokenText;
2420 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2421 // NB: testing for not starting with a double quote to avoid
2422 // breaking `template strings`.
2423 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
2424 !Input.starts_with("\"")) ||
2425 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
2426 !Input.starts_with("\'"))) {
2427 continue;
2428 }
2429
2430 // Change start and end quote.
2431 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
2432 SourceLocation Start = FormatTok->Tok.getLocation();
2433 auto Replace = [&](SourceLocation Start, unsigned Length,
2434 StringRef ReplacementText) {
2435 auto Err = Result.add(tooling::Replacement(
2436 Env.getSourceManager(), Start, Length, ReplacementText));
2437 // FIXME: handle error. For now, print error message and skip the
2438 // replacement for release version.
2439 if (Err) {
2440 llvm::errs() << toString(std::move(Err)) << "\n";
2441 assert(false);
2442 }
2443 };
2444 Replace(Start, 1, IsSingle ? "'" : "\"");
2445 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2446 IsSingle ? "'" : "\"");
2447
2448 // Escape internal quotes.
2449 bool Escaped = false;
2450 for (size_t i = 1; i < Input.size() - 1; i++) {
2451 switch (Input[i]) {
2452 case '\\':
2453 if (!Escaped && i + 1 < Input.size() &&
2454 ((IsSingle && Input[i + 1] == '"') ||
2455 (!IsSingle && Input[i + 1] == '\''))) {
2456 // Remove this \, it's escaping a " or ' that no longer needs
2457 // escaping
2458 Replace(Start.getLocWithOffset(i), 1, "");
2459 continue;
2460 }
2461 Escaped = !Escaped;
2462 break;
2463 case '\"':
2464 case '\'':
2465 if (!Escaped && IsSingle == (Input[i] == '\'')) {
2466 // Escape the quote.
2467 Replace(Start.getLocWithOffset(i), 0, "\\");
2468 }
2469 Escaped = false;
2470 break;
2471 default:
2472 Escaped = false;
2473 break;
2474 }
2475 }
2476 }
2477 }
2478 }
2479};
2480
2481class Formatter : public TokenAnalyzer {
2482public:
2483 Formatter(const Environment &Env, const FormatStyle &Style,
2484 FormattingAttemptStatus *Status)
2485 : TokenAnalyzer(Env, Style), Status(Status) {}
2486
2487 std::pair<tooling::Replacements, unsigned>
2488 analyze(TokenAnnotator &Annotator,
2489 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2490 FormatTokenLexer &Tokens) override {
2491 tooling::Replacements Result;
2492 deriveLocalStyle(AnnotatedLines);
2493 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2494 for (AnnotatedLine *Line : AnnotatedLines)
2495 Annotator.calculateFormattingInformation(*Line);
2496 Annotator.setCommentLineLevels(AnnotatedLines);
2497
2498 WhitespaceManager Whitespaces(
2499 Env.getSourceManager(), Style,
2500 Style.LineEnding > FormatStyle::LE_CRLF
2501 ? WhitespaceManager::inputUsesCRLF(
2502 Env.getSourceManager().getBufferData(Env.getFileID()),
2503 Style.LineEnding == FormatStyle::LE_DeriveCRLF)
2504 : Style.LineEnding == FormatStyle::LE_CRLF);
2505 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
2506 Env.getSourceManager(), Whitespaces, Encoding,
2507 BinPackInconclusiveFunctions);
2508 unsigned Penalty =
2509 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
2510 Tokens.getKeywords(), Env.getSourceManager(),
2511 Status)
2512 .format(AnnotatedLines, /*DryRun=*/false,
2513 /*AdditionalIndent=*/0,
2514 /*FixBadIndentation=*/false,
2515 /*FirstStartColumn=*/Env.getFirstStartColumn(),
2516 /*NextStartColumn=*/Env.getNextStartColumn(),
2517 /*LastStartColumn=*/Env.getLastStartColumn());
2518 for (const auto &R : Whitespaces.generateReplacements())
2519 if (Result.add(R))
2520 return std::make_pair(Result, 0);
2521 return std::make_pair(Result, Penalty);
2522 }
2523
2524private:
2525 bool
2526 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2527 for (const AnnotatedLine *Line : Lines) {
2528 if (hasCpp03IncompatibleFormat(Line->Children))
2529 return true;
2530 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2531 if (!Tok->hasWhitespaceBefore()) {
2532 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2533 return true;
2534 if (Tok->is(TT_TemplateCloser) &&
2535 Tok->Previous->is(TT_TemplateCloser)) {
2536 return true;
2537 }
2538 }
2539 }
2540 }
2541 return false;
2542 }
2543
2544 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2545 int AlignmentDiff = 0;
2546 for (const AnnotatedLine *Line : Lines) {
2547 AlignmentDiff += countVariableAlignments(Line->Children);
2548 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2549 if (Tok->isNot(TT_PointerOrReference))
2550 continue;
2551 // Don't treat space in `void foo() &&` as evidence.
2552 if (const auto *Prev = Tok->getPreviousNonComment()) {
2553 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2554 if (const auto *Func =
2555 Prev->MatchingParen->getPreviousNonComment()) {
2556 if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2557 TT_OverloadedOperator)) {
2558 continue;
2559 }
2560 }
2561 }
2562 }
2563 bool SpaceBefore = Tok->hasWhitespaceBefore();
2564 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2565 if (SpaceBefore && !SpaceAfter)
2566 ++AlignmentDiff;
2567 if (!SpaceBefore && SpaceAfter)
2568 --AlignmentDiff;
2569 }
2570 }
2571 return AlignmentDiff;
2572 }
2573
2574 void
2575 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2576 bool HasBinPackedFunction = false;
2577 bool HasOnePerLineFunction = false;
2578 for (AnnotatedLine *Line : AnnotatedLines) {
2579 if (!Line->First->Next)
2580 continue;
2581 FormatToken *Tok = Line->First->Next;
2582 while (Tok->Next) {
2583 if (Tok->is(PPK_BinPacked))
2584 HasBinPackedFunction = true;
2585 if (Tok->is(PPK_OnePerLine))
2586 HasOnePerLineFunction = true;
2587
2588 Tok = Tok->Next;
2589 }
2590 }
2591 if (Style.DerivePointerAlignment) {
2592 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2593 if (NetRightCount > 0)
2594 Style.PointerAlignment = FormatStyle::PAS_Right;
2595 else if (NetRightCount < 0)
2596 Style.PointerAlignment = FormatStyle::PAS_Left;
2597 Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
2598 }
2599 if (Style.Standard == FormatStyle::LS_Auto) {
2600 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2601 ? FormatStyle::LS_Latest
2602 : FormatStyle::LS_Cpp03;
2603 }
2604 BinPackInconclusiveFunctions =
2605 HasBinPackedFunction || !HasOnePerLineFunction;
2606 }
2607
2608 bool BinPackInconclusiveFunctions;
2609 FormattingAttemptStatus *Status;
2610};
2611
2612/// TrailingCommaInserter inserts trailing commas into container literals.
2613/// E.g.:
2614/// const x = [
2615/// 1,
2616/// ];
2617/// TrailingCommaInserter runs after formatting. To avoid causing a required
2618/// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2619/// ColumnLimit.
2620///
2621/// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2622/// is conceptually incompatible with bin packing.
2623class TrailingCommaInserter : public TokenAnalyzer {
2624public:
2625 TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2626 : TokenAnalyzer(Env, Style) {}
2627
2628 std::pair<tooling::Replacements, unsigned>
2629 analyze(TokenAnnotator &Annotator,
2630 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2631 FormatTokenLexer &Tokens) override {
2632 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2633 tooling::Replacements Result;
2634 insertTrailingCommas(AnnotatedLines, Result);
2635 return {Result, 0};
2636 }
2637
2638private:
2639 /// Inserts trailing commas in [] and {} initializers if they wrap over
2640 /// multiple lines.
2641 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2642 tooling::Replacements &Result) {
2643 for (AnnotatedLine *Line : Lines) {
2644 insertTrailingCommas(Line->Children, Result);
2645 if (!Line->Affected)
2646 continue;
2647 for (FormatToken *FormatTok = Line->First; FormatTok;
2648 FormatTok = FormatTok->Next) {
2649 if (FormatTok->NewlinesBefore == 0)
2650 continue;
2651 FormatToken *Matching = FormatTok->MatchingParen;
2652 if (!Matching || !FormatTok->getPreviousNonComment())
2653 continue;
2654 if (!(FormatTok->is(tok::r_square) &&
2655 Matching->is(TT_ArrayInitializerLSquare)) &&
2656 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2657 continue;
2658 }
2659 FormatToken *Prev = FormatTok->getPreviousNonComment();
2660 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2661 continue;
2662 // getEndLoc is not reliably set during re-lexing, use text length
2663 // instead.
2664 SourceLocation Start =
2665 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2666 // If inserting a comma would push the code over the column limit, skip
2667 // this location - it'd introduce an unstable formatting due to the
2668 // required reflow.
2669 unsigned ColumnNumber =
2670 Env.getSourceManager().getSpellingColumnNumber(Start);
2671 if (ColumnNumber > Style.ColumnLimit)
2672 continue;
2673 // Comma insertions cannot conflict with each other, and this pass has a
2674 // clean set of Replacements, so the operation below cannot fail.
2675 cantFail(Result.add(
2676 tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2677 }
2678 }
2679 }
2680};
2681
2682// This class clean up the erroneous/redundant code around the given ranges in
2683// file.
2684class Cleaner : public TokenAnalyzer {
2685public:
2686 Cleaner(const Environment &Env, const FormatStyle &Style)
2687 : TokenAnalyzer(Env, Style),
2688 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2689
2690 // FIXME: eliminate unused parameters.
2691 std::pair<tooling::Replacements, unsigned>
2692 analyze(TokenAnnotator &Annotator,
2693 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2694 FormatTokenLexer &Tokens) override {
2695 // FIXME: in the current implementation the granularity of affected range
2696 // is an annotated line. However, this is not sufficient. Furthermore,
2697 // redundant code introduced by replacements does not necessarily
2698 // intercept with ranges of replacements that result in the redundancy.
2699 // To determine if some redundant code is actually introduced by
2700 // replacements(e.g. deletions), we need to come up with a more
2701 // sophisticated way of computing affected ranges.
2702 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2703
2704 checkEmptyNamespace(AnnotatedLines);
2705
2706 for (auto *Line : AnnotatedLines)
2707 cleanupLine(Line);
2708
2709 return {generateFixes(), 0};
2710 }
2711
2712private:
2713 void cleanupLine(AnnotatedLine *Line) {
2714 for (auto *Child : Line->Children)
2715 cleanupLine(Child);
2716
2717 if (Line->Affected) {
2718 cleanupRight(Line->First, tok::comma, tok::comma);
2719 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2720 cleanupRight(Line->First, tok::l_paren, tok::comma);
2721 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2722 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2723 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2724 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2725 }
2726 }
2727
2728 bool containsOnlyComments(const AnnotatedLine &Line) {
2729 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2730 if (Tok->isNot(tok::comment))
2731 return false;
2732 return true;
2733 }
2734
2735 // Iterate through all lines and remove any empty (nested) namespaces.
2736 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2737 std::set<unsigned> DeletedLines;
2738 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2739 auto &Line = *AnnotatedLines[i];
2740 if (Line.startsWithNamespace())
2741 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2742 }
2743
2744 for (auto Line : DeletedLines) {
2745 FormatToken *Tok = AnnotatedLines[Line]->First;
2746 while (Tok) {
2747 deleteToken(Tok);
2748 Tok = Tok->Next;
2749 }
2750 }
2751 }
2752
2753 // The function checks if the namespace, which starts from \p CurrentLine, and
2754 // its nested namespaces are empty and delete them if they are empty. It also
2755 // sets \p NewLine to the last line checked.
2756 // Returns true if the current namespace is empty.
2757 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2758 unsigned CurrentLine, unsigned &NewLine,
2759 std::set<unsigned> &DeletedLines) {
2760 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2761 if (Style.BraceWrapping.AfterNamespace) {
2762 // If the left brace is in a new line, we should consume it first so that
2763 // it does not make the namespace non-empty.
2764 // FIXME: error handling if there is no left brace.
2765 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2766 NewLine = CurrentLine;
2767 return false;
2768 }
2769 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2770 return false;
2771 }
2772 while (++CurrentLine < End) {
2773 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2774 break;
2775
2776 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2777 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
2778 DeletedLines)) {
2779 return false;
2780 }
2781 CurrentLine = NewLine;
2782 continue;
2783 }
2784
2785 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2786 continue;
2787
2788 // If there is anything other than comments or nested namespaces in the
2789 // current namespace, the namespace cannot be empty.
2790 NewLine = CurrentLine;
2791 return false;
2792 }
2793
2794 NewLine = CurrentLine;
2795 if (CurrentLine >= End)
2796 return false;
2797
2798 // Check if the empty namespace is actually affected by changed ranges.
2799 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2800 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2801 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2802 return false;
2803 }
2804
2805 for (unsigned i = InitLine; i <= CurrentLine; ++i)
2806 DeletedLines.insert(i);
2807
2808 return true;
2809 }
2810
2811 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2812 // of the token in the pair if the left token has \p LK token kind and the
2813 // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2814 // is deleted on match; otherwise, the right token is deleted.
2815 template <typename LeftKind, typename RightKind>
2816 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2817 bool DeleteLeft) {
2818 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
2819 for (auto *Res = Tok.Next; Res; Res = Res->Next) {
2820 if (Res->isNot(tok::comment) &&
2821 DeletedTokens.find(Res) == DeletedTokens.end()) {
2822 return Res;
2823 }
2824 }
2825 return nullptr;
2826 };
2827 for (auto *Left = Start; Left;) {
2828 auto *Right = NextNotDeleted(*Left);
2829 if (!Right)
2830 break;
2831 if (Left->is(LK) && Right->is(RK)) {
2832 deleteToken(DeleteLeft ? Left : Right);
2833 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2834 deleteToken(Tok);
2835 // If the right token is deleted, we should keep the left token
2836 // unchanged and pair it with the new right token.
2837 if (!DeleteLeft)
2838 continue;
2839 }
2840 Left = Right;
2841 }
2842 }
2843
2844 template <typename LeftKind, typename RightKind>
2845 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2846 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
2847 }
2848
2849 template <typename LeftKind, typename RightKind>
2850 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2851 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
2852 }
2853
2854 // Delete the given token.
2855 inline void deleteToken(FormatToken *Tok) {
2856 if (Tok)
2857 DeletedTokens.insert(Tok);
2858 }
2859
2860 tooling::Replacements generateFixes() {
2861 tooling::Replacements Fixes;
2862 SmallVector<FormatToken *> Tokens;
2863 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2864 std::back_inserter(Tokens));
2865
2866 // Merge multiple continuous token deletions into one big deletion so that
2867 // the number of replacements can be reduced. This makes computing affected
2868 // ranges more efficient when we run reformat on the changed code.
2869 unsigned Idx = 0;
2870 while (Idx < Tokens.size()) {
2871 unsigned St = Idx, End = Idx;
2872 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2873 ++End;
2874 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2875 Tokens[End]->Tok.getEndLoc());
2876 auto Err =
2877 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2878 // FIXME: better error handling. for now just print error message and skip
2879 // for the release version.
2880 if (Err) {
2881 llvm::errs() << toString(std::move(Err)) << "\n";
2882 assert(false && "Fixes must not conflict!");
2883 }
2884 Idx = End + 1;
2885 }
2886
2887 return Fixes;
2888 }
2889
2890 // Class for less-than inequality comparason for the set `RedundantTokens`.
2891 // We store tokens in the order they appear in the translation unit so that
2892 // we do not need to sort them in `generateFixes()`.
2893 struct FormatTokenLess {
2894 FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2895
2896 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2897 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2898 RHS->Tok.getLocation());
2899 }
2900 const SourceManager &SM;
2901 };
2902
2903 // Tokens to be deleted.
2904 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2905};
2906
2907class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2908public:
2909 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2910 : TokenAnalyzer(Env, Style), IsObjC(false) {}
2911
2912 std::pair<tooling::Replacements, unsigned>
2913 analyze(TokenAnnotator &Annotator,
2914 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2915 FormatTokenLexer &Tokens) override {
2916 assert(Style.Language == FormatStyle::LK_Cpp);
2917 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2918 Tokens.getKeywords());
2919 tooling::Replacements Result;
2920 return {Result, 0};
2921 }
2922
2923 bool isObjC() { return IsObjC; }
2924
2925private:
2926 static bool
2927 guessIsObjC(const SourceManager &SourceManager,
2928 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2929 const AdditionalKeywords &Keywords) {
2930 // Keep this array sorted, since we are binary searching over it.
2931 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2932 "CGFloat",
2933 "CGPoint",
2934 "CGPointMake",
2935 "CGPointZero",
2936 "CGRect",
2937 "CGRectEdge",
2938 "CGRectInfinite",
2939 "CGRectMake",
2940 "CGRectNull",
2941 "CGRectZero",
2942 "CGSize",
2943 "CGSizeMake",
2944 "CGVector",
2945 "CGVectorMake",
2946 "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
2947 "FOUNDATION_EXTERN",
2948 "NSAffineTransform",
2949 "NSArray",
2950 "NSAttributedString",
2951 "NSBlockOperation",
2952 "NSBundle",
2953 "NSCache",
2954 "NSCalendar",
2955 "NSCharacterSet",
2956 "NSCountedSet",
2957 "NSData",
2958 "NSDataDetector",
2959 "NSDecimal",
2960 "NSDecimalNumber",
2961 "NSDictionary",
2962 "NSEdgeInsets",
2963 "NSError",
2964 "NSErrorDomain",
2965 "NSHashTable",
2966 "NSIndexPath",
2967 "NSIndexSet",
2968 "NSInteger",
2969 "NSInvocationOperation",
2970 "NSLocale",
2971 "NSMapTable",
2972 "NSMutableArray",
2973 "NSMutableAttributedString",
2974 "NSMutableCharacterSet",
2975 "NSMutableData",
2976 "NSMutableDictionary",
2977 "NSMutableIndexSet",
2978 "NSMutableOrderedSet",
2979 "NSMutableSet",
2980 "NSMutableString",
2981 "NSNumber",
2982 "NSNumberFormatter",
2983 "NSObject",
2984 "NSOperation",
2985 "NSOperationQueue",
2986 "NSOperationQueuePriority",
2987 "NSOrderedSet",
2988 "NSPoint",
2989 "NSPointerArray",
2990 "NSQualityOfService",
2991 "NSRange",
2992 "NSRect",
2993 "NSRegularExpression",
2994 "NSSet",
2995 "NSSize",
2996 "NSString",
2997 "NSTimeZone",
2998 "NSUInteger",
2999 "NSURL",
3000 "NSURLComponents",
3001 "NSURLQueryItem",
3002 "NSUUID",
3003 "NSValue",
3004 "NS_ASSUME_NONNULL_BEGIN",
3005 "UIImage",
3006 "UIView",
3007 };
3008
3009 for (auto *Line : AnnotatedLines) {
3010 if (Line->First && (Line->First->TokenText.starts_with("#") ||
3011 Line->First->TokenText == "__pragma" ||
3012 Line->First->TokenText == "_Pragma")) {
3013 continue;
3014 }
3015 for (const FormatToken *FormatTok = Line->First; FormatTok;
3016 FormatTok = FormatTok->Next) {
3017 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3018 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3019 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3020 tok::l_brace))) ||
3021 (FormatTok->Tok.isAnyIdentifier() &&
3022 std::binary_search(std::begin(FoundationIdentifiers),
3023 std::end(FoundationIdentifiers),
3024 FormatTok->TokenText)) ||
3025 FormatTok->is(TT_ObjCStringLiteral) ||
3026 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3027 Keywords.kw_NS_ERROR_ENUM,
3028 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3029 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3030 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3031 TT_ObjCProperty)) {
3032 LLVM_DEBUG(llvm::dbgs()
3033 << "Detected ObjC at location "
3034 << FormatTok->Tok.getLocation().printToString(
3035 SourceManager)
3036 << " token: " << FormatTok->TokenText << " token type: "
3037 << getTokenTypeName(FormatTok->getType()) << "\n");
3038 return true;
3039 }
3040 }
3041 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3042 return true;
3043 }
3044 return false;
3045 }
3046
3047 bool IsObjC;
3048};
3049
3050struct IncludeDirective {
3051 StringRef Filename;
3052 StringRef Text;
3053 unsigned Offset;
3056};
3057
3058struct JavaImportDirective {
3059 StringRef Identifier;
3060 StringRef Text;
3061 unsigned Offset;
3062 SmallVector<StringRef> AssociatedCommentLines;
3064};
3065
3066} // end anonymous namespace
3067
3068// Determines whether 'Ranges' intersects with ('Start', 'End').
3069static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
3070 unsigned End) {
3071 for (const auto &Range : Ranges) {
3072 if (Range.getOffset() < End &&
3073 Range.getOffset() + Range.getLength() > Start) {
3074 return true;
3075 }
3076 }
3077 return false;
3078}
3079
3080// Returns a pair (Index, OffsetToEOL) describing the position of the cursor
3081// before sorting/deduplicating. Index is the index of the include under the
3082// cursor in the original set of includes. If this include has duplicates, it is
3083// the index of the first of the duplicates as the others are going to be
3084// removed. OffsetToEOL describes the cursor's position relative to the end of
3085// its current line.
3086// If `Cursor` is not on any #include, `Index` will be UINT_MAX.
3087static std::pair<unsigned, unsigned>
3089 const ArrayRef<unsigned> &Indices, unsigned Cursor) {
3090 unsigned CursorIndex = UINT_MAX;
3091 unsigned OffsetToEOL = 0;
3092 for (int i = 0, e = Includes.size(); i != e; ++i) {
3093 unsigned Start = Includes[Indices[i]].Offset;
3094 unsigned End = Start + Includes[Indices[i]].Text.size();
3095 if (!(Cursor >= Start && Cursor < End))
3096 continue;
3097 CursorIndex = Indices[i];
3098 OffsetToEOL = End - Cursor;
3099 // Put the cursor on the only remaining #include among the duplicate
3100 // #includes.
3101 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
3102 CursorIndex = i;
3103 break;
3104 }
3105 return std::make_pair(CursorIndex, OffsetToEOL);
3106}
3107
3108// Replace all "\r\n" with "\n".
3109std::string replaceCRLF(const std::string &Code) {
3110 std::string NewCode;
3111 size_t Pos = 0, LastPos = 0;
3112
3113 do {
3114 Pos = Code.find("\r\n", LastPos);
3115 if (Pos == LastPos) {
3116 ++LastPos;
3117 continue;
3118 }
3119 if (Pos == std::string::npos) {
3120 NewCode += Code.substr(LastPos);
3121 break;
3122 }
3123 NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
3124 LastPos = Pos + 2;
3125 } while (Pos != std::string::npos);
3126
3127 return NewCode;
3128}
3129
3130// Sorts and deduplicate a block of includes given by 'Includes' alphabetically
3131// adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
3132// source order.
3133// #include directives with the same text will be deduplicated, and only the
3134// first #include in the duplicate #includes remains. If the `Cursor` is
3135// provided and put on a deleted #include, it will be moved to the remaining
3136// #include in the duplicate #includes.
3137static void sortCppIncludes(const FormatStyle &Style,
3138 const ArrayRef<IncludeDirective> &Includes,
3139 ArrayRef<tooling::Range> Ranges, StringRef FileName,
3140 StringRef Code, tooling::Replacements &Replaces,
3141 unsigned *Cursor) {
3143 const unsigned IncludesBeginOffset = Includes.front().Offset;
3144 const unsigned IncludesEndOffset =
3145 Includes.back().Offset + Includes.back().Text.size();
3146 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3147 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3148 return;
3150 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3151
3153 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3154 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3155 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3156 return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
3157 Includes[LHSI].Filename) <
3158 std::tie(Includes[RHSI].Priority, RHSFilenameLower,
3159 Includes[RHSI].Filename);
3160 });
3161 } else {
3162 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3163 return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
3164 std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
3165 });
3166 }
3167
3168 // The index of the include on which the cursor will be put after
3169 // sorting/deduplicating.
3170 unsigned CursorIndex;
3171 // The offset from cursor to the end of line.
3172 unsigned CursorToEOLOffset;
3173 if (Cursor) {
3174 std::tie(CursorIndex, CursorToEOLOffset) =
3175 FindCursorIndex(Includes, Indices, *Cursor);
3176 }
3177
3178 // Deduplicate #includes.
3179 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3180 [&](unsigned LHSI, unsigned RHSI) {
3181 return Includes[LHSI].Text.trim() ==
3182 Includes[RHSI].Text.trim();
3183 }),
3184 Indices.end());
3185
3186 int CurrentCategory = Includes.front().Category;
3187
3188 // If the #includes are out of order, we generate a single replacement fixing
3189 // the entire block. Otherwise, no replacement is generated.
3190 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
3191 // enough as additional newlines might be added or removed across #include
3192 // blocks. This we handle below by generating the updated #include blocks and
3193 // comparing it to the original.
3194 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3196 return;
3197 }
3198
3199 const auto OldCursor = Cursor ? *Cursor : 0;
3200 std::string result;
3201 for (unsigned Index : Indices) {
3202 if (!result.empty()) {
3203 result += "\n";
3204 if (Style.IncludeStyle.IncludeBlocks ==
3206 CurrentCategory != Includes[Index].Category) {
3207 result += "\n";
3208 }
3209 }
3210 result += Includes[Index].Text;
3211 if (Cursor && CursorIndex == Index)
3212 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3213 CurrentCategory = Includes[Index].Category;
3214 }
3215
3216 if (Cursor && *Cursor >= IncludesEndOffset)
3217 *Cursor += result.size() - IncludesBlockSize;
3218
3219 // If the #includes are out of order, we generate a single replacement fixing
3220 // the entire range of blocks. Otherwise, no replacement is generated.
3221 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3222 IncludesBeginOffset, IncludesBlockSize)))) {
3223 if (Cursor)
3224 *Cursor = OldCursor;
3225 return;
3226 }
3227
3228 auto Err = Replaces.add(tooling::Replacement(
3229 FileName, Includes.front().Offset, IncludesBlockSize, result));
3230 // FIXME: better error handling. For now, just skip the replacement for the
3231 // release version.
3232 if (Err) {
3233 llvm::errs() << toString(std::move(Err)) << "\n";
3234 assert(false);
3235 }
3236}
3237
3240 StringRef FileName,
3241 tooling::Replacements &Replaces,
3242 unsigned *Cursor) {
3243 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3244 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
3245 .Default(0);
3246 unsigned SearchFrom = 0;
3248 SmallVector<IncludeDirective, 16> IncludesInBlock;
3249
3250 // In compiled files, consider the first #include to be the main #include of
3251 // the file if it is not a system #include. This ensures that the header
3252 // doesn't have hidden dependencies
3253 // (http://llvm.org/docs/CodingStandards.html#include-style).
3254 //
3255 // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3256 // cases where the first #include is unlikely to be the main header.
3258 bool FirstIncludeBlock = true;
3259 bool MainIncludeFound = false;
3260 bool FormattingOff = false;
3261
3262 // '[' must be the first and '-' the last character inside [...].
3263 llvm::Regex RawStringRegex(
3264 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3265 SmallVector<StringRef, 2> RawStringMatches;
3266 std::string RawStringTermination = ")\"";
3267
3268 for (const auto Size = Code.size(); SearchFrom < Size;) {
3269 size_t Pos = SearchFrom;
3270 if (Code[SearchFrom] != '\n') {
3271 do { // Search for the first newline while skipping line splices.
3272 ++Pos;
3273 Pos = Code.find('\n', Pos);
3274 } while (Pos != StringRef::npos && Code[Pos - 1] == '\\');
3275 }
3276
3277 StringRef Line =
3278 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3279
3280 StringRef Trimmed = Line.trim();
3281
3282 // #includes inside raw string literals need to be ignored.
3283 // or we will sort the contents of the string.
3284 // Skip past until we think we are at the rawstring literal close.
3285 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3286 std::string CharSequence = RawStringMatches[1].str();
3287 RawStringTermination = ")" + CharSequence + "\"";
3288 FormattingOff = true;
3289 }
3290
3291 if (Trimmed.contains(RawStringTermination))
3292 FormattingOff = false;
3293
3294 bool IsBlockComment = false;
3295
3296 if (isClangFormatOff(Trimmed)) {
3297 FormattingOff = true;
3298 } else if (isClangFormatOn(Trimmed)) {
3299 FormattingOff = false;
3300 } else if (Trimmed.starts_with("/*")) {
3301 IsBlockComment = true;
3302 Pos = Code.find("*/", SearchFrom + 2);
3303 }
3304
3305 const bool EmptyLineSkipped =
3306 Trimmed.empty() &&
3310
3311 bool MergeWithNextLine = Trimmed.ends_with("\\");
3312 if (!FormattingOff && !MergeWithNextLine) {
3313 if (!IsBlockComment &&
3314 tooling::HeaderIncludes::IncludeRegex.match(Trimmed, &Matches)) {
3315 StringRef IncludeName = Matches[2];
3316 if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {
3317 // #include with a start of a block comment, but without the end.
3318 // Need to keep all the lines until the end of the comment together.
3319 // FIXME: This is somehow simplified check that probably does not work
3320 // correctly if there are multiple comments on a line.
3321 Pos = Code.find("*/", SearchFrom);
3322 Line = Code.substr(
3323 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3324 }
3325 int Category = Categories.getIncludePriority(
3326 IncludeName,
3327 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
3328 int Priority = Categories.getSortIncludePriority(
3329 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3330 if (Category == 0)
3331 MainIncludeFound = true;
3332 IncludesInBlock.push_back(
3333 {IncludeName, Line, Prev, Category, Priority});
3334 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3335 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
3336 Replaces, Cursor);
3337 IncludesInBlock.clear();
3338 if (Trimmed.starts_with("#pragma hdrstop")) // Precompiled headers.
3339 FirstIncludeBlock = true;
3340 else
3341 FirstIncludeBlock = false;
3342 }
3343 }
3344 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3345 break;
3346
3347 if (!MergeWithNextLine)
3348 Prev = Pos + 1;
3349 SearchFrom = Pos + 1;
3350 }
3351 if (!IncludesInBlock.empty()) {
3352 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
3353 Cursor);
3354 }
3355 return Replaces;
3356}
3357
3358// Returns group number to use as a first order sort on imports. Gives UINT_MAX
3359// if the import does not match any given groups.
3360static unsigned findJavaImportGroup(const FormatStyle &Style,
3361 StringRef ImportIdentifier) {
3362 unsigned LongestMatchIndex = UINT_MAX;
3363 unsigned LongestMatchLength = 0;
3364 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3365 const std::string &GroupPrefix = Style.JavaImportGroups[I];
3366 if (ImportIdentifier.starts_with(GroupPrefix) &&
3367 GroupPrefix.length() > LongestMatchLength) {
3368 LongestMatchIndex = I;
3369 LongestMatchLength = GroupPrefix.length();
3370 }
3371 }
3372 return LongestMatchIndex;
3373}
3374
3375// Sorts and deduplicates a block of includes given by 'Imports' based on
3376// JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3377// Import declarations with the same text will be deduplicated. Between each
3378// import group, a newline is inserted, and within each import group, a
3379// lexicographic sort based on ASCII value is performed.
3380static void sortJavaImports(const FormatStyle &Style,
3381 const ArrayRef<JavaImportDirective> &Imports,
3382 ArrayRef<tooling::Range> Ranges, StringRef FileName,
3383 StringRef Code, tooling::Replacements &Replaces) {
3384 unsigned ImportsBeginOffset = Imports.front().Offset;
3385 unsigned ImportsEndOffset =
3386 Imports.back().Offset + Imports.back().Text.size();
3387 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3388 if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3389 return;
3390
3392 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3394 JavaImportGroups.reserve(Imports.size());
3395 for (const JavaImportDirective &Import : Imports)
3396 JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
3397
3398 bool StaticImportAfterNormalImport =
3400 sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3401 // Negating IsStatic to push static imports above non-static imports.
3402 return std::make_tuple(!Imports[LHSI].IsStatic ^
3403 StaticImportAfterNormalImport,
3404 JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
3405 std::make_tuple(!Imports[RHSI].IsStatic ^
3406 StaticImportAfterNormalImport,
3407 JavaImportGroups[RHSI], Imports[RHSI].Identifier);
3408 });
3409
3410 // Deduplicate imports.
3411 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3412 [&](unsigned LHSI, unsigned RHSI) {
3413 return Imports[LHSI].Text == Imports[RHSI].Text;
3414 }),
3415 Indices.end());
3416
3417 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3418 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
3419
3420 std::string result;
3421 for (unsigned Index : Indices) {
3422 if (!result.empty()) {
3423 result += "\n";
3424 if (CurrentIsStatic != Imports[Index].IsStatic ||
3425 CurrentImportGroup != JavaImportGroups[Index]) {
3426 result += "\n";
3427 }
3428 }
3429 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
3430 result += CommentLine;
3431 result += "\n";
3432 }
3433 result += Imports[Index].Text;
3434 CurrentIsStatic = Imports[Index].IsStatic;
3435 CurrentImportGroup = JavaImportGroups[Index];
3436 }
3437
3438 // If the imports are out of order, we generate a single replacement fixing
3439 // the entire block. Otherwise, no replacement is generated.
3440 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3441 Imports.front().Offset, ImportsBlockSize)))) {
3442 return;
3443 }
3444
3445 auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
3446 ImportsBlockSize, result));
3447 // FIXME: better error handling. For now, just skip the replacement for the
3448 // release version.
3449 if (Err) {
3450 llvm::errs() << toString(std::move(Err)) << "\n";
3451 assert(false);
3452 }
3453}
3454
3455namespace {
3456
3457const char JavaImportRegexPattern[] =
3458 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3459
3460} // anonymous namespace
3461
3464 StringRef FileName,
3465 tooling::Replacements &Replaces) {
3466 unsigned Prev = 0;
3467 unsigned SearchFrom = 0;
3468 llvm::Regex ImportRegex(JavaImportRegexPattern);
3472
3473 bool FormattingOff = false;
3474
3475 for (;;) {
3476 auto Pos = Code.find('\n', SearchFrom);
3477 StringRef Line =
3478 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3479
3480 StringRef Trimmed = Line.trim();
3481 if (isClangFormatOff(Trimmed))
3482 FormattingOff = true;
3483 else if (isClangFormatOn(Trimmed))
3484 FormattingOff = false;
3485
3486 if (ImportRegex.match(Line, &Matches)) {
3487 if (FormattingOff) {
3488 // If at least one import line has formatting turned off, turn off
3489 // formatting entirely.
3490 return Replaces;
3491 }
3492 StringRef Static = Matches[1];
3493 StringRef Identifier = Matches[2];
3494 bool IsStatic = false;
3495 if (Static.contains("static"))
3496 IsStatic = true;
3497 ImportsInBlock.push_back(
3499 AssociatedCommentLines.clear();
3500 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3501 // Associating comments within the imports with the nearest import below
3502 AssociatedCommentLines.push_back(Line);
3503 }
3504 Prev = Pos + 1;
3505 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3506 break;
3507 SearchFrom = Pos + 1;
3508 }
3509 if (!ImportsInBlock.empty())
3510 sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
3511 return Replaces;
3512}
3513
3514bool isMpegTS(StringRef Code) {
3515 // MPEG transport streams use the ".ts" file extension. clang-format should
3516 // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3517 // 189 bytes - detect that and return.
3518 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3519}
3520
3521bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); }
3522
3525 StringRef FileName, unsigned *Cursor) {
3526 tooling::Replacements Replaces;
3527 if (!Style.SortIncludes || Style.DisableFormat)
3528 return Replaces;
3529 if (isLikelyXml(Code))
3530 return Replaces;
3532 isMpegTS(Code)) {
3533 return Replaces;
3534 }
3536 return sortJavaScriptImports(Style, Code, Ranges, FileName);
3538 return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
3539 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
3540 return Replaces;
3541}
3542
3543template <typename T>
3545processReplacements(T ProcessFunc, StringRef Code,
3546 const tooling::Replacements &Replaces,
3547 const FormatStyle &Style) {
3548 if (Replaces.empty())
3549 return tooling::Replacements();
3550
3551 auto NewCode = applyAllReplacements(Code, Replaces);
3552 if (!NewCode)
3553 return NewCode.takeError();
3554 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
3555 StringRef FileName = Replaces.begin()->getFilePath();
3556
3557 tooling::Replacements FormatReplaces =
3558 ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
3559
3560 return Replaces.merge(FormatReplaces);
3561}
3562
3564formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
3565 const FormatStyle &Style) {
3566 // We need to use lambda function here since there are two versions of
3567 // `sortIncludes`.
3568 auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
3569 std::vector<tooling::Range> Ranges,
3570 StringRef FileName) -> tooling::Replacements {
3571 return sortIncludes(Style, Code, Ranges, FileName);
3572 };
3573 auto SortedReplaces =
3574 processReplacements(SortIncludes, Code, Replaces, Style);
3575 if (!SortedReplaces)
3576 return SortedReplaces.takeError();
3577
3578 // We need to use lambda function here since there are two versions of
3579 // `reformat`.
3580 auto Reformat = [](const FormatStyle &Style, StringRef Code,
3581 std::vector<tooling::Range> Ranges,
3582 StringRef FileName) -> tooling::Replacements {
3583 return reformat(Style, Code, Ranges, FileName);
3584 };
3585 return processReplacements(Reformat, Code, *SortedReplaces, Style);
3586}
3587
3588namespace {
3589
3590inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
3591 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
3593 Replace.getReplacementText());
3594}
3595
3596inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3597 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
3598}
3599
3600// FIXME: insert empty lines between newly created blocks.
3601tooling::Replacements
3602fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3603 const FormatStyle &Style) {
3604 if (!Style.isCpp())
3605 return Replaces;
3606
3607 tooling::Replacements HeaderInsertions;
3608 std::set<StringRef> HeadersToDelete;
3609 tooling::Replacements Result;
3610 for (const auto &R : Replaces) {
3611 if (isHeaderInsertion(R)) {
3612 // Replacements from \p Replaces must be conflict-free already, so we can
3613 // simply consume the error.
3614 consumeError(HeaderInsertions.add(R));
3615 } else if (isHeaderDeletion(R)) {
3616 HeadersToDelete.insert(R.getReplacementText());
3617 } else if (R.getOffset() == UINT_MAX) {
3618 llvm::errs() << "Insertions other than header #include insertion are "
3619 "not supported! "
3620 << R.getReplacementText() << "\n";
3621 } else {
3622 consumeError(Result.add(R));
3623 }
3624 }
3625 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3626 return Replaces;
3627
3628 StringRef FileName = Replaces.begin()->getFilePath();
3629 tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
3630
3631 for (const auto &Header : HeadersToDelete) {
3632 tooling::Replacements Replaces =
3633 Includes.remove(Header.trim("\"<>"), Header.starts_with("<"));
3634 for (const auto &R : Replaces) {
3635 auto Err = Result.add(R);
3636 if (Err) {
3637 // Ignore the deletion on conflict.
3638 llvm::errs() << "Failed to add header deletion replacement for "
3639 << Header << ": " << toString(std::move(Err)) << "\n";
3640 }
3641 }
3642 }
3643
3644 SmallVector<StringRef, 4> Matches;
3645 for (const auto &R : HeaderInsertions) {
3646 auto IncludeDirective = R.getReplacementText();
3647 bool Matched =
3648 tooling::HeaderIncludes::IncludeRegex.match(IncludeDirective, &Matches);
3649 assert(Matched && "Header insertion replacement must have replacement text "
3650 "'#include ...'");
3651 (void)Matched;
3652 auto IncludeName = Matches[2];
3653 auto Replace =
3654 Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"),
3656 if (Replace) {
3657 auto Err = Result.add(*Replace);
3658 if (Err) {
3659 consumeError(std::move(Err));
3660 unsigned NewOffset =
3661 Result.getShiftedCodePosition(Replace->getOffset());
3662 auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3663 Replace->getReplacementText());
3664 Result = Result.merge(tooling::Replacements(Shifted));
3665 }
3666 }
3667 }
3668 return Result;
3669}
3670
3671} // anonymous namespace
3672
3673Expected<tooling::Replacements>
3674cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
3675 const FormatStyle &Style) {
3676 // We need to use lambda function here since there are two versions of
3677 // `cleanup`.
3678 auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3680 StringRef FileName) -> tooling::Replacements {
3681 return cleanup(Style, Code, Ranges, FileName);
3682 };
3683 // Make header insertion replacements insert new headers into correct blocks.
3684 tooling::Replacements NewReplaces =
3685 fixCppIncludeInsertions(Code, Replaces, Style);
3686 return cantFail(processReplacements(Cleanup, Code, NewReplaces, Style));
3687}
3688
3689namespace internal {
3690std::pair<tooling::Replacements, unsigned>
3691reformat(const FormatStyle &Style, StringRef Code,
3692 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
3693 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3694 FormattingAttemptStatus *Status) {
3695 FormatStyle Expanded = Style;
3699 Expanded.InsertBraces = false;
3700 Expanded.RemoveBracesLLVM = false;
3701 Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
3702 Expanded.RemoveSemicolon = false;
3703 switch (Expanded.RequiresClausePosition) {
3704 case FormatStyle::RCPS_SingleLine:
3705 case FormatStyle::RCPS_WithPreceding:
3706 Expanded.IndentRequiresClause = false;
3707 break;
3708 default:
3709 break;
3710 }
3711
3712 if (Expanded.DisableFormat)
3713 return {tooling::Replacements(), 0};
3714 if (isLikelyXml(Code))
3715 return {tooling::Replacements(), 0};
3716 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
3717 return {tooling::Replacements(), 0};
3718
3719 // JSON only needs the formatting passing.
3720 if (Style.isJson()) {
3721 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
3722 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3723 NextStartColumn, LastStartColumn);
3724 if (!Env)
3725 return {};
3726 // Perform the actual formatting pass.
3727 tooling::Replacements Replaces =
3728 Formatter(*Env, Style, Status).process().first;
3729 // add a replacement to remove the "x = " from the result.
3730 Replaces = Replaces.merge(
3732 // apply the reformatting changes and the removal of "x = ".
3733 if (applyAllReplacements(Code, Replaces))
3734 return {Replaces, 0};
3735 return {tooling::Replacements(), 0};
3736 }
3737
3738 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3739 NextStartColumn, LastStartColumn);
3740 if (!Env)
3741 return {};
3742
3743 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3744 const Environment &)>
3746
3748
3749 Passes.emplace_back([&](const Environment &Env) {
3750 return IntegerLiteralSeparatorFixer().process(Env, Expanded);
3751 });
3752
3753 if (Style.isCpp()) {
3754 if (Style.QualifierAlignment != FormatStyle::QAS_Leave)
3755 addQualifierAlignmentFixerPasses(Expanded, Passes);
3756
3757 if (Style.RemoveParentheses != FormatStyle::RPS_Leave) {
3758 FormatStyle S = Expanded;
3759 S.RemoveParentheses = Style.RemoveParentheses;
3760 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3761 return ParensRemover(Env, S).process(/*SkipAnnotation=*/true);
3762 });
3763 }
3764
3765 if (Style.InsertBraces) {
3766 FormatStyle S = Expanded;
3767 S.InsertBraces = true;
3768 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3769 return BracesInserter(Env, S).process(/*SkipAnnotation=*/true);
3770 });
3771 }
3772
3773 if (Style.RemoveBracesLLVM) {
3774 FormatStyle S = Expanded;
3775 S.RemoveBracesLLVM = true;
3776 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3777 return BracesRemover(Env, S).process(/*SkipAnnotation=*/true);
3778 });
3779 }
3780
3781 if (Style.RemoveSemicolon) {
3782 FormatStyle S = Expanded;
3783 S.RemoveSemicolon = true;
3784 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3785 return SemiRemover(Env, S).process();
3786 });
3787 }
3788
3789 if (Style.FixNamespaceComments) {
3790 Passes.emplace_back([&](const Environment &Env) {
3791 return NamespaceEndCommentsFixer(Env, Expanded).process();
3792 });
3793 }
3794
3795 if (Style.SortUsingDeclarations != FormatStyle::SUD_Never) {
3796 Passes.emplace_back([&](const Environment &Env) {
3797 return UsingDeclarationsSorter(Env, Expanded).process();
3798 });
3799 }
3800 }
3801
3802 if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave) {
3803 Passes.emplace_back([&](const Environment &Env) {
3804 return DefinitionBlockSeparator(Env, Expanded).process();
3805 });
3806 }
3807
3808 if (Style.Language == FormatStyle::LK_ObjC &&
3809 !Style.ObjCPropertyAttributeOrder.empty()) {
3810 Passes.emplace_back([&](const Environment &Env) {
3811 return ObjCPropertyAttributeOrderFixer(Env, Expanded).process();
3812 });
3813 }
3814
3815 if (Style.isJavaScript() &&
3816 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
3817 Passes.emplace_back([&](const Environment &Env) {
3818 return JavaScriptRequoter(Env, Expanded).process(/*SkipAnnotation=*/true);
3819 });
3820 }
3821
3822 Passes.emplace_back([&](const Environment &Env) {
3823 return Formatter(Env, Expanded, Status).process();
3824 });
3825
3826 if (Style.isJavaScript() &&
3827 Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped) {
3828 Passes.emplace_back([&](const Environment &Env) {
3829 return TrailingCommaInserter(Env, Expanded).process();
3830 });
3831 }
3832
3833 std::optional<std::string> CurrentCode;
3835 unsigned Penalty = 0;
3836 for (size_t I = 0, E = Passes.size(); I < E; ++I) {
3837 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3838 auto NewCode = applyAllReplacements(
3839 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3840 if (NewCode) {
3841 Fixes = Fixes.merge(PassFixes.first);
3842 Penalty += PassFixes.second;
3843 if (I + 1 < E) {
3844 CurrentCode = std::move(*NewCode);
3845 Env = Environment::make(
3846 *CurrentCode, FileName,
3847 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3848 FirstStartColumn, NextStartColumn, LastStartColumn);
3849 if (!Env)
3850 return {};
3851 }
3852 }
3853 }
3854
3855 if (Style.QualifierAlignment != FormatStyle::QAS_Leave) {
3856 // Don't make replacements that replace nothing. QualifierAlignment can
3857 // produce them if one of its early passes changes e.g. `const volatile` to
3858 // `volatile const` and then a later pass changes it back again.
3859 tooling::Replacements NonNoOpFixes;
3860 for (const tooling::Replacement &Fix : Fixes) {
3861 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3862 if (OriginalCode != Fix.getReplacementText()) {
3863 auto Err = NonNoOpFixes.add(Fix);
3864 if (Err) {
3865 llvm::errs() << "Error adding replacements : "
3866 << toString(std::move(Err)) << "\n";
3867 }
3868 }
3869 }
3870 Fixes = std::move(NonNoOpFixes);
3871 }
3872
3873 return {Fixes, Penalty};
3874}
3875} // namespace internal
3876
3877tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3879 StringRef FileName,
3880 FormattingAttemptStatus *Status) {
3881 return internal::reformat(Style, Code, Ranges,
3882 /*FirstStartColumn=*/0,
3883 /*NextStartColumn=*/0,
3884 /*LastStartColumn=*/0, FileName, Status)
3885 .first;
3886}
3887
3888tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
3890 StringRef FileName) {
3891 // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3892 if (Style.Language != FormatStyle::LK_Cpp)
3893 return tooling::Replacements();
3894 auto Env = Environment::make(Code, FileName, Ranges);
3895 if (!Env)
3896 return {};
3897 return Cleaner(*Env, Style).process().first;
3898}
3899
3900tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3902 StringRef FileName, bool *IncompleteFormat) {
3904 auto Result = reformat(Style, Code, Ranges, FileName, &Status);
3905 if (!Status.FormatComplete)
3906 *IncompleteFormat = true;
3907 return Result;
3908}
3909
3911 StringRef Code,
3913 StringRef FileName) {
3914 auto Env = Environment::make(Code, FileName, Ranges);
3915 if (!Env)
3916 return {};
3917 return NamespaceEndCommentsFixer(*Env, Style).process().first;
3918}
3919
3921 StringRef Code,
3923 StringRef FileName) {
3924 auto Env = Environment::make(Code, FileName, Ranges);
3925 if (!Env)
3926 return {};
3927 return UsingDeclarationsSorter(*Env, Style).process().first;
3928}
3929
3931 LangOptions LangOpts;
3932
3933 FormatStyle::LanguageStandard LexingStd = Style.Standard;
3934 if (LexingStd == FormatStyle::LS_Auto)
3935 LexingStd = FormatStyle::LS_Latest;
3936 if (LexingStd == FormatStyle::LS_Latest)
3937 LexingStd = FormatStyle::LS_Cpp20;
3938 LangOpts.CPlusPlus = 1;
3939 LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
3940 LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
3941 LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
3942 LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
3943 LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
3944 // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3945 // the sequence "<::" will be unconditionally treated as "[:".
3946 // Cf. Lexer::LexTokenInternal.
3947 LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
3948
3949 LangOpts.LineComment = 1;
3950 LangOpts.CXXOperatorNames = Style.isCpp();
3951 LangOpts.Bool = 1;
3952 LangOpts.ObjC = 1;
3953 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
3954 LangOpts.DeclSpecKeyword = 1; // To get __declspec.
3955 LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
3956 return LangOpts;
3957}
3958
3960 "Set coding style. <string> can be:\n"
3961 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3962 " Mozilla, WebKit.\n"
3963 "2. 'file' to load style configuration from a\n"
3964 " .clang-format file in one of the parent directories\n"
3965 " of the source file (for stdin, see --assume-filename).\n"
3966 " If no .clang-format file is found, falls back to\n"
3967 " --fallback-style.\n"
3968 " --style=file is the default.\n"
3969 "3. 'file:<format_file_path>' to explicitly specify\n"
3970 " the configuration file.\n"
3971 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3972 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3973
3975 if (FileName.ends_with(".java"))
3976 return FormatStyle::LK_Java;
3977 if (FileName.ends_with_insensitive(".js") ||
3978 FileName.ends_with_insensitive(".mjs") ||
3979 FileName.ends_with_insensitive(".cjs") ||
3980 FileName.ends_with_insensitive(".ts")) {
3981 return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
3982 }
3983 if (FileName.ends_with(".m") || FileName.ends_with(".mm"))
3984 return FormatStyle::LK_ObjC;
3985 if (FileName.ends_with_insensitive(".proto") ||
3986 FileName.ends_with_insensitive(".protodevel")) {
3987 return FormatStyle::LK_Proto;
3988 }
3989 // txtpb is the canonical extension, and textproto is the legacy canonical
3990 // extension
3991 // https://protobuf.dev/reference/protobuf/textformat-spec/#text-format-files
3992 if (FileName.ends_with_insensitive(".txtpb") ||
3993 FileName.ends_with_insensitive(".textpb") ||
3994 FileName.ends_with_insensitive(".pb.txt") ||
3995 FileName.ends_with_insensitive(".textproto") ||
3996 FileName.ends_with_insensitive(".asciipb")) {
3998 }
3999 if (FileName.ends_with_insensitive(".td"))
4001 if (FileName.ends_with_insensitive(".cs"))
4003 if (FileName.ends_with_insensitive(".json"))
4004 return FormatStyle::LK_Json;
4005 if (FileName.ends_with_insensitive(".sv") ||
4006 FileName.ends_with_insensitive(".svh") ||
4007 FileName.ends_with_insensitive(".v") ||
4008 FileName.ends_with_insensitive(".vh")) {
4010 }
4011 return FormatStyle::LK_Cpp;
4012}
4013
4015 const auto GuessedLanguage = getLanguageByFileName(FileName);
4016 if (GuessedLanguage == FormatStyle::LK_Cpp) {
4017 auto Extension = llvm::sys::path::extension(FileName);
4018 // If there's no file extension (or it's .h), we need to check the contents
4019 // of the code to see if it contains Objective-C.
4020 if (!Code.empty() && (Extension.empty() || Extension == ".h")) {
4021 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
4022 Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
4023 ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
4024 Guesser.process();
4025 if (Guesser.isObjC())
4026 return FormatStyle::LK_ObjC;
4027 }
4028 }
4029 return GuessedLanguage;
4030}
4031
4032// Update StyleOptionHelpDescription above when changing this.
4033const char *DefaultFormatStyle = "file";
4034
4035const char *DefaultFallbackStyle = "LLVM";
4036
4037llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4038loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
4039 FormatStyle *Style, bool AllowUnknownOptions,
4040 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4041 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4042 FS->getBufferForFile(ConfigFile.str());
4043 if (auto EC = Text.getError())
4044 return EC;
4045 if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions,
4046 DiagHandler)) {
4047 return EC;
4048 }
4049 return Text;
4050}
4051
4052Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
4053 StringRef FallbackStyleName, StringRef Code,
4054 llvm::vfs::FileSystem *FS,
4055 bool AllowUnknownOptions,
4056 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4058 FormatStyle FallbackStyle = getNoStyle();
4059 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
4060 return make_string_error("Invalid fallback style: " + FallbackStyleName);
4061
4062 SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1> ChildFormatTextToApply;
4063
4064 if (StyleName.starts_with("{")) {
4065 // Parse YAML/JSON style from the command line.
4066 StringRef Source = "<command-line>";
4067 if (std::error_code ec =
4068 parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
4069 AllowUnknownOptions, DiagHandler)) {
4070 return make_string_error("Error parsing -style: " + ec.message());
4071 }
4072
4073 if (!Style.InheritsParentConfig)
4074 return Style;
4075
4076 ChildFormatTextToApply.emplace_back(
4077 llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
4078 }
4079
4080 if (!FS)
4081 FS = llvm::vfs::getRealFileSystem().get();
4082 assert(FS);
4083
4084 // User provided clang-format file using -style=file:path/to/format/file.
4085 if (!Style.InheritsParentConfig &&
4086 StyleName.starts_with_insensitive("file:")) {
4087 auto ConfigFile = StyleName.substr(5);
4088 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4089 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4090 DiagHandler);
4091 if (auto EC = Text.getError()) {
4092 return make_string_error("Error reading " + ConfigFile + ": " +
4093 EC.message());
4094 }
4095
4096 LLVM_DEBUG(llvm::dbgs()
4097 << "Using configuration file " << ConfigFile << "\n");
4098
4099 if (!Style.InheritsParentConfig)
4100 return Style;
4101
4102 // Search for parent configs starting from the parent directory of
4103 // ConfigFile.
4104 FileName = ConfigFile;
4105 ChildFormatTextToApply.emplace_back(std::move(*Text));
4106 }
4107
4108 // If the style inherits the parent configuration it is a command line
4109 // configuration, which wants to inherit, so we have to skip the check of the
4110 // StyleName.
4111 if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
4112 if (!getPredefinedStyle(StyleName, Style.Language, &Style))
4113 return make_string_error("Invalid value for -style");
4114 if (!Style.InheritsParentConfig)
4115 return Style;
4116 }
4117
4119 if (std::error_code EC = FS->makeAbsolute(Path))
4120 return make_string_error(EC.message());
4121
4122 // Reset possible inheritance
4123 Style.InheritsParentConfig = false;
4124
4125 auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
4126
4127 auto applyChildFormatTexts = [&](FormatStyle *Style) {
4128 for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4129 auto EC =
4130 parseConfiguration(*MemBuf, Style, AllowUnknownOptions,
4131 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4132 // It was already correctly parsed.
4133 assert(!EC);
4134 static_cast<void>(EC);
4135 }
4136 };
4137
4138 // Look for .clang-format/_clang-format file in the file's parent directories.
4139 SmallVector<std::string, 2> FilesToLookFor;
4140 FilesToLookFor.push_back(".clang-format");
4141 FilesToLookFor.push_back("_clang-format");
4142
4143 SmallString<128> UnsuitableConfigFiles;
4144 for (StringRef Directory = Path; !Directory.empty();
4145 Directory = llvm::sys::path::parent_path(Directory)) {
4146 auto Status = FS->status(Directory);
4147 if (!Status ||
4148 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4149 continue;
4150 }
4151
4152 for (const auto &F : FilesToLookFor) {
4153 SmallString<128> ConfigFile(Directory);
4154
4155 llvm::sys::path::append(ConfigFile, F);
4156 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
4157
4158 Status = FS->status(ConfigFile);
4159 if (!Status ||
4160 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4161 continue;
4162 }
4163
4164 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4165 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4166 DiagHandler);
4167 if (auto EC = Text.getError()) {
4168 if (EC != ParseError::Unsuitable) {
4169 return make_string_error("Error reading " + ConfigFile + ": " +
4170 EC.message());
4171 }
4172 if (!UnsuitableConfigFiles.empty())
4173 UnsuitableConfigFiles.append(", ");
4174 UnsuitableConfigFiles.append(ConfigFile);
4175 continue;
4176 }
4177
4178 LLVM_DEBUG(llvm::dbgs()
4179 << "Using configuration file " << ConfigFile << "\n");
4180
4181 if (!Style.InheritsParentConfig) {
4182 if (!ChildFormatTextToApply.empty()) {
4183 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4184 applyChildFormatTexts(&Style);
4185 }
4186 return Style;
4187 }
4188
4189 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4190
4191 // Reset inheritance of style
4192 Style.InheritsParentConfig = false;
4193
4194 ChildFormatTextToApply.emplace_back(std::move(*Text));
4195
4196 // Breaking out of the inner loop, since we don't want to parse
4197 // .clang-format AND _clang-format, if both exist. Then we continue the
4198 // outer loop (parent directories) in search for the parent
4199 // configuration.
4200 break;
4201 }
4202 }
4203
4204 if (!UnsuitableConfigFiles.empty()) {
4205 return make_string_error("Configuration file(s) do(es) not support " +
4206 getLanguageName(Style.Language) + ": " +
4207 UnsuitableConfigFiles);
4208 }
4209
4210 if (!ChildFormatTextToApply.empty()) {
4211 LLVM_DEBUG(llvm::dbgs()
4212 << "Applying child configurations on fallback style\n");
4213 applyChildFormatTexts(&FallbackStyle);
4214 }
4215
4216 return FallbackStyle;
4217}
4218
4219static bool isClangFormatOnOff(StringRef Comment, bool On) {
4220 if (Comment == (On ? "/* clang-format on */" : "/* clang-format off */"))
4221 return true;
4222
4223 static const char ClangFormatOn[] = "// clang-format on";
4224 static const char ClangFormatOff[] = "// clang-format off";
4225 const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1;
4226
4227 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4228 (Comment.size() == Size || Comment[Size] == ':');
4229}
4230
4231bool isClangFormatOn(StringRef Comment) {
4232 return isClangFormatOnOff(Comment, /*On=*/true);
4233}
4234
4235bool isClangFormatOff(StringRef Comment) {
4236 return isClangFormatOnOff(Comment, /*On=*/false);
4237}
4238
4239} // namespace format
4240} // namespace clang
#define SM(sm)
Definition: Cuda.cpp:84
IndirectLocalPath & Path
Expr * E
This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or removes empty lines sepa...
StringRef Text
Definition: Format.cpp:3052
int Priority
Definition: Format.cpp:3055
SmallVector< StringRef > AssociatedCommentLines
Definition: Format.cpp:3062
int Category
Definition: Format.cpp:3054
bool IsStatic
Definition: Format.cpp:3063
StringRef Filename
Definition: Format.cpp:3051
StringRef Identifier
Definition: Format.cpp:3059
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:499
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:1310
std::string message(int EV) const override
Definition: Format.cpp:1314
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:3691
const char * StyleOptionHelpDescription
Description to be used for help text for a llvm::cl option for specifying format style.
Definition: Format.cpp:3959
void addQualifierAlignmentFixerPasses(const FormatStyle &Style, SmallVectorImpl< AnalyzerPass > &Passes)
static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded)
Definition: Format.cpp:1436
const char * DefaultFallbackStyle
The suggested predefined style to use as the fallback style in getStyle.
Definition: Format.cpp:4035
static bool affectsRange(ArrayRef< tooling::Range > Ranges, unsigned Start, unsigned End)
Definition: Format.cpp:3069
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:1917
bool isLikelyXml(StringRef Code)
Definition: Format.cpp:3521
static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName)
Definition: Format.cpp:3974
static unsigned findJavaImportGroup(const FormatStyle &Style, StringRef ImportIdentifier)
Definition: Format.cpp:3360
std::string replaceCRLF(const std::string &Code)
Definition: Format.cpp:3109
std::error_code make_error_code(ParseError e)
Definition: Format.cpp:1301
FormatStyle getClangFormatStyle()
Definition: Format.cpp:1985
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:1468
FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with one of Google's style guides: http://google-styleguide....
Definition: Format.cpp:1689
std::string configurationAsText(const FormatStyle &Style)
Gets configuration in a YAML string.
Definition: Format.cpp:2134
FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with Microsoft style guide: https://docs.microsoft....
Definition: Format.cpp:1956
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:2068
const std::error_category & getParseCategory()
Definition: Format.cpp:1297
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:3910
FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code)
Definition: Format.cpp:4014
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:4052
bool isMpegTS(StringRef Code)
Definition: Format.cpp:3514
static std::pair< unsigned, unsigned > FindCursorIndex(const ArrayRef< IncludeDirective > &Includes, const ArrayRef< unsigned > &Indices, unsigned Cursor)
Definition: Format.cpp:3088
const char * DefaultFormatStyle
The suggested format style to use by default.
Definition: Format.cpp:4033
FormatStyle getGNUStyle()
Returns a format style complying with GNU Coding Standards: http://www.gnu.org/prep/standards/standar...
Definition: Format.cpp:1941
bool isClangFormatOff(StringRef Comment)
Definition: Format.cpp:4235
LangOptions getFormattingLangOpts(const FormatStyle &Style=getLLVMStyle())
Returns the LangOpts that the formatter expects you to set.
Definition: Format.cpp:3930
static bool isClangFormatOnOff(StringRef Comment, bool On)
Definition: Format.cpp:4219
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:3380
FormatStyle getMozillaStyle()
Returns a format style complying with Mozilla's style guide: https://firefox-source-docs....
Definition: Format.cpp:1891
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
Gets a predefined style for the specified language by name.
Definition: Format.cpp:2007
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:3674
static void expandPresetsBraceWrapping(FormatStyle &Expanded)
Definition: Format.cpp:1336
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:3137
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:3877
bool isClangFormatOn(StringRef Comment)
Definition: Format.cpp:4231
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:4038
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:3920
llvm::Error make_string_error(const Twine &Message)
Definition: Format.cpp:1305
ParseError validateQualifierOrder(FormatStyle *Style)
Definition: Format.cpp:2036
FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language)
Returns a format style complying with Chromium's style guide: http://www.chromium....
Definition: Format.cpp:1831
static void expandPresetsSpacesInParens(FormatStyle &Expanded)
Definition: Format.cpp:1460
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:3888
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:3564
FormatStyle getNoStyle()
Returns style indicating formatting should be not applied at all.
Definition: Format.cpp:1999
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:3523
static Expected< tooling::Replacements > processReplacements(T ProcessFunc, StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)
Definition: Format.cpp:3545
StringRef getLanguageName(FormatStyle::LanguageKind Language)
Definition: Format.h:5646
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:2150
int8_t DecimalMinDigits
Format separators in decimal literals with a minimum number of digits.
Definition: Format.h:3063
int8_t Decimal
Format separators in decimal literals.
Definition: Format.h:3055
bool AtEndOfFile
Keep empty lines at end of file.
Definition: Format.h:3183
bool AtStartOfBlock
Keep empty lines at start of a block.
Definition: Format.h:3192
bool AfterControlStatements
If true, put space between control statement keywords (for/if/while...) and opening parentheses.
Definition: Format.h:4539
bool AfterForeachMacros
If true, put space between foreach macros and opening parentheses.
Definition: Format.h:4546
bool BeforeNonEmptyParentheses
If true, put a space before opening parentheses only if the parentheses are not empty.
Definition: Format.h:4610
bool AfterIfMacros
If true, put space between if macros and opening parentheses.
Definition: Format.h:4567
bool AfterPlacementOperator
If true, put a space between operator new/delete and opening parenthesis.
Definition: Format.h:4583
bool ExceptDoubleParentheses
Override any of the following options to prevent addition of space when both opening and closing pare...
Definition: Format.h:4842
bool Other
Put a space in parentheses not covered by preceding options.
Definition: Format.h:4874
bool InEmptyParentheses
Insert a space in empty parentheses, i.e.
Definition: Format.h:4868
bool InCStyleCasts
Put a space in C style casts.
Definition: Format.h:4857
bool InConditionalStatements
Put a space in parentheses only inside conditional statements (for/if/while/switch....
Definition: Format.h:4850
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:5089
bool SpaceBeforeInheritanceColon
If false, spaces will be removed before inheritance colon.
Definition: Format.h:4450
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:4959
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:3261
@ LK_CSharp
Should be used for C#.
Definition: Format.h:3267
@ LK_None
Do not use.
Definition: Format.h:3263
@ LK_Java
Should be used for Java.
Definition: Format.h:3269
@ LK_Cpp
Should be used for C, C++.
Definition: Format.h:3265
@ LK_JavaScript
Should be used for JavaScript.
Definition: Format.h:3271
@ LK_ObjC
Should be used for Objective-C, Objective-C++.
Definition: Format.h:3275
@ LK_Verilog
Should be used for Verilog and SystemVerilog.
Definition: Format.h:3287
@ LK_TableGen
Should be used for TableGen code.
Definition: Format.h:3280
@ LK_Proto
Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).
Definition: Format.h:3278
@ LK_Json
Should be used for JSON.
Definition: Format.h:3273
@ LK_TextProto
Should be used for Protocol Buffer messages in text format (https://developers.google....
Definition: Format.h:3283
bool Cpp11BracedListStyle
If true, format braced lists as best suited for C++11 braced lists.
Definition: Format.h:2530
SortIncludesOptions SortIncludes
Controls if and how clang-format will sort #includes.
Definition: Format.h:4277
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:2931
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:4163
bool IndentRequiresClause
Indent the requires clause in a template.
Definition: Format.h:2917
SpacesInAnglesStyle SpacesInAngles
The SpacesInAnglesStyle to use for template argument lists.
Definition: Format.h:4725
bool KeepFormFeed
This option is deprecated.
Definition: Format.h:3220
bool IndentCaseLabels
Indent case labels one level from the switch statement.
Definition: Format.h:2802
std::vector< RawStringFormat > RawStringFormats
Defines hints for detecting supported languages code blocks in raw strings.
Definition: Format.h:3833
std::vector< std::string > VariableTemplates
A vector of non-keyword identifiers that should be interpreted as variable template names.
Definition: Format.h:5114
@ SJSIO_Before
Static imports are placed before non-static imports.
Definition: Format.h:4287
@ SJSIO_After
Static imports are placed after non-static imports.
Definition: Format.h:4294
PPDirectiveIndentStyle IndentPPDirectives
The preprocessor directive indenting style to use.
Definition: Format.h:2894
bool RemoveSemicolon
Remove semicolons after the closing braces of functions and constructors/destructors.
Definition: Format.h:4028
std::vector< std::string > Macros
A list of macros of the form <definition>=<expansion> .
Definition: Format.h:3390
bool SpaceBeforeJsonColon
If true, a space will be added before a JSON colon.
Definition: Format.h:4461
@ TCS_None
Do not insert trailing commas.
Definition: Format.h:2986
unsigned PenaltyBreakBeforeFirstCallParameter
The penalty for breaking a function call after call(.
Definition: Format.h:3626
bool SpaceBeforeCtorInitializerColon
If false, spaces will be removed before constructor initializer colon.
Definition: Format.h:4442
@ 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:4254
@ SI_CaseSensitive
Includes are sorted in an ASCIIbetical or case sensitive fashion.
Definition: Format.h:4263
@ SI_CaseInsensitive
Includes are sorted in an alphabetical or case insensitive fashion.
Definition: Format.h:4272
@ 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:3891
@ ELBAMS_LogicalBlock
Add empty line only when access modifier starts a new logical block.
Definition: Format.h:2636
unsigned SpacesBeforeTrailingComments
If true, spaces may be inserted into ().
Definition: Format.h:4702
@ 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:2840
bool IndentCaseBlocks
Indent case label blocks one level from the case label.
Definition: Format.h:2783
bool InsertBraces
Insert braces after control statements (if, else, for, do, and while) in C++ unless the control state...
Definition: Format.h:2977
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:2543
@ 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:3310
bool SpacesInSquareBrackets
If true, spaces will be inserted after [ and before ].
Definition: Format.h:4924
bool IndentWrappedFunctionNames
Indent if a function definition or declaration is wrapped after the type.
Definition: Format.h:2945
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:5178
bool FixNamespaceComments
If true, clang-format adds missing namespace end comments for namespaces and fixes invalid existing o...
Definition: Format.h:2692
bool ObjCSpaceBeforeProtocolList
Add a space in front of an Objective-C protocol list, i.e.
Definition: Format.h:3556
@ 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:4010
std::string MacroBlockBegin
A regular expression matching macros that start a block.
Definition: Format.h:3346
bool SpaceInEmptyBlock
If true, spaces will be inserted into {}.
Definition: Format.h:4676
LanguageKind Language
Language, this format style is targeted at.
Definition: Format.h:3301
@ SIPO_Custom
Configure each individual space in parentheses in SpacesInParensOptions.
Definition: Format.h:4806
@ SIPO_Never
Never put a space in parentheses.
Definition: Format.h:4803
bool RemoveBracesLLVM
Remove optional braces of control statements (if, else, for, and while) in C++ according to the LLVM ...
Definition: Format.h:3951
@ 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:5128
unsigned TabWidth
The number of columns used for tab stops.
Definition: Format.h:5044
@ PPDIS_None
Does not indent any directives.
Definition: Format.h:2871
@ LBI_Signature
Align lambda body relative to the lambda signature.
Definition: Format.h:3231
std::vector< std::string > JavaImportGroups
A vector of prefixes ordered by the desired groups for Java imports.
Definition: Format.h:3124
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:3634
std::vector< std::string > StatementAttributeLikeMacros
Macros which are ignored in front of a statement, as if they were an attribute.
Definition: Format.h:4976
unsigned ObjCBlockIndentWidth
The number of characters to use for indentation of ObjC blocks.
Definition: Format.h:3499
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:3773
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:2175
std::vector< std::string > IfMacros
A vector of macros that should be interpreted as conditionals instead of as function calls.
Definition: Format.h:2733
NamespaceIndentationKind NamespaceIndentation
The indentation used for namespaces.
Definition: Format.h:3442
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:3546
bool ExperimentalAutoDetectBinPacking
If true, clang-format detects whether function calls and definitions are formatted with one parameter...
Definition: Format.h:2676
bool ObjCBreakBeforeNestedBlockParam
Break parameters list into lines when there is nested block parameters in a function call.
Definition: Format.h:3523
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:3638
@ 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:2068
SpacesInParensStyle SpacesInParens
If true, spaces will be inserted after ( and before ).
Definition: Format.h:4820
SpacesInParensCustom SpacesInParensOptions
Control of individual spaces in parentheses.
Definition: Format.h:4913
std::vector< std::string > ForEachMacros
A vector of macros that should be interpreted as foreach loops instead of as function calls.
Definition: Format.h:2710
ReferenceAlignmentStyle ReferenceAlignment
Reference alignment style (overrides PointerAlignment for references).
Definition: Format.h:3859
BreakBinaryOperationsStyle BreakBinaryOperations
The break constructor initializers 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:3011
unsigned PenaltyBreakTemplateDeclaration
The penalty for breaking after template declaration.
Definition: Format.h:3650
SpaceBeforeParensCustom SpaceBeforeParensOptions
Control of individual space before parentheses.
Definition: Format.h:4648
BreakConstructorInitializersStyle BreakConstructorInitializers
The break constructor initializers style to use.
Definition: Format.h:2333
bool RemoveEmptyLinesInUnwrappedLines
Remove empty lines within unwrapped lines.
Definition: Format.h:3974
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:4361
@ SBPO_Custom
Configure each individual space before parentheses in SpaceBeforeParensOptions.
Definition: Format.h:4517
@ SBPO_NonEmptyParentheses
Put a space before opening parentheses only if the parentheses are not empty.
Definition: Format.h:4502
@ SBPO_ControlStatementsExceptControlMacros
Same as SBPO_ControlStatements except this option doesn't apply to ForEach and If macros.
Definition: Format.h:4491
@ SBPO_ControlStatements
Put a space before opening parentheses only after control statement keywords (for/if/while....
Definition: Format.h:4478
@ SBPO_Always
Always put a space before opening parentheses, except when it's prohibited by the syntax rules (in fu...
Definition: Format.h:4514
@ PCIS_BinPack
Bin-pack constructor initializers.
Definition: Format.h:3573
@ PCIS_NextLine
Same as PCIS_CurrentLine except that if all constructor initializers do not fit on the current line,...
Definition: Format.h:3598
std::vector< std::string > TypeNames
A vector of non-keyword identifiers that should be interpreted as type names.
Definition: Format.h:5063
bool ObjCSpaceAfterProperty
Add a space after @property in Objective-C, i.e.
Definition: Format.h:3551
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:3654
std::vector< std::string > WhitespaceSensitiveMacros
A vector of macros which are whitespace-sensitive and should not be touched.
Definition: Format.h:5145
std::vector< std::string > TemplateNames
A vector of non-keyword identifiers that should be interpreted as template names.
Definition: Format.h:5053
@ DAS_DontBreak
Never break inside DAGArg.
Definition: Format.h:5020
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:4054
LanguageStandard
Supported language standards for parsing and formatting C++ constructs.
Definition: Format.h:4934
@ LS_Cpp17
Parse and format as C++17.
Definition: Format.h:4943
@ LS_Latest
Parse and format using the latest supported language version.
Definition: Format.h:4948
@ LS_Cpp11
Parse and format as C++11.
Definition: Format.h:4939
@ LS_Auto
Automatic detection based on the input.
Definition: Format.h:4950
@ LS_Cpp14
Parse and format as C++14.
Definition: Format.h:4941
@ LS_Cpp20
Parse and format as C++20.
Definition: Format.h:4945
@ 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:4132
@ JSQS_Single
Always use single quotes.
Definition: Format.h:3140
@ JSQS_Leave
Leave string quotes as they are.
Definition: Format.h:3134
bool SpaceAfterCStyleCast
If true, a space is inserted after C style casts.
Definition: Format.h:4353
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:3701
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:3090
SpaceAroundPointerQualifiersStyle SpaceAroundPointerQualifiers
Defines in which cases to put a space before or after pointer qualifiers.
Definition: Format.h:4402
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:4411
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:5173
@ 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:3642
unsigned PenaltyReturnTypeOnItsOwnLine
Penalty for putting the return type of a function onto its own line.
Definition: Format.h:3663
@ BFCS_Both
Add one space on each side of the :
Definition: Format.h:1252
PointerAlignmentStyle PointerAlignment
Pointer and reference alignment style.
Definition: Format.h:3686
@ 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:4145
PackConstructorInitializersStyle PackConstructorInitializers
The pack constructor initializers style to use.
Definition: Format.h:3618
@ 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:3897
KeepEmptyLinesStyle KeepEmptyLines
Which empty lines are kept.
Definition: Format.h:3204
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:3404
bool SpaceBeforeSquareBrackets
If true, spaces will be before [.
Definition: Format.h:4658
BinPackStyle ObjCBinPackProtocolList
Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...
Definition: Format.h:3488
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:4791
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:3292
DAGArgStyle TableGenBreakInsideDAGArg
The styles of the line break inside the DAGArg in TableGen.
Definition: Format.h:5040
JavaScriptQuoteStyle JavaScriptQuotes
The JavaScriptQuoteStyle to use for JavaScript strings.
Definition: Format.h:3151
bool SpacesInContainerLiterals
If true, spaces will be inserted around if/for/switch/while conditions.
Definition: Format.h:4743
SortJavaStaticImportOptions SortJavaStaticImport
When sorting Java imports, by default static imports are placed before non-static imports.
Definition: Format.h:4301
@ SAPQ_Default
Don't ensure spaces around pointer qualifiers and use PointerAlignment instead.
Definition: Format.h:4379
bool SpaceBeforeRangeBasedForLoopColon
If false, spaces will be removed before range-based for loop colon.
Definition: Format.h:4667
bool DisableFormat
Disables formatting completely.
Definition: Format.h:2547
@ ELAAMS_Never
Remove all empty lines after access modifiers.
Definition: Format.h:2567
@ 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:3455
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:3254
QualifierAlignmentStyle QualifierAlignment
Different ways to arrange specifiers and qualifiers (e.g.
Definition: Format.h:3747
@ BBO_Never
Don't break binary operations.
Definition: Format.h:2277
bool IndentGotoLabels
Indent goto labels.
Definition: Format.h:2819
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:4986
@ SIAS_Never
Remove spaces after < and before >.
Definition: Format.h:4712
@ SUD_LexicographicNumeric
Using declarations are sorted in the order defined as follows: Split the strings by :: and discard an...
Definition: Format.h:4340
@ SUD_Never
Using declarations are never sorted.
Definition: Format.h:4313
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:3984
@ RPS_ReturnStatement
Also remove parentheses enclosing the expression in a return/co_return statement.
Definition: Format.h:3999
std::vector< std::string > TableGenBreakingDAGArgOperators
Works only when TableGenBreakInsideDAGArg is not DontBreak.
Definition: Format.h:5012
EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier
Defines in which cases to put empty line before access modifiers.
Definition: Format.h:2661
bool SpaceBeforeCaseColon
If false, spaces will be removed before case colon.
Definition: Format.h:4421
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:3167
bool SkipMacroDefinitionBody
Do not format macro definition body.
Definition: Format.h:4242
unsigned PenaltyBreakAssignment
The penalty for breaking around an assignment operator.
Definition: Format.h:3622
@ PAS_Left
Align pointer to the left.
Definition: Format.h:3671
@ PAS_Right
Align pointer to the right.
Definition: Format.h:3676
unsigned PenaltyBreakString
The penalty for each line break introduced inside a string literal.
Definition: Format.h:3646
RequiresExpressionIndentationKind RequiresExpressionIndentation
The indentation used for requires expression bodies.
Definition: Format.h:4158
bool SpaceAfterTemplateKeyword
If true, a space will be inserted after the template keyword.
Definition: Format.h:4369
unsigned PenaltyIndentedWhitespace
Penalty for each character of whitespace indentation (counted relative to leading non-whitespace colu...
Definition: Format.h:3659
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:3417
@ NI_All
Indent in all namespaces.
Definition: Format.h:3437
@ NI_Inner
Indent only in inner namespaces (nested in other namespaces).
Definition: Format.h:3427
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:3350
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:3630
@ 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:3838
EmptyLineAfterAccessModifierStyle EmptyLineAfterAccessModifier
Defines when to put an empty line after access modifiers.
Definition: Format.h:2598
bool IndentAccessModifiers
Specify whether access modifiers should have their own indentation level.
Definition: Format.h:2760
bool InsertNewlineAtEOF
Insert a newline at end of file if missing.
Definition: Format.h:2981
SpaceBeforeParensStyle SpaceBeforeParens
Defines in which cases to put a space before opening parentheses.
Definition: Format.h:4522
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:4433
UseTabStyle UseTab
The way to use tab characters in the resulting file.
Definition: Format.h:5105
@ QAS_Leave
Don't change specifiers/qualifiers to either Left or Right alignment (default).
Definition: Format.h:3711
std::vector< std::string > TypenameMacros
A vector of macros that should be interpreted as type declarations instead of as function calls.
Definition: Format.h:5080
@ 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:3317
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:4238
SortUsingDeclarationsOptions SortUsingDeclarations
Controls if and how clang-format will sort using declarations.
Definition: Format.h:4345
IndentExternBlockStyle IndentExternBlock
IndentExternBlockStyle is the type of indenting of extern blocks.
Definition: Format.h:2859
SeparateDefinitionStyle SeparateDefinitionBlocks
Specifies the use of empty lines to separate definition blocks, including classes,...
Definition: Format.h:4216
tooling::IncludeStyle IncludeStyle
Definition: Format.h:2712
unsigned ColumnLimit
The column limit.
Definition: Format.h:2408
Represents the status of a formatting attempt.
Definition: Format.h:5516
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:1275
static size_t size(IO &IO, std::vector< FormatStyle > &Seq)
Definition: Format.cpp:1272
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