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