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