xref: /llvm-project/clang/lib/Format/Format.cpp (revision 106c483a102e1328f11e2b1d9398f4ad2826b59f)
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("ExportBlockIndentation", Style.ExportBlockIndentation);
1044     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
1045     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
1046     IO.mapOptional("IfMacros", Style.IfMacros);
1047     IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1048     IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
1049     IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1050     IO.mapOptional("IncludeIsMainSourceRegex",
1051                    Style.IncludeStyle.IncludeIsMainSourceRegex);
1052     IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
1053     IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
1054     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
1055     IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
1056     IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
1057     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
1058     IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause);
1059     IO.mapOptional("IndentWidth", Style.IndentWidth);
1060     IO.mapOptional("IndentWrappedFunctionNames",
1061                    Style.IndentWrappedFunctionNames);
1062     IO.mapOptional("InsertBraces", Style.InsertBraces);
1063     IO.mapOptional("InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1064     IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
1065     IO.mapOptional("IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1066     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
1067     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
1068     IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
1069     IO.mapOptional("KeepEmptyLines", Style.KeepEmptyLines);
1070     IO.mapOptional("KeepFormFeed", Style.KeepFormFeed);
1071     IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
1072     IO.mapOptional("LineEnding", Style.LineEnding);
1073     IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
1074     IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
1075     IO.mapOptional("Macros", Style.Macros);
1076     IO.mapOptional("MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1077     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1078     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
1079     IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
1080     IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1081     IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1082     IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
1083                    Style.ObjCBreakBeforeNestedBlockParam);
1084     IO.mapOptional("ObjCPropertyAttributeOrder",
1085                    Style.ObjCPropertyAttributeOrder);
1086     IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1087     IO.mapOptional("ObjCSpaceBeforeProtocolList",
1088                    Style.ObjCSpaceBeforeProtocolList);
1089     IO.mapOptional("PackConstructorInitializers",
1090                    Style.PackConstructorInitializers);
1091     IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1092     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
1093                    Style.PenaltyBreakBeforeFirstCallParameter);
1094     IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
1095     IO.mapOptional("PenaltyBreakFirstLessLess",
1096                    Style.PenaltyBreakFirstLessLess);
1097     IO.mapOptional("PenaltyBreakOpenParenthesis",
1098                    Style.PenaltyBreakOpenParenthesis);
1099     IO.mapOptional("PenaltyBreakScopeResolution",
1100                    Style.PenaltyBreakScopeResolution);
1101     IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
1102     IO.mapOptional("PenaltyBreakTemplateDeclaration",
1103                    Style.PenaltyBreakTemplateDeclaration);
1104     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1105     IO.mapOptional("PenaltyIndentedWhitespace",
1106                    Style.PenaltyIndentedWhitespace);
1107     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
1108                    Style.PenaltyReturnTypeOnItsOwnLine);
1109     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
1110     IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
1111     IO.mapOptional("QualifierAlignment", Style.QualifierAlignment);
1112     // Default Order for Left/Right based Qualifier alignment.
1113     if (Style.QualifierAlignment == FormatStyle::QAS_Right)
1114       Style.QualifierOrder = {"type", "const", "volatile"};
1115     else if (Style.QualifierAlignment == FormatStyle::QAS_Left)
1116       Style.QualifierOrder = {"const", "volatile", "type"};
1117     else if (Style.QualifierAlignment == FormatStyle::QAS_Custom)
1118       IO.mapOptional("QualifierOrder", Style.QualifierOrder);
1119     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
1120     IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
1121     IO.mapOptional("ReflowComments", Style.ReflowComments);
1122     IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
1123     IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1124                    Style.RemoveEmptyLinesInUnwrappedLines);
1125     IO.mapOptional("RemoveParentheses", Style.RemoveParentheses);
1126     IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
1127     IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
1128     IO.mapOptional("RequiresExpressionIndentation",
1129                    Style.RequiresExpressionIndentation);
1130     IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1131     IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
1132     IO.mapOptional("SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1133     IO.mapOptional("SortIncludes", Style.SortIncludes);
1134     IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
1135     IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
1136     IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1137     IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1138     IO.mapOptional("SpaceAfterTemplateKeyword",
1139                    Style.SpaceAfterTemplateKeyword);
1140     IO.mapOptional("SpaceAroundPointerQualifiers",
1141                    Style.SpaceAroundPointerQualifiers);
1142     IO.mapOptional("SpaceBeforeAssignmentOperators",
1143                    Style.SpaceBeforeAssignmentOperators);
1144     IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1145     IO.mapOptional("SpaceBeforeCpp11BracedList",
1146                    Style.SpaceBeforeCpp11BracedList);
1147     IO.mapOptional("SpaceBeforeCtorInitializerColon",
1148                    Style.SpaceBeforeCtorInitializerColon);
1149     IO.mapOptional("SpaceBeforeInheritanceColon",
1150                    Style.SpaceBeforeInheritanceColon);
1151     IO.mapOptional("SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1152     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
1153     IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1154     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
1155                    Style.SpaceBeforeRangeBasedForLoopColon);
1156     IO.mapOptional("SpaceBeforeSquareBrackets",
1157                    Style.SpaceBeforeSquareBrackets);
1158     IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
1159     IO.mapOptional("SpacesBeforeTrailingComments",
1160                    Style.SpacesBeforeTrailingComments);
1161     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
1162     IO.mapOptional("SpacesInContainerLiterals",
1163                    Style.SpacesInContainerLiterals);
1164     IO.mapOptional("SpacesInLineCommentPrefix",
1165                    Style.SpacesInLineCommentPrefix);
1166     IO.mapOptional("SpacesInParens", Style.SpacesInParens);
1167     IO.mapOptional("SpacesInParensOptions", Style.SpacesInParensOptions);
1168     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1169     IO.mapOptional("Standard", Style.Standard);
1170     IO.mapOptional("StatementAttributeLikeMacros",
1171                    Style.StatementAttributeLikeMacros);
1172     IO.mapOptional("StatementMacros", Style.StatementMacros);
1173     IO.mapOptional("TableGenBreakingDAGArgOperators",
1174                    Style.TableGenBreakingDAGArgOperators);
1175     IO.mapOptional("TableGenBreakInsideDAGArg",
1176                    Style.TableGenBreakInsideDAGArg);
1177     IO.mapOptional("TabWidth", Style.TabWidth);
1178     IO.mapOptional("TemplateNames", Style.TemplateNames);
1179     IO.mapOptional("TypeNames", Style.TypeNames);
1180     IO.mapOptional("TypenameMacros", Style.TypenameMacros);
1181     IO.mapOptional("UseTab", Style.UseTab);
1182     IO.mapOptional("VariableTemplates", Style.VariableTemplates);
1183     IO.mapOptional("VerilogBreakBetweenInstancePorts",
1184                    Style.VerilogBreakBetweenInstancePorts);
1185     IO.mapOptional("WhitespaceSensitiveMacros",
1186                    Style.WhitespaceSensitiveMacros);
1187     IO.mapOptional("WrapNamespaceBodyWithEmptyLines",
1188                    Style.WrapNamespaceBodyWithEmptyLines);
1189 
1190     // If AlwaysBreakAfterDefinitionReturnType was specified but
1191     // BreakAfterReturnType was not, initialize the latter from the former for
1192     // backwards compatibility.
1193     if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
1194         Style.BreakAfterReturnType == FormatStyle::RTBS_None) {
1195       if (Style.AlwaysBreakAfterDefinitionReturnType ==
1196           FormatStyle::DRTBS_All) {
1197         Style.BreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1198       } else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1199                  FormatStyle::DRTBS_TopLevel) {
1200         Style.BreakAfterReturnType = FormatStyle::RTBS_TopLevelDefinitions;
1201       }
1202     }
1203 
1204     // If BreakBeforeInheritanceComma was specified but BreakInheritance was
1205     // not, initialize the latter from the former for backwards compatibility.
1206     if (BreakBeforeInheritanceComma &&
1207         Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) {
1208       Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1209     }
1210 
1211     // If BreakConstructorInitializersBeforeComma was specified but
1212     // BreakConstructorInitializers was not, initialize the latter from the
1213     // former for backwards compatibility.
1214     if (BreakConstructorInitializersBeforeComma &&
1215         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon) {
1216       Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1217     }
1218 
1219     if (!IsGoogleOrChromium) {
1220       if (Style.PackConstructorInitializers == FormatStyle::PCIS_BinPack &&
1221           OnCurrentLine) {
1222         Style.PackConstructorInitializers = OnNextLine
1223                                                 ? FormatStyle::PCIS_NextLine
1224                                                 : FormatStyle::PCIS_CurrentLine;
1225       }
1226     } else if (Style.PackConstructorInitializers ==
1227                FormatStyle::PCIS_NextLine) {
1228       if (!OnCurrentLine)
1229         Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1230       else if (!OnNextLine)
1231         Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine;
1232     }
1233 
1234     if (Style.LineEnding == FormatStyle::LE_DeriveLF) {
1235       if (!DeriveLineEnding)
1236         Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1237       else if (UseCRLF)
1238         Style.LineEnding = FormatStyle::LE_DeriveCRLF;
1239     }
1240 
1241     if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
1242         (SpacesInParentheses || SpaceInEmptyParentheses ||
1243          SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1244       if (SpacesInParentheses) {
1245         // For backward compatibility.
1246         Style.SpacesInParensOptions.ExceptDoubleParentheses = false;
1247         Style.SpacesInParensOptions.InConditionalStatements = true;
1248         Style.SpacesInParensOptions.InCStyleCasts =
1249             SpacesInCStyleCastParentheses;
1250         Style.SpacesInParensOptions.InEmptyParentheses =
1251             SpaceInEmptyParentheses;
1252         Style.SpacesInParensOptions.Other = true;
1253       } else {
1254         Style.SpacesInParensOptions = {};
1255         Style.SpacesInParensOptions.InConditionalStatements =
1256             SpacesInConditionalStatement;
1257         Style.SpacesInParensOptions.InCStyleCasts =
1258             SpacesInCStyleCastParentheses;
1259         Style.SpacesInParensOptions.InEmptyParentheses =
1260             SpaceInEmptyParentheses;
1261       }
1262       Style.SpacesInParens = FormatStyle::SIPO_Custom;
1263     }
1264   }
1265 };
1266 
1267 // Allows to read vector<FormatStyle> while keeping default values.
1268 // IO.getContext() should contain a pointer to the FormatStyle structure, that
1269 // will be used to get default values for missing keys.
1270 // If the first element has no Language specified, it will be treated as the
1271 // default one for the following elements.
1272 template <> struct DocumentListTraits<std::vector<FormatStyle>> {
1273   static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1274     return Seq.size();
1275   }
1276   static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
1277                               size_t Index) {
1278     if (Index >= Seq.size()) {
1279       assert(Index == Seq.size());
1280       FormatStyle Template;
1281       if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1282         Template = Seq[0];
1283       } else {
1284         Template = *((const FormatStyle *)IO.getContext());
1285         Template.Language = FormatStyle::LK_None;
1286       }
1287       Seq.resize(Index + 1, Template);
1288     }
1289     return Seq[Index];
1290   }
1291 };
1292 } // namespace yaml
1293 } // namespace llvm
1294 
1295 namespace clang {
1296 namespace format {
1297 
1298 const std::error_category &getParseCategory() {
1299   static const ParseErrorCategory C{};
1300   return C;
1301 }
1302 std::error_code make_error_code(ParseError e) {
1303   return std::error_code(static_cast<int>(e), getParseCategory());
1304 }
1305 
1306 inline llvm::Error make_string_error(const Twine &Message) {
1307   return llvm::make_error<llvm::StringError>(Message,
1308                                              llvm::inconvertibleErrorCode());
1309 }
1310 
1311 const char *ParseErrorCategory::name() const noexcept {
1312   return "clang-format.parse_error";
1313 }
1314 
1315 std::string ParseErrorCategory::message(int EV) const {
1316   switch (static_cast<ParseError>(EV)) {
1317   case ParseError::Success:
1318     return "Success";
1319   case ParseError::Error:
1320     return "Invalid argument";
1321   case ParseError::Unsuitable:
1322     return "Unsuitable";
1323   case ParseError::BinPackTrailingCommaConflict:
1324     return "trailing comma insertion cannot be used with bin packing";
1325   case ParseError::InvalidQualifierSpecified:
1326     return "Invalid qualifier specified in QualifierOrder";
1327   case ParseError::DuplicateQualifierSpecified:
1328     return "Duplicate qualifier specified in QualifierOrder";
1329   case ParseError::MissingQualifierType:
1330     return "Missing type in QualifierOrder";
1331   case ParseError::MissingQualifierOrder:
1332     return "Missing QualifierOrder";
1333   }
1334   llvm_unreachable("unexpected parse error");
1335 }
1336 
1337 static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
1338   if (Expanded.BreakBeforeBraces == FormatStyle::BS_Custom)
1339     return;
1340   Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
1341                             /*AfterClass=*/false,
1342                             /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1343                             /*AfterEnum=*/false,
1344                             /*AfterFunction=*/false,
1345                             /*AfterNamespace=*/false,
1346                             /*AfterObjCDeclaration=*/false,
1347                             /*AfterStruct=*/false,
1348                             /*AfterUnion=*/false,
1349                             /*AfterExternBlock=*/false,
1350                             /*BeforeCatch=*/false,
1351                             /*BeforeElse=*/false,
1352                             /*BeforeLambdaBody=*/false,
1353                             /*BeforeWhile=*/false,
1354                             /*IndentBraces=*/false,
1355                             /*SplitEmptyFunction=*/true,
1356                             /*SplitEmptyRecord=*/true,
1357                             /*SplitEmptyNamespace=*/true};
1358   switch (Expanded.BreakBeforeBraces) {
1359   case FormatStyle::BS_Linux:
1360     Expanded.BraceWrapping.AfterClass = true;
1361     Expanded.BraceWrapping.AfterFunction = true;
1362     Expanded.BraceWrapping.AfterNamespace = true;
1363     break;
1364   case FormatStyle::BS_Mozilla:
1365     Expanded.BraceWrapping.AfterClass = true;
1366     Expanded.BraceWrapping.AfterEnum = true;
1367     Expanded.BraceWrapping.AfterFunction = true;
1368     Expanded.BraceWrapping.AfterStruct = true;
1369     Expanded.BraceWrapping.AfterUnion = true;
1370     Expanded.BraceWrapping.AfterExternBlock = true;
1371     Expanded.BraceWrapping.SplitEmptyFunction = true;
1372     Expanded.BraceWrapping.SplitEmptyRecord = false;
1373     break;
1374   case FormatStyle::BS_Stroustrup:
1375     Expanded.BraceWrapping.AfterFunction = true;
1376     Expanded.BraceWrapping.BeforeCatch = true;
1377     Expanded.BraceWrapping.BeforeElse = true;
1378     break;
1379   case FormatStyle::BS_Allman:
1380     Expanded.BraceWrapping.AfterCaseLabel = true;
1381     Expanded.BraceWrapping.AfterClass = true;
1382     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1383     Expanded.BraceWrapping.AfterEnum = true;
1384     Expanded.BraceWrapping.AfterFunction = true;
1385     Expanded.BraceWrapping.AfterNamespace = true;
1386     Expanded.BraceWrapping.AfterObjCDeclaration = true;
1387     Expanded.BraceWrapping.AfterStruct = true;
1388     Expanded.BraceWrapping.AfterUnion = true;
1389     Expanded.BraceWrapping.AfterExternBlock = true;
1390     Expanded.BraceWrapping.BeforeCatch = true;
1391     Expanded.BraceWrapping.BeforeElse = true;
1392     Expanded.BraceWrapping.BeforeLambdaBody = true;
1393     break;
1394   case FormatStyle::BS_Whitesmiths:
1395     Expanded.BraceWrapping.AfterCaseLabel = true;
1396     Expanded.BraceWrapping.AfterClass = true;
1397     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1398     Expanded.BraceWrapping.AfterEnum = true;
1399     Expanded.BraceWrapping.AfterFunction = true;
1400     Expanded.BraceWrapping.AfterNamespace = true;
1401     Expanded.BraceWrapping.AfterObjCDeclaration = true;
1402     Expanded.BraceWrapping.AfterStruct = true;
1403     Expanded.BraceWrapping.AfterExternBlock = true;
1404     Expanded.BraceWrapping.BeforeCatch = true;
1405     Expanded.BraceWrapping.BeforeElse = true;
1406     Expanded.BraceWrapping.BeforeLambdaBody = true;
1407     break;
1408   case FormatStyle::BS_GNU:
1409     Expanded.BraceWrapping = {
1410         /*AfterCaseLabel=*/true,
1411         /*AfterClass=*/true,
1412         /*AfterControlStatement=*/FormatStyle::BWACS_Always,
1413         /*AfterEnum=*/true,
1414         /*AfterFunction=*/true,
1415         /*AfterNamespace=*/true,
1416         /*AfterObjCDeclaration=*/true,
1417         /*AfterStruct=*/true,
1418         /*AfterUnion=*/true,
1419         /*AfterExternBlock=*/true,
1420         /*BeforeCatch=*/true,
1421         /*BeforeElse=*/true,
1422         /*BeforeLambdaBody=*/false,
1423         /*BeforeWhile=*/true,
1424         /*IndentBraces=*/true,
1425         /*SplitEmptyFunction=*/true,
1426         /*SplitEmptyRecord=*/true,
1427         /*SplitEmptyNamespace=*/true};
1428     break;
1429   case FormatStyle::BS_WebKit:
1430     Expanded.BraceWrapping.AfterFunction = true;
1431     break;
1432   default:
1433     break;
1434   }
1435 }
1436 
1437 static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded) {
1438   if (Expanded.SpaceBeforeParens == FormatStyle::SBPO_Custom)
1439     return;
1440   // Reset all flags
1441   Expanded.SpaceBeforeParensOptions = {};
1442   Expanded.SpaceBeforeParensOptions.AfterPlacementOperator = true;
1443 
1444   switch (Expanded.SpaceBeforeParens) {
1445   case FormatStyle::SBPO_ControlStatements:
1446     Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1447     Expanded.SpaceBeforeParensOptions.AfterForeachMacros = true;
1448     Expanded.SpaceBeforeParensOptions.AfterIfMacros = true;
1449     break;
1450   case FormatStyle::SBPO_ControlStatementsExceptControlMacros:
1451     Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1452     break;
1453   case FormatStyle::SBPO_NonEmptyParentheses:
1454     Expanded.SpaceBeforeParensOptions.BeforeNonEmptyParentheses = true;
1455     break;
1456   default:
1457     break;
1458   }
1459 }
1460 
1461 static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
1462   if (Expanded.SpacesInParens == FormatStyle::SIPO_Custom)
1463     return;
1464   assert(Expanded.SpacesInParens == FormatStyle::SIPO_Never);
1465   // Reset all flags
1466   Expanded.SpacesInParensOptions = {};
1467 }
1468 
1469 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
1470   FormatStyle LLVMStyle;
1471   LLVMStyle.AccessModifierOffset = -2;
1472   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
1473   LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
1474   LLVMStyle.AlignConsecutiveAssignments = {};
1475   LLVMStyle.AlignConsecutiveAssignments.PadOperators = true;
1476   LLVMStyle.AlignConsecutiveBitFields = {};
1477   LLVMStyle.AlignConsecutiveDeclarations = {};
1478   LLVMStyle.AlignConsecutiveDeclarations.AlignFunctionDeclarations = true;
1479   LLVMStyle.AlignConsecutiveMacros = {};
1480   LLVMStyle.AlignConsecutiveShortCaseStatements = {};
1481   LLVMStyle.AlignConsecutiveTableGenBreakingDAGArgColons = {};
1482   LLVMStyle.AlignConsecutiveTableGenCondOperatorColons = {};
1483   LLVMStyle.AlignConsecutiveTableGenDefinitionColons = {};
1484   LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
1485   LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
1486   LLVMStyle.AlignTrailingComments = {};
1487   LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
1488   LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;
1489   LLVMStyle.AllowAllArgumentsOnNextLine = true;
1490   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
1491   LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never;
1492   LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
1493   LLVMStyle.AllowShortCaseExpressionOnASingleLine = true;
1494   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
1495   LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
1496   LLVMStyle.AllowShortEnumsOnASingleLine = true;
1497   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
1498   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1499   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
1500   LLVMStyle.AllowShortLoopsOnASingleLine = false;
1501   LLVMStyle.AllowShortNamespacesOnASingleLine = false;
1502   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1503   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
1504   LLVMStyle.AttributeMacros.push_back("__capability");
1505   LLVMStyle.BinPackArguments = true;
1506   LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack;
1507   LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
1508   LLVMStyle.BracedInitializerIndentWidth = std::nullopt;
1509   LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
1510                              /*AfterClass=*/false,
1511                              /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1512                              /*AfterEnum=*/false,
1513                              /*AfterFunction=*/false,
1514                              /*AfterNamespace=*/false,
1515                              /*AfterObjCDeclaration=*/false,
1516                              /*AfterStruct=*/false,
1517                              /*AfterUnion=*/false,
1518                              /*AfterExternBlock=*/false,
1519                              /*BeforeCatch=*/false,
1520                              /*BeforeElse=*/false,
1521                              /*BeforeLambdaBody=*/false,
1522                              /*BeforeWhile=*/false,
1523                              /*IndentBraces=*/false,
1524                              /*SplitEmptyFunction=*/true,
1525                              /*SplitEmptyRecord=*/true,
1526                              /*SplitEmptyNamespace=*/true};
1527   LLVMStyle.BreakAdjacentStringLiterals = true;
1528   LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave;
1529   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
1530   LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None;
1531   LLVMStyle.BreakArrays = true;
1532   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
1533   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
1534   LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
1535   LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
1536   LLVMStyle.BreakBeforeTernaryOperators = true;
1537   LLVMStyle.BreakBinaryOperations = FormatStyle::BBO_Never;
1538   LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
1539   LLVMStyle.BreakFunctionDefinitionParameters = false;
1540   LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
1541   LLVMStyle.BreakStringLiterals = true;
1542   LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
1543   LLVMStyle.ColumnLimit = 80;
1544   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
1545   LLVMStyle.CompactNamespaces = false;
1546   LLVMStyle.ConstructorInitializerIndentWidth = 4;
1547   LLVMStyle.ContinuationIndentWidth = 4;
1548   LLVMStyle.Cpp11BracedListStyle = true;
1549   LLVMStyle.DerivePointerAlignment = false;
1550   LLVMStyle.DisableFormat = false;
1551   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
1552   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
1553   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1554   LLVMStyle.ExportBlockIndentation = true;
1555   LLVMStyle.FixNamespaceComments = true;
1556   LLVMStyle.ForEachMacros.push_back("foreach");
1557   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1558   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1559   LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
1560   LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
1561   LLVMStyle.IncludeStyle.IncludeCategories = {
1562       {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1563       {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1564       {".*", 1, 0, false}};
1565   LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1566   LLVMStyle.IncludeStyle.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1567   LLVMStyle.IndentAccessModifiers = false;
1568   LLVMStyle.IndentCaseBlocks = false;
1569   LLVMStyle.IndentCaseLabels = false;
1570   LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1571   LLVMStyle.IndentGotoLabels = true;
1572   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
1573   LLVMStyle.IndentRequiresClause = true;
1574   LLVMStyle.IndentWidth = 2;
1575   LLVMStyle.IndentWrappedFunctionNames = false;
1576   LLVMStyle.InheritsParentConfig = false;
1577   LLVMStyle.InsertBraces = false;
1578   LLVMStyle.InsertNewlineAtEOF = false;
1579   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1580   LLVMStyle.IntegerLiteralSeparator = {
1581       /*Binary=*/0,  /*BinaryMinDigits=*/0,
1582       /*Decimal=*/0, /*DecimalMinDigits=*/0,
1583       /*Hex=*/0,     /*HexMinDigits=*/0};
1584   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
1585   LLVMStyle.JavaScriptWrapImports = true;
1586   LLVMStyle.KeepEmptyLines = {
1587       /*AtEndOfFile=*/false,
1588       /*AtStartOfBlock=*/true,
1589       /*AtStartOfFile=*/true,
1590   };
1591   LLVMStyle.KeepFormFeed = false;
1592   LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature;
1593   LLVMStyle.Language = Language;
1594   LLVMStyle.LineEnding = FormatStyle::LE_DeriveLF;
1595   LLVMStyle.MaxEmptyLinesToKeep = 1;
1596   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
1597   LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
1598   LLVMStyle.ObjCBlockIndentWidth = 2;
1599   LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1600   LLVMStyle.ObjCSpaceAfterProperty = false;
1601   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1602   LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1603   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
1604   LLVMStyle.PPIndentWidth = -1;
1605   LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave;
1606   LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
1607   LLVMStyle.ReflowComments = FormatStyle::RCS_Always;
1608   LLVMStyle.RemoveBracesLLVM = false;
1609   LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false;
1610   LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave;
1611   LLVMStyle.RemoveSemicolon = false;
1612   LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine;
1613   LLVMStyle.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
1614   LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
1615   LLVMStyle.ShortNamespaceLines = 1;
1616   LLVMStyle.SkipMacroDefinitionBody = false;
1617   LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1618   LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
1619   LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
1620   LLVMStyle.SpaceAfterCStyleCast = false;
1621   LLVMStyle.SpaceAfterLogicalNot = false;
1622   LLVMStyle.SpaceAfterTemplateKeyword = true;
1623   LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
1624   LLVMStyle.SpaceBeforeAssignmentOperators = true;
1625   LLVMStyle.SpaceBeforeCaseColon = false;
1626   LLVMStyle.SpaceBeforeCpp11BracedList = false;
1627   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1628   LLVMStyle.SpaceBeforeInheritanceColon = true;
1629   LLVMStyle.SpaceBeforeJsonColon = false;
1630   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
1631   LLVMStyle.SpaceBeforeParensOptions = {};
1632   LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true;
1633   LLVMStyle.SpaceBeforeParensOptions.AfterForeachMacros = true;
1634   LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true;
1635   LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1636   LLVMStyle.SpaceBeforeSquareBrackets = false;
1637   LLVMStyle.SpaceInEmptyBlock = false;
1638   LLVMStyle.SpacesBeforeTrailingComments = 1;
1639   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
1640   LLVMStyle.SpacesInContainerLiterals = true;
1641   LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
1642   LLVMStyle.SpacesInParens = FormatStyle::SIPO_Never;
1643   LLVMStyle.SpacesInSquareBrackets = false;
1644   LLVMStyle.Standard = FormatStyle::LS_Latest;
1645   LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1646   LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1647   LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1648   LLVMStyle.TableGenBreakingDAGArgOperators = {};
1649   LLVMStyle.TableGenBreakInsideDAGArg = FormatStyle::DAS_DontBreak;
1650   LLVMStyle.TabWidth = 8;
1651   LLVMStyle.UseTab = FormatStyle::UT_Never;
1652   LLVMStyle.VerilogBreakBetweenInstancePorts = true;
1653   LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1654   LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1655   LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1656   LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1657   LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1658   LLVMStyle.WrapNamespaceBodyWithEmptyLines = FormatStyle::WNBWELS_Leave;
1659 
1660   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
1661   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
1662   LLVMStyle.PenaltyBreakComment = 300;
1663   LLVMStyle.PenaltyBreakFirstLessLess = 120;
1664   LLVMStyle.PenaltyBreakOpenParenthesis = 0;
1665   LLVMStyle.PenaltyBreakScopeResolution = 500;
1666   LLVMStyle.PenaltyBreakString = 1000;
1667   LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
1668   LLVMStyle.PenaltyExcessCharacter = 1'000'000;
1669   LLVMStyle.PenaltyIndentedWhitespace = 0;
1670   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1671 
1672   // Defaults that differ when not C++.
1673   switch (Language) {
1674   case FormatStyle::LK_TableGen:
1675     LLVMStyle.SpacesInContainerLiterals = false;
1676     break;
1677   case FormatStyle::LK_Json:
1678     LLVMStyle.ColumnLimit = 0;
1679     break;
1680   case FormatStyle::LK_Verilog:
1681     LLVMStyle.IndentCaseLabels = true;
1682     LLVMStyle.SpacesInContainerLiterals = false;
1683     break;
1684   default:
1685     break;
1686   }
1687 
1688   return LLVMStyle;
1689 }
1690 
1691 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
1692   if (Language == FormatStyle::LK_TextProto) {
1693     FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
1694     GoogleStyle.Language = FormatStyle::LK_TextProto;
1695 
1696     return GoogleStyle;
1697   }
1698 
1699   FormatStyle GoogleStyle = getLLVMStyle(Language);
1700 
1701   GoogleStyle.AccessModifierOffset = -1;
1702   GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
1703   GoogleStyle.AllowShortIfStatementsOnASingleLine =
1704       FormatStyle::SIS_WithoutElse;
1705   GoogleStyle.AllowShortLoopsOnASingleLine = true;
1706   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1707   GoogleStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1708   GoogleStyle.DerivePointerAlignment = true;
1709   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1710   GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1711                                                 {"^<.*\\.h>", 1, 0, false},
1712                                                 {"^<.*", 2, 0, false},
1713                                                 {".*", 3, 0, false}};
1714   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1715   GoogleStyle.IndentCaseLabels = true;
1716   GoogleStyle.KeepEmptyLines.AtStartOfBlock = false;
1717   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
1718   GoogleStyle.ObjCSpaceAfterProperty = false;
1719   GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1720   GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
1721   GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
1722   GoogleStyle.RawStringFormats = {
1723       {
1724           FormatStyle::LK_Cpp,
1725           /*Delimiters=*/
1726           {
1727               "cc",
1728               "CC",
1729               "cpp",
1730               "Cpp",
1731               "CPP",
1732               "c++",
1733               "C++",
1734           },
1735           /*EnclosingFunctionNames=*/
1736           {},
1737           /*CanonicalDelimiter=*/"",
1738           /*BasedOnStyle=*/"google",
1739       },
1740       {
1741           FormatStyle::LK_TextProto,
1742           /*Delimiters=*/
1743           {
1744               "pb",
1745               "PB",
1746               "proto",
1747               "PROTO",
1748           },
1749           /*EnclosingFunctionNames=*/
1750           {
1751               "EqualsProto",
1752               "EquivToProto",
1753               "PARSE_PARTIAL_TEXT_PROTO",
1754               "PARSE_TEST_PROTO",
1755               "PARSE_TEXT_PROTO",
1756               "ParseTextOrDie",
1757               "ParseTextProtoOrDie",
1758               "ParseTestProto",
1759               "ParsePartialTestProto",
1760           },
1761           /*CanonicalDelimiter=*/"pb",
1762           /*BasedOnStyle=*/"google",
1763       },
1764   };
1765 
1766   GoogleStyle.SpacesBeforeTrailingComments = 2;
1767   GoogleStyle.Standard = FormatStyle::LS_Auto;
1768 
1769   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
1770   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1771 
1772   if (Language == FormatStyle::LK_Java) {
1773     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1774     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1775     GoogleStyle.AlignTrailingComments = {};
1776     GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
1777     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1778     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1779     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1780     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
1781     GoogleStyle.ColumnLimit = 100;
1782     GoogleStyle.SpaceAfterCStyleCast = true;
1783     GoogleStyle.SpacesBeforeTrailingComments = 1;
1784   } else if (Language == FormatStyle::LK_JavaScript) {
1785     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
1786     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1787     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1788     // TODO: still under discussion whether to switch to SLS_All.
1789     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
1790     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1791     GoogleStyle.BreakBeforeTernaryOperators = false;
1792     // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1793     // commonly followed by overlong URLs.
1794     GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1795     // TODO: enable once decided, in particular re disabling bin packing.
1796     // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1797     // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1798     GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
1799     GoogleStyle.JavaScriptWrapImports = false;
1800     GoogleStyle.MaxEmptyLinesToKeep = 3;
1801     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1802     GoogleStyle.SpacesInContainerLiterals = false;
1803   } else if (Language == FormatStyle::LK_Proto) {
1804     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1805     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1806     // This affects protocol buffer options specifications and text protos.
1807     // Text protos are currently mostly formatted inside C++ raw string literals
1808     // and often the current breaking behavior of string literals is not
1809     // beneficial there. Investigate turning this on once proper string reflow
1810     // has been implemented.
1811     GoogleStyle.BreakStringLiterals = false;
1812     GoogleStyle.Cpp11BracedListStyle = false;
1813     GoogleStyle.SpacesInContainerLiterals = false;
1814   } else if (Language == FormatStyle::LK_ObjC) {
1815     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1816     GoogleStyle.ColumnLimit = 100;
1817     // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1818     // relationship between ObjC standard library headers and other heades,
1819     // #imports, etc.)
1820     GoogleStyle.IncludeStyle.IncludeBlocks =
1821         tooling::IncludeStyle::IBS_Preserve;
1822   } else if (Language == FormatStyle::LK_CSharp) {
1823     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1824     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1825     GoogleStyle.BreakStringLiterals = false;
1826     GoogleStyle.ColumnLimit = 100;
1827     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1828   }
1829 
1830   return GoogleStyle;
1831 }
1832 
1833 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
1834   FormatStyle ChromiumStyle = getGoogleStyle(Language);
1835 
1836   // Disable include reordering across blocks in Chromium code.
1837   // - clang-format tries to detect that foo.h is the "main" header for
1838   //   foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1839   //   uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1840   //   _private.cc, _impl.cc etc) in different permutations
1841   //   (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1842   //   better default for Chromium code.
1843   // - The default for .cc and .mm files is different (r357695) for Google style
1844   //   for the same reason. The plan is to unify this again once the main
1845   //   header detection works for Google's ObjC code, but this hasn't happened
1846   //   yet. Since Chromium has some ObjC code, switching Chromium is blocked
1847   //   on that.
1848   // - Finally, "If include reordering is harmful, put things in different
1849   //   blocks to prevent it" has been a recommendation for a long time that
1850   //   people are used to. We'll need a dev education push to change this to
1851   //   "If include reordering is harmful, put things in a different block and
1852   //   _prepend that with a comment_ to prevent it" before changing behavior.
1853   ChromiumStyle.IncludeStyle.IncludeBlocks =
1854       tooling::IncludeStyle::IBS_Preserve;
1855 
1856   if (Language == FormatStyle::LK_Java) {
1857     ChromiumStyle.AllowShortIfStatementsOnASingleLine =
1858         FormatStyle::SIS_WithoutElse;
1859     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
1860     ChromiumStyle.ContinuationIndentWidth = 8;
1861     ChromiumStyle.IndentWidth = 4;
1862     // See styleguide for import groups:
1863     // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1864     ChromiumStyle.JavaImportGroups = {
1865         "android",
1866         "androidx",
1867         "com",
1868         "dalvik",
1869         "junit",
1870         "org",
1871         "com.google.android.apps.chrome",
1872         "org.chromium",
1873         "java",
1874         "javax",
1875     };
1876     ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1877   } else if (Language == FormatStyle::LK_JavaScript) {
1878     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1879     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1880   } else {
1881     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1882     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1883     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1884     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1885     ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
1886     ChromiumStyle.DerivePointerAlignment = false;
1887     if (Language == FormatStyle::LK_ObjC)
1888       ChromiumStyle.ColumnLimit = 80;
1889   }
1890   return ChromiumStyle;
1891 }
1892 
1893 FormatStyle getMozillaStyle() {
1894   FormatStyle MozillaStyle = getLLVMStyle();
1895   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1896   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1897   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
1898       FormatStyle::DRTBS_TopLevel;
1899   MozillaStyle.BinPackArguments = false;
1900   MozillaStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
1901   MozillaStyle.BreakAfterReturnType = FormatStyle::RTBS_TopLevel;
1902   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
1903   MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1904   MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1905   MozillaStyle.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1906   MozillaStyle.ConstructorInitializerIndentWidth = 2;
1907   MozillaStyle.ContinuationIndentWidth = 2;
1908   MozillaStyle.Cpp11BracedListStyle = false;
1909   MozillaStyle.FixNamespaceComments = false;
1910   MozillaStyle.IndentCaseLabels = true;
1911   MozillaStyle.ObjCSpaceAfterProperty = true;
1912   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
1913   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1914   MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
1915   MozillaStyle.SpaceAfterTemplateKeyword = false;
1916   return MozillaStyle;
1917 }
1918 
1919 FormatStyle getWebKitStyle() {
1920   FormatStyle Style = getLLVMStyle();
1921   Style.AccessModifierOffset = -4;
1922   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1923   Style.AlignOperands = FormatStyle::OAS_DontAlign;
1924   Style.AlignTrailingComments = {};
1925   Style.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
1926   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1927   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1928   Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
1929   Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1930   Style.ColumnLimit = 0;
1931   Style.Cpp11BracedListStyle = false;
1932   Style.FixNamespaceComments = false;
1933   Style.IndentWidth = 4;
1934   Style.NamespaceIndentation = FormatStyle::NI_Inner;
1935   Style.ObjCBlockIndentWidth = 4;
1936   Style.ObjCSpaceAfterProperty = true;
1937   Style.PointerAlignment = FormatStyle::PAS_Left;
1938   Style.SpaceBeforeCpp11BracedList = true;
1939   Style.SpaceInEmptyBlock = true;
1940   return Style;
1941 }
1942 
1943 FormatStyle getGNUStyle() {
1944   FormatStyle Style = getLLVMStyle();
1945   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
1946   Style.BreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1947   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1948   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
1949   Style.BreakBeforeTernaryOperators = true;
1950   Style.ColumnLimit = 79;
1951   Style.Cpp11BracedListStyle = false;
1952   Style.FixNamespaceComments = false;
1953   Style.KeepFormFeed = true;
1954   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
1955   return Style;
1956 }
1957 
1958 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
1959   FormatStyle Style = getLLVMStyle(Language);
1960   Style.ColumnLimit = 120;
1961   Style.TabWidth = 4;
1962   Style.IndentWidth = 4;
1963   Style.UseTab = FormatStyle::UT_Never;
1964   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1965   Style.BraceWrapping.AfterClass = true;
1966   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1967   Style.BraceWrapping.AfterEnum = true;
1968   Style.BraceWrapping.AfterFunction = true;
1969   Style.BraceWrapping.AfterNamespace = true;
1970   Style.BraceWrapping.AfterObjCDeclaration = true;
1971   Style.BraceWrapping.AfterStruct = true;
1972   Style.BraceWrapping.AfterExternBlock = true;
1973   Style.BraceWrapping.BeforeCatch = true;
1974   Style.BraceWrapping.BeforeElse = true;
1975   Style.BraceWrapping.BeforeWhile = false;
1976   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
1977   Style.AllowShortEnumsOnASingleLine = false;
1978   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
1979   Style.AllowShortCaseLabelsOnASingleLine = false;
1980   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1981   Style.AllowShortLoopsOnASingleLine = false;
1982   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1983   Style.BreakAfterReturnType = FormatStyle::RTBS_None;
1984   return Style;
1985 }
1986 
1987 FormatStyle getClangFormatStyle() {
1988   FormatStyle Style = getLLVMStyle();
1989   Style.InsertBraces = true;
1990   Style.InsertNewlineAtEOF = true;
1991   Style.IntegerLiteralSeparator.Decimal = 3;
1992   Style.IntegerLiteralSeparator.DecimalMinDigits = 5;
1993   Style.LineEnding = FormatStyle::LE_LF;
1994   Style.RemoveBracesLLVM = true;
1995   Style.RemoveEmptyLinesInUnwrappedLines = true;
1996   Style.RemoveParentheses = FormatStyle::RPS_ReturnStatement;
1997   Style.RemoveSemicolon = true;
1998   return Style;
1999 }
2000 
2001 FormatStyle getNoStyle() {
2002   FormatStyle NoStyle = getLLVMStyle();
2003   NoStyle.DisableFormat = true;
2004   NoStyle.SortIncludes = FormatStyle::SI_Never;
2005   NoStyle.SortUsingDeclarations = FormatStyle::SUD_Never;
2006   return NoStyle;
2007 }
2008 
2009 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
2010                         FormatStyle *Style) {
2011   if (Name.equals_insensitive("llvm"))
2012     *Style = getLLVMStyle(Language);
2013   else if (Name.equals_insensitive("chromium"))
2014     *Style = getChromiumStyle(Language);
2015   else if (Name.equals_insensitive("mozilla"))
2016     *Style = getMozillaStyle();
2017   else if (Name.equals_insensitive("google"))
2018     *Style = getGoogleStyle(Language);
2019   else if (Name.equals_insensitive("webkit"))
2020     *Style = getWebKitStyle();
2021   else if (Name.equals_insensitive("gnu"))
2022     *Style = getGNUStyle();
2023   else if (Name.equals_insensitive("microsoft"))
2024     *Style = getMicrosoftStyle(Language);
2025   else if (Name.equals_insensitive("clang-format"))
2026     *Style = getClangFormatStyle();
2027   else if (Name.equals_insensitive("none"))
2028     *Style = getNoStyle();
2029   else if (Name.equals_insensitive("inheritparentconfig"))
2030     Style->InheritsParentConfig = true;
2031   else
2032     return false;
2033 
2034   Style->Language = Language;
2035   return true;
2036 }
2037 
2038 ParseError validateQualifierOrder(FormatStyle *Style) {
2039   // If its empty then it means don't do anything.
2040   if (Style->QualifierOrder.empty())
2041     return ParseError::MissingQualifierOrder;
2042 
2043   // Ensure the list contains only currently valid qualifiers.
2044   for (const auto &Qualifier : Style->QualifierOrder) {
2045     if (Qualifier == "type")
2046       continue;
2047     auto token =
2048         LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier);
2049     if (token == tok::identifier)
2050       return ParseError::InvalidQualifierSpecified;
2051   }
2052 
2053   // Ensure the list is unique (no duplicates).
2054   std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2055                                          Style->QualifierOrder.end());
2056   if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2057     LLVM_DEBUG(llvm::dbgs()
2058                << "Duplicate Qualifiers " << Style->QualifierOrder.size()
2059                << " vs " << UniqueQualifiers.size() << "\n");
2060     return ParseError::DuplicateQualifierSpecified;
2061   }
2062 
2063   // Ensure the list has 'type' in it.
2064   if (!llvm::is_contained(Style->QualifierOrder, "type"))
2065     return ParseError::MissingQualifierType;
2066 
2067   return ParseError::Success;
2068 }
2069 
2070 std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
2071                                    FormatStyle *Style, bool AllowUnknownOptions,
2072                                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
2073                                    void *DiagHandlerCtxt) {
2074   assert(Style);
2075   FormatStyle::LanguageKind Language = Style->Language;
2076   assert(Language != FormatStyle::LK_None);
2077   if (Config.getBuffer().trim().empty())
2078     return make_error_code(ParseError::Success);
2079   Style->StyleSet.Clear();
2080   std::vector<FormatStyle> Styles;
2081   llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
2082                           DiagHandlerCtxt);
2083   // DocumentListTraits<vector<FormatStyle>> uses the context to get default
2084   // values for the fields, keys for which are missing from the configuration.
2085   // Mapping also uses the context to get the language to find the correct
2086   // base style.
2087   Input.setContext(Style);
2088   Input.setAllowUnknownKeys(AllowUnknownOptions);
2089   Input >> Styles;
2090   if (Input.error())
2091     return Input.error();
2092 
2093   for (unsigned i = 0; i < Styles.size(); ++i) {
2094     // Ensures that only the first configuration can skip the Language option.
2095     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
2096       return make_error_code(ParseError::Error);
2097     // Ensure that each language is configured at most once.
2098     for (unsigned j = 0; j < i; ++j) {
2099       if (Styles[i].Language == Styles[j].Language) {
2100         LLVM_DEBUG(llvm::dbgs()
2101                    << "Duplicate languages in the config file on positions "
2102                    << j << " and " << i << "\n");
2103         return make_error_code(ParseError::Error);
2104       }
2105     }
2106   }
2107   // Look for a suitable configuration starting from the end, so we can
2108   // find the configuration for the specific language first, and the default
2109   // configuration (which can only be at slot 0) after it.
2110   FormatStyle::FormatStyleSet StyleSet;
2111   bool LanguageFound = false;
2112   for (const FormatStyle &Style : llvm::reverse(Styles)) {
2113     if (Style.Language != FormatStyle::LK_None)
2114       StyleSet.Add(Style);
2115     if (Style.Language == Language)
2116       LanguageFound = true;
2117   }
2118   if (!LanguageFound) {
2119     if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
2120       return make_error_code(ParseError::Unsuitable);
2121     FormatStyle DefaultStyle = Styles[0];
2122     DefaultStyle.Language = Language;
2123     StyleSet.Add(std::move(DefaultStyle));
2124   }
2125   *Style = *StyleSet.Get(Language);
2126   if (Style->InsertTrailingCommas != FormatStyle::TCS_None &&
2127       Style->BinPackArguments) {
2128     // See comment on FormatStyle::TSC_Wrapped.
2129     return make_error_code(ParseError::BinPackTrailingCommaConflict);
2130   }
2131   if (Style->QualifierAlignment != FormatStyle::QAS_Leave)
2132     return make_error_code(validateQualifierOrder(Style));
2133   return make_error_code(ParseError::Success);
2134 }
2135 
2136 std::string configurationAsText(const FormatStyle &Style) {
2137   std::string Text;
2138   llvm::raw_string_ostream Stream(Text);
2139   llvm::yaml::Output Output(Stream);
2140   // We use the same mapping method for input and output, so we need a non-const
2141   // reference here.
2142   FormatStyle NonConstStyle = Style;
2143   expandPresetsBraceWrapping(NonConstStyle);
2144   expandPresetsSpaceBeforeParens(NonConstStyle);
2145   expandPresetsSpacesInParens(NonConstStyle);
2146   Output << NonConstStyle;
2147 
2148   return Stream.str();
2149 }
2150 
2151 std::optional<FormatStyle>
2152 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
2153   if (!Styles)
2154     return std::nullopt;
2155   auto It = Styles->find(Language);
2156   if (It == Styles->end())
2157     return std::nullopt;
2158   FormatStyle Style = It->second;
2159   Style.StyleSet = *this;
2160   return Style;
2161 }
2162 
2163 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
2164   assert(Style.Language != LK_None &&
2165          "Cannot add a style for LK_None to a StyleSet");
2166   assert(
2167       !Style.StyleSet.Styles &&
2168       "Cannot add a style associated with an existing StyleSet to a StyleSet");
2169   if (!Styles)
2170     Styles = std::make_shared<MapType>();
2171   (*Styles)[Style.Language] = std::move(Style);
2172 }
2173 
2174 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
2175 
2176 std::optional<FormatStyle>
2177 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
2178   return StyleSet.Get(Language);
2179 }
2180 
2181 namespace {
2182 
2183 class ParensRemover : public TokenAnalyzer {
2184 public:
2185   ParensRemover(const Environment &Env, const FormatStyle &Style)
2186       : TokenAnalyzer(Env, Style) {}
2187 
2188   std::pair<tooling::Replacements, unsigned>
2189   analyze(TokenAnnotator &Annotator,
2190           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2191           FormatTokenLexer &Tokens) override {
2192     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2193     tooling::Replacements Result;
2194     removeParens(AnnotatedLines, Result);
2195     return {Result, 0};
2196   }
2197 
2198 private:
2199   void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2200                     tooling::Replacements &Result) {
2201     const auto &SourceMgr = Env.getSourceManager();
2202     for (auto *Line : Lines) {
2203       if (!Line->Children.empty())
2204         removeParens(Line->Children, Result);
2205       if (!Line->Affected)
2206         continue;
2207       for (const auto *Token = Line->First; Token && !Token->Finalized;
2208            Token = Token->Next) {
2209         if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2210           continue;
2211         auto *Next = Token->Next;
2212         assert(Next && Next->isNot(tok::eof));
2213         SourceLocation Start;
2214         if (Next->NewlinesBefore == 0) {
2215           Start = Token->Tok.getLocation();
2216           Next->WhitespaceRange = Token->WhitespaceRange;
2217         } else {
2218           Start = Token->WhitespaceRange.getBegin();
2219         }
2220         const auto &Range =
2221             CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2222         cantFail(Result.add(tooling::Replacement(SourceMgr, Range, " ")));
2223       }
2224     }
2225   }
2226 };
2227 
2228 class BracesInserter : public TokenAnalyzer {
2229 public:
2230   BracesInserter(const Environment &Env, const FormatStyle &Style)
2231       : TokenAnalyzer(Env, Style) {}
2232 
2233   std::pair<tooling::Replacements, unsigned>
2234   analyze(TokenAnnotator &Annotator,
2235           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2236           FormatTokenLexer &Tokens) override {
2237     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2238     tooling::Replacements Result;
2239     insertBraces(AnnotatedLines, Result);
2240     return {Result, 0};
2241   }
2242 
2243 private:
2244   void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2245                     tooling::Replacements &Result) {
2246     const auto &SourceMgr = Env.getSourceManager();
2247     int OpeningBraceSurplus = 0;
2248     for (AnnotatedLine *Line : Lines) {
2249       if (!Line->Children.empty())
2250         insertBraces(Line->Children, Result);
2251       if (!Line->Affected && OpeningBraceSurplus == 0)
2252         continue;
2253       for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2254            Token = Token->Next) {
2255         int BraceCount = Token->BraceCount;
2256         if (BraceCount == 0)
2257           continue;
2258         std::string Brace;
2259         if (BraceCount < 0) {
2260           assert(BraceCount == -1);
2261           if (!Line->Affected)
2262             break;
2263           Brace = Token->is(tok::comment) ? "\n{" : "{";
2264           ++OpeningBraceSurplus;
2265         } else {
2266           if (OpeningBraceSurplus == 0)
2267             break;
2268           if (OpeningBraceSurplus < BraceCount)
2269             BraceCount = OpeningBraceSurplus;
2270           Brace = '\n' + std::string(BraceCount, '}');
2271           OpeningBraceSurplus -= BraceCount;
2272         }
2273         Token->BraceCount = 0;
2274         const auto Start = Token->Tok.getEndLoc();
2275         cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
2276       }
2277     }
2278     assert(OpeningBraceSurplus == 0);
2279   }
2280 };
2281 
2282 class BracesRemover : public TokenAnalyzer {
2283 public:
2284   BracesRemover(const Environment &Env, const FormatStyle &Style)
2285       : TokenAnalyzer(Env, Style) {}
2286 
2287   std::pair<tooling::Replacements, unsigned>
2288   analyze(TokenAnnotator &Annotator,
2289           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2290           FormatTokenLexer &Tokens) override {
2291     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2292     tooling::Replacements Result;
2293     removeBraces(AnnotatedLines, Result);
2294     return {Result, 0};
2295   }
2296 
2297 private:
2298   void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2299                     tooling::Replacements &Result) {
2300     const auto &SourceMgr = Env.getSourceManager();
2301     const auto *End = Lines.end();
2302     for (const auto *I = Lines.begin(); I != End; ++I) {
2303       const auto &Line = *I;
2304       if (!Line->Children.empty())
2305         removeBraces(Line->Children, Result);
2306       if (!Line->Affected)
2307         continue;
2308       const auto *NextLine = I + 1 == End ? nullptr : I[1];
2309       for (const auto *Token = Line->First; Token && !Token->Finalized;
2310            Token = Token->Next) {
2311         if (!Token->Optional)
2312           continue;
2313         if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2314           continue;
2315         auto *Next = Token->Next;
2316         assert(Next || Token == Line->Last);
2317         if (!Next && NextLine)
2318           Next = NextLine->First;
2319         SourceLocation Start;
2320         if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2321           Start = Token->Tok.getLocation();
2322           Next->WhitespaceRange = Token->WhitespaceRange;
2323         } else {
2324           Start = Token->WhitespaceRange.getBegin();
2325         }
2326         const auto &Range =
2327             CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2328         cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2329       }
2330     }
2331   }
2332 };
2333 
2334 class SemiRemover : public TokenAnalyzer {
2335 public:
2336   SemiRemover(const Environment &Env, const FormatStyle &Style)
2337       : TokenAnalyzer(Env, Style) {}
2338 
2339   std::pair<tooling::Replacements, unsigned>
2340   analyze(TokenAnnotator &Annotator,
2341           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2342           FormatTokenLexer &Tokens) override {
2343     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2344     tooling::Replacements Result;
2345     removeSemi(Annotator, AnnotatedLines, Result);
2346     return {Result, 0};
2347   }
2348 
2349 private:
2350   void removeSemi(TokenAnnotator &Annotator,
2351                   SmallVectorImpl<AnnotatedLine *> &Lines,
2352                   tooling::Replacements &Result) {
2353     auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {
2354       const auto *Prev = Tok.Previous;
2355       if (!Prev || Prev->isNot(tok::r_brace))
2356         return false;
2357       const auto *LBrace = Prev->MatchingParen;
2358       return LBrace && LBrace->is(TT_FunctionLBrace);
2359     };
2360     const auto &SourceMgr = Env.getSourceManager();
2361     const auto *End = Lines.end();
2362     for (const auto *I = Lines.begin(); I != End; ++I) {
2363       const auto &Line = *I;
2364       if (!Line->Children.empty())
2365         removeSemi(Annotator, Line->Children, Result);
2366       if (!Line->Affected)
2367         continue;
2368       Annotator.calculateFormattingInformation(*Line);
2369       const auto *NextLine = I + 1 == End ? nullptr : I[1];
2370       for (const auto *Token = Line->First; Token && !Token->Finalized;
2371            Token = Token->Next) {
2372         if (Token->isNot(tok::semi) ||
2373             (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2374           continue;
2375         }
2376         auto *Next = Token->Next;
2377         assert(Next || Token == Line->Last);
2378         if (!Next && NextLine)
2379           Next = NextLine->First;
2380         SourceLocation Start;
2381         if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2382           Start = Token->Tok.getLocation();
2383           Next->WhitespaceRange = Token->WhitespaceRange;
2384         } else {
2385           Start = Token->WhitespaceRange.getBegin();
2386         }
2387         const auto &Range =
2388             CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2389         cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
2390       }
2391     }
2392   }
2393 };
2394 
2395 class JavaScriptRequoter : public TokenAnalyzer {
2396 public:
2397   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
2398       : TokenAnalyzer(Env, Style) {}
2399 
2400   std::pair<tooling::Replacements, unsigned>
2401   analyze(TokenAnnotator &Annotator,
2402           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2403           FormatTokenLexer &Tokens) override {
2404     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2405     tooling::Replacements Result;
2406     requoteJSStringLiteral(AnnotatedLines, Result);
2407     return {Result, 0};
2408   }
2409 
2410 private:
2411   // Replaces double/single-quoted string literal as appropriate, re-escaping
2412   // the contents in the process.
2413   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2414                               tooling::Replacements &Result) {
2415     for (AnnotatedLine *Line : Lines) {
2416       requoteJSStringLiteral(Line->Children, Result);
2417       if (!Line->Affected)
2418         continue;
2419       for (FormatToken *FormatTok = Line->First; FormatTok;
2420            FormatTok = FormatTok->Next) {
2421         StringRef Input = FormatTok->TokenText;
2422         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2423             // NB: testing for not starting with a double quote to avoid
2424             // breaking `template strings`.
2425             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
2426              !Input.starts_with("\"")) ||
2427             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
2428              !Input.starts_with("\'"))) {
2429           continue;
2430         }
2431 
2432         // Change start and end quote.
2433         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
2434         SourceLocation Start = FormatTok->Tok.getLocation();
2435         auto Replace = [&](SourceLocation Start, unsigned Length,
2436                            StringRef ReplacementText) {
2437           auto Err = Result.add(tooling::Replacement(
2438               Env.getSourceManager(), Start, Length, ReplacementText));
2439           // FIXME: handle error. For now, print error message and skip the
2440           // replacement for release version.
2441           if (Err) {
2442             llvm::errs() << toString(std::move(Err)) << "\n";
2443             assert(false);
2444           }
2445         };
2446         Replace(Start, 1, IsSingle ? "'" : "\"");
2447         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2448                 IsSingle ? "'" : "\"");
2449 
2450         // Escape internal quotes.
2451         bool Escaped = false;
2452         for (size_t i = 1; i < Input.size() - 1; i++) {
2453           switch (Input[i]) {
2454           case '\\':
2455             if (!Escaped && i + 1 < Input.size() &&
2456                 ((IsSingle && Input[i + 1] == '"') ||
2457                  (!IsSingle && Input[i + 1] == '\''))) {
2458               // Remove this \, it's escaping a " or ' that no longer needs
2459               // escaping
2460               Replace(Start.getLocWithOffset(i), 1, "");
2461               continue;
2462             }
2463             Escaped = !Escaped;
2464             break;
2465           case '\"':
2466           case '\'':
2467             if (!Escaped && IsSingle == (Input[i] == '\'')) {
2468               // Escape the quote.
2469               Replace(Start.getLocWithOffset(i), 0, "\\");
2470             }
2471             Escaped = false;
2472             break;
2473           default:
2474             Escaped = false;
2475             break;
2476           }
2477         }
2478       }
2479     }
2480   }
2481 };
2482 
2483 class Formatter : public TokenAnalyzer {
2484 public:
2485   Formatter(const Environment &Env, const FormatStyle &Style,
2486             FormattingAttemptStatus *Status)
2487       : TokenAnalyzer(Env, Style), Status(Status) {}
2488 
2489   std::pair<tooling::Replacements, unsigned>
2490   analyze(TokenAnnotator &Annotator,
2491           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2492           FormatTokenLexer &Tokens) override {
2493     tooling::Replacements Result;
2494     deriveLocalStyle(AnnotatedLines);
2495     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2496     for (AnnotatedLine *Line : AnnotatedLines)
2497       Annotator.calculateFormattingInformation(*Line);
2498     Annotator.setCommentLineLevels(AnnotatedLines);
2499 
2500     WhitespaceManager Whitespaces(
2501         Env.getSourceManager(), Style,
2502         Style.LineEnding > FormatStyle::LE_CRLF
2503             ? WhitespaceManager::inputUsesCRLF(
2504                   Env.getSourceManager().getBufferData(Env.getFileID()),
2505                   Style.LineEnding == FormatStyle::LE_DeriveCRLF)
2506             : Style.LineEnding == FormatStyle::LE_CRLF);
2507     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
2508                                   Env.getSourceManager(), Whitespaces, Encoding,
2509                                   BinPackInconclusiveFunctions);
2510     unsigned Penalty =
2511         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
2512                                Tokens.getKeywords(), Env.getSourceManager(),
2513                                Status)
2514             .format(AnnotatedLines, /*DryRun=*/false,
2515                     /*AdditionalIndent=*/0,
2516                     /*FixBadIndentation=*/false,
2517                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
2518                     /*NextStartColumn=*/Env.getNextStartColumn(),
2519                     /*LastStartColumn=*/Env.getLastStartColumn());
2520     for (const auto &R : Whitespaces.generateReplacements())
2521       if (Result.add(R))
2522         return std::make_pair(Result, 0);
2523     return std::make_pair(Result, Penalty);
2524   }
2525 
2526 private:
2527   bool
2528   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2529     for (const AnnotatedLine *Line : Lines) {
2530       if (hasCpp03IncompatibleFormat(Line->Children))
2531         return true;
2532       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2533         if (!Tok->hasWhitespaceBefore()) {
2534           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2535             return true;
2536           if (Tok->is(TT_TemplateCloser) &&
2537               Tok->Previous->is(TT_TemplateCloser)) {
2538             return true;
2539           }
2540         }
2541       }
2542     }
2543     return false;
2544   }
2545 
2546   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2547     int AlignmentDiff = 0;
2548     for (const AnnotatedLine *Line : Lines) {
2549       AlignmentDiff += countVariableAlignments(Line->Children);
2550       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2551         if (Tok->isNot(TT_PointerOrReference))
2552           continue;
2553         // Don't treat space in `void foo() &&` as evidence.
2554         if (const auto *Prev = Tok->getPreviousNonComment()) {
2555           if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2556             if (const auto *Func =
2557                     Prev->MatchingParen->getPreviousNonComment()) {
2558               if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2559                                 TT_OverloadedOperator)) {
2560                 continue;
2561               }
2562             }
2563           }
2564         }
2565         bool SpaceBefore = Tok->hasWhitespaceBefore();
2566         bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2567         if (SpaceBefore && !SpaceAfter)
2568           ++AlignmentDiff;
2569         if (!SpaceBefore && SpaceAfter)
2570           --AlignmentDiff;
2571       }
2572     }
2573     return AlignmentDiff;
2574   }
2575 
2576   void
2577   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2578     bool HasBinPackedFunction = false;
2579     bool HasOnePerLineFunction = false;
2580     for (AnnotatedLine *Line : AnnotatedLines) {
2581       if (!Line->First->Next)
2582         continue;
2583       FormatToken *Tok = Line->First->Next;
2584       while (Tok->Next) {
2585         if (Tok->is(PPK_BinPacked))
2586           HasBinPackedFunction = true;
2587         if (Tok->is(PPK_OnePerLine))
2588           HasOnePerLineFunction = true;
2589 
2590         Tok = Tok->Next;
2591       }
2592     }
2593     if (Style.DerivePointerAlignment) {
2594       const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2595       if (NetRightCount > 0)
2596         Style.PointerAlignment = FormatStyle::PAS_Right;
2597       else if (NetRightCount < 0)
2598         Style.PointerAlignment = FormatStyle::PAS_Left;
2599       Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
2600     }
2601     if (Style.Standard == FormatStyle::LS_Auto) {
2602       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2603                            ? FormatStyle::LS_Latest
2604                            : FormatStyle::LS_Cpp03;
2605     }
2606     BinPackInconclusiveFunctions =
2607         HasBinPackedFunction || !HasOnePerLineFunction;
2608   }
2609 
2610   bool BinPackInconclusiveFunctions;
2611   FormattingAttemptStatus *Status;
2612 };
2613 
2614 /// TrailingCommaInserter inserts trailing commas into container literals.
2615 /// E.g.:
2616 ///     const x = [
2617 ///       1,
2618 ///     ];
2619 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2620 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2621 /// ColumnLimit.
2622 ///
2623 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2624 /// is conceptually incompatible with bin packing.
2625 class TrailingCommaInserter : public TokenAnalyzer {
2626 public:
2627   TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2628       : TokenAnalyzer(Env, Style) {}
2629 
2630   std::pair<tooling::Replacements, unsigned>
2631   analyze(TokenAnnotator &Annotator,
2632           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2633           FormatTokenLexer &Tokens) override {
2634     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2635     tooling::Replacements Result;
2636     insertTrailingCommas(AnnotatedLines, Result);
2637     return {Result, 0};
2638   }
2639 
2640 private:
2641   /// Inserts trailing commas in [] and {} initializers if they wrap over
2642   /// multiple lines.
2643   void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2644                             tooling::Replacements &Result) {
2645     for (AnnotatedLine *Line : Lines) {
2646       insertTrailingCommas(Line->Children, Result);
2647       if (!Line->Affected)
2648         continue;
2649       for (FormatToken *FormatTok = Line->First; FormatTok;
2650            FormatTok = FormatTok->Next) {
2651         if (FormatTok->NewlinesBefore == 0)
2652           continue;
2653         FormatToken *Matching = FormatTok->MatchingParen;
2654         if (!Matching || !FormatTok->getPreviousNonComment())
2655           continue;
2656         if (!(FormatTok->is(tok::r_square) &&
2657               Matching->is(TT_ArrayInitializerLSquare)) &&
2658             !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2659           continue;
2660         }
2661         FormatToken *Prev = FormatTok->getPreviousNonComment();
2662         if (Prev->is(tok::comma) || Prev->is(tok::semi))
2663           continue;
2664         // getEndLoc is not reliably set during re-lexing, use text length
2665         // instead.
2666         SourceLocation Start =
2667             Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2668         // If inserting a comma would push the code over the column limit, skip
2669         // this location - it'd introduce an unstable formatting due to the
2670         // required reflow.
2671         unsigned ColumnNumber =
2672             Env.getSourceManager().getSpellingColumnNumber(Start);
2673         if (ColumnNumber > Style.ColumnLimit)
2674           continue;
2675         // Comma insertions cannot conflict with each other, and this pass has a
2676         // clean set of Replacements, so the operation below cannot fail.
2677         cantFail(Result.add(
2678             tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2679       }
2680     }
2681   }
2682 };
2683 
2684 // This class clean up the erroneous/redundant code around the given ranges in
2685 // file.
2686 class Cleaner : public TokenAnalyzer {
2687 public:
2688   Cleaner(const Environment &Env, const FormatStyle &Style)
2689       : TokenAnalyzer(Env, Style),
2690         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2691 
2692   // FIXME: eliminate unused parameters.
2693   std::pair<tooling::Replacements, unsigned>
2694   analyze(TokenAnnotator &Annotator,
2695           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2696           FormatTokenLexer &Tokens) override {
2697     // FIXME: in the current implementation the granularity of affected range
2698     // is an annotated line. However, this is not sufficient. Furthermore,
2699     // redundant code introduced by replacements does not necessarily
2700     // intercept with ranges of replacements that result in the redundancy.
2701     // To determine if some redundant code is actually introduced by
2702     // replacements(e.g. deletions), we need to come up with a more
2703     // sophisticated way of computing affected ranges.
2704     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2705 
2706     checkEmptyNamespace(AnnotatedLines);
2707 
2708     for (auto *Line : AnnotatedLines)
2709       cleanupLine(Line);
2710 
2711     return {generateFixes(), 0};
2712   }
2713 
2714 private:
2715   void cleanupLine(AnnotatedLine *Line) {
2716     for (auto *Child : Line->Children)
2717       cleanupLine(Child);
2718 
2719     if (Line->Affected) {
2720       cleanupRight(Line->First, tok::comma, tok::comma);
2721       cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2722       cleanupRight(Line->First, tok::l_paren, tok::comma);
2723       cleanupLeft(Line->First, tok::comma, tok::r_paren);
2724       cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2725       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2726       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2727     }
2728   }
2729 
2730   bool containsOnlyComments(const AnnotatedLine &Line) {
2731     for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2732       if (Tok->isNot(tok::comment))
2733         return false;
2734     return true;
2735   }
2736 
2737   // Iterate through all lines and remove any empty (nested) namespaces.
2738   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2739     std::set<unsigned> DeletedLines;
2740     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2741       auto &Line = *AnnotatedLines[i];
2742       if (Line.startsWithNamespace())
2743         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2744     }
2745 
2746     for (auto Line : DeletedLines) {
2747       FormatToken *Tok = AnnotatedLines[Line]->First;
2748       while (Tok) {
2749         deleteToken(Tok);
2750         Tok = Tok->Next;
2751       }
2752     }
2753   }
2754 
2755   // The function checks if the namespace, which starts from \p CurrentLine, and
2756   // its nested namespaces are empty and delete them if they are empty. It also
2757   // sets \p NewLine to the last line checked.
2758   // Returns true if the current namespace is empty.
2759   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2760                            unsigned CurrentLine, unsigned &NewLine,
2761                            std::set<unsigned> &DeletedLines) {
2762     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2763     if (Style.BraceWrapping.AfterNamespace) {
2764       // If the left brace is in a new line, we should consume it first so that
2765       // it does not make the namespace non-empty.
2766       // FIXME: error handling if there is no left brace.
2767       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2768         NewLine = CurrentLine;
2769         return false;
2770       }
2771     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2772       return false;
2773     }
2774     while (++CurrentLine < End) {
2775       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2776         break;
2777 
2778       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2779         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
2780                                  DeletedLines)) {
2781           return false;
2782         }
2783         CurrentLine = NewLine;
2784         continue;
2785       }
2786 
2787       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2788         continue;
2789 
2790       // If there is anything other than comments or nested namespaces in the
2791       // current namespace, the namespace cannot be empty.
2792       NewLine = CurrentLine;
2793       return false;
2794     }
2795 
2796     NewLine = CurrentLine;
2797     if (CurrentLine >= End)
2798       return false;
2799 
2800     // Check if the empty namespace is actually affected by changed ranges.
2801     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2802             AnnotatedLines[InitLine]->First->Tok.getLocation(),
2803             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2804       return false;
2805     }
2806 
2807     for (unsigned i = InitLine; i <= CurrentLine; ++i)
2808       DeletedLines.insert(i);
2809 
2810     return true;
2811   }
2812 
2813   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2814   // of the token in the pair if the left token has \p LK token kind and the
2815   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2816   // is deleted on match; otherwise, the right token is deleted.
2817   template <typename LeftKind, typename RightKind>
2818   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2819                    bool DeleteLeft) {
2820     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
2821       for (auto *Res = Tok.Next; Res; Res = Res->Next) {
2822         if (Res->isNot(tok::comment) &&
2823             DeletedTokens.find(Res) == DeletedTokens.end()) {
2824           return Res;
2825         }
2826       }
2827       return nullptr;
2828     };
2829     for (auto *Left = Start; Left;) {
2830       auto *Right = NextNotDeleted(*Left);
2831       if (!Right)
2832         break;
2833       if (Left->is(LK) && Right->is(RK)) {
2834         deleteToken(DeleteLeft ? Left : Right);
2835         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2836           deleteToken(Tok);
2837         // If the right token is deleted, we should keep the left token
2838         // unchanged and pair it with the new right token.
2839         if (!DeleteLeft)
2840           continue;
2841       }
2842       Left = Right;
2843     }
2844   }
2845 
2846   template <typename LeftKind, typename RightKind>
2847   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2848     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
2849   }
2850 
2851   template <typename LeftKind, typename RightKind>
2852   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2853     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
2854   }
2855 
2856   // Delete the given token.
2857   inline void deleteToken(FormatToken *Tok) {
2858     if (Tok)
2859       DeletedTokens.insert(Tok);
2860   }
2861 
2862   tooling::Replacements generateFixes() {
2863     tooling::Replacements Fixes;
2864     SmallVector<FormatToken *> Tokens;
2865     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2866               std::back_inserter(Tokens));
2867 
2868     // Merge multiple continuous token deletions into one big deletion so that
2869     // the number of replacements can be reduced. This makes computing affected
2870     // ranges more efficient when we run reformat on the changed code.
2871     unsigned Idx = 0;
2872     while (Idx < Tokens.size()) {
2873       unsigned St = Idx, End = Idx;
2874       while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2875         ++End;
2876       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2877                                               Tokens[End]->Tok.getEndLoc());
2878       auto Err =
2879           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2880       // FIXME: better error handling. for now just print error message and skip
2881       // for the release version.
2882       if (Err) {
2883         llvm::errs() << toString(std::move(Err)) << "\n";
2884         assert(false && "Fixes must not conflict!");
2885       }
2886       Idx = End + 1;
2887     }
2888 
2889     return Fixes;
2890   }
2891 
2892   // Class for less-than inequality comparason for the set `RedundantTokens`.
2893   // We store tokens in the order they appear in the translation unit so that
2894   // we do not need to sort them in `generateFixes()`.
2895   struct FormatTokenLess {
2896     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2897 
2898     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2899       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2900                                           RHS->Tok.getLocation());
2901     }
2902     const SourceManager &SM;
2903   };
2904 
2905   // Tokens to be deleted.
2906   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2907 };
2908 
2909 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2910 public:
2911   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2912       : TokenAnalyzer(Env, Style), IsObjC(false) {}
2913 
2914   std::pair<tooling::Replacements, unsigned>
2915   analyze(TokenAnnotator &Annotator,
2916           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2917           FormatTokenLexer &Tokens) override {
2918     assert(Style.Language == FormatStyle::LK_Cpp);
2919     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2920                          Tokens.getKeywords());
2921     tooling::Replacements Result;
2922     return {Result, 0};
2923   }
2924 
2925   bool isObjC() { return IsObjC; }
2926 
2927 private:
2928   static bool
2929   guessIsObjC(const SourceManager &SourceManager,
2930               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2931               const AdditionalKeywords &Keywords) {
2932     // Keep this array sorted, since we are binary searching over it.
2933     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2934         "CGFloat",
2935         "CGPoint",
2936         "CGPointMake",
2937         "CGPointZero",
2938         "CGRect",
2939         "CGRectEdge",
2940         "CGRectInfinite",
2941         "CGRectMake",
2942         "CGRectNull",
2943         "CGRectZero",
2944         "CGSize",
2945         "CGSizeMake",
2946         "CGVector",
2947         "CGVectorMake",
2948         "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
2949         "FOUNDATION_EXTERN",
2950         "NSAffineTransform",
2951         "NSArray",
2952         "NSAttributedString",
2953         "NSBlockOperation",
2954         "NSBundle",
2955         "NSCache",
2956         "NSCalendar",
2957         "NSCharacterSet",
2958         "NSCountedSet",
2959         "NSData",
2960         "NSDataDetector",
2961         "NSDecimal",
2962         "NSDecimalNumber",
2963         "NSDictionary",
2964         "NSEdgeInsets",
2965         "NSError",
2966         "NSErrorDomain",
2967         "NSHashTable",
2968         "NSIndexPath",
2969         "NSIndexSet",
2970         "NSInteger",
2971         "NSInvocationOperation",
2972         "NSLocale",
2973         "NSMapTable",
2974         "NSMutableArray",
2975         "NSMutableAttributedString",
2976         "NSMutableCharacterSet",
2977         "NSMutableData",
2978         "NSMutableDictionary",
2979         "NSMutableIndexSet",
2980         "NSMutableOrderedSet",
2981         "NSMutableSet",
2982         "NSMutableString",
2983         "NSNumber",
2984         "NSNumberFormatter",
2985         "NSObject",
2986         "NSOperation",
2987         "NSOperationQueue",
2988         "NSOperationQueuePriority",
2989         "NSOrderedSet",
2990         "NSPoint",
2991         "NSPointerArray",
2992         "NSQualityOfService",
2993         "NSRange",
2994         "NSRect",
2995         "NSRegularExpression",
2996         "NSSet",
2997         "NSSize",
2998         "NSString",
2999         "NSTimeZone",
3000         "NSUInteger",
3001         "NSURL",
3002         "NSURLComponents",
3003         "NSURLQueryItem",
3004         "NSUUID",
3005         "NSValue",
3006         "NS_ASSUME_NONNULL_BEGIN",
3007         "UIImage",
3008         "UIView",
3009     };
3010 
3011     for (auto *Line : AnnotatedLines) {
3012       if (Line->First && (Line->First->TokenText.starts_with("#") ||
3013                           Line->First->TokenText == "__pragma" ||
3014                           Line->First->TokenText == "_Pragma")) {
3015         continue;
3016       }
3017       for (const FormatToken *FormatTok = Line->First; FormatTok;
3018            FormatTok = FormatTok->Next) {
3019         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3020              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3021               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3022                                  tok::l_brace))) ||
3023             (FormatTok->Tok.isAnyIdentifier() &&
3024              std::binary_search(std::begin(FoundationIdentifiers),
3025                                 std::end(FoundationIdentifiers),
3026                                 FormatTok->TokenText)) ||
3027             FormatTok->is(TT_ObjCStringLiteral) ||
3028             FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3029                                Keywords.kw_NS_ERROR_ENUM,
3030                                Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3031                                TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3032                                TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3033                                TT_ObjCProperty)) {
3034           LLVM_DEBUG(llvm::dbgs()
3035                      << "Detected ObjC at location "
3036                      << FormatTok->Tok.getLocation().printToString(
3037                             SourceManager)
3038                      << " token: " << FormatTok->TokenText << " token type: "
3039                      << getTokenTypeName(FormatTok->getType()) << "\n");
3040           return true;
3041         }
3042       }
3043       if (guessIsObjC(SourceManager, Line->Children, Keywords))
3044         return true;
3045     }
3046     return false;
3047   }
3048 
3049   bool IsObjC;
3050 };
3051 
3052 struct IncludeDirective {
3053   StringRef Filename;
3054   StringRef Text;
3055   unsigned Offset;
3056   int Category;
3057   int Priority;
3058 };
3059 
3060 struct JavaImportDirective {
3061   StringRef Identifier;
3062   StringRef Text;
3063   unsigned Offset;
3064   SmallVector<StringRef> AssociatedCommentLines;
3065   bool IsStatic;
3066 };
3067 
3068 } // end anonymous namespace
3069 
3070 // Determines whether 'Ranges' intersects with ('Start', 'End').
3071 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
3072                          unsigned End) {
3073   for (const auto &Range : Ranges) {
3074     if (Range.getOffset() < End &&
3075         Range.getOffset() + Range.getLength() > Start) {
3076       return true;
3077     }
3078   }
3079   return false;
3080 }
3081 
3082 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
3083 // before sorting/deduplicating. Index is the index of the include under the
3084 // cursor in the original set of includes. If this include has duplicates, it is
3085 // the index of the first of the duplicates as the others are going to be
3086 // removed. OffsetToEOL describes the cursor's position relative to the end of
3087 // its current line.
3088 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
3089 static std::pair<unsigned, unsigned>
3090 FindCursorIndex(const ArrayRef<IncludeDirective> &Includes,
3091                 const ArrayRef<unsigned> &Indices, unsigned Cursor) {
3092   unsigned CursorIndex = UINT_MAX;
3093   unsigned OffsetToEOL = 0;
3094   for (int i = 0, e = Includes.size(); i != e; ++i) {
3095     unsigned Start = Includes[Indices[i]].Offset;
3096     unsigned End = Start + Includes[Indices[i]].Text.size();
3097     if (!(Cursor >= Start && Cursor < End))
3098       continue;
3099     CursorIndex = Indices[i];
3100     OffsetToEOL = End - Cursor;
3101     // Put the cursor on the only remaining #include among the duplicate
3102     // #includes.
3103     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
3104       CursorIndex = i;
3105     break;
3106   }
3107   return std::make_pair(CursorIndex, OffsetToEOL);
3108 }
3109 
3110 // Replace all "\r\n" with "\n".
3111 std::string replaceCRLF(const std::string &Code) {
3112   std::string NewCode;
3113   size_t Pos = 0, LastPos = 0;
3114 
3115   do {
3116     Pos = Code.find("\r\n", LastPos);
3117     if (Pos == LastPos) {
3118       ++LastPos;
3119       continue;
3120     }
3121     if (Pos == std::string::npos) {
3122       NewCode += Code.substr(LastPos);
3123       break;
3124     }
3125     NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
3126     LastPos = Pos + 2;
3127   } while (Pos != std::string::npos);
3128 
3129   return NewCode;
3130 }
3131 
3132 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
3133 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
3134 // source order.
3135 // #include directives with the same text will be deduplicated, and only the
3136 // first #include in the duplicate #includes remains. If the `Cursor` is
3137 // provided and put on a deleted #include, it will be moved to the remaining
3138 // #include in the duplicate #includes.
3139 static void sortCppIncludes(const FormatStyle &Style,
3140                             const ArrayRef<IncludeDirective> &Includes,
3141                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
3142                             StringRef Code, tooling::Replacements &Replaces,
3143                             unsigned *Cursor) {
3144   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
3145   const unsigned IncludesBeginOffset = Includes.front().Offset;
3146   const unsigned IncludesEndOffset =
3147       Includes.back().Offset + Includes.back().Text.size();
3148   const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3149   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3150     return;
3151   SmallVector<unsigned, 16> Indices =
3152       llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3153 
3154   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
3155     stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3156       const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3157       const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3158       return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
3159                       Includes[LHSI].Filename) <
3160              std::tie(Includes[RHSI].Priority, RHSFilenameLower,
3161                       Includes[RHSI].Filename);
3162     });
3163   } else {
3164     stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3165       return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
3166              std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
3167     });
3168   }
3169 
3170   // The index of the include on which the cursor will be put after
3171   // sorting/deduplicating.
3172   unsigned CursorIndex;
3173   // The offset from cursor to the end of line.
3174   unsigned CursorToEOLOffset;
3175   if (Cursor) {
3176     std::tie(CursorIndex, CursorToEOLOffset) =
3177         FindCursorIndex(Includes, Indices, *Cursor);
3178   }
3179 
3180   // Deduplicate #includes.
3181   Indices.erase(std::unique(Indices.begin(), Indices.end(),
3182                             [&](unsigned LHSI, unsigned RHSI) {
3183                               return Includes[LHSI].Text.trim() ==
3184                                      Includes[RHSI].Text.trim();
3185                             }),
3186                 Indices.end());
3187 
3188   int CurrentCategory = Includes.front().Category;
3189 
3190   // If the #includes are out of order, we generate a single replacement fixing
3191   // the entire block. Otherwise, no replacement is generated.
3192   // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
3193   // enough as additional newlines might be added or removed across #include
3194   // blocks. This we handle below by generating the updated #include blocks and
3195   // comparing it to the original.
3196   if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3197       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) {
3198     return;
3199   }
3200 
3201   const auto OldCursor = Cursor ? *Cursor : 0;
3202   std::string result;
3203   for (unsigned Index : Indices) {
3204     if (!result.empty()) {
3205       result += "\n";
3206       if (Style.IncludeStyle.IncludeBlocks ==
3207               tooling::IncludeStyle::IBS_Regroup &&
3208           CurrentCategory != Includes[Index].Category) {
3209         result += "\n";
3210       }
3211     }
3212     result += Includes[Index].Text;
3213     if (Cursor && CursorIndex == Index)
3214       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3215     CurrentCategory = Includes[Index].Category;
3216   }
3217 
3218   if (Cursor && *Cursor >= IncludesEndOffset)
3219     *Cursor += result.size() - IncludesBlockSize;
3220 
3221   // If the #includes are out of order, we generate a single replacement fixing
3222   // the entire range of blocks. Otherwise, no replacement is generated.
3223   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3224                                  IncludesBeginOffset, IncludesBlockSize)))) {
3225     if (Cursor)
3226       *Cursor = OldCursor;
3227     return;
3228   }
3229 
3230   auto Err = Replaces.add(tooling::Replacement(
3231       FileName, Includes.front().Offset, IncludesBlockSize, result));
3232   // FIXME: better error handling. For now, just skip the replacement for the
3233   // release version.
3234   if (Err) {
3235     llvm::errs() << toString(std::move(Err)) << "\n";
3236     assert(false);
3237   }
3238 }
3239 
3240 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
3241                                       ArrayRef<tooling::Range> Ranges,
3242                                       StringRef FileName,
3243                                       tooling::Replacements &Replaces,
3244                                       unsigned *Cursor) {
3245   unsigned Prev = llvm::StringSwitch<size_t>(Code)
3246                       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
3247                       .Default(0);
3248   unsigned SearchFrom = 0;
3249   SmallVector<StringRef, 4> Matches;
3250   SmallVector<IncludeDirective, 16> IncludesInBlock;
3251 
3252   // In compiled files, consider the first #include to be the main #include of
3253   // the file if it is not a system #include. This ensures that the header
3254   // doesn't have hidden dependencies
3255   // (http://llvm.org/docs/CodingStandards.html#include-style).
3256   //
3257   // FIXME: Do some validation, e.g. edit distance of the base name, to fix
3258   // cases where the first #include is unlikely to be the main header.
3259   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
3260   bool FirstIncludeBlock = true;
3261   bool MainIncludeFound = false;
3262   bool FormattingOff = false;
3263 
3264   // '[' must be the first and '-' the last character inside [...].
3265   llvm::Regex RawStringRegex(
3266       "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3267   SmallVector<StringRef, 2> RawStringMatches;
3268   std::string RawStringTermination = ")\"";
3269 
3270   for (const auto Size = Code.size(); SearchFrom < Size;) {
3271     size_t Pos = SearchFrom;
3272     if (Code[SearchFrom] != '\n') {
3273       do { // Search for the first newline while skipping line splices.
3274         ++Pos;
3275         Pos = Code.find('\n', Pos);
3276       } while (Pos != StringRef::npos && Code[Pos - 1] == '\\');
3277     }
3278 
3279     StringRef Line =
3280         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3281 
3282     StringRef Trimmed = Line.trim();
3283 
3284     // #includes inside raw string literals need to be ignored.
3285     // or we will sort the contents of the string.
3286     // Skip past until we think we are at the rawstring literal close.
3287     if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3288       std::string CharSequence = RawStringMatches[1].str();
3289       RawStringTermination = ")" + CharSequence + "\"";
3290       FormattingOff = true;
3291     }
3292 
3293     if (Trimmed.contains(RawStringTermination))
3294       FormattingOff = false;
3295 
3296     bool IsBlockComment = false;
3297 
3298     if (isClangFormatOff(Trimmed)) {
3299       FormattingOff = true;
3300     } else if (isClangFormatOn(Trimmed)) {
3301       FormattingOff = false;
3302     } else if (Trimmed.starts_with("/*")) {
3303       IsBlockComment = true;
3304       Pos = Code.find("*/", SearchFrom + 2);
3305     }
3306 
3307     const bool EmptyLineSkipped =
3308         Trimmed.empty() &&
3309         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
3310          Style.IncludeStyle.IncludeBlocks ==
3311              tooling::IncludeStyle::IBS_Regroup);
3312 
3313     bool MergeWithNextLine = Trimmed.ends_with("\\");
3314     if (!FormattingOff && !MergeWithNextLine) {
3315       if (!IsBlockComment &&
3316           tooling::HeaderIncludes::IncludeRegex.match(Trimmed, &Matches)) {
3317         StringRef IncludeName = Matches[2];
3318         if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {
3319           // #include with a start of a block comment, but without the end.
3320           // Need to keep all the lines until the end of the comment together.
3321           // FIXME: This is somehow simplified check that probably does not work
3322           // correctly if there are multiple comments on a line.
3323           Pos = Code.find("*/", SearchFrom);
3324           Line = Code.substr(
3325               Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3326         }
3327         int Category = Categories.getIncludePriority(
3328             IncludeName,
3329             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
3330         int Priority = Categories.getSortIncludePriority(
3331             IncludeName, !MainIncludeFound && FirstIncludeBlock);
3332         if (Category == 0)
3333           MainIncludeFound = true;
3334         IncludesInBlock.push_back(
3335             {IncludeName, Line, Prev, Category, Priority});
3336       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3337         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
3338                         Replaces, Cursor);
3339         IncludesInBlock.clear();
3340         if (Trimmed.starts_with("#pragma hdrstop")) // Precompiled headers.
3341           FirstIncludeBlock = true;
3342         else
3343           FirstIncludeBlock = false;
3344       }
3345     }
3346     if (Pos == StringRef::npos || Pos + 1 == Code.size())
3347       break;
3348 
3349     if (!MergeWithNextLine)
3350       Prev = Pos + 1;
3351     SearchFrom = Pos + 1;
3352   }
3353   if (!IncludesInBlock.empty()) {
3354     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
3355                     Cursor);
3356   }
3357   return Replaces;
3358 }
3359 
3360 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
3361 // if the import does not match any given groups.
3362 static unsigned findJavaImportGroup(const FormatStyle &Style,
3363                                     StringRef ImportIdentifier) {
3364   unsigned LongestMatchIndex = UINT_MAX;
3365   unsigned LongestMatchLength = 0;
3366   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3367     const std::string &GroupPrefix = Style.JavaImportGroups[I];
3368     if (ImportIdentifier.starts_with(GroupPrefix) &&
3369         GroupPrefix.length() > LongestMatchLength) {
3370       LongestMatchIndex = I;
3371       LongestMatchLength = GroupPrefix.length();
3372     }
3373   }
3374   return LongestMatchIndex;
3375 }
3376 
3377 // Sorts and deduplicates a block of includes given by 'Imports' based on
3378 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
3379 // Import declarations with the same text will be deduplicated. Between each
3380 // import group, a newline is inserted, and within each import group, a
3381 // lexicographic sort based on ASCII value is performed.
3382 static void sortJavaImports(const FormatStyle &Style,
3383                             const ArrayRef<JavaImportDirective> &Imports,
3384                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
3385                             StringRef Code, tooling::Replacements &Replaces) {
3386   unsigned ImportsBeginOffset = Imports.front().Offset;
3387   unsigned ImportsEndOffset =
3388       Imports.back().Offset + Imports.back().Text.size();
3389   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3390   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3391     return;
3392 
3393   SmallVector<unsigned, 16> Indices =
3394       llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3395   SmallVector<unsigned, 16> JavaImportGroups;
3396   JavaImportGroups.reserve(Imports.size());
3397   for (const JavaImportDirective &Import : Imports)
3398     JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
3399 
3400   bool StaticImportAfterNormalImport =
3401       Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
3402   sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
3403     // Negating IsStatic to push static imports above non-static imports.
3404     return std::make_tuple(!Imports[LHSI].IsStatic ^
3405                                StaticImportAfterNormalImport,
3406                            JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
3407            std::make_tuple(!Imports[RHSI].IsStatic ^
3408                                StaticImportAfterNormalImport,
3409                            JavaImportGroups[RHSI], Imports[RHSI].Identifier);
3410   });
3411 
3412   // Deduplicate imports.
3413   Indices.erase(std::unique(Indices.begin(), Indices.end(),
3414                             [&](unsigned LHSI, unsigned RHSI) {
3415                               return Imports[LHSI].Text == Imports[RHSI].Text;
3416                             }),
3417                 Indices.end());
3418 
3419   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3420   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
3421 
3422   std::string result;
3423   for (unsigned Index : Indices) {
3424     if (!result.empty()) {
3425       result += "\n";
3426       if (CurrentIsStatic != Imports[Index].IsStatic ||
3427           CurrentImportGroup != JavaImportGroups[Index]) {
3428         result += "\n";
3429       }
3430     }
3431     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
3432       result += CommentLine;
3433       result += "\n";
3434     }
3435     result += Imports[Index].Text;
3436     CurrentIsStatic = Imports[Index].IsStatic;
3437     CurrentImportGroup = JavaImportGroups[Index];
3438   }
3439 
3440   // If the imports are out of order, we generate a single replacement fixing
3441   // the entire block. Otherwise, no replacement is generated.
3442   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
3443                                  Imports.front().Offset, ImportsBlockSize)))) {
3444     return;
3445   }
3446 
3447   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
3448                                                ImportsBlockSize, result));
3449   // FIXME: better error handling. For now, just skip the replacement for the
3450   // release version.
3451   if (Err) {
3452     llvm::errs() << toString(std::move(Err)) << "\n";
3453     assert(false);
3454   }
3455 }
3456 
3457 namespace {
3458 
3459 const char JavaImportRegexPattern[] =
3460     "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3461 
3462 } // anonymous namespace
3463 
3464 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
3465                                       ArrayRef<tooling::Range> Ranges,
3466                                       StringRef FileName,
3467                                       tooling::Replacements &Replaces) {
3468   unsigned Prev = 0;
3469   unsigned SearchFrom = 0;
3470   llvm::Regex ImportRegex(JavaImportRegexPattern);
3471   SmallVector<StringRef, 4> Matches;
3472   SmallVector<JavaImportDirective, 16> ImportsInBlock;
3473   SmallVector<StringRef> AssociatedCommentLines;
3474 
3475   bool FormattingOff = false;
3476 
3477   for (;;) {
3478     auto Pos = Code.find('\n', SearchFrom);
3479     StringRef Line =
3480         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3481 
3482     StringRef Trimmed = Line.trim();
3483     if (isClangFormatOff(Trimmed))
3484       FormattingOff = true;
3485     else if (isClangFormatOn(Trimmed))
3486       FormattingOff = false;
3487 
3488     if (ImportRegex.match(Line, &Matches)) {
3489       if (FormattingOff) {
3490         // If at least one import line has formatting turned off, turn off
3491         // formatting entirely.
3492         return Replaces;
3493       }
3494       StringRef Static = Matches[1];
3495       StringRef Identifier = Matches[2];
3496       bool IsStatic = false;
3497       if (Static.contains("static"))
3498         IsStatic = true;
3499       ImportsInBlock.push_back(
3500           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
3501       AssociatedCommentLines.clear();
3502     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3503       // Associating comments within the imports with the nearest import below
3504       AssociatedCommentLines.push_back(Line);
3505     }
3506     Prev = Pos + 1;
3507     if (Pos == StringRef::npos || Pos + 1 == Code.size())
3508       break;
3509     SearchFrom = Pos + 1;
3510   }
3511   if (!ImportsInBlock.empty())
3512     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
3513   return Replaces;
3514 }
3515 
3516 bool isMpegTS(StringRef Code) {
3517   // MPEG transport streams use the ".ts" file extension. clang-format should
3518   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
3519   // 189 bytes - detect that and return.
3520   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3521 }
3522 
3523 bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); }
3524 
3525 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
3526                                    ArrayRef<tooling::Range> Ranges,
3527                                    StringRef FileName, unsigned *Cursor) {
3528   tooling::Replacements Replaces;
3529   if (!Style.SortIncludes || Style.DisableFormat)
3530     return Replaces;
3531   if (isLikelyXml(Code))
3532     return Replaces;
3533   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
3534       isMpegTS(Code)) {
3535     return Replaces;
3536   }
3537   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
3538     return sortJavaScriptImports(Style, Code, Ranges, FileName);
3539   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
3540     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
3541   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
3542   return Replaces;
3543 }
3544 
3545 template <typename T>
3546 static Expected<tooling::Replacements>
3547 processReplacements(T ProcessFunc, StringRef Code,
3548                     const tooling::Replacements &Replaces,
3549                     const FormatStyle &Style) {
3550   if (Replaces.empty())
3551     return tooling::Replacements();
3552 
3553   auto NewCode = applyAllReplacements(Code, Replaces);
3554   if (!NewCode)
3555     return NewCode.takeError();
3556   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
3557   StringRef FileName = Replaces.begin()->getFilePath();
3558 
3559   tooling::Replacements FormatReplaces =
3560       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
3561 
3562   return Replaces.merge(FormatReplaces);
3563 }
3564 
3565 Expected<tooling::Replacements>
3566 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
3567                    const FormatStyle &Style) {
3568   // We need to use lambda function here since there are two versions of
3569   // `sortIncludes`.
3570   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
3571                          std::vector<tooling::Range> Ranges,
3572                          StringRef FileName) -> tooling::Replacements {
3573     return sortIncludes(Style, Code, Ranges, FileName);
3574   };
3575   auto SortedReplaces =
3576       processReplacements(SortIncludes, Code, Replaces, Style);
3577   if (!SortedReplaces)
3578     return SortedReplaces.takeError();
3579 
3580   // We need to use lambda function here since there are two versions of
3581   // `reformat`.
3582   auto Reformat = [](const FormatStyle &Style, StringRef Code,
3583                      std::vector<tooling::Range> Ranges,
3584                      StringRef FileName) -> tooling::Replacements {
3585     return reformat(Style, Code, Ranges, FileName);
3586   };
3587   return processReplacements(Reformat, Code, *SortedReplaces, Style);
3588 }
3589 
3590 namespace {
3591 
3592 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
3593   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
3594          tooling::HeaderIncludes::IncludeRegex.match(
3595              Replace.getReplacementText());
3596 }
3597 
3598 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3599   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
3600 }
3601 
3602 // FIXME: insert empty lines between newly created blocks.
3603 tooling::Replacements
3604 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3605                         const FormatStyle &Style) {
3606   if (!Style.isCpp())
3607     return Replaces;
3608 
3609   tooling::Replacements HeaderInsertions;
3610   std::set<StringRef> HeadersToDelete;
3611   tooling::Replacements Result;
3612   for (const auto &R : Replaces) {
3613     if (isHeaderInsertion(R)) {
3614       // Replacements from \p Replaces must be conflict-free already, so we can
3615       // simply consume the error.
3616       consumeError(HeaderInsertions.add(R));
3617     } else if (isHeaderDeletion(R)) {
3618       HeadersToDelete.insert(R.getReplacementText());
3619     } else if (R.getOffset() == UINT_MAX) {
3620       llvm::errs() << "Insertions other than header #include insertion are "
3621                       "not supported! "
3622                    << R.getReplacementText() << "\n";
3623     } else {
3624       consumeError(Result.add(R));
3625     }
3626   }
3627   if (HeaderInsertions.empty() && HeadersToDelete.empty())
3628     return Replaces;
3629 
3630   StringRef FileName = Replaces.begin()->getFilePath();
3631   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
3632 
3633   for (const auto &Header : HeadersToDelete) {
3634     tooling::Replacements Replaces =
3635         Includes.remove(Header.trim("\"<>"), Header.starts_with("<"));
3636     for (const auto &R : Replaces) {
3637       auto Err = Result.add(R);
3638       if (Err) {
3639         // Ignore the deletion on conflict.
3640         llvm::errs() << "Failed to add header deletion replacement for "
3641                      << Header << ": " << toString(std::move(Err)) << "\n";
3642       }
3643     }
3644   }
3645 
3646   SmallVector<StringRef, 4> Matches;
3647   for (const auto &R : HeaderInsertions) {
3648     auto IncludeDirective = R.getReplacementText();
3649     bool Matched =
3650         tooling::HeaderIncludes::IncludeRegex.match(IncludeDirective, &Matches);
3651     assert(Matched && "Header insertion replacement must have replacement text "
3652                       "'#include ...'");
3653     (void)Matched;
3654     auto IncludeName = Matches[2];
3655     auto Replace =
3656         Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"),
3657                         tooling::IncludeDirective::Include);
3658     if (Replace) {
3659       auto Err = Result.add(*Replace);
3660       if (Err) {
3661         consumeError(std::move(Err));
3662         unsigned NewOffset =
3663             Result.getShiftedCodePosition(Replace->getOffset());
3664         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3665                                             Replace->getReplacementText());
3666         Result = Result.merge(tooling::Replacements(Shifted));
3667       }
3668     }
3669   }
3670   return Result;
3671 }
3672 
3673 } // anonymous namespace
3674 
3675 Expected<tooling::Replacements>
3676 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
3677                           const FormatStyle &Style) {
3678   // We need to use lambda function here since there are two versions of
3679   // `cleanup`.
3680   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3681                     ArrayRef<tooling::Range> Ranges,
3682                     StringRef FileName) -> tooling::Replacements {
3683     return cleanup(Style, Code, Ranges, FileName);
3684   };
3685   // Make header insertion replacements insert new headers into correct blocks.
3686   tooling::Replacements NewReplaces =
3687       fixCppIncludeInsertions(Code, Replaces, Style);
3688   return cantFail(processReplacements(Cleanup, Code, NewReplaces, Style));
3689 }
3690 
3691 namespace internal {
3692 std::pair<tooling::Replacements, unsigned>
3693 reformat(const FormatStyle &Style, StringRef Code,
3694          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
3695          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3696          FormattingAttemptStatus *Status) {
3697   FormatStyle Expanded = Style;
3698   expandPresetsBraceWrapping(Expanded);
3699   expandPresetsSpaceBeforeParens(Expanded);
3700   expandPresetsSpacesInParens(Expanded);
3701   Expanded.InsertBraces = false;
3702   Expanded.RemoveBracesLLVM = false;
3703   Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
3704   Expanded.RemoveSemicolon = false;
3705   switch (Expanded.RequiresClausePosition) {
3706   case FormatStyle::RCPS_SingleLine:
3707   case FormatStyle::RCPS_WithPreceding:
3708     Expanded.IndentRequiresClause = false;
3709     break;
3710   default:
3711     break;
3712   }
3713 
3714   if (Expanded.DisableFormat)
3715     return {tooling::Replacements(), 0};
3716   if (isLikelyXml(Code))
3717     return {tooling::Replacements(), 0};
3718   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
3719     return {tooling::Replacements(), 0};
3720 
3721   // JSON only needs the formatting passing.
3722   if (Style.isJson()) {
3723     std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
3724     auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3725                                  NextStartColumn, LastStartColumn);
3726     if (!Env)
3727       return {};
3728     // Perform the actual formatting pass.
3729     tooling::Replacements Replaces =
3730         Formatter(*Env, Style, Status).process().first;
3731     // add a replacement to remove the "x = " from the result.
3732     Replaces = Replaces.merge(
3733         tooling::Replacements(tooling::Replacement(FileName, 0, 4, "")));
3734     // apply the reformatting changes and the removal of "x = ".
3735     if (applyAllReplacements(Code, Replaces))
3736       return {Replaces, 0};
3737     return {tooling::Replacements(), 0};
3738   }
3739 
3740   auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3741                                NextStartColumn, LastStartColumn);
3742   if (!Env)
3743     return {};
3744 
3745   typedef std::function<std::pair<tooling::Replacements, unsigned>(
3746       const Environment &)>
3747       AnalyzerPass;
3748 
3749   SmallVector<AnalyzerPass, 16> Passes;
3750 
3751   Passes.emplace_back([&](const Environment &Env) {
3752     return IntegerLiteralSeparatorFixer().process(Env, Expanded);
3753   });
3754 
3755   if (Style.isCpp()) {
3756     if (Style.QualifierAlignment != FormatStyle::QAS_Leave)
3757       addQualifierAlignmentFixerPasses(Expanded, Passes);
3758 
3759     if (Style.RemoveParentheses != FormatStyle::RPS_Leave) {
3760       FormatStyle S = Expanded;
3761       S.RemoveParentheses = Style.RemoveParentheses;
3762       Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3763         return ParensRemover(Env, S).process(/*SkipAnnotation=*/true);
3764       });
3765     }
3766 
3767     if (Style.InsertBraces) {
3768       FormatStyle S = Expanded;
3769       S.InsertBraces = true;
3770       Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3771         return BracesInserter(Env, S).process(/*SkipAnnotation=*/true);
3772       });
3773     }
3774 
3775     if (Style.RemoveBracesLLVM) {
3776       FormatStyle S = Expanded;
3777       S.RemoveBracesLLVM = true;
3778       Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3779         return BracesRemover(Env, S).process(/*SkipAnnotation=*/true);
3780       });
3781     }
3782 
3783     if (Style.RemoveSemicolon) {
3784       FormatStyle S = Expanded;
3785       S.RemoveSemicolon = true;
3786       Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {
3787         return SemiRemover(Env, S).process();
3788       });
3789     }
3790 
3791     if (Style.FixNamespaceComments) {
3792       Passes.emplace_back([&](const Environment &Env) {
3793         return NamespaceEndCommentsFixer(Env, Expanded).process();
3794       });
3795     }
3796 
3797     if (Style.SortUsingDeclarations != FormatStyle::SUD_Never) {
3798       Passes.emplace_back([&](const Environment &Env) {
3799         return UsingDeclarationsSorter(Env, Expanded).process();
3800       });
3801     }
3802   }
3803 
3804   if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave) {
3805     Passes.emplace_back([&](const Environment &Env) {
3806       return DefinitionBlockSeparator(Env, Expanded).process();
3807     });
3808   }
3809 
3810   if (Style.Language == FormatStyle::LK_ObjC &&
3811       !Style.ObjCPropertyAttributeOrder.empty()) {
3812     Passes.emplace_back([&](const Environment &Env) {
3813       return ObjCPropertyAttributeOrderFixer(Env, Expanded).process();
3814     });
3815   }
3816 
3817   if (Style.isJavaScript() &&
3818       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
3819     Passes.emplace_back([&](const Environment &Env) {
3820       return JavaScriptRequoter(Env, Expanded).process(/*SkipAnnotation=*/true);
3821     });
3822   }
3823 
3824   Passes.emplace_back([&](const Environment &Env) {
3825     return Formatter(Env, Expanded, Status).process();
3826   });
3827 
3828   if (Style.isJavaScript() &&
3829       Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped) {
3830     Passes.emplace_back([&](const Environment &Env) {
3831       return TrailingCommaInserter(Env, Expanded).process();
3832     });
3833   }
3834 
3835   std::optional<std::string> CurrentCode;
3836   tooling::Replacements Fixes;
3837   unsigned Penalty = 0;
3838   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
3839     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3840     auto NewCode = applyAllReplacements(
3841         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3842     if (NewCode) {
3843       Fixes = Fixes.merge(PassFixes.first);
3844       Penalty += PassFixes.second;
3845       if (I + 1 < E) {
3846         CurrentCode = std::move(*NewCode);
3847         Env = Environment::make(
3848             *CurrentCode, FileName,
3849             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3850             FirstStartColumn, NextStartColumn, LastStartColumn);
3851         if (!Env)
3852           return {};
3853       }
3854     }
3855   }
3856 
3857   if (Style.QualifierAlignment != FormatStyle::QAS_Leave) {
3858     // Don't make replacements that replace nothing. QualifierAlignment can
3859     // produce them if one of its early passes changes e.g. `const volatile` to
3860     // `volatile const` and then a later pass changes it back again.
3861     tooling::Replacements NonNoOpFixes;
3862     for (const tooling::Replacement &Fix : Fixes) {
3863       StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3864       if (OriginalCode != Fix.getReplacementText()) {
3865         auto Err = NonNoOpFixes.add(Fix);
3866         if (Err) {
3867           llvm::errs() << "Error adding replacements : "
3868                        << toString(std::move(Err)) << "\n";
3869         }
3870       }
3871     }
3872     Fixes = std::move(NonNoOpFixes);
3873   }
3874 
3875   return {Fixes, Penalty};
3876 }
3877 } // namespace internal
3878 
3879 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3880                                ArrayRef<tooling::Range> Ranges,
3881                                StringRef FileName,
3882                                FormattingAttemptStatus *Status) {
3883   return internal::reformat(Style, Code, Ranges,
3884                             /*FirstStartColumn=*/0,
3885                             /*NextStartColumn=*/0,
3886                             /*LastStartColumn=*/0, FileName, Status)
3887       .first;
3888 }
3889 
3890 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
3891                               ArrayRef<tooling::Range> Ranges,
3892                               StringRef FileName) {
3893   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3894   if (Style.Language != FormatStyle::LK_Cpp)
3895     return tooling::Replacements();
3896   auto Env = Environment::make(Code, FileName, Ranges);
3897   if (!Env)
3898     return {};
3899   return Cleaner(*Env, Style).process().first;
3900 }
3901 
3902 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3903                                ArrayRef<tooling::Range> Ranges,
3904                                StringRef FileName, bool *IncompleteFormat) {
3905   FormattingAttemptStatus Status;
3906   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
3907   if (!Status.FormatComplete)
3908     *IncompleteFormat = true;
3909   return Result;
3910 }
3911 
3912 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
3913                                               StringRef Code,
3914                                               ArrayRef<tooling::Range> Ranges,
3915                                               StringRef FileName) {
3916   auto Env = Environment::make(Code, FileName, Ranges);
3917   if (!Env)
3918     return {};
3919   return NamespaceEndCommentsFixer(*Env, Style).process().first;
3920 }
3921 
3922 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
3923                                             StringRef Code,
3924                                             ArrayRef<tooling::Range> Ranges,
3925                                             StringRef FileName) {
3926   auto Env = Environment::make(Code, FileName, Ranges);
3927   if (!Env)
3928     return {};
3929   return UsingDeclarationsSorter(*Env, Style).process().first;
3930 }
3931 
3932 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
3933   LangOptions LangOpts;
3934 
3935   FormatStyle::LanguageStandard LexingStd = Style.Standard;
3936   if (LexingStd == FormatStyle::LS_Auto)
3937     LexingStd = FormatStyle::LS_Latest;
3938   if (LexingStd == FormatStyle::LS_Latest)
3939     LexingStd = FormatStyle::LS_Cpp20;
3940   LangOpts.CPlusPlus = 1;
3941   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
3942   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
3943   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
3944   LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
3945   LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
3946   // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3947   // the sequence "<::" will be unconditionally treated as "[:".
3948   // Cf. Lexer::LexTokenInternal.
3949   LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
3950 
3951   LangOpts.LineComment = 1;
3952   LangOpts.CXXOperatorNames = Style.isCpp();
3953   LangOpts.Bool = 1;
3954   LangOpts.ObjC = 1;
3955   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
3956   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
3957   LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
3958   return LangOpts;
3959 }
3960 
3961 const char *StyleOptionHelpDescription =
3962     "Set coding style. <string> can be:\n"
3963     "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3964     "   Mozilla, WebKit.\n"
3965     "2. 'file' to load style configuration from a\n"
3966     "   .clang-format file in one of the parent directories\n"
3967     "   of the source file (for stdin, see --assume-filename).\n"
3968     "   If no .clang-format file is found, falls back to\n"
3969     "   --fallback-style.\n"
3970     "   --style=file is the default.\n"
3971     "3. 'file:<format_file_path>' to explicitly specify\n"
3972     "   the configuration file.\n"
3973     "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3974     "   --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3975 
3976 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
3977   if (FileName.ends_with(".java"))
3978     return FormatStyle::LK_Java;
3979   if (FileName.ends_with_insensitive(".js") ||
3980       FileName.ends_with_insensitive(".mjs") ||
3981       FileName.ends_with_insensitive(".cjs") ||
3982       FileName.ends_with_insensitive(".ts")) {
3983     return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
3984   }
3985   if (FileName.ends_with(".m") || FileName.ends_with(".mm"))
3986     return FormatStyle::LK_ObjC;
3987   if (FileName.ends_with_insensitive(".proto") ||
3988       FileName.ends_with_insensitive(".protodevel")) {
3989     return FormatStyle::LK_Proto;
3990   }
3991   // txtpb is the canonical extension, and textproto is the legacy canonical
3992   // extension
3993   // https://protobuf.dev/reference/protobuf/textformat-spec/#text-format-files
3994   if (FileName.ends_with_insensitive(".txtpb") ||
3995       FileName.ends_with_insensitive(".textpb") ||
3996       FileName.ends_with_insensitive(".pb.txt") ||
3997       FileName.ends_with_insensitive(".textproto") ||
3998       FileName.ends_with_insensitive(".asciipb")) {
3999     return FormatStyle::LK_TextProto;
4000   }
4001   if (FileName.ends_with_insensitive(".td"))
4002     return FormatStyle::LK_TableGen;
4003   if (FileName.ends_with_insensitive(".cs"))
4004     return FormatStyle::LK_CSharp;
4005   if (FileName.ends_with_insensitive(".json"))
4006     return FormatStyle::LK_Json;
4007   if (FileName.ends_with_insensitive(".sv") ||
4008       FileName.ends_with_insensitive(".svh") ||
4009       FileName.ends_with_insensitive(".v") ||
4010       FileName.ends_with_insensitive(".vh")) {
4011     return FormatStyle::LK_Verilog;
4012   }
4013   return FormatStyle::LK_Cpp;
4014 }
4015 
4016 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
4017   const auto GuessedLanguage = getLanguageByFileName(FileName);
4018   if (GuessedLanguage == FormatStyle::LK_Cpp) {
4019     auto Extension = llvm::sys::path::extension(FileName);
4020     // If there's no file extension (or it's .h), we need to check the contents
4021     // of the code to see if it contains Objective-C.
4022     if (!Code.empty() && (Extension.empty() || Extension == ".h")) {
4023       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
4024       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
4025       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
4026       Guesser.process();
4027       if (Guesser.isObjC())
4028         return FormatStyle::LK_ObjC;
4029     }
4030   }
4031   return GuessedLanguage;
4032 }
4033 
4034 // Update StyleOptionHelpDescription above when changing this.
4035 const char *DefaultFormatStyle = "file";
4036 
4037 const char *DefaultFallbackStyle = "LLVM";
4038 
4039 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4040 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
4041                        FormatStyle *Style, bool AllowUnknownOptions,
4042                        llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4043   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4044       FS->getBufferForFile(ConfigFile.str());
4045   if (auto EC = Text.getError())
4046     return EC;
4047   if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions,
4048                                    DiagHandler)) {
4049     return EC;
4050   }
4051   return Text;
4052 }
4053 
4054 Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
4055                                StringRef FallbackStyleName, StringRef Code,
4056                                llvm::vfs::FileSystem *FS,
4057                                bool AllowUnknownOptions,
4058                                llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4059   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
4060   FormatStyle FallbackStyle = getNoStyle();
4061   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
4062     return make_string_error("Invalid fallback style: " + FallbackStyleName);
4063 
4064   SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1> ChildFormatTextToApply;
4065 
4066   if (StyleName.starts_with("{")) {
4067     // Parse YAML/JSON style from the command line.
4068     StringRef Source = "<command-line>";
4069     if (std::error_code ec =
4070             parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
4071                                AllowUnknownOptions, DiagHandler)) {
4072       return make_string_error("Error parsing -style: " + ec.message());
4073     }
4074 
4075     if (!Style.InheritsParentConfig)
4076       return Style;
4077 
4078     ChildFormatTextToApply.emplace_back(
4079         llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
4080   }
4081 
4082   if (!FS)
4083     FS = llvm::vfs::getRealFileSystem().get();
4084   assert(FS);
4085 
4086   // User provided clang-format file using -style=file:path/to/format/file.
4087   if (!Style.InheritsParentConfig &&
4088       StyleName.starts_with_insensitive("file:")) {
4089     auto ConfigFile = StyleName.substr(5);
4090     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4091         loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4092                                DiagHandler);
4093     if (auto EC = Text.getError()) {
4094       return make_string_error("Error reading " + ConfigFile + ": " +
4095                                EC.message());
4096     }
4097 
4098     LLVM_DEBUG(llvm::dbgs()
4099                << "Using configuration file " << ConfigFile << "\n");
4100 
4101     if (!Style.InheritsParentConfig)
4102       return Style;
4103 
4104     // Search for parent configs starting from the parent directory of
4105     // ConfigFile.
4106     FileName = ConfigFile;
4107     ChildFormatTextToApply.emplace_back(std::move(*Text));
4108   }
4109 
4110   // If the style inherits the parent configuration it is a command line
4111   // configuration, which wants to inherit, so we have to skip the check of the
4112   // StyleName.
4113   if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
4114     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
4115       return make_string_error("Invalid value for -style");
4116     if (!Style.InheritsParentConfig)
4117       return Style;
4118   }
4119 
4120   SmallString<128> Path(FileName);
4121   if (std::error_code EC = FS->makeAbsolute(Path))
4122     return make_string_error(EC.message());
4123 
4124   // Reset possible inheritance
4125   Style.InheritsParentConfig = false;
4126 
4127   auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
4128 
4129   auto applyChildFormatTexts = [&](FormatStyle *Style) {
4130     for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4131       auto EC =
4132           parseConfiguration(*MemBuf, Style, AllowUnknownOptions,
4133                              DiagHandler ? DiagHandler : dropDiagnosticHandler);
4134       // It was already correctly parsed.
4135       assert(!EC);
4136       static_cast<void>(EC);
4137     }
4138   };
4139 
4140   // Look for .clang-format/_clang-format file in the file's parent directories.
4141   SmallVector<std::string, 2> FilesToLookFor;
4142   FilesToLookFor.push_back(".clang-format");
4143   FilesToLookFor.push_back("_clang-format");
4144 
4145   SmallString<128> UnsuitableConfigFiles;
4146   for (StringRef Directory = Path; !Directory.empty();
4147        Directory = llvm::sys::path::parent_path(Directory)) {
4148     auto Status = FS->status(Directory);
4149     if (!Status ||
4150         Status->getType() != llvm::sys::fs::file_type::directory_file) {
4151       continue;
4152     }
4153 
4154     for (const auto &F : FilesToLookFor) {
4155       SmallString<128> ConfigFile(Directory);
4156 
4157       llvm::sys::path::append(ConfigFile, F);
4158       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
4159 
4160       Status = FS->status(ConfigFile);
4161       if (!Status ||
4162           Status->getType() != llvm::sys::fs::file_type::regular_file) {
4163         continue;
4164       }
4165 
4166       llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
4167           loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
4168                                  DiagHandler);
4169       if (auto EC = Text.getError()) {
4170         if (EC != ParseError::Unsuitable) {
4171           return make_string_error("Error reading " + ConfigFile + ": " +
4172                                    EC.message());
4173         }
4174         if (!UnsuitableConfigFiles.empty())
4175           UnsuitableConfigFiles.append(", ");
4176         UnsuitableConfigFiles.append(ConfigFile);
4177         continue;
4178       }
4179 
4180       LLVM_DEBUG(llvm::dbgs()
4181                  << "Using configuration file " << ConfigFile << "\n");
4182 
4183       if (!Style.InheritsParentConfig) {
4184         if (!ChildFormatTextToApply.empty()) {
4185           LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
4186           applyChildFormatTexts(&Style);
4187         }
4188         return Style;
4189       }
4190 
4191       LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
4192 
4193       // Reset inheritance of style
4194       Style.InheritsParentConfig = false;
4195 
4196       ChildFormatTextToApply.emplace_back(std::move(*Text));
4197 
4198       // Breaking out of the inner loop, since we don't want to parse
4199       // .clang-format AND _clang-format, if both exist. Then we continue the
4200       // outer loop (parent directories) in search for the parent
4201       // configuration.
4202       break;
4203     }
4204   }
4205 
4206   if (!UnsuitableConfigFiles.empty()) {
4207     return make_string_error("Configuration file(s) do(es) not support " +
4208                              getLanguageName(Style.Language) + ": " +
4209                              UnsuitableConfigFiles);
4210   }
4211 
4212   if (!ChildFormatTextToApply.empty()) {
4213     LLVM_DEBUG(llvm::dbgs()
4214                << "Applying child configurations on fallback style\n");
4215     applyChildFormatTexts(&FallbackStyle);
4216   }
4217 
4218   return FallbackStyle;
4219 }
4220 
4221 static bool isClangFormatOnOff(StringRef Comment, bool On) {
4222   if (Comment == (On ? "/* clang-format on */" : "/* clang-format off */"))
4223     return true;
4224 
4225   static const char ClangFormatOn[] = "// clang-format on";
4226   static const char ClangFormatOff[] = "// clang-format off";
4227   const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1;
4228 
4229   return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4230          (Comment.size() == Size || Comment[Size] == ':');
4231 }
4232 
4233 bool isClangFormatOn(StringRef Comment) {
4234   return isClangFormatOnOff(Comment, /*On=*/true);
4235 }
4236 
4237 bool isClangFormatOff(StringRef Comment) {
4238   return isClangFormatOnOff(Comment, /*On=*/false);
4239 }
4240 
4241 } // namespace format
4242 } // namespace clang
4243