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