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