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