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