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