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