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