Coverage Report

Created: 2022-01-25 06:29

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