26#include "llvm/ADT/Sequence.h"
27#include "llvm/ADT/StringSet.h"
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/VirtualFileSystem.h"
33#define DEBUG_TYPE "format-formatter"
52struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeNoexceptSpecifierStyle> {
61template <>
struct MappingTraits<
FormatStyle::AlignConsecutiveStyle> {
64 IO.enumCase(
Value,
"Consecutive",
71 IO.enumCase(
Value,
"AcrossEmptyLines",
78 IO.enumCase(
Value,
"AcrossComments",
85 IO.enumCase(
Value,
"AcrossEmptyLinesAndComments",
94 IO.enumCase(
Value,
"true",
105 IO.mapOptional(
"Enabled",
Value.Enabled);
106 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
107 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
108 IO.mapOptional(
"AlignCompound",
Value.AlignCompound);
109 IO.mapOptional(
"AlignFunctionDeclarations",
110 Value.AlignFunctionDeclarations);
111 IO.mapOptional(
"AlignFunctionPointers",
Value.AlignFunctionPointers);
112 IO.mapOptional(
"EnumAssignments",
Value.EnumAssignments);
113 IO.mapOptional(
"PadOperators",
Value.PadOperators);
118struct MappingTraits<
FormatStyle::ShortCaseStatementsAlignmentStyle> {
121 IO.mapOptional(
"Enabled",
Value.Enabled);
122 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
123 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
124 IO.mapOptional(
"AlignCaseArrows",
Value.AlignCaseArrows);
125 IO.mapOptional(
"AlignCaseColons",
Value.AlignCaseColons);
130struct ScalarEnumerationTraits<
FormatStyle::AttributeBreakingStyle> {
140struct ScalarEnumerationTraits<
FormatStyle::ArrayInitializerAlignmentStyle> {
149template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
159template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackArgumentsStyle> {
172struct ScalarEnumerationTraits<
FormatStyle::BinPackParametersStyle> {
185template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
194struct ScalarEnumerationTraits<
FormatStyle::BitFieldColonSpacingStyle> {
204template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
218template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
221 IO.mapOptional(
"AfterClass", Wrapping.
AfterClass);
223 IO.mapOptional(
"AfterEnum", Wrapping.
AfterEnum);
230 IO.mapOptional(
"AfterStruct", Wrapping.
AfterStruct);
231 IO.mapOptional(
"AfterUnion", Wrapping.
AfterUnion);
232 IO.mapOptional(
"BeforeCatch", Wrapping.
BeforeCatch);
233 IO.mapOptional(
"BeforeElse", Wrapping.
BeforeElse);
235 IO.mapOptional(
"BeforeWhile", Wrapping.
BeforeWhile);
257struct ScalarEnumerationTraits<
258 FormatStyle::BraceWrappingAfterControlStatementStyle> {
273struct ScalarEnumerationTraits<
274 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
288struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeInlineASMColonStyle> {
298struct ScalarEnumerationTraits<
FormatStyle::BreakBinaryOperationsStyle> {
307template <>
struct ScalarTraits<
clang::tok::TokenKind> {
309 llvm::raw_ostream &Out) {
316 static StringRef
input(StringRef Scalar,
void *,
319#define PUNCTUATOR(Name, Spelling) \
320 if (Scalar == Spelling) { \
321 Value = clang::tok::Name; \
324#include "clang/Basic/TokenKinds.def"
325 return "unknown operator";
328 static QuotingType
mustQuote(StringRef) {
return QuotingType::None; }
331template <>
struct MappingTraits<
FormatStyle::BinaryOperationBreakRule> {
333 IO.mapOptional(
"Operators",
Value.Operators);
335 if (!IO.outputting())
337 IO.mapOptional(
"Style",
Value.Style);
338 IO.mapOptional(
"MinChainLength",
Value.MinChainLength);
342template <>
struct MappingTraits<
FormatStyle::BreakBinaryOperationsOptions> {
345 IO.enumCase(
Value,
"Never",
348 IO.enumCase(
Value,
"OnePerLine",
351 IO.enumCase(
Value,
"RespectPrecedence",
358 IO.mapOptional(
"Default",
Value.Default);
359 IO.mapOptional(
"PerOperator",
Value.PerOperator);
364struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
375struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
386struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
400template <>
struct ScalarEnumerationTraits<
FormatStyle::BracedListStyle> {
412template <>
struct ScalarEnumerationTraits<
FormatStyle::DAGArgStyle> {
421struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
435struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
450struct ScalarEnumerationTraits<
FormatStyle::EmptyLineAfterAccessModifierStyle> {
460struct ScalarEnumerationTraits<
472struct ScalarEnumerationTraits<
FormatStyle::EnumTrailingCommaStyle> {
481struct ScalarEnumerationTraits<
FormatStyle::IndentAccessModifierStyle> {
486 IO.enumCase(
Value,
"AfterFirstAccessModifier",
496struct ScalarEnumerationTraits<
FormatStyle::IndentExternBlockStyle> {
506template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
508 IO.mapOptional(
"Binary",
Base.Binary);
509 IO.mapOptional(
"BinaryMinDigitsInsert",
Base.BinaryMinDigitsInsert);
510 IO.mapOptional(
"BinaryMaxDigitsRemove",
Base.BinaryMaxDigitsRemove);
511 IO.mapOptional(
"Decimal",
Base.Decimal);
512 IO.mapOptional(
"DecimalMinDigitsInsert",
Base.DecimalMinDigitsInsert);
513 IO.mapOptional(
"DecimalMaxDigitsRemove",
Base.DecimalMaxDigitsRemove);
514 IO.mapOptional(
"Hex",
Base.Hex);
515 IO.mapOptional(
"HexMinDigitsInsert",
Base.HexMinDigitsInsert);
516 IO.mapOptional(
"HexMaxDigitsRemove",
Base.HexMaxDigitsRemove);
519 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigitsInsert);
520 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigitsInsert);
521 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigitsInsert);
525template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
533template <>
struct MappingTraits<
FormatStyle::KeepEmptyLinesStyle> {
535 IO.mapOptional(
"AtEndOfBlock",
Value.AtEndOfBlock);
536 IO.mapOptional(
"AtEndOfFile",
Value.AtEndOfFile);
537 IO.mapOptional(
"AtStartOfBlock",
Value.AtStartOfBlock);
538 IO.mapOptional(
"AtStartOfFile",
Value.AtStartOfFile);
542template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
558template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
580struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
588template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
598struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
608struct ScalarEnumerationTraits<
FormatStyle::NumericLiteralComponentStyle> {
617template <>
struct MappingTraits<
FormatStyle::NumericLiteralCaseStyle> {
619 IO.mapOptional(
"ExponentLetter",
Value.ExponentLetter);
620 IO.mapOptional(
"HexDigit",
Value.HexDigit);
621 IO.mapOptional(
"Prefix",
Value.Prefix);
622 IO.mapOptional(
"Suffix",
Value.Suffix);
626template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
630 IO.enumCase(
Value,
"AlignAfterOperator",
639template <>
struct MappingTraits<
FormatStyle::PackParametersStyle> {
641 IO.mapOptional(
"BinPack",
Value.BinPack);
642 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
647struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
658template <>
struct MappingTraits<
FormatStyle::PackArgumentsStyle> {
660 IO.mapOptional(
"BinPack",
Value.BinPack);
661 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
665template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
678struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
688struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
699 IO.mapOptional(
"Language", Format.Language);
700 IO.mapOptional(
"Delimiters", Format.Delimiters);
701 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
702 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
703 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
707template <>
struct ScalarEnumerationTraits<
FormatStyle::ReflowCommentsStyle> {
719struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
729struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
732 IO.enumCase(
Value,
"MultipleParentheses",
739struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
751struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
760struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
767 IO.enumCase(
Value,
"TopLevelDefinitions",
774struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeReturnTypeStyle> {
781 IO.enumCase(
Value,
"TopLevelDefinitions",
787struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
795template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
805template <>
struct MappingTraits<
FormatStyle::ShortFunctionStyle> {
808 IO.enumCase(
Value,
"Empty",
810 IO.enumCase(
Value,
"Inline",
812 IO.enumCase(
Value,
"InlineOnly",
822 IO.mapOptional(
"Empty",
Value.Empty);
823 IO.mapOptional(
"Inline",
Value.Inline);
824 IO.mapOptional(
"Other",
Value.Other);
828template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
842template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
853template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortRecordStyle> {
862template <>
struct MappingTraits<
FormatStyle::SortIncludesOptions> {
865 IO.enumCase(
Value,
"CaseInsensitive",
871 IO.enumCase(
Value,
"CaseSensitive",
877 IO.enumCase(
Value,
"Natural",
886 IO.enumCase(
Value,
"true",
894 IO.mapOptional(
"Enabled",
Value.Enabled);
895 IO.mapOptional(
"IgnoreCase",
Value.IgnoreCase);
896 IO.mapOptional(
"IgnoreExtension",
Value.IgnoreExtension);
897 IO.mapOptional(
"Natural",
Value.Natural);
898 IO.mapOptional(
"FilesBeforeFolders",
Value.FilesBeforeFolders);
903struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
912struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
917 IO.enumCase(
Value,
"LexicographicNumeric",
927struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
937template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
941 IO.mapOptional(
"AfterFunctionDefinitionName",
943 IO.mapOptional(
"AfterFunctionDeclarationName",
946 IO.mapOptional(
"AfterNot", Spacing.
AfterNot);
950 IO.mapOptional(
"AfterRequiresInExpression",
952 IO.mapOptional(
"BeforeNonEmptyParentheses",
958struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
961 IO.enumCase(
Value,
"ControlStatements",
963 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
965 IO.enumCase(
Value,
"NonEmptyParentheses",
973 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
979struct ScalarEnumerationTraits<
FormatStyle::SpaceInEmptyBracesStyle> {
987template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
1000struct ScalarEnumerationTraits<
FormatStyle::SpacesInBlockCommentsStyle> {
1012 int signedMaximum =
static_cast<int>(Space.
Maximum);
1013 IO.mapOptional(
"Minimum", Space.
Minimum);
1014 IO.mapOptional(
"Maximum", signedMaximum);
1015 Space.
Maximum =
static_cast<unsigned>(signedMaximum);
1017 if (Space.
Maximum < std::numeric_limits<unsigned>::max())
1028 IO.mapOptional(
"Other", Spaces.
Other);
1032template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
1039template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
1047struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
1056template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
1059 IO.enumCase(
Value,
"Leave",
1063 IO.enumCase(
Value,
"Always",
1067 IO.enumCase(
Value,
"Never",
1072 IO.enumCase(
Value,
"true",
1075 IO.enumCase(
Value,
"false",
1082 IO.mapOptional(
"AlignPPAndNotPP",
Value.AlignPPAndNotPP);
1083 IO.mapOptional(
"Kind",
Value.Kind);
1084 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
1095 IO.enumCase(
Value,
"ForContinuationAndIndentation",
1102struct ScalarEnumerationTraits<
1103 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
1116 IO.mapOptional(
"Language", Style.Language);
1118 StringRef BasedOnStyle;
1119 if (IO.outputting()) {
1120 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
1121 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
1122 for (StringRef StyleName : Styles) {
1124 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
1125 Style == PredefinedStyle) {
1126 BasedOnStyle = StyleName;
1131 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
1132 if (!BasedOnStyle.empty()) {
1136 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
1137 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
1140 Style.Language = OldLanguage;
1155 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
1156 BasedOnStyle.equals_insensitive(
"chromium");
1157 bool OnCurrentLine = IsGoogleOrChromium;
1158 bool OnNextLine =
true;
1160 bool BreakBeforeInheritanceComma =
false;
1161 bool BreakConstructorInitializersBeforeComma =
false;
1163 bool DeriveLineEnding =
true;
1164 bool UseCRLF =
false;
1166 bool SpaceInEmptyBlock =
false;
1167 bool SpaceInEmptyParentheses =
false;
1168 bool SpacesInConditionalStatement =
false;
1169 bool SpacesInCStyleCastParentheses =
false;
1170 bool SpacesInParentheses =
false;
1172 if (IO.outputting()) {
1173 IO.mapOptional(
"AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
1177 if (IsGoogleOrChromium) {
1180 Language = ((
FormatStyle *)IO.getContext())->Language;
1185 }
else if (BasedOnStyle.equals_insensitive(
"webkit")) {
1188 IO.mapOptional(
"AlignAfterOpenBracket", LocalBAS);
1192 Style.AlignAfterOpenBracket =
false;
1193 Style.BreakAfterOpenBracketBracedList =
false;
1194 Style.BreakAfterOpenBracketFunction =
false;
1195 Style.BreakAfterOpenBracketIf =
false;
1196 Style.BreakAfterOpenBracketLoop =
false;
1197 Style.BreakAfterOpenBracketSwitch =
false;
1198 Style.BreakBeforeCloseBracketBracedList =
false;
1199 Style.BreakBeforeCloseBracketFunction =
false;
1200 Style.BreakBeforeCloseBracketIf =
false;
1201 Style.BreakBeforeCloseBracketLoop =
false;
1202 Style.BreakBeforeCloseBracketSwitch =
false;
1205 Style.AlignAfterOpenBracket =
true;
1206 Style.BreakAfterOpenBracketBracedList =
true;
1207 Style.BreakAfterOpenBracketFunction =
true;
1208 Style.BreakAfterOpenBracketIf =
true;
1209 Style.BreakAfterOpenBracketLoop =
false;
1210 Style.BreakAfterOpenBracketSwitch =
false;
1211 Style.BreakBeforeCloseBracketBracedList =
true;
1212 Style.BreakBeforeCloseBracketFunction =
true;
1213 Style.BreakBeforeCloseBracketIf =
true;
1214 Style.BreakBeforeCloseBracketLoop =
false;
1215 Style.BreakBeforeCloseBracketSwitch =
false;
1218 Style.AlignAfterOpenBracket =
true;
1219 Style.BreakAfterOpenBracketBracedList =
true;
1220 Style.BreakAfterOpenBracketFunction =
true;
1221 Style.BreakAfterOpenBracketIf =
true;
1222 Style.BreakAfterOpenBracketLoop =
false;
1223 Style.BreakAfterOpenBracketSwitch =
false;
1224 Style.BreakBeforeCloseBracketBracedList =
false;
1225 Style.BreakBeforeCloseBracketFunction =
false;
1226 Style.BreakBeforeCloseBracketIf =
false;
1227 Style.BreakBeforeCloseBracketLoop =
false;
1228 Style.BreakBeforeCloseBracketSwitch =
false;
1231 Style.AlignAfterOpenBracket =
true;
1232 Style.BreakAfterOpenBracketBracedList =
false;
1233 Style.BreakAfterOpenBracketFunction =
false;
1234 Style.BreakAfterOpenBracketIf =
false;
1235 Style.BreakAfterOpenBracketLoop =
false;
1236 Style.BreakAfterOpenBracketSwitch =
false;
1237 Style.BreakBeforeCloseBracketBracedList =
false;
1238 Style.BreakBeforeCloseBracketFunction =
false;
1239 Style.BreakBeforeCloseBracketIf =
false;
1240 Style.BreakBeforeCloseBracketLoop =
false;
1241 Style.BreakBeforeCloseBracketSwitch =
false;
1249 if (!IO.outputting()) {
1250 IO.mapOptional(
"AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
1251 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
1252 IO.mapOptional(
"AlwaysBreakAfterReturnType", Style.BreakAfterReturnType);
1253 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
1254 Style.BreakTemplateDeclarations);
1255 IO.mapOptional(
"BinPackArguments", Style.PackArguments.BinPack);
1256 IO.mapOptional(
"BinPackParameters", Style.PackParameters.BinPack);
1257 IO.mapOptional(
"BreakBeforeInheritanceComma",
1258 BreakBeforeInheritanceComma);
1259 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
1260 BreakConstructorInitializersBeforeComma);
1261 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
1263 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
1264 IO.mapOptional(
"DerivePointerBinding", Style.DerivePointerAlignment);
1265 IO.mapOptional(
"KeepEmptyLinesAtEOF", Style.KeepEmptyLines.AtEndOfFile);
1266 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
1267 Style.KeepEmptyLines.AtStartOfBlock);
1268 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
1269 Style.IndentWrappedFunctionNames);
1270 IO.mapOptional(
"IndentRequires", Style.IndentRequiresClause);
1271 IO.mapOptional(
"PointerBindsToType", Style.PointerAlignment);
1272 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
1273 Style.SpaceBeforeParens);
1274 IO.mapOptional(
"SpaceInEmptyBlock", SpaceInEmptyBlock);
1275 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
1276 IO.mapOptional(
"SpacesInConditionalStatement",
1277 SpacesInConditionalStatement);
1278 IO.mapOptional(
"SpacesInCStyleCastParentheses",
1279 SpacesInCStyleCastParentheses);
1280 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
1281 IO.mapOptional(
"UseCRLF", UseCRLF);
1284 IO.mapOptional(
"AccessModifierOffset", Style.AccessModifierOffset);
1285 IO.mapOptional(
"AlignArrayOfStructures", Style.AlignArrayOfStructures);
1286 IO.mapOptional(
"AlignConsecutiveAssignments",
1287 Style.AlignConsecutiveAssignments);
1288 IO.mapOptional(
"AlignConsecutiveBitFields",
1289 Style.AlignConsecutiveBitFields);
1290 IO.mapOptional(
"AlignConsecutiveDeclarations",
1291 Style.AlignConsecutiveDeclarations);
1292 IO.mapOptional(
"AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
1293 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
1294 Style.AlignConsecutiveShortCaseStatements);
1295 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
1296 Style.AlignConsecutiveTableGenBreakingDAGArgColons);
1297 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
1298 Style.AlignConsecutiveTableGenCondOperatorColons);
1299 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
1300 Style.AlignConsecutiveTableGenDefinitionColons);
1301 IO.mapOptional(
"AlignEscapedNewlines", Style.AlignEscapedNewlines);
1302 IO.mapOptional(
"AlignOperands", Style.AlignOperands);
1303 IO.mapOptional(
"AlignTrailingComments", Style.AlignTrailingComments);
1304 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
1305 Style.AllowAllArgumentsOnNextLine);
1306 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
1307 Style.AllowAllParametersOfDeclarationOnNextLine);
1308 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
1309 Style.AllowBreakBeforeNoexceptSpecifier);
1310 IO.mapOptional(
"AllowBreakBeforeQtProperty",
1311 Style.AllowBreakBeforeQtProperty);
1312 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
1313 Style.AllowShortBlocksOnASingleLine);
1314 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
1315 Style.AllowShortCaseExpressionOnASingleLine);
1316 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
1317 Style.AllowShortCaseLabelsOnASingleLine);
1318 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
1319 Style.AllowShortCompoundRequirementOnASingleLine);
1320 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
1321 Style.AllowShortEnumsOnASingleLine);
1322 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
1323 Style.AllowShortFunctionsOnASingleLine);
1324 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
1325 Style.AllowShortIfStatementsOnASingleLine);
1326 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
1327 Style.AllowShortLambdasOnASingleLine);
1328 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
1329 Style.AllowShortLoopsOnASingleLine);
1330 IO.mapOptional(
"AllowShortNamespacesOnASingleLine",
1331 Style.AllowShortNamespacesOnASingleLine);
1332 IO.mapOptional(
"AllowShortRecordOnASingleLine",
1333 Style.AllowShortRecordOnASingleLine);
1334 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
1335 Style.AlwaysBreakAfterDefinitionReturnType);
1336 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
1337 Style.AlwaysBreakBeforeMultilineStrings);
1338 IO.mapOptional(
"AttributeMacros", Style.AttributeMacros);
1339 IO.mapOptional(
"BinPackLongBracedList", Style.BinPackLongBracedList);
1340 IO.mapOptional(
"BitFieldColonSpacing", Style.BitFieldColonSpacing);
1341 IO.mapOptional(
"BracedInitializerIndentWidth",
1342 Style.BracedInitializerIndentWidth);
1343 IO.mapOptional(
"BraceWrapping", Style.BraceWrapping);
1344 IO.mapOptional(
"BreakAdjacentStringLiterals",
1345 Style.BreakAdjacentStringLiterals);
1346 IO.mapOptional(
"BreakAfterAttributes", Style.BreakAfterAttributes);
1347 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
1348 Style.BreakAfterJavaFieldAnnotations);
1349 IO.mapOptional(
"BreakAfterOpenBracketBracedList",
1350 Style.BreakAfterOpenBracketBracedList);
1351 IO.mapOptional(
"BreakAfterOpenBracketFunction",
1352 Style.BreakAfterOpenBracketFunction);
1353 IO.mapOptional(
"BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf);
1354 IO.mapOptional(
"BreakAfterOpenBracketLoop",
1355 Style.BreakAfterOpenBracketLoop);
1356 IO.mapOptional(
"BreakAfterOpenBracketSwitch",
1357 Style.BreakAfterOpenBracketSwitch);
1358 IO.mapOptional(
"BreakAfterReturnType", Style.BreakAfterReturnType);
1359 IO.mapOptional(
"BreakArrays", Style.BreakArrays);
1360 IO.mapOptional(
"BreakBeforeBinaryOperators",
1361 Style.BreakBeforeBinaryOperators);
1362 IO.mapOptional(
"BreakBeforeCloseBracketBracedList",
1363 Style.BreakBeforeCloseBracketBracedList);
1364 IO.mapOptional(
"BreakBeforeCloseBracketFunction",
1365 Style.BreakBeforeCloseBracketFunction);
1366 IO.mapOptional(
"BreakBeforeCloseBracketIf",
1367 Style.BreakBeforeCloseBracketIf);
1368 IO.mapOptional(
"BreakBeforeCloseBracketLoop",
1369 Style.BreakBeforeCloseBracketLoop);
1370 IO.mapOptional(
"BreakBeforeCloseBracketSwitch",
1371 Style.BreakBeforeCloseBracketSwitch);
1372 IO.mapOptional(
"BreakBeforeConceptDeclarations",
1373 Style.BreakBeforeConceptDeclarations);
1374 IO.mapOptional(
"BreakBeforeBraces", Style.BreakBeforeBraces);
1375 IO.mapOptional(
"BreakBeforeInlineASMColon",
1376 Style.BreakBeforeInlineASMColon);
1377 IO.mapOptional(
"BreakBeforeReturnType", Style.BreakBeforeReturnType);
1378 IO.mapOptional(
"BreakBeforeTemplateCloser",
1379 Style.BreakBeforeTemplateCloser);
1380 IO.mapOptional(
"BreakBeforeTernaryOperators",
1381 Style.BreakBeforeTernaryOperators);
1382 IO.mapOptional(
"BreakBinaryOperations", Style.BreakBinaryOperations);
1383 IO.mapOptional(
"BreakConstructorInitializers",
1384 Style.BreakConstructorInitializers);
1385 IO.mapOptional(
"BreakFunctionDeclarationParameters",
1386 Style.BreakFunctionDeclarationParameters);
1387 IO.mapOptional(
"BreakFunctionDefinitionParameters",
1388 Style.BreakFunctionDefinitionParameters);
1389 IO.mapOptional(
"BreakInheritanceList", Style.BreakInheritanceList);
1390 IO.mapOptional(
"BreakStringLiterals", Style.BreakStringLiterals);
1391 IO.mapOptional(
"BreakTemplateDeclarations",
1392 Style.BreakTemplateDeclarations);
1393 IO.mapOptional(
"ColumnLimit", Style.ColumnLimit);
1394 IO.mapOptional(
"CommentPragmas", Style.CommentPragmas);
1395 IO.mapOptional(
"CompactCaseLabels", Style.CompactCaseLabels);
1396 IO.mapOptional(
"CompactNamespaces", Style.CompactNamespaces);
1397 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1398 Style.ConstructorInitializerIndentWidth);
1399 IO.mapOptional(
"ContinuationIndentWidth", Style.ContinuationIndentWidth);
1400 IO.mapOptional(
"Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
1401 IO.mapOptional(
"DerivePointerAlignment", Style.DerivePointerAlignment);
1402 IO.mapOptional(
"DisableFormat", Style.DisableFormat);
1403 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1404 Style.EmptyLineAfterAccessModifier);
1405 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1406 Style.EmptyLineBeforeAccessModifier);
1407 IO.mapOptional(
"EnumTrailingComma", Style.EnumTrailingComma);
1408 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1409 Style.ExperimentalAutoDetectBinPacking);
1410 IO.mapOptional(
"FixNamespaceComments", Style.FixNamespaceComments);
1411 IO.mapOptional(
"ForEachMacros", Style.ForEachMacros);
1412 IO.mapOptional(
"IfMacros", Style.IfMacros);
1413 IO.mapOptional(
"IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1414 IO.mapOptional(
"IncludeCategories", Style.IncludeStyle.IncludeCategories);
1415 IO.mapOptional(
"IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1416 IO.mapOptional(
"IncludeIsMainSourceRegex",
1417 Style.IncludeStyle.IncludeIsMainSourceRegex);
1418 IO.mapOptional(
"IndentAccessModifiers", Style.IndentAccessModifiers);
1419 IO.mapOptional(
"IndentCaseBlocks", Style.IndentCaseBlocks);
1420 IO.mapOptional(
"IndentCaseLabels", Style.IndentCaseLabels);
1421 IO.mapOptional(
"IndentExportBlock", Style.IndentExportBlock);
1422 IO.mapOptional(
"IndentExternBlock", Style.IndentExternBlock);
1423 IO.mapOptional(
"IndentGotoLabels", Style.IndentGotoLabels);
1424 IO.mapOptional(
"IndentPPDirectives", Style.IndentPPDirectives);
1425 IO.mapOptional(
"IndentRequiresClause", Style.IndentRequiresClause);
1426 IO.mapOptional(
"IndentWidth", Style.IndentWidth);
1427 IO.mapOptional(
"IndentWrappedFunctionNames",
1428 Style.IndentWrappedFunctionNames);
1429 IO.mapOptional(
"InsertBraces", Style.InsertBraces);
1430 IO.mapOptional(
"InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1431 IO.mapOptional(
"InsertTrailingCommas", Style.InsertTrailingCommas);
1432 IO.mapOptional(
"IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1433 IO.mapOptional(
"JavaImportGroups", Style.JavaImportGroups);
1434 IO.mapOptional(
"JavaScriptQuotes", Style.JavaScriptQuotes);
1435 IO.mapOptional(
"JavaScriptWrapImports", Style.JavaScriptWrapImports);
1436 IO.mapOptional(
"KeepEmptyLines", Style.KeepEmptyLines);
1437 IO.mapOptional(
"KeepFormFeed", Style.KeepFormFeed);
1438 IO.mapOptional(
"LambdaBodyIndentation", Style.LambdaBodyIndentation);
1439 IO.mapOptional(
"LineEnding", Style.LineEnding);
1440 IO.mapOptional(
"MacroBlockBegin", Style.MacroBlockBegin);
1441 IO.mapOptional(
"MacroBlockEnd", Style.MacroBlockEnd);
1442 IO.mapOptional(
"Macros", Style.Macros);
1443 IO.mapOptional(
"MacrosSkippedByRemoveParentheses",
1444 Style.MacrosSkippedByRemoveParentheses);
1445 IO.mapOptional(
"MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1446 IO.mapOptional(
"MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1447 IO.mapOptional(
"NamespaceIndentation", Style.NamespaceIndentation);
1448 IO.mapOptional(
"NamespaceMacros", Style.NamespaceMacros);
1449 IO.mapOptional(
"NumericLiteralCase", Style.NumericLiteralCase);
1450 IO.mapOptional(
"ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1451 IO.mapOptional(
"ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1452 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1453 Style.ObjCBreakBeforeNestedBlockParam);
1454 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1455 Style.ObjCPropertyAttributeOrder);
1456 IO.mapOptional(
"ObjCSpaceAfterMethodDeclarationPrefix",
1457 Style.ObjCSpaceAfterMethodDeclarationPrefix);
1458 IO.mapOptional(
"ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1459 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1460 Style.ObjCSpaceBeforeProtocolList);
1461 IO.mapOptional(
"OneLineFormatOffRegex", Style.OneLineFormatOffRegex);
1462 IO.mapOptional(
"PackArguments", Style.PackArguments);
1463 IO.mapOptional(
"PackConstructorInitializers",
1464 Style.PackConstructorInitializers);
1465 IO.mapOptional(
"PackParameters", Style.PackParameters);
1466 IO.mapOptional(
"PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1467 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1468 Style.PenaltyBreakBeforeFirstCallParameter);
1469 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1470 Style.PenaltyBreakBeforeMemberAccess);
1471 IO.mapOptional(
"PenaltyBreakComment", Style.PenaltyBreakComment);
1472 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1473 Style.PenaltyBreakFirstLessLess);
1474 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1475 Style.PenaltyBreakOpenParenthesis);
1476 IO.mapOptional(
"PenaltyBreakScopeResolution",
1477 Style.PenaltyBreakScopeResolution);
1478 IO.mapOptional(
"PenaltyBreakString", Style.PenaltyBreakString);
1479 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1480 Style.PenaltyBreakTemplateDeclaration);
1481 IO.mapOptional(
"PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1482 IO.mapOptional(
"PenaltyIndentedWhitespace",
1483 Style.PenaltyIndentedWhitespace);
1484 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1485 Style.PenaltyReturnTypeOnItsOwnLine);
1486 IO.mapOptional(
"PointerAlignment", Style.PointerAlignment);
1487 IO.mapOptional(
"PPIndentWidth", Style.PPIndentWidth);
1488 IO.mapOptional(
"QualifierAlignment", Style.QualifierAlignment);
1491 Style.QualifierOrder = {
"type",
"const",
"volatile"};
1493 Style.QualifierOrder = {
"const",
"volatile",
"type"};
1495 IO.mapOptional(
"QualifierOrder", Style.QualifierOrder);
1496 IO.mapOptional(
"RawStringFormats", Style.RawStringFormats);
1497 IO.mapOptional(
"ReferenceAlignment", Style.ReferenceAlignment);
1498 IO.mapOptional(
"ReflowComments", Style.ReflowComments);
1499 IO.mapOptional(
"RemoveBracesLLVM", Style.RemoveBracesLLVM);
1500 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1501 Style.RemoveEmptyLinesInUnwrappedLines);
1502 IO.mapOptional(
"RemoveParentheses", Style.RemoveParentheses);
1503 IO.mapOptional(
"RemoveSemicolon", Style.RemoveSemicolon);
1504 IO.mapOptional(
"RequiresClausePosition", Style.RequiresClausePosition);
1505 IO.mapOptional(
"RequiresExpressionIndentation",
1506 Style.RequiresExpressionIndentation);
1507 IO.mapOptional(
"SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1508 IO.mapOptional(
"ShortNamespaceLines", Style.ShortNamespaceLines);
1509 IO.mapOptional(
"SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1510 IO.mapOptional(
"SortIncludes", Style.SortIncludes);
1511 IO.mapOptional(
"SortJavaStaticImport", Style.SortJavaStaticImport);
1512 IO.mapOptional(
"SortUsingDeclarations", Style.SortUsingDeclarations);
1513 IO.mapOptional(
"SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1514 IO.mapOptional(
"SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1515 IO.mapOptional(
"SpaceAfterOperatorKeyword",
1516 Style.SpaceAfterOperatorKeyword);
1517 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1518 Style.SpaceAfterTemplateKeyword);
1519 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1520 Style.SpaceAroundPointerQualifiers);
1521 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1522 Style.SpaceBeforeAssignmentOperators);
1523 IO.mapOptional(
"SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1524 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1525 Style.SpaceBeforeCpp11BracedList);
1526 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1527 Style.SpaceBeforeCtorInitializerColon);
1528 IO.mapOptional(
"SpaceBeforeEnumUnderlyingTypeColon",
1529 Style.SpaceBeforeEnumUnderlyingTypeColon);
1530 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1531 Style.SpaceBeforeInheritanceColon);
1532 IO.mapOptional(
"SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1533 IO.mapOptional(
"SpaceBeforeParens", Style.SpaceBeforeParens);
1534 IO.mapOptional(
"SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1535 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1536 Style.SpaceBeforeRangeBasedForLoopColon);
1537 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1538 Style.SpaceBeforeSquareBrackets);
1539 IO.mapOptional(
"SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
1540 IO.mapOptional(
"SpacesBeforeTrailingComments",
1541 Style.SpacesBeforeTrailingComments);
1542 IO.mapOptional(
"SpacesInAngles", Style.SpacesInAngles);
1543 IO.mapOptional(
"SpacesInBlockComments", Style.SpacesInBlockComments);
1544 IO.mapOptional(
"SpacesInContainerLiterals",
1545 Style.SpacesInContainerLiterals);
1546 IO.mapOptional(
"SpacesInLineCommentPrefix",
1547 Style.SpacesInLineCommentPrefix);
1548 IO.mapOptional(
"SpacesInParens", Style.SpacesInParens);
1549 IO.mapOptional(
"SpacesInParensOptions", Style.SpacesInParensOptions);
1550 IO.mapOptional(
"SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1551 IO.mapOptional(
"Standard", Style.Standard);
1552 IO.mapOptional(
"StatementAttributeLikeMacros",
1553 Style.StatementAttributeLikeMacros);
1554 IO.mapOptional(
"StatementMacros", Style.StatementMacros);
1555 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1556 Style.TableGenBreakingDAGArgOperators);
1557 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1558 Style.TableGenBreakInsideDAGArg);
1559 IO.mapOptional(
"TabWidth", Style.TabWidth);
1560 IO.mapOptional(
"TemplateNames", Style.TemplateNames);
1561 IO.mapOptional(
"TypeNames", Style.TypeNames);
1562 IO.mapOptional(
"TypenameMacros", Style.TypenameMacros);
1563 IO.mapOptional(
"UseTab", Style.UseTab);
1564 IO.mapOptional(
"VariableTemplates", Style.VariableTemplates);
1565 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1566 Style.VerilogBreakBetweenInstancePorts);
1567 IO.mapOptional(
"WhitespaceSensitiveMacros",
1568 Style.WhitespaceSensitiveMacros);
1569 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1570 Style.WrapNamespaceBodyWithEmptyLines);
1577 if (Style.AlwaysBreakAfterDefinitionReturnType ==
1580 }
else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1588 if (BreakBeforeInheritanceComma &&
1596 if (BreakConstructorInitializersBeforeComma &&
1601 if (!IsGoogleOrChromium) {
1604 Style.PackConstructorInitializers = OnNextLine
1608 }
else if (Style.PackConstructorInitializers ==
1612 else if (!OnNextLine)
1617 if (!DeriveLineEnding)
1625 if (SpaceInEmptyBlock &&
1631 (SpacesInParentheses || SpaceInEmptyParentheses ||
1632 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1633 if (SpacesInParentheses) {
1635 Style.SpacesInParensOptions.ExceptDoubleParentheses =
false;
1636 Style.SpacesInParensOptions.InConditionalStatements =
true;
1637 Style.SpacesInParensOptions.InCStyleCasts =
1638 SpacesInCStyleCastParentheses;
1639 Style.SpacesInParensOptions.InEmptyParentheses =
1640 SpaceInEmptyParentheses;
1641 Style.SpacesInParensOptions.Other =
true;
1643 Style.SpacesInParensOptions = {};
1644 Style.SpacesInParensOptions.InConditionalStatements =
1645 SpacesInConditionalStatement;
1646 Style.SpacesInParensOptions.InCStyleCasts =
1647 SpacesInCStyleCastParentheses;
1648 Style.SpacesInParensOptions.InEmptyParentheses =
1649 SpaceInEmptyParentheses;
1661template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1662 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1667 if (Index >= Seq.size()) {
1668 assert(Index == Seq.size());
1673 Template = *((
const FormatStyle *)IO.getContext());
1676 Seq.resize(Index + 1, Template);
1682template <>
struct ScalarEnumerationTraits<
FormatStyle::IndentGotoLabelStyle> {
1710 return llvm::make_error<llvm::StringError>(Message,
1711 llvm::inconvertibleErrorCode());
1715 return "clang-format.parse_error";
1723 return "Invalid argument";
1725 return "Unsuitable";
1727 return "trailing comma insertion cannot be used with bin packing";
1729 return "Invalid qualifier specified in QualifierOrder";
1731 return "Duplicate qualifier specified in QualifierOrder";
1733 return "Missing type in QualifierOrder";
1735 return "Missing QualifierOrder";
1737 llvm_unreachable(
"unexpected parse error");
1989 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1992 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1993 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1994 {
".*", 1, 0,
false}};
2084 1, std::numeric_limits<unsigned>::max()};
2158 {
"^<.*\\.h>", 1, 0,
false},
2159 {
"^<.*", 2, 0,
false},
2160 {
".*", 3, 0,
false}};
2200 "PARSE_PARTIAL_TEXT_PROTO",
2204 "ParseTextProtoOrDie",
2206 "ParsePartialTestProto",
2325 "com.google.android.apps.chrome",
2344 return ChromiumStyle;
2371 return MozillaStyle;
2376 Style.AccessModifierOffset = -4;
2377 Style.AlignAfterOpenBracket =
false;
2379 Style.AlignTrailingComments = {};
2385 Style.ColumnLimit = 0;
2387 Style.FixNamespaceComments =
false;
2388 Style.IndentWidth = 4;
2390 Style.ObjCBlockIndentWidth = 4;
2391 Style.ObjCSpaceAfterProperty =
true;
2393 Style.SpaceBeforeCpp11BracedList =
true;
2404 Style.BreakBeforeTernaryOperators =
true;
2405 Style.ColumnLimit = 79;
2407 Style.FixNamespaceComments =
false;
2408 Style.KeepFormFeed =
true;
2415 Style.ColumnLimit = 120;
2417 Style.IndentWidth = 4;
2420 Style.BraceWrapping.AfterClass =
true;
2422 Style.BraceWrapping.AfterEnum =
true;
2423 Style.BraceWrapping.AfterFunction =
true;
2424 Style.BraceWrapping.AfterNamespace =
true;
2425 Style.BraceWrapping.AfterObjCDeclaration =
true;
2426 Style.BraceWrapping.AfterStruct =
true;
2427 Style.BraceWrapping.AfterExternBlock =
true;
2428 Style.BraceWrapping.BeforeCatch =
true;
2429 Style.BraceWrapping.BeforeElse =
true;
2430 Style.BraceWrapping.BeforeWhile =
false;
2431 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
2432 Style.AllowShortEnumsOnASingleLine =
false;
2434 Style.AllowShortCaseLabelsOnASingleLine =
false;
2436 Style.AllowShortLoopsOnASingleLine =
false;
2444 Style.InsertBraces =
true;
2445 Style.InsertNewlineAtEOF =
true;
2446 Style.IntegerLiteralSeparator.Decimal = 3;
2447 Style.IntegerLiteralSeparator.DecimalMinDigitsInsert = 5;
2449 Style.RemoveBracesLLVM =
true;
2450 Style.RemoveEmptyLinesInUnwrappedLines =
true;
2452 Style.RemoveSemicolon =
true;
2466 constexpr StringRef Prefix(
"inheritparentconfig=");
2468 if (Name.equals_insensitive(
"llvm"))
2470 else if (Name.equals_insensitive(
"chromium"))
2472 else if (Name.equals_insensitive(
"mozilla"))
2474 else if (Name.equals_insensitive(
"google"))
2476 else if (Name.equals_insensitive(
"webkit"))
2478 else if (Name.equals_insensitive(
"gnu"))
2480 else if (Name.equals_insensitive(
"microsoft"))
2482 else if (Name.equals_insensitive(
"clang-format"))
2484 else if (Name.equals_insensitive(
"none"))
2486 else if (Name.equals_insensitive(Prefix.drop_back()))
2487 Style->InheritConfig =
"..";
2488 else if (Name.size() > Prefix.size() && Name.starts_with_insensitive(Prefix))
2489 Style->InheritConfig = Name.substr(Prefix.size());
2499 if (Style->QualifierOrder.empty())
2503 for (
const auto &Qualifier : Style->QualifierOrder) {
2504 if (Qualifier ==
"type")
2508 if (token == tok::identifier)
2513 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2514 Style->QualifierOrder.end());
2515 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2516 LLVM_DEBUG(llvm::dbgs()
2517 <<
"Duplicate Qualifiers " << Style->QualifierOrder.size()
2518 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2523 if (!llvm::is_contained(Style->QualifierOrder,
"type"))
2531 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2532 void *DiagHandlerCtxt,
bool IsDotHFile) {
2536 if (Config.getBuffer().trim().empty())
2538 Style->StyleSet.Clear();
2539 std::vector<FormatStyle> Styles;
2540 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2546 Input.setContext(Style);
2547 Input.setAllowUnknownKeys(AllowUnknownOptions);
2550 return Input.error();
2554 const auto StyleCount = Styles.size();
2557 for (
unsigned I = 1; I < StyleCount; ++I) {
2558 const auto Lang = Styles[I].Language;
2562 for (
unsigned J = 0; J < I; ++J) {
2564 LLVM_DEBUG(llvm::dbgs()
2565 <<
"Duplicate languages in the config file on positions "
2566 << J <<
" and " << I <<
'\n');
2572 int LanguagePos = -1;
2578 for (
unsigned I = 0; I < StyleCount; ++I) {
2579 const auto Lang = Styles[I].Language;
2593 if (LanguagePos < 0) {
2599 LanguagePos = CppPos;
2600 if (LanguagePos < 0)
2604 for (
const auto &S : llvm::reverse(llvm::drop_begin(Styles)))
2605 Style->StyleSet.Add(S);
2607 *Style = Styles[LanguagePos];
2609 if (LanguagePos == 0) {
2612 Style->StyleSet.Add(*Style);
2628 llvm::raw_string_ostream Stream(
Text);
2629 llvm::yaml::Output Output(Stream);
2636 Output << NonConstStyle;
2638 return Stream.str();
2641std::optional<FormatStyle>
2644 return std::nullopt;
2646 if (It == Styles->end())
2647 return std::nullopt;
2649 Style.StyleSet = *
this;
2654 assert(Style.Language !=
LK_None &&
2655 "Cannot add a style for LK_None to a StyleSet");
2657 !Style.StyleSet.Styles &&
2658 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2660 Styles = std::make_shared<MapType>();
2661 (*Styles)[Style.Language] = std::move(Style);
2666std::optional<FormatStyle>
2675 StringRef
Text =
"") {
2678 if (
Next &&
Next->NewlinesBefore == 0 &&
Next->isNot(tok::eof)) {
2679 Start =
Tok.getLocation();
2680 Next->WhitespaceRange =
Token.WhitespaceRange;
2682 Start =
Token.WhitespaceRange.getBegin();
2685 cantFail(
Result.add(tooling::Replacement(SourceMgr, Range,
Text)));
2688class ParensRemover :
public TokenAnalyzer {
2690 ParensRemover(
const Environment &Env,
const FormatStyle &Style)
2691 : TokenAnalyzer(Env, Style) {}
2693 std::pair<tooling::Replacements, unsigned>
2694 analyze(TokenAnnotator &Annotator,
2695 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2696 FormatTokenLexer &Tokens)
override {
2697 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2698 tooling::Replacements
Result;
2699 removeParens(AnnotatedLines,
Result);
2704 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2705 tooling::Replacements &
Result) {
2706 const auto &SourceMgr = Env.getSourceManager();
2707 for (
auto *Line : Lines) {
2708 if (!
Line->Children.empty())
2710 if (!
Line->Affected)
2712 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2713 Token = Token->
Next) {
2715 replaceToken(*Token, Token->
Next, SourceMgr,
Result,
" ");
2721class BracesInserter :
public TokenAnalyzer {
2723 BracesInserter(
const Environment &Env,
const FormatStyle &Style)
2724 : TokenAnalyzer(Env, Style) {}
2726 std::pair<tooling::Replacements, unsigned>
2727 analyze(TokenAnnotator &Annotator,
2728 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2729 FormatTokenLexer &Tokens)
override {
2730 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2731 tooling::Replacements
Result;
2732 insertBraces(AnnotatedLines,
Result);
2737 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2738 tooling::Replacements &
Result) {
2739 const auto &SourceMgr = Env.getSourceManager();
2740 int OpeningBraceSurplus = 0;
2741 for (AnnotatedLine *Line : Lines) {
2742 if (!
Line->Children.empty())
2744 if (!
Line->Affected && OpeningBraceSurplus == 0)
2747 Token = Token->
Next) {
2758 if (!
Line->Affected)
2760 Brace = Token->
is(tok::comment) ?
"\n{" :
"{";
2761 ++OpeningBraceSurplus;
2764 if (OpeningBraceSurplus == 0)
2773 cantFail(
Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2776 assert(OpeningBraceSurplus == 0);
2780class BracesRemover :
public TokenAnalyzer {
2782 BracesRemover(
const Environment &Env,
const FormatStyle &Style)
2783 : TokenAnalyzer(Env, Style) {}
2785 std::pair<tooling::Replacements, unsigned>
2786 analyze(TokenAnnotator &Annotator,
2787 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2788 FormatTokenLexer &Tokens)
override {
2789 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2790 tooling::Replacements
Result;
2791 removeBraces(AnnotatedLines,
Result);
2796 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2797 tooling::Replacements &
Result) {
2798 const auto &SourceMgr = Env.getSourceManager();
2799 const auto *End = Lines.end();
2800 for (
const auto *I = Lines.begin(); I != End; ++I) {
2801 const auto &
Line = *I;
2802 if (!
Line->Children.empty())
2804 if (!
Line->Affected)
2806 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2807 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2808 Token = Token->
Next) {
2812 assert(
Next || Token ==
Line->Last);
2813 if (!
Next && NextLine)
2814 Next = NextLine->First;
2815 replaceToken(*Token,
Next, SourceMgr,
Result);
2821class SemiRemover :
public TokenAnalyzer {
2823 SemiRemover(
const Environment &Env,
const FormatStyle &Style)
2824 : TokenAnalyzer(Env, Style) {}
2826 std::pair<tooling::Replacements, unsigned>
2827 analyze(TokenAnnotator &Annotator,
2828 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2829 FormatTokenLexer &Tokens)
override {
2830 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2831 tooling::Replacements
Result;
2832 removeSemi(Annotator, AnnotatedLines,
Result);
2837 void removeSemi(TokenAnnotator &Annotator,
2838 SmallVectorImpl<AnnotatedLine *> &Lines,
2839 tooling::Replacements &
Result) {
2841 const auto *Prev =
Tok.Previous;
2842 if (!Prev || Prev->isNot(tok::r_brace))
2844 const auto *LBrace = Prev->MatchingParen;
2845 return LBrace && LBrace->is(TT_FunctionLBrace);
2847 const auto &SourceMgr = Env.getSourceManager();
2848 const auto *End = Lines.end();
2849 for (
const auto *I = Lines.begin(); I != End; ++I) {
2850 const auto &
Line = *I;
2851 if (!
Line->Children.empty())
2852 removeSemi(Annotator,
Line->Children,
Result);
2853 if (!
Line->Affected)
2855 Annotator.calculateFormattingInformation(*Line);
2856 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2857 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2858 Token = Token->
Next) {
2859 if (Token->
isNot(tok::semi) ||
2860 (!Token->
Optional && !PrecededByFunctionRBrace(*Token))) {
2864 assert(
Next || Token ==
Line->Last);
2865 if (!
Next && NextLine)
2866 Next = NextLine->First;
2867 replaceToken(*Token,
Next, SourceMgr,
Result);
2873class EnumTrailingCommaEditor :
public TokenAnalyzer {
2875 EnumTrailingCommaEditor(
const Environment &Env,
const FormatStyle &Style)
2876 : TokenAnalyzer(Env, Style) {}
2878 std::pair<tooling::Replacements, unsigned>
2879 analyze(TokenAnnotator &Annotator,
2880 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2881 FormatTokenLexer &Tokens)
override {
2882 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2883 tooling::Replacements
Result;
2884 editEnumTrailingComma(AnnotatedLines,
Result);
2889 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2890 tooling::Replacements &
Result) {
2891 bool InEnumBraces =
false;
2893 const auto &SourceMgr = Env.getSourceManager();
2894 for (
auto *Line : Lines) {
2895 if (!
Line->Children.empty())
2896 editEnumTrailingComma(
Line->Children,
Result);
2898 Token = Token->
Next) {
2899 if (Token->
isNot(TT_EnumRBrace)) {
2900 if (Token->
is(TT_EnumLBrace))
2901 InEnumBraces =
true;
2902 else if (InEnumBraces && Token->
isNot(tok::comment))
2903 BeforeRBrace =
Line->Affected ? Token :
nullptr;
2906 InEnumBraces =
false;
2907 if (!BeforeRBrace || BeforeRBrace->HasEnumTrailingCommaHandled) {
2911 if (BeforeRBrace->is(tok::comma)) {
2913 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr,
Result);
2915 cantFail(
Result.add(tooling::Replacement(
2916 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0,
",")));
2918 BeforeRBrace->HasEnumTrailingCommaHandled =
true;
2919 BeforeRBrace =
nullptr;
2925class JavaScriptRequoter :
public TokenAnalyzer {
2927 JavaScriptRequoter(
const Environment &Env,
const FormatStyle &Style)
2928 : TokenAnalyzer(Env, Style) {}
2930 std::pair<tooling::Replacements, unsigned>
2931 analyze(TokenAnnotator &Annotator,
2932 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2933 FormatTokenLexer &Tokens)
override {
2934 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2935 tooling::Replacements
Result;
2936 requoteJSStringLiteral(AnnotatedLines,
Result);
2943 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2944 tooling::Replacements &
Result) {
2945 for (AnnotatedLine *Line : Lines) {
2946 requoteJSStringLiteral(
Line->Children,
Result);
2947 if (!
Line->Affected)
2950 FormatTok = FormatTok->Next) {
2951 StringRef Input = FormatTok->TokenText;
2952 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2956 !Input.starts_with(
"\"")) ||
2958 !Input.starts_with(
"\'"))) {
2964 SourceLocation Start = FormatTok->Tok.getLocation();
2965 auto Replace = [&](SourceLocation Start,
unsigned Length,
2966 StringRef ReplacementText) {
2967 auto Err =
Result.add(tooling::Replacement(
2968 Env.getSourceManager(), Start, Length, ReplacementText));
2972 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2976 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2977 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2978 IsSingle ?
"'" :
"\"");
2981 bool Escaped =
false;
2982 for (
size_t i = 1; i < Input.size() - 1; i++) {
2985 if (!Escaped && i + 1 < Input.size() &&
2986 ((IsSingle && Input[i + 1] ==
'"') ||
2987 (!IsSingle && Input[i + 1] ==
'\''))) {
2990 Replace(Start.getLocWithOffset(i), 1,
"");
2997 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2999 Replace(Start.getLocWithOffset(i), 0,
"\\");
3013class Formatter :
public TokenAnalyzer {
3015 Formatter(
const Environment &Env,
const FormatStyle &Style,
3016 FormattingAttemptStatus *Status)
3017 : TokenAnalyzer(Env, Style), Status(Status) {}
3019 std::pair<tooling::Replacements, unsigned>
3020 analyze(TokenAnnotator &Annotator,
3021 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3022 FormatTokenLexer &Tokens)
override {
3023 tooling::Replacements
Result;
3024 deriveLocalStyle(AnnotatedLines);
3025 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3026 for (AnnotatedLine *Line : AnnotatedLines)
3027 Annotator.calculateFormattingInformation(*Line);
3028 Annotator.setCommentLineLevels(AnnotatedLines);
3030 WhitespaceManager Whitespaces(
3031 Env.getSourceManager(), Style,
3033 ? WhitespaceManager::inputUsesCRLF(
3034 Env.getSourceManager().getBufferData(Env.getFileID()),
3037 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
3038 Env.getSourceManager(), Whitespaces, Encoding,
3039 BinPackInconclusiveFunctions);
3041 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
3042 Tokens.getKeywords(), Env.getSourceManager(),
3044 .format(AnnotatedLines,
false,
3047 Env.getFirstStartColumn(),
3048 Env.getNextStartColumn(),
3049 Env.getLastStartColumn());
3050 for (
const auto &R : Whitespaces.generateReplacements())
3052 return std::make_pair(
Result, 0);
3053 return std::make_pair(
3054 Result,
static_cast<unsigned>(std::min<uint64_t>(Penalty,
UINT_MAX)));
3059 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3060 for (
const AnnotatedLine *Line : Lines) {
3061 if (hasCpp03IncompatibleFormat(
Line->Children))
3064 if (!
Tok->hasWhitespaceBefore()) {
3065 if (
Tok->is(tok::coloncolon) &&
Tok->Previous->is(TT_TemplateOpener))
3067 if (
Tok->is(TT_TemplateCloser) &&
3068 Tok->Previous->is(TT_TemplateCloser)) {
3077 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3078 int AlignmentDiff = 0;
3080 for (
const AnnotatedLine *Line : Lines) {
3081 AlignmentDiff += countVariableAlignments(
Line->Children);
3084 if (
Tok->isNot(TT_PointerOrReference))
3087 const auto *Prev =
Tok->Previous;
3088 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
3089 const bool SpaceBefore =
Tok->hasWhitespaceBefore();
3092 while (
Tok->Next &&
Tok->Next->is(TT_PointerOrReference))
3096 const bool FollowedByName =
Next &&
Next->Tok.getIdentifierInfo();
3097 const bool SpaceAfter =
Next &&
Next->hasWhitespaceBefore();
3099 if ((!PrecededByName && !FollowedByName) ||
3101 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
3105 if ((PrecededByName && SpaceBefore) ||
3106 (FollowedByName && !SpaceAfter)) {
3109 }
else if ((PrecededByName && !SpaceBefore) ||
3110 (FollowedByName && SpaceAfter)) {
3117 return AlignmentDiff;
3121 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3122 bool HasBinPackedFunction =
false;
3123 bool HasOnePerLineFunction =
false;
3124 for (AnnotatedLine *Line : AnnotatedLines) {
3125 if (!
Line->First->Next)
3129 if (
Tok->is(PPK_BinPacked))
3130 HasBinPackedFunction =
true;
3131 if (
Tok->is(PPK_OnePerLine))
3132 HasOnePerLineFunction =
true;
3137 if (Style.DerivePointerAlignment) {
3138 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
3139 if (NetRightCount > 0)
3141 else if (NetRightCount < 0)
3146 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
3150 BinPackInconclusiveFunctions =
3151 HasBinPackedFunction || !HasOnePerLineFunction;
3154 bool BinPackInconclusiveFunctions;
3155 FormattingAttemptStatus *Status;
3169class TrailingCommaInserter :
public TokenAnalyzer {
3171 TrailingCommaInserter(
const Environment &Env,
const FormatStyle &Style)
3172 : TokenAnalyzer(Env, Style) {}
3174 std::pair<tooling::Replacements, unsigned>
3175 analyze(TokenAnnotator &Annotator,
3176 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3177 FormatTokenLexer &Tokens)
override {
3178 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3179 tooling::Replacements
Result;
3180 insertTrailingCommas(AnnotatedLines,
Result);
3187 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
3188 tooling::Replacements &
Result) {
3189 for (AnnotatedLine *Line : Lines) {
3190 insertTrailingCommas(
Line->Children,
Result);
3191 if (!
Line->Affected)
3194 FormatTok = FormatTok->Next) {
3195 if (FormatTok->NewlinesBefore == 0)
3198 if (!Matching || !FormatTok->getPreviousNonComment())
3200 if (!(FormatTok->is(tok::r_square) &&
3201 Matching->is(TT_ArrayInitializerLSquare)) &&
3202 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
3205 FormatToken *Prev = FormatTok->getPreviousNonComment();
3206 if (Prev->is(tok::comma) || Prev->is(tok::semi))
3210 SourceLocation Start =
3211 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
3215 unsigned ColumnNumber =
3216 Env.getSourceManager().getSpellingColumnNumber(Start);
3217 if (ColumnNumber > Style.ColumnLimit)
3222 tooling::Replacement(Env.getSourceManager(), Start, 0,
",")));
3230class Cleaner :
public TokenAnalyzer {
3232 Cleaner(
const Environment &Env,
const FormatStyle &Style)
3233 : TokenAnalyzer(Env, Style),
3234 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
3237 std::pair<tooling::Replacements, unsigned>
3238 analyze(TokenAnnotator &Annotator,
3239 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3240 FormatTokenLexer &Tokens)
override {
3248 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3250 checkEmptyNamespace(AnnotatedLines);
3252 for (
auto *Line : AnnotatedLines)
3255 return {generateFixes(), 0};
3259 void cleanupLine(AnnotatedLine *Line) {
3260 for (
auto *Child :
Line->Children)
3263 if (
Line->Affected) {
3264 cleanupRight(
Line->First, tok::comma, tok::comma);
3265 cleanupRight(
Line->First, TT_CtorInitializerColon, tok::comma);
3266 cleanupRight(
Line->First, tok::l_paren, tok::comma);
3267 cleanupLeft(
Line->First, tok::comma, tok::r_paren);
3268 cleanupLeft(
Line->First, TT_CtorInitializerComma, tok::l_brace);
3269 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::l_brace);
3270 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::equal);
3274 bool containsOnlyComments(
const AnnotatedLine &Line) {
3276 if (
Tok->isNot(tok::comment))
3282 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3283 std::set<unsigned> DeletedLines;
3284 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
3285 auto &
Line = *AnnotatedLines[i];
3286 if (
Line.startsWithNamespace())
3287 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
3290 for (
auto Line : DeletedLines) {
3303 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3304 unsigned CurrentLine,
unsigned &NewLine,
3305 std::set<unsigned> &DeletedLines) {
3306 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
3307 if (Style.BraceWrapping.AfterNamespace) {
3311 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
3312 NewLine = CurrentLine;
3315 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
3318 while (++CurrentLine < End) {
3319 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
3322 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
3323 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
3327 CurrentLine = NewLine;
3331 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
3336 NewLine = CurrentLine;
3340 NewLine = CurrentLine;
3341 if (CurrentLine >= End)
3345 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
3346 AnnotatedLines[InitLine]->First->Tok.getLocation(),
3347 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
3351 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
3352 DeletedLines.insert(i);
3361 template <
typename LeftKind,
typename RightKind>
3362 void cleanupPair(
FormatToken *Start, LeftKind LK, RightKind RK,
3365 for (
auto *Res =
Tok.Next; Res; Res = Res->Next) {
3366 if (Res->isNot(tok::comment) &&
3367 DeletedTokens.find(Res) == DeletedTokens.end()) {
3373 for (
auto *Left = Start;
Left;) {
3374 auto *
Right = NextNotDeleted(*Left);
3378 deleteToken(DeleteLeft ? Left : Right);
3390 template <
typename LeftKind,
typename RightKind>
3391 void cleanupLeft(
FormatToken *Start, LeftKind LK, RightKind RK) {
3392 cleanupPair(Start, LK, RK,
true);
3395 template <
typename LeftKind,
typename RightKind>
3396 void cleanupRight(
FormatToken *Start, LeftKind LK, RightKind RK) {
3397 cleanupPair(Start, LK, RK,
false);
3403 DeletedTokens.insert(
Tok);
3406 tooling::Replacements generateFixes() {
3407 tooling::Replacements Fixes;
3408 SmallVector<FormatToken *> Tokens;
3409 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
3410 std::back_inserter(Tokens));
3416 while (Idx < Tokens.size()) {
3417 unsigned St = Idx, End = Idx;
3418 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3420 auto SR = CharSourceRange::getCharRange(Tokens[St]->
Tok.getLocation(),
3421 Tokens[End]->Tok.getEndLoc());
3423 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR,
""));
3427 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3428 assert(
false &&
"Fixes must not conflict!");
3439 struct FormatTokenLess {
3440 FormatTokenLess(
const SourceManager &SM) : SM(SM) {}
3443 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3444 RHS->Tok.getLocation());
3446 const SourceManager &SM;
3450 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3453class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
3455 ObjCHeaderStyleGuesser(
const Environment &Env,
const FormatStyle &Style)
3456 : TokenAnalyzer(Env, Style), IsObjC(
false) {}
3458 std::pair<tooling::Replacements, unsigned>
3459 analyze(TokenAnnotator &Annotator,
3460 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3461 FormatTokenLexer &Tokens)
override {
3463 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
3464 Tokens.getKeywords());
3465 tooling::Replacements
Result;
3469 bool isObjC() {
return IsObjC; }
3473 guessIsObjC(
const SourceManager &SourceManager,
3474 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3475 const AdditionalKeywords &Keywords) {
3477 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3492 "FOUNDATION_EXPORT",
3493 "FOUNDATION_EXTERN",
3494 "NSAffineTransform",
3496 "NSAttributedString",
3515 "NSInvocationOperation",
3519 "NSMutableAttributedString",
3520 "NSMutableCharacterSet",
3522 "NSMutableDictionary",
3523 "NSMutableIndexSet",
3524 "NSMutableOrderedSet",
3528 "NSNumberFormatter",
3532 "NSOperationQueuePriority",
3536 "NSQualityOfService",
3539 "NSRegularExpression",
3550 "NS_ASSUME_NONNULL_BEGIN",
3554 assert(llvm::is_sorted(FoundationIdentifiers));
3556 for (
auto *Line : AnnotatedLines) {
3557 if (
Line->First && (
Line->First->TokenText.starts_with(
"#") ||
3558 Line->First->TokenText ==
"__pragma" ||
3559 Line->First->TokenText ==
"_Pragma")) {
3563 FormatTok = FormatTok->Next) {
3564 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3565 (FormatTok->isNot(tok::objc_not_keyword) ||
3566 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3568 (FormatTok->Tok.isAnyIdentifier() &&
3569 llvm::binary_search(FoundationIdentifiers,
3570 FormatTok->TokenText)) ||
3571 FormatTok->is(TT_ObjCStringLiteral) ||
3572 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3573 Keywords.kw_NS_ERROR_ENUM,
3574 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3575 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3576 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3577 TT_ObjCProperty, TT_ObjCSelector)) {
3578 LLVM_DEBUG(llvm::dbgs()
3579 <<
"Detected ObjC at location "
3580 << FormatTok->Tok.getLocation().printToString(
3582 <<
" token: " << FormatTok->TokenText <<
" token type: "
3587 if (guessIsObjC(SourceManager,
Line->Children, Keywords))
3604struct JavaImportDirective {
3605 StringRef Identifier;
3608 SmallVector<StringRef> AssociatedCommentLines;
3617 for (
const auto &Range : Ranges) {
3618 if (Range.getOffset() < End &&
3619 Range.getOffset() + Range.getLength() > Start) {
3634static std::pair<unsigned, unsigned>
3637 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3638 unsigned OffsetToEOL = 0;
3639 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3640 unsigned Start = Includes[Indices[i]].Offset;
3641 unsigned End = Start + Includes[Indices[i]].Text.size();
3642 if (!(Cursor >= Start && Cursor < End))
3644 CursorIndex = Indices[i];
3645 OffsetToEOL = End - Cursor;
3648 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3652 return std::make_pair(CursorIndex, OffsetToEOL);
3657 std::string NewCode;
3658 size_t Pos = 0, LastPos = 0;
3661 Pos = Code.find(
"\r\n", LastPos);
3662 if (Pos == LastPos) {
3666 if (Pos == std::string::npos) {
3667 NewCode += Code.substr(LastPos);
3670 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3672 }
while (Pos != std::string::npos);
3690 const unsigned IncludesBeginOffset = Includes.front().Offset;
3691 const unsigned IncludesEndOffset =
3692 Includes.back().Offset + Includes.back().Text.size();
3693 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3694 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3697 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3699 if (Style.SortIncludes.Enabled) {
3700 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3701 if (Includes[LHSI].Priority != Includes[RHSI].Priority)
3702 return Includes[LHSI].Priority < Includes[RHSI].Priority;
3704 auto LHSStem = Includes[LHSI].Filename;
3705 auto RHSStem = Includes[RHSI].Filename;
3708 if (Style.SortIncludes.IgnoreExtension) {
3709 LHSStemStorage = Includes[LHSI].Filename;
3710 RHSStemStorage = Includes[RHSI].Filename;
3711 llvm::sys::path::replace_extension(LHSStemStorage,
"");
3712 llvm::sys::path::replace_extension(RHSStemStorage,
"");
3713 LHSStem = LHSStemStorage;
3714 RHSStem = RHSStemStorage;
3717 std::string LHSStemLower, RHSStemLower;
3718 std::string LHSFilenameLower, RHSFilenameLower;
3719 if (Style.SortIncludes.IgnoreCase) {
3720 LHSStemLower = LHSStem.lower();
3721 RHSStemLower = RHSStem.lower();
3722 LHSFilenameLower = Includes[LHSI].Filename.lower();
3723 RHSFilenameLower = Includes[RHSI].Filename.lower();
3726 const auto Compare = Style.SortIncludes.Natural
3727 ? &StringRef::compare_numeric
3728 : &StringRef::compare;
3730 while (Style.SortIncludes.FilesBeforeFolders) {
3731 auto [LHead, LTail] = LHSStem.split(
'/');
3732 auto [RHead, RTail] = RHSStem.split(
'/');
3734 bool LIsFile = LTail.empty();
3735 bool RIsFile = RTail.empty();
3738 if (LIsFile != RIsFile)
3747 if (Style.SortIncludes.IgnoreCase) {
3748 int Cmp = std::invoke(Compare, StringRef(LHead.lower()),
3749 StringRef(RHead.lower()));
3753 if (
int Cmp = std::invoke(Compare, LHead, RHead);
Cmp != 0)
3761 if (Style.SortIncludes.IgnoreCase) {
3762 int Cmp = std::invoke(Compare, StringRef(LHSStemLower), RHSStemLower);
3767 if (
int Cmp = std::invoke(Compare, LHSStem, RHSStem);
Cmp != 0)
3770 if (Style.SortIncludes.IgnoreCase) {
3772 std::invoke(Compare, StringRef(LHSFilenameLower), RHSFilenameLower);
3776 return std::invoke(Compare, Includes[LHSI].Filename,
3777 Includes[RHSI].Filename) < 0;
3783 unsigned CursorIndex;
3785 unsigned CursorToEOLOffset;
3787 std::tie(CursorIndex, CursorToEOLOffset) =
3792 Indices.erase(llvm::unique(Indices,
3793 [&](
unsigned LHSI,
unsigned RHSI) {
3794 return Includes[LHSI].Text.trim() ==
3795 Includes[RHSI].Text.trim();
3799 int CurrentCategory = Includes.front().Category;
3800 const auto TopLevelDirectory = [](StringRef Filename) {
3801 Filename = Filename.drop_front();
3802 const size_t SlashPos = Filename.find(
'/');
3803 return SlashPos == StringRef::npos ? StringRef()
3804 : Filename.take_front(SlashPos);
3806 StringRef CurrentDirectory = TopLevelDirectory(Includes.front().Filename);
3807 const auto DirectoryChanged = [&](StringRef Filename) {
3808 const StringRef Directory = TopLevelDirectory(Filename);
3809 return Style.SortIncludes.IgnoreCase
3810 ? !CurrentDirectory.equals_insensitive(Directory)
3811 : CurrentDirectory != Directory;
3820 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3825 const auto OldCursor = Cursor ? *Cursor : 0;
3827 for (
unsigned Index : Indices) {
3828 if (!result.empty()) {
3830 if (Style.IncludeStyle.IncludeBlocks ==
3832 CurrentCategory != Includes[Index].Category) {
3834 }
else if (Style.IncludeStyle.IncludeBlocks ==
3836 (CurrentCategory != Includes[Index].Category ||
3837 DirectoryChanged(Includes[Index].Filename))) {
3841 result += Includes[Index].Text;
3842 if (Cursor && CursorIndex == Index)
3843 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3844 CurrentCategory = Includes[Index].Category;
3845 CurrentDirectory = TopLevelDirectory(Includes[Index].Filename);
3848 if (Cursor && *Cursor >= IncludesEndOffset)
3849 *Cursor += result.size() - IncludesBlockSize;
3854 IncludesBeginOffset, IncludesBlockSize)))) {
3856 *Cursor = OldCursor;
3861 FileName, Includes.front().Offset, IncludesBlockSize, result));
3865 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3875 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3876 .StartsWith(
"\xEF\xBB\xBF", 3)
3878 unsigned SearchFrom = 0;
3890 bool FirstIncludeBlock =
true;
3891 bool MainIncludeFound =
false;
3892 bool FormattingOff =
false;
3895 llvm::Regex RawStringRegex(
3896 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3898 std::string RawStringTermination =
")\"";
3900 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3901 size_t Pos = SearchFrom;
3902 if (Code[SearchFrom] !=
'\n') {
3905 Pos = Code.find(
'\n', Pos);
3906 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3910 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3912 StringRef Trimmed =
Line.trim();
3917 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3918 std::string CharSequence = RawStringMatches[1].str();
3919 RawStringTermination =
")" + CharSequence +
"\"";
3920 FormattingOff =
true;
3923 if (Trimmed.contains(RawStringTermination))
3924 FormattingOff =
false;
3926 bool IsBlockComment =
false;
3929 FormattingOff =
true;
3931 FormattingOff =
false;
3932 }
else if (Trimmed.starts_with(
"/*")) {
3933 IsBlockComment =
true;
3934 Pos = Code.find(
"*/", SearchFrom + 2);
3937 const bool EmptyLineSkipped =
3940 Style.IncludeStyle.IncludeBlocks ==
3942 Style.IncludeStyle.IncludeBlocks ==
3945 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3946 if (!FormattingOff && !MergeWithNextLine) {
3947 if (!IsBlockComment &&
3949 StringRef IncludeName = Matches[2];
3950 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3955 Pos = Code.find(
"*/", SearchFrom);
3957 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3961 !MainIncludeFound && FirstIncludeBlock);
3963 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3965 MainIncludeFound =
true;
3966 IncludesInBlock.push_back(
3967 {IncludeName,
Line, Prev, Category, Priority});
3968 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3971 IncludesInBlock.clear();
3972 if (Trimmed.starts_with(
"#pragma hdrstop"))
3973 FirstIncludeBlock =
true;
3975 FirstIncludeBlock =
false;
3978 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3981 if (!MergeWithNextLine)
3983 SearchFrom = Pos + 1;
3985 if (!IncludesInBlock.empty()) {
3996 StringRef ImportIdentifier) {
3997 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3998 unsigned LongestMatchLength = 0;
3999 for (
unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
4000 const std::string &GroupPrefix = Style.JavaImportGroups[I];
4001 if (ImportIdentifier.starts_with(GroupPrefix) &&
4002 GroupPrefix.length() > LongestMatchLength) {
4003 LongestMatchIndex = I;
4004 LongestMatchLength = GroupPrefix.length();
4007 return LongestMatchIndex;
4019 unsigned ImportsBeginOffset = Imports.front().Offset;
4020 unsigned ImportsEndOffset =
4021 Imports.back().Offset + Imports.back().Text.size();
4022 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
4023 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
4027 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
4030 for (
const JavaImportDirective &Import : Imports)
4033 bool StaticImportAfterNormalImport =
4035 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
4037 return std::make_tuple(!Imports[LHSI].IsStatic ^
4038 StaticImportAfterNormalImport,
4040 std::make_tuple(!Imports[RHSI].IsStatic ^
4041 StaticImportAfterNormalImport,
4046 Indices.erase(llvm::unique(Indices,
4047 [&](
unsigned LHSI,
unsigned RHSI) {
4048 return Imports[LHSI].Text == Imports[RHSI].Text;
4052 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
4056 for (
unsigned Index : Indices) {
4057 if (!result.empty()) {
4059 if (CurrentIsStatic != Imports[Index].IsStatic ||
4064 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
4065 result += CommentLine;
4068 result += Imports[Index].Text;
4069 CurrentIsStatic = Imports[Index].IsStatic;
4076 Imports.front().Offset, ImportsBlockSize)))) {
4081 ImportsBlockSize, result));
4085 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
4093 JavaImportRegexPattern(
"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;");
4095constexpr StringRef JavaPackageRegexPattern(
"^package[\t ]");
4104 bool HasImport =
false;
4105 llvm::Regex ImportRegex(JavaImportRegexPattern);
4106 llvm::Regex PackageRegex(JavaPackageRegexPattern);
4111 for (
bool FormattingOff =
false;;) {
4112 auto Pos = Code.find(
'\n', Prev);
4113 auto GetLine = [&] {
4114 return Code.substr(Prev,
4115 (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
4117 StringRef
Line = GetLine();
4119 StringRef Trimmed =
Line.trim();
4120 if (Trimmed.empty() || PackageRegex.match(Trimmed)) {
4123 FormattingOff =
true;
4125 FormattingOff =
false;
4126 }
else if (Trimmed.starts_with(
"//")) {
4129 AssociatedCommentLines.push_back(
Line);
4130 }
else if (Trimmed.starts_with(
"/*")) {
4131 Pos = Code.find(
"*/", Pos + 2);
4132 if (Pos != StringRef::npos)
4133 Pos = Code.find(
'\n', Pos + 2);
4138 AssociatedCommentLines.push_back(
Line);
4140 }
else if (ImportRegex.match(Trimmed, &Matches)) {
4141 if (FormattingOff) {
4146 StringRef
Static = Matches[1];
4147 StringRef Identifier = Matches[2];
4148 bool IsStatic =
false;
4149 if (
Static.contains(
"static"))
4151 ImportsInBlock.push_back(
4152 {Identifier,
Line, Prev, AssociatedCommentLines, IsStatic});
4154 AssociatedCommentLines.clear();
4160 if (Pos == StringRef::npos || Pos + 1 == Code.size())
4173 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
4176bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
4180 StringRef
FileName,
unsigned *Cursor) {
4182 if (!Style.SortIncludes.Enabled || Style.DisableFormat)
4186 if (Style.isJavaScript()) {
4198template <
typename T>
4203 if (Replaces.
empty())
4206 auto NewCode = applyAllReplacements(Code, Replaces);
4208 return NewCode.takeError();
4213 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
4215 return Replaces.
merge(FormatReplaces);
4224 std::vector<tooling::Range> Ranges,
4228 auto SortedReplaces =
4230 if (!SortedReplaces)
4231 return SortedReplaces.takeError();
4235 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
4236 std::vector<tooling::Range> Ranges,
4246 return Replace.
getOffset() == std::numeric_limits<unsigned>::max() &&
4252inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
4253 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
4254 Replace.getLength() == 1;
4258tooling::Replacements
4259fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
4260 const FormatStyle &Style) {
4264 tooling::Replacements HeaderInsertions;
4265 std::set<StringRef> HeadersToDelete;
4266 tooling::Replacements
Result;
4267 for (
const auto &R : Replaces) {
4268 if (isHeaderInsertion(R)) {
4271 consumeError(HeaderInsertions.add(R));
4272 }
else if (isHeaderDeletion(R)) {
4273 HeadersToDelete.insert(
R.getReplacementText());
4274 }
else if (
R.getOffset() == std::numeric_limits<unsigned>::max()) {
4275 llvm::errs() <<
"Insertions other than header #include insertion are "
4277 <<
R.getReplacementText() <<
"\n";
4279 consumeError(
Result.add(R));
4282 if (HeaderInsertions.empty() && HeadersToDelete.empty())
4285 StringRef
FileName = Replaces.begin()->getFilePath();
4288 for (
const auto &Header : HeadersToDelete) {
4289 tooling::Replacements Replaces =
4290 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
4291 for (
const auto &R : Replaces) {
4292 auto Err =
Result.add(R);
4295 llvm::errs() <<
"Failed to add header deletion replacement for "
4296 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
4301 SmallVector<StringRef, 4> Matches;
4302 SmallVector<tooling::HeaderIncludes::HeaderToInsert, 4> HeadersToInsert;
4303 for (
const auto &R : HeaderInsertions) {
4307 assert(Matched &&
"Header insertion replacement must have replacement text "
4310 auto IncludeName = Matches[2];
4311 HeadersToInsert.emplace_back(IncludeName,
4314 for (
const auto &Replace : Includes.insert(HeadersToInsert)) {
4315 auto Err =
Result.add(Replace);
4317 consumeError(std::move(Err));
4318 unsigned NewOffset =
Result.getShiftedCodePosition(Replace.getOffset());
4319 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
4320 Replace.getReplacementText());
4329Expected<tooling::Replacements>
4334 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
4341 fixCppIncludeInsertions(Code, Replaces, Style);
4346std::pair<tooling::Replacements, unsigned>
4349 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef
FileName,
4382 if (Style.isJson()) {
4383 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
4385 NextStartColumn, LastStartColumn);
4390 Formatter(*Env, Style, Status).process().first;
4392 if (Code.starts_with(
"x = ")) {
4393 Replaces = Replaces.
merge(
4397 if (applyAllReplacements(Code, Replaces))
4398 return {Replaces, 0};
4403 NextStartColumn, LastStartColumn);
4421 if (Style.isCpp()) {
4428 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4429 return ParensRemover(Env, S).process(
true);
4433 if (Style.InsertBraces) {
4436 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4437 return BracesInserter(Env, S).process(
true);
4441 if (Style.RemoveBracesLLVM) {
4444 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4445 return BracesRemover(Env, S).process(
true);
4449 if (Style.RemoveSemicolon) {
4452 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4453 return SemiRemover(Env, S).process();
4459 return EnumTrailingCommaEditor(Env, Expanded)
4464 if (Style.FixNamespaceComments) {
4478 !Style.ObjCPropertyAttributeOrder.empty()) {
4484 if (Style.isJavaScript() &&
4487 return JavaScriptRequoter(Env, Expanded).process(
true);
4492 return Formatter(Env, Expanded, Status).process();
4501 if (Style.isJavaScript() &&
4504 return TrailingCommaInserter(Env, Expanded).process();
4508 std::optional<std::string> CurrentCode;
4510 unsigned Penalty = 0;
4511 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
4512 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
4513 auto NewCode = applyAllReplacements(
4514 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
4516 Fixes = Fixes.
merge(PassFixes.first);
4517 Penalty += PassFixes.second;
4519 CurrentCode = std::move(*NewCode);
4523 FirstStartColumn, NextStartColumn, LastStartColumn);
4536 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4537 if (OriginalCode != Fix.getReplacementText()) {
4538 auto Err = NonNoOpFixes.
add(Fix);
4540 llvm::errs() <<
"Error adding replacements : "
4541 <<
toString(std::move(Err)) <<
"\n";
4545 Fixes = std::move(NonNoOpFixes);
4548 return {Fixes, Penalty};
4572 return Cleaner(*Env, Style).process().first;
4577 StringRef
FileName,
bool *IncompleteFormat) {
4580 if (!Status.FormatComplete)
4581 *IncompleteFormat =
true;
4608 auto LexingStd = Style.Standard;
4615 switch (Style.Language) {
4622 LangOpts.CXXOperatorNames = 1;
4623 LangOpts.CPlusPlus11 = SinceCpp11;
4626 LangOpts.CPlusPlus20 = SinceCpp20;
4631 LangOpts.CPlusPlus = 1;
4634 LangOpts.Char8 = SinceCpp20;
4635 LangOpts.AllowLiteralDigitSeparator = LangOpts.CPlusPlus14 || LangOpts.C23;
4639 LangOpts.Digraphs = SinceCpp11;
4641 LangOpts.LineComment = 1;
4644 LangOpts.MicrosoftExt = 1;
4645 LangOpts.DeclSpecKeyword = 1;
4652 "Set coding style. <string> can be:\n"
4653 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4654 " Mozilla, WebKit.\n"
4655 "2. 'file' to load style configuration from a\n"
4656 " .clang-format file in one of the parent directories\n"
4657 " of the source file (for stdin, see --assume-filename).\n"
4658 " If no .clang-format file is found, falls back to\n"
4659 " --fallback-style.\n"
4660 " --style=file is the default.\n"
4661 "3. 'file:<format_file_path>' to explicitly specify\n"
4662 " the configuration file.\n"
4663 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4664 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4667 static constexpr std::array<llvm::StringLiteral, 2> TemplateSuffixes{
4671 for (
auto Suffix : TemplateSuffixes)
4679 if (
FileName.ends_with_insensitive(
".js") ||
4680 FileName.ends_with_insensitive(
".mjs") ||
4681 FileName.ends_with_insensitive(
".cjs") ||
4682 FileName.ends_with_insensitive(
".ts")) {
4687 if (
FileName.ends_with_insensitive(
".proto") ||
4688 FileName.ends_with_insensitive(
".protodevel")) {
4694 if (
FileName.ends_with_insensitive(
".txtpb") ||
4695 FileName.ends_with_insensitive(
".textpb") ||
4696 FileName.ends_with_insensitive(
".pb.txt") ||
4697 FileName.ends_with_insensitive(
".textproto") ||
4698 FileName.ends_with_insensitive(
".asciipb")) {
4701 if (
FileName.ends_with_insensitive(
".td"))
4703 if (
FileName.ends_with_insensitive(
".cs"))
4705 if (
FileName.ends_with_insensitive(
".json") ||
4706 FileName.ends_with_insensitive(
".ipynb")) {
4709 if (
FileName.ends_with_insensitive(
".sv") ||
4710 FileName.ends_with_insensitive(
".svh") ||
4711 FileName.ends_with_insensitive(
".v") ||
4712 FileName.ends_with_insensitive(
".vh")) {
4723 LangOpts.CPlusPlus = 1;
4724 LangOpts.LineComment = 1;
4726 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);
4730 auto Text = StringRef(SourceMgr.getCharacterData(
Tok.getLocation()),
4732 if (!
Text.consume_front(
"// clang-format Language:"))
4750 auto Extension = llvm::sys::path::extension(
FileName);
4753 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4762 if (Guesser.isObjC())
4766 return GuessedLanguage;
4774llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4777 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4779 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4780 FS->getBufferForFile(ConfigFile);
4781 if (
auto EC =
Text.getError())
4784 DiagHandler,
nullptr,
4792 StringRef FallbackStyleName, StringRef Code,
4793 llvm::vfs::FileSystem *FS,
4794 bool AllowUnknownOptions,
4795 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4803 if (StyleName.starts_with(
"{")) {
4805 StringRef Source =
"<command-line>";
4806 if (std::error_code ec =
4808 AllowUnknownOptions, DiagHandler)) {
4812 if (Style.InheritConfig.empty())
4815 ChildFormatTextToApply.emplace_back(
4816 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4820 FS = llvm::vfs::getRealFileSystem().get();
4823 const bool IsDotHFile =
FileName.ends_with(
".h");
4826 if (Style.InheritConfig.empty() &&
4827 StyleName.starts_with_insensitive(
"file:")) {
4828 auto ConfigFile = StyleName.substr(5);
4829 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4831 DiagHandler, IsDotHFile);
4832 if (
auto EC =
Text.getError()) {
4837 LLVM_DEBUG(llvm::dbgs()
4838 <<
"Using configuration file " << ConfigFile <<
"\n");
4840 if (Style.InheritConfig.empty())
4846 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4852 if (Style.InheritConfig.empty() && !StyleName.equals_insensitive(
"file")) {
4855 if (Style.InheritConfig.empty())
4859 using namespace llvm::sys::path;
4863 if (std::error_code EC = FS->makeAbsolute(Path))
4866 auto Normalize = [](String &Path) {
4867 Path = convert_to_slash(Path);
4868 remove_dots(Path,
true, Style::posix);
4874 Style.InheritConfig.clear();
4876 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4878 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4879 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4882 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4885 static_cast<void>(EC);
4891 FilesToLookFor.push_back(
".clang-format");
4892 FilesToLookFor.push_back(
"_clang-format");
4894 llvm::StringSet<> Directories;
4895 bool Redirected =
false;
4896 String Dir, UnsuitableConfigFiles;
4897 for (StringRef Directory = Path; !Directory.empty();
4898 Directory = Redirected ? Dir.str() : parent_path(Directory)) {
4899 auto Status = FS->status(Directory);
4901 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4908 for (
const auto &F : FilesToLookFor) {
4909 String ConfigFile(Directory);
4911 append(ConfigFile, F);
4912 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4914 Status = FS->status(ConfigFile);
4916 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4920 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4922 DiagHandler, IsDotHFile);
4923 if (
auto EC =
Text.getError()) {
4928 if (!UnsuitableConfigFiles.empty())
4929 UnsuitableConfigFiles.append(
", ");
4930 UnsuitableConfigFiles.append(ConfigFile);
4934 LLVM_DEBUG(llvm::dbgs()
4935 <<
"Using configuration file " << ConfigFile <<
"\n");
4937 if (Style.InheritConfig.empty()) {
4938 if (!ChildFormatTextToApply.empty()) {
4939 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4940 applyChildFormatTexts(&Style);
4945 if (!Directories.insert(Directory).second) {
4947 "Loop detected when inheriting configuration file in " + Directory);
4950 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4952 if (Style.InheritConfig ==
"..") {
4957 llvm::sys::fs::expand_tilde(Style.InheritConfig, ExpandedDir);
4958 Normalize(ExpandedDir);
4959 if (is_absolute(ExpandedDir, Style::posix)) {
4962 Dir = Directory.str();
4963 append(Dir, Style::posix, ExpandedDir);
4968 Style.InheritConfig.clear();
4970 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4980 if (!UnsuitableConfigFiles.empty()) {
4983 UnsuitableConfigFiles);
4986 if (!ChildFormatTextToApply.empty()) {
4987 LLVM_DEBUG(llvm::dbgs()
4988 <<
"Applying child configurations on fallback style\n");
4989 applyChildFormatTexts(&FallbackStyle);
4992 return FallbackStyle;
4996 if (Comment == (
On ?
"/* clang-format on */" :
"/* clang-format off */"))
4999 static const char ClangFormatOn[] =
"// clang-format on";
5000 static const char ClangFormatOff[] =
"// clang-format off";
5001 const unsigned Size = (
On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
5003 return Comment.starts_with(
On ? ClangFormatOn : ClangFormatOff) &&
5004 (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.
Result
Implement __builtin_bit_cast and related operations.
This file declares NumericLiteralCaseFixer that standardizes character case within numeric literals.
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.
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).
const char * getTokenName(TokenKind Kind) LLVM_READNONE
Determines the name of a token as used within the front end.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple punctuation tokens like '!
Top level wrappers for InstallAPI frontend operations.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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
@ On
Always emit colors regardless of the output stream.
Diagnostic wrappers for TextAPI types for error reporting.
int const char * function
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 __builtin_riscv_mqwacc_i64 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 int8_t
static void enumeration(IO &IO, BracketAlignmentStyle &Value)
static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value)
static void enumeration(IO &IO, FormatStyle::LambdaBodyIndentationKind &Value)
static void enumeration(IO &IO, FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value)
static StringRef input(StringRef Scalar, void *, clang::tok::TokenKind &Value)
static QuotingType mustQuote(StringRef)
static void output(const clang::tok::TokenKind &Value, void *, llvm::raw_ostream &Out)