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