Coverage Report

Created: 2021-09-21 08:58

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