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 BracesInserter : public TokenAnalyzer {
1788 public:
1789   BracesInserter(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     insertBraces(AnnotatedLines, Result);
1799     return {Result, 0};
1800   }
1801 
1802 private:
1803   void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
1804                     tooling::Replacements &Result) {
1805     const auto &SourceMgr = Env.getSourceManager();
1806     for (AnnotatedLine *Line : Lines) {
1807       insertBraces(Line->Children, Result);
1808       if (!Line->Affected)
1809         continue;
1810       for (FormatToken *Token = Line->First; Token && !Token->Finalized;
1811            Token = Token->Next) {
1812         if (Token->BraceCount == 0)
1813           continue;
1814         std::string Brace;
1815         if (Token->BraceCount < 0) {
1816           assert(Token->BraceCount == -1);
1817           Brace = '{';
1818         } else {
1819           Brace = '\n' + std::string(Token->BraceCount, '}');
1820         }
1821         Token->BraceCount = 0;
1822         const auto Start = Token->Tok.getEndLoc();
1823         cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
1824       }
1825     }
1826   }
1827 };
1828 
1829 class BracesRemover : public TokenAnalyzer {
1830 public:
1831   BracesRemover(const Environment &Env, const FormatStyle &Style)
1832       : TokenAnalyzer(Env, Style) {}
1833 
1834   std::pair<tooling::Replacements, unsigned>
1835   analyze(TokenAnnotator &Annotator,
1836           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1837           FormatTokenLexer &Tokens) override {
1838     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1839     tooling::Replacements Result;
1840     removeBraces(AnnotatedLines, Result);
1841     return {Result, 0};
1842   }
1843 
1844 private:
1845   void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
1846                     tooling::Replacements &Result) {
1847     const auto &SourceMgr = Env.getSourceManager();
1848     for (AnnotatedLine *Line : Lines) {
1849       removeBraces(Line->Children, Result);
1850       if (!Line->Affected)
1851         continue;
1852       for (FormatToken *Token = Line->First; Token && !Token->Finalized;
1853            Token = Token->Next) {
1854         if (!Token->Optional)
1855           continue;
1856         assert(Token->isOneOf(tok::l_brace, tok::r_brace));
1857         assert(Token->Next || Token == Line->Last);
1858         const auto Start =
1859             Token == Line->Last || (Token->Next->is(tok::kw_else) &&
1860                                     Token->Next->NewlinesBefore > 0)
1861                 ? Token->WhitespaceRange.getBegin()
1862                 : Token->Tok.getLocation();
1863         const auto Range =
1864             CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
1865         cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
1866       }
1867     }
1868   }
1869 };
1870 
1871 class JavaScriptRequoter : public TokenAnalyzer {
1872 public:
1873   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
1874       : TokenAnalyzer(Env, Style) {}
1875 
1876   std::pair<tooling::Replacements, unsigned>
1877   analyze(TokenAnnotator &Annotator,
1878           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1879           FormatTokenLexer &Tokens) override {
1880     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1881     tooling::Replacements Result;
1882     requoteJSStringLiteral(AnnotatedLines, Result);
1883     return {Result, 0};
1884   }
1885 
1886 private:
1887   // Replaces double/single-quoted string literal as appropriate, re-escaping
1888   // the contents in the process.
1889   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
1890                               tooling::Replacements &Result) {
1891     for (AnnotatedLine *Line : Lines) {
1892       requoteJSStringLiteral(Line->Children, Result);
1893       if (!Line->Affected)
1894         continue;
1895       for (FormatToken *FormatTok = Line->First; FormatTok;
1896            FormatTok = FormatTok->Next) {
1897         StringRef Input = FormatTok->TokenText;
1898         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1899             // NB: testing for not starting with a double quote to avoid
1900             // breaking `template strings`.
1901             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
1902              !Input.startswith("\"")) ||
1903             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
1904              !Input.startswith("\'")))
1905           continue;
1906 
1907         // Change start and end quote.
1908         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
1909         SourceLocation Start = FormatTok->Tok.getLocation();
1910         auto Replace = [&](SourceLocation Start, unsigned Length,
1911                            StringRef ReplacementText) {
1912           auto Err = Result.add(tooling::Replacement(
1913               Env.getSourceManager(), Start, Length, ReplacementText));
1914           // FIXME: handle error. For now, print error message and skip the
1915           // replacement for release version.
1916           if (Err) {
1917             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1918             assert(false);
1919           }
1920         };
1921         Replace(Start, 1, IsSingle ? "'" : "\"");
1922         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1923                 IsSingle ? "'" : "\"");
1924 
1925         // Escape internal quotes.
1926         bool Escaped = false;
1927         for (size_t i = 1; i < Input.size() - 1; i++) {
1928           switch (Input[i]) {
1929           case '\\':
1930             if (!Escaped && i + 1 < Input.size() &&
1931                 ((IsSingle && Input[i + 1] == '"') ||
1932                  (!IsSingle && Input[i + 1] == '\''))) {
1933               // Remove this \, it's escaping a " or ' that no longer needs
1934               // escaping
1935               Replace(Start.getLocWithOffset(i), 1, "");
1936               continue;
1937             }
1938             Escaped = !Escaped;
1939             break;
1940           case '\"':
1941           case '\'':
1942             if (!Escaped && IsSingle == (Input[i] == '\'')) {
1943               // Escape the quote.
1944               Replace(Start.getLocWithOffset(i), 0, "\\");
1945             }
1946             Escaped = false;
1947             break;
1948           default:
1949             Escaped = false;
1950             break;
1951           }
1952         }
1953       }
1954     }
1955   }
1956 };
1957 
1958 class Formatter : public TokenAnalyzer {
1959 public:
1960   Formatter(const Environment &Env, const FormatStyle &Style,
1961             FormattingAttemptStatus *Status)
1962       : TokenAnalyzer(Env, Style), Status(Status) {}
1963 
1964   std::pair<tooling::Replacements, unsigned>
1965   analyze(TokenAnnotator &Annotator,
1966           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1967           FormatTokenLexer &Tokens) override {
1968     tooling::Replacements Result;
1969     deriveLocalStyle(AnnotatedLines);
1970     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1971     for (AnnotatedLine *Line : AnnotatedLines)
1972       Annotator.calculateFormattingInformation(*Line);
1973     Annotator.setCommentLineLevels(AnnotatedLines);
1974 
1975     WhitespaceManager Whitespaces(
1976         Env.getSourceManager(), Style,
1977         Style.DeriveLineEnding
1978             ? WhitespaceManager::inputUsesCRLF(
1979                   Env.getSourceManager().getBufferData(Env.getFileID()),
1980                   Style.UseCRLF)
1981             : Style.UseCRLF);
1982     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
1983                                   Env.getSourceManager(), Whitespaces, Encoding,
1984                                   BinPackInconclusiveFunctions);
1985     unsigned Penalty =
1986         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
1987                                Tokens.getKeywords(), Env.getSourceManager(),
1988                                Status)
1989             .format(AnnotatedLines, /*DryRun=*/false,
1990                     /*AdditionalIndent=*/0,
1991                     /*FixBadIndentation=*/false,
1992                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
1993                     /*NextStartColumn=*/Env.getNextStartColumn(),
1994                     /*LastStartColumn=*/Env.getLastStartColumn());
1995     for (const auto &R : Whitespaces.generateReplacements())
1996       if (Result.add(R))
1997         return std::make_pair(Result, 0);
1998     return std::make_pair(Result, Penalty);
1999   }
2000 
2001 private:
2002   bool
2003   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2004     for (const AnnotatedLine *Line : Lines) {
2005       if (hasCpp03IncompatibleFormat(Line->Children))
2006         return true;
2007       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2008         if (!Tok->hasWhitespaceBefore()) {
2009           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2010             return true;
2011           if (Tok->is(TT_TemplateCloser) &&
2012               Tok->Previous->is(TT_TemplateCloser))
2013             return true;
2014         }
2015       }
2016     }
2017     return false;
2018   }
2019 
2020   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2021     int AlignmentDiff = 0;
2022     for (const AnnotatedLine *Line : Lines) {
2023       AlignmentDiff += countVariableAlignments(Line->Children);
2024       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2025         if (!Tok->is(TT_PointerOrReference))
2026           continue;
2027         // Don't treat space in `void foo() &&` as evidence.
2028         if (const auto *Prev = Tok->getPreviousNonComment()) {
2029           if (Prev->is(tok::r_paren) && Prev->MatchingParen)
2030             if (const auto *Func = Prev->MatchingParen->getPreviousNonComment())
2031               if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2032                                 TT_OverloadedOperator))
2033                 continue;
2034         }
2035         bool SpaceBefore = Tok->hasWhitespaceBefore();
2036         bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2037         if (SpaceBefore && !SpaceAfter)
2038           ++AlignmentDiff;
2039         if (!SpaceBefore && SpaceAfter)
2040           --AlignmentDiff;
2041       }
2042     }
2043     return AlignmentDiff;
2044   }
2045 
2046   void
2047   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2048     bool HasBinPackedFunction = false;
2049     bool HasOnePerLineFunction = false;
2050     for (AnnotatedLine *Line : AnnotatedLines) {
2051       if (!Line->First->Next)
2052         continue;
2053       FormatToken *Tok = Line->First->Next;
2054       while (Tok->Next) {
2055         if (Tok->is(PPK_BinPacked))
2056           HasBinPackedFunction = true;
2057         if (Tok->is(PPK_OnePerLine))
2058           HasOnePerLineFunction = true;
2059 
2060         Tok = Tok->Next;
2061       }
2062     }
2063     if (Style.DerivePointerAlignment) {
2064       Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
2065                                    ? FormatStyle::PAS_Left
2066                                    : FormatStyle::PAS_Right;
2067       Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
2068     }
2069     if (Style.Standard == FormatStyle::LS_Auto)
2070       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2071                            ? FormatStyle::LS_Latest
2072                            : FormatStyle::LS_Cpp03;
2073     BinPackInconclusiveFunctions =
2074         HasBinPackedFunction || !HasOnePerLineFunction;
2075   }
2076 
2077   bool BinPackInconclusiveFunctions;
2078   FormattingAttemptStatus *Status;
2079 };
2080 
2081 /// TrailingCommaInserter inserts trailing commas into container literals.
2082 /// E.g.:
2083 ///     const x = [
2084 ///       1,
2085 ///     ];
2086 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2087 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2088 /// ColumnLimit.
2089 ///
2090 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2091 /// is conceptually incompatible with bin packing.
2092 class TrailingCommaInserter : public TokenAnalyzer {
2093 public:
2094   TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2095       : TokenAnalyzer(Env, Style) {}
2096 
2097   std::pair<tooling::Replacements, unsigned>
2098   analyze(TokenAnnotator &Annotator,
2099           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2100           FormatTokenLexer &Tokens) override {
2101     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2102     tooling::Replacements Result;
2103     insertTrailingCommas(AnnotatedLines, Result);
2104     return {Result, 0};
2105   }
2106 
2107 private:
2108   /// Inserts trailing commas in [] and {} initializers if they wrap over
2109   /// multiple lines.
2110   void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2111                             tooling::Replacements &Result) {
2112     for (AnnotatedLine *Line : Lines) {
2113       insertTrailingCommas(Line->Children, Result);
2114       if (!Line->Affected)
2115         continue;
2116       for (FormatToken *FormatTok = Line->First; FormatTok;
2117            FormatTok = FormatTok->Next) {
2118         if (FormatTok->NewlinesBefore == 0)
2119           continue;
2120         FormatToken *Matching = FormatTok->MatchingParen;
2121         if (!Matching || !FormatTok->getPreviousNonComment())
2122           continue;
2123         if (!(FormatTok->is(tok::r_square) &&
2124               Matching->is(TT_ArrayInitializerLSquare)) &&
2125             !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral)))
2126           continue;
2127         FormatToken *Prev = FormatTok->getPreviousNonComment();
2128         if (Prev->is(tok::comma) || Prev->is(tok::semi))
2129           continue;
2130         // getEndLoc is not reliably set during re-lexing, use text length
2131         // instead.
2132         SourceLocation Start =
2133             Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2134         // If inserting a comma would push the code over the column limit, skip
2135         // this location - it'd introduce an unstable formatting due to the
2136         // required reflow.
2137         unsigned ColumnNumber =
2138             Env.getSourceManager().getSpellingColumnNumber(Start);
2139         if (ColumnNumber > Style.ColumnLimit)
2140           continue;
2141         // Comma insertions cannot conflict with each other, and this pass has a
2142         // clean set of Replacements, so the operation below cannot fail.
2143         cantFail(Result.add(
2144             tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2145       }
2146     }
2147   }
2148 };
2149 
2150 // This class clean up the erroneous/redundant code around the given ranges in
2151 // file.
2152 class Cleaner : public TokenAnalyzer {
2153 public:
2154   Cleaner(const Environment &Env, const FormatStyle &Style)
2155       : TokenAnalyzer(Env, Style),
2156         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2157 
2158   // FIXME: eliminate unused parameters.
2159   std::pair<tooling::Replacements, unsigned>
2160   analyze(TokenAnnotator &Annotator,
2161           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2162           FormatTokenLexer &Tokens) override {
2163     // FIXME: in the current implementation the granularity of affected range
2164     // is an annotated line. However, this is not sufficient. Furthermore,
2165     // redundant code introduced by replacements does not necessarily
2166     // intercept with ranges of replacements that result in the redundancy.
2167     // To determine if some redundant code is actually introduced by
2168     // replacements(e.g. deletions), we need to come up with a more
2169     // sophisticated way of computing affected ranges.
2170     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2171 
2172     checkEmptyNamespace(AnnotatedLines);
2173 
2174     for (auto *Line : AnnotatedLines)
2175       cleanupLine(Line);
2176 
2177     return {generateFixes(), 0};
2178   }
2179 
2180 private:
2181   void cleanupLine(AnnotatedLine *Line) {
2182     for (auto *Child : Line->Children)
2183       cleanupLine(Child);
2184 
2185     if (Line->Affected) {
2186       cleanupRight(Line->First, tok::comma, tok::comma);
2187       cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2188       cleanupRight(Line->First, tok::l_paren, tok::comma);
2189       cleanupLeft(Line->First, tok::comma, tok::r_paren);
2190       cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2191       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2192       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2193     }
2194   }
2195 
2196   bool containsOnlyComments(const AnnotatedLine &Line) {
2197     for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
2198       if (Tok->isNot(tok::comment))
2199         return false;
2200     return true;
2201   }
2202 
2203   // Iterate through all lines and remove any empty (nested) namespaces.
2204   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2205     std::set<unsigned> DeletedLines;
2206     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2207       auto &Line = *AnnotatedLines[i];
2208       if (Line.startsWithNamespace())
2209         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2210     }
2211 
2212     for (auto Line : DeletedLines) {
2213       FormatToken *Tok = AnnotatedLines[Line]->First;
2214       while (Tok) {
2215         deleteToken(Tok);
2216         Tok = Tok->Next;
2217       }
2218     }
2219   }
2220 
2221   // The function checks if the namespace, which starts from \p CurrentLine, and
2222   // its nested namespaces are empty and delete them if they are empty. It also
2223   // sets \p NewLine to the last line checked.
2224   // Returns true if the current namespace is empty.
2225   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2226                            unsigned CurrentLine, unsigned &NewLine,
2227                            std::set<unsigned> &DeletedLines) {
2228     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2229     if (Style.BraceWrapping.AfterNamespace) {
2230       // If the left brace is in a new line, we should consume it first so that
2231       // it does not make the namespace non-empty.
2232       // FIXME: error handling if there is no left brace.
2233       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2234         NewLine = CurrentLine;
2235         return false;
2236       }
2237     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2238       return false;
2239     }
2240     while (++CurrentLine < End) {
2241       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2242         break;
2243 
2244       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2245         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
2246                                  DeletedLines))
2247           return false;
2248         CurrentLine = NewLine;
2249         continue;
2250       }
2251 
2252       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2253         continue;
2254 
2255       // If there is anything other than comments or nested namespaces in the
2256       // current namespace, the namespace cannot be empty.
2257       NewLine = CurrentLine;
2258       return false;
2259     }
2260 
2261     NewLine = CurrentLine;
2262     if (CurrentLine >= End)
2263       return false;
2264 
2265     // Check if the empty namespace is actually affected by changed ranges.
2266     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2267             AnnotatedLines[InitLine]->First->Tok.getLocation(),
2268             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
2269       return false;
2270 
2271     for (unsigned i = InitLine; i <= CurrentLine; ++i)
2272       DeletedLines.insert(i);
2273 
2274     return true;
2275   }
2276 
2277   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2278   // of the token in the pair if the left token has \p LK token kind and the
2279   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2280   // is deleted on match; otherwise, the right token is deleted.
2281   template <typename LeftKind, typename RightKind>
2282   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2283                    bool DeleteLeft) {
2284     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
2285       for (auto *Res = Tok.Next; Res; Res = Res->Next)
2286         if (!Res->is(tok::comment) &&
2287             DeletedTokens.find(Res) == DeletedTokens.end())
2288           return Res;
2289       return nullptr;
2290     };
2291     for (auto *Left = Start; Left;) {
2292       auto *Right = NextNotDeleted(*Left);
2293       if (!Right)
2294         break;
2295       if (Left->is(LK) && Right->is(RK)) {
2296         deleteToken(DeleteLeft ? Left : Right);
2297         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2298           deleteToken(Tok);
2299         // If the right token is deleted, we should keep the left token
2300         // unchanged and pair it with the new right token.
2301         if (!DeleteLeft)
2302           continue;
2303       }
2304       Left = Right;
2305     }
2306   }
2307 
2308   template <typename LeftKind, typename RightKind>
2309   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2310     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
2311   }
2312 
2313   template <typename LeftKind, typename RightKind>
2314   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2315     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
2316   }
2317 
2318   // Delete the given token.
2319   inline void deleteToken(FormatToken *Tok) {
2320     if (Tok)
2321       DeletedTokens.insert(Tok);
2322   }
2323 
2324   tooling::Replacements generateFixes() {
2325     tooling::Replacements Fixes;
2326     std::vector<FormatToken *> Tokens;
2327     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2328               std::back_inserter(Tokens));
2329 
2330     // Merge multiple continuous token deletions into one big deletion so that
2331     // the number of replacements can be reduced. This makes computing affected
2332     // ranges more efficient when we run reformat on the changed code.
2333     unsigned Idx = 0;
2334     while (Idx < Tokens.size()) {
2335       unsigned St = Idx, End = Idx;
2336       while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2337         ++End;
2338       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2339                                               Tokens[End]->Tok.getEndLoc());
2340       auto Err =
2341           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2342       // FIXME: better error handling. for now just print error message and skip
2343       // for the release version.
2344       if (Err) {
2345         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2346         assert(false && "Fixes must not conflict!");
2347       }
2348       Idx = End + 1;
2349     }
2350 
2351     return Fixes;
2352   }
2353 
2354   // Class for less-than inequality comparason for the set `RedundantTokens`.
2355   // We store tokens in the order they appear in the translation unit so that
2356   // we do not need to sort them in `generateFixes()`.
2357   struct FormatTokenLess {
2358     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2359 
2360     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2361       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2362                                           RHS->Tok.getLocation());
2363     }
2364     const SourceManager &SM;
2365   };
2366 
2367   // Tokens to be deleted.
2368   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2369 };
2370 
2371 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2372 public:
2373   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2374       : TokenAnalyzer(Env, Style), IsObjC(false) {}
2375 
2376   std::pair<tooling::Replacements, unsigned>
2377   analyze(TokenAnnotator &Annotator,
2378           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2379           FormatTokenLexer &Tokens) override {
2380     assert(Style.Language == FormatStyle::LK_Cpp);
2381     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2382                          Tokens.getKeywords());
2383     tooling::Replacements Result;
2384     return {Result, 0};
2385   }
2386 
2387   bool isObjC() { return IsObjC; }
2388 
2389 private:
2390   static bool
2391   guessIsObjC(const SourceManager &SourceManager,
2392               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2393               const AdditionalKeywords &Keywords) {
2394     // Keep this array sorted, since we are binary searching over it.
2395     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2396         "CGFloat",
2397         "CGPoint",
2398         "CGPointMake",
2399         "CGPointZero",
2400         "CGRect",
2401         "CGRectEdge",
2402         "CGRectInfinite",
2403         "CGRectMake",
2404         "CGRectNull",
2405         "CGRectZero",
2406         "CGSize",
2407         "CGSizeMake",
2408         "CGVector",
2409         "CGVectorMake",
2410         "NSAffineTransform",
2411         "NSArray",
2412         "NSAttributedString",
2413         "NSBlockOperation",
2414         "NSBundle",
2415         "NSCache",
2416         "NSCalendar",
2417         "NSCharacterSet",
2418         "NSCountedSet",
2419         "NSData",
2420         "NSDataDetector",
2421         "NSDecimal",
2422         "NSDecimalNumber",
2423         "NSDictionary",
2424         "NSEdgeInsets",
2425         "NSHashTable",
2426         "NSIndexPath",
2427         "NSIndexSet",
2428         "NSInteger",
2429         "NSInvocationOperation",
2430         "NSLocale",
2431         "NSMapTable",
2432         "NSMutableArray",
2433         "NSMutableAttributedString",
2434         "NSMutableCharacterSet",
2435         "NSMutableData",
2436         "NSMutableDictionary",
2437         "NSMutableIndexSet",
2438         "NSMutableOrderedSet",
2439         "NSMutableSet",
2440         "NSMutableString",
2441         "NSNumber",
2442         "NSNumberFormatter",
2443         "NSObject",
2444         "NSOperation",
2445         "NSOperationQueue",
2446         "NSOperationQueuePriority",
2447         "NSOrderedSet",
2448         "NSPoint",
2449         "NSPointerArray",
2450         "NSQualityOfService",
2451         "NSRange",
2452         "NSRect",
2453         "NSRegularExpression",
2454         "NSSet",
2455         "NSSize",
2456         "NSString",
2457         "NSTimeZone",
2458         "NSUInteger",
2459         "NSURL",
2460         "NSURLComponents",
2461         "NSURLQueryItem",
2462         "NSUUID",
2463         "NSValue",
2464         "UIImage",
2465         "UIView",
2466     };
2467 
2468     for (auto Line : AnnotatedLines) {
2469       if (Line->First && (Line->First->TokenText.startswith("#") ||
2470                           Line->First->TokenText == "__pragma" ||
2471                           Line->First->TokenText == "_Pragma"))
2472         continue;
2473       for (const FormatToken *FormatTok = Line->First; FormatTok;
2474            FormatTok = FormatTok->Next) {
2475         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
2476              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
2477               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
2478                                  tok::l_brace))) ||
2479             (FormatTok->Tok.isAnyIdentifier() &&
2480              std::binary_search(std::begin(FoundationIdentifiers),
2481                                 std::end(FoundationIdentifiers),
2482                                 FormatTok->TokenText)) ||
2483             FormatTok->is(TT_ObjCStringLiteral) ||
2484             FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
2485                                Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
2486                                TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
2487                                TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
2488                                TT_ObjCProperty)) {
2489           LLVM_DEBUG(llvm::dbgs()
2490                      << "Detected ObjC at location "
2491                      << FormatTok->Tok.getLocation().printToString(
2492                             SourceManager)
2493                      << " token: " << FormatTok->TokenText << " token type: "
2494                      << getTokenTypeName(FormatTok->getType()) << "\n");
2495           return true;
2496         }
2497         if (guessIsObjC(SourceManager, Line->Children, Keywords))
2498           return true;
2499       }
2500     }
2501     return false;
2502   }
2503 
2504   bool IsObjC;
2505 };
2506 
2507 struct IncludeDirective {
2508   StringRef Filename;
2509   StringRef Text;
2510   unsigned Offset;
2511   int Category;
2512   int Priority;
2513 };
2514 
2515 struct JavaImportDirective {
2516   StringRef Identifier;
2517   StringRef Text;
2518   unsigned Offset;
2519   std::vector<StringRef> AssociatedCommentLines;
2520   bool IsStatic;
2521 };
2522 
2523 } // end anonymous namespace
2524 
2525 // Determines whether 'Ranges' intersects with ('Start', 'End').
2526 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
2527                          unsigned End) {
2528   for (auto Range : Ranges)
2529     if (Range.getOffset() < End &&
2530         Range.getOffset() + Range.getLength() > Start)
2531       return true;
2532   return false;
2533 }
2534 
2535 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
2536 // before sorting/deduplicating. Index is the index of the include under the
2537 // cursor in the original set of includes. If this include has duplicates, it is
2538 // the index of the first of the duplicates as the others are going to be
2539 // removed. OffsetToEOL describes the cursor's position relative to the end of
2540 // its current line.
2541 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
2542 static std::pair<unsigned, unsigned>
2543 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
2544                 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) {
2545   unsigned CursorIndex = UINT_MAX;
2546   unsigned OffsetToEOL = 0;
2547   for (int i = 0, e = Includes.size(); i != e; ++i) {
2548     unsigned Start = Includes[Indices[i]].Offset;
2549     unsigned End = Start + Includes[Indices[i]].Text.size();
2550     if (!(Cursor >= Start && Cursor < End))
2551       continue;
2552     CursorIndex = Indices[i];
2553     OffsetToEOL = End - Cursor;
2554     // Put the cursor on the only remaining #include among the duplicate
2555     // #includes.
2556     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
2557       CursorIndex = i;
2558     break;
2559   }
2560   return std::make_pair(CursorIndex, OffsetToEOL);
2561 }
2562 
2563 // Replace all "\r\n" with "\n".
2564 std::string replaceCRLF(const std::string &Code) {
2565   std::string NewCode;
2566   size_t Pos = 0, LastPos = 0;
2567 
2568   do {
2569     Pos = Code.find("\r\n", LastPos);
2570     if (Pos == LastPos) {
2571       ++LastPos;
2572       continue;
2573     }
2574     if (Pos == std::string::npos) {
2575       NewCode += Code.substr(LastPos);
2576       break;
2577     }
2578     NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
2579     LastPos = Pos + 2;
2580   } while (Pos != std::string::npos);
2581 
2582   return NewCode;
2583 }
2584 
2585 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
2586 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
2587 // source order.
2588 // #include directives with the same text will be deduplicated, and only the
2589 // first #include in the duplicate #includes remains. If the `Cursor` is
2590 // provided and put on a deleted #include, it will be moved to the remaining
2591 // #include in the duplicate #includes.
2592 static void sortCppIncludes(const FormatStyle &Style,
2593                             const SmallVectorImpl<IncludeDirective> &Includes,
2594                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2595                             StringRef Code, tooling::Replacements &Replaces,
2596                             unsigned *Cursor) {
2597   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2598   unsigned IncludesBeginOffset = Includes.front().Offset;
2599   unsigned IncludesEndOffset =
2600       Includes.back().Offset + Includes.back().Text.size();
2601   unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
2602   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
2603     return;
2604   SmallVector<unsigned, 16> Indices =
2605       llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
2606 
2607   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive)
2608     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2609       const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
2610       const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
2611       return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
2612                       Includes[LHSI].Filename) <
2613              std::tie(Includes[RHSI].Priority, RHSFilenameLower,
2614                       Includes[RHSI].Filename);
2615     });
2616   else
2617     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2618       return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
2619              std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
2620     });
2621 
2622   // The index of the include on which the cursor will be put after
2623   // sorting/deduplicating.
2624   unsigned CursorIndex;
2625   // The offset from cursor to the end of line.
2626   unsigned CursorToEOLOffset;
2627   if (Cursor)
2628     std::tie(CursorIndex, CursorToEOLOffset) =
2629         FindCursorIndex(Includes, Indices, *Cursor);
2630 
2631   // Deduplicate #includes.
2632   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2633                             [&](unsigned LHSI, unsigned RHSI) {
2634                               return Includes[LHSI].Text.trim() ==
2635                                      Includes[RHSI].Text.trim();
2636                             }),
2637                 Indices.end());
2638 
2639   int CurrentCategory = Includes.front().Category;
2640 
2641   // If the #includes are out of order, we generate a single replacement fixing
2642   // the entire block. Otherwise, no replacement is generated.
2643   // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
2644   // enough as additional newlines might be added or removed across #include
2645   // blocks. This we handle below by generating the updated #imclude blocks and
2646   // comparing it to the original.
2647   if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) &&
2648       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
2649     return;
2650 
2651   std::string result;
2652   for (unsigned Index : Indices) {
2653     if (!result.empty()) {
2654       result += "\n";
2655       if (Style.IncludeStyle.IncludeBlocks ==
2656               tooling::IncludeStyle::IBS_Regroup &&
2657           CurrentCategory != Includes[Index].Category)
2658         result += "\n";
2659     }
2660     result += Includes[Index].Text;
2661     if (Cursor && CursorIndex == Index)
2662       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
2663     CurrentCategory = Includes[Index].Category;
2664   }
2665 
2666   // If the #includes are out of order, we generate a single replacement fixing
2667   // the entire range of blocks. Otherwise, no replacement is generated.
2668   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2669                                  IncludesBeginOffset, IncludesBlockSize))))
2670     return;
2671 
2672   auto Err = Replaces.add(tooling::Replacement(
2673       FileName, Includes.front().Offset, IncludesBlockSize, result));
2674   // FIXME: better error handling. For now, just skip the replacement for the
2675   // release version.
2676   if (Err) {
2677     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2678     assert(false);
2679   }
2680 }
2681 
2682 namespace {
2683 
2684 const char CppIncludeRegexPattern[] =
2685     R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))";
2686 
2687 } // anonymous namespace
2688 
2689 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
2690                                       ArrayRef<tooling::Range> Ranges,
2691                                       StringRef FileName,
2692                                       tooling::Replacements &Replaces,
2693                                       unsigned *Cursor) {
2694   unsigned Prev = llvm::StringSwitch<size_t>(Code)
2695                       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
2696                       .Default(0);
2697   unsigned SearchFrom = 0;
2698   llvm::Regex IncludeRegex(CppIncludeRegexPattern);
2699   SmallVector<StringRef, 4> Matches;
2700   SmallVector<IncludeDirective, 16> IncludesInBlock;
2701 
2702   // In compiled files, consider the first #include to be the main #include of
2703   // the file if it is not a system #include. This ensures that the header
2704   // doesn't have hidden dependencies
2705   // (http://llvm.org/docs/CodingStandards.html#include-style).
2706   //
2707   // FIXME: Do some validation, e.g. edit distance of the base name, to fix
2708   // cases where the first #include is unlikely to be the main header.
2709   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2710   bool FirstIncludeBlock = true;
2711   bool MainIncludeFound = false;
2712   bool FormattingOff = false;
2713 
2714   // '[' must be the first and '-' the last character inside [...].
2715   llvm::Regex RawStringRegex(
2716       "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
2717   SmallVector<StringRef, 2> RawStringMatches;
2718   std::string RawStringTermination = ")\"";
2719 
2720   for (;;) {
2721     auto Pos = Code.find('\n', SearchFrom);
2722     StringRef Line =
2723         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2724 
2725     StringRef Trimmed = Line.trim();
2726 
2727     // #includes inside raw string literals need to be ignored.
2728     // or we will sort the contents of the string.
2729     // Skip past until we think we are at the rawstring literal close.
2730     if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
2731       std::string CharSequence = RawStringMatches[1].str();
2732       RawStringTermination = ")" + CharSequence + "\"";
2733       FormattingOff = true;
2734     }
2735 
2736     if (Trimmed.contains(RawStringTermination))
2737       FormattingOff = false;
2738 
2739     if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
2740       FormattingOff = true;
2741     else if (Trimmed == "// clang-format on" ||
2742              Trimmed == "/* clang-format on */")
2743       FormattingOff = false;
2744 
2745     const bool EmptyLineSkipped =
2746         Trimmed.empty() &&
2747         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
2748          Style.IncludeStyle.IncludeBlocks ==
2749              tooling::IncludeStyle::IBS_Regroup);
2750 
2751     bool MergeWithNextLine = Trimmed.endswith("\\");
2752     if (!FormattingOff && !MergeWithNextLine) {
2753       if (IncludeRegex.match(Line, &Matches)) {
2754         StringRef IncludeName = Matches[2];
2755         if (Line.contains("/*") && !Line.contains("*/")) {
2756           // #include with a start of a block comment, but without the end.
2757           // Need to keep all the lines until the end of the comment together.
2758           // FIXME: This is somehow simplified check that probably does not work
2759           // correctly if there are multiple comments on a line.
2760           Pos = Code.find("*/", SearchFrom);
2761           Line = Code.substr(
2762               Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
2763         }
2764         int Category = Categories.getIncludePriority(
2765             IncludeName,
2766             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
2767         int Priority = Categories.getSortIncludePriority(
2768             IncludeName, !MainIncludeFound && FirstIncludeBlock);
2769         if (Category == 0)
2770           MainIncludeFound = true;
2771         IncludesInBlock.push_back(
2772             {IncludeName, Line, Prev, Category, Priority});
2773       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
2774         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
2775                         Replaces, Cursor);
2776         IncludesInBlock.clear();
2777         if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers.
2778           FirstIncludeBlock = true;
2779         else
2780           FirstIncludeBlock = false;
2781       }
2782     }
2783     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2784       break;
2785 
2786     if (!MergeWithNextLine)
2787       Prev = Pos + 1;
2788     SearchFrom = Pos + 1;
2789   }
2790   if (!IncludesInBlock.empty()) {
2791     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
2792                     Cursor);
2793   }
2794   return Replaces;
2795 }
2796 
2797 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
2798 // if the import does not match any given groups.
2799 static unsigned findJavaImportGroup(const FormatStyle &Style,
2800                                     StringRef ImportIdentifier) {
2801   unsigned LongestMatchIndex = UINT_MAX;
2802   unsigned LongestMatchLength = 0;
2803   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
2804     const std::string &GroupPrefix = Style.JavaImportGroups[I];
2805     if (ImportIdentifier.startswith(GroupPrefix) &&
2806         GroupPrefix.length() > LongestMatchLength) {
2807       LongestMatchIndex = I;
2808       LongestMatchLength = GroupPrefix.length();
2809     }
2810   }
2811   return LongestMatchIndex;
2812 }
2813 
2814 // Sorts and deduplicates a block of includes given by 'Imports' based on
2815 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
2816 // Import declarations with the same text will be deduplicated. Between each
2817 // import group, a newline is inserted, and within each import group, a
2818 // lexicographic sort based on ASCII value is performed.
2819 static void sortJavaImports(const FormatStyle &Style,
2820                             const SmallVectorImpl<JavaImportDirective> &Imports,
2821                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2822                             StringRef Code, tooling::Replacements &Replaces) {
2823   unsigned ImportsBeginOffset = Imports.front().Offset;
2824   unsigned ImportsEndOffset =
2825       Imports.back().Offset + Imports.back().Text.size();
2826   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
2827   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
2828     return;
2829 
2830   SmallVector<unsigned, 16> Indices =
2831       llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
2832   SmallVector<unsigned, 16> JavaImportGroups;
2833   JavaImportGroups.reserve(Imports.size());
2834   for (const JavaImportDirective &Import : Imports)
2835     JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
2836 
2837   bool StaticImportAfterNormalImport =
2838       Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
2839   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2840     // Negating IsStatic to push static imports above non-static imports.
2841     return std::make_tuple(!Imports[LHSI].IsStatic ^
2842                                StaticImportAfterNormalImport,
2843                            JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
2844            std::make_tuple(!Imports[RHSI].IsStatic ^
2845                                StaticImportAfterNormalImport,
2846                            JavaImportGroups[RHSI], Imports[RHSI].Identifier);
2847   });
2848 
2849   // Deduplicate imports.
2850   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2851                             [&](unsigned LHSI, unsigned RHSI) {
2852                               return Imports[LHSI].Text == Imports[RHSI].Text;
2853                             }),
2854                 Indices.end());
2855 
2856   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
2857   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
2858 
2859   std::string result;
2860   for (unsigned Index : Indices) {
2861     if (!result.empty()) {
2862       result += "\n";
2863       if (CurrentIsStatic != Imports[Index].IsStatic ||
2864           CurrentImportGroup != JavaImportGroups[Index])
2865         result += "\n";
2866     }
2867     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
2868       result += CommentLine;
2869       result += "\n";
2870     }
2871     result += Imports[Index].Text;
2872     CurrentIsStatic = Imports[Index].IsStatic;
2873     CurrentImportGroup = JavaImportGroups[Index];
2874   }
2875 
2876   // If the imports are out of order, we generate a single replacement fixing
2877   // the entire block. Otherwise, no replacement is generated.
2878   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2879                                  Imports.front().Offset, ImportsBlockSize))))
2880     return;
2881 
2882   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
2883                                                ImportsBlockSize, result));
2884   // FIXME: better error handling. For now, just skip the replacement for the
2885   // release version.
2886   if (Err) {
2887     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2888     assert(false);
2889   }
2890 }
2891 
2892 namespace {
2893 
2894 const char JavaImportRegexPattern[] =
2895     "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
2896 
2897 } // anonymous namespace
2898 
2899 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
2900                                       ArrayRef<tooling::Range> Ranges,
2901                                       StringRef FileName,
2902                                       tooling::Replacements &Replaces) {
2903   unsigned Prev = 0;
2904   unsigned SearchFrom = 0;
2905   llvm::Regex ImportRegex(JavaImportRegexPattern);
2906   SmallVector<StringRef, 4> Matches;
2907   SmallVector<JavaImportDirective, 16> ImportsInBlock;
2908   std::vector<StringRef> AssociatedCommentLines;
2909 
2910   bool FormattingOff = false;
2911 
2912   for (;;) {
2913     auto Pos = Code.find('\n', SearchFrom);
2914     StringRef Line =
2915         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2916 
2917     StringRef Trimmed = Line.trim();
2918     if (Trimmed == "// clang-format off")
2919       FormattingOff = true;
2920     else if (Trimmed == "// clang-format on")
2921       FormattingOff = false;
2922 
2923     if (ImportRegex.match(Line, &Matches)) {
2924       if (FormattingOff) {
2925         // If at least one import line has formatting turned off, turn off
2926         // formatting entirely.
2927         return Replaces;
2928       }
2929       StringRef Static = Matches[1];
2930       StringRef Identifier = Matches[2];
2931       bool IsStatic = false;
2932       if (Static.contains("static"))
2933         IsStatic = true;
2934       ImportsInBlock.push_back(
2935           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
2936       AssociatedCommentLines.clear();
2937     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
2938       // Associating comments within the imports with the nearest import below
2939       AssociatedCommentLines.push_back(Line);
2940     }
2941     Prev = Pos + 1;
2942     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2943       break;
2944     SearchFrom = Pos + 1;
2945   }
2946   if (!ImportsInBlock.empty())
2947     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
2948   return Replaces;
2949 }
2950 
2951 bool isMpegTS(StringRef Code) {
2952   // MPEG transport streams use the ".ts" file extension. clang-format should
2953   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
2954   // 189 bytes - detect that and return.
2955   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
2956 }
2957 
2958 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); }
2959 
2960 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
2961                                    ArrayRef<tooling::Range> Ranges,
2962                                    StringRef FileName, unsigned *Cursor) {
2963   tooling::Replacements Replaces;
2964   if (!Style.SortIncludes || Style.DisableFormat)
2965     return Replaces;
2966   if (isLikelyXml(Code))
2967     return Replaces;
2968   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
2969       isMpegTS(Code))
2970     return Replaces;
2971   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
2972     return sortJavaScriptImports(Style, Code, Ranges, FileName);
2973   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
2974     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
2975   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
2976   return Replaces;
2977 }
2978 
2979 template <typename T>
2980 static llvm::Expected<tooling::Replacements>
2981 processReplacements(T ProcessFunc, StringRef Code,
2982                     const tooling::Replacements &Replaces,
2983                     const FormatStyle &Style) {
2984   if (Replaces.empty())
2985     return tooling::Replacements();
2986 
2987   auto NewCode = applyAllReplacements(Code, Replaces);
2988   if (!NewCode)
2989     return NewCode.takeError();
2990   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
2991   StringRef FileName = Replaces.begin()->getFilePath();
2992 
2993   tooling::Replacements FormatReplaces =
2994       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2995 
2996   return Replaces.merge(FormatReplaces);
2997 }
2998 
2999 llvm::Expected<tooling::Replacements>
3000 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
3001                    const FormatStyle &Style) {
3002   // We need to use lambda function here since there are two versions of
3003   // `sortIncludes`.
3004   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
3005                          std::vector<tooling::Range> Ranges,
3006                          StringRef FileName) -> tooling::Replacements {
3007     return sortIncludes(Style, Code, Ranges, FileName);
3008   };
3009   auto SortedReplaces =
3010       processReplacements(SortIncludes, Code, Replaces, Style);
3011   if (!SortedReplaces)
3012     return SortedReplaces.takeError();
3013 
3014   // We need to use lambda function here since there are two versions of
3015   // `reformat`.
3016   auto Reformat = [](const FormatStyle &Style, StringRef Code,
3017                      std::vector<tooling::Range> Ranges,
3018                      StringRef FileName) -> tooling::Replacements {
3019     return reformat(Style, Code, Ranges, FileName);
3020   };
3021   return processReplacements(Reformat, Code, *SortedReplaces, Style);
3022 }
3023 
3024 namespace {
3025 
3026 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
3027   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
3028          llvm::Regex(CppIncludeRegexPattern)
3029              .match(Replace.getReplacementText());
3030 }
3031 
3032 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3033   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
3034 }
3035 
3036 // FIXME: insert empty lines between newly created blocks.
3037 tooling::Replacements
3038 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3039                         const FormatStyle &Style) {
3040   if (!Style.isCpp())
3041     return Replaces;
3042 
3043   tooling::Replacements HeaderInsertions;
3044   std::set<llvm::StringRef> HeadersToDelete;
3045   tooling::Replacements Result;
3046   for (const auto &R : Replaces) {
3047     if (isHeaderInsertion(R)) {
3048       // Replacements from \p Replaces must be conflict-free already, so we can
3049       // simply consume the error.
3050       llvm::consumeError(HeaderInsertions.add(R));
3051     } else if (isHeaderDeletion(R)) {
3052       HeadersToDelete.insert(R.getReplacementText());
3053     } else if (R.getOffset() == UINT_MAX) {
3054       llvm::errs() << "Insertions other than header #include insertion are "
3055                       "not supported! "
3056                    << R.getReplacementText() << "\n";
3057     } else {
3058       llvm::consumeError(Result.add(R));
3059     }
3060   }
3061   if (HeaderInsertions.empty() && HeadersToDelete.empty())
3062     return Replaces;
3063 
3064   StringRef FileName = Replaces.begin()->getFilePath();
3065   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
3066 
3067   for (const auto &Header : HeadersToDelete) {
3068     tooling::Replacements Replaces =
3069         Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
3070     for (const auto &R : Replaces) {
3071       auto Err = Result.add(R);
3072       if (Err) {
3073         // Ignore the deletion on conflict.
3074         llvm::errs() << "Failed to add header deletion replacement for "
3075                      << Header << ": " << llvm::toString(std::move(Err))
3076                      << "\n";
3077       }
3078     }
3079   }
3080 
3081   llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
3082   llvm::SmallVector<StringRef, 4> Matches;
3083   for (const auto &R : HeaderInsertions) {
3084     auto IncludeDirective = R.getReplacementText();
3085     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
3086     assert(Matched && "Header insertion replacement must have replacement text "
3087                       "'#include ...'");
3088     (void)Matched;
3089     auto IncludeName = Matches[2];
3090     auto Replace =
3091         Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"));
3092     if (Replace) {
3093       auto Err = Result.add(*Replace);
3094       if (Err) {
3095         llvm::consumeError(std::move(Err));
3096         unsigned NewOffset =
3097             Result.getShiftedCodePosition(Replace->getOffset());
3098         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3099                                             Replace->getReplacementText());
3100         Result = Result.merge(tooling::Replacements(Shifted));
3101       }
3102     }
3103   }
3104   return Result;
3105 }
3106 
3107 } // anonymous namespace
3108 
3109 llvm::Expected<tooling::Replacements>
3110 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
3111                           const FormatStyle &Style) {
3112   // We need to use lambda function here since there are two versions of
3113   // `cleanup`.
3114   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3115                     std::vector<tooling::Range> Ranges,
3116                     StringRef FileName) -> tooling::Replacements {
3117     return cleanup(Style, Code, Ranges, FileName);
3118   };
3119   // Make header insertion replacements insert new headers into correct blocks.
3120   tooling::Replacements NewReplaces =
3121       fixCppIncludeInsertions(Code, Replaces, Style);
3122   return processReplacements(Cleanup, Code, NewReplaces, Style);
3123 }
3124 
3125 namespace internal {
3126 std::pair<tooling::Replacements, unsigned>
3127 reformat(const FormatStyle &Style, StringRef Code,
3128          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
3129          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3130          FormattingAttemptStatus *Status) {
3131   FormatStyle Expanded = Style;
3132   expandPresetsBraceWrapping(Expanded);
3133   expandPresetsSpaceBeforeParens(Expanded);
3134   switch (Expanded.RequiresClausePosition) {
3135   case FormatStyle::RCPS_SingleLine:
3136   case FormatStyle::RCPS_WithPreceding:
3137     Expanded.IndentRequiresClause = false;
3138     break;
3139   default:
3140     break;
3141   }
3142 
3143   if (Expanded.DisableFormat)
3144     return {tooling::Replacements(), 0};
3145   if (isLikelyXml(Code))
3146     return {tooling::Replacements(), 0};
3147   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
3148     return {tooling::Replacements(), 0};
3149 
3150   // JSON only needs the formatting passing.
3151   if (Style.isJson()) {
3152     std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
3153     auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3154                                  NextStartColumn, LastStartColumn);
3155     if (!Env)
3156       return {};
3157     // Perform the actual formatting pass.
3158     tooling::Replacements Replaces =
3159         Formatter(*Env, Style, Status).process().first;
3160     // add a replacement to remove the "x = " from the result.
3161     if (!Replaces.add(tooling::Replacement(FileName, 0, 4, ""))) {
3162       // apply the reformatting changes and the removal of "x = ".
3163       if (applyAllReplacements(Code, Replaces))
3164         return {Replaces, 0};
3165     }
3166     return {tooling::Replacements(), 0};
3167   }
3168 
3169   typedef std::function<std::pair<tooling::Replacements, unsigned>(
3170       const Environment &)>
3171       AnalyzerPass;
3172   SmallVector<AnalyzerPass, 8> Passes;
3173 
3174   if (Style.isCpp()) {
3175     if (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.InsertBraces)
3185       Passes.emplace_back([&](const Environment &Env) {
3186         return BracesInserter(Env, Expanded).process();
3187       });
3188 
3189     if (Style.RemoveBracesLLVM)
3190       Passes.emplace_back([&](const Environment &Env) {
3191         return BracesRemover(Env, Expanded).process();
3192       });
3193 
3194     if (Style.FixNamespaceComments)
3195       Passes.emplace_back([&](const Environment &Env) {
3196         return NamespaceEndCommentsFixer(Env, Expanded).process();
3197       });
3198 
3199     if (Style.SortUsingDeclarations)
3200       Passes.emplace_back([&](const Environment &Env) {
3201         return UsingDeclarationsSorter(Env, Expanded).process();
3202       });
3203   }
3204 
3205   if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave)
3206     Passes.emplace_back([&](const Environment &Env) {
3207       return DefinitionBlockSeparator(Env, Expanded).process();
3208     });
3209 
3210   if (Style.isJavaScript() && Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
3211     Passes.emplace_back([&](const Environment &Env) {
3212       return JavaScriptRequoter(Env, Expanded).process();
3213     });
3214 
3215   Passes.emplace_back([&](const Environment &Env) {
3216     return Formatter(Env, Expanded, Status).process();
3217   });
3218 
3219   if (Style.isJavaScript() &&
3220       Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped)
3221     Passes.emplace_back([&](const Environment &Env) {
3222       return TrailingCommaInserter(Env, Expanded).process();
3223     });
3224 
3225   auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3226                                NextStartColumn, LastStartColumn);
3227   if (!Env)
3228     return {};
3229   llvm::Optional<std::string> CurrentCode = None;
3230   tooling::Replacements Fixes;
3231   unsigned Penalty = 0;
3232   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
3233     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3234     auto NewCode = applyAllReplacements(
3235         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3236     if (NewCode) {
3237       Fixes = Fixes.merge(PassFixes.first);
3238       Penalty += PassFixes.second;
3239       if (I + 1 < E) {
3240         CurrentCode = std::move(*NewCode);
3241         Env = Environment::make(
3242             *CurrentCode, FileName,
3243             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3244             FirstStartColumn, NextStartColumn, LastStartColumn);
3245         if (!Env)
3246           return {};
3247       }
3248     }
3249   }
3250 
3251   return {Fixes, Penalty};
3252 }
3253 } // namespace internal
3254 
3255 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3256                                ArrayRef<tooling::Range> Ranges,
3257                                StringRef FileName,
3258                                FormattingAttemptStatus *Status) {
3259   return internal::reformat(Style, Code, Ranges,
3260                             /*FirstStartColumn=*/0,
3261                             /*NextStartColumn=*/0,
3262                             /*LastStartColumn=*/0, FileName, Status)
3263       .first;
3264 }
3265 
3266 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
3267                               ArrayRef<tooling::Range> Ranges,
3268                               StringRef FileName) {
3269   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3270   if (Style.Language != FormatStyle::LK_Cpp)
3271     return tooling::Replacements();
3272   auto Env = Environment::make(Code, FileName, Ranges);
3273   if (!Env)
3274     return {};
3275   return Cleaner(*Env, Style).process().first;
3276 }
3277 
3278 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3279                                ArrayRef<tooling::Range> Ranges,
3280                                StringRef FileName, bool *IncompleteFormat) {
3281   FormattingAttemptStatus Status;
3282   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
3283   if (!Status.FormatComplete)
3284     *IncompleteFormat = true;
3285   return Result;
3286 }
3287 
3288 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
3289                                               StringRef Code,
3290                                               ArrayRef<tooling::Range> Ranges,
3291                                               StringRef FileName) {
3292   auto Env = Environment::make(Code, FileName, Ranges);
3293   if (!Env)
3294     return {};
3295   return NamespaceEndCommentsFixer(*Env, Style).process().first;
3296 }
3297 
3298 tooling::Replacements separateDefinitionBlocks(const FormatStyle &Style,
3299                                                StringRef Code,
3300                                                ArrayRef<tooling::Range> Ranges,
3301                                                StringRef FileName) {
3302   auto Env = Environment::make(Code, FileName, Ranges);
3303   if (!Env)
3304     return {};
3305   return DefinitionBlockSeparator(*Env, Style).process().first;
3306 }
3307 
3308 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
3309                                             StringRef Code,
3310                                             ArrayRef<tooling::Range> Ranges,
3311                                             StringRef FileName) {
3312   auto Env = Environment::make(Code, FileName, Ranges);
3313   if (!Env)
3314     return {};
3315   return UsingDeclarationsSorter(*Env, Style).process().first;
3316 }
3317 
3318 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
3319   LangOptions LangOpts;
3320 
3321   FormatStyle::LanguageStandard LexingStd = Style.Standard;
3322   if (LexingStd == FormatStyle::LS_Auto)
3323     LexingStd = FormatStyle::LS_Latest;
3324   if (LexingStd == FormatStyle::LS_Latest)
3325     LexingStd = FormatStyle::LS_Cpp20;
3326   LangOpts.CPlusPlus = 1;
3327   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
3328   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
3329   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
3330   LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
3331   LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
3332   // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3333   // the sequence "<::" will be unconditionally treated as "[:".
3334   // Cf. Lexer::LexTokenInternal.
3335   LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
3336 
3337   LangOpts.LineComment = 1;
3338   bool AlternativeOperators = Style.isCpp();
3339   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
3340   LangOpts.Bool = 1;
3341   LangOpts.ObjC = 1;
3342   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
3343   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
3344   LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
3345   return LangOpts;
3346 }
3347 
3348 const char *StyleOptionHelpDescription =
3349     "Coding style, currently supports:\n"
3350     "  LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n"
3351     "Use -style=file to load style configuration from\n"
3352     ".clang-format file located in one of the parent\n"
3353     "directories of the source file (or current\n"
3354     "directory for stdin).\n"
3355     "Use -style=file:<format_file_path> to explicitly specify\n"
3356     "the configuration file.\n"
3357     "Use -style=\"{key: value, ...}\" to set specific\n"
3358     "parameters, e.g.:\n"
3359     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3360 
3361 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
3362   if (FileName.endswith(".java"))
3363     return FormatStyle::LK_Java;
3364   if (FileName.endswith_insensitive(".js") ||
3365       FileName.endswith_insensitive(".mjs") ||
3366       FileName.endswith_insensitive(".ts"))
3367     return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
3368   if (FileName.endswith(".m") || FileName.endswith(".mm"))
3369     return FormatStyle::LK_ObjC;
3370   if (FileName.endswith_insensitive(".proto") ||
3371       FileName.endswith_insensitive(".protodevel"))
3372     return FormatStyle::LK_Proto;
3373   if (FileName.endswith_insensitive(".textpb") ||
3374       FileName.endswith_insensitive(".pb.txt") ||
3375       FileName.endswith_insensitive(".textproto") ||
3376       FileName.endswith_insensitive(".asciipb"))
3377     return FormatStyle::LK_TextProto;
3378   if (FileName.endswith_insensitive(".td"))
3379     return FormatStyle::LK_TableGen;
3380   if (FileName.endswith_insensitive(".cs"))
3381     return FormatStyle::LK_CSharp;
3382   if (FileName.endswith_insensitive(".json"))
3383     return FormatStyle::LK_Json;
3384   return FormatStyle::LK_Cpp;
3385 }
3386 
3387 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
3388   const auto GuessedLanguage = getLanguageByFileName(FileName);
3389   if (GuessedLanguage == FormatStyle::LK_Cpp) {
3390     auto Extension = llvm::sys::path::extension(FileName);
3391     // If there's no file extension (or it's .h), we need to check the contents
3392     // of the code to see if it contains Objective-C.
3393     if (Extension.empty() || Extension == ".h") {
3394       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
3395       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
3396       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
3397       Guesser.process();
3398       if (Guesser.isObjC())
3399         return FormatStyle::LK_ObjC;
3400     }
3401   }
3402   return GuessedLanguage;
3403 }
3404 
3405 const char *DefaultFormatStyle = "file";
3406 
3407 const char *DefaultFallbackStyle = "LLVM";
3408 
3409 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
3410 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
3411                        FormatStyle *Style, bool AllowUnknownOptions) {
3412   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3413       FS->getBufferForFile(ConfigFile.str());
3414   if (auto EC = Text.getError())
3415     return EC;
3416   if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions))
3417     return EC;
3418   return Text;
3419 }
3420 
3421 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
3422                                      StringRef FallbackStyleName,
3423                                      StringRef Code, llvm::vfs::FileSystem *FS,
3424                                      bool AllowUnknownOptions) {
3425   if (!FS)
3426     FS = llvm::vfs::getRealFileSystem().get();
3427   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
3428 
3429   FormatStyle FallbackStyle = getNoStyle();
3430   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
3431     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
3432 
3433   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
3434       ChildFormatTextToApply;
3435 
3436   if (StyleName.startswith("{")) {
3437     // Parse YAML/JSON style from the command line.
3438     StringRef Source = "<command-line>";
3439     if (std::error_code ec =
3440             parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
3441                                AllowUnknownOptions))
3442       return make_string_error("Error parsing -style: " + ec.message());
3443     if (Style.InheritsParentConfig)
3444       ChildFormatTextToApply.emplace_back(
3445           llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
3446     else
3447       return Style;
3448   }
3449 
3450   // User provided clang-format file using -style=file:path/to/format/file.
3451   if (!Style.InheritsParentConfig &&
3452       StyleName.startswith_insensitive("file:")) {
3453     auto ConfigFile = StyleName.substr(5);
3454     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3455         loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
3456     if (auto EC = Text.getError())
3457       return make_string_error("Error reading " + ConfigFile + ": " +
3458                                EC.message());
3459 
3460     LLVM_DEBUG(llvm::dbgs()
3461                << "Using configuration file " << ConfigFile << "\n");
3462 
3463     if (!Style.InheritsParentConfig)
3464       return Style;
3465 
3466     // Search for parent configs starting from the parent directory of
3467     // ConfigFile.
3468     FileName = ConfigFile;
3469     ChildFormatTextToApply.emplace_back(std::move(*Text));
3470   }
3471 
3472   // If the style inherits the parent configuration it is a command line
3473   // configuration, which wants to inherit, so we have to skip the check of the
3474   // StyleName.
3475   if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
3476     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
3477       return make_string_error("Invalid value for -style");
3478     if (!Style.InheritsParentConfig)
3479       return Style;
3480   }
3481 
3482   // Reset possible inheritance
3483   Style.InheritsParentConfig = false;
3484 
3485   // Look for .clang-format/_clang-format file in the file's parent directories.
3486   SmallString<128> UnsuitableConfigFiles;
3487   SmallString<128> Path(FileName);
3488   if (std::error_code EC = FS->makeAbsolute(Path))
3489     return make_string_error(EC.message());
3490 
3491   llvm::SmallVector<std::string, 2> FilesToLookFor;
3492   FilesToLookFor.push_back(".clang-format");
3493   FilesToLookFor.push_back("_clang-format");
3494 
3495   auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
3496 
3497   auto applyChildFormatTexts = [&](FormatStyle *Style) {
3498     for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
3499       auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions,
3500                                    dropDiagnosticHandler);
3501       // It was already correctly parsed.
3502       assert(!EC);
3503       static_cast<void>(EC);
3504     }
3505   };
3506 
3507   for (StringRef Directory = Path; !Directory.empty();
3508        Directory = llvm::sys::path::parent_path(Directory)) {
3509 
3510     auto Status = FS->status(Directory);
3511     if (!Status ||
3512         Status->getType() != llvm::sys::fs::file_type::directory_file)
3513       continue;
3514 
3515     for (const auto &F : FilesToLookFor) {
3516       SmallString<128> ConfigFile(Directory);
3517 
3518       llvm::sys::path::append(ConfigFile, F);
3519       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
3520 
3521       Status = FS->status(ConfigFile.str());
3522 
3523       if (Status &&
3524           (Status->getType() == llvm::sys::fs::file_type::regular_file)) {
3525         llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3526             loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
3527         if (auto EC = Text.getError()) {
3528           if (EC == ParseError::Unsuitable) {
3529             if (!UnsuitableConfigFiles.empty())
3530               UnsuitableConfigFiles.append(", ");
3531             UnsuitableConfigFiles.append(ConfigFile);
3532             continue;
3533           }
3534           return make_string_error("Error reading " + ConfigFile + ": " +
3535                                    EC.message());
3536         }
3537         LLVM_DEBUG(llvm::dbgs()
3538                    << "Using configuration file " << ConfigFile << "\n");
3539 
3540         if (!Style.InheritsParentConfig) {
3541           if (ChildFormatTextToApply.empty())
3542             return Style;
3543 
3544           LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
3545           applyChildFormatTexts(&Style);
3546 
3547           return Style;
3548         }
3549 
3550         LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
3551 
3552         // Reset inheritance of style
3553         Style.InheritsParentConfig = false;
3554 
3555         ChildFormatTextToApply.emplace_back(std::move(*Text));
3556 
3557         // Breaking out of the inner loop, since we don't want to parse
3558         // .clang-format AND _clang-format, if both exist. Then we continue the
3559         // inner loop (parent directories) in search for the parent
3560         // configuration.
3561         break;
3562       }
3563     }
3564   }
3565   if (!UnsuitableConfigFiles.empty())
3566     return make_string_error("Configuration file(s) do(es) not support " +
3567                              getLanguageName(Style.Language) + ": " +
3568                              UnsuitableConfigFiles);
3569 
3570   if (!ChildFormatTextToApply.empty()) {
3571     LLVM_DEBUG(llvm::dbgs()
3572                << "Applying child configurations on fallback style\n");
3573     applyChildFormatTexts(&FallbackStyle);
3574   }
3575 
3576   return FallbackStyle;
3577 }
3578 
3579 } // namespace format
3580 } // namespace clang
3581