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