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