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