25#include "llvm/ADT/Sequence.h"
28#define DEBUG_TYPE "format-formatter"
32LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat)
37struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeNoexceptSpecifierStyle> {
40 IO.enumCase(
Value,
"Never", FormatStyle::BBNSS_Never);
41 IO.enumCase(
Value,
"OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen);
42 IO.enumCase(
Value,
"Always", FormatStyle::BBNSS_Always);
46template <>
struct MappingTraits<
FormatStyle::AlignConsecutiveStyle> {
48 IO.enumCase(
Value,
"None", FormatStyle::AlignConsecutiveStyle({}));
49 IO.enumCase(
Value,
"Consecutive",
50 FormatStyle::AlignConsecutiveStyle(
55 IO.enumCase(
Value,
"AcrossEmptyLines",
56 FormatStyle::AlignConsecutiveStyle(
61 IO.enumCase(
Value,
"AcrossComments",
62 FormatStyle::AlignConsecutiveStyle(
67 IO.enumCase(
Value,
"AcrossEmptyLinesAndComments",
68 FormatStyle::AlignConsecutiveStyle(
75 IO.enumCase(
Value,
"true",
76 FormatStyle::AlignConsecutiveStyle(
81 IO.enumCase(
Value,
"false", FormatStyle::AlignConsecutiveStyle({}));
84 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &
Value) {
85 IO.mapOptional(
"Enabled",
Value.Enabled);
86 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
87 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
88 IO.mapOptional(
"AlignCompound",
Value.AlignCompound);
89 IO.mapOptional(
"AlignFunctionDeclarations",
90 Value.AlignFunctionDeclarations);
91 IO.mapOptional(
"AlignFunctionPointers",
Value.AlignFunctionPointers);
92 IO.mapOptional(
"PadOperators",
Value.PadOperators);
97struct MappingTraits<
FormatStyle::ShortCaseStatementsAlignmentStyle> {
99 FormatStyle::ShortCaseStatementsAlignmentStyle &
Value) {
100 IO.mapOptional(
"Enabled",
Value.Enabled);
101 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
102 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
103 IO.mapOptional(
"AlignCaseArrows",
Value.AlignCaseArrows);
104 IO.mapOptional(
"AlignCaseColons",
Value.AlignCaseColons);
109struct ScalarEnumerationTraits<
FormatStyle::AttributeBreakingStyle> {
111 IO.enumCase(
Value,
"Always", FormatStyle::ABS_Always);
112 IO.enumCase(
Value,
"Leave", FormatStyle::ABS_Leave);
113 IO.enumCase(
Value,
"Never", FormatStyle::ABS_Never);
118struct ScalarEnumerationTraits<
FormatStyle::ArrayInitializerAlignmentStyle> {
120 FormatStyle::ArrayInitializerAlignmentStyle &
Value) {
121 IO.enumCase(
Value,
"None", FormatStyle::AIAS_None);
122 IO.enumCase(
Value,
"Left", FormatStyle::AIAS_Left);
123 IO.enumCase(
Value,
"Right", FormatStyle::AIAS_Right);
127template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
129 IO.enumCase(
Value,
"All", FormatStyle::BOS_All);
130 IO.enumCase(
Value,
"true", FormatStyle::BOS_All);
131 IO.enumCase(
Value,
"None", FormatStyle::BOS_None);
132 IO.enumCase(
Value,
"false", FormatStyle::BOS_None);
133 IO.enumCase(
Value,
"NonAssignment", FormatStyle::BOS_NonAssignment);
138struct ScalarEnumerationTraits<
FormatStyle::BinPackParametersStyle> {
140 IO.enumCase(
Value,
"BinPack", FormatStyle::BPPS_BinPack);
141 IO.enumCase(
Value,
"OnePerLine", FormatStyle::BPPS_OnePerLine);
142 IO.enumCase(
Value,
"AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine);
145 IO.enumCase(
Value,
"true", FormatStyle::BPPS_BinPack);
146 IO.enumCase(
Value,
"false", FormatStyle::BPPS_OnePerLine);
150template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
152 IO.enumCase(
Value,
"Auto", FormatStyle::BPS_Auto);
153 IO.enumCase(
Value,
"Always", FormatStyle::BPS_Always);
154 IO.enumCase(
Value,
"Never", FormatStyle::BPS_Never);
159struct ScalarEnumerationTraits<
FormatStyle::BitFieldColonSpacingStyle> {
161 FormatStyle::BitFieldColonSpacingStyle &
Value) {
162 IO.enumCase(
Value,
"Both", FormatStyle::BFCS_Both);
163 IO.enumCase(
Value,
"None", FormatStyle::BFCS_None);
164 IO.enumCase(
Value,
"Before", FormatStyle::BFCS_Before);
165 IO.enumCase(
Value,
"After", FormatStyle::BFCS_After);
169template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
171 IO.enumCase(
Value,
"Attach", FormatStyle::BS_Attach);
172 IO.enumCase(
Value,
"Linux", FormatStyle::BS_Linux);
173 IO.enumCase(
Value,
"Mozilla", FormatStyle::BS_Mozilla);
174 IO.enumCase(
Value,
"Stroustrup", FormatStyle::BS_Stroustrup);
175 IO.enumCase(
Value,
"Allman", FormatStyle::BS_Allman);
176 IO.enumCase(
Value,
"Whitesmiths", FormatStyle::BS_Whitesmiths);
177 IO.enumCase(
Value,
"GNU", FormatStyle::BS_GNU);
178 IO.enumCase(
Value,
"WebKit", FormatStyle::BS_WebKit);
179 IO.enumCase(
Value,
"Custom", FormatStyle::BS_Custom);
183template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
184 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
185 IO.mapOptional(
"AfterCaseLabel", Wrapping.AfterCaseLabel);
186 IO.mapOptional(
"AfterClass", Wrapping.AfterClass);
187 IO.mapOptional(
"AfterControlStatement", Wrapping.AfterControlStatement);
188 IO.mapOptional(
"AfterEnum", Wrapping.AfterEnum);
189 IO.mapOptional(
"AfterExternBlock", Wrapping.AfterExternBlock);
190 IO.mapOptional(
"AfterFunction", Wrapping.AfterFunction);
191 IO.mapOptional(
"AfterNamespace", Wrapping.AfterNamespace);
192 IO.mapOptional(
"AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
193 IO.mapOptional(
"AfterStruct", Wrapping.AfterStruct);
194 IO.mapOptional(
"AfterUnion", Wrapping.AfterUnion);
195 IO.mapOptional(
"BeforeCatch", Wrapping.BeforeCatch);
196 IO.mapOptional(
"BeforeElse", Wrapping.BeforeElse);
197 IO.mapOptional(
"BeforeLambdaBody", Wrapping.BeforeLambdaBody);
198 IO.mapOptional(
"BeforeWhile", Wrapping.BeforeWhile);
199 IO.mapOptional(
"IndentBraces", Wrapping.IndentBraces);
200 IO.mapOptional(
"SplitEmptyFunction", Wrapping.SplitEmptyFunction);
201 IO.mapOptional(
"SplitEmptyRecord", Wrapping.SplitEmptyRecord);
202 IO.mapOptional(
"SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
206template <>
struct ScalarEnumerationTraits<
FormatStyle::BracketAlignmentStyle> {
208 IO.enumCase(
Value,
"Align", FormatStyle::BAS_Align);
209 IO.enumCase(
Value,
"DontAlign", FormatStyle::BAS_DontAlign);
210 IO.enumCase(
Value,
"AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
211 IO.enumCase(
Value,
"BlockIndent", FormatStyle::BAS_BlockIndent);
214 IO.enumCase(
Value,
"true", FormatStyle::BAS_Align);
215 IO.enumCase(
Value,
"false", FormatStyle::BAS_DontAlign);
220struct ScalarEnumerationTraits<
221 FormatStyle::BraceWrappingAfterControlStatementStyle> {
224 FormatStyle::BraceWrappingAfterControlStatementStyle &
Value) {
225 IO.enumCase(
Value,
"Never", FormatStyle::BWACS_Never);
226 IO.enumCase(
Value,
"MultiLine", FormatStyle::BWACS_MultiLine);
227 IO.enumCase(
Value,
"Always", FormatStyle::BWACS_Always);
230 IO.enumCase(
Value,
"false", FormatStyle::BWACS_Never);
231 IO.enumCase(
Value,
"true", FormatStyle::BWACS_Always);
236struct ScalarEnumerationTraits<
237 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
240 IO.enumCase(
Value,
"Never", FormatStyle::BBCDS_Never);
241 IO.enumCase(
Value,
"Allowed", FormatStyle::BBCDS_Allowed);
242 IO.enumCase(
Value,
"Always", FormatStyle::BBCDS_Always);
245 IO.enumCase(
Value,
"true", FormatStyle::BBCDS_Always);
246 IO.enumCase(
Value,
"false", FormatStyle::BBCDS_Allowed);
251struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeInlineASMColonStyle> {
253 FormatStyle::BreakBeforeInlineASMColonStyle &
Value) {
254 IO.enumCase(
Value,
"Never", FormatStyle::BBIAS_Never);
255 IO.enumCase(
Value,
"OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
256 IO.enumCase(
Value,
"Always", FormatStyle::BBIAS_Always);
261struct ScalarEnumerationTraits<
FormatStyle::BreakBinaryOperationsStyle> {
263 FormatStyle::BreakBinaryOperationsStyle &
Value) {
264 IO.enumCase(
Value,
"Never", FormatStyle::BBO_Never);
265 IO.enumCase(
Value,
"OnePerLine", FormatStyle::BBO_OnePerLine);
266 IO.enumCase(
Value,
"RespectPrecedence", FormatStyle::BBO_RespectPrecedence);
271struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
274 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BCIS_BeforeColon);
275 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BCIS_BeforeComma);
276 IO.enumCase(
Value,
"AfterColon", FormatStyle::BCIS_AfterColon);
281struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
283 FormatStyle::BreakInheritanceListStyle &
Value) {
284 IO.enumCase(
Value,
"BeforeColon", FormatStyle::BILS_BeforeColon);
285 IO.enumCase(
Value,
"BeforeComma", FormatStyle::BILS_BeforeComma);
286 IO.enumCase(
Value,
"AfterColon", FormatStyle::BILS_AfterColon);
287 IO.enumCase(
Value,
"AfterComma", FormatStyle::BILS_AfterComma);
292struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
294 FormatStyle::BreakTemplateDeclarationsStyle &
Value) {
295 IO.enumCase(
Value,
"Leave", FormatStyle::BTDS_Leave);
296 IO.enumCase(
Value,
"No", FormatStyle::BTDS_No);
297 IO.enumCase(
Value,
"MultiLine", FormatStyle::BTDS_MultiLine);
298 IO.enumCase(
Value,
"Yes", FormatStyle::BTDS_Yes);
301 IO.enumCase(
Value,
"false", FormatStyle::BTDS_MultiLine);
302 IO.enumCase(
Value,
"true", FormatStyle::BTDS_Yes);
306template <>
struct ScalarEnumerationTraits<
FormatStyle::DAGArgStyle> {
308 IO.enumCase(
Value,
"DontBreak", FormatStyle::DAS_DontBreak);
309 IO.enumCase(
Value,
"BreakElements", FormatStyle::DAS_BreakElements);
310 IO.enumCase(
Value,
"BreakAll", FormatStyle::DAS_BreakAll);
315struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
318 IO.enumCase(
Value,
"None", FormatStyle::DRTBS_None);
319 IO.enumCase(
Value,
"All", FormatStyle::DRTBS_All);
320 IO.enumCase(
Value,
"TopLevel", FormatStyle::DRTBS_TopLevel);
323 IO.enumCase(
Value,
"false", FormatStyle::DRTBS_None);
324 IO.enumCase(
Value,
"true", FormatStyle::DRTBS_All);
329struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
331 FormatStyle::EscapedNewlineAlignmentStyle &
Value) {
332 IO.enumCase(
Value,
"DontAlign", FormatStyle::ENAS_DontAlign);
333 IO.enumCase(
Value,
"Left", FormatStyle::ENAS_Left);
334 IO.enumCase(
Value,
"LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);
335 IO.enumCase(
Value,
"Right", FormatStyle::ENAS_Right);
338 IO.enumCase(
Value,
"true", FormatStyle::ENAS_Left);
339 IO.enumCase(
Value,
"false", FormatStyle::ENAS_Right);
344struct ScalarEnumerationTraits<
FormatStyle::EmptyLineAfterAccessModifierStyle> {
347 IO.enumCase(
Value,
"Never", FormatStyle::ELAAMS_Never);
348 IO.enumCase(
Value,
"Leave", FormatStyle::ELAAMS_Leave);
349 IO.enumCase(
Value,
"Always", FormatStyle::ELAAMS_Always);
354struct ScalarEnumerationTraits<
358 IO.enumCase(
Value,
"Never", FormatStyle::ELBAMS_Never);
359 IO.enumCase(
Value,
"Leave", FormatStyle::ELBAMS_Leave);
360 IO.enumCase(
Value,
"LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
361 IO.enumCase(
Value,
"Always", FormatStyle::ELBAMS_Always);
366struct ScalarEnumerationTraits<
FormatStyle::EnumTrailingCommaStyle> {
368 IO.enumCase(
Value,
"Leave", FormatStyle::ETC_Leave);
369 IO.enumCase(
Value,
"Insert", FormatStyle::ETC_Insert);
370 IO.enumCase(
Value,
"Remove", FormatStyle::ETC_Remove);
375struct ScalarEnumerationTraits<
FormatStyle::IndentExternBlockStyle> {
377 IO.enumCase(
Value,
"AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
378 IO.enumCase(
Value,
"Indent", FormatStyle::IEBS_Indent);
379 IO.enumCase(
Value,
"NoIndent", FormatStyle::IEBS_NoIndent);
380 IO.enumCase(
Value,
"true", FormatStyle::IEBS_Indent);
381 IO.enumCase(
Value,
"false", FormatStyle::IEBS_NoIndent);
385template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
386 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &
Base) {
387 IO.mapOptional(
"Binary",
Base.Binary);
388 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigits);
389 IO.mapOptional(
"Decimal",
Base.Decimal);
390 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigits);
391 IO.mapOptional(
"Hex",
Base.Hex);
392 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigits);
396template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
398 IO.enumCase(
Value,
"Leave", FormatStyle::JSQS_Leave);
399 IO.enumCase(
Value,
"Single", FormatStyle::JSQS_Single);
400 IO.enumCase(
Value,
"Double", FormatStyle::JSQS_Double);
404template <>
struct MappingTraits<
FormatStyle::KeepEmptyLinesStyle> {
406 IO.mapOptional(
"AtEndOfFile",
Value.AtEndOfFile);
407 IO.mapOptional(
"AtStartOfBlock",
Value.AtStartOfBlock);
408 IO.mapOptional(
"AtStartOfFile",
Value.AtStartOfFile);
412template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
414 IO.enumCase(
Value,
"C", FormatStyle::LK_C);
415 IO.enumCase(
Value,
"Cpp", FormatStyle::LK_Cpp);
416 IO.enumCase(
Value,
"Java", FormatStyle::LK_Java);
417 IO.enumCase(
Value,
"JavaScript", FormatStyle::LK_JavaScript);
418 IO.enumCase(
Value,
"ObjC", FormatStyle::LK_ObjC);
419 IO.enumCase(
Value,
"Proto", FormatStyle::LK_Proto);
420 IO.enumCase(
Value,
"TableGen", FormatStyle::LK_TableGen);
421 IO.enumCase(
Value,
"TextProto", FormatStyle::LK_TextProto);
422 IO.enumCase(
Value,
"CSharp", FormatStyle::LK_CSharp);
423 IO.enumCase(
Value,
"Json", FormatStyle::LK_Json);
424 IO.enumCase(
Value,
"Verilog", FormatStyle::LK_Verilog);
428template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
430 IO.enumCase(
Value,
"c++03", FormatStyle::LS_Cpp03);
431 IO.enumCase(
Value,
"C++03", FormatStyle::LS_Cpp03);
432 IO.enumCase(
Value,
"Cpp03", FormatStyle::LS_Cpp03);
434 IO.enumCase(
Value,
"c++11", FormatStyle::LS_Cpp11);
435 IO.enumCase(
Value,
"C++11", FormatStyle::LS_Cpp11);
437 IO.enumCase(
Value,
"c++14", FormatStyle::LS_Cpp14);
438 IO.enumCase(
Value,
"c++17", FormatStyle::LS_Cpp17);
439 IO.enumCase(
Value,
"c++20", FormatStyle::LS_Cpp20);
441 IO.enumCase(
Value,
"Latest", FormatStyle::LS_Latest);
442 IO.enumCase(
Value,
"Cpp11", FormatStyle::LS_Latest);
443 IO.enumCase(
Value,
"Auto", FormatStyle::LS_Auto);
448struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
450 FormatStyle::LambdaBodyIndentationKind &
Value) {
451 IO.enumCase(
Value,
"Signature", FormatStyle::LBI_Signature);
452 IO.enumCase(
Value,
"OuterScope", FormatStyle::LBI_OuterScope);
456template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
458 IO.enumCase(
Value,
"LF", FormatStyle::LE_LF);
459 IO.enumCase(
Value,
"CRLF", FormatStyle::LE_CRLF);
460 IO.enumCase(
Value,
"DeriveLF", FormatStyle::LE_DeriveLF);
461 IO.enumCase(
Value,
"DeriveCRLF", FormatStyle::LE_DeriveCRLF);
466struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
468 FormatStyle::NamespaceIndentationKind &
Value) {
469 IO.enumCase(
Value,
"None", FormatStyle::NI_None);
470 IO.enumCase(
Value,
"Inner", FormatStyle::NI_Inner);
471 IO.enumCase(
Value,
"All", FormatStyle::NI_All);
475template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
477 IO.enumCase(
Value,
"DontAlign", FormatStyle::OAS_DontAlign);
478 IO.enumCase(
Value,
"Align", FormatStyle::OAS_Align);
479 IO.enumCase(
Value,
"AlignAfterOperator",
480 FormatStyle::OAS_AlignAfterOperator);
483 IO.enumCase(
Value,
"true", FormatStyle::OAS_Align);
484 IO.enumCase(
Value,
"false", FormatStyle::OAS_DontAlign);
489struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
492 IO.enumCase(
Value,
"Never", FormatStyle::PCIS_Never);
493 IO.enumCase(
Value,
"BinPack", FormatStyle::PCIS_BinPack);
494 IO.enumCase(
Value,
"CurrentLine", FormatStyle::PCIS_CurrentLine);
495 IO.enumCase(
Value,
"NextLine", FormatStyle::PCIS_NextLine);
496 IO.enumCase(
Value,
"NextLineOnly", FormatStyle::PCIS_NextLineOnly);
500template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
502 IO.enumCase(
Value,
"Middle", FormatStyle::PAS_Middle);
503 IO.enumCase(
Value,
"Left", FormatStyle::PAS_Left);
504 IO.enumCase(
Value,
"Right", FormatStyle::PAS_Right);
507 IO.enumCase(
Value,
"true", FormatStyle::PAS_Left);
508 IO.enumCase(
Value,
"false", FormatStyle::PAS_Right);
513struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
515 IO.enumCase(
Value,
"None", FormatStyle::PPDIS_None);
516 IO.enumCase(
Value,
"AfterHash", FormatStyle::PPDIS_AfterHash);
517 IO.enumCase(
Value,
"BeforeHash", FormatStyle::PPDIS_BeforeHash);
522struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
524 IO.enumCase(
Value,
"Leave", FormatStyle::QAS_Leave);
525 IO.enumCase(
Value,
"Left", FormatStyle::QAS_Left);
526 IO.enumCase(
Value,
"Right", FormatStyle::QAS_Right);
527 IO.enumCase(
Value,
"Custom", FormatStyle::QAS_Custom);
532 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
533 IO.mapOptional(
"Language", Format.Language);
534 IO.mapOptional(
"Delimiters", Format.Delimiters);
535 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
536 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
537 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
541template <>
struct ScalarEnumerationTraits<
FormatStyle::ReflowCommentsStyle> {
543 IO.enumCase(
Value,
"Never", FormatStyle::RCS_Never);
544 IO.enumCase(
Value,
"IndentOnly", FormatStyle::RCS_IndentOnly);
545 IO.enumCase(
Value,
"Always", FormatStyle::RCS_Always);
547 IO.enumCase(
Value,
"false", FormatStyle::RCS_Never);
548 IO.enumCase(
Value,
"true", FormatStyle::RCS_Always);
553struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
555 IO.enumCase(
Value,
"Pointer", FormatStyle::RAS_Pointer);
556 IO.enumCase(
Value,
"Middle", FormatStyle::RAS_Middle);
557 IO.enumCase(
Value,
"Left", FormatStyle::RAS_Left);
558 IO.enumCase(
Value,
"Right", FormatStyle::RAS_Right);
563struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
565 IO.enumCase(
Value,
"Leave", FormatStyle::RPS_Leave);
566 IO.enumCase(
Value,
"MultipleParentheses",
567 FormatStyle::RPS_MultipleParentheses);
568 IO.enumCase(
Value,
"ReturnStatement", FormatStyle::RPS_ReturnStatement);
573struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
575 FormatStyle::RequiresClausePositionStyle &
Value) {
576 IO.enumCase(
Value,
"OwnLine", FormatStyle::RCPS_OwnLine);
577 IO.enumCase(
Value,
"OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace);
578 IO.enumCase(
Value,
"WithPreceding", FormatStyle::RCPS_WithPreceding);
579 IO.enumCase(
Value,
"WithFollowing", FormatStyle::RCPS_WithFollowing);
580 IO.enumCase(
Value,
"SingleLine", FormatStyle::RCPS_SingleLine);
585struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
588 IO.enumCase(
Value,
"Keyword", FormatStyle::REI_Keyword);
589 IO.enumCase(
Value,
"OuterScope", FormatStyle::REI_OuterScope);
594struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
596 IO.enumCase(
Value,
"None", FormatStyle::RTBS_None);
597 IO.enumCase(
Value,
"Automatic", FormatStyle::RTBS_Automatic);
598 IO.enumCase(
Value,
"ExceptShortType", FormatStyle::RTBS_ExceptShortType);
599 IO.enumCase(
Value,
"All", FormatStyle::RTBS_All);
600 IO.enumCase(
Value,
"TopLevel", FormatStyle::RTBS_TopLevel);
601 IO.enumCase(
Value,
"TopLevelDefinitions",
602 FormatStyle::RTBS_TopLevelDefinitions);
603 IO.enumCase(
Value,
"AllDefinitions", FormatStyle::RTBS_AllDefinitions);
608struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
610 IO.enumCase(
Value,
"Leave", FormatStyle::SDS_Leave);
611 IO.enumCase(
Value,
"Always", FormatStyle::SDS_Always);
612 IO.enumCase(
Value,
"Never", FormatStyle::SDS_Never);
616template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
618 IO.enumCase(
Value,
"Never", FormatStyle::SBS_Never);
619 IO.enumCase(
Value,
"false", FormatStyle::SBS_Never);
620 IO.enumCase(
Value,
"Always", FormatStyle::SBS_Always);
621 IO.enumCase(
Value,
"true", FormatStyle::SBS_Always);
622 IO.enumCase(
Value,
"Empty", FormatStyle::SBS_Empty);
626template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortFunctionStyle> {
628 IO.enumCase(
Value,
"None", FormatStyle::SFS_None);
629 IO.enumCase(
Value,
"false", FormatStyle::SFS_None);
630 IO.enumCase(
Value,
"All", FormatStyle::SFS_All);
631 IO.enumCase(
Value,
"true", FormatStyle::SFS_All);
632 IO.enumCase(
Value,
"Inline", FormatStyle::SFS_Inline);
633 IO.enumCase(
Value,
"InlineOnly", FormatStyle::SFS_InlineOnly);
634 IO.enumCase(
Value,
"Empty", FormatStyle::SFS_Empty);
638template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
640 IO.enumCase(
Value,
"Never", FormatStyle::SIS_Never);
641 IO.enumCase(
Value,
"WithoutElse", FormatStyle::SIS_WithoutElse);
642 IO.enumCase(
Value,
"OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
643 IO.enumCase(
Value,
"AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
646 IO.enumCase(
Value,
"Always", FormatStyle::SIS_OnlyFirstIf);
647 IO.enumCase(
Value,
"false", FormatStyle::SIS_Never);
648 IO.enumCase(
Value,
"true", FormatStyle::SIS_WithoutElse);
652template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
654 IO.enumCase(
Value,
"None", FormatStyle::SLS_None);
655 IO.enumCase(
Value,
"false", FormatStyle::SLS_None);
656 IO.enumCase(
Value,
"Empty", FormatStyle::SLS_Empty);
657 IO.enumCase(
Value,
"Inline", FormatStyle::SLS_Inline);
658 IO.enumCase(
Value,
"All", FormatStyle::SLS_All);
659 IO.enumCase(
Value,
"true", FormatStyle::SLS_All);
663template <>
struct MappingTraits<
FormatStyle::SortIncludesOptions> {
665 IO.enumCase(
Value,
"Never", FormatStyle::SortIncludesOptions({}));
666 IO.enumCase(
Value,
"CaseInsensitive",
667 FormatStyle::SortIncludesOptions({
true,
670 IO.enumCase(
Value,
"CaseSensitive",
671 FormatStyle::SortIncludesOptions({
true,
676 IO.enumCase(
Value,
"false", FormatStyle::SortIncludesOptions({}));
677 IO.enumCase(
Value,
"true",
678 FormatStyle::SortIncludesOptions({
true,
684 IO.mapOptional(
"Enabled",
Value.Enabled);
685 IO.mapOptional(
"IgnoreCase",
Value.IgnoreCase);
686 IO.mapOptional(
"IgnoreExtension",
Value.IgnoreExtension);
691struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
693 FormatStyle::SortJavaStaticImportOptions &
Value) {
694 IO.enumCase(
Value,
"Before", FormatStyle::SJSIO_Before);
695 IO.enumCase(
Value,
"After", FormatStyle::SJSIO_After);
700struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
702 FormatStyle::SortUsingDeclarationsOptions &
Value) {
703 IO.enumCase(
Value,
"Never", FormatStyle::SUD_Never);
704 IO.enumCase(
Value,
"Lexicographic", FormatStyle::SUD_Lexicographic);
705 IO.enumCase(
Value,
"LexicographicNumeric",
706 FormatStyle::SUD_LexicographicNumeric);
709 IO.enumCase(
Value,
"false", FormatStyle::SUD_Never);
710 IO.enumCase(
Value,
"true", FormatStyle::SUD_LexicographicNumeric);
715struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
718 IO.enumCase(
Value,
"Default", FormatStyle::SAPQ_Default);
719 IO.enumCase(
Value,
"Before", FormatStyle::SAPQ_Before);
720 IO.enumCase(
Value,
"After", FormatStyle::SAPQ_After);
721 IO.enumCase(
Value,
"Both", FormatStyle::SAPQ_Both);
725template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
726 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
727 IO.mapOptional(
"AfterControlStatements", Spacing.AfterControlStatements);
728 IO.mapOptional(
"AfterForeachMacros", Spacing.AfterForeachMacros);
729 IO.mapOptional(
"AfterFunctionDefinitionName",
730 Spacing.AfterFunctionDefinitionName);
731 IO.mapOptional(
"AfterFunctionDeclarationName",
732 Spacing.AfterFunctionDeclarationName);
733 IO.mapOptional(
"AfterIfMacros", Spacing.AfterIfMacros);
734 IO.mapOptional(
"AfterNot", Spacing.AfterNot);
735 IO.mapOptional(
"AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
736 IO.mapOptional(
"AfterPlacementOperator", Spacing.AfterPlacementOperator);
737 IO.mapOptional(
"AfterRequiresInClause", Spacing.AfterRequiresInClause);
738 IO.mapOptional(
"AfterRequiresInExpression",
739 Spacing.AfterRequiresInExpression);
740 IO.mapOptional(
"BeforeNonEmptyParentheses",
741 Spacing.BeforeNonEmptyParentheses);
746struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
748 IO.enumCase(
Value,
"Never", FormatStyle::SBPO_Never);
749 IO.enumCase(
Value,
"ControlStatements",
750 FormatStyle::SBPO_ControlStatements);
751 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
752 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
753 IO.enumCase(
Value,
"NonEmptyParentheses",
754 FormatStyle::SBPO_NonEmptyParentheses);
755 IO.enumCase(
Value,
"Always", FormatStyle::SBPO_Always);
756 IO.enumCase(
Value,
"Custom", FormatStyle::SBPO_Custom);
759 IO.enumCase(
Value,
"false", FormatStyle::SBPO_Never);
760 IO.enumCase(
Value,
"true", FormatStyle::SBPO_ControlStatements);
761 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
762 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
767struct ScalarEnumerationTraits<
FormatStyle::SpaceInEmptyBracesStyle> {
769 IO.enumCase(
Value,
"Always", FormatStyle::SIEB_Always);
770 IO.enumCase(
Value,
"Block", FormatStyle::SIEB_Block);
771 IO.enumCase(
Value,
"Never", FormatStyle::SIEB_Never);
775template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
777 IO.enumCase(
Value,
"Never", FormatStyle::SIAS_Never);
778 IO.enumCase(
Value,
"Always", FormatStyle::SIAS_Always);
779 IO.enumCase(
Value,
"Leave", FormatStyle::SIAS_Leave);
782 IO.enumCase(
Value,
"false", FormatStyle::SIAS_Never);
783 IO.enumCase(
Value,
"true", FormatStyle::SIAS_Always);
787template <>
struct MappingTraits<
FormatStyle::SpacesInLineComment> {
788 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
790 int signedMaximum =
static_cast<int>(Space.Maximum);
791 IO.mapOptional(
"Minimum", Space.Minimum);
792 IO.mapOptional(
"Maximum", signedMaximum);
793 Space.Maximum =
static_cast<unsigned>(signedMaximum);
795 if (Space.Maximum < std::numeric_limits<unsigned>::max())
796 Space.Minimum = std::min(Space.Minimum, Space.Maximum);
800template <>
struct MappingTraits<
FormatStyle::SpacesInParensCustom> {
801 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
802 IO.mapOptional(
"ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);
803 IO.mapOptional(
"InCStyleCasts", Spaces.InCStyleCasts);
804 IO.mapOptional(
"InConditionalStatements", Spaces.InConditionalStatements);
805 IO.mapOptional(
"InEmptyParentheses", Spaces.InEmptyParentheses);
806 IO.mapOptional(
"Other", Spaces.Other);
810template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
812 IO.enumCase(
Value,
"Never", FormatStyle::SIPO_Never);
813 IO.enumCase(
Value,
"Custom", FormatStyle::SIPO_Custom);
817template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
819 IO.enumCase(
Value,
"None", FormatStyle::TCS_None);
820 IO.enumCase(
Value,
"Wrapped", FormatStyle::TCS_Wrapped);
825struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
827 FormatStyle::TrailingCommentsAlignmentKinds &
Value) {
828 IO.enumCase(
Value,
"Leave", FormatStyle::TCAS_Leave);
829 IO.enumCase(
Value,
"Always", FormatStyle::TCAS_Always);
830 IO.enumCase(
Value,
"Never", FormatStyle::TCAS_Never);
834template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
836 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
837 IO.enumCase(
Value,
"Leave",
838 FormatStyle::TrailingCommentsAlignmentStyle(
839 {FormatStyle::TCAS_Leave, 0}));
841 IO.enumCase(
Value,
"Always",
842 FormatStyle::TrailingCommentsAlignmentStyle(
843 {FormatStyle::TCAS_Always, 0}));
845 IO.enumCase(
Value,
"Never",
846 FormatStyle::TrailingCommentsAlignmentStyle(
847 {FormatStyle::TCAS_Never, 0}));
850 IO.enumCase(
Value,
"true",
851 FormatStyle::TrailingCommentsAlignmentStyle(
852 {FormatStyle::TCAS_Always, 0}));
853 IO.enumCase(
Value,
"false",
854 FormatStyle::TrailingCommentsAlignmentStyle(
855 {FormatStyle::TCAS_Never, 0}));
859 FormatStyle::TrailingCommentsAlignmentStyle &
Value) {
860 IO.mapOptional(
"Kind",
Value.Kind);
861 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
865template <>
struct ScalarEnumerationTraits<
FormatStyle::UseTabStyle> {
867 IO.enumCase(
Value,
"Never", FormatStyle::UT_Never);
868 IO.enumCase(
Value,
"false", FormatStyle::UT_Never);
869 IO.enumCase(
Value,
"Always", FormatStyle::UT_Always);
870 IO.enumCase(
Value,
"true", FormatStyle::UT_Always);
871 IO.enumCase(
Value,
"ForIndentation", FormatStyle::UT_ForIndentation);
872 IO.enumCase(
Value,
"ForContinuationAndIndentation",
873 FormatStyle::UT_ForContinuationAndIndentation);
874 IO.enumCase(
Value,
"AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
879struct ScalarEnumerationTraits<
880 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
883 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &
Value) {
884 IO.enumCase(
Value,
"Never", FormatStyle::WNBWELS_Never);
885 IO.enumCase(
Value,
"Always", FormatStyle::WNBWELS_Always);
886 IO.enumCase(
Value,
"Leave", FormatStyle::WNBWELS_Leave);
893 IO.mapOptional(
"Language", Style.
Language);
895 StringRef BasedOnStyle;
896 if (IO.outputting()) {
897 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
898 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
899 for (StringRef StyleName : Styles) {
901 if (getPredefinedStyle(StyleName, Style.
Language, &PredefinedStyle) &&
902 Style == PredefinedStyle) {
903 BasedOnStyle = StyleName;
908 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
909 if (!BasedOnStyle.empty()) {
910 FormatStyle::LanguageKind OldLanguage = Style.
Language;
911 FormatStyle::LanguageKind Language =
913 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
914 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
932 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
933 BasedOnStyle.equals_insensitive(
"chromium");
934 bool OnCurrentLine = IsGoogleOrChromium;
935 bool OnNextLine =
true;
937 bool BreakBeforeInheritanceComma =
false;
938 bool BreakConstructorInitializersBeforeComma =
false;
940 bool DeriveLineEnding =
true;
941 bool UseCRLF =
false;
943 bool SpaceInEmptyBlock =
false;
944 bool SpaceInEmptyParentheses =
false;
945 bool SpacesInConditionalStatement =
false;
946 bool SpacesInCStyleCastParentheses =
false;
947 bool SpacesInParentheses =
false;
950 if (!IO.outputting()) {
952 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
954 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
956 IO.mapOptional(
"BreakBeforeInheritanceComma",
957 BreakBeforeInheritanceComma);
958 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
959 BreakConstructorInitializersBeforeComma);
960 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
962 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
965 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
967 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
971 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
973 IO.mapOptional(
"SpaceInEmptyBlock", SpaceInEmptyBlock);
974 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
975 IO.mapOptional(
"SpacesInConditionalStatement",
976 SpacesInConditionalStatement);
977 IO.mapOptional(
"SpacesInCStyleCastParentheses",
978 SpacesInCStyleCastParentheses);
979 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
980 IO.mapOptional(
"UseCRLF", UseCRLF);
986 IO.mapOptional(
"AlignConsecutiveAssignments",
988 IO.mapOptional(
"AlignConsecutiveBitFields",
990 IO.mapOptional(
"AlignConsecutiveDeclarations",
993 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
995 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
997 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
999 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
1004 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
1006 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
1008 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
1010 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
1012 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
1014 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
1016 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
1018 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
1020 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
1022 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
1024 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
1026 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
1028 IO.mapOptional(
"AllowShortNamespacesOnASingleLine",
1030 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
1032 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
1039 IO.mapOptional(
"BracedInitializerIndentWidth",
1042 IO.mapOptional(
"BreakAdjacentStringLiterals",
1045 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
1049 IO.mapOptional(
"BreakBeforeBinaryOperators",
1051 IO.mapOptional(
"BreakBeforeConceptDeclarations",
1054 IO.mapOptional(
"BreakBeforeInlineASMColon",
1056 IO.mapOptional(
"BreakBeforeTemplateCloser",
1058 IO.mapOptional(
"BreakBeforeTernaryOperators",
1061 IO.mapOptional(
"BreakConstructorInitializers",
1063 IO.mapOptional(
"BreakFunctionDefinitionParameters",
1067 IO.mapOptional(
"BreakTemplateDeclarations",
1072 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1078 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1080 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1083 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1087 IO.mapOptional(
"IfMacros", Style.
IfMacros);
1091 IO.mapOptional(
"IncludeIsMainSourceRegex",
1102 IO.mapOptional(
"IndentWrappedFunctionNames",
1114 IO.mapOptional(
"LineEnding", Style.
LineEnding);
1117 IO.mapOptional(
"Macros", Style.
Macros);
1118 IO.mapOptional(
"MacrosSkippedByRemoveParentheses",
1126 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1128 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1131 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1134 IO.mapOptional(
"PackConstructorInitializers",
1137 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1139 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1142 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1144 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1146 IO.mapOptional(
"PenaltyBreakScopeResolution",
1149 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1152 IO.mapOptional(
"PenaltyIndentedWhitespace",
1154 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1170 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1175 IO.mapOptional(
"RequiresExpressionIndentation",
1185 IO.mapOptional(
"SpaceAfterOperatorKeyword",
1187 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1189 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1191 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1194 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1196 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1198 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1203 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1205 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1208 IO.mapOptional(
"SpacesBeforeTrailingComments",
1211 IO.mapOptional(
"SpacesInContainerLiterals",
1213 IO.mapOptional(
"SpacesInLineCommentPrefix",
1218 IO.mapOptional(
"Standard", Style.
Standard);
1219 IO.mapOptional(
"StatementAttributeLikeMacros",
1222 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1224 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1226 IO.mapOptional(
"TabWidth", Style.
TabWidth);
1228 IO.mapOptional(
"TypeNames", Style.
TypeNames);
1230 IO.mapOptional(
"UseTab", Style.
UseTab);
1232 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1234 IO.mapOptional(
"WhitespaceSensitiveMacros",
1236 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1245 FormatStyle::DRTBS_All) {
1248 FormatStyle::DRTBS_TopLevel) {
1255 if (BreakBeforeInheritanceComma &&
1263 if (BreakConstructorInitializersBeforeComma &&
1268 if (!IsGoogleOrChromium) {
1272 ? FormatStyle::PCIS_NextLine
1273 : FormatStyle::PCIS_CurrentLine;
1276 FormatStyle::PCIS_NextLine) {
1279 else if (!OnNextLine)
1283 if (Style.
LineEnding == FormatStyle::LE_DeriveLF) {
1284 if (!DeriveLineEnding)
1285 Style.
LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;
1287 Style.
LineEnding = FormatStyle::LE_DeriveCRLF;
1292 if (SpaceInEmptyBlock &&
1298 (SpacesInParentheses || SpaceInEmptyParentheses ||
1299 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1300 if (SpacesInParentheses) {
1305 SpacesInCStyleCastParentheses;
1307 SpaceInEmptyParentheses;
1312 SpacesInConditionalStatement;
1314 SpacesInCStyleCastParentheses;
1316 SpaceInEmptyParentheses;
1328template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1329 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1334 if (Index >= Seq.size()) {
1335 assert(Index == Seq.size());
1337 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
1340 Template = *((
const FormatStyle *)IO.getContext());
1341 Template.Language = FormatStyle::LK_None;
1343 Seq.resize(Index + 1, Template);
1363 return llvm::make_error<llvm::StringError>(Message,
1364 llvm::inconvertibleErrorCode());
1368 return "clang-format.parse_error";
1376 return "Invalid argument";
1378 return "Unsuitable";
1380 return "trailing comma insertion cannot be used with bin packing";
1382 return "Invalid qualifier specified in QualifierOrder";
1384 return "Duplicate qualifier specified in QualifierOrder";
1386 return "Missing type in QualifierOrder";
1388 return "Missing QualifierOrder";
1390 llvm_unreachable(
"unexpected parse error");
1617 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1620 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1621 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1622 {
".*", 1, 0,
false}};
1703 1, std::numeric_limits<unsigned>::max()};
1777 {
"^<.*\\.h>", 1, 0,
false},
1778 {
"^<.*", 2, 0,
false},
1779 {
".*", 3, 0,
false}};
1819 "PARSE_PARTIAL_TEXT_PROTO",
1823 "ParseTextProtoOrDie",
1825 "ParsePartialTestProto",
1938 "com.google.android.apps.chrome",
1956 return ChromiumStyle;
1982 return MozillaStyle;
2077 if (Name.equals_insensitive(
"llvm"))
2079 else if (Name.equals_insensitive(
"chromium"))
2081 else if (Name.equals_insensitive(
"mozilla"))
2083 else if (Name.equals_insensitive(
"google"))
2085 else if (Name.equals_insensitive(
"webkit"))
2087 else if (Name.equals_insensitive(
"gnu"))
2089 else if (Name.equals_insensitive(
"microsoft"))
2091 else if (Name.equals_insensitive(
"clang-format"))
2093 else if (Name.equals_insensitive(
"none"))
2095 else if (Name.equals_insensitive(
"inheritparentconfig"))
2111 if (Qualifier ==
"type")
2115 if (token == tok::identifier)
2120 std::set<std::string> UniqueQualifiers(Style->
QualifierOrder.begin(),
2123 LLVM_DEBUG(llvm::dbgs()
2125 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2138 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2139 void *DiagHandlerCtxt,
bool IsDotHFile) {
2143 if (Config.getBuffer().trim().empty())
2145 Style->StyleSet.
Clear();
2146 std::vector<FormatStyle> Styles;
2147 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2153 Input.setContext(Style);
2154 Input.setAllowUnknownKeys(AllowUnknownOptions);
2157 return Input.error();
2159 for (
unsigned i = 0; i < Styles.size(); ++i) {
2164 for (
unsigned j = 0; j < i; ++j) {
2166 LLVM_DEBUG(llvm::dbgs()
2167 <<
"Duplicate languages in the config file on positions "
2168 << j <<
" and " << i <<
"\n");
2177 bool LanguageFound =
false;
2178 for (
const FormatStyle &Style : llvm::reverse(Styles)) {
2181 StyleSet.
Add(Style);
2185 LanguageFound =
true;
2189 LanguageFound =
true;
2192 if (!LanguageFound) {
2197 StyleSet.
Add(std::move(DefaultStyle));
2212 llvm::raw_string_ostream Stream(
Text);
2213 llvm::yaml::Output Output(Stream);
2220 Output << NonConstStyle;
2222 return Stream.str();
2225std::optional<FormatStyle>
2228 return std::nullopt;
2230 if (It == Styles->end()) {
2232 return std::nullopt;
2235 if (It == Styles->end())
2236 return std::nullopt;
2239 Style.StyleSet = *
this;
2245 "Cannot add a style for LK_None to a StyleSet");
2247 !Style.StyleSet.Styles &&
2248 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2250 Styles = std::make_shared<MapType>();
2251 (*Styles)[Style.
Language] = std::move(Style);
2256std::optional<FormatStyle>
2265 StringRef
Text =
"") {
2266 const auto &Tok =
Token.Tok;
2268 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {
2269 Start = Tok.getLocation();
2270 Next->WhitespaceRange =
Token.WhitespaceRange;
2272 Start =
Token.WhitespaceRange.getBegin();
2278class ParensRemover :
public TokenAnalyzer {
2281 : TokenAnalyzer(
Env, Style) {}
2283 std::pair<tooling::Replacements, unsigned>
2284 analyze(TokenAnnotator &Annotator,
2285 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2286 FormatTokenLexer &Tokens)
override {
2287 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2288 tooling::Replacements Result;
2289 removeParens(AnnotatedLines, Result);
2294 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2295 tooling::Replacements &Result) {
2296 const auto &SourceMgr =
Env.getSourceManager();
2297 for (
auto *Line : Lines) {
2298 if (!Line->Children.empty())
2299 removeParens(Line->Children, Result);
2300 if (!Line->Affected)
2302 for (
const auto *Token = Line->First; Token && !Token->
Finalized;
2303 Token = Token->
Next) {
2305 replaceToken(*Token, Token->
Next, SourceMgr, Result,
" ");
2311class BracesInserter :
public TokenAnalyzer {
2314 : TokenAnalyzer(
Env, Style) {}
2316 std::pair<tooling::Replacements, unsigned>
2317 analyze(TokenAnnotator &Annotator,
2318 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2319 FormatTokenLexer &Tokens)
override {
2320 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2321 tooling::Replacements Result;
2322 insertBraces(AnnotatedLines, Result);
2327 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2328 tooling::Replacements &Result) {
2329 const auto &SourceMgr =
Env.getSourceManager();
2330 int OpeningBraceSurplus = 0;
2331 for (AnnotatedLine *Line : Lines) {
2332 if (!Line->Children.empty())
2333 insertBraces(Line->Children, Result);
2334 if (!Line->Affected && OpeningBraceSurplus == 0)
2336 for (FormatToken *Token = Line->First; Token && !Token->
Finalized;
2337 Token = Token->
Next) {
2339 if (BraceCount == 0)
2342 if (BraceCount < 0) {
2343 assert(BraceCount == -1);
2344 if (!Line->Affected)
2346 Brace = Token->
is(tok::comment) ?
"\n{" :
"{";
2347 ++OpeningBraceSurplus;
2349 if (OpeningBraceSurplus == 0)
2351 if (OpeningBraceSurplus < BraceCount)
2352 BraceCount = OpeningBraceSurplus;
2353 Brace =
'\n' + std::string(BraceCount,
'}');
2354 OpeningBraceSurplus -= BraceCount;
2358 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2361 assert(OpeningBraceSurplus == 0);
2365class BracesRemover :
public TokenAnalyzer {
2368 : TokenAnalyzer(
Env, Style) {}
2370 std::pair<tooling::Replacements, unsigned>
2371 analyze(TokenAnnotator &Annotator,
2372 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2373 FormatTokenLexer &Tokens)
override {
2374 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2375 tooling::Replacements Result;
2376 removeBraces(AnnotatedLines, Result);
2381 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2382 tooling::Replacements &Result) {
2383 const auto &SourceMgr =
Env.getSourceManager();
2384 const auto *End = Lines.end();
2385 for (
const auto *I = Lines.begin(); I != End; ++I) {
2386 const auto &Line = *I;
2387 if (!Line->Children.empty())
2388 removeBraces(Line->Children, Result);
2389 if (!Line->Affected)
2391 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2392 for (
const auto *Token = Line->First; Token && !Token->
Finalized;
2393 Token = Token->
Next) {
2396 auto *Next = Token->
Next;
2397 assert(Next || Token == Line->Last);
2398 if (!Next && NextLine)
2399 Next = NextLine->First;
2400 replaceToken(*Token, Next, SourceMgr, Result);
2406class SemiRemover :
public TokenAnalyzer {
2409 : TokenAnalyzer(
Env, Style) {}
2411 std::pair<tooling::Replacements, unsigned>
2412 analyze(TokenAnnotator &Annotator,
2413 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2414 FormatTokenLexer &Tokens)
override {
2415 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2416 tooling::Replacements Result;
2417 removeSemi(Annotator, AnnotatedLines, Result);
2422 void removeSemi(TokenAnnotator &Annotator,
2423 SmallVectorImpl<AnnotatedLine *> &Lines,
2424 tooling::Replacements &Result) {
2425 auto PrecededByFunctionRBrace = [](
const FormatToken &Tok) {
2426 const auto *Prev = Tok.Previous;
2427 if (!Prev || Prev->isNot(tok::r_brace))
2429 const auto *LBrace = Prev->MatchingParen;
2430 return LBrace && LBrace->is(TT_FunctionLBrace);
2432 const auto &SourceMgr =
Env.getSourceManager();
2433 const auto *End = Lines.end();
2434 for (
const auto *I = Lines.begin(); I != End; ++I) {
2435 const auto &Line = *I;
2436 if (!Line->Children.empty())
2437 removeSemi(Annotator, Line->Children, Result);
2438 if (!Line->Affected)
2440 Annotator.calculateFormattingInformation(*Line);
2441 const auto *NextLine = I + 1 == End ? nullptr : I[1];
2442 for (
const auto *Token = Line->First; Token && !Token->
Finalized;
2443 Token = Token->
Next) {
2444 if (Token->
isNot(tok::semi) ||
2445 (!Token->
Optional && !PrecededByFunctionRBrace(*Token))) {
2448 auto *Next = Token->
Next;
2449 assert(Next || Token == Line->Last);
2450 if (!Next && NextLine)
2451 Next = NextLine->First;
2452 replaceToken(*Token, Next, SourceMgr, Result);
2458class EnumTrailingCommaEditor :
public TokenAnalyzer {
2460 EnumTrailingCommaEditor(
const Environment &
Env,
const FormatStyle &Style)
2461 : TokenAnalyzer(
Env, Style) {}
2463 std::pair<tooling::Replacements, unsigned>
2464 analyze(TokenAnnotator &Annotator,
2465 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2466 FormatTokenLexer &Tokens)
override {
2467 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2468 tooling::Replacements Result;
2469 editEnumTrailingComma(AnnotatedLines, Result);
2474 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2475 tooling::Replacements &Result) {
2476 bool InEnumBraces =
false;
2477 const FormatToken *BeforeRBrace =
nullptr;
2478 const auto &SourceMgr =
Env.getSourceManager();
2479 for (
auto *Line : Lines) {
2480 if (!Line->Children.empty())
2481 editEnumTrailingComma(Line->Children, Result);
2482 for (
const auto *Token = Line->First; Token && !Token->
Finalized;
2483 Token = Token->
Next) {
2484 if (Token->
isNot(TT_EnumRBrace)) {
2485 if (Token->
is(TT_EnumLBrace))
2486 InEnumBraces =
true;
2487 else if (InEnumBraces && Token->
isNot(tok::comment))
2488 BeforeRBrace = Line->Affected ? Token :
nullptr;
2491 InEnumBraces =
false;
2494 if (BeforeRBrace->is(tok::comma)) {
2496 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr, Result);
2498 cantFail(Result.add(tooling::Replacement(
2499 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0,
",")));
2501 BeforeRBrace =
nullptr;
2507class JavaScriptRequoter :
public TokenAnalyzer {
2509 JavaScriptRequoter(
const Environment &
Env,
const FormatStyle &Style)
2510 : TokenAnalyzer(
Env, Style) {}
2512 std::pair<tooling::Replacements, unsigned>
2513 analyze(TokenAnnotator &Annotator,
2514 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2515 FormatTokenLexer &Tokens)
override {
2516 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2517 tooling::Replacements Result;
2518 requoteJSStringLiteral(AnnotatedLines, Result);
2525 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2526 tooling::Replacements &Result) {
2527 for (AnnotatedLine *Line : Lines) {
2528 requoteJSStringLiteral(Line->Children, Result);
2529 if (!Line->Affected)
2531 for (FormatToken *FormatTok = Line->First; FormatTok;
2532 FormatTok = FormatTok->Next) {
2533 StringRef Input = FormatTok->TokenText;
2534 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2538 !Input.starts_with(
"\"")) ||
2540 !Input.starts_with(
"\'"))) {
2546 SourceLocation Start = FormatTok->Tok.getLocation();
2547 auto Replace = [&](SourceLocation Start,
unsigned Length,
2548 StringRef ReplacementText) {
2549 auto Err = Result.add(tooling::Replacement(
2550 Env.getSourceManager(), Start, Length, ReplacementText));
2554 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2558 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2559 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2560 IsSingle ?
"'" :
"\"");
2563 bool Escaped =
false;
2564 for (
size_t i = 1; i < Input.size() - 1; i++) {
2567 if (!Escaped && i + 1 < Input.size() &&
2568 ((IsSingle && Input[i + 1] ==
'"') ||
2569 (!IsSingle && Input[i + 1] ==
'\''))) {
2572 Replace(Start.getLocWithOffset(i), 1,
"");
2579 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2581 Replace(Start.getLocWithOffset(i), 0,
"\\");
2595class Formatter :
public TokenAnalyzer {
2598 FormattingAttemptStatus *Status)
2599 : TokenAnalyzer(
Env, Style), Status(Status) {}
2601 std::pair<tooling::Replacements, unsigned>
2602 analyze(TokenAnnotator &Annotator,
2603 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2604 FormatTokenLexer &Tokens)
override {
2605 tooling::Replacements Result;
2606 deriveLocalStyle(AnnotatedLines);
2607 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2608 for (AnnotatedLine *Line : AnnotatedLines)
2609 Annotator.calculateFormattingInformation(*Line);
2610 Annotator.setCommentLineLevels(AnnotatedLines);
2612 WhitespaceManager Whitespaces(
2613 Env.getSourceManager(), Style,
2615 ? WhitespaceManager::inputUsesCRLF(
2616 Env.getSourceManager().getBufferData(
Env.getFileID()),
2617 Style.
LineEnding == FormatStyle::LE_DeriveCRLF)
2619 ContinuationIndenter
Indenter(Style, Tokens.getKeywords(),
2620 Env.getSourceManager(), Whitespaces, Encoding,
2621 BinPackInconclusiveFunctions);
2623 UnwrappedLineFormatter(&
Indenter, &Whitespaces, Style,
2624 Tokens.getKeywords(),
Env.getSourceManager(),
2626 .format(AnnotatedLines,
false,
2629 Env.getFirstStartColumn(),
2630 Env.getNextStartColumn(),
2631 Env.getLastStartColumn());
2632 for (
const auto &R : Whitespaces.generateReplacements())
2634 return std::make_pair(Result, 0);
2635 return std::make_pair(Result, Penalty);
2640 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2641 for (
const AnnotatedLine *Line : Lines) {
2642 if (hasCpp03IncompatibleFormat(Line->Children))
2644 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2645 if (!Tok->hasWhitespaceBefore()) {
2646 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2648 if (Tok->is(TT_TemplateCloser) &&
2649 Tok->Previous->is(TT_TemplateCloser)) {
2658 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
2659 int AlignmentDiff = 0;
2661 for (
const AnnotatedLine *Line : Lines) {
2662 AlignmentDiff += countVariableAlignments(Line->Children);
2664 for (
const auto *Tok = Line->getFirstNonComment(); Tok; Tok = Tok->Next) {
2665 if (Tok->isNot(TT_PointerOrReference))
2668 const auto *Prev = Tok->Previous;
2669 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
2670 const bool SpaceBefore = Tok->hasWhitespaceBefore();
2673 while (Tok->Next && Tok->Next->is(TT_PointerOrReference))
2676 const auto *Next = Tok->Next;
2677 const bool FollowedByName = Next && Next->Tok.getIdentifierInfo();
2678 const bool SpaceAfter = Next && Next->hasWhitespaceBefore();
2680 if ((!PrecededByName && !FollowedByName) ||
2682 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
2686 if ((PrecededByName && SpaceBefore) ||
2687 (FollowedByName && !SpaceAfter)) {
2690 }
else if ((PrecededByName && !SpaceBefore) ||
2691 (FollowedByName && SpaceAfter)) {
2698 return AlignmentDiff;
2702 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2703 bool HasBinPackedFunction =
false;
2704 bool HasOnePerLineFunction =
false;
2705 for (AnnotatedLine *Line : AnnotatedLines) {
2706 if (!Line->First->Next)
2708 FormatToken *Tok = Line->First->Next;
2710 if (Tok->is(PPK_BinPacked))
2711 HasBinPackedFunction =
true;
2712 if (Tok->is(PPK_OnePerLine))
2713 HasOnePerLineFunction =
true;
2719 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
2720 if (NetRightCount > 0)
2722 else if (NetRightCount < 0)
2726 if (Style.
Standard == FormatStyle::LS_Auto) {
2727 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2728 ? FormatStyle::LS_Latest
2729 : FormatStyle::LS_Cpp03;
2731 BinPackInconclusiveFunctions =
2732 HasBinPackedFunction || !HasOnePerLineFunction;
2735 bool BinPackInconclusiveFunctions;
2736 FormattingAttemptStatus *Status;
2750class TrailingCommaInserter :
public TokenAnalyzer {
2752 TrailingCommaInserter(
const Environment &
Env,
const FormatStyle &Style)
2753 : TokenAnalyzer(
Env, Style) {}
2755 std::pair<tooling::Replacements, unsigned>
2756 analyze(TokenAnnotator &Annotator,
2757 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2758 FormatTokenLexer &Tokens)
override {
2759 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2760 tooling::Replacements Result;
2761 insertTrailingCommas(AnnotatedLines, Result);
2768 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2769 tooling::Replacements &Result) {
2770 for (AnnotatedLine *Line : Lines) {
2771 insertTrailingCommas(Line->Children, Result);
2772 if (!Line->Affected)
2774 for (FormatToken *FormatTok = Line->First; FormatTok;
2775 FormatTok = FormatTok->Next) {
2776 if (FormatTok->NewlinesBefore == 0)
2778 FormatToken *Matching = FormatTok->MatchingParen;
2779 if (!Matching || !FormatTok->getPreviousNonComment())
2781 if (!(FormatTok->is(tok::r_square) &&
2782 Matching->is(TT_ArrayInitializerLSquare)) &&
2783 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
2786 FormatToken *Prev = FormatTok->getPreviousNonComment();
2787 if (Prev->is(tok::comma) || Prev->is(tok::semi))
2791 SourceLocation Start =
2792 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2796 unsigned ColumnNumber =
2797 Env.getSourceManager().getSpellingColumnNumber(Start);
2802 cantFail(Result.add(
2803 tooling::Replacement(
Env.getSourceManager(), Start, 0,
",")));
2811class Cleaner :
public TokenAnalyzer {
2814 : TokenAnalyzer(
Env, Style),
2815 DeletedTokens(FormatTokenLess(
Env.getSourceManager())) {}
2818 std::pair<tooling::Replacements, unsigned>
2819 analyze(TokenAnnotator &Annotator,
2820 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2821 FormatTokenLexer &Tokens)
override {
2829 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2831 checkEmptyNamespace(AnnotatedLines);
2833 for (
auto *Line : AnnotatedLines)
2836 return {generateFixes(), 0};
2840 void cleanupLine(AnnotatedLine *Line) {
2841 for (
auto *Child : Line->Children)
2844 if (Line->Affected) {
2845 cleanupRight(Line->First, tok::comma, tok::comma);
2846 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2847 cleanupRight(Line->First, tok::l_paren, tok::comma);
2848 cleanupLeft(Line->First, tok::comma, tok::r_paren);
2849 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2850 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2851 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2855 bool containsOnlyComments(
const AnnotatedLine &Line) {
2856 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)
2857 if (Tok->isNot(tok::comment))
2863 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2864 std::set<unsigned> DeletedLines;
2865 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2866 auto &Line = *AnnotatedLines[i];
2867 if (Line.startsWithNamespace())
2868 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2871 for (
auto Line : DeletedLines) {
2872 FormatToken *Tok = AnnotatedLines[Line]->First;
2884 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2885 unsigned CurrentLine,
unsigned &
NewLine,
2886 std::set<unsigned> &DeletedLines) {
2887 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2892 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2896 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2899 while (++CurrentLine < End) {
2900 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2903 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2904 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine,
NewLine,
2912 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2922 if (CurrentLine >= End)
2926 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2927 AnnotatedLines[InitLine]->First->Tok.getLocation(),
2928 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
2932 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
2933 DeletedLines.insert(i);
2942 template <
typename LeftKind,
typename RightKind>
2943 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2945 auto NextNotDeleted = [
this](
const FormatToken &Tok) -> FormatToken * {
2946 for (
auto *Res = Tok.Next; Res; Res = Res->Next) {
2947 if (Res->isNot(tok::comment) &&
2948 DeletedTokens.find(Res) == DeletedTokens.end()) {
2954 for (
auto *Left = Start;
Left;) {
2955 auto *
Right = NextNotDeleted(*Left);
2959 deleteToken(DeleteLeft ? Left : Right);
2960 for (
auto *Tok =
Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2971 template <
typename LeftKind,
typename RightKind>
2972 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2973 cleanupPair(Start, LK, RK,
true);
2976 template <
typename LeftKind,
typename RightKind>
2977 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2978 cleanupPair(Start, LK, RK,
false);
2982 inline void deleteToken(FormatToken *Tok) {
2984 DeletedTokens.insert(Tok);
2987 tooling::Replacements generateFixes() {
2988 tooling::Replacements Fixes;
2989 SmallVector<FormatToken *> Tokens;
2990 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2991 std::back_inserter(Tokens));
2997 while (Idx < Tokens.size()) {
2998 unsigned St = Idx, End = Idx;
2999 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3001 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
3002 Tokens[End]->Tok.getEndLoc());
3004 Fixes.add(tooling::Replacement(
Env.getSourceManager(), SR,
""));
3008 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3009 assert(
false &&
"Fixes must not conflict!");
3020 struct FormatTokenLess {
3021 FormatTokenLess(
const SourceManager &
SM) :
SM(
SM) {}
3023 bool operator()(
const FormatToken *LHS,
const FormatToken *RHS)
const {
3024 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3025 RHS->Tok.getLocation());
3031 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3034class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
3036 ObjCHeaderStyleGuesser(
const Environment &
Env,
const FormatStyle &Style)
3037 : TokenAnalyzer(
Env, Style), IsObjC(
false) {}
3039 std::pair<tooling::Replacements, unsigned>
3040 analyze(TokenAnnotator &Annotator,
3041 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3042 FormatTokenLexer &Tokens)
override {
3043 assert(Style.
Language == FormatStyle::LK_Cpp);
3044 IsObjC = guessIsObjC(
Env.getSourceManager(), AnnotatedLines,
3045 Tokens.getKeywords());
3046 tooling::Replacements Result;
3050 bool isObjC() {
return IsObjC; }
3054 guessIsObjC(
const SourceManager &SourceManager,
3055 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3056 const AdditionalKeywords &Keywords) {
3058 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3073 "FOUNDATION_EXPORT",
3074 "FOUNDATION_EXTERN",
3075 "NSAffineTransform",
3077 "NSAttributedString",
3096 "NSInvocationOperation",
3100 "NSMutableAttributedString",
3101 "NSMutableCharacterSet",
3103 "NSMutableDictionary",
3104 "NSMutableIndexSet",
3105 "NSMutableOrderedSet",
3109 "NSNumberFormatter",
3113 "NSOperationQueuePriority",
3117 "NSQualityOfService",
3120 "NSRegularExpression",
3131 "NS_ASSUME_NONNULL_BEGIN",
3136 for (
auto *Line : AnnotatedLines) {
3137 if (Line->First && (Line->First->TokenText.starts_with(
"#") ||
3138 Line->First->TokenText ==
"__pragma" ||
3139 Line->First->TokenText ==
"_Pragma")) {
3142 for (
const FormatToken *FormatTok = Line->First; FormatTok;
3143 FormatTok = FormatTok->Next) {
3144 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3145 (FormatTok->isNot(tok::objc_not_keyword) ||
3146 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3148 (FormatTok->Tok.isAnyIdentifier() &&
3149 llvm::binary_search(FoundationIdentifiers,
3150 FormatTok->TokenText)) ||
3151 FormatTok->is(TT_ObjCStringLiteral) ||
3152 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3153 Keywords.kw_NS_ERROR_ENUM,
3154 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3155 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3156 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3158 LLVM_DEBUG(llvm::dbgs()
3159 <<
"Detected ObjC at location "
3160 << FormatTok->Tok.getLocation().printToString(
3162 <<
" token: " << FormatTok->TokenText <<
" token type: "
3167 if (guessIsObjC(SourceManager, Line->Children, Keywords))
3184struct JavaImportDirective {
3197 for (
const auto &
Range : Ranges) {
3198 if (
Range.getOffset() < End &&
3199 Range.getOffset() +
Range.getLength() > Start) {
3214static std::pair<unsigned, unsigned>
3217 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3218 unsigned OffsetToEOL = 0;
3219 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3220 unsigned Start = Includes[Indices[i]].Offset;
3221 unsigned End = Start + Includes[Indices[i]].Text.size();
3222 if (!(Cursor >= Start && Cursor < End))
3224 CursorIndex = Indices[i];
3225 OffsetToEOL = End - Cursor;
3228 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3232 return std::make_pair(CursorIndex, OffsetToEOL);
3237 std::string NewCode;
3238 size_t Pos = 0, LastPos = 0;
3241 Pos = Code.find(
"\r\n", LastPos);
3242 if (Pos == LastPos) {
3246 if (Pos == std::string::npos) {
3247 NewCode += Code.substr(LastPos);
3250 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3252 }
while (Pos != std::string::npos);
3270 const unsigned IncludesBeginOffset = Includes.front().Offset;
3271 const unsigned IncludesEndOffset =
3272 Includes.back().Offset + Includes.back().Text.size();
3273 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3274 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3277 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3280 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3283 LHSStem = Includes[LHSI].Filename;
3284 RHSStem = Includes[RHSI].Filename;
3285 llvm::sys::path::replace_extension(LHSStem,
"");
3286 llvm::sys::path::replace_extension(RHSStem,
"");
3288 std::string LHSStemLower, RHSStemLower;
3289 std::string LHSFilenameLower, RHSFilenameLower;
3291 LHSStemLower = LHSStem.str().lower();
3292 RHSStemLower = RHSStem.str().lower();
3293 LHSFilenameLower = Includes[LHSI].Filename.lower();
3294 RHSFilenameLower = Includes[RHSI].Filename.lower();
3296 return std::tie(Includes[LHSI].Priority, LHSStemLower, LHSStem,
3297 LHSFilenameLower, Includes[LHSI].Filename) <
3298 std::tie(Includes[RHSI].Priority, RHSStemLower, RHSStem,
3299 RHSFilenameLower, Includes[RHSI].Filename);
3305 unsigned CursorIndex;
3307 unsigned CursorToEOLOffset;
3309 std::tie(CursorIndex, CursorToEOLOffset) =
3314 Indices.erase(llvm::unique(Indices,
3315 [&](
unsigned LHSI,
unsigned RHSI) {
3316 return Includes[LHSI].Text.trim() ==
3317 Includes[RHSI].
Text.trim();
3321 int CurrentCategory = Includes.front().Category;
3329 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3334 const auto OldCursor = Cursor ? *Cursor : 0;
3336 for (
unsigned Index : Indices) {
3337 if (!result.empty()) {
3341 CurrentCategory != Includes[Index].Category) {
3345 result += Includes[Index].Text;
3346 if (Cursor && CursorIndex == Index)
3347 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3348 CurrentCategory = Includes[Index].Category;
3351 if (Cursor && *Cursor >= IncludesEndOffset)
3352 *Cursor += result.size() - IncludesBlockSize;
3357 IncludesBeginOffset, IncludesBlockSize)))) {
3359 *Cursor = OldCursor;
3364 FileName, Includes.front().Offset, IncludesBlockSize, result));
3368 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3378 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3379 .StartsWith(
"\xEF\xBB\xBF", 3)
3381 unsigned SearchFrom = 0;
3393 bool FirstIncludeBlock =
true;
3394 bool MainIncludeFound =
false;
3395 bool FormattingOff =
false;
3398 llvm::Regex RawStringRegex(
3399 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3401 std::string RawStringTermination =
")\"";
3403 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3404 size_t Pos = SearchFrom;
3405 if (Code[SearchFrom] !=
'\n') {
3408 Pos = Code.find(
'\n', Pos);
3409 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3413 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3415 StringRef Trimmed =
Line.trim();
3420 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3421 std::string CharSequence = RawStringMatches[1].str();
3422 RawStringTermination =
")" + CharSequence +
"\"";
3423 FormattingOff =
true;
3426 if (Trimmed.contains(RawStringTermination))
3427 FormattingOff =
false;
3429 bool IsBlockComment =
false;
3432 FormattingOff =
true;
3434 FormattingOff =
false;
3435 }
else if (Trimmed.starts_with(
"/*")) {
3436 IsBlockComment =
true;
3437 Pos = Code.find(
"*/", SearchFrom + 2);
3440 const bool EmptyLineSkipped =
3446 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3447 if (!FormattingOff && !MergeWithNextLine) {
3448 if (!IsBlockComment &&
3450 StringRef IncludeName = Matches[2];
3451 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3456 Pos = Code.find(
"*/", SearchFrom);
3458 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3462 !MainIncludeFound && FirstIncludeBlock);
3464 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3466 MainIncludeFound =
true;
3467 IncludesInBlock.push_back(
3469 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3472 IncludesInBlock.clear();
3473 if (Trimmed.starts_with(
"#pragma hdrstop"))
3474 FirstIncludeBlock =
true;
3476 FirstIncludeBlock =
false;
3479 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3482 if (!MergeWithNextLine)
3484 SearchFrom = Pos + 1;
3486 if (!IncludesInBlock.empty()) {
3497 StringRef ImportIdentifier) {
3498 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3499 unsigned LongestMatchLength = 0;
3502 if (ImportIdentifier.starts_with(GroupPrefix) &&
3503 GroupPrefix.length() > LongestMatchLength) {
3504 LongestMatchIndex = I;
3505 LongestMatchLength = GroupPrefix.length();
3508 return LongestMatchIndex;
3520 unsigned ImportsBeginOffset = Imports.front().Offset;
3521 unsigned ImportsEndOffset =
3522 Imports.back().Offset + Imports.back().Text.size();
3523 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3524 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3528 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3531 for (
const JavaImportDirective &Import : Imports)
3534 bool StaticImportAfterNormalImport =
3536 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3538 return std::make_tuple(!Imports[LHSI].
IsStatic ^
3539 StaticImportAfterNormalImport,
3541 std::make_tuple(!Imports[RHSI].
IsStatic ^
3542 StaticImportAfterNormalImport,
3547 Indices.erase(llvm::unique(Indices,
3548 [&](
unsigned LHSI,
unsigned RHSI) {
3549 return Imports[LHSI].Text == Imports[RHSI].Text;
3553 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3557 for (
unsigned Index : Indices) {
3558 if (!result.empty()) {
3560 if (CurrentIsStatic != Imports[Index].
IsStatic ||
3566 result += CommentLine;
3569 result += Imports[Index].Text;
3570 CurrentIsStatic = Imports[Index].IsStatic;
3577 Imports.front().Offset, ImportsBlockSize)))) {
3582 ImportsBlockSize, result));
3586 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3593const char JavaImportRegexPattern[] =
3594 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
3603 unsigned SearchFrom = 0;
3604 llvm::Regex ImportRegex(JavaImportRegexPattern);
3609 bool FormattingOff =
false;
3612 auto Pos = Code.find(
'\n', SearchFrom);
3614 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3616 StringRef Trimmed =
Line.trim();
3618 FormattingOff =
true;
3620 FormattingOff =
false;
3622 if (ImportRegex.match(
Line, &Matches)) {
3623 if (FormattingOff) {
3628 StringRef
Static = Matches[1];
3631 if (
Static.contains(
"static"))
3633 ImportsInBlock.push_back(
3636 }
else if (!Trimmed.empty() && !ImportsInBlock.empty()) {
3641 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3643 SearchFrom = Pos + 1;
3645 if (!ImportsInBlock.empty())
3654 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
3657bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
3661 StringRef
FileName,
unsigned *Cursor) {
3679template <
typename T>
3684 if (Replaces.
empty())
3687 auto NewCode = applyAllReplacements(Code, Replaces);
3689 return NewCode.takeError();
3694 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
3696 return Replaces.
merge(FormatReplaces);
3705 std::vector<tooling::Range> Ranges,
3709 auto SortedReplaces =
3711 if (!SortedReplaces)
3712 return SortedReplaces.takeError();
3716 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
3717 std::vector<tooling::Range> Ranges,
3727 return Replace.
getOffset() == std::numeric_limits<unsigned>::max() &&
3733inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
3734 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
3735 Replace.getLength() == 1;
3739tooling::Replacements
3740fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
3745 tooling::Replacements HeaderInsertions;
3746 std::set<StringRef> HeadersToDelete;
3747 tooling::Replacements
Result;
3748 for (
const auto &R : Replaces) {
3749 if (isHeaderInsertion(R)) {
3752 consumeError(HeaderInsertions.add(R));
3753 }
else if (isHeaderDeletion(R)) {
3754 HeadersToDelete.insert(R.getReplacementText());
3755 }
else if (R.getOffset() == std::numeric_limits<unsigned>::max()) {
3756 llvm::errs() <<
"Insertions other than header #include insertion are "
3758 << R.getReplacementText() <<
"\n";
3760 consumeError(
Result.add(R));
3763 if (HeaderInsertions.empty() && HeadersToDelete.empty())
3766 StringRef
FileName = Replaces.begin()->getFilePath();
3769 for (
const auto &Header : HeadersToDelete) {
3770 tooling::Replacements Replaces =
3771 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
3772 for (
const auto &R : Replaces) {
3773 auto Err =
Result.add(R);
3776 llvm::errs() <<
"Failed to add header deletion replacement for "
3777 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
3782 SmallVector<StringRef, 4> Matches;
3783 for (
const auto &R : HeaderInsertions) {
3787 assert(Matched &&
"Header insertion replacement must have replacement text "
3790 auto IncludeName = Matches[2];
3792 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
3795 auto Err =
Result.add(*Replace);
3797 consumeError(std::move(Err));
3798 unsigned NewOffset =
3799 Result.getShiftedCodePosition(Replace->getOffset());
3800 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
3801 Replace->getReplacementText());
3811Expected<tooling::Replacements>
3816 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
3823 fixCppIncludeInsertions(Code, Replaces, Style);
3828std::pair<tooling::Replacements, unsigned>
3831 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
3842 case FormatStyle::RCPS_SingleLine:
3843 case FormatStyle::RCPS_WithPreceding:
3859 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
3860 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3861 NextStartColumn, LastStartColumn);
3866 Formatter(*
Env, Style, Status).process().first;
3868 if (Code.starts_with(
"x = ")) {
3869 Replaces = Replaces.
merge(
3873 if (applyAllReplacements(Code, Replaces))
3874 return {Replaces, 0};
3878 auto Env = Environment::make(Code,
FileName, Ranges, FirstStartColumn,
3879 NextStartColumn, LastStartColumn);
3883 typedef std::function<std::pair<tooling::Replacements, unsigned>(
3893 if (Style.
isCpp()) {
3900 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3901 return ParensRemover(
Env, S).process(
true);
3907 S.InsertBraces =
true;
3908 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3909 return BracesInserter(
Env, S).process(
true);
3915 S.RemoveBracesLLVM =
true;
3916 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3917 return BracesRemover(
Env, S).process(
true);
3923 S.RemoveSemicolon =
true;
3924 Passes.emplace_back([&, S = std::move(S)](
const Environment &
Env) {
3925 return SemiRemover(
Env, S).process();
3931 return EnumTrailingCommaEditor(
Env, Expanded)
3955 if (Style.
Language == FormatStyle::LK_ObjC &&
3965 return JavaScriptRequoter(
Env, Expanded).process(
true);
3970 return Formatter(
Env, Expanded, Status).process();
3976 return TrailingCommaInserter(
Env, Expanded).process();
3980 std::optional<std::string> CurrentCode;
3982 unsigned Penalty = 0;
3983 for (
size_t I = 0,
E = Passes.size(); I <
E; ++I) {
3984 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3985 auto NewCode = applyAllReplacements(
3986 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3988 Fixes = Fixes.
merge(PassFixes.first);
3989 Penalty += PassFixes.second;
3991 CurrentCode = std::move(*NewCode);
3992 Env = Environment::make(
3994 tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3995 FirstStartColumn, NextStartColumn, LastStartColumn);
4008 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4009 if (OriginalCode != Fix.getReplacementText()) {
4010 auto Err = NonNoOpFixes.
add(Fix);
4012 llvm::errs() <<
"Error adding replacements : "
4013 <<
toString(std::move(Err)) <<
"\n";
4017 Fixes = std::move(NonNoOpFixes);
4020 return {Fixes, Penalty};
4044 return Cleaner(*
Env, Style).process().first;
4049 StringRef
FileName,
bool *IncompleteFormat) {
4052 if (!Status.FormatComplete)
4053 *IncompleteFormat =
true;
4093 LangOpts.CXXOperatorNames = 1;
4094 LangOpts.CPlusPlus11 = SinceCpp11;
4097 LangOpts.CPlusPlus20 = SinceCpp20;
4100 LangOpts.CPlusPlus = 1;
4103 LangOpts.Char8 = SinceCpp20;
4107 LangOpts.Digraphs = SinceCpp11;
4109 LangOpts.LineComment = 1;
4112 LangOpts.MicrosoftExt = 1;
4113 LangOpts.DeclSpecKeyword = 1;
4120 "Set coding style. <string> can be:\n"
4121 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4122 " Mozilla, WebKit.\n"
4123 "2. 'file' to load style configuration from a\n"
4124 " .clang-format file in one of the parent directories\n"
4125 " of the source file (for stdin, see --assume-filename).\n"
4126 " If no .clang-format file is found, falls back to\n"
4127 " --fallback-style.\n"
4128 " --style=file is the default.\n"
4129 "3. 'file:<format_file_path>' to explicitly specify\n"
4130 " the configuration file.\n"
4131 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4132 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4139 if (
FileName.ends_with_insensitive(
".js") ||
4140 FileName.ends_with_insensitive(
".mjs") ||
4141 FileName.ends_with_insensitive(
".cjs") ||
4142 FileName.ends_with_insensitive(
".ts")) {
4147 if (
FileName.ends_with_insensitive(
".proto") ||
4148 FileName.ends_with_insensitive(
".protodevel")) {
4154 if (
FileName.ends_with_insensitive(
".txtpb") ||
4155 FileName.ends_with_insensitive(
".textpb") ||
4156 FileName.ends_with_insensitive(
".pb.txt") ||
4157 FileName.ends_with_insensitive(
".textproto") ||
4158 FileName.ends_with_insensitive(
".asciipb")) {
4161 if (
FileName.ends_with_insensitive(
".td"))
4163 if (
FileName.ends_with_insensitive(
".cs"))
4165 if (
FileName.ends_with_insensitive(
".json") ||
4166 FileName.ends_with_insensitive(
".ipynb")) {
4169 if (
FileName.ends_with_insensitive(
".sv") ||
4170 FileName.ends_with_insensitive(
".svh") ||
4171 FileName.ends_with_insensitive(
".v") ||
4172 FileName.ends_with_insensitive(
".vh")) {
4179 const auto ID =
Env.getFileID();
4180 const auto &SourceMgr =
Env.getSourceManager();
4183 LangOpts.CPlusPlus = 1;
4184 LangOpts.LineComment = 1;
4192 if (!
Text.consume_front(
"// clang-format Language:"))
4210 auto Extension = llvm::sys::path::extension(
FileName);
4213 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4222 if (Guesser.isObjC())
4226 return GuessedLanguage;
4234llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4237 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4239 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4240 FS->getBufferForFile(ConfigFile.str());
4241 if (
auto EC =
Text.getError())
4244 DiagHandler,
nullptr,
4252 StringRef FallbackStyleName, StringRef Code,
4253 llvm::vfs::FileSystem *FS,
4254 bool AllowUnknownOptions,
4255 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4263 if (StyleName.starts_with(
"{")) {
4265 StringRef Source =
"<command-line>";
4266 if (std::error_code ec =
4268 AllowUnknownOptions, DiagHandler)) {
4275 ChildFormatTextToApply.emplace_back(
4276 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4280 FS = llvm::vfs::getRealFileSystem().get();
4283 const bool IsDotHFile =
FileName.ends_with(
".h");
4287 StyleName.starts_with_insensitive(
"file:")) {
4288 auto ConfigFile = StyleName.substr(5);
4289 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4291 DiagHandler, IsDotHFile);
4292 if (
auto EC =
Text.getError()) {
4297 LLVM_DEBUG(llvm::dbgs()
4298 <<
"Using configuration file " << ConfigFile <<
"\n");
4306 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4320 if (std::error_code EC = FS->makeAbsolute(
Path))
4326 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4328 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4329 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4332 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4335 static_cast<void>(EC);
4341 FilesToLookFor.push_back(
".clang-format");
4342 FilesToLookFor.push_back(
"_clang-format");
4345 for (StringRef Directory =
Path; !Directory.empty();
4346 Directory = llvm::sys::path::parent_path(Directory)) {
4347 auto Status = FS->status(Directory);
4349 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4353 for (
const auto &F : FilesToLookFor) {
4356 llvm::sys::path::append(ConfigFile, F);
4357 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4359 Status = FS->status(ConfigFile);
4361 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4365 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4367 DiagHandler, IsDotHFile);
4368 if (
auto EC =
Text.getError()) {
4373 if (!UnsuitableConfigFiles.empty())
4374 UnsuitableConfigFiles.append(
", ");
4375 UnsuitableConfigFiles.append(ConfigFile);
4379 LLVM_DEBUG(llvm::dbgs()
4380 <<
"Using configuration file " << ConfigFile <<
"\n");
4383 if (!ChildFormatTextToApply.empty()) {
4384 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4385 applyChildFormatTexts(&Style);
4390 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4395 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4405 if (!UnsuitableConfigFiles.empty()) {
4408 UnsuitableConfigFiles);
4411 if (!ChildFormatTextToApply.empty()) {
4412 LLVM_DEBUG(llvm::dbgs()
4413 <<
"Applying child configurations on fallback style\n");
4414 applyChildFormatTexts(&FallbackStyle);
4417 return FallbackStyle;
4421 if (Comment == (On ?
"/* clang-format on */" :
"/* clang-format off */"))
4424 static const char ClangFormatOn[] =
"// clang-format on";
4425 static const char ClangFormatOff[] =
"// clang-format off";
4426 const unsigned Size = (On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4428 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&
4429 (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...
static CharSourceRange getCharRange(SourceRange R)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
void SetCommentRetentionState(bool Mode)
SetCommentRetentionMode - Change the comment retention mode of the lexer to the specified mode.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
llvm::MemoryBufferRef getBufferOrFake(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
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.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
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)