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