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",
1059 IO.mapOptional(
"IndentWrappedFunctionNames",
1071 IO.mapOptional(
"LineEnding", Style.
LineEnding);
1074 IO.mapOptional(
"Macros", Style.
Macros);
1081 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1083 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1086 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1088 IO.mapOptional(
"PackConstructorInitializers",
1091 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1094 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1096 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1098 IO.mapOptional(
"PenaltyBreakScopeResolution",
1101 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1104 IO.mapOptional(
"PenaltyIndentedWhitespace",
1106 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1122 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1127 IO.mapOptional(
"RequiresExpressionIndentation",
1137 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1139 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1141 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1144 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1146 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1148 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1153 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1155 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1158 IO.mapOptional(
"SpacesBeforeTrailingComments",
1161 IO.mapOptional(
"SpacesInContainerLiterals",
1163 IO.mapOptional(
"SpacesInLineCommentPrefix",
1168 IO.mapOptional(
"Standard", Style.
Standard);
1169 IO.mapOptional(
"StatementAttributeLikeMacros",
1172 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1174 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1176 IO.mapOptional(
"TabWidth", Style.
TabWidth);
1178 IO.mapOptional(
"TypeNames", Style.
TypeNames);
1180 IO.mapOptional(
"UseTab", Style.
UseTab);
1182 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1184 IO.mapOptional(
"WhitespaceSensitiveMacros",
1186 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1195 FormatStyle::DRTBS_All) {
1198 FormatStyle::DRTBS_TopLevel) {
1205 if (BreakBeforeInheritanceComma &&
1213 if (BreakConstructorInitializersBeforeComma &&
1218 if (!IsGoogleOrChromium) {
1222 ? FormatStyle::PCIS_NextLine
1223 : FormatStyle::PCIS_CurrentLine;
1226 FormatStyle::PCIS_NextLine) {
1229 else if (!OnNextLine)
1233 if (Style.
LineEnding == FormatStyle::LE_DeriveLF) {
1234 if (!DeriveLineEnding)
1235 Style.
LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1237 Style.
LineEnding = FormatStyle::LE_DeriveCRLF;
1241 (SpacesInParentheses || SpaceInEmptyParentheses ||
1242 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1243 if (SpacesInParentheses) {
1248 SpacesInCStyleCastParentheses;
1250 SpaceInEmptyParentheses;
1255 SpacesInConditionalStatement;
1257 SpacesInCStyleCastParentheses;
1259 SpaceInEmptyParentheses;
1271template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1272 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1277 if (Index >= Seq.size()) {
1278 assert(Index == Seq.size());
1280 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1283 Template = *((
const FormatStyle *)IO.getContext());
1284 Template.
Language = FormatStyle::LK_None;
1286 Seq.resize(Index + 1, Template);
1306 return llvm::make_error<llvm::StringError>(Message,
1307 llvm::inconvertibleErrorCode());
1311 return "clang-format.parse_error";
1319 return "Invalid argument";
1321 return "Unsuitable";
1323 return "trailing comma insertion cannot be used with bin packing";
1325 return "Invalid qualifier specified in QualifierOrder";
1327 return "Duplicate qualifier specified in QualifierOrder";
1329 return "Missing type in QualifierOrder";
1331 return "Missing QualifierOrder";
1333 llvm_unreachable(
"unexpected parse error");
1557 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1560 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1561 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1562 {
".*", 1, 0,
false}};
1709 {
"^<.*\\.h>", 1, 0,
false},
1710 {
"^<.*", 2, 0,
false},
1711 {
".*", 3, 0,
false}};
1751 "PARSE_PARTIAL_TEXT_PROTO",
1755 "ParseTextProtoOrDie",
1757 "ParsePartialTestProto",
1869 "com.google.android.apps.chrome",
1888 return ChromiumStyle;
1914 return MozillaStyle;
2009 if (Name.equals_insensitive(
"llvm"))
2011 else if (Name.equals_insensitive(
"chromium"))
2013 else if (Name.equals_insensitive(
"mozilla"))
2015 else if (Name.equals_insensitive(
"google"))
2017 else if (Name.equals_insensitive(
"webkit"))
2019 else if (Name.equals_insensitive(
"gnu"))
2021 else if (Name.equals_insensitive(
"microsoft"))
2023 else if (Name.equals_insensitive(
"clang-format"))
2025 else if (Name.equals_insensitive(
"none"))
2027 else if (Name.equals_insensitive(
"inheritparentconfig"))
2043 if (Qualifier ==
"type")
2047 if (token == tok::identifier)
2052 std::set<std::string> UniqueQualifiers(Style->
QualifierOrder.begin(),
2055 LLVM_DEBUG(llvm::dbgs()
2057 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2070 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2071 void *DiagHandlerCtxt) {
2075 if (Config.getBuffer().trim().empty())
2077 Style->StyleSet.
Clear();
2078 std::vector<FormatStyle> Styles;
2079 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2085 Input.setContext(Style);
2086 Input.setAllowUnknownKeys(AllowUnknownOptions);
2089 return Input.error();
2091 for (
unsigned i = 0; i < Styles.size(); ++i) {
2096 for (
unsigned j = 0; j < i; ++j) {
2098 LLVM_DEBUG(llvm::dbgs()
2099 <<
"Duplicate languages in the config file on positions "
2100 << j <<
" and " << i <<
"\n");
2109 bool LanguageFound =
false;
2110 for (
const FormatStyle &Style : llvm::reverse(Styles)) {
2112 StyleSet.
Add(Style);
2114 LanguageFound =
true;
2116 if (!LanguageFound) {
2121 StyleSet.
Add(std::move(DefaultStyle));
2136 llvm::raw_string_ostream Stream(
Text);
2137 llvm::yaml::Output Output(Stream);
2144 Output << NonConstStyle;
2146 return Stream.str();
2149std::optional<FormatStyle>
2152 return std::nullopt;
2154 if (It == Styles->end())
2155 return std::nullopt;
2157 Style.StyleSet = *
this;
2163 "Cannot add a style for LK_None to a StyleSet");
2165 !Style.StyleSet.Styles &&
2166 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2168 Styles = std::make_shared<MapType>();
2169 (*Styles)[Style.
Language] = std::move(Style);
2174std::optional<FormatStyle>
2186 std::pair<tooling::Replacements, unsigned>
2187 analyze(TokenAnnotator &Annotator,
2189 FormatTokenLexer &Tokens)
override {
2190 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2192 removeParens(AnnotatedLines, Result);
2197 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2198 tooling::Replacements &Result) {
2199 const auto &SourceMgr =
Env.getSourceManager();
2200 for (
auto *Line : Lines) {
2201 if (!Line->Children.empty())
2202 removeParens(Line->Children, Result);
2203 if (!Line->Affected)
2205 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2206 Token = Token->Next) {
2207 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))
2209 auto *Next = Token->Next;
2210 assert(Next && Next->isNot(tok::eof));
2211 SourceLocation Start;
2212 if (Next->NewlinesBefore == 0) {
2213 Start = Token->Tok.getLocation();
2214 Next->WhitespaceRange = Token->WhitespaceRange;
2216 Start = Token->WhitespaceRange.getBegin();
2219 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2220 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
" ")));
2226class BracesInserter :
public TokenAnalyzer {
2229 : TokenAnalyzer(
Env, Style) {}
2231 std::pair<tooling::Replacements, unsigned>
2232 analyze(TokenAnnotator &Annotator,
2233 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2234 FormatTokenLexer &Tokens)
override {
2235 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2236 tooling::Replacements Result;
2237 insertBraces(AnnotatedLines, Result);
2242 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2243 tooling::Replacements &Result) {
2244 const auto &SourceMgr =
Env.getSourceManager();
2245 int OpeningBraceSurplus = 0;
2246 for (AnnotatedLine *Line : Lines) {
2247 if (!Line->Children.empty())
2248 insertBraces(Line->Children, Result);
2249 if (!Line->Affected && OpeningBraceSurplus == 0)
2251 for (FormatToken *Token = Line->First; Token && !Token->Finalized;
2252 Token = Token->Next) {
2253 int BraceCount = Token->BraceCount;
2254 if (BraceCount == 0)
2257 if (BraceCount < 0) {
2258 assert(BraceCount == -1);
2259 if (!Line->Affected)
2261 Brace = Token->is(tok::comment) ?
"\n{" :
"{";
2262 ++OpeningBraceSurplus;
2264 if (OpeningBraceSurplus == 0)
2266 if (OpeningBraceSurplus < BraceCount)
2267 BraceCount = OpeningBraceSurplus;
2268 Brace =
'\n' + std::string(BraceCount,
'}');
2269 OpeningBraceSurplus -= BraceCount;
2271 Token->BraceCount = 0;
2272 const auto Start = Token->Tok.getEndLoc();
2273 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2276 assert(OpeningBraceSurplus == 0);
2280class BracesRemover :
public TokenAnalyzer {
2283 : TokenAnalyzer(
Env, Style) {}
2285 std::pair<tooling::Replacements, unsigned>
2286 analyze(TokenAnnotator &Annotator,
2287 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2288 FormatTokenLexer &Tokens)
override {
2289 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2290 tooling::Replacements Result;
2291 removeBraces(AnnotatedLines, Result);
2296 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2297 tooling::Replacements &Result) {
2298 const auto &SourceMgr =
Env.getSourceManager();
2299 const auto *End = Lines.end();
2300 for (
const auto *I = Lines.begin(); I != End; ++I) {
2301 const auto &Line = *I;
2302 if (!Line->Children.empty())
2303 removeBraces(Line->Children, Result);
2304 if (!Line->Affected)
2306 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2307 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2308 Token = Token->Next) {
2309 if (!Token->Optional)
2311 if (!Token->isOneOf(tok::l_brace, tok::r_brace))
2313 auto *Next = Token->Next;
2314 assert(Next || Token == Line->Last);
2315 if (!Next && NextLine)
2316 Next = NextLine->First;
2317 SourceLocation Start;
2318 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2319 Start = Token->Tok.getLocation();
2320 Next->WhitespaceRange = Token->WhitespaceRange;
2322 Start = Token->WhitespaceRange.getBegin();
2325 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2326 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2332class SemiRemover :
public TokenAnalyzer {
2335 : TokenAnalyzer(
Env, Style) {}
2337 std::pair<tooling::Replacements, unsigned>
2338 analyze(TokenAnnotator &Annotator,
2339 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2340 FormatTokenLexer &Tokens)
override {
2341 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2342 tooling::Replacements Result;
2343 removeSemi(Annotator, AnnotatedLines, Result);
2348 void removeSemi(TokenAnnotator &Annotator,
2349 SmallVectorImpl<AnnotatedLine *> &Lines,
2350 tooling::Replacements &Result) {
2351 auto PrecededByFunctionRBrace = [](
const FormatToken &Tok) {
2352 const auto *Prev = Tok.Previous;
2353 if (!Prev || Prev->isNot(tok::r_brace))
2355 const auto *LBrace = Prev->MatchingParen;
2356 return LBrace && LBrace->is(TT_FunctionLBrace);
2358 const auto &SourceMgr =
Env.getSourceManager();
2359 const auto *End = Lines.end();
2360 for (
const auto *I = Lines.begin(); I != End; ++I) {
2361 const auto &Line = *I;
2362 if (!Line->Children.empty())
2363 removeSemi(Annotator, Line->Children, Result);
2364 if (!Line->Affected)
2366 Annotator.calculateFormattingInformation(*Line);
2367 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2368 for (
const auto *Token = Line->First; Token && !Token->Finalized;
2369 Token = Token->Next) {
2370 if (Token->isNot(tok::semi) ||
2371 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {
2374 auto *Next = Token->Next;
2375 assert(Next || Token == Line->Last);
2376 if (!Next && NextLine)
2377 Next = NextLine->First;
2378 SourceLocation Start;
2379 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2380 Start = Token->Tok.getLocation();
2381 Next->WhitespaceRange = Token->WhitespaceRange;
2383 Start = Token->WhitespaceRange.getBegin();
2386 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
2387 cantFail(Result.add(tooling::Replacement(SourceMgr,
Range,
"")));
2393class JavaScriptRequoter :
public TokenAnalyzer {
2395 JavaScriptRequoter(
const Environment &
Env,
const FormatStyle &Style)
2396 : TokenAnalyzer(
Env, Style) {}
2398 std::pair<tooling::Replacements, unsigned>
2399 analyze(TokenAnnotator &Annotator,
2400 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2401 FormatTokenLexer &Tokens)
override {
2402 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2403 tooling::Replacements Result;
2404 requoteJSStringLiteral(AnnotatedLines, Result);
2411 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2412 tooling::Replacements &Result) {
2413 for (AnnotatedLine *Line : Lines) {
2414 requoteJSStringLiteral(Line->Children, Result);
2415 if (!Line->Affected)
2417 for (FormatToken *FormatTok = Line->First; FormatTok;
2418 FormatTok = FormatTok->Next) {
2419 StringRef Input = FormatTok->TokenText;
2420 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2424 !Input.starts_with(
"\"")) ||
2426 !Input.starts_with(
"\'"))) {
2432 SourceLocation Start = FormatTok->Tok.getLocation();
2433 auto Replace = [&](SourceLocation Start,
unsigned Length,
2434 StringRef ReplacementText) {
2435 auto Err = Result.add(tooling::Replacement(
2436 Env.getSourceManager(), Start, Length, ReplacementText));
2440 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2444 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2445 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2446 IsSingle ?
"'" :
"\"");
2449 bool Escaped =
false;
2450 for (
size_t i = 1; i < Input.size() - 1; i++) {
2453 if (!Escaped && i + 1 < Input.size() &&
2454 ((IsSingle && Input[i + 1] ==
'"') ||
2455 (!IsSingle && Input[i + 1] ==
'\''))) {
2458 Replace(Start.getLocWithOffset(i), 1,
"");
2465 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2467 Replace(Start.getLocWithOffset(i), 0,
"\\");
2481class Formatter :
public TokenAnalyzer {
2484 FormattingAttemptStatus *Status)
2485 : TokenAnalyzer(
Env, Style), Status(Status) {}
2487 std::pair<tooling::Replacements, unsigned>
2488 analyze(TokenAnnotator &Annotator,
2489 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2490 FormatTokenLexer &Tokens)
override {
2491 tooling::Replacements Result;
2492 deriveLocalStyle(AnnotatedLines);
2493 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2494 for (AnnotatedLine *Line : AnnotatedLines)
2495 Annotator.calculateFormattingInformation(*Line);
2496 Annotator.setCommentLineLevels(AnnotatedLines);
2498 WhitespaceManager Whitespaces(
2499 Env.getSourceManager(), Style,
2501 ? WhitespaceManager::inputUsesCRLF(
2502 Env.getSourceManager().getBufferData(
Env.getFileID()),
2503 Style.
LineEnding == FormatStyle::LE_DeriveCRLF)
2505 ContinuationIndenter
Indenter(Style, Tokens.getKeywords(),
2506 Env.getSourceManager(), Whitespaces, Encoding,
2507 BinPackInconclusiveFunctions);
2509 UnwrappedLineFormatter(&
Indenter, &Whitespaces, Style,
2510 Tokens.getKeywords(),
Env.getSourceManager(),
2512 .format(AnnotatedLines,
false,
2515 Env.getFirstStartColumn(),
2516 Env.getNextStartColumn(),
2517 Env.getLastStartColumn());
2518 for (
const auto &R : Whitespaces.generateReplacements())
2520 return std::make_pair(Result, 0);
2521 return std::make_pair(Result, Penalty);
2526 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2527 for (
const AnnotatedLine *Line : Lines) {
2528 if (hasCpp03IncompatibleFormat(Line->Children))
2530 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2531 if (!Tok->hasWhitespaceBefore()) {
2532 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2534 if (Tok->is(TT_TemplateCloser) &&
2535 Tok->Previous->is(TT_TemplateCloser)) {
2544 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2545 int AlignmentDiff = 0;
2546 for (
const AnnotatedLine *Line : Lines) {
2547 AlignmentDiff += countVariableAlignments(Line->Children);
2548 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2549 if (Tok->isNot(TT_PointerOrReference))
2552 if (
const auto *Prev = Tok->getPreviousNonComment()) {
2553 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2554 if (
const auto *Func =
2555 Prev->MatchingParen->getPreviousNonComment()) {
2556 if (
Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2557 TT_OverloadedOperator)) {
2563 bool SpaceBefore = Tok->hasWhitespaceBefore();
2564 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2565 if (SpaceBefore && !SpaceAfter)
2567 if (!SpaceBefore && SpaceAfter)
2571 return AlignmentDiff;
2575 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2576 bool HasBinPackedFunction =
false;
2577 bool HasOnePerLineFunction =
false;
2578 for (AnnotatedLine *Line : AnnotatedLines) {
2579 if (!Line->First->Next)
2581 FormatToken *Tok = Line->First->Next;
2583 if (Tok->is(PPK_BinPacked))
2584 HasBinPackedFunction =
true;
2585 if (Tok->is(PPK_OnePerLine))
2586 HasOnePerLineFunction =
true;
2592 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2593 if (NetRightCount > 0)
2595 else if (NetRightCount < 0)
2599 if (Style.
Standard == FormatStyle::LS_Auto) {
2600 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2601 ? FormatStyle::LS_Latest
2602 : FormatStyle::LS_Cpp03;
2604 BinPackInconclusiveFunctions =
2605 HasBinPackedFunction || !HasOnePerLineFunction;
2608 bool BinPackInconclusiveFunctions;
2609 FormattingAttemptStatus *Status;
2623class TrailingCommaInserter :
public TokenAnalyzer {
2625 TrailingCommaInserter(
const Environment &
Env,
const FormatStyle &Style)
2626 : TokenAnalyzer(
Env, Style) {}
2628 std::pair<tooling::Replacements, unsigned>
2629 analyze(TokenAnnotator &Annotator,
2630 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2631 FormatTokenLexer &Tokens)
override {
2632 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2633 tooling::Replacements Result;
2634 insertTrailingCommas(AnnotatedLines, Result);
2641 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2642 tooling::Replacements &Result) {
2643 for (AnnotatedLine *Line : Lines) {
2644 insertTrailingCommas(Line->Children, Result);
2645 if (!Line->Affected)
2647 for (FormatToken *FormatTok = Line->First; FormatTok;
2648 FormatTok = FormatTok->Next) {
2649 if (FormatTok->NewlinesBefore == 0)
2651 FormatToken *Matching = FormatTok->MatchingParen;
2652 if (!Matching || !FormatTok->getPreviousNonComment())
2654 if (!(FormatTok->is(tok::r_square) &&
2655 Matching->is(TT_ArrayInitializerLSquare)) &&
2656 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2659 FormatToken *Prev = FormatTok->getPreviousNonComment();
2660 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2664 SourceLocation Start =
2665 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2669 unsigned ColumnNumber =
2670 Env.getSourceManager().getSpellingColumnNumber(Start);
2675 cantFail(Result.add(
2676 tooling::Replacement(
Env.getSourceManager(), Start, 0,
",")));
2684class Cleaner :
public TokenAnalyzer {
2687 : TokenAnalyzer(
Env, Style),
2688 DeletedTokens(FormatTokenLess(
Env.getSourceManager())) {}
2691 std::pair<tooling::Replacements, unsigned>
2692 analyze(TokenAnnotator &Annotator,
2693 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2694 FormatTokenLexer &Tokens)
override {
2702 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2704 checkEmptyNamespace(AnnotatedLines);
2706 for (
auto *Line : AnnotatedLines)
2709 return {generateFixes(), 0};
2713 void cleanupLine(AnnotatedLine *Line) {
2714 for (
auto *Child : Line->Children)
2717 if (Line->Affected) {
2718 cleanupRight(Line->First, tok::comma, tok::comma);
2719 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2720 cleanupRight(Line->First, tok::l_paren, tok::comma);
2721 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2722 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2723 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2724 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2728 bool containsOnlyComments(
const AnnotatedLine &Line) {
2729 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2730 if (Tok->isNot(tok::comment))
2736 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2737 std::set<unsigned> DeletedLines;
2738 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2739 auto &Line = *AnnotatedLines[i];
2740 if (Line.startsWithNamespace())
2741 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2744 for (
auto Line : DeletedLines) {
2745 FormatToken *Tok = AnnotatedLines[Line]->First;
2757 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2758 unsigned CurrentLine,
unsigned &
NewLine,
2759 std::set<unsigned> &DeletedLines) {
2760 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2765 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2769 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2772 while (++CurrentLine < End) {
2773 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2776 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2777 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine,
NewLine,
2785 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2795 if (CurrentLine >= End)
2799 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2800 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2801 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2805 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
2806 DeletedLines.insert(i);
2815 template <
typename LeftKind,
typename RightKind>
2816 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2818 auto NextNotDeleted = [
this](
const FormatToken &Tok) -> FormatToken * {
2819 for (
auto *Res = Tok.Next; Res; Res = Res->Next) {
2820 if (Res->isNot(tok::comment) &&
2821 DeletedTokens.find(Res) == DeletedTokens.end()) {
2827 for (
auto *Left = Start;
Left;) {
2828 auto *
Right = NextNotDeleted(*Left);
2832 deleteToken(DeleteLeft ? Left : Right);
2833 for (
auto *Tok =
Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2844 template <
typename LeftKind,
typename RightKind>
2845 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2846 cleanupPair(Start, LK, RK,
true);
2849 template <
typename LeftKind,
typename RightKind>
2850 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2851 cleanupPair(Start, LK, RK,
false);
2855 inline void deleteToken(FormatToken *Tok) {
2857 DeletedTokens.insert(Tok);
2860 tooling::Replacements generateFixes() {
2861 tooling::Replacements Fixes;
2862 SmallVector<FormatToken *> Tokens;
2863 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2864 std::back_inserter(Tokens));
2870 while (Idx < Tokens.size()) {
2871 unsigned St = Idx, End = Idx;
2872 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2874 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2875 Tokens[End]->Tok.getEndLoc());
2877 Fixes.add(tooling::Replacement(
Env.getSourceManager(), SR,
""));
2881 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2882 assert(
false &&
"Fixes must not conflict!");
2893 struct FormatTokenLess {
2894 FormatTokenLess(
const SourceManager &
SM) :
SM(
SM) {}
2896 bool operator()(
const FormatToken *LHS,
const FormatToken *RHS)
const {
2897 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2898 RHS->Tok.getLocation());
2904 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2907class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
2909 ObjCHeaderStyleGuesser(
const Environment &
Env,
const FormatStyle &Style)
2910 : TokenAnalyzer(
Env, Style), IsObjC(
false) {}
2912 std::pair<tooling::Replacements, unsigned>
2913 analyze(TokenAnnotator &Annotator,
2914 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2915 FormatTokenLexer &Tokens)
override {
2916 assert(Style.
Language == FormatStyle::LK_Cpp);
2917 IsObjC = guessIsObjC(
Env.getSourceManager(), AnnotatedLines,
2918 Tokens.getKeywords());
2919 tooling::Replacements Result;
2923 bool isObjC() {
return IsObjC; }
2927 guessIsObjC(
const SourceManager &SourceManager,
2928 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2929 const AdditionalKeywords &Keywords) {
2931 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2946 "FOUNDATION_EXPORT",
2947 "FOUNDATION_EXTERN",
2948 "NSAffineTransform",
2950 "NSAttributedString",
2969 "NSInvocationOperation",
2973 "NSMutableAttributedString",
2974 "NSMutableCharacterSet",
2976 "NSMutableDictionary",
2977 "NSMutableIndexSet",
2978 "NSMutableOrderedSet",
2982 "NSNumberFormatter",
2986 "NSOperationQueuePriority",
2990 "NSQualityOfService",
2993 "NSRegularExpression",
3004 "NS_ASSUME_NONNULL_BEGIN",
3009 for (
auto *Line : AnnotatedLines) {
3010 if (Line->First && (Line->First->TokenText.starts_with(
"#") ||
3011 Line->First->TokenText ==
"__pragma" ||
3012 Line->First->TokenText ==
"_Pragma")) {
3015 for (
const FormatToken *FormatTok = Line->First; FormatTok;
3016 FormatTok = FormatTok->Next) {
3017 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3018 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
3019 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3021 (FormatTok->Tok.isAnyIdentifier() &&
3022 std::binary_search(std::begin(FoundationIdentifiers),
3023 std::end(FoundationIdentifiers),
3024 FormatTok->TokenText)) ||
3025 FormatTok->is(TT_ObjCStringLiteral) ||
3026 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3027 Keywords.kw_NS_ERROR_ENUM,
3028 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3029 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3030 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3032 LLVM_DEBUG(llvm::dbgs()
3033 <<
"Detected ObjC at location "
3034 << FormatTok->Tok.getLocation().printToString(
3036 <<
" token: " << FormatTok->TokenText <<
" token type: "
3041 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3058struct JavaImportDirective {
3071 for (
const auto &
Range : Ranges) {
3072 if (
Range.getOffset() < End &&
3073 Range.getOffset() +
Range.getLength() > Start) {
3087static std::pair<unsigned, unsigned>
3091 unsigned OffsetToEOL = 0;
3092 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3093 unsigned Start = Includes[Indices[i]].Offset;
3094 unsigned End = Start + Includes[Indices[i]].Text.size();
3095 if (!(Cursor >= Start && Cursor < End))
3097 CursorIndex = Indices[i];
3098 OffsetToEOL = End - Cursor;
3101 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3105 return std::make_pair(CursorIndex, OffsetToEOL);
3110 std::string NewCode;
3111 size_t Pos = 0, LastPos = 0;
3114 Pos = Code.find(
"\r\n", LastPos);
3115 if (Pos == LastPos) {
3119 if (Pos == std::string::npos) {
3120 NewCode += Code.substr(LastPos);
3123 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3125 }
while (Pos != std::string::npos);
3143 const unsigned IncludesBeginOffset = Includes.front().Offset;
3144 const unsigned IncludesEndOffset =
3145 Includes.back().Offset + Includes.back().Text.size();
3146 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3147 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3150 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3153 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3154 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
3155 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
3156 return std::tie(Includes[LHSI].
Priority, LHSFilenameLower,
3158 std::tie(Includes[RHSI].
Priority, RHSFilenameLower,
3162 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3170 unsigned CursorIndex;
3172 unsigned CursorToEOLOffset;
3174 std::tie(CursorIndex, CursorToEOLOffset) =
3179 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3180 [&](
unsigned LHSI,
unsigned RHSI) {
3181 return Includes[LHSI].Text.trim() ==
3182 Includes[RHSI].Text.trim();
3186 int CurrentCategory = Includes.front().Category;
3194 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3199 const auto OldCursor = Cursor ? *Cursor : 0;
3201 for (
unsigned Index : Indices) {
3202 if (!result.empty()) {
3206 CurrentCategory != Includes[Index].Category) {
3210 result += Includes[Index].Text;
3211 if (Cursor && CursorIndex == Index)
3212 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3213 CurrentCategory = Includes[Index].Category;
3216 if (Cursor && *Cursor >= IncludesEndOffset)
3217 *Cursor += result.size() - IncludesBlockSize;
3222 IncludesBeginOffset, IncludesBlockSize)))) {
3224 *Cursor = OldCursor;
3229 FileName, Includes.front().Offset, IncludesBlockSize, result));
3233 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3243 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3244 .StartsWith(
"\xEF\xBB\xBF", 3)
3246 unsigned SearchFrom = 0;
3258 bool FirstIncludeBlock =
true;
3259 bool MainIncludeFound =
false;
3260 bool FormattingOff =
false;
3263 llvm::Regex RawStringRegex(
3264 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3266 std::string RawStringTermination =
")\"";
3268 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3269 size_t Pos = SearchFrom;
3270 if (Code[SearchFrom] !=
'\n') {
3273 Pos = Code.find(
'\n', Pos);
3274 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3278 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3280 StringRef Trimmed =
Line.trim();
3285 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3286 std::string CharSequence = RawStringMatches[1].str();
3287 RawStringTermination =
")" + CharSequence +
"\"";
3288 FormattingOff =
true;
3291 if (Trimmed.contains(RawStringTermination))
3292 FormattingOff =
false;
3294 bool IsBlockComment =
false;
3297 FormattingOff =
true;
3299 FormattingOff =
false;
3300 }
else if (Trimmed.starts_with(
"/*")) {
3301 IsBlockComment =
true;
3302 Pos = Code.find(
"*/", SearchFrom + 2);
3305 const bool EmptyLineSkipped =
3311 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3312 if (!FormattingOff && !MergeWithNextLine) {
3313 if (!IsBlockComment &&
3315 StringRef IncludeName = Matches[2];
3316 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3321 Pos = Code.find(
"*/", SearchFrom);
3323 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3327 !MainIncludeFound && FirstIncludeBlock);
3329 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3331 MainIncludeFound =
true;
3332 IncludesInBlock.push_back(
3334 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3337 IncludesInBlock.clear();
3338 if (Trimmed.starts_with(
"#pragma hdrstop"))
3339 FirstIncludeBlock =
true;
3341 FirstIncludeBlock =
false;
3344 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3347 if (!MergeWithNextLine)
3349 SearchFrom = Pos + 1;
3351 if (!IncludesInBlock.empty()) {
3361 StringRef ImportIdentifier) {
3362 unsigned LongestMatchIndex =
UINT_MAX;
3363 unsigned LongestMatchLength = 0;
3366 if (ImportIdentifier.starts_with(GroupPrefix) &&
3367 GroupPrefix.length() > LongestMatchLength) {
3368 LongestMatchIndex = I;
3369 LongestMatchLength = GroupPrefix.length();
3372 return LongestMatchIndex;
3384 unsigned ImportsBeginOffset = Imports.front().Offset;
3385 unsigned ImportsEndOffset =
3386 Imports.back().Offset + Imports.back().Text.size();
3387 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3388 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3392 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3395 for (
const JavaImportDirective &Import : Imports)
3398 bool StaticImportAfterNormalImport =
3400 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3402 return std::make_tuple(!Imports[LHSI].
IsStatic ^
3403 StaticImportAfterNormalImport,
3405 std::make_tuple(!Imports[RHSI].
IsStatic ^
3406 StaticImportAfterNormalImport,
3411 Indices.erase(std::unique(Indices.begin(), Indices.end(),
3412 [&](
unsigned LHSI,
unsigned RHSI) {
3413 return Imports[LHSI].Text == Imports[RHSI].Text;
3417 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3421 for (
unsigned Index : Indices) {
3422 if (!result.empty()) {
3424 if (CurrentIsStatic != Imports[Index].
IsStatic ||
3430 result += CommentLine;
3433 result += Imports[Index].Text;
3434 CurrentIsStatic = Imports[Index].IsStatic;
3441 Imports.front().Offset, ImportsBlockSize)))) {
3446 ImportsBlockSize, result));
3450 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3457const char JavaImportRegexPattern[] =
3458 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3467 unsigned SearchFrom = 0;
3468 llvm::Regex ImportRegex(JavaImportRegexPattern);
3473 bool FormattingOff =
false;
3476 auto Pos = Code.find(
'\n', SearchFrom);
3478 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3480 StringRef Trimmed =
Line.trim();
3482 FormattingOff =
true;
3484 FormattingOff =
false;
3486 if (ImportRegex.match(
Line, &Matches)) {
3487 if (FormattingOff) {
3492 StringRef
Static = Matches[1];
3495 if (
Static.contains(
"static"))
3497 ImportsInBlock.push_back(
3500 }
else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
3505 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3507 SearchFrom = Pos + 1;
3509 if (!ImportsInBlock.empty())
3518 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3521bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
3525 StringRef
FileName,
unsigned *Cursor) {
3543template <
typename T>
3548 if (Replaces.
empty())
3551 auto NewCode = applyAllReplacements(Code, Replaces);
3553 return NewCode.takeError();
3558 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
3560 return Replaces.
merge(FormatReplaces);
3569 std::vector<tooling::Range> Ranges,
3573 auto SortedReplaces =
3575 if (!SortedReplaces)
3576 return SortedReplaces.takeError();
3580 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
3581 std::vector<tooling::Range> Ranges,
3596inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
3597 return Replace.getOffset() ==
UINT_MAX && Replace.getLength() == 1;
3601tooling::Replacements
3602fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
3607 tooling::Replacements HeaderInsertions;
3608 std::set<StringRef> HeadersToDelete;
3609 tooling::Replacements
Result;
3610 for (
const auto &R : Replaces) {
3611 if (isHeaderInsertion(R)) {
3614 consumeError(HeaderInsertions.add(R));
3615 }
else if (isHeaderDeletion(R)) {
3616 HeadersToDelete.insert(R.getReplacementText());
3617 }
else if (R.getOffset() ==
UINT_MAX) {
3618 llvm::errs() <<
"Insertions other than header #include insertion are "
3620 << R.getReplacementText() <<
"\n";
3622 consumeError(
Result.add(R));
3625 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3628 StringRef
FileName = Replaces.begin()->getFilePath();
3631 for (
const auto &Header : HeadersToDelete) {
3632 tooling::Replacements Replaces =
3633 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
3634 for (
const auto &R : Replaces) {
3635 auto Err =
Result.add(R);
3638 llvm::errs() <<
"Failed to add header deletion replacement for "
3639 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
3644 SmallVector<StringRef, 4> Matches;
3645 for (
const auto &R : HeaderInsertions) {
3649 assert(Matched &&
"Header insertion replacement must have replacement text "
3652 auto IncludeName = Matches[2];
3654 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
3657 auto Err =
Result.add(*Replace);
3659 consumeError(std::move(Err));
3660 unsigned NewOffset =
3661 Result.getShiftedCodePosition(Replace->getOffset());
3662 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
3663 Replace->getReplacementText());
3673Expected<tooling::Replacements>
3678 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
3685 fixCppIncludeInsertions(Code, Replaces, Style);
3690std::pair<tooling::Replacements, unsigned>
3693 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
3704 case FormatStyle::RCPS_SingleLine:
3705 case FormatStyle::RCPS_WithPreceding:
3721 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
3722 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3723 NextStartColumn, LastStartColumn);
3728 Formatter(*
Env, Style, Status).process().first;
3730 Replaces = Replaces.
merge(
3733 if (applyAllReplacements(Code, Replaces))
3734 return {Replaces, 0};
3738 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3739 NextStartColumn, LastStartColumn);
3743 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3753 if (Style.
isCpp()) {
3760 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3761 return ParensRemover(
Env, S).process(
true);
3767 S.InsertBraces =
true;
3768 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3769 return BracesInserter(
Env, S).process(
true);
3775 S.RemoveBracesLLVM =
true;
3776 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3777 return BracesRemover(
Env, S).process(
true);
3783 S.RemoveSemicolon =
true;
3784 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3785 return SemiRemover(
Env, S).process();
3808 if (Style.
Language == FormatStyle::LK_ObjC &&
3818 return JavaScriptRequoter(
Env, Expanded).process(
true);
3823 return Formatter(
Env, Expanded, Status).process();
3829 return TrailingCommaInserter(
Env, Expanded).process();
3833 std::optional<std::string> CurrentCode;
3835 unsigned Penalty = 0;
3836 for (
size_t I = 0,
E = Passes.size(); I <
E; ++I) {
3837 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3838 auto NewCode = applyAllReplacements(
3839 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3841 Fixes = Fixes.
merge(PassFixes.first);
3842 Penalty += PassFixes.second;
3844 CurrentCode = std::move(*NewCode);
3845 Env = Environment::make(
3847 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3848 FirstStartColumn, NextStartColumn, LastStartColumn);
3861 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
3862 if (OriginalCode != Fix.getReplacementText()) {
3863 auto Err = NonNoOpFixes.
add(Fix);
3865 llvm::errs() <<
"Error adding replacements : "
3866 <<
toString(std::move(Err)) <<
"\n";
3870 Fixes = std::move(NonNoOpFixes);
3873 return {Fixes, Penalty};
3897 return Cleaner(*
Env, Style).process().first;
3902 StringRef
FileName,
bool *IncompleteFormat) {
3905 if (!Status.FormatComplete)
3906 *IncompleteFormat =
true;
3938 LangOpts.CPlusPlus = 1;
3949 LangOpts.LineComment = 1;
3950 LangOpts.CXXOperatorNames = Style.
isCpp();
3953 LangOpts.MicrosoftExt = 1;
3954 LangOpts.DeclSpecKeyword = 1;
3960 "Set coding style. <string> can be:\n"
3961 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
3962 " Mozilla, WebKit.\n"
3963 "2. 'file' to load style configuration from a\n"
3964 " .clang-format file in one of the parent directories\n"
3965 " of the source file (for stdin, see --assume-filename).\n"
3966 " If no .clang-format file is found, falls back to\n"
3967 " --fallback-style.\n"
3968 " --style=file is the default.\n"
3969 "3. 'file:<format_file_path>' to explicitly specify\n"
3970 " the configuration file.\n"
3971 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
3972 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3977 if (
FileName.ends_with_insensitive(
".js") ||
3978 FileName.ends_with_insensitive(
".mjs") ||
3979 FileName.ends_with_insensitive(
".cjs") ||
3980 FileName.ends_with_insensitive(
".ts")) {
3985 if (
FileName.ends_with_insensitive(
".proto") ||
3986 FileName.ends_with_insensitive(
".protodevel")) {
3992 if (
FileName.ends_with_insensitive(
".txtpb") ||
3993 FileName.ends_with_insensitive(
".textpb") ||
3994 FileName.ends_with_insensitive(
".pb.txt") ||
3995 FileName.ends_with_insensitive(
".textproto") ||
3996 FileName.ends_with_insensitive(
".asciipb")) {
3999 if (
FileName.ends_with_insensitive(
".td"))
4001 if (
FileName.ends_with_insensitive(
".cs"))
4003 if (
FileName.ends_with_insensitive(
".json"))
4005 if (
FileName.ends_with_insensitive(
".sv") ||
4006 FileName.ends_with_insensitive(
".svh") ||
4007 FileName.ends_with_insensitive(
".v") ||
4008 FileName.ends_with_insensitive(
".vh")) {
4017 auto Extension = llvm::sys::path::extension(
FileName);
4020 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4025 if (Guesser.isObjC())
4029 return GuessedLanguage;
4037llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4040 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4041 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4042 FS->getBufferForFile(ConfigFile.str());
4043 if (
auto EC =
Text.getError())
4053 StringRef FallbackStyleName, StringRef Code,
4054 llvm::vfs::FileSystem *FS,
4055 bool AllowUnknownOptions,
4056 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4064 if (StyleName.starts_with(
"{")) {
4066 StringRef Source =
"<command-line>";
4067 if (std::error_code ec =
4069 AllowUnknownOptions, DiagHandler)) {
4076 ChildFormatTextToApply.emplace_back(
4077 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4081 FS = llvm::vfs::getRealFileSystem().get();
4086 StyleName.starts_with_insensitive(
"file:")) {
4087 auto ConfigFile = StyleName.substr(5);
4088 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4091 if (
auto EC =
Text.getError()) {
4096 LLVM_DEBUG(llvm::dbgs()
4097 <<
"Using configuration file " << ConfigFile <<
"\n");
4105 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4119 if (std::error_code EC = FS->makeAbsolute(
Path))
4125 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4127 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4128 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4131 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4134 static_cast<void>(EC);
4140 FilesToLookFor.push_back(
".clang-format");
4141 FilesToLookFor.push_back(
"_clang-format");
4144 for (StringRef Directory =
Path; !Directory.empty();
4145 Directory = llvm::sys::path::parent_path(Directory)) {
4146 auto Status = FS->status(Directory);
4148 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4152 for (
const auto &F : FilesToLookFor) {
4155 llvm::sys::path::append(ConfigFile, F);
4156 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4158 Status = FS->status(ConfigFile);
4160 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4164 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4167 if (
auto EC =
Text.getError()) {
4172 if (!UnsuitableConfigFiles.empty())
4173 UnsuitableConfigFiles.append(
", ");
4174 UnsuitableConfigFiles.append(ConfigFile);
4178 LLVM_DEBUG(llvm::dbgs()
4179 <<
"Using configuration file " << ConfigFile <<
"\n");
4182 if (!ChildFormatTextToApply.empty()) {
4183 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4184 applyChildFormatTexts(&Style);
4189 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4194 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4204 if (!UnsuitableConfigFiles.empty()) {
4207 UnsuitableConfigFiles);
4210 if (!ChildFormatTextToApply.empty()) {
4211 LLVM_DEBUG(llvm::dbgs()
4212 <<
"Applying child configurations on fallback style\n");
4213 applyChildFormatTexts(&FallbackStyle);
4216 return FallbackStyle;
4220 if (Comment == (On ?
"/* clang-format on */" :
"/* clang-format off */"))
4223 static const char ClangFormatOn[] =
"// clang-format on";
4224 static const char ClangFormatOff[] =
"// clang-format off";
4225 const unsigned Size = (On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4227 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4228 (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)