25#include "llvm/ADT/Sequence.h"
27#define DEBUG_TYPE "format-formatter"
31LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat)
36struct 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);
45template <>
struct MappingTraits<
FormatStyle::AlignConsecutiveStyle> {
47 IO.enumCase(
Value,
"None", FormatStyle::AlignConsecutiveStyle({}));
48 IO.enumCase(
Value,
"Consecutive",
49 FormatStyle::AlignConsecutiveStyle(
54 IO.enumCase(
Value,
"AcrossEmptyLines",
55 FormatStyle::AlignConsecutiveStyle(
60 IO.enumCase(
Value,
"AcrossComments",
61 FormatStyle::AlignConsecutiveStyle(
66 IO.enumCase(
Value,
"AcrossEmptyLinesAndComments",
67 FormatStyle::AlignConsecutiveStyle(
74 IO.enumCase(
Value,
"true",
75 FormatStyle::AlignConsecutiveStyle(
80 IO.enumCase(
Value,
"false", FormatStyle::AlignConsecutiveStyle({}));
83 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &
Value) {
84 IO.mapOptional(
"Enabled",
Value.Enabled);
85 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
86 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
87 IO.mapOptional(
"AlignCompound",
Value.AlignCompound);
88 IO.mapOptional(
"AlignFunctionDeclarations",
89 Value.AlignFunctionDeclarations);
90 IO.mapOptional(
"AlignFunctionPointers",
Value.AlignFunctionPointers);
91 IO.mapOptional(
"PadOperators",
Value.PadOperators);
96struct MappingTraits<
FormatStyle::ShortCaseStatementsAlignmentStyle> {
98 FormatStyle::ShortCaseStatementsAlignmentStyle &
Value) {
99 IO.mapOptional(
"Enabled",
Value.Enabled);
100 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
101 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
102 IO.mapOptional(
"AlignCaseArrows",
Value.AlignCaseArrows);
103 IO.mapOptional(
"AlignCaseColons",
Value.AlignCaseColons);
108struct ScalarEnumerationTraits<
FormatStyle::AttributeBreakingStyle> {
110 IO.enumCase(
Value,
"Always", FormatStyle::ABS_Always);
111 IO.enumCase(
Value,
"Leave", FormatStyle::ABS_Leave);
112 IO.enumCase(
Value,
"Never", FormatStyle::ABS_Never);
117struct ScalarEnumerationTraits<
FormatStyle::ArrayInitializerAlignmentStyle> {
119 FormatStyle::ArrayInitializerAlignmentStyle &
Value) {
120 IO.enumCase(
Value,
"None", FormatStyle::AIAS_None);
121 IO.enumCase(
Value,
"Left", FormatStyle::AIAS_Left);
122 IO.enumCase(
Value,
"Right", FormatStyle::AIAS_Right);
126template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
128 IO.enumCase(
Value,
"All", FormatStyle::BOS_All);
129 IO.enumCase(
Value,
"true", FormatStyle::BOS_All);
130 IO.enumCase(
Value,
"None", FormatStyle::BOS_None);
131 IO.enumCase(
Value,
"false", FormatStyle::BOS_None);
132 IO.enumCase(
Value,
"NonAssignment", FormatStyle::BOS_NonAssignment);
137struct ScalarEnumerationTraits<
FormatStyle::BinPackParametersStyle> {
139 IO.enumCase(
Value,
"BinPack", FormatStyle::BPPS_BinPack);
140 IO.enumCase(
Value,
"OnePerLine", FormatStyle::BPPS_OnePerLine);
141 IO.enumCase(
Value,
"AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine);
144 IO.enumCase(
Value,
"true", FormatStyle::BPPS_BinPack);
145 IO.enumCase(
Value,
"false", FormatStyle::BPPS_OnePerLine);
149template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
151 IO.enumCase(
Value,
"Auto", FormatStyle::BPS_Auto);
152 IO.enumCase(
Value,
"Always", FormatStyle::BPS_Always);
153 IO.enumCase(
Value,
"Never", FormatStyle::BPS_Never);
158struct ScalarEnumerationTraits<
FormatStyle::BitFieldColonSpacingStyle> {
160 FormatStyle::BitFieldColonSpacingStyle &
Value) {
161 IO.enumCase(
Value,
"Both", FormatStyle::BFCS_Both);
162 IO.enumCase(
Value,
"None", FormatStyle::BFCS_None);
163 IO.enumCase(
Value,
"Before", FormatStyle::BFCS_Before);
164 IO.enumCase(
Value,
"After", FormatStyle::BFCS_After);
168template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
170 IO.enumCase(
Value,
"Attach", FormatStyle::BS_Attach);
171 IO.enumCase(
Value,
"Linux", FormatStyle::BS_Linux);
172 IO.enumCase(
Value,
"Mozilla", FormatStyle::BS_Mozilla);
173 IO.enumCase(
Value,
"Stroustrup", FormatStyle::BS_Stroustrup);
174 IO.enumCase(
Value,
"Allman", FormatStyle::BS_Allman);
175 IO.enumCase(
Value,
"Whitesmiths", FormatStyle::BS_Whitesmiths);
176 IO.enumCase(
Value,
"GNU", FormatStyle::BS_GNU);
177 IO.enumCase(
Value,
"WebKit", FormatStyle::BS_WebKit);
178 IO.enumCase(
Value,
"Custom", FormatStyle::BS_Custom);
182template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
183 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
184 IO.mapOptional(
"AfterCaseLabel", Wrapping.AfterCaseLabel);
185 IO.mapOptional(
"AfterClass", Wrapping.AfterClass);
186 IO.mapOptional(
"AfterControlStatement", Wrapping.AfterControlStatement);
187 IO.mapOptional(
"AfterEnum", Wrapping.AfterEnum);
188 IO.mapOptional(
"AfterExternBlock", Wrapping.AfterExternBlock);
189 IO.mapOptional(
"AfterFunction", Wrapping.AfterFunction);
190 IO.mapOptional(
"AfterNamespace", Wrapping.AfterNamespace);
191 IO.mapOptional(
"AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
192 IO.mapOptional(
"AfterStruct", Wrapping.AfterStruct);
193 IO.mapOptional(
"AfterUnion", Wrapping.AfterUnion);
194 IO.mapOptional(
"BeforeCatch", Wrapping.BeforeCatch);
195 IO.mapOptional(
"BeforeElse", Wrapping.BeforeElse);
196 IO.mapOptional(
"BeforeLambdaBody", Wrapping.BeforeLambdaBody);
197 IO.mapOptional(
"BeforeWhile", Wrapping.BeforeWhile);
198 IO.mapOptional(
"IndentBraces", Wrapping.IndentBraces);
199 IO.mapOptional(
"SplitEmptyFunction", Wrapping.SplitEmptyFunction);
200 IO.mapOptional(
"SplitEmptyRecord", Wrapping.SplitEmptyRecord);
201 IO.mapOptional(
"SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
205template <>
struct ScalarEnumerationTraits<
FormatStyle::BracketAlignmentStyle> {
207 IO.enumCase(
Value,
"Align", FormatStyle::BAS_Align);
208 IO.enumCase(
Value,
"DontAlign", FormatStyle::BAS_DontAlign);
209 IO.enumCase(
Value,
"AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
210 IO.enumCase(
Value,
"BlockIndent", FormatStyle::BAS_BlockIndent);
213 IO.enumCase(
Value,
"true", FormatStyle::BAS_Align);
214 IO.enumCase(
Value,
"false", FormatStyle::BAS_DontAlign);
219struct ScalarEnumerationTraits<
220 FormatStyle::BraceWrappingAfterControlStatementStyle> {
223 FormatStyle::BraceWrappingAfterControlStatementStyle &
Value) {
224 IO.enumCase(
Value,
"Never", FormatStyle::BWACS_Never);
225 IO.enumCase(
Value,
"MultiLine", FormatStyle::BWACS_MultiLine);
226 IO.enumCase(
Value,
"Always", FormatStyle::BWACS_Always);
229 IO.enumCase(
Value,
"false", FormatStyle::BWACS_Never);
230 IO.enumCase(
Value,
"true", FormatStyle::BWACS_Always);
235struct ScalarEnumerationTraits<
236 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
239 IO.enumCase(
Value,
"Never", FormatStyle::BBCDS_Never);
240 IO.enumCase(
Value,
"Allowed", FormatStyle::BBCDS_Allowed);
241 IO.enumCase(
Value,
"Always", FormatStyle::BBCDS_Always);
244 IO.enumCase(
Value,
"true", FormatStyle::BBCDS_Always);
245 IO.enumCase(
Value,
"false", FormatStyle::BBCDS_Allowed);
250struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeInlineASMColonStyle> {
252 FormatStyle::BreakBeforeInlineASMColonStyle &
Value) {
253 IO.enumCase(
Value,
"Never", FormatStyle::BBIAS_Never);
254 IO.enumCase(
Value,
"OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
255 IO.enumCase(
Value,
"Always", FormatStyle::BBIAS_Always);
260struct ScalarEnumerationTraits<
FormatStyle::BreakBinaryOperationsStyle> {
262 FormatStyle::BreakBinaryOperationsStyle &
Value) {
263 IO.enumCase(
Value,
"Never", FormatStyle::BBO_Never);
264 IO.enumCase(
Value,
"OnePerLine", FormatStyle::BBO_OnePerLine);
265 IO.enumCase(
Value,
"RespectPrecedence", FormatStyle::BBO_RespectPrecedence);
270struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
273 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BCIS_BeforeColon);
274 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BCIS_BeforeComma);
275 IO.enumCase(
Value,
"AfterColon", FormatStyle::BCIS_AfterColon);
280struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
282 FormatStyle::BreakInheritanceListStyle &
Value) {
283 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BILS_BeforeColon);
284 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BILS_BeforeComma);
285 IO.enumCase(
Value,
"AfterColon", FormatStyle::BILS_AfterColon);
286 IO.enumCase(
Value,
"AfterComma", FormatStyle::BILS_AfterComma);
291struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
293 FormatStyle::BreakTemplateDeclarationsStyle &
Value) {
294 IO.enumCase(
Value,
"Leave", FormatStyle::BTDS_Leave);
295 IO.enumCase(
Value,
"No", FormatStyle::BTDS_No);
296 IO.enumCase(
Value,
"MultiLine", FormatStyle::BTDS_MultiLine);
297 IO.enumCase(
Value,
"Yes", FormatStyle::BTDS_Yes);
300 IO.enumCase(
Value,
"false", FormatStyle::BTDS_MultiLine);
301 IO.enumCase(
Value,
"true", FormatStyle::BTDS_Yes);
305template <>
struct ScalarEnumerationTraits<
FormatStyle::DAGArgStyle> {
307 IO.enumCase(
Value,
"DontBreak", FormatStyle::DAS_DontBreak);
308 IO.enumCase(
Value,
"BreakElements", FormatStyle::DAS_BreakElements);
309 IO.enumCase(
Value,
"BreakAll", FormatStyle::DAS_BreakAll);
314struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
317 IO.enumCase(
Value,
"None", FormatStyle::DRTBS_None);
318 IO.enumCase(
Value,
"All", FormatStyle::DRTBS_All);
319 IO.enumCase(
Value,
"TopLevel", FormatStyle::DRTBS_TopLevel);
322 IO.enumCase(
Value,
"false", FormatStyle::DRTBS_None);
323 IO.enumCase(
Value,
"true", FormatStyle::DRTBS_All);
328struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
330 FormatStyle::EscapedNewlineAlignmentStyle &
Value) {
331 IO.enumCase(
Value,
"DontAlign", FormatStyle::ENAS_DontAlign);
332 IO.enumCase(
Value,
"Left", FormatStyle::ENAS_Left);
333 IO.enumCase(
Value,
"LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);
334 IO.enumCase(
Value,
"Right", FormatStyle::ENAS_Right);
337 IO.enumCase(
Value,
"true", FormatStyle::ENAS_Left);
338 IO.enumCase(
Value,
"false", FormatStyle::ENAS_Right);
343struct ScalarEnumerationTraits<
FormatStyle::EmptyLineAfterAccessModifierStyle> {
346 IO.enumCase(
Value,
"Never", FormatStyle::ELAAMS_Never);
347 IO.enumCase(
Value,
"Leave", FormatStyle::ELAAMS_Leave);
348 IO.enumCase(
Value,
"Always", FormatStyle::ELAAMS_Always);
353struct ScalarEnumerationTraits<
357 IO.enumCase(
Value,
"Never", FormatStyle::ELBAMS_Never);
358 IO.enumCase(
Value,
"Leave", FormatStyle::ELBAMS_Leave);
359 IO.enumCase(
Value,
"LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
360 IO.enumCase(
Value,
"Always", FormatStyle::ELBAMS_Always);
365struct ScalarEnumerationTraits<
FormatStyle::IndentExternBlockStyle> {
367 IO.enumCase(
Value,
"AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
368 IO.enumCase(
Value,
"Indent", FormatStyle::IEBS_Indent);
369 IO.enumCase(
Value,
"NoIndent", FormatStyle::IEBS_NoIndent);
370 IO.enumCase(
Value,
"true", FormatStyle::IEBS_Indent);
371 IO.enumCase(
Value,
"false", FormatStyle::IEBS_NoIndent);
375template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
376 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &
Base) {
377 IO.mapOptional(
"Binary",
Base.Binary);
378 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigits);
379 IO.mapOptional(
"Decimal",
Base.Decimal);
380 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigits);
381 IO.mapOptional(
"Hex",
Base.Hex);
382 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigits);
386template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
388 IO.enumCase(
Value,
"Leave", FormatStyle::JSQS_Leave);
389 IO.enumCase(
Value,
"Single", FormatStyle::JSQS_Single);
390 IO.enumCase(
Value,
"Double", FormatStyle::JSQS_Double);
394template <>
struct MappingTraits<
FormatStyle::KeepEmptyLinesStyle> {
396 IO.mapOptional(
"AtEndOfFile",
Value.AtEndOfFile);
397 IO.mapOptional(
"AtStartOfBlock",
Value.AtStartOfBlock);
398 IO.mapOptional(
"AtStartOfFile",
Value.AtStartOfFile);
402template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
404 IO.enumCase(
Value,
"Cpp", FormatStyle::LK_Cpp);
405 IO.enumCase(
Value,
"Java", FormatStyle::LK_Java);
406 IO.enumCase(
Value,
"JavaScript", FormatStyle::LK_JavaScript);
407 IO.enumCase(
Value,
"ObjC", FormatStyle::LK_ObjC);
408 IO.enumCase(
Value,
"Proto", FormatStyle::LK_Proto);
409 IO.enumCase(
Value,
"TableGen", FormatStyle::LK_TableGen);
410 IO.enumCase(
Value,
"TextProto", FormatStyle::LK_TextProto);
411 IO.enumCase(
Value,
"CSharp", FormatStyle::LK_CSharp);
412 IO.enumCase(
Value,
"Json", FormatStyle::LK_Json);
413 IO.enumCase(
Value,
"Verilog", FormatStyle::LK_Verilog);
417template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
419 IO.enumCase(
Value,
"c++03", FormatStyle::LS_Cpp03);
420 IO.enumCase(
Value,
"C++03", FormatStyle::LS_Cpp03);
421 IO.enumCase(
Value,
"Cpp03", FormatStyle::LS_Cpp03);
423 IO.enumCase(
Value,
"c++11", FormatStyle::LS_Cpp11);
424 IO.enumCase(
Value,
"C++11", FormatStyle::LS_Cpp11);
426 IO.enumCase(
Value,
"c++14", FormatStyle::LS_Cpp14);
427 IO.enumCase(
Value,
"c++17", FormatStyle::LS_Cpp17);
428 IO.enumCase(
Value,
"c++20", FormatStyle::LS_Cpp20);
430 IO.enumCase(
Value,
"Latest", FormatStyle::LS_Latest);
431 IO.enumCase(
Value,
"Cpp11", FormatStyle::LS_Latest);
432 IO.enumCase(
Value,
"Auto", FormatStyle::LS_Auto);
437struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
439 FormatStyle::LambdaBodyIndentationKind &
Value) {
440 IO.enumCase(
Value,
"Signature", FormatStyle::LBI_Signature);
441 IO.enumCase(
Value,
"OuterScope", FormatStyle::LBI_OuterScope);
445template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
447 IO.enumCase(
Value,
"LF", FormatStyle::LE_LF);
448 IO.enumCase(
Value,
"CRLF", FormatStyle::LE_CRLF);
449 IO.enumCase(
Value,
"DeriveLF", FormatStyle::LE_DeriveLF);
450 IO.enumCase(
Value,
"DeriveCRLF", FormatStyle::LE_DeriveCRLF);
455struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
457 FormatStyle::NamespaceIndentationKind &
Value) {
458 IO.enumCase(
Value,
"None", FormatStyle::NI_None);
459 IO.enumCase(
Value,
"Inner", FormatStyle::NI_Inner);
460 IO.enumCase(
Value,
"All", FormatStyle::NI_All);
464template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
466 IO.enumCase(
Value,
"DontAlign", FormatStyle::OAS_DontAlign);
467 IO.enumCase(
Value,
"Align", FormatStyle::OAS_Align);
468 IO.enumCase(
Value,
"AlignAfterOperator",
469 FormatStyle::OAS_AlignAfterOperator);
472 IO.enumCase(
Value,
"true", FormatStyle::OAS_Align);
473 IO.enumCase(
Value,
"false", FormatStyle::OAS_DontAlign);
478struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
481 IO.enumCase(
Value,
"Never", FormatStyle::PCIS_Never);
482 IO.enumCase(
Value,
"BinPack", FormatStyle::PCIS_BinPack);
483 IO.enumCase(
Value,
"CurrentLine", FormatStyle::PCIS_CurrentLine);
484 IO.enumCase(
Value,
"NextLine", FormatStyle::PCIS_NextLine);
485 IO.enumCase(
Value,
"NextLineOnly", FormatStyle::PCIS_NextLineOnly);
489template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
491 IO.enumCase(
Value,
"Middle", FormatStyle::PAS_Middle);
492 IO.enumCase(
Value,
"Left", FormatStyle::PAS_Left);
493 IO.enumCase(
Value,
"Right", FormatStyle::PAS_Right);
496 IO.enumCase(
Value,
"true", FormatStyle::PAS_Left);
497 IO.enumCase(
Value,
"false", FormatStyle::PAS_Right);
502struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
504 IO.enumCase(
Value,
"None", FormatStyle::PPDIS_None);
505 IO.enumCase(
Value,
"AfterHash", FormatStyle::PPDIS_AfterHash);
506 IO.enumCase(
Value,
"BeforeHash", FormatStyle::PPDIS_BeforeHash);
511struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
513 IO.enumCase(
Value,
"Leave", FormatStyle::QAS_Leave);
514 IO.enumCase(
Value,
"Left", FormatStyle::QAS_Left);
515 IO.enumCase(
Value,
"Right", FormatStyle::QAS_Right);
516 IO.enumCase(
Value,
"Custom", FormatStyle::QAS_Custom);
521 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
522 IO.mapOptional(
"Language", Format.Language);
523 IO.mapOptional(
"Delimiters", Format.Delimiters);
524 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
525 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
526 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
530template <>
struct ScalarEnumerationTraits<
FormatStyle::ReflowCommentsStyle> {
532 IO.enumCase(
Value,
"Never", FormatStyle::RCS_Never);
533 IO.enumCase(
Value,
"IndentOnly", FormatStyle::RCS_IndentOnly);
534 IO.enumCase(
Value,
"Always", FormatStyle::RCS_Always);
536 IO.enumCase(
Value,
"false", FormatStyle::RCS_Never);
537 IO.enumCase(
Value,
"true", FormatStyle::RCS_Always);
542struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
544 IO.enumCase(
Value,
"Pointer", FormatStyle::RAS_Pointer);
545 IO.enumCase(
Value,
"Middle", FormatStyle::RAS_Middle);
546 IO.enumCase(
Value,
"Left", FormatStyle::RAS_Left);
547 IO.enumCase(
Value,
"Right", FormatStyle::RAS_Right);
552struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
554 IO.enumCase(
Value,
"Leave", FormatStyle::RPS_Leave);
555 IO.enumCase(
Value,
"MultipleParentheses",
556 FormatStyle::RPS_MultipleParentheses);
557 IO.enumCase(
Value,
"ReturnStatement", FormatStyle::RPS_ReturnStatement);
562struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
564 FormatStyle::RequiresClausePositionStyle &
Value) {
565 IO.enumCase(
Value,
"OwnLine", FormatStyle::RCPS_OwnLine);
566 IO.enumCase(
Value,
"OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace);
567 IO.enumCase(
Value,
"WithPreceding", FormatStyle::RCPS_WithPreceding);
568 IO.enumCase(
Value,
"WithFollowing", FormatStyle::RCPS_WithFollowing);
569 IO.enumCase(
Value,
"SingleLine", FormatStyle::RCPS_SingleLine);
574struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
577 IO.enumCase(
Value,
"Keyword", FormatStyle::REI_Keyword);
578 IO.enumCase(
Value,
"OuterScope", FormatStyle::REI_OuterScope);
583struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
585 IO.enumCase(
Value,
"None", FormatStyle::RTBS_None);
586 IO.enumCase(
Value,
"Automatic", FormatStyle::RTBS_Automatic);
587 IO.enumCase(
Value,
"ExceptShortType", FormatStyle::RTBS_ExceptShortType);
588 IO.enumCase(
Value,
"All", FormatStyle::RTBS_All);
589 IO.enumCase(
Value,
"TopLevel", FormatStyle::RTBS_TopLevel);
590 IO.enumCase(
Value,
"TopLevelDefinitions",
591 FormatStyle::RTBS_TopLevelDefinitions);
592 IO.enumCase(
Value,
"AllDefinitions", FormatStyle::RTBS_AllDefinitions);
597struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
599 IO.enumCase(
Value,
"Leave", FormatStyle::SDS_Leave);
600 IO.enumCase(
Value,
"Always", FormatStyle::SDS_Always);
601 IO.enumCase(
Value,
"Never", FormatStyle::SDS_Never);
605template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
607 IO.enumCase(
Value,
"Never", FormatStyle::SBS_Never);
608 IO.enumCase(
Value,
"false", FormatStyle::SBS_Never);
609 IO.enumCase(
Value,
"Always", FormatStyle::SBS_Always);
610 IO.enumCase(
Value,
"true", FormatStyle::SBS_Always);
611 IO.enumCase(
Value,
"Empty", FormatStyle::SBS_Empty);
615template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortFunctionStyle> {
617 IO.enumCase(
Value,
"None", FormatStyle::SFS_None);
618 IO.enumCase(
Value,
"false", FormatStyle::SFS_None);
619 IO.enumCase(
Value,
"All", FormatStyle::SFS_All);
620 IO.enumCase(
Value,
"true", FormatStyle::SFS_All);
621 IO.enumCase(
Value,
"Inline", FormatStyle::SFS_Inline);
622 IO.enumCase(
Value,
"InlineOnly", FormatStyle::SFS_InlineOnly);
623 IO.enumCase(
Value,
"Empty", FormatStyle::SFS_Empty);
627template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
629 IO.enumCase(
Value,
"Never", FormatStyle::SIS_Never);
630 IO.enumCase(
Value,
"WithoutElse", FormatStyle::SIS_WithoutElse);
631 IO.enumCase(
Value,
"OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
632 IO.enumCase(
Value,
"AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
635 IO.enumCase(
Value,
"Always", FormatStyle::SIS_OnlyFirstIf);
636 IO.enumCase(
Value,
"false", FormatStyle::SIS_Never);
637 IO.enumCase(
Value,
"true", FormatStyle::SIS_WithoutElse);
641template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
643 IO.enumCase(
Value,
"None", FormatStyle::SLS_None);
644 IO.enumCase(
Value,
"false", FormatStyle::SLS_None);
645 IO.enumCase(
Value,
"Empty", FormatStyle::SLS_Empty);
646 IO.enumCase(
Value,
"Inline", FormatStyle::SLS_Inline);
647 IO.enumCase(
Value,
"All", FormatStyle::SLS_All);
648 IO.enumCase(
Value,
"true", FormatStyle::SLS_All);
652template <>
struct ScalarEnumerationTraits<
FormatStyle::SortIncludesOptions> {
654 IO.enumCase(
Value,
"Never", FormatStyle::SI_Never);
655 IO.enumCase(
Value,
"CaseInsensitive", FormatStyle::SI_CaseInsensitive);
656 IO.enumCase(
Value,
"CaseSensitive", FormatStyle::SI_CaseSensitive);
659 IO.enumCase(
Value,
"false", FormatStyle::SI_Never);
660 IO.enumCase(
Value,
"true", FormatStyle::SI_CaseSensitive);
665struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
667 FormatStyle::SortJavaStaticImportOptions &
Value) {
668 IO.enumCase(
Value,
"Before", FormatStyle::SJSIO_Before);
669 IO.enumCase(
Value,
"After", FormatStyle::SJSIO_After);
674struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
676 FormatStyle::SortUsingDeclarationsOptions &
Value) {
677 IO.enumCase(
Value,
"Never", FormatStyle::SUD_Never);
678 IO.enumCase(
Value,
"Lexicographic", FormatStyle::SUD_Lexicographic);
679 IO.enumCase(
Value,
"LexicographicNumeric",
680 FormatStyle::SUD_LexicographicNumeric);
683 IO.enumCase(
Value,
"false", FormatStyle::SUD_Never);
684 IO.enumCase(
Value,
"true", FormatStyle::SUD_LexicographicNumeric);
689struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
692 IO.enumCase(
Value,
"Default", FormatStyle::SAPQ_Default);
693 IO.enumCase(
Value,
"Before", FormatStyle::SAPQ_Before);
694 IO.enumCase(
Value,
"After", FormatStyle::SAPQ_After);
695 IO.enumCase(
Value,
"Both", FormatStyle::SAPQ_Both);
699template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
700 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
701 IO.mapOptional(
"AfterControlStatements", Spacing.AfterControlStatements);
702 IO.mapOptional(
"AfterForeachMacros", Spacing.AfterForeachMacros);
703 IO.mapOptional(
"AfterFunctionDefinitionName",
704 Spacing.AfterFunctionDefinitionName);
705 IO.mapOptional(
"AfterFunctionDeclarationName",
706 Spacing.AfterFunctionDeclarationName);
707 IO.mapOptional(
"AfterIfMacros", Spacing.AfterIfMacros);
708 IO.mapOptional(
"AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
709 IO.mapOptional(
"AfterPlacementOperator", Spacing.AfterPlacementOperator);
710 IO.mapOptional(
"AfterRequiresInClause", Spacing.AfterRequiresInClause);
711 IO.mapOptional(
"AfterRequiresInExpression",
712 Spacing.AfterRequiresInExpression);
713 IO.mapOptional(
"BeforeNonEmptyParentheses",
714 Spacing.BeforeNonEmptyParentheses);
719struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
721 IO.enumCase(
Value,
"Never", FormatStyle::SBPO_Never);
722 IO.enumCase(
Value,
"ControlStatements",
723 FormatStyle::SBPO_ControlStatements);
724 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
725 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
726 IO.enumCase(
Value,
"NonEmptyParentheses",
727 FormatStyle::SBPO_NonEmptyParentheses);
728 IO.enumCase(
Value,
"Always", FormatStyle::SBPO_Always);
729 IO.enumCase(
Value,
"Custom", FormatStyle::SBPO_Custom);
732 IO.enumCase(
Value,
"false", FormatStyle::SBPO_Never);
733 IO.enumCase(
Value,
"true", FormatStyle::SBPO_ControlStatements);
734 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
735 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
739template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
741 IO.enumCase(
Value,
"Never", FormatStyle::SIAS_Never);
742 IO.enumCase(
Value,
"Always", FormatStyle::SIAS_Always);
743 IO.enumCase(
Value,
"Leave", FormatStyle::SIAS_Leave);
746 IO.enumCase(
Value,
"false", FormatStyle::SIAS_Never);
747 IO.enumCase(
Value,
"true", FormatStyle::SIAS_Always);
751template <>
struct MappingTraits<
FormatStyle::SpacesInLineComment> {
752 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
754 int signedMaximum =
static_cast<int>(Space.Maximum);
755 IO.mapOptional(
"Minimum", Space.Minimum);
756 IO.mapOptional(
"Maximum", signedMaximum);
757 Space.Maximum =
static_cast<unsigned>(signedMaximum);
759 if (Space.Maximum != -1u)
760 Space.Minimum = std::min(Space.Minimum, Space.Maximum);
764template <>
struct MappingTraits<
FormatStyle::SpacesInParensCustom> {
765 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
766 IO.mapOptional(
"ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
767 IO.mapOptional(
"InCStyleCasts", Spaces.InCStyleCasts);
768 IO.mapOptional(
"InConditionalStatements", Spaces.InConditionalStatements);
769 IO.mapOptional(
"InEmptyParentheses", Spaces.InEmptyParentheses);
770 IO.mapOptional(
"Other", Spaces.Other);
774template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
776 IO.enumCase(
Value,
"Never", FormatStyle::SIPO_Never);
777 IO.enumCase(
Value,
"Custom", FormatStyle::SIPO_Custom);
781template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
783 IO.enumCase(
Value,
"None", FormatStyle::TCS_None);
784 IO.enumCase(
Value,
"Wrapped", FormatStyle::TCS_Wrapped);
789struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
791 FormatStyle::TrailingCommentsAlignmentKinds &
Value) {
792 IO.enumCase(
Value,
"Leave", FormatStyle::TCAS_Leave);
793 IO.enumCase(
Value,
"Always", FormatStyle::TCAS_Always);
794 IO.enumCase(
Value,
"Never", FormatStyle::TCAS_Never);
798template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
800 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
801 IO.enumCase(
Value,
"Leave",
802 FormatStyle::TrailingCommentsAlignmentStyle(
803 {FormatStyle::TCAS_Leave, 0}));
805 IO.enumCase(
Value,
"Always",
806 FormatStyle::TrailingCommentsAlignmentStyle(
807 {FormatStyle::TCAS_Always, 0}));
809 IO.enumCase(
Value,
"Never",
810 FormatStyle::TrailingCommentsAlignmentStyle(
811 {FormatStyle::TCAS_Never, 0}));
814 IO.enumCase(
Value,
"true",
815 FormatStyle::TrailingCommentsAlignmentStyle(
816 {FormatStyle::TCAS_Always, 0}));
817 IO.enumCase(
Value,
"false",
818 FormatStyle::TrailingCommentsAlignmentStyle(
819 {FormatStyle::TCAS_Never, 0}));
823 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
824 IO.mapOptional(
"Kind",
Value.Kind);
825 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
829template <>
struct ScalarEnumerationTraits<
FormatStyle::UseTabStyle> {
831 IO.enumCase(
Value,
"Never", FormatStyle::UT_Never);
832 IO.enumCase(
Value,
"false", FormatStyle::UT_Never);
833 IO.enumCase(
Value,
"Always", FormatStyle::UT_Always);
834 IO.enumCase(
Value,
"true", FormatStyle::UT_Always);
835 IO.enumCase(
Value,
"ForIndentation", FormatStyle::UT_ForIndentation);
836 IO.enumCase(
Value,
"ForContinuationAndIndentation",
837 FormatStyle::UT_ForContinuationAndIndentation);
838 IO.enumCase(
Value,
"AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
843struct ScalarEnumerationTraits<
844 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
847 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &
Value) {
848 IO.enumCase(
Value,
"Never", FormatStyle::WNBWELS_Never);
849 IO.enumCase(
Value,
"Always", FormatStyle::WNBWELS_Always);
850 IO.enumCase(
Value,
"Leave", FormatStyle::WNBWELS_Leave);
857 IO.mapOptional(
"Language", Style.
Language);
859 StringRef BasedOnStyle;
860 if (IO.outputting()) {
861 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
862 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
863 for (StringRef StyleName : Styles) {
865 if (getPredefinedStyle(StyleName, Style.
Language, &PredefinedStyle) &&
866 Style == PredefinedStyle) {
867 BasedOnStyle = StyleName;
872 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
873 if (!BasedOnStyle.empty()) {
874 FormatStyle::LanguageKind OldLanguage = Style.
Language;
875 FormatStyle::LanguageKind Language =
877 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
878 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
896 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
897 BasedOnStyle.equals_insensitive(
"chromium");
898 bool OnCurrentLine = IsGoogleOrChromium;
899 bool OnNextLine =
true;
901 bool BreakBeforeInheritanceComma =
false;
902 bool BreakConstructorInitializersBeforeComma =
false;
904 bool DeriveLineEnding =
true;
905 bool UseCRLF =
false;
907 bool SpaceInEmptyParentheses =
false;
908 bool SpacesInConditionalStatement =
false;
909 bool SpacesInCStyleCastParentheses =
false;
910 bool SpacesInParentheses =
false;
913 if (!IO.outputting()) {
915 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
917 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
919 IO.mapOptional(
"BreakBeforeInheritanceComma",
920 BreakBeforeInheritanceComma);
921 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
922 BreakConstructorInitializersBeforeComma);
923 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
925 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
928 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
930 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
934 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
936 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
937 IO.mapOptional(
"SpacesInConditionalStatement",
938 SpacesInConditionalStatement);
939 IO.mapOptional(
"SpacesInCStyleCastParentheses",
940 SpacesInCStyleCastParentheses);
941 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
942 IO.mapOptional(
"UseCRLF", UseCRLF);
948 IO.mapOptional(
"AlignConsecutiveAssignments",
950 IO.mapOptional(
"AlignConsecutiveBitFields",
952 IO.mapOptional(
"AlignConsecutiveDeclarations",
955 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
957 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
959 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
961 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
966 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
968 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
970 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
972 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
974 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
976 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
978 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
980 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
982 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
984 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
986 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
988 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
990 IO.mapOptional(
"AllowShortNamespacesOnASingleLine",
992 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
994 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
1000 IO.mapOptional(
"BracedInitializerIndentWidth",
1003 IO.mapOptional(
"BreakAdjacentStringLiterals",
1006 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
1010 IO.mapOptional(
"BreakBeforeBinaryOperators",
1012 IO.mapOptional(
"BreakBeforeConceptDeclarations",
1015 IO.mapOptional(
"BreakBeforeInlineASMColon",
1017 IO.mapOptional(
"BreakBeforeTernaryOperators",
1020 IO.mapOptional(
"BreakConstructorInitializers",
1022 IO.mapOptional(
"BreakFunctionDefinitionParameters",
1026 IO.mapOptional(
"BreakTemplateDeclarations",
1031 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1037 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1039 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1041 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1045 IO.mapOptional(
"IfMacros", Style.
IfMacros);
1049 IO.mapOptional(
"IncludeIsMainSourceRegex",
1060 IO.mapOptional(
"IndentWrappedFunctionNames",
1072 IO.mapOptional(
"LineEnding", Style.
LineEnding);
1075 IO.mapOptional(
"Macros", Style.
Macros);
1082 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1084 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1087 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1089 IO.mapOptional(
"PackConstructorInitializers",
1092 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1094 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1097 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1099 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1101 IO.mapOptional(
"PenaltyBreakScopeResolution",
1104 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1107 IO.mapOptional(
"PenaltyIndentedWhitespace",
1109 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1125 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1130 IO.mapOptional(
"RequiresExpressionIndentation",
1140 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1142 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1144 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1147 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1149 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1151 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1156 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1158 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1161 IO.mapOptional(
"SpacesBeforeTrailingComments",
1164 IO.mapOptional(
"SpacesInContainerLiterals",
1166 IO.mapOptional(
"SpacesInLineCommentPrefix",
1171 IO.mapOptional(
"Standard", Style.
Standard);
1172 IO.mapOptional(
"StatementAttributeLikeMacros",
1175 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1177 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1179 IO.mapOptional(
"TabWidth", Style.
TabWidth);
1181 IO.mapOptional(
"TypeNames", Style.
TypeNames);
1183 IO.mapOptional(
"UseTab", Style.
UseTab);
1185 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1187 IO.mapOptional(
"WhitespaceSensitiveMacros",
1189 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1198 FormatStyle::DRTBS_All) {
1201 FormatStyle::DRTBS_TopLevel) {
1208 if (BreakBeforeInheritanceComma &&
1216 if (BreakConstructorInitializersBeforeComma &&
1221 if (!IsGoogleOrChromium) {
1225 ? FormatStyle::PCIS_NextLine
1226 : FormatStyle::PCIS_CurrentLine;
1229 FormatStyle::PCIS_NextLine) {
1232 else if (!OnNextLine)
1236 if (Style.
LineEnding == FormatStyle::LE_DeriveLF) {
1237 if (!DeriveLineEnding)
1238 Style.
LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1240 Style.
LineEnding = FormatStyle::LE_DeriveCRLF;
1244 (SpacesInParentheses || SpaceInEmptyParentheses ||
1245 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1246 if (SpacesInParentheses) {
1251 SpacesInCStyleCastParentheses;
1253 SpaceInEmptyParentheses;
1258 SpacesInConditionalStatement;
1260 SpacesInCStyleCastParentheses;
1262 SpaceInEmptyParentheses;
1274template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1275 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1280 if (Index >= Seq.size()) {
1281 assert(Index == Seq.size());
1283 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1286 Template = *((
const FormatStyle *)IO.getContext());
1287 Template.
Language = FormatStyle::LK_None;
1289 Seq.resize(Index + 1, Template);
1309 return llvm::make_error<llvm::StringError>(Message,
1310 llvm::inconvertibleErrorCode());
1314 return "clang-format.parse_error";
1322 return "Invalid argument";
1324 return "Unsuitable";
1326 return "trailing comma insertion cannot be used with bin packing";
1328 return "Invalid qualifier specified in QualifierOrder";
1330 return "Duplicate qualifier specified in QualifierOrder";
1332 return "Missing type in QualifierOrder";
1334 return "Missing QualifierOrder";
1336 llvm_unreachable(
"unexpected parse error");
1560 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1563 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1564 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1565 {
".*", 1, 0,
false}};
1714 {
"^<.*\\.h>", 1, 0,
false},
1715 {
"^<.*", 2, 0,
false},
1716 {
".*", 3, 0,
false}};
1756 "PARSE_PARTIAL_TEXT_PROTO",
1760 "ParseTextProtoOrDie",
1762 "ParsePartialTestProto",
1874 "com.google.android.apps.chrome",
1893 return ChromiumStyle;
1919 return MozillaStyle;
2014 if (Name.equals_insensitive(
"llvm"))
2016 else if (Name.equals_insensitive(
"chromium"))
2018 else if (Name.equals_insensitive(
"mozilla"))
2020 else if (Name.equals_insensitive(
"google"))
2022 else if (Name.equals_insensitive(
"webkit"))
2024 else if (Name.equals_insensitive(
"gnu"))
2026 else if (Name.equals_insensitive(
"microsoft"))
2028 else if (Name.equals_insensitive(
"clang-format"))
2030 else if (Name.equals_insensitive(
"none"))
2032 else if (Name.equals_insensitive(
"inheritparentconfig"))
2048 if (Qualifier ==
"type")
2052 if (token == tok::identifier)
2057 std::set<std::string> UniqueQualifiers(Style->
QualifierOrder.begin(),
2060 LLVM_DEBUG(llvm::dbgs()
2062 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2075 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2076 void *DiagHandlerCtxt) {
2080 if (Config.getBuffer().trim().empty())
2082 Style->StyleSet.
Clear();
2083 std::vector<FormatStyle> Styles;
2084 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2090 Input.setContext(Style);
2091 Input.setAllowUnknownKeys(AllowUnknownOptions);
2094 return Input.error();
2096 for (
unsigned i = 0; i < Styles.size(); ++i) {
2101 for (
unsigned j = 0; j < i; ++j) {
2103 LLVM_DEBUG(llvm::dbgs()
2104 <<
"Duplicate languages in the config file on positions "
2105 << j <<
" and " << i <<
"\n");
2114 bool LanguageFound =
false;
2115 for (
const FormatStyle &Style : llvm::reverse(Styles)) {
2117 StyleSet.
Add(Style);
2119 LanguageFound =
true;
2121 if (!LanguageFound) {
2126 StyleSet.
Add(std::move(DefaultStyle));
2141 llvm::raw_string_ostream Stream(
Text);
2142 llvm::yaml::Output Output(Stream);
2149 Output << NonConstStyle;
2151 return Stream.str();
2154std::optional<FormatStyle>
2157 return std::nullopt;
2159 if (It == Styles->end())
2160 return std::nullopt;
2162 Style.StyleSet = *
this;
2168 "Cannot add a style for LK_None to a StyleSet");
2170 !Style.StyleSet.Styles &&
2171 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2173 Styles = std::make_shared<MapType>();
2174 (*Styles)[Style.
Language] = std::move(Style);
2179std::optional<FormatStyle>
2191 std::pair<tooling::Replacements, unsigned>
2192 analyze(TokenAnnotator &Annotator,
2194 FormatTokenLexer &Tokens)
override {
2195 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2197 removeParens(AnnotatedLines, Result);
2202 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2203 tooling::Replacements &Result) {
2204 const auto &SourceMgr =
Env.getSourceManager();
2205 for (
auto *Line : Lines) {
2206 if (!Line->Children.empty())
2207 removeParens(Line->Children, Result);
2208 if (!Line->Affected)
2210 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2211 Token = Token->Next) {
2212 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2214 auto *Next = Token->Next;
2215 assert(Next && Next->isNot(tok::eof));
2216 SourceLocation Start;
2217 if (Next->NewlinesBefore == 0) {
2218 Start = Token->Tok.getLocation();
2219 Next->WhitespaceRange = Token->WhitespaceRange;
2221 Start = Token->WhitespaceRange.getBegin();
2224 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2225 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
" ")));
2231class BracesInserter :
public TokenAnalyzer {
2234 : TokenAnalyzer(
Env, Style) {}
2236 std::pair<tooling::Replacements, unsigned>
2237 analyze(TokenAnnotator &Annotator,
2238 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2239 FormatTokenLexer &Tokens)
override {
2240 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2241 tooling::Replacements Result;
2242 insertBraces(AnnotatedLines, Result);
2247 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2248 tooling::Replacements &Result) {
2249 const auto &SourceMgr =
Env.getSourceManager();
2250 int OpeningBraceSurplus = 0;
2251 for (AnnotatedLine *Line : Lines) {
2252 if (!Line->Children.empty())
2253 insertBraces(Line->Children, Result);
2254 if (!Line->Affected && OpeningBraceSurplus == 0)
2256 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2257 Token = Token->Next) {
2258 int BraceCount = Token->BraceCount;
2259 if (BraceCount == 0)
2262 if (BraceCount < 0) {
2263 assert(BraceCount == -1);
2264 if (!Line->Affected)
2266 Brace = Token->is(tok::comment) ?
"\n{" :
"{";
2267 ++OpeningBraceSurplus;
2269 if (OpeningBraceSurplus == 0)
2271 if (OpeningBraceSurplus < BraceCount)
2272 BraceCount = OpeningBraceSurplus;
2273 Brace =
'\n' + std::string(BraceCount,
'}');
2274 OpeningBraceSurplus -= BraceCount;
2276 Token->BraceCount = 0;
2277 const auto Start = Token->Tok.getEndLoc();
2278 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2281 assert(OpeningBraceSurplus == 0);
2285class BracesRemover :
public TokenAnalyzer {
2288 : TokenAnalyzer(
Env, Style) {}
2290 std::pair<tooling::Replacements, unsigned>
2291 analyze(TokenAnnotator &Annotator,
2292 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2293 FormatTokenLexer &Tokens)
override {
2294 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2295 tooling::Replacements Result;
2296 removeBraces(AnnotatedLines, Result);
2301 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2302 tooling::Replacements &Result) {
2303 const auto &SourceMgr =
Env.getSourceManager();
2304 const auto *End = Lines.end();
2305 for (
const auto *I = Lines.begin(); I != End; ++I) {
2306 const auto &Line = *I;
2307 if (!Line->Children.empty())
2308 removeBraces(Line->Children, Result);
2309 if (!Line->Affected)
2311 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2312 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2313 Token = Token->Next) {
2314 if (!Token->Optional)
2316 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2318 auto *Next = Token->Next;
2319 assert(Next || Token == Line->Last);
2320 if (!Next && NextLine)
2321 Next = NextLine->First;
2322 SourceLocation Start;
2323 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2324 Start = Token->Tok.getLocation();
2325 Next->WhitespaceRange = Token->WhitespaceRange;
2327 Start = Token->WhitespaceRange.getBegin();
2330 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2331 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2337class SemiRemover :
public TokenAnalyzer {
2340 : TokenAnalyzer(
Env, Style) {}
2342 std::pair<tooling::Replacements, unsigned>
2343 analyze(TokenAnnotator &Annotator,
2344 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2345 FormatTokenLexer &Tokens)
override {
2346 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2347 tooling::Replacements Result;
2348 removeSemi(Annotator, AnnotatedLines, Result);
2353 void removeSemi(TokenAnnotator &Annotator,
2354 SmallVectorImpl<AnnotatedLine *> &Lines,
2355 tooling::Replacements &Result) {
2356 auto PrecededByFunctionRBrace = [](
const FormatToken &Tok) {
2357 const auto *Prev = Tok.Previous;
2358 if (!Prev || Prev->isNot(tok::r_brace))
2360 const auto *LBrace = Prev->MatchingParen;
2361 return LBrace && LBrace->is(TT_FunctionLBrace);
2363 const auto &SourceMgr =
Env.getSourceManager();
2364 const auto *End = Lines.end();
2365 for (
const auto *I = Lines.begin(); I != End; ++I) {
2366 const auto &Line = *I;
2367 if (!Line->Children.empty())
2368 removeSemi(Annotator, Line->Children, Result);
2369 if (!Line->Affected)
2371 Annotator.calculateFormattingInformation(*Line);
2372 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2373 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2374 Token = Token->Next) {
2375 if (Token->isNot(tok::semi) ||
2376 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2379 auto *Next = Token->Next;
2380 assert(Next || Token == Line->Last);
2381 if (!Next && NextLine)
2382 Next = NextLine->First;
2383 SourceLocation Start;
2384 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2385 Start = Token->Tok.getLocation();
2386 Next->WhitespaceRange = Token->WhitespaceRange;
2388 Start = Token->WhitespaceRange.getBegin();
2391 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2392 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2398class JavaScriptRequoter :
public TokenAnalyzer {
2400 JavaScriptRequoter(
const Environment &
Env,
const FormatStyle &Style)
2401 : TokenAnalyzer(
Env, Style) {}
2403 std::pair<tooling::Replacements, unsigned>
2404 analyze(TokenAnnotator &Annotator,
2405 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2406 FormatTokenLexer &Tokens)
override {
2407 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2408 tooling::Replacements Result;
2409 requoteJSStringLiteral(AnnotatedLines, Result);
2416 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2417 tooling::Replacements &Result) {
2418 for (AnnotatedLine *Line : Lines) {
2419 requoteJSStringLiteral(Line->Children, Result);
2420 if (!Line->Affected)
2422 for (FormatToken *FormatTok = Line->First; FormatTok;
2423 FormatTok = FormatTok->Next) {
2424 StringRef Input = FormatTok->TokenText;
2425 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2429 !Input.starts_with(
"\"")) ||
2431 !Input.starts_with(
"\'"))) {
2437 SourceLocation Start = FormatTok->Tok.getLocation();
2438 auto Replace = [&](SourceLocation Start,
unsigned Length,
2439 StringRef ReplacementText) {
2440 auto Err = Result.add(tooling::Replacement(
2441 Env.getSourceManager(), Start, Length, ReplacementText));
2445 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2449 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2450 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2451 IsSingle ?
"'" :
"\"");
2454 bool Escaped =
false;
2455 for (
size_t i = 1; i < Input.size() - 1; i++) {
2458 if (!Escaped && i + 1 < Input.size() &&
2459 ((IsSingle && Input[i + 1] ==
'"') ||
2460 (!IsSingle && Input[i + 1] ==
'\''))) {
2463 Replace(Start.getLocWithOffset(i), 1,
"");
2470 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2472 Replace(Start.getLocWithOffset(i), 0,
"\\");
2486class Formatter :
public TokenAnalyzer {
2489 FormattingAttemptStatus *Status)
2490 : TokenAnalyzer(
Env, Style), Status(Status) {}
2492 std::pair<tooling::Replacements, unsigned>
2493 analyze(TokenAnnotator &Annotator,
2494 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2495 FormatTokenLexer &Tokens)
override {
2496 tooling::Replacements Result;
2497 deriveLocalStyle(AnnotatedLines);
2498 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2499 for (AnnotatedLine *Line : AnnotatedLines)
2500 Annotator.calculateFormattingInformation(*Line);
2501 Annotator.setCommentLineLevels(AnnotatedLines);
2503 WhitespaceManager Whitespaces(
2504 Env.getSourceManager(), Style,
2506 ? WhitespaceManager::inputUsesCRLF(
2507 Env.getSourceManager().getBufferData(
Env.getFileID()),
2508 Style.
LineEnding == FormatStyle::LE_DeriveCRLF)
2510 ContinuationIndenter
Indenter(Style, Tokens.getKeywords(),
2511 Env.getSourceManager(), Whitespaces, Encoding,
2512 BinPackInconclusiveFunctions);
2514 UnwrappedLineFormatter(&
Indenter, &Whitespaces, Style,
2515 Tokens.getKeywords(),
Env.getSourceManager(),
2517 .format(AnnotatedLines,
false,
2520 Env.getFirstStartColumn(),
2521 Env.getNextStartColumn(),
2522 Env.getLastStartColumn());
2523 for (
const auto &R : Whitespaces.generateReplacements())
2525 return std::make_pair(Result, 0);
2526 return std::make_pair(Result, Penalty);
2531 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2532 for (
const AnnotatedLine *Line : Lines) {
2533 if (hasCpp03IncompatibleFormat(Line->Children))
2535 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2536 if (!Tok->hasWhitespaceBefore()) {
2537 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2539 if (Tok->is(TT_TemplateCloser) &&
2540 Tok->Previous->is(TT_TemplateCloser)) {
2549 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2550 int AlignmentDiff = 0;
2551 for (
const AnnotatedLine *Line : Lines) {
2552 AlignmentDiff += countVariableAlignments(Line->Children);
2553 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2554 if (Tok->isNot(TT_PointerOrReference))
2557 if (
const auto *Prev = Tok->getPreviousNonComment()) {
2558 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2559 if (
const auto *Func =
2560 Prev->MatchingParen->getPreviousNonComment()) {
2561 if (
Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2562 TT_OverloadedOperator)) {
2568 bool SpaceBefore = Tok->hasWhitespaceBefore();
2569 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2570 if (SpaceBefore && !SpaceAfter)
2572 if (!SpaceBefore && SpaceAfter)
2576 return AlignmentDiff;
2580 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2581 bool HasBinPackedFunction =
false;
2582 bool HasOnePerLineFunction =
false;
2583 for (AnnotatedLine *Line : AnnotatedLines) {
2584 if (!Line->First->Next)
2586 FormatToken *Tok = Line->First->Next;
2588 if (Tok->is(PPK_BinPacked))
2589 HasBinPackedFunction =
true;
2590 if (Tok->is(PPK_OnePerLine))
2591 HasOnePerLineFunction =
true;
2597 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2598 if (NetRightCount > 0)
2600 else if (NetRightCount < 0)
2604 if (Style.
Standard == FormatStyle::LS_Auto) {
2605 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2606 ? FormatStyle::LS_Latest
2607 : FormatStyle::LS_Cpp03;
2609 BinPackInconclusiveFunctions =
2610 HasBinPackedFunction || !HasOnePerLineFunction;
2613 bool BinPackInconclusiveFunctions;
2614 FormattingAttemptStatus *Status;
2628class TrailingCommaInserter :
public TokenAnalyzer {
2630 TrailingCommaInserter(
const Environment &
Env,
const FormatStyle &Style)
2631 : TokenAnalyzer(
Env, Style) {}
2633 std::pair<tooling::Replacements, unsigned>
2634 analyze(TokenAnnotator &Annotator,
2635 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2636 FormatTokenLexer &Tokens)
override {
2637 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2638 tooling::Replacements Result;
2639 insertTrailingCommas(AnnotatedLines, Result);
2646 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2647 tooling::Replacements &Result) {
2648 for (AnnotatedLine *Line : Lines) {
2649 insertTrailingCommas(Line->Children, Result);
2650 if (!Line->Affected)
2652 for (FormatToken *FormatTok = Line->First; FormatTok;
2653 FormatTok = FormatTok->Next) {
2654 if (FormatTok->NewlinesBefore == 0)
2656 FormatToken *Matching = FormatTok->MatchingParen;
2657 if (!Matching || !FormatTok->getPreviousNonComment())
2659 if (!(FormatTok->is(tok::r_square) &&
2660 Matching->is(TT_ArrayInitializerLSquare)) &&
2661 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2664 FormatToken *Prev = FormatTok->getPreviousNonComment();
2665 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2669 SourceLocation Start =
2670 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2674 unsigned ColumnNumber =
2675 Env.getSourceManager().getSpellingColumnNumber(Start);
2680 cantFail(Result.add(
2681 tooling::Replacement(
Env.getSourceManager(), Start, 0,
",")));
2689class Cleaner :
public TokenAnalyzer {
2692 : TokenAnalyzer(
Env, Style),
2693 DeletedTokens(FormatTokenLess(
Env.getSourceManager())) {}
2696 std::pair<tooling::Replacements, unsigned>
2697 analyze(TokenAnnotator &Annotator,
2698 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2699 FormatTokenLexer &Tokens)
override {
2707 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2709 checkEmptyNamespace(AnnotatedLines);
2711 for (
auto *Line : AnnotatedLines)
2714 return {generateFixes(), 0};
2718 void cleanupLine(AnnotatedLine *Line) {
2719 for (
auto *Child : Line->Children)
2722 if (Line->Affected) {
2723 cleanupRight(Line->First, tok::comma, tok::comma);
2724 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2725 cleanupRight(Line->First, tok::l_paren, tok::comma);
2726 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2727 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2728 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2729 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2733 bool containsOnlyComments(
const AnnotatedLine &Line) {
2734 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2735 if (Tok->isNot(tok::comment))
2741 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2742 std::set<unsigned> DeletedLines;
2743 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2744 auto &Line = *AnnotatedLines[i];
2745 if (Line.startsWithNamespace())
2746 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2749 for (
auto Line : DeletedLines) {
2750 FormatToken *Tok = AnnotatedLines[Line]->First;
2762 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2763 unsigned CurrentLine,
unsigned &
NewLine,
2764 std::set<unsigned> &DeletedLines) {
2765 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2770 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2774 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2777 while (++CurrentLine < End) {
2778 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2781 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2782 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine,
NewLine,
2790 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2800 if (CurrentLine >= End)
2804 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2805 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2806 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2810 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
2811 DeletedLines.insert(i);
2820 template <
typename LeftKind,
typename RightKind>
2821 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2823 auto NextNotDeleted = [
this](
const FormatToken &Tok) -> FormatToken * {
2824 for (
auto *Res = Tok.Next; Res; Res = Res->Next) {
2825 if (Res->isNot(tok::comment) &&
2826 DeletedTokens.find(Res) == DeletedTokens.end()) {
2832 for (
auto *Left = Start;
Left;) {
2833 auto *
Right = NextNotDeleted(*Left);
2837 deleteToken(DeleteLeft ? Left : Right);
2838 for (
auto *Tok =
Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2849 template <
typename LeftKind,
typename RightKind>
2850 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2851 cleanupPair(Start, LK, RK,
true);
2854 template <
typename LeftKind,
typename RightKind>
2855 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2856 cleanupPair(Start, LK, RK,
false);
2860 inline void deleteToken(FormatToken *Tok) {
2862 DeletedTokens.insert(Tok);
2865 tooling::Replacements generateFixes() {
2866 tooling::Replacements Fixes;
2867 SmallVector<FormatToken *> Tokens;
2868 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2869 std::back_inserter(Tokens));
2875 while (Idx < Tokens.size()) {
2876 unsigned St = Idx, End = Idx;
2877 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2879 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2880 Tokens[End]->Tok.getEndLoc());
2882 Fixes.add(tooling::Replacement(
Env.getSourceManager(), SR,
""));
2886 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2887 assert(
false &&
"Fixes must not conflict!");
2898 struct FormatTokenLess {
2899 FormatTokenLess(
const SourceManager &
SM) :
SM(
SM) {}
2901 bool operator()(
const FormatToken *LHS,
const FormatToken *RHS)
const {
2902 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2903 RHS->Tok.getLocation());
2909 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2912class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
2914 ObjCHeaderStyleGuesser(
const Environment &
Env,
const FormatStyle &Style)
2915 : TokenAnalyzer(
Env, Style), IsObjC(
false) {}
2917 std::pair<tooling::Replacements, unsigned>
2918 analyze(TokenAnnotator &Annotator,
2919 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2920 FormatTokenLexer &Tokens)
override {
2921 assert(Style.
Language == FormatStyle::LK_Cpp);
2922 IsObjC = guessIsObjC(
Env.getSourceManager(), AnnotatedLines,
2923 Tokens.getKeywords());
2924 tooling::Replacements Result;
2928 bool isObjC() {
return IsObjC; }
2932 guessIsObjC(
const SourceManager &SourceManager,
2933 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2934 const AdditionalKeywords &Keywords) {
2936 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2951 "FOUNDATION_EXPORT",
2952 "FOUNDATION_EXTERN",
2953 "NSAffineTransform",
2955 "NSAttributedString",
2974 "NSInvocationOperation",
2978 "NSMutableAttributedString",
2979 "NSMutableCharacterSet",
2981 "NSMutableDictionary",
2982 "NSMutableIndexSet",
2983 "NSMutableOrderedSet",
2987 "NSNumberFormatter",
2991 "NSOperationQueuePriority",
2995 "NSQualityOfService",
2998 "NSRegularExpression",
3009 "NS_ASSUME_NONNULL_BEGIN",
3014 for (
auto *Line : AnnotatedLines) {
3015 if (Line->First && (Line->First->TokenText.starts_with(
"#") ||
3016 Line->First->TokenText ==
"__pragma" ||
3017 Line->First->TokenText ==
"_Pragma")) {
3020 for (
const FormatToken *FormatTok = Line->First; FormatTok;
3021 FormatTok = FormatTok->Next) {
3022 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3023 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3024 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3026 (FormatTok->Tok.isAnyIdentifier() &&
3027 std::binary_search(std::begin(FoundationIdentifiers),
3028 std::end(FoundationIdentifiers),
3029 FormatTok->TokenText)) ||
3030 FormatTok->is(TT_ObjCStringLiteral) ||
3031 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3032 Keywords.kw_NS_ERROR_ENUM,
3033 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3034 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3035 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3037 LLVM_DEBUG(llvm::dbgs()
3038 <<
"Detected ObjC at location "
3039 << FormatTok->Tok.getLocation().printToString(
3041 <<
" token: " << FormatTok->TokenText <<
" token type: "
3046 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3063struct JavaImportDirective {
3076 for (
const auto &
Range : Ranges) {
3077 if (
Range.getOffset() < End &&
3078 Range.getOffset() +
Range.getLength() > Start) {
3092static std::pair<unsigned, unsigned>
3096 unsigned OffsetToEOL = 0;
3097 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3098 unsigned Start = Includes[Indices[i]].Offset;
3099 unsigned End = Start + Includes[Indices[i]].Text.size();
3100 if (!(Cursor >= Start && Cursor < End))
3102 CursorIndex = Indices[i];
3103 OffsetToEOL = End - Cursor;
3106 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3110 return std::make_pair(CursorIndex, OffsetToEOL);
3115 std::string NewCode;
3116 size_t Pos = 0, LastPos = 0;
3119 Pos = Code.find(
"\r\n", LastPos);
3120 if (Pos == LastPos) {
3124 if (Pos == std::string::npos) {
3125 NewCode += Code.substr(LastPos);
3128 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3130 }
while (Pos != std::string::npos);
3148 const unsigned IncludesBeginOffset = Includes.front().Offset;
3149 const unsigned IncludesEndOffset =
3150 Includes.back().Offset + Includes.back().Text.size();
3151 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3152 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3155 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3158 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3159 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3160 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3161 return std::tie(Includes[LHSI].
Priority, LHSFilenameLower,
3163 std::tie(Includes[RHSI].
Priority, RHSFilenameLower,
3167 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3175 unsigned CursorIndex;
3177 unsigned CursorToEOLOffset;
3179 std::tie(CursorIndex, CursorToEOLOffset) =
3184 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3185 [&](
unsigned LHSI,
unsigned RHSI) {
3186 return Includes[LHSI].Text.trim() ==
3187 Includes[RHSI].Text.trim();
3191 int CurrentCategory = Includes.front().Category;
3199 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3204 const auto OldCursor = Cursor ? *Cursor : 0;
3206 for (
unsigned Index : Indices) {
3207 if (!result.empty()) {
3211 CurrentCategory != Includes[Index].Category) {
3215 result += Includes[Index].Text;
3216 if (Cursor && CursorIndex == Index)
3217 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3218 CurrentCategory = Includes[Index].Category;
3221 if (Cursor && *Cursor >= IncludesEndOffset)
3222 *Cursor += result.size() - IncludesBlockSize;
3227 IncludesBeginOffset, IncludesBlockSize)))) {
3229 *Cursor = OldCursor;
3234 FileName, Includes.front().Offset, IncludesBlockSize, result));
3238 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3248 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3249 .StartsWith(
"\xEF\xBB\xBF", 3)
3251 unsigned SearchFrom = 0;
3263 bool FirstIncludeBlock =
true;
3264 bool MainIncludeFound =
false;
3265 bool FormattingOff =
false;
3268 llvm::Regex RawStringRegex(
3269 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3271 std::string RawStringTermination =
")\"";
3273 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3274 size_t Pos = SearchFrom;
3275 if (Code[SearchFrom] !=
'\n') {
3278 Pos = Code.find(
'\n', Pos);
3279 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3283 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3285 StringRef Trimmed =
Line.trim();
3290 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3291 std::string CharSequence = RawStringMatches[1].str();
3292 RawStringTermination =
")" + CharSequence +
"\"";
3293 FormattingOff =
true;
3296 if (Trimmed.contains(RawStringTermination))
3297 FormattingOff =
false;
3299 bool IsBlockComment =
false;
3302 FormattingOff =
true;
3304 FormattingOff =
false;
3305 }
else if (Trimmed.starts_with(
"/*")) {
3306 IsBlockComment =
true;
3307 Pos = Code.find(
"*/", SearchFrom + 2);
3310 const bool EmptyLineSkipped =
3316 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3317 if (!FormattingOff && !MergeWithNextLine) {
3318 if (!IsBlockComment &&
3320 StringRef IncludeName = Matches[2];
3321 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3326 Pos = Code.find(
"*/", SearchFrom);
3328 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3332 !MainIncludeFound && FirstIncludeBlock);
3334 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3336 MainIncludeFound =
true;
3337 IncludesInBlock.push_back(
3339 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3342 IncludesInBlock.clear();
3343 if (Trimmed.starts_with(
"#pragma hdrstop"))
3344 FirstIncludeBlock =
true;
3346 FirstIncludeBlock =
false;
3349 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3352 if (!MergeWithNextLine)
3354 SearchFrom = Pos + 1;
3356 if (!IncludesInBlock.empty()) {
3366 StringRef ImportIdentifier) {
3367 unsigned LongestMatchIndex =
UINT_MAX;
3368 unsigned LongestMatchLength = 0;
3371 if (ImportIdentifier.starts_with(GroupPrefix) &&
3372 GroupPrefix.length() > LongestMatchLength) {
3373 LongestMatchIndex = I;
3374 LongestMatchLength = GroupPrefix.length();
3377 return LongestMatchIndex;
3389 unsigned ImportsBeginOffset = Imports.front().Offset;
3390 unsigned ImportsEndOffset =
3391 Imports.back().Offset + Imports.back().Text.size();
3392 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3393 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3397 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3400 for (
const JavaImportDirective &Import : Imports)
3403 bool StaticImportAfterNormalImport =
3405 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3407 return std::make_tuple(!Imports[LHSI].
IsStatic ^
3408 StaticImportAfterNormalImport,
3410 std::make_tuple(!Imports[RHSI].
IsStatic ^
3411 StaticImportAfterNormalImport,
3416 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3417 [&](
unsigned LHSI,
unsigned RHSI) {
3418 return Imports[LHSI].Text == Imports[RHSI].Text;
3422 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3426 for (
unsigned Index : Indices) {
3427 if (!result.empty()) {
3429 if (CurrentIsStatic != Imports[Index].
IsStatic ||
3435 result += CommentLine;
3438 result += Imports[Index].Text;
3439 CurrentIsStatic = Imports[Index].IsStatic;
3446 Imports.front().Offset, ImportsBlockSize)))) {
3451 ImportsBlockSize, result));
3455 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3462const char JavaImportRegexPattern[] =
3463 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3472 unsigned SearchFrom = 0;
3473 llvm::Regex ImportRegex(JavaImportRegexPattern);
3478 bool FormattingOff =
false;
3481 auto Pos = Code.find(
'\n', SearchFrom);
3483 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3485 StringRef Trimmed =
Line.trim();
3487 FormattingOff =
true;
3489 FormattingOff =
false;
3491 if (ImportRegex.match(
Line, &Matches)) {
3492 if (FormattingOff) {
3497 StringRef
Static = Matches[1];
3500 if (
Static.contains(
"static"))
3502 ImportsInBlock.push_back(
3505 }
else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3510 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3512 SearchFrom = Pos + 1;
3514 if (!ImportsInBlock.empty())
3523 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3526bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
3530 StringRef
FileName,
unsigned *Cursor) {
3548template <
typename T>
3553 if (Replaces.
empty())
3556 auto NewCode = applyAllReplacements(Code, Replaces);
3558 return NewCode.takeError();
3563 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
3565 return Replaces.
merge(FormatReplaces);
3574 std::vector<tooling::Range> Ranges,
3578 auto SortedReplaces =
3580 if (!SortedReplaces)
3581 return SortedReplaces.takeError();
3585 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
3586 std::vector<tooling::Range> Ranges,
3601inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
3602 return Replace.getOffset() ==
UINT_MAX && Replace.getLength() == 1;
3606tooling::Replacements
3607fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
3612 tooling::Replacements HeaderInsertions;
3613 std::set<StringRef> HeadersToDelete;
3614 tooling::Replacements
Result;
3615 for (
const auto &R : Replaces) {
3616 if (isHeaderInsertion(R)) {
3619 consumeError(HeaderInsertions.add(R));
3620 }
else if (isHeaderDeletion(R)) {
3621 HeadersToDelete.insert(R.getReplacementText());
3622 }
else if (R.getOffset() ==
UINT_MAX) {
3623 llvm::errs() <<
"Insertions other than header #include insertion are "
3625 << R.getReplacementText() <<
"\n";
3627 consumeError(
Result.add(R));
3630 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3633 StringRef
FileName = Replaces.begin()->getFilePath();
3636 for (
const auto &Header : HeadersToDelete) {
3637 tooling::Replacements Replaces =
3638 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
3639 for (
const auto &R : Replaces) {
3640 auto Err =
Result.add(R);
3643 llvm::errs() <<
"Failed to add header deletion replacement for "
3644 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
3649 SmallVector<StringRef, 4> Matches;
3650 for (
const auto &R : HeaderInsertions) {
3654 assert(Matched &&
"Header insertion replacement must have replacement text "
3657 auto IncludeName = Matches[2];
3659 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
3662 auto Err =
Result.add(*Replace);
3664 consumeError(std::move(Err));
3665 unsigned NewOffset =
3666 Result.getShiftedCodePosition(Replace->getOffset());
3667 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
3668 Replace->getReplacementText());
3678Expected<tooling::Replacements>
3683 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
3690 fixCppIncludeInsertions(Code, Replaces, Style);
3695std::pair<tooling::Replacements, unsigned>
3698 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
3709 case FormatStyle::RCPS_SingleLine:
3710 case FormatStyle::RCPS_WithPreceding:
3726 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
3727 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3728 NextStartColumn, LastStartColumn);
3733 Formatter(*
Env, Style, Status).process().first;
3735 Replaces = Replaces.
merge(
3738 if (applyAllReplacements(Code, Replaces))
3739 return {Replaces, 0};
3743 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3744 NextStartColumn, LastStartColumn);
3748 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3758 if (Style.
isCpp()) {
3765 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3766 return ParensRemover(
Env, S).process(
true);
3772 S.InsertBraces =
true;
3773 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3774 return BracesInserter(
Env, S).process(
true);
3780 S.RemoveBracesLLVM =
true;
3781 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3782 return BracesRemover(
Env, S).process(
true);
3788 S.RemoveSemicolon =
true;
3789 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3790 return SemiRemover(
Env, S).process();
3813 if (Style.
Language == FormatStyle::LK_ObjC &&
3823 return JavaScriptRequoter(
Env, Expanded).process(
true);
3828 return Formatter(
Env, Expanded, Status).process();
3834 return TrailingCommaInserter(
Env, Expanded).process();
3838 std::optional<std::string> CurrentCode;
3840 unsigned Penalty = 0;
3841 for (
size_t I = 0,
E = Passes.size(); I <
E; ++I) {
3842 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3843 auto NewCode = applyAllReplacements(
3844 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3846 Fixes = Fixes.
merge(PassFixes.first);
3847 Penalty += PassFixes.second;
3849 CurrentCode = std::move(*NewCode);
3850 Env = Environment::make(
3852 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3853 FirstStartColumn, NextStartColumn, LastStartColumn);
3866 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3867 if (OriginalCode != Fix.getReplacementText()) {
3868 auto Err = NonNoOpFixes.
add(Fix);
3870 llvm::errs() <<
"Error adding replacements : "
3871 <<
toString(std::move(Err)) <<
"\n";
3875 Fixes = std::move(NonNoOpFixes);
3878 return {Fixes, Penalty};
3902 return Cleaner(*
Env, Style).process().first;
3907 StringRef
FileName,
bool *IncompleteFormat) {
3910 if (!Status.FormatComplete)
3911 *IncompleteFormat =
true;
3943 LangOpts.CPlusPlus = 1;
3954 LangOpts.LineComment = 1;
3955 LangOpts.CXXOperatorNames = Style.
isCpp();
3958 LangOpts.MicrosoftExt = 1;
3959 LangOpts.DeclSpecKeyword = 1;
3965 "Set coding style. <string> can be:\n"
3966 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3967 " Mozilla, WebKit.\n"
3968 "2. 'file' to load style configuration from a\n"
3969 " .clang-format file in one of the parent directories\n"
3970 " of the source file (for stdin, see --assume-filename).\n"
3971 " If no .clang-format file is found, falls back to\n"
3972 " --fallback-style.\n"
3973 " --style=file is the default.\n"
3974 "3. 'file:<format_file_path>' to explicitly specify\n"
3975 " the configuration file.\n"
3976 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3977 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3982 if (
FileName.ends_with_insensitive(
".js") ||
3983 FileName.ends_with_insensitive(
".mjs") ||
3984 FileName.ends_with_insensitive(
".cjs") ||
3985 FileName.ends_with_insensitive(
".ts")) {
3990 if (
FileName.ends_with_insensitive(
".proto") ||
3991 FileName.ends_with_insensitive(
".protodevel")) {
3997 if (
FileName.ends_with_insensitive(
".txtpb") ||
3998 FileName.ends_with_insensitive(
".textpb") ||
3999 FileName.ends_with_insensitive(
".pb.txt") ||
4000 FileName.ends_with_insensitive(
".textproto") ||
4001 FileName.ends_with_insensitive(
".asciipb")) {
4004 if (
FileName.ends_with_insensitive(
".td"))
4006 if (
FileName.ends_with_insensitive(
".cs"))
4008 if (
FileName.ends_with_insensitive(
".json"))
4010 if (
FileName.ends_with_insensitive(
".sv") ||
4011 FileName.ends_with_insensitive(
".svh") ||
4012 FileName.ends_with_insensitive(
".v") ||
4013 FileName.ends_with_insensitive(
".vh")) {
4022 auto Extension = llvm::sys::path::extension(
FileName);
4025 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4030 if (Guesser.isObjC())
4034 return GuessedLanguage;
4042llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4045 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4046 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4047 FS->getBufferForFile(ConfigFile.str());
4048 if (
auto EC =
Text.getError())
4058 StringRef FallbackStyleName, StringRef Code,
4059 llvm::vfs::FileSystem *FS,
4060 bool AllowUnknownOptions,
4061 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4069 if (StyleName.starts_with(
"{")) {
4071 StringRef Source =
"<command-line>";
4072 if (std::error_code ec =
4074 AllowUnknownOptions, DiagHandler)) {
4081 ChildFormatTextToApply.emplace_back(
4082 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4086 FS = llvm::vfs::getRealFileSystem().get();
4091 StyleName.starts_with_insensitive(
"file:")) {
4092 auto ConfigFile = StyleName.substr(5);
4093 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4096 if (
auto EC =
Text.getError()) {
4101 LLVM_DEBUG(llvm::dbgs()
4102 <<
"Using configuration file " << ConfigFile <<
"\n");
4110 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4124 if (std::error_code EC = FS->makeAbsolute(
Path))
4130 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4132 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4133 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4136 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4139 static_cast<void>(EC);
4145 FilesToLookFor.push_back(
".clang-format");
4146 FilesToLookFor.push_back(
"_clang-format");
4149 for (StringRef Directory =
Path; !Directory.empty();
4150 Directory = llvm::sys::path::parent_path(Directory)) {
4151 auto Status = FS->status(Directory);
4153 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4157 for (
const auto &F : FilesToLookFor) {
4160 llvm::sys::path::append(ConfigFile, F);
4161 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4163 Status = FS->status(ConfigFile);
4165 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4169 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4172 if (
auto EC =
Text.getError()) {
4177 if (!UnsuitableConfigFiles.empty())
4178 UnsuitableConfigFiles.append(
", ");
4179 UnsuitableConfigFiles.append(ConfigFile);
4183 LLVM_DEBUG(llvm::dbgs()
4184 <<
"Using configuration file " << ConfigFile <<
"\n");
4187 if (!ChildFormatTextToApply.empty()) {
4188 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4189 applyChildFormatTexts(&Style);
4194 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4199 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4209 if (!UnsuitableConfigFiles.empty()) {
4212 UnsuitableConfigFiles);
4215 if (!ChildFormatTextToApply.empty()) {
4216 LLVM_DEBUG(llvm::dbgs()
4217 <<
"Applying child configurations on fallback style\n");
4218 applyChildFormatTexts(&FallbackStyle);
4221 return FallbackStyle;
4225 if (Comment == (On ?
"/* clang-format on */" :
"/* clang-format off */"))
4228 static const char ClangFormatOn[] =
"// clang-format on";
4229 static const char ClangFormatOff[] =
"// clang-format off";
4230 const unsigned Size = (On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4232 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4233 (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...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file implements a sorter for JavaScript ES6 imports.
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
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).
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.
@ Result
The result type of a method or function.
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)
static void enumeration(IO &IO, FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value)