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