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