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