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