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