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