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