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