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",
1046 IO.mapOptional(
"IfMacros", Style.
IfMacros);
1050 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",
1095 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1097 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1099 IO.mapOptional(
"PenaltyBreakScopeResolution",
1102 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1105 IO.mapOptional(
"PenaltyIndentedWhitespace",
1107 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1123 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1128 IO.mapOptional(
"RequiresExpressionIndentation",
1138 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1140 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1142 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1145 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1147 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1149 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1154 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1156 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1159 IO.mapOptional(
"SpacesBeforeTrailingComments",
1162 IO.mapOptional(
"SpacesInContainerLiterals",
1164 IO.mapOptional(
"SpacesInLineCommentPrefix",
1169 IO.mapOptional(
"Standard", Style.
Standard);
1170 IO.mapOptional(
"StatementAttributeLikeMacros",
1173 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1175 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1177 IO.mapOptional(
"TabWidth", Style.
TabWidth);
1179 IO.mapOptional(
"TypeNames", Style.
TypeNames);
1181 IO.mapOptional(
"UseTab", Style.
UseTab);
1183 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1185 IO.mapOptional(
"WhitespaceSensitiveMacros",
1187 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1196 FormatStyle::DRTBS_All) {
1199 FormatStyle::DRTBS_TopLevel) {
1206 if (BreakBeforeInheritanceComma &&
1214 if (BreakConstructorInitializersBeforeComma &&
1219 if (!IsGoogleOrChromium) {
1223 ? FormatStyle::PCIS_NextLine
1224 : FormatStyle::PCIS_CurrentLine;
1227 FormatStyle::PCIS_NextLine) {
1230 else if (!OnNextLine)
1234 if (Style.
LineEnding == FormatStyle::LE_DeriveLF) {
1235 if (!DeriveLineEnding)
1236 Style.
LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1238 Style.
LineEnding = FormatStyle::LE_DeriveCRLF;
1242 (SpacesInParentheses || SpaceInEmptyParentheses ||
1243 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1244 if (SpacesInParentheses) {
1249 SpacesInCStyleCastParentheses;
1251 SpaceInEmptyParentheses;
1256 SpacesInConditionalStatement;
1258 SpacesInCStyleCastParentheses;
1260 SpaceInEmptyParentheses;
1272template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1273 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1278 if (Index >= Seq.size()) {
1279 assert(Index == Seq.size());
1281 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1284 Template = *((
const FormatStyle *)IO.getContext());
1285 Template.
Language = FormatStyle::LK_None;
1287 Seq.resize(Index + 1, Template);
1307 return llvm::make_error<llvm::StringError>(Message,
1308 llvm::inconvertibleErrorCode());
1312 return "clang-format.parse_error";
1320 return "Invalid argument";
1322 return "Unsuitable";
1324 return "trailing comma insertion cannot be used with bin packing";
1326 return "Invalid qualifier specified in QualifierOrder";
1328 return "Duplicate qualifier specified in QualifierOrder";
1330 return "Missing type in QualifierOrder";
1332 return "Missing QualifierOrder";
1334 llvm_unreachable(
"unexpected parse error");
1559 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1562 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1563 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1564 {
".*", 1, 0,
false}};
1711 {
"^<.*\\.h>", 1, 0,
false},
1712 {
"^<.*", 2, 0,
false},
1713 {
".*", 3, 0,
false}};
1753 "PARSE_PARTIAL_TEXT_PROTO",
1757 "ParseTextProtoOrDie",
1759 "ParsePartialTestProto",
1871 "com.google.android.apps.chrome",
1890 return ChromiumStyle;
1916 return MozillaStyle;
2011 if (Name.equals_insensitive(
"llvm"))
2013 else if (Name.equals_insensitive(
"chromium"))
2015 else if (Name.equals_insensitive(
"mozilla"))
2017 else if (Name.equals_insensitive(
"google"))
2019 else if (Name.equals_insensitive(
"webkit"))
2021 else if (Name.equals_insensitive(
"gnu"))
2023 else if (Name.equals_insensitive(
"microsoft"))
2025 else if (Name.equals_insensitive(
"clang-format"))
2027 else if (Name.equals_insensitive(
"none"))
2029 else if (Name.equals_insensitive(
"inheritparentconfig"))
2045 if (Qualifier ==
"type")
2049 if (token == tok::identifier)
2054 std::set<std::string> UniqueQualifiers(Style->
QualifierOrder.begin(),
2057 LLVM_DEBUG(llvm::dbgs()
2059 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2072 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2073 void *DiagHandlerCtxt) {
2077 if (Config.getBuffer().trim().empty())
2079 Style->StyleSet.
Clear();
2080 std::vector<FormatStyle> Styles;
2081 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2087 Input.setContext(Style);
2088 Input.setAllowUnknownKeys(AllowUnknownOptions);
2091 return Input.error();
2093 for (
unsigned i = 0; i < Styles.size(); ++i) {
2098 for (
unsigned j = 0; j < i; ++j) {
2100 LLVM_DEBUG(llvm::dbgs()
2101 <<
"Duplicate languages in the config file on positions "
2102 << j <<
" and " << i <<
"\n");
2111 bool LanguageFound =
false;
2112 for (
const FormatStyle &Style : llvm::reverse(Styles)) {
2114 StyleSet.
Add(Style);
2116 LanguageFound =
true;
2118 if (!LanguageFound) {
2123 StyleSet.
Add(std::move(DefaultStyle));
2138 llvm::raw_string_ostream Stream(
Text);
2139 llvm::yaml::Output Output(Stream);
2146 Output << NonConstStyle;
2148 return Stream.str();
2151std::optional<FormatStyle>
2154 return std::nullopt;
2156 if (It == Styles->end())
2157 return std::nullopt;
2159 Style.StyleSet = *
this;
2165 "Cannot add a style for LK_None to a StyleSet");
2167 !Style.StyleSet.Styles &&
2168 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2170 Styles = std::make_shared<MapType>();
2171 (*Styles)[Style.
Language] = std::move(Style);
2176std::optional<FormatStyle>
2188 std::pair<tooling::Replacements, unsigned>
2189 analyze(TokenAnnotator &Annotator,
2191 FormatTokenLexer &Tokens)
override {
2192 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2194 removeParens(AnnotatedLines, Result);
2199 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2200 tooling::Replacements &Result) {
2201 const auto &SourceMgr =
Env.getSourceManager();
2202 for (
auto *Line : Lines) {
2203 if (!Line->Children.empty())
2204 removeParens(Line->Children, Result);
2205 if (!Line->Affected)
2207 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2208 Token = Token->Next) {
2209 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2211 auto *Next = Token->Next;
2212 assert(Next && Next->isNot(tok::eof));
2213 SourceLocation Start;
2214 if (Next->NewlinesBefore == 0) {
2215 Start = Token->Tok.getLocation();
2216 Next->WhitespaceRange = Token->WhitespaceRange;
2218 Start = Token->WhitespaceRange.getBegin();
2221 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2222 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
" ")));
2228class BracesInserter :
public TokenAnalyzer {
2231 : TokenAnalyzer(
Env, Style) {}
2233 std::pair<tooling::Replacements, unsigned>
2234 analyze(TokenAnnotator &Annotator,
2235 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2236 FormatTokenLexer &Tokens)
override {
2237 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2238 tooling::Replacements Result;
2239 insertBraces(AnnotatedLines, Result);
2244 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2245 tooling::Replacements &Result) {
2246 const auto &SourceMgr =
Env.getSourceManager();
2247 int OpeningBraceSurplus = 0;
2248 for (AnnotatedLine *Line : Lines) {
2249 if (!Line->Children.empty())
2250 insertBraces(Line->Children, Result);
2251 if (!Line->Affected && OpeningBraceSurplus == 0)
2253 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2254 Token = Token->Next) {
2255 int BraceCount = Token->BraceCount;
2256 if (BraceCount == 0)
2259 if (BraceCount < 0) {
2260 assert(BraceCount == -1);
2261 if (!Line->Affected)
2263 Brace = Token->is(tok::comment) ?
"\n{" :
"{";
2264 ++OpeningBraceSurplus;
2266 if (OpeningBraceSurplus == 0)
2268 if (OpeningBraceSurplus < BraceCount)
2269 BraceCount = OpeningBraceSurplus;
2270 Brace =
'\n' + std::string(BraceCount,
'}');
2271 OpeningBraceSurplus -= BraceCount;
2273 Token->BraceCount = 0;
2274 const auto Start = Token->Tok.getEndLoc();
2275 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2278 assert(OpeningBraceSurplus == 0);
2282class BracesRemover :
public TokenAnalyzer {
2285 : TokenAnalyzer(
Env, Style) {}
2287 std::pair<tooling::Replacements, unsigned>
2288 analyze(TokenAnnotator &Annotator,
2289 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2290 FormatTokenLexer &Tokens)
override {
2291 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2292 tooling::Replacements Result;
2293 removeBraces(AnnotatedLines, Result);
2298 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2299 tooling::Replacements &Result) {
2300 const auto &SourceMgr =
Env.getSourceManager();
2301 const auto *End = Lines.end();
2302 for (
const auto *I = Lines.begin(); I != End; ++I) {
2303 const auto &Line = *I;
2304 if (!Line->Children.empty())
2305 removeBraces(Line->Children, Result);
2306 if (!Line->Affected)
2308 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2309 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2310 Token = Token->Next) {
2311 if (!Token->Optional)
2313 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2315 auto *Next = Token->Next;
2316 assert(Next || Token == Line->Last);
2317 if (!Next && NextLine)
2318 Next = NextLine->First;
2319 SourceLocation Start;
2320 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2321 Start = Token->Tok.getLocation();
2322 Next->WhitespaceRange = Token->WhitespaceRange;
2324 Start = Token->WhitespaceRange.getBegin();
2327 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2328 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2334class SemiRemover :
public TokenAnalyzer {
2337 : TokenAnalyzer(
Env, Style) {}
2339 std::pair<tooling::Replacements, unsigned>
2340 analyze(TokenAnnotator &Annotator,
2341 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2342 FormatTokenLexer &Tokens)
override {
2343 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2344 tooling::Replacements Result;
2345 removeSemi(Annotator, AnnotatedLines, Result);
2350 void removeSemi(TokenAnnotator &Annotator,
2351 SmallVectorImpl<AnnotatedLine *> &Lines,
2352 tooling::Replacements &Result) {
2353 auto PrecededByFunctionRBrace = [](
const FormatToken &Tok) {
2354 const auto *Prev = Tok.Previous;
2355 if (!Prev || Prev->isNot(tok::r_brace))
2357 const auto *LBrace = Prev->MatchingParen;
2358 return LBrace && LBrace->is(TT_FunctionLBrace);
2360 const auto &SourceMgr =
Env.getSourceManager();
2361 const auto *End = Lines.end();
2362 for (
const auto *I = Lines.begin(); I != End; ++I) {
2363 const auto &Line = *I;
2364 if (!Line->Children.empty())
2365 removeSemi(Annotator, Line->Children, Result);
2366 if (!Line->Affected)
2368 Annotator.calculateFormattingInformation(*Line);
2369 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2370 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2371 Token = Token->Next) {
2372 if (Token->isNot(tok::semi) ||
2373 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2376 auto *Next = Token->Next;
2377 assert(Next || Token == Line->Last);
2378 if (!Next && NextLine)
2379 Next = NextLine->First;
2380 SourceLocation Start;
2381 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2382 Start = Token->Tok.getLocation();
2383 Next->WhitespaceRange = Token->WhitespaceRange;
2385 Start = Token->WhitespaceRange.getBegin();
2388 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2389 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2395class JavaScriptRequoter :
public TokenAnalyzer {
2397 JavaScriptRequoter(
const Environment &
Env,
const FormatStyle &Style)
2398 : TokenAnalyzer(
Env, Style) {}
2400 std::pair<tooling::Replacements, unsigned>
2401 analyze(TokenAnnotator &Annotator,
2402 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2403 FormatTokenLexer &Tokens)
override {
2404 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2405 tooling::Replacements Result;
2406 requoteJSStringLiteral(AnnotatedLines, Result);
2413 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2414 tooling::Replacements &Result) {
2415 for (AnnotatedLine *Line : Lines) {
2416 requoteJSStringLiteral(Line->Children, Result);
2417 if (!Line->Affected)
2419 for (FormatToken *FormatTok = Line->First; FormatTok;
2420 FormatTok = FormatTok->Next) {
2421 StringRef Input = FormatTok->TokenText;
2422 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2426 !Input.starts_with(
"\"")) ||
2428 !Input.starts_with(
"\'"))) {
2434 SourceLocation Start = FormatTok->Tok.getLocation();
2435 auto Replace = [&](SourceLocation Start,
unsigned Length,
2436 StringRef ReplacementText) {
2437 auto Err = Result.add(tooling::Replacement(
2438 Env.getSourceManager(), Start, Length, ReplacementText));
2442 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2446 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2447 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2448 IsSingle ?
"'" :
"\"");
2451 bool Escaped =
false;
2452 for (
size_t i = 1; i < Input.size() - 1; i++) {
2455 if (!Escaped && i + 1 < Input.size() &&
2456 ((IsSingle && Input[i + 1] ==
'"') ||
2457 (!IsSingle && Input[i + 1] ==
'\''))) {
2460 Replace(Start.getLocWithOffset(i), 1,
"");
2467 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2469 Replace(Start.getLocWithOffset(i), 0,
"\\");
2483class Formatter :
public TokenAnalyzer {
2486 FormattingAttemptStatus *Status)
2487 : TokenAnalyzer(
Env, Style), Status(Status) {}
2489 std::pair<tooling::Replacements, unsigned>
2490 analyze(TokenAnnotator &Annotator,
2491 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2492 FormatTokenLexer &Tokens)
override {
2493 tooling::Replacements Result;
2494 deriveLocalStyle(AnnotatedLines);
2495 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2496 for (AnnotatedLine *Line : AnnotatedLines)
2497 Annotator.calculateFormattingInformation(*Line);
2498 Annotator.setCommentLineLevels(AnnotatedLines);
2500 WhitespaceManager Whitespaces(
2501 Env.getSourceManager(), Style,
2503 ? WhitespaceManager::inputUsesCRLF(
2504 Env.getSourceManager().getBufferData(
Env.getFileID()),
2505 Style.
LineEnding == FormatStyle::LE_DeriveCRLF)
2507 ContinuationIndenter
Indenter(Style, Tokens.getKeywords(),
2508 Env.getSourceManager(), Whitespaces, Encoding,
2509 BinPackInconclusiveFunctions);
2511 UnwrappedLineFormatter(&
Indenter, &Whitespaces, Style,
2512 Tokens.getKeywords(),
Env.getSourceManager(),
2514 .format(AnnotatedLines,
false,
2517 Env.getFirstStartColumn(),
2518 Env.getNextStartColumn(),
2519 Env.getLastStartColumn());
2520 for (
const auto &R : Whitespaces.generateReplacements())
2522 return std::make_pair(Result, 0);
2523 return std::make_pair(Result, Penalty);
2528 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2529 for (
const AnnotatedLine *Line : Lines) {
2530 if (hasCpp03IncompatibleFormat(Line->Children))
2532 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2533 if (!Tok->hasWhitespaceBefore()) {
2534 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2536 if (Tok->is(TT_TemplateCloser) &&
2537 Tok->Previous->is(TT_TemplateCloser)) {
2546 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2547 int AlignmentDiff = 0;
2548 for (
const AnnotatedLine *Line : Lines) {
2549 AlignmentDiff += countVariableAlignments(Line->Children);
2550 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2551 if (Tok->isNot(TT_PointerOrReference))
2554 if (
const auto *Prev = Tok->getPreviousNonComment()) {
2555 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2556 if (
const auto *Func =
2557 Prev->MatchingParen->getPreviousNonComment()) {
2558 if (
Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2559 TT_OverloadedOperator)) {
2565 bool SpaceBefore = Tok->hasWhitespaceBefore();
2566 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2567 if (SpaceBefore && !SpaceAfter)
2569 if (!SpaceBefore && SpaceAfter)
2573 return AlignmentDiff;
2577 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2578 bool HasBinPackedFunction =
false;
2579 bool HasOnePerLineFunction =
false;
2580 for (AnnotatedLine *Line : AnnotatedLines) {
2581 if (!Line->First->Next)
2583 FormatToken *Tok = Line->First->Next;
2585 if (Tok->is(PPK_BinPacked))
2586 HasBinPackedFunction =
true;
2587 if (Tok->is(PPK_OnePerLine))
2588 HasOnePerLineFunction =
true;
2594 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2595 if (NetRightCount > 0)
2597 else if (NetRightCount < 0)
2601 if (Style.
Standard == FormatStyle::LS_Auto) {
2602 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2603 ? FormatStyle::LS_Latest
2604 : FormatStyle::LS_Cpp03;
2606 BinPackInconclusiveFunctions =
2607 HasBinPackedFunction || !HasOnePerLineFunction;
2610 bool BinPackInconclusiveFunctions;
2611 FormattingAttemptStatus *Status;
2625class TrailingCommaInserter :
public TokenAnalyzer {
2627 TrailingCommaInserter(
const Environment &
Env,
const FormatStyle &Style)
2628 : TokenAnalyzer(
Env, Style) {}
2630 std::pair<tooling::Replacements, unsigned>
2631 analyze(TokenAnnotator &Annotator,
2632 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2633 FormatTokenLexer &Tokens)
override {
2634 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2635 tooling::Replacements Result;
2636 insertTrailingCommas(AnnotatedLines, Result);
2643 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2644 tooling::Replacements &Result) {
2645 for (AnnotatedLine *Line : Lines) {
2646 insertTrailingCommas(Line->Children, Result);
2647 if (!Line->Affected)
2649 for (FormatToken *FormatTok = Line->First; FormatTok;
2650 FormatTok = FormatTok->Next) {
2651 if (FormatTok->NewlinesBefore == 0)
2653 FormatToken *Matching = FormatTok->MatchingParen;
2654 if (!Matching || !FormatTok->getPreviousNonComment())
2656 if (!(FormatTok->is(tok::r_square) &&
2657 Matching->is(TT_ArrayInitializerLSquare)) &&
2658 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2661 FormatToken *Prev = FormatTok->getPreviousNonComment();
2662 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2666 SourceLocation Start =
2667 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2671 unsigned ColumnNumber =
2672 Env.getSourceManager().getSpellingColumnNumber(Start);
2677 cantFail(Result.add(
2678 tooling::Replacement(
Env.getSourceManager(), Start, 0,
",")));
2686class Cleaner :
public TokenAnalyzer {
2689 : TokenAnalyzer(
Env, Style),
2690 DeletedTokens(FormatTokenLess(
Env.getSourceManager())) {}
2693 std::pair<tooling::Replacements, unsigned>
2694 analyze(TokenAnnotator &Annotator,
2695 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2696 FormatTokenLexer &Tokens)
override {
2704 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2706 checkEmptyNamespace(AnnotatedLines);
2708 for (
auto *Line : AnnotatedLines)
2711 return {generateFixes(), 0};
2715 void cleanupLine(AnnotatedLine *Line) {
2716 for (
auto *Child : Line->Children)
2719 if (Line->Affected) {
2720 cleanupRight(Line->First, tok::comma, tok::comma);
2721 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2722 cleanupRight(Line->First, tok::l_paren, tok::comma);
2723 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2724 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2725 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2726 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2730 bool containsOnlyComments(
const AnnotatedLine &Line) {
2731 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2732 if (Tok->isNot(tok::comment))
2738 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2739 std::set<unsigned> DeletedLines;
2740 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2741 auto &Line = *AnnotatedLines[i];
2742 if (Line.startsWithNamespace())
2743 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2746 for (
auto Line : DeletedLines) {
2747 FormatToken *Tok = AnnotatedLines[Line]->First;
2759 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2760 unsigned CurrentLine,
unsigned &
NewLine,
2761 std::set<unsigned> &DeletedLines) {
2762 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2767 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2771 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2774 while (++CurrentLine < End) {
2775 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2778 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2779 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine,
NewLine,
2787 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2797 if (CurrentLine >= End)
2801 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2802 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2803 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2807 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
2808 DeletedLines.insert(i);
2817 template <
typename LeftKind,
typename RightKind>
2818 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2820 auto NextNotDeleted = [
this](
const FormatToken &Tok) -> FormatToken * {
2821 for (
auto *Res = Tok.Next; Res; Res = Res->Next) {
2822 if (Res->isNot(tok::comment) &&
2823 DeletedTokens.find(Res) == DeletedTokens.end()) {
2829 for (
auto *Left = Start;
Left;) {
2830 auto *
Right = NextNotDeleted(*Left);
2834 deleteToken(DeleteLeft ? Left : Right);
2835 for (
auto *Tok =
Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2846 template <
typename LeftKind,
typename RightKind>
2847 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2848 cleanupPair(Start, LK, RK,
true);
2851 template <
typename LeftKind,
typename RightKind>
2852 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2853 cleanupPair(Start, LK, RK,
false);
2857 inline void deleteToken(FormatToken *Tok) {
2859 DeletedTokens.insert(Tok);
2862 tooling::Replacements generateFixes() {
2863 tooling::Replacements Fixes;
2864 SmallVector<FormatToken *> Tokens;
2865 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2866 std::back_inserter(Tokens));
2872 while (Idx < Tokens.size()) {
2873 unsigned St = Idx, End = Idx;
2874 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2876 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2877 Tokens[End]->Tok.getEndLoc());
2879 Fixes.add(tooling::Replacement(
Env.getSourceManager(), SR,
""));
2883 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2884 assert(
false &&
"Fixes must not conflict!");
2895 struct FormatTokenLess {
2896 FormatTokenLess(
const SourceManager &
SM) :
SM(
SM) {}
2898 bool operator()(
const FormatToken *LHS,
const FormatToken *RHS)
const {
2899 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2900 RHS->Tok.getLocation());
2906 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2909class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
2911 ObjCHeaderStyleGuesser(
const Environment &
Env,
const FormatStyle &Style)
2912 : TokenAnalyzer(
Env, Style), IsObjC(
false) {}
2914 std::pair<tooling::Replacements, unsigned>
2915 analyze(TokenAnnotator &Annotator,
2916 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2917 FormatTokenLexer &Tokens)
override {
2918 assert(Style.
Language == FormatStyle::LK_Cpp);
2919 IsObjC = guessIsObjC(
Env.getSourceManager(), AnnotatedLines,
2920 Tokens.getKeywords());
2921 tooling::Replacements Result;
2925 bool isObjC() {
return IsObjC; }
2929 guessIsObjC(
const SourceManager &SourceManager,
2930 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2931 const AdditionalKeywords &Keywords) {
2933 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2948 "FOUNDATION_EXPORT",
2949 "FOUNDATION_EXTERN",
2950 "NSAffineTransform",
2952 "NSAttributedString",
2971 "NSInvocationOperation",
2975 "NSMutableAttributedString",
2976 "NSMutableCharacterSet",
2978 "NSMutableDictionary",
2979 "NSMutableIndexSet",
2980 "NSMutableOrderedSet",
2984 "NSNumberFormatter",
2988 "NSOperationQueuePriority",
2992 "NSQualityOfService",
2995 "NSRegularExpression",
3006 "NS_ASSUME_NONNULL_BEGIN",
3011 for (
auto *Line : AnnotatedLines) {
3012 if (Line->First && (Line->First->TokenText.starts_with(
"#") ||
3013 Line->First->TokenText ==
"__pragma" ||
3014 Line->First->TokenText ==
"_Pragma")) {
3017 for (
const FormatToken *FormatTok = Line->First; FormatTok;
3018 FormatTok = FormatTok->Next) {
3019 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3020 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3021 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3023 (FormatTok->Tok.isAnyIdentifier() &&
3024 std::binary_search(std::begin(FoundationIdentifiers),
3025 std::end(FoundationIdentifiers),
3026 FormatTok->TokenText)) ||
3027 FormatTok->is(TT_ObjCStringLiteral) ||
3028 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3029 Keywords.kw_NS_ERROR_ENUM,
3030 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3031 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3032 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3034 LLVM_DEBUG(llvm::dbgs()
3035 <<
"Detected ObjC at location "
3036 << FormatTok->Tok.getLocation().printToString(
3038 <<
" token: " << FormatTok->TokenText <<
" token type: "
3043 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3060struct JavaImportDirective {
3073 for (
const auto &
Range : Ranges) {
3074 if (
Range.getOffset() < End &&
3075 Range.getOffset() +
Range.getLength() > Start) {
3089static std::pair<unsigned, unsigned>
3093 unsigned OffsetToEOL = 0;
3094 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3095 unsigned Start = Includes[Indices[i]].Offset;
3096 unsigned End = Start + Includes[Indices[i]].Text.size();
3097 if (!(Cursor >= Start && Cursor < End))
3099 CursorIndex = Indices[i];
3100 OffsetToEOL = End - Cursor;
3103 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3107 return std::make_pair(CursorIndex, OffsetToEOL);
3112 std::string NewCode;
3113 size_t Pos = 0, LastPos = 0;
3116 Pos = Code.find(
"\r\n", LastPos);
3117 if (Pos == LastPos) {
3121 if (Pos == std::string::npos) {
3122 NewCode += Code.substr(LastPos);
3125 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3127 }
while (Pos != std::string::npos);
3145 const unsigned IncludesBeginOffset = Includes.front().Offset;
3146 const unsigned IncludesEndOffset =
3147 Includes.back().Offset + Includes.back().Text.size();
3148 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3149 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3152 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3155 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3156 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3157 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3158 return std::tie(Includes[LHSI].
Priority, LHSFilenameLower,
3160 std::tie(Includes[RHSI].
Priority, RHSFilenameLower,
3164 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3172 unsigned CursorIndex;
3174 unsigned CursorToEOLOffset;
3176 std::tie(CursorIndex, CursorToEOLOffset) =
3181 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3182 [&](
unsigned LHSI,
unsigned RHSI) {
3183 return Includes[LHSI].Text.trim() ==
3184 Includes[RHSI].Text.trim();
3188 int CurrentCategory = Includes.front().Category;
3196 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3201 const auto OldCursor = Cursor ? *Cursor : 0;
3203 for (
unsigned Index : Indices) {
3204 if (!result.empty()) {
3208 CurrentCategory != Includes[Index].Category) {
3212 result += Includes[Index].Text;
3213 if (Cursor && CursorIndex == Index)
3214 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3215 CurrentCategory = Includes[Index].Category;
3218 if (Cursor && *Cursor >= IncludesEndOffset)
3219 *Cursor += result.size() - IncludesBlockSize;
3224 IncludesBeginOffset, IncludesBlockSize)))) {
3226 *Cursor = OldCursor;
3231 FileName, Includes.front().Offset, IncludesBlockSize, result));
3235 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3245 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3246 .StartsWith(
"\xEF\xBB\xBF", 3)
3248 unsigned SearchFrom = 0;
3260 bool FirstIncludeBlock =
true;
3261 bool MainIncludeFound =
false;
3262 bool FormattingOff =
false;
3265 llvm::Regex RawStringRegex(
3266 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3268 std::string RawStringTermination =
")\"";
3270 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3271 size_t Pos = SearchFrom;
3272 if (Code[SearchFrom] !=
'\n') {
3275 Pos = Code.find(
'\n', Pos);
3276 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3280 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3282 StringRef Trimmed =
Line.trim();
3287 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3288 std::string CharSequence = RawStringMatches[1].str();
3289 RawStringTermination =
")" + CharSequence +
"\"";
3290 FormattingOff =
true;
3293 if (Trimmed.contains(RawStringTermination))
3294 FormattingOff =
false;
3296 bool IsBlockComment =
false;
3299 FormattingOff =
true;
3301 FormattingOff =
false;
3302 }
else if (Trimmed.starts_with(
"/*")) {
3303 IsBlockComment =
true;
3304 Pos = Code.find(
"*/", SearchFrom + 2);
3307 const bool EmptyLineSkipped =
3313 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3314 if (!FormattingOff && !MergeWithNextLine) {
3315 if (!IsBlockComment &&
3317 StringRef IncludeName = Matches[2];
3318 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3323 Pos = Code.find(
"*/", SearchFrom);
3325 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3329 !MainIncludeFound && FirstIncludeBlock);
3331 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3333 MainIncludeFound =
true;
3334 IncludesInBlock.push_back(
3336 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3339 IncludesInBlock.clear();
3340 if (Trimmed.starts_with(
"#pragma hdrstop"))
3341 FirstIncludeBlock =
true;
3343 FirstIncludeBlock =
false;
3346 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3349 if (!MergeWithNextLine)
3351 SearchFrom = Pos + 1;
3353 if (!IncludesInBlock.empty()) {
3363 StringRef ImportIdentifier) {
3364 unsigned LongestMatchIndex =
UINT_MAX;
3365 unsigned LongestMatchLength = 0;
3368 if (ImportIdentifier.starts_with(GroupPrefix) &&
3369 GroupPrefix.length() > LongestMatchLength) {
3370 LongestMatchIndex = I;
3371 LongestMatchLength = GroupPrefix.length();
3374 return LongestMatchIndex;
3386 unsigned ImportsBeginOffset = Imports.front().Offset;
3387 unsigned ImportsEndOffset =
3388 Imports.back().Offset + Imports.back().Text.size();
3389 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3390 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3394 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3397 for (
const JavaImportDirective &Import : Imports)
3400 bool StaticImportAfterNormalImport =
3402 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3404 return std::make_tuple(!Imports[LHSI].
IsStatic ^
3405 StaticImportAfterNormalImport,
3407 std::make_tuple(!Imports[RHSI].
IsStatic ^
3408 StaticImportAfterNormalImport,
3413 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3414 [&](
unsigned LHSI,
unsigned RHSI) {
3415 return Imports[LHSI].Text == Imports[RHSI].Text;
3419 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3423 for (
unsigned Index : Indices) {
3424 if (!result.empty()) {
3426 if (CurrentIsStatic != Imports[Index].
IsStatic ||
3432 result += CommentLine;
3435 result += Imports[Index].Text;
3436 CurrentIsStatic = Imports[Index].IsStatic;
3443 Imports.front().Offset, ImportsBlockSize)))) {
3448 ImportsBlockSize, result));
3452 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3459const char JavaImportRegexPattern[] =
3460 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3469 unsigned SearchFrom = 0;
3470 llvm::Regex ImportRegex(JavaImportRegexPattern);
3475 bool FormattingOff =
false;
3478 auto Pos = Code.find(
'\n', SearchFrom);
3480 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3482 StringRef Trimmed =
Line.trim();
3484 FormattingOff =
true;
3486 FormattingOff =
false;
3488 if (ImportRegex.match(
Line, &Matches)) {
3489 if (FormattingOff) {
3494 StringRef
Static = Matches[1];
3497 if (
Static.contains(
"static"))
3499 ImportsInBlock.push_back(
3502 }
else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3507 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3509 SearchFrom = Pos + 1;
3511 if (!ImportsInBlock.empty())
3520 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3523bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
3527 StringRef
FileName,
unsigned *Cursor) {
3545template <
typename T>
3550 if (Replaces.
empty())
3553 auto NewCode = applyAllReplacements(Code, Replaces);
3555 return NewCode.takeError();
3560 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
3562 return Replaces.
merge(FormatReplaces);
3571 std::vector<tooling::Range> Ranges,
3575 auto SortedReplaces =
3577 if (!SortedReplaces)
3578 return SortedReplaces.takeError();
3582 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
3583 std::vector<tooling::Range> Ranges,
3598inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
3599 return Replace.getOffset() ==
UINT_MAX && Replace.getLength() == 1;
3603tooling::Replacements
3604fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
3609 tooling::Replacements HeaderInsertions;
3610 std::set<StringRef> HeadersToDelete;
3611 tooling::Replacements
Result;
3612 for (
const auto &R : Replaces) {
3613 if (isHeaderInsertion(R)) {
3616 consumeError(HeaderInsertions.add(R));
3617 }
else if (isHeaderDeletion(R)) {
3618 HeadersToDelete.insert(R.getReplacementText());
3619 }
else if (R.getOffset() ==
UINT_MAX) {
3620 llvm::errs() <<
"Insertions other than header #include insertion are "
3622 << R.getReplacementText() <<
"\n";
3624 consumeError(
Result.add(R));
3627 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3630 StringRef
FileName = Replaces.begin()->getFilePath();
3633 for (
const auto &Header : HeadersToDelete) {
3634 tooling::Replacements Replaces =
3635 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
3636 for (
const auto &R : Replaces) {
3637 auto Err =
Result.add(R);
3640 llvm::errs() <<
"Failed to add header deletion replacement for "
3641 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
3646 SmallVector<StringRef, 4> Matches;
3647 for (
const auto &R : HeaderInsertions) {
3651 assert(Matched &&
"Header insertion replacement must have replacement text "
3654 auto IncludeName = Matches[2];
3656 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
3659 auto Err =
Result.add(*Replace);
3661 consumeError(std::move(Err));
3662 unsigned NewOffset =
3663 Result.getShiftedCodePosition(Replace->getOffset());
3664 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
3665 Replace->getReplacementText());
3675Expected<tooling::Replacements>
3680 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
3687 fixCppIncludeInsertions(Code, Replaces, Style);
3692std::pair<tooling::Replacements, unsigned>
3695 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
3706 case FormatStyle::RCPS_SingleLine:
3707 case FormatStyle::RCPS_WithPreceding:
3723 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
3724 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3725 NextStartColumn, LastStartColumn);
3730 Formatter(*
Env, Style, Status).process().first;
3732 Replaces = Replaces.
merge(
3735 if (applyAllReplacements(Code, Replaces))
3736 return {Replaces, 0};
3740 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3741 NextStartColumn, LastStartColumn);
3745 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3755 if (Style.
isCpp()) {
3762 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3763 return ParensRemover(
Env, S).process(
true);
3769 S.InsertBraces =
true;
3770 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3771 return BracesInserter(
Env, S).process(
true);
3777 S.RemoveBracesLLVM =
true;
3778 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3779 return BracesRemover(
Env, S).process(
true);
3785 S.RemoveSemicolon =
true;
3786 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3787 return SemiRemover(
Env, S).process();
3810 if (Style.
Language == FormatStyle::LK_ObjC &&
3820 return JavaScriptRequoter(
Env, Expanded).process(
true);
3825 return Formatter(
Env, Expanded, Status).process();
3831 return TrailingCommaInserter(
Env, Expanded).process();
3835 std::optional<std::string> CurrentCode;
3837 unsigned Penalty = 0;
3838 for (
size_t I = 0,
E = Passes.size(); I <
E; ++I) {
3839 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3840 auto NewCode = applyAllReplacements(
3841 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3843 Fixes = Fixes.
merge(PassFixes.first);
3844 Penalty += PassFixes.second;
3846 CurrentCode = std::move(*NewCode);
3847 Env = Environment::make(
3849 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3850 FirstStartColumn, NextStartColumn, LastStartColumn);
3863 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3864 if (OriginalCode != Fix.getReplacementText()) {
3865 auto Err = NonNoOpFixes.
add(Fix);
3867 llvm::errs() <<
"Error adding replacements : "
3868 <<
toString(std::move(Err)) <<
"\n";
3872 Fixes = std::move(NonNoOpFixes);
3875 return {Fixes, Penalty};
3899 return Cleaner(*
Env, Style).process().first;
3904 StringRef
FileName,
bool *IncompleteFormat) {
3907 if (!Status.FormatComplete)
3908 *IncompleteFormat =
true;
3940 LangOpts.CPlusPlus = 1;
3951 LangOpts.LineComment = 1;
3952 LangOpts.CXXOperatorNames = Style.
isCpp();
3955 LangOpts.MicrosoftExt = 1;
3956 LangOpts.DeclSpecKeyword = 1;
3962 "Set coding style. <string> can be:\n"
3963 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3964 " Mozilla, WebKit.\n"
3965 "2. 'file' to load style configuration from a\n"
3966 " .clang-format file in one of the parent directories\n"
3967 " of the source file (for stdin, see --assume-filename).\n"
3968 " If no .clang-format file is found, falls back to\n"
3969 " --fallback-style.\n"
3970 " --style=file is the default.\n"
3971 "3. 'file:<format_file_path>' to explicitly specify\n"
3972 " the configuration file.\n"
3973 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3974 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3979 if (
FileName.ends_with_insensitive(
".js") ||
3980 FileName.ends_with_insensitive(
".mjs") ||
3981 FileName.ends_with_insensitive(
".cjs") ||
3982 FileName.ends_with_insensitive(
".ts")) {
3987 if (
FileName.ends_with_insensitive(
".proto") ||
3988 FileName.ends_with_insensitive(
".protodevel")) {
3994 if (
FileName.ends_with_insensitive(
".txtpb") ||
3995 FileName.ends_with_insensitive(
".textpb") ||
3996 FileName.ends_with_insensitive(
".pb.txt") ||
3997 FileName.ends_with_insensitive(
".textproto") ||
3998 FileName.ends_with_insensitive(
".asciipb")) {
4001 if (
FileName.ends_with_insensitive(
".td"))
4003 if (
FileName.ends_with_insensitive(
".cs"))
4005 if (
FileName.ends_with_insensitive(
".json"))
4007 if (
FileName.ends_with_insensitive(
".sv") ||
4008 FileName.ends_with_insensitive(
".svh") ||
4009 FileName.ends_with_insensitive(
".v") ||
4010 FileName.ends_with_insensitive(
".vh")) {
4019 auto Extension = llvm::sys::path::extension(
FileName);
4022 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4027 if (Guesser.isObjC())
4031 return GuessedLanguage;
4039llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4042 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4043 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4044 FS->getBufferForFile(ConfigFile.str());
4045 if (
auto EC =
Text.getError())
4055 StringRef FallbackStyleName, StringRef Code,
4056 llvm::vfs::FileSystem *FS,
4057 bool AllowUnknownOptions,
4058 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4066 if (StyleName.starts_with(
"{")) {
4068 StringRef Source =
"<command-line>";
4069 if (std::error_code ec =
4071 AllowUnknownOptions, DiagHandler)) {
4078 ChildFormatTextToApply.emplace_back(
4079 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4083 FS = llvm::vfs::getRealFileSystem().get();
4088 StyleName.starts_with_insensitive(
"file:")) {
4089 auto ConfigFile = StyleName.substr(5);
4090 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4093 if (
auto EC =
Text.getError()) {
4098 LLVM_DEBUG(llvm::dbgs()
4099 <<
"Using configuration file " << ConfigFile <<
"\n");
4107 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4121 if (std::error_code EC = FS->makeAbsolute(
Path))
4127 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4129 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4130 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4133 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4136 static_cast<void>(EC);
4142 FilesToLookFor.push_back(
".clang-format");
4143 FilesToLookFor.push_back(
"_clang-format");
4146 for (StringRef Directory =
Path; !Directory.empty();
4147 Directory = llvm::sys::path::parent_path(Directory)) {
4148 auto Status = FS->status(Directory);
4150 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4154 for (
const auto &F : FilesToLookFor) {
4157 llvm::sys::path::append(ConfigFile, F);
4158 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4160 Status = FS->status(ConfigFile);
4162 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4166 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4169 if (
auto EC =
Text.getError()) {
4174 if (!UnsuitableConfigFiles.empty())
4175 UnsuitableConfigFiles.append(
", ");
4176 UnsuitableConfigFiles.append(ConfigFile);
4180 LLVM_DEBUG(llvm::dbgs()
4181 <<
"Using configuration file " << ConfigFile <<
"\n");
4184 if (!ChildFormatTextToApply.empty()) {
4185 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4186 applyChildFormatTexts(&Style);
4191 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4196 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4206 if (!UnsuitableConfigFiles.empty()) {
4209 UnsuitableConfigFiles);
4212 if (!ChildFormatTextToApply.empty()) {
4213 LLVM_DEBUG(llvm::dbgs()
4214 <<
"Applying child configurations on fallback style\n");
4215 applyChildFormatTexts(&FallbackStyle);
4218 return FallbackStyle;
4222 if (Comment == (On ?
"/* clang-format on */" :
"/* clang-format off */"))
4225 static const char ClangFormatOn[] =
"// clang-format on";
4226 static const char ClangFormatOff[] =
"// clang-format off";
4227 const unsigned Size = (On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4229 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4230 (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)