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 "FormatInternal.h"
20 #include "FormatTokenLexer.h"
21 #include "NamespaceEndCommentsFixer.h"
22 #include "SortJavaScriptImports.h"
23 #include "TokenAnalyzer.h"
24 #include "TokenAnnotator.h"
25 #include "UnwrappedLineFormatter.h"
26 #include "UnwrappedLineParser.h"
27 #include "UsingDeclarationsSorter.h"
28 #include "WhitespaceManager.h"
29 #include "clang/Basic/Diagnostic.h"
30 #include "clang/Basic/DiagnosticOptions.h"
31 #include "clang/Basic/SourceManager.h"
32 #include "clang/Lex/Lexer.h"
33 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
34 #include "llvm/ADT/STLExtras.h"
35 #include "llvm/ADT/StringRef.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/Path.h"
39 #include "llvm/Support/Regex.h"
40 #include "llvm/Support/VirtualFileSystem.h"
41 #include "llvm/Support/YAMLTraits.h"
42 #include <algorithm>
43 #include <memory>
44 #include <mutex>
45 #include <string>
46 #include <unordered_map>
47 
48 #define DEBUG_TYPE "format-formatter"
49 
50 using clang::format::FormatStyle;
51 
52 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat)
53 
54 namespace llvm {
55 namespace yaml {
56 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
57   static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
58     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
59     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
60     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
61     IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
62     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
63     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
64     IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
65     IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
66   }
67 };
68 
69 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
70   static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
71     IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);
72     IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias
73     IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias
74 
75     IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);
76     IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias
77 
78     IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);
79     IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);
80     IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);
81 
82     IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);
83     IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias
84     IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
85   }
86 };
87 
88 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
89   static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
90     IO.enumCase(Value, "Never", FormatStyle::UT_Never);
91     IO.enumCase(Value, "false", FormatStyle::UT_Never);
92     IO.enumCase(Value, "Always", FormatStyle::UT_Always);
93     IO.enumCase(Value, "true", FormatStyle::UT_Always);
94     IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
95     IO.enumCase(Value, "ForContinuationAndIndentation",
96                 FormatStyle::UT_ForContinuationAndIndentation);
97     IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
98   }
99 };
100 
101 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
102   static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
103     IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
104     IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
105     IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
106   }
107 };
108 
109 template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
110   static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) {
111     IO.enumCase(Value, "Never", FormatStyle::SBS_Never);
112     IO.enumCase(Value, "false", FormatStyle::SBS_Never);
113     IO.enumCase(Value, "Always", FormatStyle::SBS_Always);
114     IO.enumCase(Value, "true", FormatStyle::SBS_Always);
115     IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);
116   }
117 };
118 
119 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
120   static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
121     IO.enumCase(Value, "None", FormatStyle::SFS_None);
122     IO.enumCase(Value, "false", FormatStyle::SFS_None);
123     IO.enumCase(Value, "All", FormatStyle::SFS_All);
124     IO.enumCase(Value, "true", FormatStyle::SFS_All);
125     IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
126     IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
127     IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
128   }
129 };
130 
131 template <> struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveStyle> {
132   static void enumeration(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
133     IO.enumCase(Value, "None", FormatStyle::ACS_None);
134     IO.enumCase(Value, "Consecutive", FormatStyle::ACS_Consecutive);
135     IO.enumCase(Value, "AcrossEmptyLines", FormatStyle::ACS_AcrossEmptyLines);
136     IO.enumCase(Value, "AcrossComments", FormatStyle::ACS_AcrossComments);
137     IO.enumCase(Value, "AcrossEmptyLinesAndComments",
138                 FormatStyle::ACS_AcrossEmptyLinesAndComments);
139 
140     // For backward compability.
141     IO.enumCase(Value, "true", FormatStyle::ACS_Consecutive);
142     IO.enumCase(Value, "false", FormatStyle::ACS_None);
143   }
144 };
145 
146 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
147   static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
148     IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
149     IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
150     IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
151     IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
152 
153     // For backward compatibility.
154     IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
155     IO.enumCase(Value, "false", FormatStyle::SIS_Never);
156     IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
157   }
158 };
159 
160 template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
161   static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) {
162     IO.enumCase(Value, "None", FormatStyle::SLS_None);
163     IO.enumCase(Value, "false", FormatStyle::SLS_None);
164     IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
165     IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
166     IO.enumCase(Value, "All", FormatStyle::SLS_All);
167     IO.enumCase(Value, "true", FormatStyle::SLS_All);
168   }
169 };
170 
171 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
172   static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
173     IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
174     IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
175     IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
176   }
177 };
178 
179 template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {
180   static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {
181     IO.enumCase(Value, "None", FormatStyle::TCS_None);
182     IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);
183   }
184 };
185 
186 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {
187   static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {
188     IO.enumCase(Value, "All", FormatStyle::BOS_All);
189     IO.enumCase(Value, "true", FormatStyle::BOS_All);
190     IO.enumCase(Value, "None", FormatStyle::BOS_None);
191     IO.enumCase(Value, "false", FormatStyle::BOS_None);
192     IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);
193   }
194 };
195 
196 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
197   static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
198     IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
199     IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
200     IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
201     IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
202     IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
203     IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
204     IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
205     IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
206     IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
207   }
208 };
209 
210 template <>
211 struct ScalarEnumerationTraits<
212     FormatStyle::BraceWrappingAfterControlStatementStyle> {
213   static void
214   enumeration(IO &IO,
215               FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {
216     IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);
217     IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);
218     IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
219 
220     // For backward compatibility.
221     IO.enumCase(Value, "false", FormatStyle::BWACS_Never);
222     IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
223   }
224 };
225 
226 template <>
227 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
228   static void
229   enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
230     IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
231     IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
232     IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
233   }
234 };
235 
236 template <>
237 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
238   static void enumeration(IO &IO,
239                           FormatStyle::BreakInheritanceListStyle &Value) {
240     IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
241     IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
242     IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
243     IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
244   }
245 };
246 
247 template <>
248 struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
249   static void
250   enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
251     IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
252     IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
253     IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
254   }
255 };
256 
257 template <>
258 struct ScalarEnumerationTraits<
259     FormatStyle::EmptyLineBeforeAccessModifierStyle> {
260   static void
261   enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
262     IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
263     IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
264     IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
265     IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
266   }
267 };
268 
269 template <>
270 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
271   static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
272     IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
273     IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
274     IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
275   }
276 };
277 
278 template <>
279 struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
280   static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
281     IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
282     IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
283     IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
284     IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
285     IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
286   }
287 };
288 
289 template <>
290 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
291   static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
292     IO.enumCase(Value, "None", FormatStyle::RTBS_None);
293     IO.enumCase(Value, "All", FormatStyle::RTBS_All);
294     IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
295     IO.enumCase(Value, "TopLevelDefinitions",
296                 FormatStyle::RTBS_TopLevelDefinitions);
297     IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
298   }
299 };
300 
301 template <>
302 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
303   static void enumeration(IO &IO,
304                           FormatStyle::BreakTemplateDeclarationsStyle &Value) {
305     IO.enumCase(Value, "No", FormatStyle::BTDS_No);
306     IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
307     IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
308 
309     // For backward compatibility.
310     IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
311     IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
312   }
313 };
314 
315 template <>
316 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
317   static void
318   enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
319     IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
320     IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
321     IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
322 
323     // For backward compatibility.
324     IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
325     IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
326   }
327 };
328 
329 template <>
330 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
331   static void enumeration(IO &IO,
332                           FormatStyle::NamespaceIndentationKind &Value) {
333     IO.enumCase(Value, "None", FormatStyle::NI_None);
334     IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
335     IO.enumCase(Value, "All", FormatStyle::NI_All);
336   }
337 };
338 
339 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
340   static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {
341     IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
342     IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
343     IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
344 
345     // For backward compatibility.
346     IO.enumCase(Value, "true", FormatStyle::BAS_Align);
347     IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);
348   }
349 };
350 
351 template <>
352 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
353   static void enumeration(IO &IO,
354                           FormatStyle::EscapedNewlineAlignmentStyle &Value) {
355     IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
356     IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
357     IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
358 
359     // For backward compatibility.
360     IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
361     IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
362   }
363 };
364 
365 template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
366   static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
367     IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
368     IO.enumCase(Value, "Align", FormatStyle::OAS_Align);
369     IO.enumCase(Value, "AlignAfterOperator",
370                 FormatStyle::OAS_AlignAfterOperator);
371 
372     // For backward compatibility.
373     IO.enumCase(Value, "true", FormatStyle::OAS_Align);
374     IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);
375   }
376 };
377 
378 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
379   static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
380     IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
381     IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
382     IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
383 
384     // For backward compatibility.
385     IO.enumCase(Value, "true", FormatStyle::PAS_Left);
386     IO.enumCase(Value, "false", FormatStyle::PAS_Right);
387   }
388 };
389 
390 template <>
391 struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
392   static void
393   enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
394     IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
395     IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
396     IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
397     IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
398   }
399 };
400 
401 template <>
402 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
403   static void enumeration(IO &IO,
404                           FormatStyle::SpaceBeforeParensOptions &Value) {
405     IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
406     IO.enumCase(Value, "ControlStatements",
407                 FormatStyle::SBPO_ControlStatements);
408     IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
409                 FormatStyle::SBPO_ControlStatementsExceptForEachMacros);
410     IO.enumCase(Value, "NonEmptyParentheses",
411                 FormatStyle::SBPO_NonEmptyParentheses);
412     IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
413 
414     // For backward compatibility.
415     IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
416     IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
417   }
418 };
419 
420 template <>
421 struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
422   static void enumeration(IO &IO,
423                           FormatStyle::BitFieldColonSpacingStyle &Value) {
424     IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);
425     IO.enumCase(Value, "None", FormatStyle::BFCS_None);
426     IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);
427     IO.enumCase(Value, "After", FormatStyle::BFCS_After);
428   }
429 };
430 
431 template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {
432   static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {
433     IO.enumCase(Value, "Never", FormatStyle::SI_Never);
434     IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);
435     IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);
436 
437     // For backward compatibility.
438     IO.enumCase(Value, "false", FormatStyle::SI_Never);
439     IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);
440   }
441 };
442 
443 template <>
444 struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
445   static void enumeration(IO &IO,
446                           FormatStyle::SortJavaStaticImportOptions &Value) {
447     IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
448     IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
449   }
450 };
451 
452 template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
453   static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
454     IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
455     IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
456     IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
457 
458     // For backward compatibility.
459     IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
460     IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
461   }
462 };
463 
464 template <> struct MappingTraits<FormatStyle> {
465   static void mapping(IO &IO, FormatStyle &Style) {
466     // When reading, read the language first, we need it for getPredefinedStyle.
467     IO.mapOptional("Language", Style.Language);
468 
469     if (IO.outputting()) {
470       StringRef StylesArray[] = {"LLVM",   "Google", "Chromium", "Mozilla",
471                                  "WebKit", "GNU",    "Microsoft"};
472       ArrayRef<StringRef> Styles(StylesArray);
473       for (size_t i = 0, e = Styles.size(); i < e; ++i) {
474         StringRef StyleName(Styles[i]);
475         FormatStyle PredefinedStyle;
476         if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
477             Style == PredefinedStyle) {
478           IO.mapOptional("# BasedOnStyle", StyleName);
479           break;
480         }
481       }
482     } else {
483       StringRef BasedOnStyle;
484       IO.mapOptional("BasedOnStyle", BasedOnStyle);
485       if (!BasedOnStyle.empty()) {
486         FormatStyle::LanguageKind OldLanguage = Style.Language;
487         FormatStyle::LanguageKind Language =
488             ((FormatStyle *)IO.getContext())->Language;
489         if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
490           IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
491           return;
492         }
493         Style.Language = OldLanguage;
494       }
495     }
496 
497     // For backward compatibility.
498     if (!IO.outputting()) {
499       IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
500       IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
501       IO.mapOptional("IndentFunctionDeclarationAfterType",
502                      Style.IndentWrappedFunctionNames);
503       IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
504       IO.mapOptional("SpaceAfterControlStatementKeyword",
505                      Style.SpaceBeforeParens);
506     }
507 
508     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
509     IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
510     IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
511     IO.mapOptional("AlignConsecutiveAssignments",
512                    Style.AlignConsecutiveAssignments);
513     IO.mapOptional("AlignConsecutiveBitFields",
514                    Style.AlignConsecutiveBitFields);
515     IO.mapOptional("AlignConsecutiveDeclarations",
516                    Style.AlignConsecutiveDeclarations);
517     IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
518     IO.mapOptional("AlignOperands", Style.AlignOperands);
519     IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
520     IO.mapOptional("AllowAllArgumentsOnNextLine",
521                    Style.AllowAllArgumentsOnNextLine);
522     IO.mapOptional("AllowAllConstructorInitializersOnNextLine",
523                    Style.AllowAllConstructorInitializersOnNextLine);
524     IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
525                    Style.AllowAllParametersOfDeclarationOnNextLine);
526     IO.mapOptional("AllowShortEnumsOnASingleLine",
527                    Style.AllowShortEnumsOnASingleLine);
528     IO.mapOptional("AllowShortBlocksOnASingleLine",
529                    Style.AllowShortBlocksOnASingleLine);
530     IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
531                    Style.AllowShortCaseLabelsOnASingleLine);
532     IO.mapOptional("AllowShortFunctionsOnASingleLine",
533                    Style.AllowShortFunctionsOnASingleLine);
534     IO.mapOptional("AllowShortLambdasOnASingleLine",
535                    Style.AllowShortLambdasOnASingleLine);
536     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
537                    Style.AllowShortIfStatementsOnASingleLine);
538     IO.mapOptional("AllowShortLoopsOnASingleLine",
539                    Style.AllowShortLoopsOnASingleLine);
540     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
541                    Style.AlwaysBreakAfterDefinitionReturnType);
542     IO.mapOptional("AlwaysBreakAfterReturnType",
543                    Style.AlwaysBreakAfterReturnType);
544 
545     // If AlwaysBreakAfterDefinitionReturnType was specified but
546     // AlwaysBreakAfterReturnType was not, initialize the latter from the
547     // former for backwards compatibility.
548     if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
549         Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) {
550       if (Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All)
551         Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
552       else if (Style.AlwaysBreakAfterDefinitionReturnType ==
553                FormatStyle::DRTBS_TopLevel)
554         Style.AlwaysBreakAfterReturnType =
555             FormatStyle::RTBS_TopLevelDefinitions;
556     }
557 
558     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
559                    Style.AlwaysBreakBeforeMultilineStrings);
560     IO.mapOptional("AlwaysBreakTemplateDeclarations",
561                    Style.AlwaysBreakTemplateDeclarations);
562     IO.mapOptional("AttributeMacros", Style.AttributeMacros);
563     IO.mapOptional("BinPackArguments", Style.BinPackArguments);
564     IO.mapOptional("BinPackParameters", Style.BinPackParameters);
565     IO.mapOptional("BraceWrapping", Style.BraceWrapping);
566     IO.mapOptional("BreakBeforeBinaryOperators",
567                    Style.BreakBeforeBinaryOperators);
568     IO.mapOptional("BreakBeforeConceptDeclarations",
569                    Style.BreakBeforeConceptDeclarations);
570     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
571 
572     bool BreakBeforeInheritanceComma = false;
573     IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma);
574     IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
575     // If BreakBeforeInheritanceComma was specified but
576     // BreakInheritance was not, initialize the latter from the
577     // former for backwards compatibility.
578     if (BreakBeforeInheritanceComma &&
579         Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon)
580       Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
581 
582     IO.mapOptional("BreakBeforeTernaryOperators",
583                    Style.BreakBeforeTernaryOperators);
584 
585     bool BreakConstructorInitializersBeforeComma = false;
586     IO.mapOptional("BreakConstructorInitializersBeforeComma",
587                    BreakConstructorInitializersBeforeComma);
588     IO.mapOptional("BreakConstructorInitializers",
589                    Style.BreakConstructorInitializers);
590     // If BreakConstructorInitializersBeforeComma was specified but
591     // BreakConstructorInitializers was not, initialize the latter from the
592     // former for backwards compatibility.
593     if (BreakConstructorInitializersBeforeComma &&
594         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon)
595       Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
596 
597     IO.mapOptional("BreakAfterJavaFieldAnnotations",
598                    Style.BreakAfterJavaFieldAnnotations);
599     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
600     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
601     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
602     IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
603     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
604                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
605     IO.mapOptional("ConstructorInitializerIndentWidth",
606                    Style.ConstructorInitializerIndentWidth);
607     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
608     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
609     IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
610     IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
611     IO.mapOptional("DisableFormat", Style.DisableFormat);
612     IO.mapOptional("EmptyLineAfterAccessModifier",
613                    Style.EmptyLineAfterAccessModifier);
614     IO.mapOptional("EmptyLineBeforeAccessModifier",
615                    Style.EmptyLineBeforeAccessModifier);
616     IO.mapOptional("ExperimentalAutoDetectBinPacking",
617                    Style.ExperimentalAutoDetectBinPacking);
618     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
619     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
620     IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
621     IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
622     IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
623     IO.mapOptional("IncludeIsMainSourceRegex",
624                    Style.IncludeStyle.IncludeIsMainSourceRegex);
625     IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
626     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
627     IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
628     IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
629     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
630     IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
631     IO.mapOptional("IndentRequires", Style.IndentRequires);
632     IO.mapOptional("IndentWidth", Style.IndentWidth);
633     IO.mapOptional("IndentWrappedFunctionNames",
634                    Style.IndentWrappedFunctionNames);
635     IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
636     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
637     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
638     IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
639     IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
640                    Style.KeepEmptyLinesAtTheStartOfBlocks);
641     IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
642     IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
643     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
644     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
645     IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
646     IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
647     IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
648     IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
649                    Style.ObjCBreakBeforeNestedBlockParam);
650     IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
651     IO.mapOptional("ObjCSpaceBeforeProtocolList",
652                    Style.ObjCSpaceBeforeProtocolList);
653     IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
654     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
655                    Style.PenaltyBreakBeforeFirstCallParameter);
656     IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
657     IO.mapOptional("PenaltyBreakFirstLessLess",
658                    Style.PenaltyBreakFirstLessLess);
659     IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
660     IO.mapOptional("PenaltyBreakTemplateDeclaration",
661                    Style.PenaltyBreakTemplateDeclaration);
662     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
663     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
664                    Style.PenaltyReturnTypeOnItsOwnLine);
665     IO.mapOptional("PenaltyIndentedWhitespace",
666                    Style.PenaltyIndentedWhitespace);
667     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
668     IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
669     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
670     IO.mapOptional("ReflowComments", Style.ReflowComments);
671     IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
672     IO.mapOptional("SortIncludes", Style.SortIncludes);
673     IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
674     IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
675     IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
676     IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
677     IO.mapOptional("SpaceAfterTemplateKeyword",
678                    Style.SpaceAfterTemplateKeyword);
679     IO.mapOptional("SpaceBeforeAssignmentOperators",
680                    Style.SpaceBeforeAssignmentOperators);
681     IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
682     IO.mapOptional("SpaceBeforeCpp11BracedList",
683                    Style.SpaceBeforeCpp11BracedList);
684     IO.mapOptional("SpaceBeforeCtorInitializerColon",
685                    Style.SpaceBeforeCtorInitializerColon);
686     IO.mapOptional("SpaceBeforeInheritanceColon",
687                    Style.SpaceBeforeInheritanceColon);
688     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
689     IO.mapOptional("SpaceAroundPointerQualifiers",
690                    Style.SpaceAroundPointerQualifiers);
691     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
692                    Style.SpaceBeforeRangeBasedForLoopColon);
693     IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
694     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
695     IO.mapOptional("SpacesBeforeTrailingComments",
696                    Style.SpacesBeforeTrailingComments);
697     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
698     IO.mapOptional("SpacesInConditionalStatement",
699                    Style.SpacesInConditionalStatement);
700     IO.mapOptional("SpacesInContainerLiterals",
701                    Style.SpacesInContainerLiterals);
702     IO.mapOptional("SpacesInCStyleCastParentheses",
703                    Style.SpacesInCStyleCastParentheses);
704     IO.mapOptional("SpacesInLineCommentPrefix",
705                    Style.SpacesInLineCommentPrefix);
706     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
707     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
708     IO.mapOptional("SpaceBeforeSquareBrackets",
709                    Style.SpaceBeforeSquareBrackets);
710     IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing);
711     IO.mapOptional("Standard", Style.Standard);
712     IO.mapOptional("StatementAttributeLikeMacros",
713                    Style.StatementAttributeLikeMacros);
714     IO.mapOptional("StatementMacros", Style.StatementMacros);
715     IO.mapOptional("TabWidth", Style.TabWidth);
716     IO.mapOptional("TypenameMacros", Style.TypenameMacros);
717     IO.mapOptional("UseCRLF", Style.UseCRLF);
718     IO.mapOptional("UseTab", Style.UseTab);
719     IO.mapOptional("WhitespaceSensitiveMacros",
720                    Style.WhitespaceSensitiveMacros);
721   }
722 };
723 
724 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
725   static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
726     IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
727     IO.mapOptional("AfterClass", Wrapping.AfterClass);
728     IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
729     IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
730     IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
731     IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
732     IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
733     IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
734     IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
735     IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
736     IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
737     IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
738     IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
739     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
740     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
741     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
742     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
743     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
744   }
745 };
746 
747 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
748   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
749     IO.mapOptional("Language", Format.Language);
750     IO.mapOptional("Delimiters", Format.Delimiters);
751     IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
752     IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
753     IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
754   }
755 };
756 
757 template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
758   static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
759     // Transform the maximum to signed, to parse "-1" correctly
760     int signedMaximum = static_cast<int>(Space.Maximum);
761     IO.mapOptional("Minimum", Space.Minimum);
762     IO.mapOptional("Maximum", signedMaximum);
763     Space.Maximum = static_cast<unsigned>(signedMaximum);
764 
765     if (Space.Maximum != -1u) {
766       Space.Minimum = std::min(Space.Minimum, Space.Maximum);
767     }
768   }
769 };
770 
771 // Allows to read vector<FormatStyle> while keeping default values.
772 // IO.getContext() should contain a pointer to the FormatStyle structure, that
773 // will be used to get default values for missing keys.
774 // If the first element has no Language specified, it will be treated as the
775 // default one for the following elements.
776 template <> struct DocumentListTraits<std::vector<FormatStyle>> {
777   static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
778     return Seq.size();
779   }
780   static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
781                               size_t Index) {
782     if (Index >= Seq.size()) {
783       assert(Index == Seq.size());
784       FormatStyle Template;
785       if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
786         Template = Seq[0];
787       } else {
788         Template = *((const FormatStyle *)IO.getContext());
789         Template.Language = FormatStyle::LK_None;
790       }
791       Seq.resize(Index + 1, Template);
792     }
793     return Seq[Index];
794   }
795 };
796 } // namespace yaml
797 } // namespace llvm
798 
799 namespace clang {
800 namespace format {
801 
802 const std::error_category &getParseCategory() {
803   static const ParseErrorCategory C{};
804   return C;
805 }
806 std::error_code make_error_code(ParseError e) {
807   return std::error_code(static_cast<int>(e), getParseCategory());
808 }
809 
810 inline llvm::Error make_string_error(const llvm::Twine &Message) {
811   return llvm::make_error<llvm::StringError>(Message,
812                                              llvm::inconvertibleErrorCode());
813 }
814 
815 const char *ParseErrorCategory::name() const noexcept {
816   return "clang-format.parse_error";
817 }
818 
819 std::string ParseErrorCategory::message(int EV) const {
820   switch (static_cast<ParseError>(EV)) {
821   case ParseError::Success:
822     return "Success";
823   case ParseError::Error:
824     return "Invalid argument";
825   case ParseError::Unsuitable:
826     return "Unsuitable";
827   case ParseError::BinPackTrailingCommaConflict:
828     return "trailing comma insertion cannot be used with bin packing";
829   }
830   llvm_unreachable("unexpected parse error");
831 }
832 
833 static FormatStyle expandPresets(const FormatStyle &Style) {
834   if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
835     return Style;
836   FormatStyle Expanded = Style;
837   Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
838                             /*AfterClass=*/false,
839                             /*AfterControlStatement=*/FormatStyle::BWACS_Never,
840                             /*AfterEnum=*/false,
841                             /*AfterFunction=*/false,
842                             /*AfterNamespace=*/false,
843                             /*AfterObjCDeclaration=*/false,
844                             /*AfterStruct=*/false,
845                             /*AfterUnion=*/false,
846                             /*AfterExternBlock=*/false,
847                             /*BeforeCatch=*/false,
848                             /*BeforeElse=*/false,
849                             /*BeforeLambdaBody=*/false,
850                             /*BeforeWhile=*/false,
851                             /*IndentBraces=*/false,
852                             /*SplitEmptyFunction=*/true,
853                             /*SplitEmptyRecord=*/true,
854                             /*SplitEmptyNamespace=*/true};
855   switch (Style.BreakBeforeBraces) {
856   case FormatStyle::BS_Linux:
857     Expanded.BraceWrapping.AfterClass = true;
858     Expanded.BraceWrapping.AfterFunction = true;
859     Expanded.BraceWrapping.AfterNamespace = true;
860     break;
861   case FormatStyle::BS_Mozilla:
862     Expanded.BraceWrapping.AfterClass = true;
863     Expanded.BraceWrapping.AfterEnum = true;
864     Expanded.BraceWrapping.AfterFunction = true;
865     Expanded.BraceWrapping.AfterStruct = true;
866     Expanded.BraceWrapping.AfterUnion = true;
867     Expanded.BraceWrapping.AfterExternBlock = true;
868     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
869     Expanded.BraceWrapping.SplitEmptyFunction = true;
870     Expanded.BraceWrapping.SplitEmptyRecord = false;
871     break;
872   case FormatStyle::BS_Stroustrup:
873     Expanded.BraceWrapping.AfterFunction = true;
874     Expanded.BraceWrapping.BeforeCatch = true;
875     Expanded.BraceWrapping.BeforeElse = true;
876     break;
877   case FormatStyle::BS_Allman:
878     Expanded.BraceWrapping.AfterCaseLabel = true;
879     Expanded.BraceWrapping.AfterClass = true;
880     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
881     Expanded.BraceWrapping.AfterEnum = true;
882     Expanded.BraceWrapping.AfterFunction = true;
883     Expanded.BraceWrapping.AfterNamespace = true;
884     Expanded.BraceWrapping.AfterObjCDeclaration = true;
885     Expanded.BraceWrapping.AfterStruct = true;
886     Expanded.BraceWrapping.AfterUnion = true;
887     Expanded.BraceWrapping.AfterExternBlock = true;
888     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
889     Expanded.BraceWrapping.BeforeCatch = true;
890     Expanded.BraceWrapping.BeforeElse = true;
891     Expanded.BraceWrapping.BeforeLambdaBody = true;
892     break;
893   case FormatStyle::BS_Whitesmiths:
894     Expanded.BraceWrapping.AfterCaseLabel = true;
895     Expanded.BraceWrapping.AfterClass = true;
896     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
897     Expanded.BraceWrapping.AfterEnum = true;
898     Expanded.BraceWrapping.AfterFunction = true;
899     Expanded.BraceWrapping.AfterNamespace = true;
900     Expanded.BraceWrapping.AfterObjCDeclaration = true;
901     Expanded.BraceWrapping.AfterStruct = true;
902     Expanded.BraceWrapping.AfterExternBlock = true;
903     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
904     Expanded.BraceWrapping.BeforeCatch = true;
905     Expanded.BraceWrapping.BeforeElse = true;
906     Expanded.BraceWrapping.BeforeLambdaBody = true;
907     break;
908   case FormatStyle::BS_GNU:
909     Expanded.BraceWrapping = {
910         /*AfterCaseLabel=*/true,
911         /*AfterClass=*/true,
912         /*AfterControlStatement=*/FormatStyle::BWACS_Always,
913         /*AfterEnum=*/true,
914         /*AfterFunction=*/true,
915         /*AfterNamespace=*/true,
916         /*AfterObjCDeclaration=*/true,
917         /*AfterStruct=*/true,
918         /*AfterUnion=*/true,
919         /*AfterExternBlock=*/true,
920         /*BeforeCatch=*/true,
921         /*BeforeElse=*/true,
922         /*BeforeLambdaBody=*/false,
923         /*BeforeWhile=*/true,
924         /*IndentBraces=*/true,
925         /*SplitEmptyFunction=*/true,
926         /*SplitEmptyRecord=*/true,
927         /*SplitEmptyNamespace=*/true};
928     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
929     break;
930   case FormatStyle::BS_WebKit:
931     Expanded.BraceWrapping.AfterFunction = true;
932     break;
933   default:
934     break;
935   }
936   return Expanded;
937 }
938 
939 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
940   FormatStyle LLVMStyle;
941   LLVMStyle.InheritsParentConfig = false;
942   LLVMStyle.Language = Language;
943   LLVMStyle.AccessModifierOffset = -2;
944   LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
945   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
946   LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
947   LLVMStyle.AlignTrailingComments = true;
948   LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
949   LLVMStyle.AlignConsecutiveBitFields = FormatStyle::ACS_None;
950   LLVMStyle.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
951   LLVMStyle.AlignConsecutiveMacros = FormatStyle::ACS_None;
952   LLVMStyle.AllowAllArgumentsOnNextLine = true;
953   LLVMStyle.AllowAllConstructorInitializersOnNextLine = true;
954   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
955   LLVMStyle.AllowShortEnumsOnASingleLine = true;
956   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
957   LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
958   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
959   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
960   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
961   LLVMStyle.AllowShortLoopsOnASingleLine = false;
962   LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
963   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
964   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
965   LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
966   LLVMStyle.AttributeMacros.push_back("__capability");
967   LLVMStyle.BinPackArguments = true;
968   LLVMStyle.BinPackParameters = true;
969   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
970   LLVMStyle.BreakBeforeConceptDeclarations = true;
971   LLVMStyle.BreakBeforeTernaryOperators = true;
972   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
973   LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
974                              /*AfterClass=*/false,
975                              /*AfterControlStatement=*/FormatStyle::BWACS_Never,
976                              /*AfterEnum=*/false,
977                              /*AfterFunction=*/false,
978                              /*AfterNamespace=*/false,
979                              /*AfterObjCDeclaration=*/false,
980                              /*AfterStruct=*/false,
981                              /*AfterUnion=*/false,
982                              /*AfterExternBlock=*/false,
983                              /*BeforeCatch=*/false,
984                              /*BeforeElse=*/false,
985                              /*BeforeLambdaBody=*/false,
986                              /*BeforeWhile=*/false,
987                              /*IndentBraces=*/false,
988                              /*SplitEmptyFunction=*/true,
989                              /*SplitEmptyRecord=*/true,
990                              /*SplitEmptyNamespace=*/true};
991   LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
992   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
993   LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
994   LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
995   LLVMStyle.BreakStringLiterals = true;
996   LLVMStyle.ColumnLimit = 80;
997   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
998   LLVMStyle.CompactNamespaces = false;
999   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
1000   LLVMStyle.ConstructorInitializerIndentWidth = 4;
1001   LLVMStyle.ContinuationIndentWidth = 4;
1002   LLVMStyle.Cpp11BracedListStyle = true;
1003   LLVMStyle.DeriveLineEnding = true;
1004   LLVMStyle.DerivePointerAlignment = false;
1005   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
1006   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
1007   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1008   LLVMStyle.FixNamespaceComments = true;
1009   LLVMStyle.ForEachMacros.push_back("foreach");
1010   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1011   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1012   LLVMStyle.IncludeStyle.IncludeCategories = {
1013       {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1014       {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1015       {".*", 1, 0, false}};
1016   LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1017   LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
1018   LLVMStyle.IndentAccessModifiers = false;
1019   LLVMStyle.IndentCaseLabels = false;
1020   LLVMStyle.IndentCaseBlocks = false;
1021   LLVMStyle.IndentGotoLabels = true;
1022   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
1023   LLVMStyle.IndentRequires = false;
1024   LLVMStyle.IndentWrappedFunctionNames = false;
1025   LLVMStyle.IndentWidth = 2;
1026   LLVMStyle.PPIndentWidth = -1;
1027   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1028   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
1029   LLVMStyle.JavaScriptWrapImports = true;
1030   LLVMStyle.TabWidth = 8;
1031   LLVMStyle.MaxEmptyLinesToKeep = 1;
1032   LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
1033   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
1034   LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
1035   LLVMStyle.ObjCBlockIndentWidth = 2;
1036   LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1037   LLVMStyle.ObjCSpaceAfterProperty = false;
1038   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1039   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
1040   LLVMStyle.ShortNamespaceLines = 1;
1041   LLVMStyle.SpacesBeforeTrailingComments = 1;
1042   LLVMStyle.Standard = FormatStyle::LS_Latest;
1043   LLVMStyle.UseCRLF = false;
1044   LLVMStyle.UseTab = FormatStyle::UT_Never;
1045   LLVMStyle.ReflowComments = true;
1046   LLVMStyle.SpacesInParentheses = false;
1047   LLVMStyle.SpacesInSquareBrackets = false;
1048   LLVMStyle.SpaceInEmptyBlock = false;
1049   LLVMStyle.SpaceInEmptyParentheses = false;
1050   LLVMStyle.SpacesInContainerLiterals = true;
1051   LLVMStyle.SpacesInCStyleCastParentheses = false;
1052   LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
1053   LLVMStyle.SpaceAfterCStyleCast = false;
1054   LLVMStyle.SpaceAfterLogicalNot = false;
1055   LLVMStyle.SpaceAfterTemplateKeyword = true;
1056   LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
1057   LLVMStyle.SpaceBeforeCaseColon = false;
1058   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1059   LLVMStyle.SpaceBeforeInheritanceColon = true;
1060   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
1061   LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1062   LLVMStyle.SpaceBeforeAssignmentOperators = true;
1063   LLVMStyle.SpaceBeforeCpp11BracedList = false;
1064   LLVMStyle.SpaceBeforeSquareBrackets = false;
1065   LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
1066   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
1067   LLVMStyle.SpacesInConditionalStatement = false;
1068 
1069   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
1070   LLVMStyle.PenaltyBreakComment = 300;
1071   LLVMStyle.PenaltyBreakFirstLessLess = 120;
1072   LLVMStyle.PenaltyBreakString = 1000;
1073   LLVMStyle.PenaltyExcessCharacter = 1000000;
1074   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1075   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
1076   LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
1077   LLVMStyle.PenaltyIndentedWhitespace = 0;
1078 
1079   LLVMStyle.DisableFormat = false;
1080   LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1081   LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
1082   LLVMStyle.SortUsingDeclarations = true;
1083   LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1084   LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1085   LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1086   LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1087   LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1088   LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1089   LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1090   LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1091 
1092   // Defaults that differ when not C++.
1093   if (Language == FormatStyle::LK_TableGen) {
1094     LLVMStyle.SpacesInContainerLiterals = false;
1095   }
1096 
1097   return LLVMStyle;
1098 }
1099 
1100 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
1101   if (Language == FormatStyle::LK_TextProto) {
1102     FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
1103     GoogleStyle.Language = FormatStyle::LK_TextProto;
1104 
1105     return GoogleStyle;
1106   }
1107 
1108   FormatStyle GoogleStyle = getLLVMStyle(Language);
1109 
1110   GoogleStyle.AccessModifierOffset = -1;
1111   GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
1112   GoogleStyle.AllowShortIfStatementsOnASingleLine =
1113       FormatStyle::SIS_WithoutElse;
1114   GoogleStyle.AllowShortLoopsOnASingleLine = true;
1115   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1116   GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1117   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
1118   GoogleStyle.DerivePointerAlignment = true;
1119   GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1120                                                 {"^<.*\\.h>", 1, 0, false},
1121                                                 {"^<.*", 2, 0, false},
1122                                                 {".*", 3, 0, false}};
1123   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1124   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1125   GoogleStyle.IndentCaseLabels = true;
1126   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
1127   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
1128   GoogleStyle.ObjCSpaceAfterProperty = false;
1129   GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1130   GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
1131   GoogleStyle.RawStringFormats = {
1132       {
1133           FormatStyle::LK_Cpp,
1134           /*Delimiters=*/
1135           {
1136               "cc",
1137               "CC",
1138               "cpp",
1139               "Cpp",
1140               "CPP",
1141               "c++",
1142               "C++",
1143           },
1144           /*EnclosingFunctionNames=*/
1145           {},
1146           /*CanonicalDelimiter=*/"",
1147           /*BasedOnStyle=*/"google",
1148       },
1149       {
1150           FormatStyle::LK_TextProto,
1151           /*Delimiters=*/
1152           {
1153               "pb",
1154               "PB",
1155               "proto",
1156               "PROTO",
1157           },
1158           /*EnclosingFunctionNames=*/
1159           {
1160               "EqualsProto",
1161               "EquivToProto",
1162               "PARSE_PARTIAL_TEXT_PROTO",
1163               "PARSE_TEST_PROTO",
1164               "PARSE_TEXT_PROTO",
1165               "ParseTextOrDie",
1166               "ParseTextProtoOrDie",
1167               "ParseTestProto",
1168               "ParsePartialTestProto",
1169           },
1170           /*CanonicalDelimiter=*/"pb",
1171           /*BasedOnStyle=*/"google",
1172       },
1173   };
1174   GoogleStyle.SpacesBeforeTrailingComments = 2;
1175   GoogleStyle.Standard = FormatStyle::LS_Auto;
1176 
1177   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1178   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
1179 
1180   if (Language == FormatStyle::LK_Java) {
1181     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1182     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1183     GoogleStyle.AlignTrailingComments = false;
1184     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1185     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1186     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1187     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
1188     GoogleStyle.ColumnLimit = 100;
1189     GoogleStyle.SpaceAfterCStyleCast = true;
1190     GoogleStyle.SpacesBeforeTrailingComments = 1;
1191   } else if (Language == FormatStyle::LK_JavaScript) {
1192     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
1193     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1194     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1195     // TODO: still under discussion whether to switch to SLS_All.
1196     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
1197     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1198     GoogleStyle.BreakBeforeTernaryOperators = false;
1199     // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1200     // commonly followed by overlong URLs.
1201     GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1202     // TODO: enable once decided, in particular re disabling bin packing.
1203     // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1204     // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1205     GoogleStyle.MaxEmptyLinesToKeep = 3;
1206     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1207     GoogleStyle.SpacesInContainerLiterals = false;
1208     GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
1209     GoogleStyle.JavaScriptWrapImports = false;
1210   } else if (Language == FormatStyle::LK_Proto) {
1211     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1212     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1213     GoogleStyle.SpacesInContainerLiterals = false;
1214     GoogleStyle.Cpp11BracedListStyle = false;
1215     // This affects protocol buffer options specifications and text protos.
1216     // Text protos are currently mostly formatted inside C++ raw string literals
1217     // and often the current breaking behavior of string literals is not
1218     // beneficial there. Investigate turning this on once proper string reflow
1219     // has been implemented.
1220     GoogleStyle.BreakStringLiterals = false;
1221   } else if (Language == FormatStyle::LK_ObjC) {
1222     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1223     GoogleStyle.ColumnLimit = 100;
1224     // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1225     // relationship between ObjC standard library headers and other heades,
1226     // #imports, etc.)
1227     GoogleStyle.IncludeStyle.IncludeBlocks =
1228         tooling::IncludeStyle::IBS_Preserve;
1229   } else if (Language == FormatStyle::LK_CSharp) {
1230     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1231     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1232     GoogleStyle.BreakStringLiterals = false;
1233     GoogleStyle.ColumnLimit = 100;
1234     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1235   }
1236 
1237   return GoogleStyle;
1238 }
1239 
1240 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
1241   FormatStyle ChromiumStyle = getGoogleStyle(Language);
1242 
1243   // Disable include reordering across blocks in Chromium code.
1244   // - clang-format tries to detect that foo.h is the "main" header for
1245   //   foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1246   //   uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1247   //   _private.cc, _impl.cc etc) in different permutations
1248   //   (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1249   //   better default for Chromium code.
1250   // - The default for .cc and .mm files is different (r357695) for Google style
1251   //   for the same reason. The plan is to unify this again once the main
1252   //   header detection works for Google's ObjC code, but this hasn't happened
1253   //   yet. Since Chromium has some ObjC code, switching Chromium is blocked
1254   //   on that.
1255   // - Finally, "If include reordering is harmful, put things in different
1256   //   blocks to prevent it" has been a recommendation for a long time that
1257   //   people are used to. We'll need a dev education push to change this to
1258   //   "If include reordering is harmful, put things in a different block and
1259   //   _prepend that with a comment_ to prevent it" before changing behavior.
1260   ChromiumStyle.IncludeStyle.IncludeBlocks =
1261       tooling::IncludeStyle::IBS_Preserve;
1262 
1263   if (Language == FormatStyle::LK_Java) {
1264     ChromiumStyle.AllowShortIfStatementsOnASingleLine =
1265         FormatStyle::SIS_WithoutElse;
1266     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
1267     ChromiumStyle.ContinuationIndentWidth = 8;
1268     ChromiumStyle.IndentWidth = 4;
1269     // See styleguide for import groups:
1270     // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order
1271     ChromiumStyle.JavaImportGroups = {
1272         "android",
1273         "androidx",
1274         "com",
1275         "dalvik",
1276         "junit",
1277         "org",
1278         "com.google.android.apps.chrome",
1279         "org.chromium",
1280         "java",
1281         "javax",
1282     };
1283     ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1284   } else if (Language == FormatStyle::LK_JavaScript) {
1285     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1286     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1287   } else {
1288     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1289     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1290     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1291     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1292     ChromiumStyle.BinPackParameters = false;
1293     ChromiumStyle.DerivePointerAlignment = false;
1294     if (Language == FormatStyle::LK_ObjC)
1295       ChromiumStyle.ColumnLimit = 80;
1296   }
1297   return ChromiumStyle;
1298 }
1299 
1300 FormatStyle getMozillaStyle() {
1301   FormatStyle MozillaStyle = getLLVMStyle();
1302   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1303   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1304   MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel;
1305   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
1306       FormatStyle::DRTBS_TopLevel;
1307   MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1308   MozillaStyle.BinPackParameters = false;
1309   MozillaStyle.BinPackArguments = false;
1310   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
1311   MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1312   MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1313   MozillaStyle.ConstructorInitializerIndentWidth = 2;
1314   MozillaStyle.ContinuationIndentWidth = 2;
1315   MozillaStyle.Cpp11BracedListStyle = false;
1316   MozillaStyle.FixNamespaceComments = false;
1317   MozillaStyle.IndentCaseLabels = true;
1318   MozillaStyle.ObjCSpaceAfterProperty = true;
1319   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
1320   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1321   MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
1322   MozillaStyle.SpaceAfterTemplateKeyword = false;
1323   return MozillaStyle;
1324 }
1325 
1326 FormatStyle getWebKitStyle() {
1327   FormatStyle Style = getLLVMStyle();
1328   Style.AccessModifierOffset = -4;
1329   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1330   Style.AlignOperands = FormatStyle::OAS_DontAlign;
1331   Style.AlignTrailingComments = false;
1332   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1333   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1334   Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
1335   Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1336   Style.Cpp11BracedListStyle = false;
1337   Style.ColumnLimit = 0;
1338   Style.FixNamespaceComments = false;
1339   Style.IndentWidth = 4;
1340   Style.NamespaceIndentation = FormatStyle::NI_Inner;
1341   Style.ObjCBlockIndentWidth = 4;
1342   Style.ObjCSpaceAfterProperty = true;
1343   Style.PointerAlignment = FormatStyle::PAS_Left;
1344   Style.SpaceBeforeCpp11BracedList = true;
1345   Style.SpaceInEmptyBlock = true;
1346   return Style;
1347 }
1348 
1349 FormatStyle getGNUStyle() {
1350   FormatStyle Style = getLLVMStyle();
1351   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
1352   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1353   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1354   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
1355   Style.BreakBeforeTernaryOperators = true;
1356   Style.Cpp11BracedListStyle = false;
1357   Style.ColumnLimit = 79;
1358   Style.FixNamespaceComments = false;
1359   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
1360   Style.Standard = FormatStyle::LS_Cpp03;
1361   return Style;
1362 }
1363 
1364 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
1365   FormatStyle Style = getLLVMStyle(Language);
1366   Style.ColumnLimit = 120;
1367   Style.TabWidth = 4;
1368   Style.IndentWidth = 4;
1369   Style.UseTab = FormatStyle::UT_Never;
1370   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1371   Style.BraceWrapping.AfterClass = true;
1372   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1373   Style.BraceWrapping.AfterEnum = true;
1374   Style.BraceWrapping.AfterFunction = true;
1375   Style.BraceWrapping.AfterNamespace = true;
1376   Style.BraceWrapping.AfterObjCDeclaration = true;
1377   Style.BraceWrapping.AfterStruct = true;
1378   Style.BraceWrapping.AfterExternBlock = true;
1379   Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1380   Style.BraceWrapping.BeforeCatch = true;
1381   Style.BraceWrapping.BeforeElse = true;
1382   Style.BraceWrapping.BeforeWhile = false;
1383   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
1384   Style.AllowShortEnumsOnASingleLine = false;
1385   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
1386   Style.AllowShortCaseLabelsOnASingleLine = false;
1387   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1388   Style.AllowShortLoopsOnASingleLine = false;
1389   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1390   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
1391   return Style;
1392 }
1393 
1394 FormatStyle getNoStyle() {
1395   FormatStyle NoStyle = getLLVMStyle();
1396   NoStyle.DisableFormat = true;
1397   NoStyle.SortIncludes = FormatStyle::SI_Never;
1398   NoStyle.SortUsingDeclarations = false;
1399   return NoStyle;
1400 }
1401 
1402 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
1403                         FormatStyle *Style) {
1404   if (Name.equals_lower("llvm")) {
1405     *Style = getLLVMStyle(Language);
1406   } else if (Name.equals_lower("chromium")) {
1407     *Style = getChromiumStyle(Language);
1408   } else if (Name.equals_lower("mozilla")) {
1409     *Style = getMozillaStyle();
1410   } else if (Name.equals_lower("google")) {
1411     *Style = getGoogleStyle(Language);
1412   } else if (Name.equals_lower("webkit")) {
1413     *Style = getWebKitStyle();
1414   } else if (Name.equals_lower("gnu")) {
1415     *Style = getGNUStyle();
1416   } else if (Name.equals_lower("microsoft")) {
1417     *Style = getMicrosoftStyle(Language);
1418   } else if (Name.equals_lower("none")) {
1419     *Style = getNoStyle();
1420   } else if (Name.equals_lower("inheritparentconfig")) {
1421     Style->InheritsParentConfig = true;
1422   } else {
1423     return false;
1424   }
1425 
1426   Style->Language = Language;
1427   return true;
1428 }
1429 
1430 std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
1431                                    FormatStyle *Style, bool AllowUnknownOptions,
1432                                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
1433                                    void *DiagHandlerCtxt) {
1434   assert(Style);
1435   FormatStyle::LanguageKind Language = Style->Language;
1436   assert(Language != FormatStyle::LK_None);
1437   if (Config.getBuffer().trim().empty())
1438     return make_error_code(ParseError::Error);
1439   Style->StyleSet.Clear();
1440   std::vector<FormatStyle> Styles;
1441   llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
1442                           DiagHandlerCtxt);
1443   // DocumentListTraits<vector<FormatStyle>> uses the context to get default
1444   // values for the fields, keys for which are missing from the configuration.
1445   // Mapping also uses the context to get the language to find the correct
1446   // base style.
1447   Input.setContext(Style);
1448   Input.setAllowUnknownKeys(AllowUnknownOptions);
1449   Input >> Styles;
1450   if (Input.error())
1451     return Input.error();
1452 
1453   for (unsigned i = 0; i < Styles.size(); ++i) {
1454     // Ensures that only the first configuration can skip the Language option.
1455     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
1456       return make_error_code(ParseError::Error);
1457     // Ensure that each language is configured at most once.
1458     for (unsigned j = 0; j < i; ++j) {
1459       if (Styles[i].Language == Styles[j].Language) {
1460         LLVM_DEBUG(llvm::dbgs()
1461                    << "Duplicate languages in the config file on positions "
1462                    << j << " and " << i << "\n");
1463         return make_error_code(ParseError::Error);
1464       }
1465     }
1466   }
1467   // Look for a suitable configuration starting from the end, so we can
1468   // find the configuration for the specific language first, and the default
1469   // configuration (which can only be at slot 0) after it.
1470   FormatStyle::FormatStyleSet StyleSet;
1471   bool LanguageFound = false;
1472   for (int i = Styles.size() - 1; i >= 0; --i) {
1473     if (Styles[i].Language != FormatStyle::LK_None)
1474       StyleSet.Add(Styles[i]);
1475     if (Styles[i].Language == Language)
1476       LanguageFound = true;
1477   }
1478   if (!LanguageFound) {
1479     if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
1480       return make_error_code(ParseError::Unsuitable);
1481     FormatStyle DefaultStyle = Styles[0];
1482     DefaultStyle.Language = Language;
1483     StyleSet.Add(std::move(DefaultStyle));
1484   }
1485   *Style = *StyleSet.Get(Language);
1486   if (Style->InsertTrailingCommas != FormatStyle::TCS_None &&
1487       Style->BinPackArguments) {
1488     // See comment on FormatStyle::TSC_Wrapped.
1489     return make_error_code(ParseError::BinPackTrailingCommaConflict);
1490   }
1491   return make_error_code(ParseError::Success);
1492 }
1493 
1494 std::string configurationAsText(const FormatStyle &Style) {
1495   std::string Text;
1496   llvm::raw_string_ostream Stream(Text);
1497   llvm::yaml::Output Output(Stream);
1498   // We use the same mapping method for input and output, so we need a non-const
1499   // reference here.
1500   FormatStyle NonConstStyle = expandPresets(Style);
1501   Output << NonConstStyle;
1502   return Stream.str();
1503 }
1504 
1505 llvm::Optional<FormatStyle>
1506 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
1507   if (!Styles)
1508     return None;
1509   auto It = Styles->find(Language);
1510   if (It == Styles->end())
1511     return None;
1512   FormatStyle Style = It->second;
1513   Style.StyleSet = *this;
1514   return Style;
1515 }
1516 
1517 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
1518   assert(Style.Language != LK_None &&
1519          "Cannot add a style for LK_None to a StyleSet");
1520   assert(
1521       !Style.StyleSet.Styles &&
1522       "Cannot add a style associated with an existing StyleSet to a StyleSet");
1523   if (!Styles)
1524     Styles = std::make_shared<MapType>();
1525   (*Styles)[Style.Language] = std::move(Style);
1526 }
1527 
1528 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
1529 
1530 llvm::Optional<FormatStyle>
1531 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
1532   return StyleSet.Get(Language);
1533 }
1534 
1535 namespace {
1536 
1537 class JavaScriptRequoter : public TokenAnalyzer {
1538 public:
1539   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
1540       : TokenAnalyzer(Env, Style) {}
1541 
1542   std::pair<tooling::Replacements, unsigned>
1543   analyze(TokenAnnotator &Annotator,
1544           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1545           FormatTokenLexer &Tokens) override {
1546     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1547     tooling::Replacements Result;
1548     requoteJSStringLiteral(AnnotatedLines, Result);
1549     return {Result, 0};
1550   }
1551 
1552 private:
1553   // Replaces double/single-quoted string literal as appropriate, re-escaping
1554   // the contents in the process.
1555   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
1556                               tooling::Replacements &Result) {
1557     for (AnnotatedLine *Line : Lines) {
1558       requoteJSStringLiteral(Line->Children, Result);
1559       if (!Line->Affected)
1560         continue;
1561       for (FormatToken *FormatTok = Line->First; FormatTok;
1562            FormatTok = FormatTok->Next) {
1563         StringRef Input = FormatTok->TokenText;
1564         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1565             // NB: testing for not starting with a double quote to avoid
1566             // breaking `template strings`.
1567             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
1568              !Input.startswith("\"")) ||
1569             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
1570              !Input.startswith("\'")))
1571           continue;
1572 
1573         // Change start and end quote.
1574         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
1575         SourceLocation Start = FormatTok->Tok.getLocation();
1576         auto Replace = [&](SourceLocation Start, unsigned Length,
1577                            StringRef ReplacementText) {
1578           auto Err = Result.add(tooling::Replacement(
1579               Env.getSourceManager(), Start, Length, ReplacementText));
1580           // FIXME: handle error. For now, print error message and skip the
1581           // replacement for release version.
1582           if (Err) {
1583             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1584             assert(false);
1585           }
1586         };
1587         Replace(Start, 1, IsSingle ? "'" : "\"");
1588         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1589                 IsSingle ? "'" : "\"");
1590 
1591         // Escape internal quotes.
1592         bool Escaped = false;
1593         for (size_t i = 1; i < Input.size() - 1; i++) {
1594           switch (Input[i]) {
1595           case '\\':
1596             if (!Escaped && i + 1 < Input.size() &&
1597                 ((IsSingle && Input[i + 1] == '"') ||
1598                  (!IsSingle && Input[i + 1] == '\''))) {
1599               // Remove this \, it's escaping a " or ' that no longer needs
1600               // escaping
1601               Replace(Start.getLocWithOffset(i), 1, "");
1602               continue;
1603             }
1604             Escaped = !Escaped;
1605             break;
1606           case '\"':
1607           case '\'':
1608             if (!Escaped && IsSingle == (Input[i] == '\'')) {
1609               // Escape the quote.
1610               Replace(Start.getLocWithOffset(i), 0, "\\");
1611             }
1612             Escaped = false;
1613             break;
1614           default:
1615             Escaped = false;
1616             break;
1617           }
1618         }
1619       }
1620     }
1621   }
1622 };
1623 
1624 class Formatter : public TokenAnalyzer {
1625 public:
1626   Formatter(const Environment &Env, const FormatStyle &Style,
1627             FormattingAttemptStatus *Status)
1628       : TokenAnalyzer(Env, Style), Status(Status) {}
1629 
1630   std::pair<tooling::Replacements, unsigned>
1631   analyze(TokenAnnotator &Annotator,
1632           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1633           FormatTokenLexer &Tokens) override {
1634     tooling::Replacements Result;
1635     deriveLocalStyle(AnnotatedLines);
1636     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1637     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1638       Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
1639     }
1640     Annotator.setCommentLineLevels(AnnotatedLines);
1641 
1642     WhitespaceManager Whitespaces(
1643         Env.getSourceManager(), Style,
1644         Style.DeriveLineEnding
1645             ? inputUsesCRLF(
1646                   Env.getSourceManager().getBufferData(Env.getFileID()),
1647                   Style.UseCRLF)
1648             : Style.UseCRLF);
1649     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
1650                                   Env.getSourceManager(), Whitespaces, Encoding,
1651                                   BinPackInconclusiveFunctions);
1652     unsigned Penalty =
1653         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
1654                                Tokens.getKeywords(), Env.getSourceManager(),
1655                                Status)
1656             .format(AnnotatedLines, /*DryRun=*/false,
1657                     /*AdditionalIndent=*/0,
1658                     /*FixBadIndentation=*/false,
1659                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
1660                     /*NextStartColumn=*/Env.getNextStartColumn(),
1661                     /*LastStartColumn=*/Env.getLastStartColumn());
1662     for (const auto &R : Whitespaces.generateReplacements())
1663       if (Result.add(R))
1664         return std::make_pair(Result, 0);
1665     return std::make_pair(Result, Penalty);
1666   }
1667 
1668 private:
1669   static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF) {
1670     size_t LF = Text.count('\n');
1671     size_t CR = Text.count('\r') * 2;
1672     return LF == CR ? DefaultToCRLF : CR > LF;
1673   }
1674 
1675   bool
1676   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1677     for (const AnnotatedLine *Line : Lines) {
1678       if (hasCpp03IncompatibleFormat(Line->Children))
1679         return true;
1680       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
1681         if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) {
1682           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
1683             return true;
1684           if (Tok->is(TT_TemplateCloser) &&
1685               Tok->Previous->is(TT_TemplateCloser))
1686             return true;
1687         }
1688       }
1689     }
1690     return false;
1691   }
1692 
1693   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1694     int AlignmentDiff = 0;
1695     for (const AnnotatedLine *Line : Lines) {
1696       AlignmentDiff += countVariableAlignments(Line->Children);
1697       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
1698         if (!Tok->is(TT_PointerOrReference))
1699           continue;
1700         bool SpaceBefore =
1701             Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd();
1702         bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() !=
1703                           Tok->Next->WhitespaceRange.getEnd();
1704         if (SpaceBefore && !SpaceAfter)
1705           ++AlignmentDiff;
1706         if (!SpaceBefore && SpaceAfter)
1707           --AlignmentDiff;
1708       }
1709     }
1710     return AlignmentDiff;
1711   }
1712 
1713   void
1714   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1715     bool HasBinPackedFunction = false;
1716     bool HasOnePerLineFunction = false;
1717     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1718       if (!AnnotatedLines[i]->First->Next)
1719         continue;
1720       FormatToken *Tok = AnnotatedLines[i]->First->Next;
1721       while (Tok->Next) {
1722         if (Tok->is(PPK_BinPacked))
1723           HasBinPackedFunction = true;
1724         if (Tok->is(PPK_OnePerLine))
1725           HasOnePerLineFunction = true;
1726 
1727         Tok = Tok->Next;
1728       }
1729     }
1730     if (Style.DerivePointerAlignment)
1731       Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
1732                                    ? FormatStyle::PAS_Left
1733                                    : FormatStyle::PAS_Right;
1734     if (Style.Standard == FormatStyle::LS_Auto)
1735       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
1736                            ? FormatStyle::LS_Latest
1737                            : FormatStyle::LS_Cpp03;
1738     BinPackInconclusiveFunctions =
1739         HasBinPackedFunction || !HasOnePerLineFunction;
1740   }
1741 
1742   bool BinPackInconclusiveFunctions;
1743   FormattingAttemptStatus *Status;
1744 };
1745 
1746 /// TrailingCommaInserter inserts trailing commas into container literals.
1747 /// E.g.:
1748 ///     const x = [
1749 ///       1,
1750 ///     ];
1751 /// TrailingCommaInserter runs after formatting. To avoid causing a required
1752 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
1753 /// ColumnLimit.
1754 ///
1755 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
1756 /// is conceptually incompatible with bin packing.
1757 class TrailingCommaInserter : public TokenAnalyzer {
1758 public:
1759   TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
1760       : TokenAnalyzer(Env, Style) {}
1761 
1762   std::pair<tooling::Replacements, unsigned>
1763   analyze(TokenAnnotator &Annotator,
1764           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1765           FormatTokenLexer &Tokens) override {
1766     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1767     tooling::Replacements Result;
1768     insertTrailingCommas(AnnotatedLines, Result);
1769     return {Result, 0};
1770   }
1771 
1772 private:
1773   /// Inserts trailing commas in [] and {} initializers if they wrap over
1774   /// multiple lines.
1775   void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
1776                             tooling::Replacements &Result) {
1777     for (AnnotatedLine *Line : Lines) {
1778       insertTrailingCommas(Line->Children, Result);
1779       if (!Line->Affected)
1780         continue;
1781       for (FormatToken *FormatTok = Line->First; FormatTok;
1782            FormatTok = FormatTok->Next) {
1783         if (FormatTok->NewlinesBefore == 0)
1784           continue;
1785         FormatToken *Matching = FormatTok->MatchingParen;
1786         if (!Matching || !FormatTok->getPreviousNonComment())
1787           continue;
1788         if (!(FormatTok->is(tok::r_square) &&
1789               Matching->is(TT_ArrayInitializerLSquare)) &&
1790             !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral)))
1791           continue;
1792         FormatToken *Prev = FormatTok->getPreviousNonComment();
1793         if (Prev->is(tok::comma) || Prev->is(tok::semi))
1794           continue;
1795         // getEndLoc is not reliably set during re-lexing, use text length
1796         // instead.
1797         SourceLocation Start =
1798             Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
1799         // If inserting a comma would push the code over the column limit, skip
1800         // this location - it'd introduce an unstable formatting due to the
1801         // required reflow.
1802         unsigned ColumnNumber =
1803             Env.getSourceManager().getSpellingColumnNumber(Start);
1804         if (ColumnNumber > Style.ColumnLimit)
1805           continue;
1806         // Comma insertions cannot conflict with each other, and this pass has a
1807         // clean set of Replacements, so the operation below cannot fail.
1808         cantFail(Result.add(
1809             tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
1810       }
1811     }
1812   }
1813 };
1814 
1815 // This class clean up the erroneous/redundant code around the given ranges in
1816 // file.
1817 class Cleaner : public TokenAnalyzer {
1818 public:
1819   Cleaner(const Environment &Env, const FormatStyle &Style)
1820       : TokenAnalyzer(Env, Style),
1821         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
1822 
1823   // FIXME: eliminate unused parameters.
1824   std::pair<tooling::Replacements, unsigned>
1825   analyze(TokenAnnotator &Annotator,
1826           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1827           FormatTokenLexer &Tokens) override {
1828     // FIXME: in the current implementation the granularity of affected range
1829     // is an annotated line. However, this is not sufficient. Furthermore,
1830     // redundant code introduced by replacements does not necessarily
1831     // intercept with ranges of replacements that result in the redundancy.
1832     // To determine if some redundant code is actually introduced by
1833     // replacements(e.g. deletions), we need to come up with a more
1834     // sophisticated way of computing affected ranges.
1835     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1836 
1837     checkEmptyNamespace(AnnotatedLines);
1838 
1839     for (auto *Line : AnnotatedLines)
1840       cleanupLine(Line);
1841 
1842     return {generateFixes(), 0};
1843   }
1844 
1845 private:
1846   void cleanupLine(AnnotatedLine *Line) {
1847     for (auto *Child : Line->Children) {
1848       cleanupLine(Child);
1849     }
1850 
1851     if (Line->Affected) {
1852       cleanupRight(Line->First, tok::comma, tok::comma);
1853       cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
1854       cleanupRight(Line->First, tok::l_paren, tok::comma);
1855       cleanupLeft(Line->First, tok::comma, tok::r_paren);
1856       cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
1857       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
1858       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
1859     }
1860   }
1861 
1862   bool containsOnlyComments(const AnnotatedLine &Line) {
1863     for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) {
1864       if (Tok->isNot(tok::comment))
1865         return false;
1866     }
1867     return true;
1868   }
1869 
1870   // Iterate through all lines and remove any empty (nested) namespaces.
1871   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1872     std::set<unsigned> DeletedLines;
1873     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1874       auto &Line = *AnnotatedLines[i];
1875       if (Line.startsWithNamespace()) {
1876         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
1877       }
1878     }
1879 
1880     for (auto Line : DeletedLines) {
1881       FormatToken *Tok = AnnotatedLines[Line]->First;
1882       while (Tok) {
1883         deleteToken(Tok);
1884         Tok = Tok->Next;
1885       }
1886     }
1887   }
1888 
1889   // The function checks if the namespace, which starts from \p CurrentLine, and
1890   // its nested namespaces are empty and delete them if they are empty. It also
1891   // sets \p NewLine to the last line checked.
1892   // Returns true if the current namespace is empty.
1893   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1894                            unsigned CurrentLine, unsigned &NewLine,
1895                            std::set<unsigned> &DeletedLines) {
1896     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
1897     if (Style.BraceWrapping.AfterNamespace) {
1898       // If the left brace is in a new line, we should consume it first so that
1899       // it does not make the namespace non-empty.
1900       // FIXME: error handling if there is no left brace.
1901       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
1902         NewLine = CurrentLine;
1903         return false;
1904       }
1905     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
1906       return false;
1907     }
1908     while (++CurrentLine < End) {
1909       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
1910         break;
1911 
1912       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
1913         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
1914                                  DeletedLines))
1915           return false;
1916         CurrentLine = NewLine;
1917         continue;
1918       }
1919 
1920       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
1921         continue;
1922 
1923       // If there is anything other than comments or nested namespaces in the
1924       // current namespace, the namespace cannot be empty.
1925       NewLine = CurrentLine;
1926       return false;
1927     }
1928 
1929     NewLine = CurrentLine;
1930     if (CurrentLine >= End)
1931       return false;
1932 
1933     // Check if the empty namespace is actually affected by changed ranges.
1934     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
1935             AnnotatedLines[InitLine]->First->Tok.getLocation(),
1936             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
1937       return false;
1938 
1939     for (unsigned i = InitLine; i <= CurrentLine; ++i) {
1940       DeletedLines.insert(i);
1941     }
1942 
1943     return true;
1944   }
1945 
1946   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
1947   // of the token in the pair if the left token has \p LK token kind and the
1948   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
1949   // is deleted on match; otherwise, the right token is deleted.
1950   template <typename LeftKind, typename RightKind>
1951   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
1952                    bool DeleteLeft) {
1953     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
1954       for (auto *Res = Tok.Next; Res; Res = Res->Next)
1955         if (!Res->is(tok::comment) &&
1956             DeletedTokens.find(Res) == DeletedTokens.end())
1957           return Res;
1958       return nullptr;
1959     };
1960     for (auto *Left = Start; Left;) {
1961       auto *Right = NextNotDeleted(*Left);
1962       if (!Right)
1963         break;
1964       if (Left->is(LK) && Right->is(RK)) {
1965         deleteToken(DeleteLeft ? Left : Right);
1966         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
1967           deleteToken(Tok);
1968         // If the right token is deleted, we should keep the left token
1969         // unchanged and pair it with the new right token.
1970         if (!DeleteLeft)
1971           continue;
1972       }
1973       Left = Right;
1974     }
1975   }
1976 
1977   template <typename LeftKind, typename RightKind>
1978   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
1979     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
1980   }
1981 
1982   template <typename LeftKind, typename RightKind>
1983   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
1984     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
1985   }
1986 
1987   // Delete the given token.
1988   inline void deleteToken(FormatToken *Tok) {
1989     if (Tok)
1990       DeletedTokens.insert(Tok);
1991   }
1992 
1993   tooling::Replacements generateFixes() {
1994     tooling::Replacements Fixes;
1995     std::vector<FormatToken *> Tokens;
1996     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
1997               std::back_inserter(Tokens));
1998 
1999     // Merge multiple continuous token deletions into one big deletion so that
2000     // the number of replacements can be reduced. This makes computing affected
2001     // ranges more efficient when we run reformat on the changed code.
2002     unsigned Idx = 0;
2003     while (Idx < Tokens.size()) {
2004       unsigned St = Idx, End = Idx;
2005       while ((End + 1) < Tokens.size() &&
2006              Tokens[End]->Next == Tokens[End + 1]) {
2007         End++;
2008       }
2009       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2010                                               Tokens[End]->Tok.getEndLoc());
2011       auto Err =
2012           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2013       // FIXME: better error handling. for now just print error message and skip
2014       // for the release version.
2015       if (Err) {
2016         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2017         assert(false && "Fixes must not conflict!");
2018       }
2019       Idx = End + 1;
2020     }
2021 
2022     return Fixes;
2023   }
2024 
2025   // Class for less-than inequality comparason for the set `RedundantTokens`.
2026   // We store tokens in the order they appear in the translation unit so that
2027   // we do not need to sort them in `generateFixes()`.
2028   struct FormatTokenLess {
2029     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2030 
2031     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2032       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2033                                           RHS->Tok.getLocation());
2034     }
2035     const SourceManager &SM;
2036   };
2037 
2038   // Tokens to be deleted.
2039   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2040 };
2041 
2042 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2043 public:
2044   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2045       : TokenAnalyzer(Env, Style), IsObjC(false) {}
2046 
2047   std::pair<tooling::Replacements, unsigned>
2048   analyze(TokenAnnotator &Annotator,
2049           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2050           FormatTokenLexer &Tokens) override {
2051     assert(Style.Language == FormatStyle::LK_Cpp);
2052     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2053                          Tokens.getKeywords());
2054     tooling::Replacements Result;
2055     return {Result, 0};
2056   }
2057 
2058   bool isObjC() { return IsObjC; }
2059 
2060 private:
2061   static bool
2062   guessIsObjC(const SourceManager &SourceManager,
2063               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2064               const AdditionalKeywords &Keywords) {
2065     // Keep this array sorted, since we are binary searching over it.
2066     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2067         "CGFloat",
2068         "CGPoint",
2069         "CGPointMake",
2070         "CGPointZero",
2071         "CGRect",
2072         "CGRectEdge",
2073         "CGRectInfinite",
2074         "CGRectMake",
2075         "CGRectNull",
2076         "CGRectZero",
2077         "CGSize",
2078         "CGSizeMake",
2079         "CGVector",
2080         "CGVectorMake",
2081         "NSAffineTransform",
2082         "NSArray",
2083         "NSAttributedString",
2084         "NSBlockOperation",
2085         "NSBundle",
2086         "NSCache",
2087         "NSCalendar",
2088         "NSCharacterSet",
2089         "NSCountedSet",
2090         "NSData",
2091         "NSDataDetector",
2092         "NSDecimal",
2093         "NSDecimalNumber",
2094         "NSDictionary",
2095         "NSEdgeInsets",
2096         "NSHashTable",
2097         "NSIndexPath",
2098         "NSIndexSet",
2099         "NSInteger",
2100         "NSInvocationOperation",
2101         "NSLocale",
2102         "NSMapTable",
2103         "NSMutableArray",
2104         "NSMutableAttributedString",
2105         "NSMutableCharacterSet",
2106         "NSMutableData",
2107         "NSMutableDictionary",
2108         "NSMutableIndexSet",
2109         "NSMutableOrderedSet",
2110         "NSMutableSet",
2111         "NSMutableString",
2112         "NSNumber",
2113         "NSNumberFormatter",
2114         "NSObject",
2115         "NSOperation",
2116         "NSOperationQueue",
2117         "NSOperationQueuePriority",
2118         "NSOrderedSet",
2119         "NSPoint",
2120         "NSPointerArray",
2121         "NSQualityOfService",
2122         "NSRange",
2123         "NSRect",
2124         "NSRegularExpression",
2125         "NSSet",
2126         "NSSize",
2127         "NSString",
2128         "NSTimeZone",
2129         "NSUInteger",
2130         "NSURL",
2131         "NSURLComponents",
2132         "NSURLQueryItem",
2133         "NSUUID",
2134         "NSValue",
2135         "UIImage",
2136         "UIView",
2137     };
2138 
2139     for (auto Line : AnnotatedLines) {
2140       if (Line->First && (Line->First->TokenText.startswith("#") ||
2141                           Line->First->TokenText == "__pragma" ||
2142                           Line->First->TokenText == "_Pragma"))
2143         continue;
2144       for (const FormatToken *FormatTok = Line->First; FormatTok;
2145            FormatTok = FormatTok->Next) {
2146         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
2147              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
2148               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
2149                                  tok::l_brace))) ||
2150             (FormatTok->Tok.isAnyIdentifier() &&
2151              std::binary_search(std::begin(FoundationIdentifiers),
2152                                 std::end(FoundationIdentifiers),
2153                                 FormatTok->TokenText)) ||
2154             FormatTok->is(TT_ObjCStringLiteral) ||
2155             FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
2156                                Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
2157                                TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
2158                                TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
2159                                TT_ObjCProperty)) {
2160           LLVM_DEBUG(llvm::dbgs()
2161                      << "Detected ObjC at location "
2162                      << FormatTok->Tok.getLocation().printToString(
2163                             SourceManager)
2164                      << " token: " << FormatTok->TokenText << " token type: "
2165                      << getTokenTypeName(FormatTok->getType()) << "\n");
2166           return true;
2167         }
2168         if (guessIsObjC(SourceManager, Line->Children, Keywords))
2169           return true;
2170       }
2171     }
2172     return false;
2173   }
2174 
2175   bool IsObjC;
2176 };
2177 
2178 struct IncludeDirective {
2179   StringRef Filename;
2180   StringRef Text;
2181   unsigned Offset;
2182   int Category;
2183   int Priority;
2184 };
2185 
2186 struct JavaImportDirective {
2187   StringRef Identifier;
2188   StringRef Text;
2189   unsigned Offset;
2190   std::vector<StringRef> AssociatedCommentLines;
2191   bool IsStatic;
2192 };
2193 
2194 } // end anonymous namespace
2195 
2196 // Determines whether 'Ranges' intersects with ('Start', 'End').
2197 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
2198                          unsigned End) {
2199   for (auto Range : Ranges) {
2200     if (Range.getOffset() < End &&
2201         Range.getOffset() + Range.getLength() > Start)
2202       return true;
2203   }
2204   return false;
2205 }
2206 
2207 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
2208 // before sorting/deduplicating. Index is the index of the include under the
2209 // cursor in the original set of includes. If this include has duplicates, it is
2210 // the index of the first of the duplicates as the others are going to be
2211 // removed. OffsetToEOL describes the cursor's position relative to the end of
2212 // its current line.
2213 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
2214 static std::pair<unsigned, unsigned>
2215 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
2216                 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) {
2217   unsigned CursorIndex = UINT_MAX;
2218   unsigned OffsetToEOL = 0;
2219   for (int i = 0, e = Includes.size(); i != e; ++i) {
2220     unsigned Start = Includes[Indices[i]].Offset;
2221     unsigned End = Start + Includes[Indices[i]].Text.size();
2222     if (!(Cursor >= Start && Cursor < End))
2223       continue;
2224     CursorIndex = Indices[i];
2225     OffsetToEOL = End - Cursor;
2226     // Put the cursor on the only remaining #include among the duplicate
2227     // #includes.
2228     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
2229       CursorIndex = i;
2230     break;
2231   }
2232   return std::make_pair(CursorIndex, OffsetToEOL);
2233 }
2234 
2235 // Replace all "\r\n" with "\n".
2236 std::string replaceCRLF(const std::string &Code) {
2237   std::string NewCode;
2238   size_t Pos = 0, LastPos = 0;
2239 
2240   do {
2241     Pos = Code.find("\r\n", LastPos);
2242     if (Pos == LastPos) {
2243       LastPos++;
2244       continue;
2245     }
2246     if (Pos == std::string::npos) {
2247       NewCode += Code.substr(LastPos);
2248       break;
2249     }
2250     NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
2251     LastPos = Pos + 2;
2252   } while (Pos != std::string::npos);
2253 
2254   return NewCode;
2255 }
2256 
2257 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
2258 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
2259 // source order.
2260 // #include directives with the same text will be deduplicated, and only the
2261 // first #include in the duplicate #includes remains. If the `Cursor` is
2262 // provided and put on a deleted #include, it will be moved to the remaining
2263 // #include in the duplicate #includes.
2264 static void sortCppIncludes(const FormatStyle &Style,
2265                             const SmallVectorImpl<IncludeDirective> &Includes,
2266                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2267                             StringRef Code, tooling::Replacements &Replaces,
2268                             unsigned *Cursor) {
2269   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2270   unsigned IncludesBeginOffset = Includes.front().Offset;
2271   unsigned IncludesEndOffset =
2272       Includes.back().Offset + Includes.back().Text.size();
2273   unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
2274   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
2275     return;
2276   SmallVector<unsigned, 16> Indices;
2277   for (unsigned i = 0, e = Includes.size(); i != e; ++i) {
2278     Indices.push_back(i);
2279   }
2280 
2281   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
2282     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2283       const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
2284       const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
2285       return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
2286                       Includes[LHSI].Filename) <
2287              std::tie(Includes[RHSI].Priority, RHSFilenameLower,
2288                       Includes[RHSI].Filename);
2289     });
2290   } else {
2291     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2292       return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
2293              std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
2294     });
2295   }
2296 
2297   // The index of the include on which the cursor will be put after
2298   // sorting/deduplicating.
2299   unsigned CursorIndex;
2300   // The offset from cursor to the end of line.
2301   unsigned CursorToEOLOffset;
2302   if (Cursor)
2303     std::tie(CursorIndex, CursorToEOLOffset) =
2304         FindCursorIndex(Includes, Indices, *Cursor);
2305 
2306   // Deduplicate #includes.
2307   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2308                             [&](unsigned LHSI, unsigned RHSI) {
2309                               return Includes[LHSI].Text.trim() ==
2310                                      Includes[RHSI].Text.trim();
2311                             }),
2312                 Indices.end());
2313 
2314   int CurrentCategory = Includes.front().Category;
2315 
2316   // If the #includes are out of order, we generate a single replacement fixing
2317   // the entire block. Otherwise, no replacement is generated.
2318   // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
2319   // enough as additional newlines might be added or removed across #include
2320   // blocks. This we handle below by generating the updated #imclude blocks and
2321   // comparing it to the original.
2322   if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) &&
2323       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
2324     return;
2325 
2326   std::string result;
2327   for (unsigned Index : Indices) {
2328     if (!result.empty()) {
2329       result += "\n";
2330       if (Style.IncludeStyle.IncludeBlocks ==
2331               tooling::IncludeStyle::IBS_Regroup &&
2332           CurrentCategory != Includes[Index].Category)
2333         result += "\n";
2334     }
2335     result += Includes[Index].Text;
2336     if (Cursor && CursorIndex == Index)
2337       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
2338     CurrentCategory = Includes[Index].Category;
2339   }
2340 
2341   // If the #includes are out of order, we generate a single replacement fixing
2342   // the entire range of blocks. Otherwise, no replacement is generated.
2343   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2344                                  IncludesBeginOffset, IncludesBlockSize))))
2345     return;
2346 
2347   auto Err = Replaces.add(tooling::Replacement(
2348       FileName, Includes.front().Offset, IncludesBlockSize, result));
2349   // FIXME: better error handling. For now, just skip the replacement for the
2350   // release version.
2351   if (Err) {
2352     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2353     assert(false);
2354   }
2355 }
2356 
2357 namespace {
2358 
2359 const char CppIncludeRegexPattern[] =
2360     R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))";
2361 
2362 } // anonymous namespace
2363 
2364 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
2365                                       ArrayRef<tooling::Range> Ranges,
2366                                       StringRef FileName,
2367                                       tooling::Replacements &Replaces,
2368                                       unsigned *Cursor) {
2369   unsigned Prev = llvm::StringSwitch<size_t>(Code)
2370                       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
2371                       .Default(0);
2372   unsigned SearchFrom = 0;
2373   llvm::Regex IncludeRegex(CppIncludeRegexPattern);
2374   SmallVector<StringRef, 4> Matches;
2375   SmallVector<IncludeDirective, 16> IncludesInBlock;
2376 
2377   // In compiled files, consider the first #include to be the main #include of
2378   // the file if it is not a system #include. This ensures that the header
2379   // doesn't have hidden dependencies
2380   // (http://llvm.org/docs/CodingStandards.html#include-style).
2381   //
2382   // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix
2383   // cases where the first #include is unlikely to be the main header.
2384   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2385   bool FirstIncludeBlock = true;
2386   bool MainIncludeFound = false;
2387   bool FormattingOff = false;
2388 
2389   for (;;) {
2390     auto Pos = Code.find('\n', SearchFrom);
2391     StringRef Line =
2392         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2393 
2394     StringRef Trimmed = Line.trim();
2395     if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
2396       FormattingOff = true;
2397     else if (Trimmed == "// clang-format on" ||
2398              Trimmed == "/* clang-format on */")
2399       FormattingOff = false;
2400 
2401     const bool EmptyLineSkipped =
2402         Trimmed.empty() &&
2403         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
2404          Style.IncludeStyle.IncludeBlocks ==
2405              tooling::IncludeStyle::IBS_Regroup);
2406 
2407     bool MergeWithNextLine = Trimmed.endswith("\\");
2408     if (!FormattingOff && !MergeWithNextLine) {
2409       if (IncludeRegex.match(Line, &Matches)) {
2410         StringRef IncludeName = Matches[2];
2411         int Category = Categories.getIncludePriority(
2412             IncludeName,
2413             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
2414         int Priority = Categories.getSortIncludePriority(
2415             IncludeName, !MainIncludeFound && FirstIncludeBlock);
2416         if (Category == 0)
2417           MainIncludeFound = true;
2418         IncludesInBlock.push_back(
2419             {IncludeName, Line, Prev, Category, Priority});
2420       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
2421         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
2422                         Replaces, Cursor);
2423         IncludesInBlock.clear();
2424         if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers.
2425           FirstIncludeBlock = true;
2426         else
2427           FirstIncludeBlock = false;
2428       }
2429     }
2430     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2431       break;
2432 
2433     if (!MergeWithNextLine)
2434       Prev = Pos + 1;
2435     SearchFrom = Pos + 1;
2436   }
2437   if (!IncludesInBlock.empty()) {
2438     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
2439                     Cursor);
2440   }
2441   return Replaces;
2442 }
2443 
2444 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
2445 // if the import does not match any given groups.
2446 static unsigned findJavaImportGroup(const FormatStyle &Style,
2447                                     StringRef ImportIdentifier) {
2448   unsigned LongestMatchIndex = UINT_MAX;
2449   unsigned LongestMatchLength = 0;
2450   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
2451     std::string GroupPrefix = Style.JavaImportGroups[I];
2452     if (ImportIdentifier.startswith(GroupPrefix) &&
2453         GroupPrefix.length() > LongestMatchLength) {
2454       LongestMatchIndex = I;
2455       LongestMatchLength = GroupPrefix.length();
2456     }
2457   }
2458   return LongestMatchIndex;
2459 }
2460 
2461 // Sorts and deduplicates a block of includes given by 'Imports' based on
2462 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
2463 // Import declarations with the same text will be deduplicated. Between each
2464 // import group, a newline is inserted, and within each import group, a
2465 // lexicographic sort based on ASCII value is performed.
2466 static void sortJavaImports(const FormatStyle &Style,
2467                             const SmallVectorImpl<JavaImportDirective> &Imports,
2468                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2469                             StringRef Code, tooling::Replacements &Replaces) {
2470   unsigned ImportsBeginOffset = Imports.front().Offset;
2471   unsigned ImportsEndOffset =
2472       Imports.back().Offset + Imports.back().Text.size();
2473   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
2474   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
2475     return;
2476   SmallVector<unsigned, 16> Indices;
2477   SmallVector<unsigned, 16> JavaImportGroups;
2478   for (unsigned i = 0, e = Imports.size(); i != e; ++i) {
2479     Indices.push_back(i);
2480     JavaImportGroups.push_back(
2481         findJavaImportGroup(Style, Imports[i].Identifier));
2482   }
2483   bool StaticImportAfterNormalImport =
2484       Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
2485   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2486     // Negating IsStatic to push static imports above non-static imports.
2487     return std::make_tuple(!Imports[LHSI].IsStatic ^
2488                                StaticImportAfterNormalImport,
2489                            JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
2490            std::make_tuple(!Imports[RHSI].IsStatic ^
2491                                StaticImportAfterNormalImport,
2492                            JavaImportGroups[RHSI], Imports[RHSI].Identifier);
2493   });
2494 
2495   // Deduplicate imports.
2496   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2497                             [&](unsigned LHSI, unsigned RHSI) {
2498                               return Imports[LHSI].Text == Imports[RHSI].Text;
2499                             }),
2500                 Indices.end());
2501 
2502   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
2503   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
2504 
2505   std::string result;
2506   for (unsigned Index : Indices) {
2507     if (!result.empty()) {
2508       result += "\n";
2509       if (CurrentIsStatic != Imports[Index].IsStatic ||
2510           CurrentImportGroup != JavaImportGroups[Index])
2511         result += "\n";
2512     }
2513     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
2514       result += CommentLine;
2515       result += "\n";
2516     }
2517     result += Imports[Index].Text;
2518     CurrentIsStatic = Imports[Index].IsStatic;
2519     CurrentImportGroup = JavaImportGroups[Index];
2520   }
2521 
2522   // If the imports are out of order, we generate a single replacement fixing
2523   // the entire block. Otherwise, no replacement is generated.
2524   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2525                                  Imports.front().Offset, ImportsBlockSize))))
2526     return;
2527 
2528   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
2529                                                ImportsBlockSize, result));
2530   // FIXME: better error handling. For now, just skip the replacement for the
2531   // release version.
2532   if (Err) {
2533     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2534     assert(false);
2535   }
2536 }
2537 
2538 namespace {
2539 
2540 const char JavaImportRegexPattern[] =
2541     "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
2542 
2543 } // anonymous namespace
2544 
2545 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
2546                                       ArrayRef<tooling::Range> Ranges,
2547                                       StringRef FileName,
2548                                       tooling::Replacements &Replaces) {
2549   unsigned Prev = 0;
2550   unsigned SearchFrom = 0;
2551   llvm::Regex ImportRegex(JavaImportRegexPattern);
2552   SmallVector<StringRef, 4> Matches;
2553   SmallVector<JavaImportDirective, 16> ImportsInBlock;
2554   std::vector<StringRef> AssociatedCommentLines;
2555 
2556   bool FormattingOff = false;
2557 
2558   for (;;) {
2559     auto Pos = Code.find('\n', SearchFrom);
2560     StringRef Line =
2561         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2562 
2563     StringRef Trimmed = Line.trim();
2564     if (Trimmed == "// clang-format off")
2565       FormattingOff = true;
2566     else if (Trimmed == "// clang-format on")
2567       FormattingOff = false;
2568 
2569     if (ImportRegex.match(Line, &Matches)) {
2570       if (FormattingOff) {
2571         // If at least one import line has formatting turned off, turn off
2572         // formatting entirely.
2573         return Replaces;
2574       }
2575       StringRef Static = Matches[1];
2576       StringRef Identifier = Matches[2];
2577       bool IsStatic = false;
2578       if (Static.contains("static")) {
2579         IsStatic = true;
2580       }
2581       ImportsInBlock.push_back(
2582           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
2583       AssociatedCommentLines.clear();
2584     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
2585       // Associating comments within the imports with the nearest import below
2586       AssociatedCommentLines.push_back(Line);
2587     }
2588     Prev = Pos + 1;
2589     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2590       break;
2591     SearchFrom = Pos + 1;
2592   }
2593   if (!ImportsInBlock.empty())
2594     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
2595   return Replaces;
2596 }
2597 
2598 bool isMpegTS(StringRef Code) {
2599   // MPEG transport streams use the ".ts" file extension. clang-format should
2600   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
2601   // 189 bytes - detect that and return.
2602   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
2603 }
2604 
2605 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); }
2606 
2607 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
2608                                    ArrayRef<tooling::Range> Ranges,
2609                                    StringRef FileName, unsigned *Cursor) {
2610   tooling::Replacements Replaces;
2611   if (!Style.SortIncludes || Style.DisableFormat)
2612     return Replaces;
2613   if (isLikelyXml(Code))
2614     return Replaces;
2615   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
2616       isMpegTS(Code))
2617     return Replaces;
2618   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
2619     return sortJavaScriptImports(Style, Code, Ranges, FileName);
2620   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
2621     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
2622   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
2623   return Replaces;
2624 }
2625 
2626 template <typename T>
2627 static llvm::Expected<tooling::Replacements>
2628 processReplacements(T ProcessFunc, StringRef Code,
2629                     const tooling::Replacements &Replaces,
2630                     const FormatStyle &Style) {
2631   if (Replaces.empty())
2632     return tooling::Replacements();
2633 
2634   auto NewCode = applyAllReplacements(Code, Replaces);
2635   if (!NewCode)
2636     return NewCode.takeError();
2637   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
2638   StringRef FileName = Replaces.begin()->getFilePath();
2639 
2640   tooling::Replacements FormatReplaces =
2641       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2642 
2643   return Replaces.merge(FormatReplaces);
2644 }
2645 
2646 llvm::Expected<tooling::Replacements>
2647 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
2648                    const FormatStyle &Style) {
2649   // We need to use lambda function here since there are two versions of
2650   // `sortIncludes`.
2651   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
2652                          std::vector<tooling::Range> Ranges,
2653                          StringRef FileName) -> tooling::Replacements {
2654     return sortIncludes(Style, Code, Ranges, FileName);
2655   };
2656   auto SortedReplaces =
2657       processReplacements(SortIncludes, Code, Replaces, Style);
2658   if (!SortedReplaces)
2659     return SortedReplaces.takeError();
2660 
2661   // We need to use lambda function here since there are two versions of
2662   // `reformat`.
2663   auto Reformat = [](const FormatStyle &Style, StringRef Code,
2664                      std::vector<tooling::Range> Ranges,
2665                      StringRef FileName) -> tooling::Replacements {
2666     return reformat(Style, Code, Ranges, FileName);
2667   };
2668   return processReplacements(Reformat, Code, *SortedReplaces, Style);
2669 }
2670 
2671 namespace {
2672 
2673 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
2674   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
2675          llvm::Regex(CppIncludeRegexPattern)
2676              .match(Replace.getReplacementText());
2677 }
2678 
2679 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
2680   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
2681 }
2682 
2683 // FIXME: insert empty lines between newly created blocks.
2684 tooling::Replacements
2685 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
2686                         const FormatStyle &Style) {
2687   if (!Style.isCpp())
2688     return Replaces;
2689 
2690   tooling::Replacements HeaderInsertions;
2691   std::set<llvm::StringRef> HeadersToDelete;
2692   tooling::Replacements Result;
2693   for (const auto &R : Replaces) {
2694     if (isHeaderInsertion(R)) {
2695       // Replacements from \p Replaces must be conflict-free already, so we can
2696       // simply consume the error.
2697       llvm::consumeError(HeaderInsertions.add(R));
2698     } else if (isHeaderDeletion(R)) {
2699       HeadersToDelete.insert(R.getReplacementText());
2700     } else if (R.getOffset() == UINT_MAX) {
2701       llvm::errs() << "Insertions other than header #include insertion are "
2702                       "not supported! "
2703                    << R.getReplacementText() << "\n";
2704     } else {
2705       llvm::consumeError(Result.add(R));
2706     }
2707   }
2708   if (HeaderInsertions.empty() && HeadersToDelete.empty())
2709     return Replaces;
2710 
2711   StringRef FileName = Replaces.begin()->getFilePath();
2712   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
2713 
2714   for (const auto &Header : HeadersToDelete) {
2715     tooling::Replacements Replaces =
2716         Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
2717     for (const auto &R : Replaces) {
2718       auto Err = Result.add(R);
2719       if (Err) {
2720         // Ignore the deletion on conflict.
2721         llvm::errs() << "Failed to add header deletion replacement for "
2722                      << Header << ": " << llvm::toString(std::move(Err))
2723                      << "\n";
2724       }
2725     }
2726   }
2727 
2728   llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
2729   llvm::SmallVector<StringRef, 4> Matches;
2730   for (const auto &R : HeaderInsertions) {
2731     auto IncludeDirective = R.getReplacementText();
2732     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
2733     assert(Matched && "Header insertion replacement must have replacement text "
2734                       "'#include ...'");
2735     (void)Matched;
2736     auto IncludeName = Matches[2];
2737     auto Replace =
2738         Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"));
2739     if (Replace) {
2740       auto Err = Result.add(*Replace);
2741       if (Err) {
2742         llvm::consumeError(std::move(Err));
2743         unsigned NewOffset =
2744             Result.getShiftedCodePosition(Replace->getOffset());
2745         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
2746                                             Replace->getReplacementText());
2747         Result = Result.merge(tooling::Replacements(Shifted));
2748       }
2749     }
2750   }
2751   return Result;
2752 }
2753 
2754 } // anonymous namespace
2755 
2756 llvm::Expected<tooling::Replacements>
2757 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
2758                           const FormatStyle &Style) {
2759   // We need to use lambda function here since there are two versions of
2760   // `cleanup`.
2761   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
2762                     std::vector<tooling::Range> Ranges,
2763                     StringRef FileName) -> tooling::Replacements {
2764     return cleanup(Style, Code, Ranges, FileName);
2765   };
2766   // Make header insertion replacements insert new headers into correct blocks.
2767   tooling::Replacements NewReplaces =
2768       fixCppIncludeInsertions(Code, Replaces, Style);
2769   return processReplacements(Cleanup, Code, NewReplaces, Style);
2770 }
2771 
2772 namespace internal {
2773 std::pair<tooling::Replacements, unsigned>
2774 reformat(const FormatStyle &Style, StringRef Code,
2775          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
2776          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
2777          FormattingAttemptStatus *Status) {
2778   FormatStyle Expanded = expandPresets(Style);
2779   if (Expanded.DisableFormat)
2780     return {tooling::Replacements(), 0};
2781   if (isLikelyXml(Code))
2782     return {tooling::Replacements(), 0};
2783   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
2784     return {tooling::Replacements(), 0};
2785 
2786   typedef std::function<std::pair<tooling::Replacements, unsigned>(
2787       const Environment &)>
2788       AnalyzerPass;
2789   SmallVector<AnalyzerPass, 4> Passes;
2790 
2791   if (Style.Language == FormatStyle::LK_Cpp) {
2792     if (Style.FixNamespaceComments)
2793       Passes.emplace_back([&](const Environment &Env) {
2794         return NamespaceEndCommentsFixer(Env, Expanded).process();
2795       });
2796 
2797     if (Style.SortUsingDeclarations)
2798       Passes.emplace_back([&](const Environment &Env) {
2799         return UsingDeclarationsSorter(Env, Expanded).process();
2800       });
2801   }
2802 
2803   if (Style.Language == FormatStyle::LK_JavaScript &&
2804       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
2805     Passes.emplace_back([&](const Environment &Env) {
2806       return JavaScriptRequoter(Env, Expanded).process();
2807     });
2808 
2809   Passes.emplace_back([&](const Environment &Env) {
2810     return Formatter(Env, Expanded, Status).process();
2811   });
2812 
2813   if (Style.Language == FormatStyle::LK_JavaScript &&
2814       Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped)
2815     Passes.emplace_back([&](const Environment &Env) {
2816       return TrailingCommaInserter(Env, Expanded).process();
2817     });
2818 
2819   auto Env =
2820       std::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
2821                                     NextStartColumn, LastStartColumn);
2822   llvm::Optional<std::string> CurrentCode = None;
2823   tooling::Replacements Fixes;
2824   unsigned Penalty = 0;
2825   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
2826     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
2827     auto NewCode = applyAllReplacements(
2828         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
2829     if (NewCode) {
2830       Fixes = Fixes.merge(PassFixes.first);
2831       Penalty += PassFixes.second;
2832       if (I + 1 < E) {
2833         CurrentCode = std::move(*NewCode);
2834         Env = std::make_unique<Environment>(
2835             *CurrentCode, FileName,
2836             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
2837             FirstStartColumn, NextStartColumn, LastStartColumn);
2838       }
2839     }
2840   }
2841 
2842   return {Fixes, Penalty};
2843 }
2844 } // namespace internal
2845 
2846 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2847                                ArrayRef<tooling::Range> Ranges,
2848                                StringRef FileName,
2849                                FormattingAttemptStatus *Status) {
2850   return internal::reformat(Style, Code, Ranges,
2851                             /*FirstStartColumn=*/0,
2852                             /*NextStartColumn=*/0,
2853                             /*LastStartColumn=*/0, FileName, Status)
2854       .first;
2855 }
2856 
2857 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
2858                               ArrayRef<tooling::Range> Ranges,
2859                               StringRef FileName) {
2860   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
2861   if (Style.Language != FormatStyle::LK_Cpp)
2862     return tooling::Replacements();
2863   return Cleaner(Environment(Code, FileName, Ranges), Style).process().first;
2864 }
2865 
2866 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2867                                ArrayRef<tooling::Range> Ranges,
2868                                StringRef FileName, bool *IncompleteFormat) {
2869   FormattingAttemptStatus Status;
2870   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
2871   if (!Status.FormatComplete)
2872     *IncompleteFormat = true;
2873   return Result;
2874 }
2875 
2876 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
2877                                               StringRef Code,
2878                                               ArrayRef<tooling::Range> Ranges,
2879                                               StringRef FileName) {
2880   return NamespaceEndCommentsFixer(Environment(Code, FileName, Ranges), Style)
2881       .process()
2882       .first;
2883 }
2884 
2885 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
2886                                             StringRef Code,
2887                                             ArrayRef<tooling::Range> Ranges,
2888                                             StringRef FileName) {
2889   return UsingDeclarationsSorter(Environment(Code, FileName, Ranges), Style)
2890       .process()
2891       .first;
2892 }
2893 
2894 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
2895   LangOptions LangOpts;
2896 
2897   FormatStyle::LanguageStandard LexingStd = Style.Standard;
2898   if (LexingStd == FormatStyle::LS_Auto)
2899     LexingStd = FormatStyle::LS_Latest;
2900   if (LexingStd == FormatStyle::LS_Latest)
2901     LexingStd = FormatStyle::LS_Cpp20;
2902   LangOpts.CPlusPlus = 1;
2903   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
2904   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
2905   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
2906   LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
2907   LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
2908 
2909   LangOpts.LineComment = 1;
2910   bool AlternativeOperators = Style.isCpp();
2911   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
2912   LangOpts.Bool = 1;
2913   LangOpts.ObjC = 1;
2914   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
2915   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
2916   LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
2917   return LangOpts;
2918 }
2919 
2920 const char *StyleOptionHelpDescription =
2921     "Coding style, currently supports:\n"
2922     "  LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n"
2923     "Use -style=file to load style configuration from\n"
2924     ".clang-format file located in one of the parent\n"
2925     "directories of the source file (or current\n"
2926     "directory for stdin).\n"
2927     "Use -style=\"{key: value, ...}\" to set specific\n"
2928     "parameters, e.g.:\n"
2929     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
2930 
2931 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
2932   if (FileName.endswith(".java"))
2933     return FormatStyle::LK_Java;
2934   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".mjs") ||
2935       FileName.endswith_lower(".ts"))
2936     return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
2937   if (FileName.endswith(".m") || FileName.endswith(".mm"))
2938     return FormatStyle::LK_ObjC;
2939   if (FileName.endswith_lower(".proto") ||
2940       FileName.endswith_lower(".protodevel"))
2941     return FormatStyle::LK_Proto;
2942   if (FileName.endswith_lower(".textpb") ||
2943       FileName.endswith_lower(".pb.txt") ||
2944       FileName.endswith_lower(".textproto") ||
2945       FileName.endswith_lower(".asciipb"))
2946     return FormatStyle::LK_TextProto;
2947   if (FileName.endswith_lower(".td"))
2948     return FormatStyle::LK_TableGen;
2949   if (FileName.endswith_lower(".cs"))
2950     return FormatStyle::LK_CSharp;
2951   return FormatStyle::LK_Cpp;
2952 }
2953 
2954 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
2955   const auto GuessedLanguage = getLanguageByFileName(FileName);
2956   if (GuessedLanguage == FormatStyle::LK_Cpp) {
2957     auto Extension = llvm::sys::path::extension(FileName);
2958     // If there's no file extension (or it's .h), we need to check the contents
2959     // of the code to see if it contains Objective-C.
2960     if (Extension.empty() || Extension == ".h") {
2961       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
2962       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
2963       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
2964       Guesser.process();
2965       if (Guesser.isObjC())
2966         return FormatStyle::LK_ObjC;
2967     }
2968   }
2969   return GuessedLanguage;
2970 }
2971 
2972 const char *DefaultFormatStyle = "file";
2973 
2974 const char *DefaultFallbackStyle = "LLVM";
2975 
2976 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
2977                                      StringRef FallbackStyleName,
2978                                      StringRef Code, llvm::vfs::FileSystem *FS,
2979                                      bool AllowUnknownOptions) {
2980   if (!FS) {
2981     FS = llvm::vfs::getRealFileSystem().get();
2982   }
2983   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
2984 
2985   FormatStyle FallbackStyle = getNoStyle();
2986   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
2987     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
2988 
2989   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
2990       ChildFormatTextToApply;
2991 
2992   if (StyleName.startswith("{")) {
2993     // Parse YAML/JSON style from the command line.
2994     StringRef Source = "<command-line>";
2995     if (std::error_code ec =
2996             parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
2997                                AllowUnknownOptions))
2998       return make_string_error("Error parsing -style: " + ec.message());
2999     if (Style.InheritsParentConfig)
3000       ChildFormatTextToApply.emplace_back(
3001           llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
3002     else
3003       return Style;
3004   }
3005 
3006   // If the style inherits the parent configuration it is a command line
3007   // configuration, which wants to inherit, so we have to skip the check of the
3008   // StyleName.
3009   if (!Style.InheritsParentConfig && !StyleName.equals_lower("file")) {
3010     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
3011       return make_string_error("Invalid value for -style");
3012     if (!Style.InheritsParentConfig)
3013       return Style;
3014   }
3015 
3016   // Reset possible inheritance
3017   Style.InheritsParentConfig = false;
3018 
3019   // Look for .clang-format/_clang-format file in the file's parent directories.
3020   SmallString<128> UnsuitableConfigFiles;
3021   SmallString<128> Path(FileName);
3022   if (std::error_code EC = FS->makeAbsolute(Path))
3023     return make_string_error(EC.message());
3024 
3025   llvm::SmallVector<std::string, 2> FilesToLookFor;
3026   FilesToLookFor.push_back(".clang-format");
3027   FilesToLookFor.push_back("_clang-format");
3028 
3029   auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
3030 
3031   for (StringRef Directory = Path; !Directory.empty();
3032        Directory = llvm::sys::path::parent_path(Directory)) {
3033 
3034     auto Status = FS->status(Directory);
3035     if (!Status ||
3036         Status->getType() != llvm::sys::fs::file_type::directory_file) {
3037       continue;
3038     }
3039 
3040     for (const auto &F : FilesToLookFor) {
3041       SmallString<128> ConfigFile(Directory);
3042 
3043       llvm::sys::path::append(ConfigFile, F);
3044       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
3045 
3046       Status = FS->status(ConfigFile.str());
3047 
3048       if (Status &&
3049           (Status->getType() == llvm::sys::fs::file_type::regular_file)) {
3050         llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3051             FS->getBufferForFile(ConfigFile.str());
3052         if (std::error_code EC = Text.getError())
3053           return make_string_error(EC.message());
3054         if (std::error_code ec =
3055                 parseConfiguration(*Text.get(), &Style, AllowUnknownOptions)) {
3056           if (ec == ParseError::Unsuitable) {
3057             if (!UnsuitableConfigFiles.empty())
3058               UnsuitableConfigFiles.append(", ");
3059             UnsuitableConfigFiles.append(ConfigFile);
3060             continue;
3061           }
3062           return make_string_error("Error reading " + ConfigFile + ": " +
3063                                    ec.message());
3064         }
3065         LLVM_DEBUG(llvm::dbgs()
3066                    << "Using configuration file " << ConfigFile << "\n");
3067 
3068         if (!Style.InheritsParentConfig) {
3069           if (ChildFormatTextToApply.empty())
3070             return Style;
3071 
3072           LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
3073 
3074           for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
3075             auto Ec = parseConfiguration(*MemBuf, &Style, AllowUnknownOptions,
3076                                          dropDiagnosticHandler);
3077             // It was already correctly parsed.
3078             assert(!Ec);
3079             static_cast<void>(Ec);
3080           }
3081 
3082           return Style;
3083         }
3084 
3085         LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
3086 
3087         // Reset inheritance of style
3088         Style.InheritsParentConfig = false;
3089 
3090         ChildFormatTextToApply.emplace_back(std::move(*Text));
3091 
3092         // Breaking out of the inner loop, since we don't want to parse
3093         // .clang-format AND _clang-format, if both exist. Then we continue the
3094         // inner loop (parent directories) in search for the parent
3095         // configuration.
3096         break;
3097       }
3098     }
3099   }
3100   if (!UnsuitableConfigFiles.empty())
3101     return make_string_error("Configuration file(s) do(es) not support " +
3102                              getLanguageName(Style.Language) + ": " +
3103                              UnsuitableConfigFiles);
3104 
3105   if (!ChildFormatTextToApply.empty()) {
3106     assert(ChildFormatTextToApply.size() == 1);
3107 
3108     LLVM_DEBUG(llvm::dbgs()
3109                << "Applying child configuration on fallback style\n");
3110 
3111     auto Ec =
3112         parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle,
3113                            AllowUnknownOptions, dropDiagnosticHandler);
3114     // It was already correctly parsed.
3115     assert(!Ec);
3116     static_cast<void>(Ec);
3117   }
3118 
3119   return FallbackStyle;
3120 }
3121 
3122 } // namespace format
3123 } // namespace clang
3124