25 #include "llvm/ADT/Sequence.h"
27 #define DEBUG_TYPE "format-formatter"
31 LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat)
36 struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeNoexceptSpecifierStyle> {
39 IO.enumCase(
Value,
"Never", FormatStyle::BBNSS_Never);
40 IO.enumCase(
Value,
"OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen);
41 IO.enumCase(
Value,
"Always", FormatStyle::BBNSS_Always);
45 template <>
struct MappingTraits<
FormatStyle::AlignConsecutiveStyle> {
47 IO.enumCase(
Value,
"None",
48 FormatStyle::AlignConsecutiveStyle(
52 IO.enumCase(
Value,
"Consecutive",
53 FormatStyle::AlignConsecutiveStyle(
57 IO.enumCase(
Value,
"AcrossEmptyLines",
58 FormatStyle::AlignConsecutiveStyle(
62 IO.enumCase(
Value,
"AcrossComments",
63 FormatStyle::AlignConsecutiveStyle(
67 IO.enumCase(
Value,
"AcrossEmptyLinesAndComments",
68 FormatStyle::AlignConsecutiveStyle(
74 IO.enumCase(
Value,
"true",
75 FormatStyle::AlignConsecutiveStyle(
79 IO.enumCase(
Value,
"false",
80 FormatStyle::AlignConsecutiveStyle(
86 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &
Value) {
87 IO.mapOptional(
"Enabled",
Value.Enabled);
88 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
89 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
90 IO.mapOptional(
"AlignCompound",
Value.AlignCompound);
91 IO.mapOptional(
"AlignFunctionPointers",
Value.AlignFunctionPointers);
92 IO.mapOptional(
"PadOperators",
Value.PadOperators);
97 struct MappingTraits<
FormatStyle::ShortCaseStatementsAlignmentStyle> {
99 FormatStyle::ShortCaseStatementsAlignmentStyle &
Value) {
100 IO.mapOptional(
"Enabled",
Value.Enabled);
101 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
102 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
103 IO.mapOptional(
"AlignCaseArrows",
Value.AlignCaseArrows);
104 IO.mapOptional(
"AlignCaseColons",
Value.AlignCaseColons);
109 struct ScalarEnumerationTraits<
FormatStyle::AttributeBreakingStyle> {
111 IO.enumCase(
Value,
"Always", FormatStyle::ABS_Always);
112 IO.enumCase(
Value,
"Leave", FormatStyle::ABS_Leave);
113 IO.enumCase(
Value,
"Never", FormatStyle::ABS_Never);
118 struct ScalarEnumerationTraits<
FormatStyle::ArrayInitializerAlignmentStyle> {
120 FormatStyle::ArrayInitializerAlignmentStyle &
Value) {
121 IO.enumCase(
Value,
"None", FormatStyle::AIAS_None);
122 IO.enumCase(
Value,
"Left", FormatStyle::AIAS_Left);
123 IO.enumCase(
Value,
"Right", FormatStyle::AIAS_Right);
127 template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
129 IO.enumCase(
Value,
"All", FormatStyle::BOS_All);
130 IO.enumCase(
Value,
"true", FormatStyle::BOS_All);
131 IO.enumCase(
Value,
"None", FormatStyle::BOS_None);
132 IO.enumCase(
Value,
"false", FormatStyle::BOS_None);
133 IO.enumCase(
Value,
"NonAssignment", FormatStyle::BOS_NonAssignment);
137 template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
139 IO.enumCase(
Value,
"Auto", FormatStyle::BPS_Auto);
140 IO.enumCase(
Value,
"Always", FormatStyle::BPS_Always);
141 IO.enumCase(
Value,
"Never", FormatStyle::BPS_Never);
146 struct ScalarEnumerationTraits<
FormatStyle::BitFieldColonSpacingStyle> {
148 FormatStyle::BitFieldColonSpacingStyle &
Value) {
149 IO.enumCase(
Value,
"Both", FormatStyle::BFCS_Both);
150 IO.enumCase(
Value,
"None", FormatStyle::BFCS_None);
151 IO.enumCase(
Value,
"Before", FormatStyle::BFCS_Before);
152 IO.enumCase(
Value,
"After", FormatStyle::BFCS_After);
156 template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
158 IO.enumCase(
Value,
"Attach", FormatStyle::BS_Attach);
159 IO.enumCase(
Value,
"Linux", FormatStyle::BS_Linux);
160 IO.enumCase(
Value,
"Mozilla", FormatStyle::BS_Mozilla);
161 IO.enumCase(
Value,
"Stroustrup", FormatStyle::BS_Stroustrup);
162 IO.enumCase(
Value,
"Allman", FormatStyle::BS_Allman);
163 IO.enumCase(
Value,
"Whitesmiths", FormatStyle::BS_Whitesmiths);
164 IO.enumCase(
Value,
"GNU", FormatStyle::BS_GNU);
165 IO.enumCase(
Value,
"WebKit", FormatStyle::BS_WebKit);
166 IO.enumCase(
Value,
"Custom", FormatStyle::BS_Custom);
170 template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
171 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
172 IO.mapOptional(
"AfterCaseLabel", Wrapping.AfterCaseLabel);
173 IO.mapOptional(
"AfterClass", Wrapping.AfterClass);
174 IO.mapOptional(
"AfterControlStatement", Wrapping.AfterControlStatement);
175 IO.mapOptional(
"AfterEnum", Wrapping.AfterEnum);
176 IO.mapOptional(
"AfterExternBlock", Wrapping.AfterExternBlock);
177 IO.mapOptional(
"AfterFunction", Wrapping.AfterFunction);
178 IO.mapOptional(
"AfterNamespace", Wrapping.AfterNamespace);
179 IO.mapOptional(
"AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
180 IO.mapOptional(
"AfterStruct", Wrapping.AfterStruct);
181 IO.mapOptional(
"AfterUnion", Wrapping.AfterUnion);
182 IO.mapOptional(
"BeforeCatch", Wrapping.BeforeCatch);
183 IO.mapOptional(
"BeforeElse", Wrapping.BeforeElse);
184 IO.mapOptional(
"BeforeLambdaBody", Wrapping.BeforeLambdaBody);
185 IO.mapOptional(
"BeforeWhile", Wrapping.BeforeWhile);
186 IO.mapOptional(
"IndentBraces", Wrapping.IndentBraces);
187 IO.mapOptional(
"SplitEmptyFunction", Wrapping.SplitEmptyFunction);
188 IO.mapOptional(
"SplitEmptyRecord", Wrapping.SplitEmptyRecord);
189 IO.mapOptional(
"SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
193 template <>
struct ScalarEnumerationTraits<
FormatStyle::BracketAlignmentStyle> {
195 IO.enumCase(
Value,
"Align", FormatStyle::BAS_Align);
196 IO.enumCase(
Value,
"DontAlign", FormatStyle::BAS_DontAlign);
197 IO.enumCase(
Value,
"AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
198 IO.enumCase(
Value,
"BlockIndent", FormatStyle::BAS_BlockIndent);
201 IO.enumCase(
Value,
"true", FormatStyle::BAS_Align);
202 IO.enumCase(
Value,
"false", FormatStyle::BAS_DontAlign);
207 struct ScalarEnumerationTraits<
208 FormatStyle::BraceWrappingAfterControlStatementStyle> {
211 FormatStyle::BraceWrappingAfterControlStatementStyle &
Value) {
212 IO.enumCase(
Value,
"Never", FormatStyle::BWACS_Never);
213 IO.enumCase(
Value,
"MultiLine", FormatStyle::BWACS_MultiLine);
214 IO.enumCase(
Value,
"Always", FormatStyle::BWACS_Always);
217 IO.enumCase(
Value,
"false", FormatStyle::BWACS_Never);
218 IO.enumCase(
Value,
"true", FormatStyle::BWACS_Always);
223 struct ScalarEnumerationTraits<
224 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
227 IO.enumCase(
Value,
"Never", FormatStyle::BBCDS_Never);
228 IO.enumCase(
Value,
"Allowed", FormatStyle::BBCDS_Allowed);
229 IO.enumCase(
Value,
"Always", FormatStyle::BBCDS_Always);
232 IO.enumCase(
Value,
"true", FormatStyle::BBCDS_Always);
233 IO.enumCase(
Value,
"false", FormatStyle::BBCDS_Allowed);
238 struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeInlineASMColonStyle> {
240 FormatStyle::BreakBeforeInlineASMColonStyle &
Value) {
241 IO.enumCase(
Value,
"Never", FormatStyle::BBIAS_Never);
242 IO.enumCase(
Value,
"OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
243 IO.enumCase(
Value,
"Always", FormatStyle::BBIAS_Always);
248 struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
251 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BCIS_BeforeColon);
252 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BCIS_BeforeComma);
253 IO.enumCase(
Value,
"AfterColon", FormatStyle::BCIS_AfterColon);
258 struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
260 FormatStyle::BreakInheritanceListStyle &
Value) {
261 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BILS_BeforeColon);
262 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BILS_BeforeComma);
263 IO.enumCase(
Value,
"AfterColon", FormatStyle::BILS_AfterColon);
264 IO.enumCase(
Value,
"AfterComma", FormatStyle::BILS_AfterComma);
269 struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
271 FormatStyle::BreakTemplateDeclarationsStyle &
Value) {
272 IO.enumCase(
Value,
"Leave", FormatStyle::BTDS_Leave);
273 IO.enumCase(
Value,
"No", FormatStyle::BTDS_No);
274 IO.enumCase(
Value,
"MultiLine", FormatStyle::BTDS_MultiLine);
275 IO.enumCase(
Value,
"Yes", FormatStyle::BTDS_Yes);
278 IO.enumCase(
Value,
"false", FormatStyle::BTDS_MultiLine);
279 IO.enumCase(
Value,
"true", FormatStyle::BTDS_Yes);
283 template <>
struct ScalarEnumerationTraits<
FormatStyle::DAGArgStyle> {
285 IO.enumCase(
Value,
"DontBreak", FormatStyle::DAS_DontBreak);
286 IO.enumCase(
Value,
"BreakElements", FormatStyle::DAS_BreakElements);
287 IO.enumCase(
Value,
"BreakAll", FormatStyle::DAS_BreakAll);
292 struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
295 IO.enumCase(
Value,
"None", FormatStyle::DRTBS_None);
296 IO.enumCase(
Value,
"All", FormatStyle::DRTBS_All);
297 IO.enumCase(
Value,
"TopLevel", FormatStyle::DRTBS_TopLevel);
300 IO.enumCase(
Value,
"false", FormatStyle::DRTBS_None);
301 IO.enumCase(
Value,
"true", FormatStyle::DRTBS_All);
306 struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
308 FormatStyle::EscapedNewlineAlignmentStyle &
Value) {
309 IO.enumCase(
Value,
"DontAlign", FormatStyle::ENAS_DontAlign);
310 IO.enumCase(
Value,
"Left", FormatStyle::ENAS_Left);
311 IO.enumCase(
Value,
"LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);
312 IO.enumCase(
Value,
"Right", FormatStyle::ENAS_Right);
315 IO.enumCase(
Value,
"true", FormatStyle::ENAS_Left);
316 IO.enumCase(
Value,
"false", FormatStyle::ENAS_Right);
321 struct ScalarEnumerationTraits<
FormatStyle::EmptyLineAfterAccessModifierStyle> {
324 IO.enumCase(
Value,
"Never", FormatStyle::ELAAMS_Never);
325 IO.enumCase(
Value,
"Leave", FormatStyle::ELAAMS_Leave);
326 IO.enumCase(
Value,
"Always", FormatStyle::ELAAMS_Always);
331 struct ScalarEnumerationTraits<
335 IO.enumCase(
Value,
"Never", FormatStyle::ELBAMS_Never);
336 IO.enumCase(
Value,
"Leave", FormatStyle::ELBAMS_Leave);
337 IO.enumCase(
Value,
"LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
338 IO.enumCase(
Value,
"Always", FormatStyle::ELBAMS_Always);
343 struct ScalarEnumerationTraits<
FormatStyle::IndentExternBlockStyle> {
345 IO.enumCase(
Value,
"AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
346 IO.enumCase(
Value,
"Indent", FormatStyle::IEBS_Indent);
347 IO.enumCase(
Value,
"NoIndent", FormatStyle::IEBS_NoIndent);
348 IO.enumCase(
Value,
"true", FormatStyle::IEBS_Indent);
349 IO.enumCase(
Value,
"false", FormatStyle::IEBS_NoIndent);
353 template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
354 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &
Base) {
355 IO.mapOptional(
"Binary",
Base.Binary);
356 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigits);
357 IO.mapOptional(
"Decimal",
Base.Decimal);
358 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigits);
359 IO.mapOptional(
"Hex",
Base.Hex);
360 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigits);
364 template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
366 IO.enumCase(
Value,
"Leave", FormatStyle::JSQS_Leave);
367 IO.enumCase(
Value,
"Single", FormatStyle::JSQS_Single);
368 IO.enumCase(
Value,
"Double", FormatStyle::JSQS_Double);
372 template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
374 IO.enumCase(
Value,
"Cpp", FormatStyle::LK_Cpp);
375 IO.enumCase(
Value,
"Java", FormatStyle::LK_Java);
376 IO.enumCase(
Value,
"JavaScript", FormatStyle::LK_JavaScript);
377 IO.enumCase(
Value,
"ObjC", FormatStyle::LK_ObjC);
378 IO.enumCase(
Value,
"Proto", FormatStyle::LK_Proto);
379 IO.enumCase(
Value,
"TableGen", FormatStyle::LK_TableGen);
380 IO.enumCase(
Value,
"TextProto", FormatStyle::LK_TextProto);
381 IO.enumCase(
Value,
"CSharp", FormatStyle::LK_CSharp);
382 IO.enumCase(
Value,
"Json", FormatStyle::LK_Json);
383 IO.enumCase(
Value,
"Verilog", FormatStyle::LK_Verilog);
387 template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
389 IO.enumCase(
Value,
"c++03", FormatStyle::LS_Cpp03);
390 IO.enumCase(
Value,
"C++03", FormatStyle::LS_Cpp03);
391 IO.enumCase(
Value,
"Cpp03", FormatStyle::LS_Cpp03);
393 IO.enumCase(
Value,
"c++11", FormatStyle::LS_Cpp11);
394 IO.enumCase(
Value,
"C++11", FormatStyle::LS_Cpp11);
396 IO.enumCase(
Value,
"c++14", FormatStyle::LS_Cpp14);
397 IO.enumCase(
Value,
"c++17", FormatStyle::LS_Cpp17);
398 IO.enumCase(
Value,
"c++20", FormatStyle::LS_Cpp20);
400 IO.enumCase(
Value,
"Latest", FormatStyle::LS_Latest);
401 IO.enumCase(
Value,
"Cpp11", FormatStyle::LS_Latest);
402 IO.enumCase(
Value,
"Auto", FormatStyle::LS_Auto);
407 struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
409 FormatStyle::LambdaBodyIndentationKind &
Value) {
410 IO.enumCase(
Value,
"Signature", FormatStyle::LBI_Signature);
411 IO.enumCase(
Value,
"OuterScope", FormatStyle::LBI_OuterScope);
415 template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
417 IO.enumCase(
Value,
"LF", FormatStyle::LE_LF);
418 IO.enumCase(
Value,
"CRLF", FormatStyle::LE_CRLF);
419 IO.enumCase(
Value,
"DeriveLF", FormatStyle::LE_DeriveLF);
420 IO.enumCase(
Value,
"DeriveCRLF", FormatStyle::LE_DeriveCRLF);
425 struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
427 FormatStyle::NamespaceIndentationKind &
Value) {
428 IO.enumCase(
Value,
"None", FormatStyle::NI_None);
429 IO.enumCase(
Value,
"Inner", FormatStyle::NI_Inner);
430 IO.enumCase(
Value,
"All", FormatStyle::NI_All);
434 template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
436 IO.enumCase(
Value,
"DontAlign", FormatStyle::OAS_DontAlign);
437 IO.enumCase(
Value,
"Align", FormatStyle::OAS_Align);
438 IO.enumCase(
Value,
"AlignAfterOperator",
439 FormatStyle::OAS_AlignAfterOperator);
442 IO.enumCase(
Value,
"true", FormatStyle::OAS_Align);
443 IO.enumCase(
Value,
"false", FormatStyle::OAS_DontAlign);
448 struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
451 IO.enumCase(
Value,
"Never", FormatStyle::PCIS_Never);
452 IO.enumCase(
Value,
"BinPack", FormatStyle::PCIS_BinPack);
453 IO.enumCase(
Value,
"CurrentLine", FormatStyle::PCIS_CurrentLine);
454 IO.enumCase(
Value,
"NextLine", FormatStyle::PCIS_NextLine);
455 IO.enumCase(
Value,
"NextLineOnly", FormatStyle::PCIS_NextLineOnly);
459 template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
461 IO.enumCase(
Value,
"Middle", FormatStyle::PAS_Middle);
462 IO.enumCase(
Value,
"Left", FormatStyle::PAS_Left);
463 IO.enumCase(
Value,
"Right", FormatStyle::PAS_Right);
466 IO.enumCase(
Value,
"true", FormatStyle::PAS_Left);
467 IO.enumCase(
Value,
"false", FormatStyle::PAS_Right);
472 struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
474 IO.enumCase(
Value,
"None", FormatStyle::PPDIS_None);
475 IO.enumCase(
Value,
"AfterHash", FormatStyle::PPDIS_AfterHash);
476 IO.enumCase(
Value,
"BeforeHash", FormatStyle::PPDIS_BeforeHash);
481 struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
483 IO.enumCase(
Value,
"Leave", FormatStyle::QAS_Leave);
484 IO.enumCase(
Value,
"Left", FormatStyle::QAS_Left);
485 IO.enumCase(
Value,
"Right", FormatStyle::QAS_Right);
486 IO.enumCase(
Value,
"Custom", FormatStyle::QAS_Custom);
491 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
492 IO.mapOptional(
"Language", Format.Language);
493 IO.mapOptional(
"Delimiters", Format.Delimiters);
494 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
495 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
496 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
501 struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
503 IO.enumCase(
Value,
"Pointer", FormatStyle::RAS_Pointer);
504 IO.enumCase(
Value,
"Middle", FormatStyle::RAS_Middle);
505 IO.enumCase(
Value,
"Left", FormatStyle::RAS_Left);
506 IO.enumCase(
Value,
"Right", FormatStyle::RAS_Right);
511 struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
513 IO.enumCase(
Value,
"Leave", FormatStyle::RPS_Leave);
514 IO.enumCase(
Value,
"MultipleParentheses",
515 FormatStyle::RPS_MultipleParentheses);
516 IO.enumCase(
Value,
"ReturnStatement", FormatStyle::RPS_ReturnStatement);
521 struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
523 FormatStyle::RequiresClausePositionStyle &
Value) {
524 IO.enumCase(
Value,
"OwnLine", FormatStyle::RCPS_OwnLine);
525 IO.enumCase(
Value,
"WithPreceding", FormatStyle::RCPS_WithPreceding);
526 IO.enumCase(
Value,
"WithFollowing", FormatStyle::RCPS_WithFollowing);
527 IO.enumCase(
Value,
"SingleLine", FormatStyle::RCPS_SingleLine);
532 struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
535 IO.enumCase(
Value,
"Keyword", FormatStyle::REI_Keyword);
536 IO.enumCase(
Value,
"OuterScope", FormatStyle::REI_OuterScope);
541 struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
543 IO.enumCase(
Value,
"None", FormatStyle::RTBS_None);
544 IO.enumCase(
Value,
"Automatic", FormatStyle::RTBS_Automatic);
545 IO.enumCase(
Value,
"ExceptShortType", FormatStyle::RTBS_ExceptShortType);
546 IO.enumCase(
Value,
"All", FormatStyle::RTBS_All);
547 IO.enumCase(
Value,
"TopLevel", FormatStyle::RTBS_TopLevel);
548 IO.enumCase(
Value,
"TopLevelDefinitions",
549 FormatStyle::RTBS_TopLevelDefinitions);
550 IO.enumCase(
Value,
"AllDefinitions", FormatStyle::RTBS_AllDefinitions);
555 struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
557 IO.enumCase(
Value,
"Leave", FormatStyle::SDS_Leave);
558 IO.enumCase(
Value,
"Always", FormatStyle::SDS_Always);
559 IO.enumCase(
Value,
"Never", FormatStyle::SDS_Never);
563 template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
565 IO.enumCase(
Value,
"Never", FormatStyle::SBS_Never);
566 IO.enumCase(
Value,
"false", FormatStyle::SBS_Never);
567 IO.enumCase(
Value,
"Always", FormatStyle::SBS_Always);
568 IO.enumCase(
Value,
"true", FormatStyle::SBS_Always);
569 IO.enumCase(
Value,
"Empty", FormatStyle::SBS_Empty);
573 template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortFunctionStyle> {
575 IO.enumCase(
Value,
"None", FormatStyle::SFS_None);
576 IO.enumCase(
Value,
"false", FormatStyle::SFS_None);
577 IO.enumCase(
Value,
"All", FormatStyle::SFS_All);
578 IO.enumCase(
Value,
"true", FormatStyle::SFS_All);
579 IO.enumCase(
Value,
"Inline", FormatStyle::SFS_Inline);
580 IO.enumCase(
Value,
"InlineOnly", FormatStyle::SFS_InlineOnly);
581 IO.enumCase(
Value,
"Empty", FormatStyle::SFS_Empty);
585 template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
587 IO.enumCase(
Value,
"Never", FormatStyle::SIS_Never);
588 IO.enumCase(
Value,
"WithoutElse", FormatStyle::SIS_WithoutElse);
589 IO.enumCase(
Value,
"OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
590 IO.enumCase(
Value,
"AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
593 IO.enumCase(
Value,
"Always", FormatStyle::SIS_OnlyFirstIf);
594 IO.enumCase(
Value,
"false", FormatStyle::SIS_Never);
595 IO.enumCase(
Value,
"true", FormatStyle::SIS_WithoutElse);
599 template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
601 IO.enumCase(
Value,
"None", FormatStyle::SLS_None);
602 IO.enumCase(
Value,
"false", FormatStyle::SLS_None);
603 IO.enumCase(
Value,
"Empty", FormatStyle::SLS_Empty);
604 IO.enumCase(
Value,
"Inline", FormatStyle::SLS_Inline);
605 IO.enumCase(
Value,
"All", FormatStyle::SLS_All);
606 IO.enumCase(
Value,
"true", FormatStyle::SLS_All);
610 template <>
struct ScalarEnumerationTraits<
FormatStyle::SortIncludesOptions> {
612 IO.enumCase(
Value,
"Never", FormatStyle::SI_Never);
613 IO.enumCase(
Value,
"CaseInsensitive", FormatStyle::SI_CaseInsensitive);
614 IO.enumCase(
Value,
"CaseSensitive", FormatStyle::SI_CaseSensitive);
617 IO.enumCase(
Value,
"false", FormatStyle::SI_Never);
618 IO.enumCase(
Value,
"true", FormatStyle::SI_CaseSensitive);
623 struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
625 FormatStyle::SortJavaStaticImportOptions &
Value) {
626 IO.enumCase(
Value,
"Before", FormatStyle::SJSIO_Before);
627 IO.enumCase(
Value,
"After", FormatStyle::SJSIO_After);
632 struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
634 FormatStyle::SortUsingDeclarationsOptions &
Value) {
635 IO.enumCase(
Value,
"Never", FormatStyle::SUD_Never);
636 IO.enumCase(
Value,
"Lexicographic", FormatStyle::SUD_Lexicographic);
637 IO.enumCase(
Value,
"LexicographicNumeric",
638 FormatStyle::SUD_LexicographicNumeric);
641 IO.enumCase(
Value,
"false", FormatStyle::SUD_Never);
642 IO.enumCase(
Value,
"true", FormatStyle::SUD_LexicographicNumeric);
647 struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
650 IO.enumCase(
Value,
"Default", FormatStyle::SAPQ_Default);
651 IO.enumCase(
Value,
"Before", FormatStyle::SAPQ_Before);
652 IO.enumCase(
Value,
"After", FormatStyle::SAPQ_After);
653 IO.enumCase(
Value,
"Both", FormatStyle::SAPQ_Both);
657 template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
658 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
659 IO.mapOptional(
"AfterControlStatements", Spacing.AfterControlStatements);
660 IO.mapOptional(
"AfterForeachMacros", Spacing.AfterForeachMacros);
661 IO.mapOptional(
"AfterFunctionDefinitionName",
662 Spacing.AfterFunctionDefinitionName);
663 IO.mapOptional(
"AfterFunctionDeclarationName",
664 Spacing.AfterFunctionDeclarationName);
665 IO.mapOptional(
"AfterIfMacros", Spacing.AfterIfMacros);
666 IO.mapOptional(
"AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
667 IO.mapOptional(
"AfterPlacementOperator", Spacing.AfterPlacementOperator);
668 IO.mapOptional(
"AfterRequiresInClause", Spacing.AfterRequiresInClause);
669 IO.mapOptional(
"AfterRequiresInExpression",
670 Spacing.AfterRequiresInExpression);
671 IO.mapOptional(
"BeforeNonEmptyParentheses",
672 Spacing.BeforeNonEmptyParentheses);
677 struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
679 IO.enumCase(
Value,
"Never", FormatStyle::SBPO_Never);
680 IO.enumCase(
Value,
"ControlStatements",
681 FormatStyle::SBPO_ControlStatements);
682 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
683 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
684 IO.enumCase(
Value,
"NonEmptyParentheses",
685 FormatStyle::SBPO_NonEmptyParentheses);
686 IO.enumCase(
Value,
"Always", FormatStyle::SBPO_Always);
687 IO.enumCase(
Value,
"Custom", FormatStyle::SBPO_Custom);
690 IO.enumCase(
Value,
"false", FormatStyle::SBPO_Never);
691 IO.enumCase(
Value,
"true", FormatStyle::SBPO_ControlStatements);
692 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
693 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
697 template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
699 IO.enumCase(
Value,
"Never", FormatStyle::SIAS_Never);
700 IO.enumCase(
Value,
"Always", FormatStyle::SIAS_Always);
701 IO.enumCase(
Value,
"Leave", FormatStyle::SIAS_Leave);
704 IO.enumCase(
Value,
"false", FormatStyle::SIAS_Never);
705 IO.enumCase(
Value,
"true", FormatStyle::SIAS_Always);
709 template <>
struct MappingTraits<
FormatStyle::SpacesInLineComment> {
710 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
712 int signedMaximum =
static_cast<int>(Space.Maximum);
713 IO.mapOptional(
"Minimum", Space.Minimum);
714 IO.mapOptional(
"Maximum", signedMaximum);
715 Space.Maximum =
static_cast<unsigned>(signedMaximum);
717 if (Space.Maximum != -1u)
718 Space.Minimum =
std::min(Space.Minimum, Space.Maximum);
722 template <>
struct MappingTraits<
FormatStyle::SpacesInParensCustom> {
723 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
724 IO.mapOptional(
"InCStyleCasts", Spaces.InCStyleCasts);
725 IO.mapOptional(
"InConditionalStatements", Spaces.InConditionalStatements);
726 IO.mapOptional(
"InEmptyParentheses", Spaces.InEmptyParentheses);
727 IO.mapOptional(
"Other", Spaces.Other);
731 template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
733 IO.enumCase(
Value,
"Never", FormatStyle::SIPO_Never);
734 IO.enumCase(
Value,
"Custom", FormatStyle::SIPO_Custom);
738 template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
740 IO.enumCase(
Value,
"None", FormatStyle::TCS_None);
741 IO.enumCase(
Value,
"Wrapped", FormatStyle::TCS_Wrapped);
746 struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
748 FormatStyle::TrailingCommentsAlignmentKinds &
Value) {
749 IO.enumCase(
Value,
"Leave", FormatStyle::TCAS_Leave);
750 IO.enumCase(
Value,
"Always", FormatStyle::TCAS_Always);
751 IO.enumCase(
Value,
"Never", FormatStyle::TCAS_Never);
755 template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
757 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
758 IO.enumCase(
Value,
"Leave",
759 FormatStyle::TrailingCommentsAlignmentStyle(
760 {FormatStyle::TCAS_Leave, 0}));
762 IO.enumCase(
Value,
"Always",
763 FormatStyle::TrailingCommentsAlignmentStyle(
764 {FormatStyle::TCAS_Always, 0}));
766 IO.enumCase(
Value,
"Never",
767 FormatStyle::TrailingCommentsAlignmentStyle(
768 {FormatStyle::TCAS_Never, 0}));
771 IO.enumCase(
Value,
"true",
772 FormatStyle::TrailingCommentsAlignmentStyle(
773 {FormatStyle::TCAS_Always, 0}));
774 IO.enumCase(
Value,
"false",
775 FormatStyle::TrailingCommentsAlignmentStyle(
776 {FormatStyle::TCAS_Never, 0}));
780 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
781 IO.mapOptional(
"Kind",
Value.Kind);
782 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
786 template <>
struct ScalarEnumerationTraits<
FormatStyle::UseTabStyle> {
788 IO.enumCase(
Value,
"Never", FormatStyle::UT_Never);
789 IO.enumCase(
Value,
"false", FormatStyle::UT_Never);
790 IO.enumCase(
Value,
"Always", FormatStyle::UT_Always);
791 IO.enumCase(
Value,
"true", FormatStyle::UT_Always);
792 IO.enumCase(
Value,
"ForIndentation", FormatStyle::UT_ForIndentation);
793 IO.enumCase(
Value,
"ForContinuationAndIndentation",
794 FormatStyle::UT_ForContinuationAndIndentation);
795 IO.enumCase(
Value,
"AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
802 IO.mapOptional(
"Language", Style.
Language);
804 StringRef BasedOnStyle;
805 if (IO.outputting()) {
806 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
807 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
808 for (StringRef StyleName : Styles) {
811 Style == PredefinedStyle) {
812 BasedOnStyle = StyleName;
817 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
818 if (!BasedOnStyle.empty()) {
819 FormatStyle::LanguageKind OldLanguage = Style.
Language;
820 FormatStyle::LanguageKind
Language =
823 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
841 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
842 BasedOnStyle.equals_insensitive(
"chromium");
843 bool OnCurrentLine = IsGoogleOrChromium;
844 bool OnNextLine =
true;
846 bool BreakBeforeInheritanceComma =
false;
847 bool BreakConstructorInitializersBeforeComma =
false;
849 bool DeriveLineEnding =
true;
850 bool UseCRLF =
false;
852 bool SpaceInEmptyParentheses =
false;
853 bool SpacesInConditionalStatement =
false;
854 bool SpacesInCStyleCastParentheses =
false;
855 bool SpacesInParentheses =
false;
858 if (!IO.outputting()) {
860 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
862 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
864 IO.mapOptional(
"BreakBeforeInheritanceComma",
865 BreakBeforeInheritanceComma);
866 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
867 BreakConstructorInitializersBeforeComma);
868 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
870 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
872 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
876 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
878 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
879 IO.mapOptional(
"SpacesInConditionalStatement",
880 SpacesInConditionalStatement);
881 IO.mapOptional(
"SpacesInCStyleCastParentheses",
882 SpacesInCStyleCastParentheses);
883 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
884 IO.mapOptional(
"UseCRLF", UseCRLF);
890 IO.mapOptional(
"AlignConsecutiveAssignments",
892 IO.mapOptional(
"AlignConsecutiveBitFields",
894 IO.mapOptional(
"AlignConsecutiveDeclarations",
897 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
899 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
901 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
903 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
908 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
910 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
912 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
914 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
916 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
918 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
920 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
922 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
924 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
926 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
928 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
930 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
932 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
934 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
940 IO.mapOptional(
"BracedInitializerIndentWidth",
943 IO.mapOptional(
"BreakAdjacentStringLiterals",
946 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
950 IO.mapOptional(
"BreakBeforeBinaryOperators",
952 IO.mapOptional(
"BreakBeforeConceptDeclarations",
955 IO.mapOptional(
"BreakBeforeInlineASMColon",
957 IO.mapOptional(
"BreakBeforeTernaryOperators",
959 IO.mapOptional(
"BreakConstructorInitializers",
961 IO.mapOptional(
"BreakFunctionDefinitionParameters",
965 IO.mapOptional(
"BreakTemplateDeclarations",
970 IO.mapOptional(
"ConstructorInitializerIndentWidth",
976 IO.mapOptional(
"EmptyLineAfterAccessModifier",
978 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
980 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
984 IO.mapOptional(
"IfMacros", Style.
IfMacros);
988 IO.mapOptional(
"IncludeIsMainSourceRegex",
998 IO.mapOptional(
"IndentWrappedFunctionNames",
1007 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
1011 IO.mapOptional(
"LineEnding", Style.
LineEnding);
1014 IO.mapOptional(
"Macros", Style.
Macros);
1021 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1023 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1026 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1028 IO.mapOptional(
"PackConstructorInitializers",
1031 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1034 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1036 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1038 IO.mapOptional(
"PenaltyBreakScopeResolution",
1041 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1044 IO.mapOptional(
"PenaltyIndentedWhitespace",
1046 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1065 IO.mapOptional(
"RequiresExpressionIndentation",
1075 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1077 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1079 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1082 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1084 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1086 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1091 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1093 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1096 IO.mapOptional(
"SpacesBeforeTrailingComments",
1099 IO.mapOptional(
"SpacesInContainerLiterals",
1101 IO.mapOptional(
"SpacesInLineCommentPrefix",
1106 IO.mapOptional(
"Standard", Style.
Standard);
1107 IO.mapOptional(
"StatementAttributeLikeMacros",
1110 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1112 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1114 IO.mapOptional(
"TabWidth", Style.
TabWidth);
1115 IO.mapOptional(
"TypeNames", Style.
TypeNames);
1117 IO.mapOptional(
"UseTab", Style.
UseTab);
1118 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1120 IO.mapOptional(
"WhitespaceSensitiveMacros",
1129 FormatStyle::DRTBS_All) {
1132 FormatStyle::DRTBS_TopLevel) {
1139 if (BreakBeforeInheritanceComma &&
1147 if (BreakConstructorInitializersBeforeComma &&
1152 if (!IsGoogleOrChromium) {
1156 ? FormatStyle::PCIS_NextLine
1157 : FormatStyle::PCIS_CurrentLine;
1160 FormatStyle::PCIS_NextLine) {
1163 else if (!OnNextLine)
1167 if (Style.
LineEnding == FormatStyle::LE_DeriveLF) {
1168 if (!DeriveLineEnding)
1169 Style.
LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1171 Style.
LineEnding = FormatStyle::LE_DeriveCRLF;
1175 (SpacesInParentheses || SpaceInEmptyParentheses ||
1176 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1177 if (SpacesInParentheses) {
1182 SpacesInCStyleCastParentheses;
1184 SpaceInEmptyParentheses;
1189 SpacesInConditionalStatement;
1191 SpacesInCStyleCastParentheses;
1193 SpaceInEmptyParentheses;
1205 template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1206 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1211 if (Index >= Seq.size()) {
1212 assert(Index == Seq.size());
1214 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1217 Template = *((
const FormatStyle *)IO.getContext());
1218 Template.
Language = FormatStyle::LK_None;
1220 Seq.resize(Index + 1, Template);
1240 return llvm::make_error<llvm::StringError>(Message,
1241 llvm::inconvertibleErrorCode());
1245 return "clang-format.parse_error";
1253 return "Invalid argument";
1255 return "Unsuitable";
1257 return "trailing comma insertion cannot be used with bin packing";
1259 return "Invalid qualifier specified in QualifierOrder";
1261 return "Duplicate qualifier specified in QualifierOrder";
1263 return "Missing type in QualifierOrder";
1265 return "Missing QualifierOrder";
1267 llvm_unreachable(
"unexpected parse error");
1493 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1496 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1497 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1498 {
".*", 1, 0,
false}};
1639 {
"^<.*\\.h>", 1, 0,
false},
1640 {
"^<.*", 2, 0,
false},
1641 {
".*", 3, 0,
false}};
1681 "PARSE_PARTIAL_TEXT_PROTO",
1685 "ParseTextProtoOrDie",
1687 "ParsePartialTestProto",
1799 "com.google.android.apps.chrome",
1818 return ChromiumStyle;
1844 return MozillaStyle;
1938 if (Name.equals_insensitive(
"llvm"))
1940 else if (Name.equals_insensitive(
"chromium"))
1942 else if (Name.equals_insensitive(
"mozilla"))
1944 else if (Name.equals_insensitive(
"google"))
1946 else if (Name.equals_insensitive(
"webkit"))
1948 else if (Name.equals_insensitive(
"gnu"))
1950 else if (Name.equals_insensitive(
"microsoft"))
1952 else if (Name.equals_insensitive(
"clang-format"))
1954 else if (Name.equals_insensitive(
"none"))
1956 else if (Name.equals_insensitive(
"inheritparentconfig"))
1972 if (Qualifier ==
"type")
1976 if (token == tok::identifier)
1981 std::set<std::string> UniqueQualifiers(Style->
QualifierOrder.begin(),
1984 LLVM_DEBUG(llvm::dbgs()
1986 <<
" vs " << UniqueQualifiers.size() <<
"\n");
1999 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2000 void *DiagHandlerCtxt) {
2004 if (Config.getBuffer().trim().empty())
2006 Style->StyleSet.
Clear();
2007 std::vector<FormatStyle> Styles;
2008 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2014 Input.setContext(Style);
2015 Input.setAllowUnknownKeys(AllowUnknownOptions);
2018 return Input.error();
2020 for (
unsigned i = 0; i < Styles.size(); ++i) {
2025 for (
unsigned j = 0; j < i; ++j) {
2027 LLVM_DEBUG(llvm::dbgs()
2028 <<
"Duplicate languages in the config file on positions "
2029 << j <<
" and " << i <<
"\n");
2038 bool LanguageFound =
false;
2039 for (
const FormatStyle &Style : llvm::reverse(Styles)) {
2041 StyleSet.
Add(Style);
2043 LanguageFound =
true;
2045 if (!LanguageFound) {
2050 StyleSet.
Add(std::move(DefaultStyle));
2065 llvm::raw_string_ostream Stream(
Text);
2066 llvm::yaml::Output Output(Stream);
2073 Output << NonConstStyle;
2075 return Stream.str();
2078 std::optional<FormatStyle>
2081 return std::nullopt;
2083 if (It == Styles->end())
2084 return std::nullopt;
2086 Style.StyleSet = *
this;
2092 "Cannot add a style for LK_None to a StyleSet");
2094 !Style.StyleSet.Styles &&
2095 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2097 Styles = std::make_shared<MapType>();
2098 (*Styles)[Style.
Language] = std::move(Style);
2103 std::optional<FormatStyle>
2115 std::pair<tooling::Replacements, unsigned>
2116 analyze(TokenAnnotator &Annotator,
2118 FormatTokenLexer &Tokens)
override {
2119 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2121 removeParens(AnnotatedLines, Result);
2126 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2127 tooling::Replacements &Result) {
2128 const auto &SourceMgr =
Env.getSourceManager();
2129 for (
auto *Line : Lines) {
2130 removeParens(Line->Children, Result);
2131 if (!Line->Affected)
2133 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2134 Token = Token->Next) {
2135 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2137 auto *Next = Token->Next;
2138 assert(Next && Next->isNot(
tok::eof));
2139 SourceLocation Start;
2140 if (Next->NewlinesBefore == 0) {
2141 Start = Token->Tok.getLocation();
2142 Next->WhitespaceRange = Token->WhitespaceRange;
2144 Start = Token->WhitespaceRange.getBegin();
2148 cantFail(Result.add(tooling::Replacement(SourceMgr, Range,
" ")));
2154 class BracesInserter :
public TokenAnalyzer {
2157 : TokenAnalyzer(
Env, Style) {}
2159 std::pair<tooling::Replacements, unsigned>
2160 analyze(TokenAnnotator &Annotator,
2161 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2162 FormatTokenLexer &Tokens)
override {
2163 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2164 tooling::Replacements Result;
2165 insertBraces(AnnotatedLines, Result);
2170 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2171 tooling::Replacements &Result) {
2172 const auto &SourceMgr =
Env.getSourceManager();
2173 int OpeningBraceSurplus = 0;
2174 for (AnnotatedLine *Line : Lines) {
2175 insertBraces(Line->Children, Result);
2176 if (!Line->Affected && OpeningBraceSurplus == 0)
2178 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2179 Token = Token->Next) {
2180 int BraceCount = Token->BraceCount;
2181 if (BraceCount == 0)
2184 if (BraceCount < 0) {
2185 assert(BraceCount == -1);
2186 if (!Line->Affected)
2188 Brace = Token->is(tok::comment) ?
"\n{" :
"{";
2189 ++OpeningBraceSurplus;
2191 if (OpeningBraceSurplus == 0)
2193 if (OpeningBraceSurplus < BraceCount)
2194 BraceCount = OpeningBraceSurplus;
2195 Brace =
'\n' + std::string(BraceCount,
'}');
2196 OpeningBraceSurplus -= BraceCount;
2198 Token->BraceCount = 0;
2199 const auto Start = Token->Tok.getEndLoc();
2200 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2203 assert(OpeningBraceSurplus == 0);
2207 class BracesRemover :
public TokenAnalyzer {
2210 : TokenAnalyzer(
Env, Style) {}
2212 std::pair<tooling::Replacements, unsigned>
2213 analyze(TokenAnnotator &Annotator,
2214 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2215 FormatTokenLexer &Tokens)
override {
2216 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2217 tooling::Replacements Result;
2218 removeBraces(AnnotatedLines, Result);
2223 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2224 tooling::Replacements &Result) {
2225 const auto &SourceMgr =
Env.getSourceManager();
2226 const auto End = Lines.end();
2227 for (
auto I = Lines.begin(); I !=
End; ++I) {
2228 const auto Line = *I;
2229 removeBraces(Line->Children, Result);
2230 if (!Line->Affected)
2232 const auto NextLine = I + 1 ==
End ? nullptr : I[1];
2233 for (
auto Token = Line->First; Token && !Token->Finalized;
2234 Token = Token->Next) {
2235 if (!Token->Optional)
2237 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2239 auto Next = Token->Next;
2240 assert(Next || Token == Line->Last);
2241 if (!Next && NextLine)
2242 Next = NextLine->First;
2243 SourceLocation Start;
2244 if (Next && Next->NewlinesBefore == 0 && Next->isNot(
tok::eof)) {
2245 Start = Token->Tok.getLocation();
2246 Next->WhitespaceRange = Token->WhitespaceRange;
2248 Start = Token->WhitespaceRange.getBegin();
2252 cantFail(Result.add(tooling::Replacement(SourceMgr, Range,
"")));
2258 class SemiRemover :
public TokenAnalyzer {
2261 : TokenAnalyzer(
Env, Style) {}
2263 std::pair<tooling::Replacements, unsigned>
2264 analyze(TokenAnnotator &Annotator,
2265 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2266 FormatTokenLexer &Tokens)
override {
2267 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2268 tooling::Replacements Result;
2269 removeSemi(Annotator, AnnotatedLines, Result);
2274 void removeSemi(TokenAnnotator &Annotator,
2275 SmallVectorImpl<AnnotatedLine *> &Lines,
2276 tooling::Replacements &Result) {
2277 auto PrecededByFunctionRBrace = [](
const FormatToken &Tok) {
2278 const auto *Prev = Tok.Previous;
2279 if (!Prev || Prev->isNot(tok::r_brace))
2281 const auto *LBrace = Prev->MatchingParen;
2282 return LBrace && LBrace->is(TT_FunctionLBrace);
2284 const auto &SourceMgr =
Env.getSourceManager();
2285 const auto End = Lines.end();
2286 for (
auto I = Lines.begin(); I !=
End; ++I) {
2287 const auto Line = *I;
2288 removeSemi(Annotator, Line->Children, Result);
2289 if (!Line->Affected)
2291 Annotator.calculateFormattingInformation(*Line);
2292 const auto NextLine = I + 1 ==
End ? nullptr : I[1];
2293 for (
auto Token = Line->First; Token && !Token->Finalized;
2294 Token = Token->Next) {
2295 if (Token->isNot(tok::semi) ||
2296 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2299 auto Next = Token->Next;
2300 assert(Next || Token == Line->Last);
2301 if (!Next && NextLine)
2302 Next = NextLine->First;
2303 SourceLocation Start;
2304 if (Next && Next->NewlinesBefore == 0 && Next->isNot(
tok::eof)) {
2305 Start = Token->Tok.getLocation();
2306 Next->WhitespaceRange = Token->WhitespaceRange;
2308 Start = Token->WhitespaceRange.getBegin();
2312 cantFail(Result.add(tooling::Replacement(SourceMgr, Range,
"")));
2318 class JavaScriptRequoter :
public TokenAnalyzer {
2320 JavaScriptRequoter(
const Environment &
Env,
const FormatStyle &Style)
2321 : TokenAnalyzer(
Env, Style) {}
2323 std::pair<tooling::Replacements, unsigned>
2324 analyze(TokenAnnotator &Annotator,
2325 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2326 FormatTokenLexer &Tokens)
override {
2327 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2328 tooling::Replacements Result;
2329 requoteJSStringLiteral(AnnotatedLines, Result);
2336 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2337 tooling::Replacements &Result) {
2338 for (AnnotatedLine *Line : Lines) {
2339 requoteJSStringLiteral(Line->Children, Result);
2340 if (!Line->Affected)
2342 for (FormatToken *FormatTok = Line->First; FormatTok;
2343 FormatTok = FormatTok->Next) {
2344 StringRef Input = FormatTok->TokenText;
2345 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2349 !Input.starts_with(
"\"")) ||
2351 !Input.starts_with(
"\'"))) {
2357 SourceLocation Start = FormatTok->Tok.getLocation();
2358 auto Replace = [&](SourceLocation Start,
unsigned Length,
2359 StringRef ReplacementText) {
2360 auto Err = Result.add(tooling::Replacement(
2361 Env.getSourceManager(), Start, Length, ReplacementText));
2365 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2369 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2370 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2371 IsSingle ?
"'" :
"\"");
2374 bool Escaped =
false;
2375 for (
size_t i = 1; i < Input.size() - 1; i++) {
2378 if (!Escaped && i + 1 < Input.size() &&
2379 ((IsSingle && Input[i + 1] ==
'"') ||
2380 (!IsSingle && Input[i + 1] ==
'\''))) {
2383 Replace(Start.getLocWithOffset(i), 1,
"");
2390 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2392 Replace(Start.getLocWithOffset(i), 0,
"\\");
2406 class Formatter :
public TokenAnalyzer {
2409 FormattingAttemptStatus *Status)
2410 : TokenAnalyzer(
Env, Style), Status(Status) {}
2412 std::pair<tooling::Replacements, unsigned>
2413 analyze(TokenAnnotator &Annotator,
2414 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2415 FormatTokenLexer &Tokens)
override {
2416 tooling::Replacements Result;
2417 deriveLocalStyle(AnnotatedLines);
2418 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2419 for (AnnotatedLine *Line : AnnotatedLines)
2420 Annotator.calculateFormattingInformation(*Line);
2421 Annotator.setCommentLineLevels(AnnotatedLines);
2423 WhitespaceManager Whitespaces(
2424 Env.getSourceManager(), Style,
2427 Env.getSourceManager().getBufferData(
Env.getFileID()),
2430 ContinuationIndenter
Indenter(Style, Tokens.getKeywords(),
2432 BinPackInconclusiveFunctions);
2434 UnwrappedLineFormatter(&
Indenter, &Whitespaces, Style,
2435 Tokens.getKeywords(),
Env.getSourceManager(),
2437 .format(AnnotatedLines,
false,
2440 Env.getFirstStartColumn(),
2441 Env.getNextStartColumn(),
2442 Env.getLastStartColumn());
2443 for (
const auto &R : Whitespaces.generateReplacements())
2445 return std::make_pair(Result, 0);
2446 return std::make_pair(Result, Penalty);
2451 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2452 for (
const AnnotatedLine *Line : Lines) {
2453 if (hasCpp03IncompatibleFormat(Line->Children))
2455 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2456 if (!Tok->hasWhitespaceBefore()) {
2457 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2459 if (Tok->is(TT_TemplateCloser) &&
2460 Tok->Previous->is(TT_TemplateCloser)) {
2469 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2470 int AlignmentDiff = 0;
2471 for (
const AnnotatedLine *Line : Lines) {
2472 AlignmentDiff += countVariableAlignments(Line->Children);
2473 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2474 if (Tok->isNot(TT_PointerOrReference))
2477 if (
const auto *Prev = Tok->getPreviousNonComment()) {
2478 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2479 if (
const auto *Func =
2480 Prev->MatchingParen->getPreviousNonComment()) {
2481 if (
Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2482 TT_OverloadedOperator)) {
2488 bool SpaceBefore = Tok->hasWhitespaceBefore();
2489 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2490 if (SpaceBefore && !SpaceAfter)
2492 if (!SpaceBefore && SpaceAfter)
2496 return AlignmentDiff;
2500 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2501 bool HasBinPackedFunction =
false;
2502 bool HasOnePerLineFunction =
false;
2503 for (AnnotatedLine *Line : AnnotatedLines) {
2504 if (!Line->First->Next)
2506 FormatToken *Tok = Line->First->Next;
2509 HasBinPackedFunction =
true;
2511 HasOnePerLineFunction =
true;
2517 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2518 if (NetRightCount > 0)
2520 else if (NetRightCount < 0)
2525 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2529 BinPackInconclusiveFunctions =
2530 HasBinPackedFunction || !HasOnePerLineFunction;
2533 bool BinPackInconclusiveFunctions;
2534 FormattingAttemptStatus *Status;
2548 class TrailingCommaInserter :
public TokenAnalyzer {
2550 TrailingCommaInserter(
const Environment &
Env,
const FormatStyle &Style)
2551 : TokenAnalyzer(
Env, Style) {}
2553 std::pair<tooling::Replacements, unsigned>
2554 analyze(TokenAnnotator &Annotator,
2555 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2556 FormatTokenLexer &Tokens)
override {
2557 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2558 tooling::Replacements Result;
2559 insertTrailingCommas(AnnotatedLines, Result);
2566 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2567 tooling::Replacements &Result) {
2568 for (AnnotatedLine *Line : Lines) {
2569 insertTrailingCommas(Line->Children, Result);
2570 if (!Line->Affected)
2572 for (FormatToken *FormatTok = Line->First; FormatTok;
2573 FormatTok = FormatTok->Next) {
2574 if (FormatTok->NewlinesBefore == 0)
2576 FormatToken *Matching = FormatTok->MatchingParen;
2577 if (!Matching || !FormatTok->getPreviousNonComment())
2579 if (!(FormatTok->is(tok::r_square) &&
2580 Matching->is(TT_ArrayInitializerLSquare)) &&
2581 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2584 FormatToken *Prev = FormatTok->getPreviousNonComment();
2585 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2589 SourceLocation Start =
2590 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2594 unsigned ColumnNumber =
2595 Env.getSourceManager().getSpellingColumnNumber(Start);
2600 cantFail(Result.add(
2601 tooling::Replacement(
Env.getSourceManager(), Start, 0,
",")));
2609 class Cleaner :
public TokenAnalyzer {
2612 : TokenAnalyzer(
Env, Style),
2613 DeletedTokens(FormatTokenLess(
Env.getSourceManager())) {}
2616 std::pair<tooling::Replacements, unsigned>
2617 analyze(TokenAnnotator &Annotator,
2618 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2619 FormatTokenLexer &Tokens)
override {
2627 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2629 checkEmptyNamespace(AnnotatedLines);
2631 for (
auto *Line : AnnotatedLines)
2634 return {generateFixes(), 0};
2638 void cleanupLine(AnnotatedLine *Line) {
2639 for (
auto *Child : Line->Children)
2642 if (Line->Affected) {
2643 cleanupRight(Line->First, tok::comma, tok::comma);
2644 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2645 cleanupRight(Line->First, tok::l_paren, tok::comma);
2646 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2647 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2648 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2649 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2653 bool containsOnlyComments(
const AnnotatedLine &Line) {
2654 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2655 if (Tok->isNot(tok::comment))
2661 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2662 std::set<unsigned> DeletedLines;
2663 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2664 auto &Line = *AnnotatedLines[i];
2665 if (Line.startsWithNamespace())
2666 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2669 for (
auto Line : DeletedLines) {
2670 FormatToken *Tok = AnnotatedLines[Line]->First;
2682 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2683 unsigned CurrentLine,
unsigned &
NewLine,
2684 std::set<unsigned> &DeletedLines) {
2685 unsigned InitLine = CurrentLine,
End = AnnotatedLines.size();
2690 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2694 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2697 while (++CurrentLine <
End) {
2698 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2701 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2702 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine,
NewLine,
2710 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2720 if (CurrentLine >=
End)
2725 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2726 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2730 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
2731 DeletedLines.insert(i);
2740 template <
typename LeftKind,
typename RightKind>
2741 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2743 auto NextNotDeleted = [
this](
const FormatToken &Tok) -> FormatToken * {
2744 for (
auto *Res = Tok.Next; Res; Res = Res->Next) {
2745 if (Res->isNot(tok::comment) &&
2746 DeletedTokens.find(Res) == DeletedTokens.end()) {
2752 for (
auto *Left = Start; Left;) {
2753 auto *Right = NextNotDeleted(*Left);
2756 if (Left->is(LK) && Right->is(RK)) {
2757 deleteToken(DeleteLeft ? Left : Right);
2758 for (
auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2769 template <
typename LeftKind,
typename RightKind>
2770 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2771 cleanupPair(Start, LK, RK,
true);
2774 template <
typename LeftKind,
typename RightKind>
2775 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2776 cleanupPair(Start, LK, RK,
false);
2780 inline void deleteToken(FormatToken *Tok) {
2782 DeletedTokens.insert(Tok);
2785 tooling::Replacements generateFixes() {
2786 tooling::Replacements Fixes;
2787 SmallVector<FormatToken *> Tokens;
2788 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2789 std::back_inserter(Tokens));
2795 while (Idx < Tokens.size()) {
2796 unsigned St = Idx,
End = Idx;
2797 while ((
End + 1) < Tokens.size() && Tokens[
End]->Next == Tokens[
End + 1])
2800 Tokens[
End]->Tok.getEndLoc());
2802 Fixes.add(tooling::Replacement(
Env.getSourceManager(), SR,
""));
2806 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2807 assert(
false &&
"Fixes must not conflict!");
2818 struct FormatTokenLess {
2819 FormatTokenLess(
const SourceManager &
SM) :
SM(
SM) {}
2821 bool operator()(
const FormatToken *LHS,
const FormatToken *RHS)
const {
2822 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2823 RHS->Tok.getLocation());
2829 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2832 class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
2834 ObjCHeaderStyleGuesser(
const Environment &
Env,
const FormatStyle &Style)
2835 : TokenAnalyzer(
Env, Style), IsObjC(
false) {}
2837 std::pair<tooling::Replacements, unsigned>
2838 analyze(TokenAnnotator &Annotator,
2839 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2840 FormatTokenLexer &Tokens)
override {
2842 IsObjC = guessIsObjC(
Env.getSourceManager(), AnnotatedLines,
2843 Tokens.getKeywords());
2844 tooling::Replacements Result;
2848 bool isObjC() {
return IsObjC; }
2852 guessIsObjC(
const SourceManager &SourceManager,
2853 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2854 const AdditionalKeywords &Keywords) {
2856 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2871 "FOUNDATION_EXPORT",
2872 "FOUNDATION_EXTERN",
2873 "NSAffineTransform",
2875 "NSAttributedString",
2894 "NSInvocationOperation",
2898 "NSMutableAttributedString",
2899 "NSMutableCharacterSet",
2901 "NSMutableDictionary",
2902 "NSMutableIndexSet",
2903 "NSMutableOrderedSet",
2907 "NSNumberFormatter",
2911 "NSOperationQueuePriority",
2915 "NSQualityOfService",
2918 "NSRegularExpression",
2929 "NS_ASSUME_NONNULL_BEGIN",
2934 for (
auto *Line : AnnotatedLines) {
2935 if (Line->First && (Line->First->TokenText.starts_with(
"#") ||
2936 Line->First->TokenText ==
"__pragma" ||
2937 Line->First->TokenText ==
"_Pragma")) {
2940 for (
const FormatToken *FormatTok = Line->First; FormatTok;
2941 FormatTok = FormatTok->Next) {
2942 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
2943 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
2944 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
2946 (FormatTok->Tok.isAnyIdentifier() &&
2947 std::binary_search(std::begin(FoundationIdentifiers),
2948 std::end(FoundationIdentifiers),
2949 FormatTok->TokenText)) ||
2950 FormatTok->is(TT_ObjCStringLiteral) ||
2951 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
2952 Keywords.kw_NS_ERROR_ENUM,
2953 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
2954 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
2955 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
2957 LLVM_DEBUG(llvm::dbgs()
2958 <<
"Detected ObjC at location "
2959 << FormatTok->Tok.getLocation().printToString(
2961 <<
" token: " << FormatTok->TokenText <<
" token type: "
2966 if (guessIsObjC(SourceManager, Line->Children, Keywords))
2983 struct JavaImportDirective {
2996 for (
const auto &
Range : Ranges) {
2998 Range.getOffset() +
Range.getLength() > Start) {
3012 static std::pair<unsigned, unsigned>
3016 unsigned OffsetToEOL = 0;
3017 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3018 unsigned Start = Includes[Indices[i]].Offset;
3019 unsigned End = Start + Includes[Indices[i]].Text.size();
3022 CursorIndex = Indices[i];
3026 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3030 return std::make_pair(CursorIndex, OffsetToEOL);
3035 std::string NewCode;
3036 size_t Pos = 0, LastPos = 0;
3039 Pos = Code.find(
"\r\n", LastPos);
3040 if (Pos == LastPos) {
3044 if (Pos == std::string::npos) {
3045 NewCode += Code.substr(LastPos);
3048 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3050 }
while (Pos != std::string::npos);
3068 const unsigned IncludesBeginOffset = Includes.front().Offset;
3069 const unsigned IncludesEndOffset =
3070 Includes.back().Offset + Includes.back().Text.size();
3071 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3072 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3075 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3078 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3079 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3080 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3081 return std::tie(Includes[LHSI].
Priority, LHSFilenameLower,
3083 std::tie(Includes[RHSI].
Priority, RHSFilenameLower,
3087 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3095 unsigned CursorIndex;
3097 unsigned CursorToEOLOffset;
3099 std::tie(CursorIndex, CursorToEOLOffset) =
3104 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3105 [&](
unsigned LHSI,
unsigned RHSI) {
3106 return Includes[LHSI].Text.trim() ==
3107 Includes[RHSI].Text.trim();
3111 int CurrentCategory = Includes.front().Category;
3119 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3126 for (
unsigned Index : Indices) {
3127 if (!result.empty()) {
3131 CurrentCategory != Includes[Index].Category) {
3135 result += Includes[Index].Text;
3136 if (
Cursor && CursorIndex == Index)
3137 *
Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3138 CurrentCategory = Includes[Index].Category;
3142 *
Cursor += result.size() - IncludesBlockSize;
3147 IncludesBeginOffset, IncludesBlockSize)))) {
3154 FileName, Includes.front().Offset, IncludesBlockSize, result));
3158 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3168 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3169 .StartsWith(
"\xEF\xBB\xBF", 3)
3171 unsigned SearchFrom = 0;
3183 bool FirstIncludeBlock =
true;
3184 bool MainIncludeFound =
false;
3185 bool FormattingOff =
false;
3188 llvm::Regex RawStringRegex(
3189 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3191 std::string RawStringTermination =
")\"";
3194 auto Pos = Code.find(
'\n', SearchFrom);
3196 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3198 StringRef Trimmed = Line.trim();
3203 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3204 std::string CharSequence = RawStringMatches[1].str();
3205 RawStringTermination =
")" + CharSequence +
"\"";
3206 FormattingOff =
true;
3209 if (Trimmed.contains(RawStringTermination))
3210 FormattingOff =
false;
3213 FormattingOff =
true;
3215 FormattingOff =
false;
3217 const bool EmptyLineSkipped =
3223 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3224 if (!FormattingOff && !MergeWithNextLine) {
3226 StringRef IncludeName = Matches[2];
3227 if (Line.contains(
"/*") && !Line.contains(
"*/")) {
3232 Pos = Code.find(
"*/", SearchFrom);
3234 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3238 !MainIncludeFound && FirstIncludeBlock);
3240 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3242 MainIncludeFound =
true;
3243 IncludesInBlock.push_back(
3245 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3248 IncludesInBlock.clear();
3249 if (Trimmed.starts_with(
"#pragma hdrstop"))
3250 FirstIncludeBlock =
true;
3252 FirstIncludeBlock =
false;
3255 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3258 if (!MergeWithNextLine)
3260 SearchFrom = Pos + 1;
3262 if (!IncludesInBlock.empty()) {
3272 StringRef ImportIdentifier) {
3273 unsigned LongestMatchIndex =
UINT_MAX;
3274 unsigned LongestMatchLength = 0;
3277 if (ImportIdentifier.starts_with(GroupPrefix) &&
3278 GroupPrefix.length() > LongestMatchLength) {
3279 LongestMatchIndex = I;
3280 LongestMatchLength = GroupPrefix.length();
3283 return LongestMatchIndex;
3295 unsigned ImportsBeginOffset = Imports.front().Offset;
3296 unsigned ImportsEndOffset =
3297 Imports.back().Offset + Imports.back().Text.size();
3298 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3299 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3303 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3306 for (
const JavaImportDirective &Import : Imports)
3309 bool StaticImportAfterNormalImport =
3311 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3313 return std::make_tuple(!Imports[LHSI].
IsStatic ^
3314 StaticImportAfterNormalImport,
3316 std::make_tuple(!Imports[RHSI].
IsStatic ^
3317 StaticImportAfterNormalImport,
3322 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3323 [&](
unsigned LHSI,
unsigned RHSI) {
3324 return Imports[LHSI].Text == Imports[RHSI].Text;
3328 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3332 for (
unsigned Index : Indices) {
3333 if (!result.empty()) {
3335 if (CurrentIsStatic != Imports[Index].
IsStatic ||
3341 result += CommentLine;
3344 result += Imports[Index].Text;
3345 CurrentIsStatic = Imports[Index].IsStatic;
3352 Imports.front().Offset, ImportsBlockSize)))) {
3357 ImportsBlockSize, result));
3361 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3368 const char JavaImportRegexPattern[] =
3369 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3378 unsigned SearchFrom = 0;
3379 llvm::Regex ImportRegex(JavaImportRegexPattern);
3384 bool FormattingOff =
false;
3387 auto Pos = Code.find(
'\n', SearchFrom);
3389 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3391 StringRef Trimmed = Line.trim();
3393 FormattingOff =
true;
3395 FormattingOff =
false;
3397 if (ImportRegex.match(Line, &Matches)) {
3398 if (FormattingOff) {
3403 StringRef
Static = Matches[1];
3406 if (
Static.contains(
"static"))
3408 ImportsInBlock.push_back(
3411 }
else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3416 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3418 SearchFrom = Pos + 1;
3420 if (!ImportsInBlock.empty())
3429 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3432 bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
3436 StringRef FileName,
unsigned *
Cursor) {
3442 if (Style.
Language == FormatStyle::LanguageKind::LK_JavaScript &&
3446 if (Style.
Language == FormatStyle::LanguageKind::LK_JavaScript)
3448 if (Style.
Language == FormatStyle::LanguageKind::LK_Java)
3454 template <
typename T>
3459 if (Replaces.
empty())
3464 return NewCode.takeError();
3469 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
3471 return Replaces.
merge(FormatReplaces);
3480 std::vector<tooling::Range> Ranges,
3484 auto SortedReplaces =
3486 if (!SortedReplaces)
3487 return SortedReplaces.takeError();
3491 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
3492 std::vector<tooling::Range> Ranges,
3507 inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
3508 return Replace.getOffset() ==
UINT_MAX && Replace.getLength() == 1;
3512 tooling::Replacements
3513 fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
3518 tooling::Replacements HeaderInsertions;
3519 std::set<StringRef> HeadersToDelete;
3520 tooling::Replacements Result;
3521 for (
const auto &R : Replaces) {
3522 if (isHeaderInsertion(R)) {
3525 consumeError(HeaderInsertions.add(R));
3526 }
else if (isHeaderDeletion(R)) {
3527 HeadersToDelete.insert(R.getReplacementText());
3528 }
else if (R.getOffset() ==
UINT_MAX) {
3529 llvm::errs() <<
"Insertions other than header #include insertion are "
3531 << R.getReplacementText() <<
"\n";
3533 consumeError(Result.add(R));
3536 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3539 StringRef
FileName = Replaces.begin()->getFilePath();
3540 tooling::HeaderIncludes Includes(FileName, Code, Style.
IncludeStyle);
3542 for (
const auto &Header : HeadersToDelete) {
3543 tooling::Replacements Replaces =
3544 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
3545 for (
const auto &R : Replaces) {
3546 auto Err = Result.add(R);
3549 llvm::errs() <<
"Failed to add header deletion replacement for "
3550 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
3555 SmallVector<StringRef, 4> Matches;
3556 for (
const auto &R : HeaderInsertions) {
3560 assert(Matched &&
"Header insertion replacement must have replacement text "
3563 auto IncludeName = Matches[2];
3565 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
3568 auto Err = Result.add(*Replace);
3570 consumeError(std::move(Err));
3571 unsigned NewOffset =
3572 Result.getShiftedCodePosition(Replace->getOffset());
3573 auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3574 Replace->getReplacementText());
3575 Result = Result.merge(tooling::Replacements(Shifted));
3584 Expected<tooling::Replacements>
3589 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
3596 fixCppIncludeInsertions(Code, Replaces, Style);
3600 namespace internal {
3601 std::pair<tooling::Replacements, unsigned>
3604 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
3632 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
3634 NextStartColumn, LastStartColumn);
3639 Formatter(*
Env, Style, Status).process().first;
3641 Replaces = Replaces.
merge(
3645 return {Replaces, 0};
3650 NextStartColumn, LastStartColumn);
3654 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3664 if (Style.
isCpp()) {
3671 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3672 return ParensRemover(
Env, S).process(
true);
3678 S.InsertBraces =
true;
3679 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3680 return BracesInserter(
Env, S).process(
true);
3686 S.RemoveBracesLLVM =
true;
3687 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3688 return BracesRemover(
Env, S).process(
true);
3694 S.RemoveSemicolon =
true;
3695 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3696 return SemiRemover(
Env, S).process();
3729 return JavaScriptRequoter(
Env, Expanded).process(
true);
3734 return Formatter(
Env, Expanded, Status).process();
3740 return TrailingCommaInserter(
Env, Expanded).process();
3744 std::optional<std::string> CurrentCode;
3746 unsigned Penalty = 0;
3747 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
3748 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3750 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3752 Fixes = Fixes.
merge(PassFixes.first);
3753 Penalty += PassFixes.second;
3755 CurrentCode = std::move(*NewCode);
3759 FirstStartColumn, NextStartColumn, LastStartColumn);
3772 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3773 if (OriginalCode != Fix.getReplacementText()) {
3774 auto Err = NonNoOpFixes.
add(Fix);
3776 llvm::errs() <<
"Error adding replacements : "
3777 <<
toString(std::move(Err)) <<
"\n";
3781 Fixes = std::move(NonNoOpFixes);
3784 return {Fixes, Penalty};
3801 StringRef FileName) {
3808 return Cleaner(*
Env, Style).process().first;
3813 StringRef FileName,
bool *IncompleteFormat) {
3816 if (!Status.FormatComplete)
3817 *IncompleteFormat =
true;
3824 StringRef FileName) {
3834 StringRef FileName) {
3849 LangOpts.CPlusPlus = 1;
3860 LangOpts.LineComment = 1;
3861 LangOpts.CXXOperatorNames = Style.
isCpp();
3864 LangOpts.MicrosoftExt = 1;
3865 LangOpts.DeclSpecKeyword = 1;
3871 "Set coding style. <string> can be:\n"
3872 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3873 " Mozilla, WebKit.\n"
3874 "2. 'file' to load style configuration from a\n"
3875 " .clang-format file in one of the parent directories\n"
3876 " of the source file (for stdin, see --assume-filename).\n"
3877 " If no .clang-format file is found, falls back to\n"
3878 " --fallback-style.\n"
3879 " --style=file is the default.\n"
3880 "3. 'file:<format_file_path>' to explicitly specify\n"
3881 " the configuration file.\n"
3882 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3883 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3888 if (
FileName.ends_with_insensitive(
".js") ||
3889 FileName.ends_with_insensitive(
".mjs") ||
3890 FileName.ends_with_insensitive(
".ts")) {
3895 if (
FileName.ends_with_insensitive(
".proto") ||
3896 FileName.ends_with_insensitive(
".protodevel")) {
3902 if (
FileName.ends_with_insensitive(
".txtpb") ||
3903 FileName.ends_with_insensitive(
".textpb") ||
3904 FileName.ends_with_insensitive(
".pb.txt") ||
3905 FileName.ends_with_insensitive(
".textproto") ||
3906 FileName.ends_with_insensitive(
".asciipb")) {
3909 if (
FileName.ends_with_insensitive(
".td"))
3911 if (
FileName.ends_with_insensitive(
".cs"))
3913 if (
FileName.ends_with_insensitive(
".json"))
3915 if (
FileName.ends_with_insensitive(
".sv") ||
3916 FileName.ends_with_insensitive(
".svh") ||
3917 FileName.ends_with_insensitive(
".v") ||
3918 FileName.ends_with_insensitive(
".vh")) {
3927 auto Extension = llvm::sys::path::extension(
FileName);
3930 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
3935 if (Guesser.isObjC())
3939 return GuessedLanguage;
3947 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
3950 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
3951 FS->getBufferForFile(ConfigFile.str());
3952 if (
auto EC =
Text.getError())
3960 StringRef FallbackStyleName, StringRef Code,
3961 llvm::vfs::FileSystem *FS,
3962 bool AllowUnknownOptions) {
3970 if (StyleName.starts_with(
"{")) {
3972 StringRef Source =
"<command-line>";
3973 if (std::error_code ec =
3975 AllowUnknownOptions)) {
3982 ChildFormatTextToApply.emplace_back(
3983 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
3987 FS = llvm::vfs::getRealFileSystem().get();
3992 StyleName.starts_with_insensitive(
"file:")) {
3993 auto ConfigFile = StyleName.substr(5);
3994 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
3996 if (
auto EC =
Text.getError()) {
4001 LLVM_DEBUG(llvm::dbgs()
4002 <<
"Using configuration file " << ConfigFile <<
"\n");
4010 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4024 if (std::error_code EC = FS->makeAbsolute(Path))
4030 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4032 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4033 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4035 dropDiagnosticHandler);
4038 static_cast<void>(EC);
4044 FilesToLookFor.push_back(
".clang-format");
4045 FilesToLookFor.push_back(
"_clang-format");
4048 for (StringRef Directory = Path; !Directory.empty();
4049 Directory = llvm::sys::path::parent_path(Directory)) {
4050 auto Status = FS->status(Directory);
4052 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4056 for (
const auto &F : FilesToLookFor) {
4059 llvm::sys::path::append(ConfigFile, F);
4060 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4062 Status = FS->status(ConfigFile);
4064 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4068 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4070 if (
auto EC =
Text.getError()) {
4075 if (!UnsuitableConfigFiles.empty())
4076 UnsuitableConfigFiles.append(
", ");
4077 UnsuitableConfigFiles.append(ConfigFile);
4081 LLVM_DEBUG(llvm::dbgs()
4082 <<
"Using configuration file " << ConfigFile <<
"\n");
4085 if (!ChildFormatTextToApply.empty()) {
4086 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4087 applyChildFormatTexts(&Style);
4092 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4097 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4107 if (!UnsuitableConfigFiles.empty()) {
4110 UnsuitableConfigFiles);
4113 if (!ChildFormatTextToApply.empty()) {
4114 LLVM_DEBUG(llvm::dbgs()
4115 <<
"Applying child configurations on fallback style\n");
4116 applyChildFormatTexts(&FallbackStyle);
4119 return FallbackStyle;
4123 if (Comment == (On ?
"/* clang-format on */" :
"/* clang-format off */"))
4126 static const char ClangFormatOn[] =
"// clang-format on";
4127 static const char ClangFormatOff[] =
"// clang-format off";
4128 const unsigned Size = (On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4130 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4131 (Comment.size() == Size || Comment[Size] ==
':');
This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or removes empty lines sepa...
This file declares IntegerLiteralSeparatorFixer that fixes C++ integer literal separators.
This file declares ObjCPropertyAttributeOrderFixer, a TokenAnalyzer that adjusts the order of attribu...
This file declares QualifierAlignmentFixer, a TokenAnalyzer that enforces either east or west const d...
This file implements a sorter for JavaScript ES6 imports.
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
__DEVICE__ int min(int __a, int __b)
static CharSourceRange getCharRange(SourceRange R)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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).
std::string toString(const til::SExpr *E)
The JSON file list parser is used to communicate input to InstallAPI.
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value)
static void enumeration(IO &IO, FormatStyle::LambdaBodyIndentationKind &Value)