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