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(
"CompactNamespaces", Style.CompactNamespaces);
1396 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1397 Style.ConstructorInitializerIndentWidth);
1398 IO.mapOptional(
"ContinuationIndentWidth", Style.ContinuationIndentWidth);
1399 IO.mapOptional(
"Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
1400 IO.mapOptional(
"DerivePointerAlignment", Style.DerivePointerAlignment);
1401 IO.mapOptional(
"DisableFormat", Style.DisableFormat);
1402 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1403 Style.EmptyLineAfterAccessModifier);
1404 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1405 Style.EmptyLineBeforeAccessModifier);
1406 IO.mapOptional(
"EnumTrailingComma", Style.EnumTrailingComma);
1407 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1408 Style.ExperimentalAutoDetectBinPacking);
1409 IO.mapOptional(
"FixNamespaceComments", Style.FixNamespaceComments);
1410 IO.mapOptional(
"ForEachMacros", Style.ForEachMacros);
1411 IO.mapOptional(
"IfMacros", Style.IfMacros);
1412 IO.mapOptional(
"IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1413 IO.mapOptional(
"IncludeCategories", Style.IncludeStyle.IncludeCategories);
1414 IO.mapOptional(
"IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1415 IO.mapOptional(
"IncludeIsMainSourceRegex",
1416 Style.IncludeStyle.IncludeIsMainSourceRegex);
1417 IO.mapOptional(
"IndentAccessModifiers", Style.IndentAccessModifiers);
1418 IO.mapOptional(
"IndentCaseBlocks", Style.IndentCaseBlocks);
1419 IO.mapOptional(
"IndentCaseLabels", Style.IndentCaseLabels);
1420 IO.mapOptional(
"IndentExportBlock", Style.IndentExportBlock);
1421 IO.mapOptional(
"IndentExternBlock", Style.IndentExternBlock);
1422 IO.mapOptional(
"IndentGotoLabels", Style.IndentGotoLabels);
1423 IO.mapOptional(
"IndentPPDirectives", Style.IndentPPDirectives);
1424 IO.mapOptional(
"IndentRequiresClause", Style.IndentRequiresClause);
1425 IO.mapOptional(
"IndentWidth", Style.IndentWidth);
1426 IO.mapOptional(
"IndentWrappedFunctionNames",
1427 Style.IndentWrappedFunctionNames);
1428 IO.mapOptional(
"InsertBraces", Style.InsertBraces);
1429 IO.mapOptional(
"InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1430 IO.mapOptional(
"InsertTrailingCommas", Style.InsertTrailingCommas);
1431 IO.mapOptional(
"IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1432 IO.mapOptional(
"JavaImportGroups", Style.JavaImportGroups);
1433 IO.mapOptional(
"JavaScriptQuotes", Style.JavaScriptQuotes);
1434 IO.mapOptional(
"JavaScriptWrapImports", Style.JavaScriptWrapImports);
1435 IO.mapOptional(
"KeepEmptyLines", Style.KeepEmptyLines);
1436 IO.mapOptional(
"KeepFormFeed", Style.KeepFormFeed);
1437 IO.mapOptional(
"LambdaBodyIndentation", Style.LambdaBodyIndentation);
1438 IO.mapOptional(
"LineEnding", Style.LineEnding);
1439 IO.mapOptional(
"MacroBlockBegin", Style.MacroBlockBegin);
1440 IO.mapOptional(
"MacroBlockEnd", Style.MacroBlockEnd);
1441 IO.mapOptional(
"Macros", Style.Macros);
1442 IO.mapOptional(
"MacrosSkippedByRemoveParentheses",
1443 Style.MacrosSkippedByRemoveParentheses);
1444 IO.mapOptional(
"MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1445 IO.mapOptional(
"MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1446 IO.mapOptional(
"NamespaceIndentation", Style.NamespaceIndentation);
1447 IO.mapOptional(
"NamespaceMacros", Style.NamespaceMacros);
1448 IO.mapOptional(
"NumericLiteralCase", Style.NumericLiteralCase);
1449 IO.mapOptional(
"ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1450 IO.mapOptional(
"ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1451 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1452 Style.ObjCBreakBeforeNestedBlockParam);
1453 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1454 Style.ObjCPropertyAttributeOrder);
1455 IO.mapOptional(
"ObjCSpaceAfterMethodDeclarationPrefix",
1456 Style.ObjCSpaceAfterMethodDeclarationPrefix);
1457 IO.mapOptional(
"ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1458 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1459 Style.ObjCSpaceBeforeProtocolList);
1460 IO.mapOptional(
"OneLineFormatOffRegex", Style.OneLineFormatOffRegex);
1461 IO.mapOptional(
"PackArguments", Style.PackArguments);
1462 IO.mapOptional(
"PackConstructorInitializers",
1463 Style.PackConstructorInitializers);
1464 IO.mapOptional(
"PackParameters", Style.PackParameters);
1465 IO.mapOptional(
"PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1466 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1467 Style.PenaltyBreakBeforeFirstCallParameter);
1468 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1469 Style.PenaltyBreakBeforeMemberAccess);
1470 IO.mapOptional(
"PenaltyBreakComment", Style.PenaltyBreakComment);
1471 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1472 Style.PenaltyBreakFirstLessLess);
1473 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1474 Style.PenaltyBreakOpenParenthesis);
1475 IO.mapOptional(
"PenaltyBreakScopeResolution",
1476 Style.PenaltyBreakScopeResolution);
1477 IO.mapOptional(
"PenaltyBreakString", Style.PenaltyBreakString);
1478 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1479 Style.PenaltyBreakTemplateDeclaration);
1480 IO.mapOptional(
"PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1481 IO.mapOptional(
"PenaltyIndentedWhitespace",
1482 Style.PenaltyIndentedWhitespace);
1483 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1484 Style.PenaltyReturnTypeOnItsOwnLine);
1485 IO.mapOptional(
"PointerAlignment", Style.PointerAlignment);
1486 IO.mapOptional(
"PPIndentWidth", Style.PPIndentWidth);
1487 IO.mapOptional(
"QualifierAlignment", Style.QualifierAlignment);
1490 Style.QualifierOrder = {
"type",
"const",
"volatile"};
1492 Style.QualifierOrder = {
"const",
"volatile",
"type"};
1494 IO.mapOptional(
"QualifierOrder", Style.QualifierOrder);
1495 IO.mapOptional(
"RawStringFormats", Style.RawStringFormats);
1496 IO.mapOptional(
"ReferenceAlignment", Style.ReferenceAlignment);
1497 IO.mapOptional(
"ReflowComments", Style.ReflowComments);
1498 IO.mapOptional(
"RemoveBracesLLVM", Style.RemoveBracesLLVM);
1499 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1500 Style.RemoveEmptyLinesInUnwrappedLines);
1501 IO.mapOptional(
"RemoveParentheses", Style.RemoveParentheses);
1502 IO.mapOptional(
"RemoveSemicolon", Style.RemoveSemicolon);
1503 IO.mapOptional(
"RequiresClausePosition", Style.RequiresClausePosition);
1504 IO.mapOptional(
"RequiresExpressionIndentation",
1505 Style.RequiresExpressionIndentation);
1506 IO.mapOptional(
"SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1507 IO.mapOptional(
"ShortNamespaceLines", Style.ShortNamespaceLines);
1508 IO.mapOptional(
"SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1509 IO.mapOptional(
"SortIncludes", Style.SortIncludes);
1510 IO.mapOptional(
"SortJavaStaticImport", Style.SortJavaStaticImport);
1511 IO.mapOptional(
"SortUsingDeclarations", Style.SortUsingDeclarations);
1512 IO.mapOptional(
"SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1513 IO.mapOptional(
"SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1514 IO.mapOptional(
"SpaceAfterOperatorKeyword",
1515 Style.SpaceAfterOperatorKeyword);
1516 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1517 Style.SpaceAfterTemplateKeyword);
1518 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1519 Style.SpaceAroundPointerQualifiers);
1520 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1521 Style.SpaceBeforeAssignmentOperators);
1522 IO.mapOptional(
"SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1523 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1524 Style.SpaceBeforeCpp11BracedList);
1525 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1526 Style.SpaceBeforeCtorInitializerColon);
1527 IO.mapOptional(
"SpaceBeforeEnumUnderlyingTypeColon",
1528 Style.SpaceBeforeEnumUnderlyingTypeColon);
1529 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1530 Style.SpaceBeforeInheritanceColon);
1531 IO.mapOptional(
"SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1532 IO.mapOptional(
"SpaceBeforeParens", Style.SpaceBeforeParens);
1533 IO.mapOptional(
"SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1534 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1535 Style.SpaceBeforeRangeBasedForLoopColon);
1536 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1537 Style.SpaceBeforeSquareBrackets);
1538 IO.mapOptional(
"SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
1539 IO.mapOptional(
"SpacesBeforeTrailingComments",
1540 Style.SpacesBeforeTrailingComments);
1541 IO.mapOptional(
"SpacesInAngles", Style.SpacesInAngles);
1542 IO.mapOptional(
"SpacesInBlockComments", Style.SpacesInBlockComments);
1543 IO.mapOptional(
"SpacesInContainerLiterals",
1544 Style.SpacesInContainerLiterals);
1545 IO.mapOptional(
"SpacesInLineCommentPrefix",
1546 Style.SpacesInLineCommentPrefix);
1547 IO.mapOptional(
"SpacesInParens", Style.SpacesInParens);
1548 IO.mapOptional(
"SpacesInParensOptions", Style.SpacesInParensOptions);
1549 IO.mapOptional(
"SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1550 IO.mapOptional(
"Standard", Style.Standard);
1551 IO.mapOptional(
"StatementAttributeLikeMacros",
1552 Style.StatementAttributeLikeMacros);
1553 IO.mapOptional(
"StatementMacros", Style.StatementMacros);
1554 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1555 Style.TableGenBreakingDAGArgOperators);
1556 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1557 Style.TableGenBreakInsideDAGArg);
1558 IO.mapOptional(
"TabWidth", Style.TabWidth);
1559 IO.mapOptional(
"TemplateNames", Style.TemplateNames);
1560 IO.mapOptional(
"TypeNames", Style.TypeNames);
1561 IO.mapOptional(
"TypenameMacros", Style.TypenameMacros);
1562 IO.mapOptional(
"UseTab", Style.UseTab);
1563 IO.mapOptional(
"VariableTemplates", Style.VariableTemplates);
1564 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1565 Style.VerilogBreakBetweenInstancePorts);
1566 IO.mapOptional(
"WhitespaceSensitiveMacros",
1567 Style.WhitespaceSensitiveMacros);
1568 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1569 Style.WrapNamespaceBodyWithEmptyLines);
1576 if (Style.AlwaysBreakAfterDefinitionReturnType ==
1579 }
else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1587 if (BreakBeforeInheritanceComma &&
1595 if (BreakConstructorInitializersBeforeComma &&
1600 if (!IsGoogleOrChromium) {
1603 Style.PackConstructorInitializers = OnNextLine
1607 }
else if (Style.PackConstructorInitializers ==
1611 else if (!OnNextLine)
1616 if (!DeriveLineEnding)
1624 if (SpaceInEmptyBlock &&
1630 (SpacesInParentheses || SpaceInEmptyParentheses ||
1631 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1632 if (SpacesInParentheses) {
1634 Style.SpacesInParensOptions.ExceptDoubleParentheses =
false;
1635 Style.SpacesInParensOptions.InConditionalStatements =
true;
1636 Style.SpacesInParensOptions.InCStyleCasts =
1637 SpacesInCStyleCastParentheses;
1638 Style.SpacesInParensOptions.InEmptyParentheses =
1639 SpaceInEmptyParentheses;
1640 Style.SpacesInParensOptions.Other =
true;
1642 Style.SpacesInParensOptions = {};
1643 Style.SpacesInParensOptions.InConditionalStatements =
1644 SpacesInConditionalStatement;
1645 Style.SpacesInParensOptions.InCStyleCasts =
1646 SpacesInCStyleCastParentheses;
1647 Style.SpacesInParensOptions.InEmptyParentheses =
1648 SpaceInEmptyParentheses;
1660template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1661 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1666 if (Index >= Seq.size()) {
1667 assert(Index == Seq.size());
1672 Template = *((
const FormatStyle *)IO.getContext());
1675 Seq.resize(Index + 1, Template);
1681template <>
struct ScalarEnumerationTraits<
FormatStyle::IndentGotoLabelStyle> {
1709 return llvm::make_error<llvm::StringError>(Message,
1710 llvm::inconvertibleErrorCode());
1714 return "clang-format.parse_error";
1722 return "Invalid argument";
1724 return "Unsuitable";
1726 return "trailing comma insertion cannot be used with bin packing";
1728 return "Invalid qualifier specified in QualifierOrder";
1730 return "Duplicate qualifier specified in QualifierOrder";
1732 return "Missing type in QualifierOrder";
1734 return "Missing QualifierOrder";
1736 llvm_unreachable(
"unexpected parse error");
1987 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1990 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1991 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1992 {
".*", 1, 0,
false}};
2082 1, std::numeric_limits<unsigned>::max()};
2156 {
"^<.*\\.h>", 1, 0,
false},
2157 {
"^<.*", 2, 0,
false},
2158 {
".*", 3, 0,
false}};
2198 "PARSE_PARTIAL_TEXT_PROTO",
2202 "ParseTextProtoOrDie",
2204 "ParsePartialTestProto",
2323 "com.google.android.apps.chrome",
2342 return ChromiumStyle;
2369 return MozillaStyle;
2374 Style.AccessModifierOffset = -4;
2375 Style.AlignAfterOpenBracket =
false;
2377 Style.AlignTrailingComments = {};
2383 Style.ColumnLimit = 0;
2385 Style.FixNamespaceComments =
false;
2386 Style.IndentWidth = 4;
2388 Style.ObjCBlockIndentWidth = 4;
2389 Style.ObjCSpaceAfterProperty =
true;
2391 Style.SpaceBeforeCpp11BracedList =
true;
2402 Style.BreakBeforeTernaryOperators =
true;
2403 Style.ColumnLimit = 79;
2405 Style.FixNamespaceComments =
false;
2406 Style.KeepFormFeed =
true;
2413 Style.ColumnLimit = 120;
2415 Style.IndentWidth = 4;
2418 Style.BraceWrapping.AfterClass =
true;
2420 Style.BraceWrapping.AfterEnum =
true;
2421 Style.BraceWrapping.AfterFunction =
true;
2422 Style.BraceWrapping.AfterNamespace =
true;
2423 Style.BraceWrapping.AfterObjCDeclaration =
true;
2424 Style.BraceWrapping.AfterStruct =
true;
2425 Style.BraceWrapping.AfterExternBlock =
true;
2426 Style.BraceWrapping.BeforeCatch =
true;
2427 Style.BraceWrapping.BeforeElse =
true;
2428 Style.BraceWrapping.BeforeWhile =
false;
2429 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
2430 Style.AllowShortEnumsOnASingleLine =
false;
2432 Style.AllowShortCaseLabelsOnASingleLine =
false;
2434 Style.AllowShortLoopsOnASingleLine =
false;
2442 Style.InsertBraces =
true;
2443 Style.InsertNewlineAtEOF =
true;
2444 Style.IntegerLiteralSeparator.Decimal = 3;
2445 Style.IntegerLiteralSeparator.DecimalMinDigitsInsert = 5;
2447 Style.RemoveBracesLLVM =
true;
2448 Style.RemoveEmptyLinesInUnwrappedLines =
true;
2450 Style.RemoveSemicolon =
true;
2464 constexpr StringRef Prefix(
"inheritparentconfig=");
2466 if (Name.equals_insensitive(
"llvm"))
2468 else if (Name.equals_insensitive(
"chromium"))
2470 else if (Name.equals_insensitive(
"mozilla"))
2472 else if (Name.equals_insensitive(
"google"))
2474 else if (Name.equals_insensitive(
"webkit"))
2476 else if (Name.equals_insensitive(
"gnu"))
2478 else if (Name.equals_insensitive(
"microsoft"))
2480 else if (Name.equals_insensitive(
"clang-format"))
2482 else if (Name.equals_insensitive(
"none"))
2484 else if (Name.equals_insensitive(Prefix.drop_back()))
2485 Style->InheritConfig =
"..";
2486 else if (Name.size() > Prefix.size() && Name.starts_with_insensitive(Prefix))
2487 Style->InheritConfig = Name.substr(Prefix.size());
2497 if (Style->QualifierOrder.empty())
2501 for (
const auto &Qualifier : Style->QualifierOrder) {
2502 if (Qualifier ==
"type")
2506 if (token == tok::identifier)
2511 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2512 Style->QualifierOrder.end());
2513 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2514 LLVM_DEBUG(llvm::dbgs()
2515 <<
"Duplicate Qualifiers " << Style->QualifierOrder.size()
2516 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2521 if (!llvm::is_contained(Style->QualifierOrder,
"type"))
2529 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2530 void *DiagHandlerCtxt,
bool IsDotHFile) {
2534 if (Config.getBuffer().trim().empty())
2536 Style->StyleSet.Clear();
2537 std::vector<FormatStyle> Styles;
2538 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2544 Input.setContext(Style);
2545 Input.setAllowUnknownKeys(AllowUnknownOptions);
2548 return Input.error();
2552 const auto StyleCount = Styles.size();
2555 for (
unsigned I = 1; I < StyleCount; ++I) {
2556 const auto Lang = Styles[I].Language;
2560 for (
unsigned J = 0; J < I; ++J) {
2562 LLVM_DEBUG(llvm::dbgs()
2563 <<
"Duplicate languages in the config file on positions "
2564 << J <<
" and " << I <<
'\n');
2570 int LanguagePos = -1;
2576 for (
unsigned I = 0; I < StyleCount; ++I) {
2577 const auto Lang = Styles[I].Language;
2591 if (LanguagePos < 0) {
2597 LanguagePos = CppPos;
2598 if (LanguagePos < 0)
2602 for (
const auto &S : llvm::reverse(llvm::drop_begin(Styles)))
2603 Style->StyleSet.Add(S);
2605 *Style = Styles[LanguagePos];
2607 if (LanguagePos == 0) {
2610 Style->StyleSet.Add(*Style);
2626 llvm::raw_string_ostream Stream(
Text);
2627 llvm::yaml::Output Output(Stream);
2634 Output << NonConstStyle;
2636 return Stream.str();
2639std::optional<FormatStyle>
2642 return std::nullopt;
2644 if (It == Styles->end())
2645 return std::nullopt;
2647 Style.StyleSet = *
this;
2652 assert(Style.Language !=
LK_None &&
2653 "Cannot add a style for LK_None to a StyleSet");
2655 !Style.StyleSet.Styles &&
2656 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2658 Styles = std::make_shared<MapType>();
2659 (*Styles)[Style.Language] = std::move(Style);
2664std::optional<FormatStyle>
2673 StringRef
Text =
"") {
2676 if (
Next &&
Next->NewlinesBefore == 0 &&
Next->isNot(tok::eof)) {
2677 Start =
Tok.getLocation();
2678 Next->WhitespaceRange =
Token.WhitespaceRange;
2680 Start =
Token.WhitespaceRange.getBegin();
2683 cantFail(
Result.add(tooling::Replacement(SourceMgr, Range,
Text)));
2686class ParensRemover :
public TokenAnalyzer {
2688 ParensRemover(
const Environment &Env,
const FormatStyle &Style)
2689 : TokenAnalyzer(Env, Style) {}
2691 std::pair<tooling::Replacements, unsigned>
2692 analyze(TokenAnnotator &Annotator,
2693 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2694 FormatTokenLexer &Tokens)
override {
2695 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2696 tooling::Replacements
Result;
2697 removeParens(AnnotatedLines,
Result);
2702 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2703 tooling::Replacements &
Result) {
2704 const auto &SourceMgr = Env.getSourceManager();
2705 for (
auto *Line : Lines) {
2706 if (!
Line->Children.empty())
2708 if (!
Line->Affected)
2710 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2711 Token = Token->
Next) {
2713 replaceToken(*Token, Token->
Next, SourceMgr,
Result,
" ");
2719class BracesInserter :
public TokenAnalyzer {
2721 BracesInserter(
const Environment &Env,
const FormatStyle &Style)
2722 : TokenAnalyzer(Env, Style) {}
2724 std::pair<tooling::Replacements, unsigned>
2725 analyze(TokenAnnotator &Annotator,
2726 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2727 FormatTokenLexer &Tokens)
override {
2728 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2729 tooling::Replacements
Result;
2730 insertBraces(AnnotatedLines,
Result);
2735 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2736 tooling::Replacements &
Result) {
2737 const auto &SourceMgr = Env.getSourceManager();
2738 int OpeningBraceSurplus = 0;
2739 for (AnnotatedLine *Line : Lines) {
2740 if (!
Line->Children.empty())
2742 if (!
Line->Affected && OpeningBraceSurplus == 0)
2745 Token = Token->
Next) {
2752 if (!
Line->Affected)
2754 Brace = Token->
is(tok::comment) ?
"\n{" :
"{";
2755 ++OpeningBraceSurplus;
2757 if (OpeningBraceSurplus == 0)
2766 cantFail(
Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2769 assert(OpeningBraceSurplus == 0);
2773class BracesRemover :
public TokenAnalyzer {
2775 BracesRemover(
const Environment &Env,
const FormatStyle &Style)
2776 : TokenAnalyzer(Env, Style) {}
2778 std::pair<tooling::Replacements, unsigned>
2779 analyze(TokenAnnotator &Annotator,
2780 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2781 FormatTokenLexer &Tokens)
override {
2782 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2783 tooling::Replacements
Result;
2784 removeBraces(AnnotatedLines,
Result);
2789 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2790 tooling::Replacements &
Result) {
2791 const auto &SourceMgr = Env.getSourceManager();
2792 const auto *End = Lines.end();
2793 for (
const auto *I = Lines.begin(); I != End; ++I) {
2794 const auto &
Line = *I;
2795 if (!
Line->Children.empty())
2797 if (!
Line->Affected)
2799 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2800 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2801 Token = Token->
Next) {
2805 assert(
Next || Token ==
Line->Last);
2806 if (!
Next && NextLine)
2807 Next = NextLine->First;
2808 replaceToken(*Token,
Next, SourceMgr,
Result);
2814class SemiRemover :
public TokenAnalyzer {
2816 SemiRemover(
const Environment &Env,
const FormatStyle &Style)
2817 : TokenAnalyzer(Env, Style) {}
2819 std::pair<tooling::Replacements, unsigned>
2820 analyze(TokenAnnotator &Annotator,
2821 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2822 FormatTokenLexer &Tokens)
override {
2823 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2824 tooling::Replacements
Result;
2825 removeSemi(Annotator, AnnotatedLines,
Result);
2830 void removeSemi(TokenAnnotator &Annotator,
2831 SmallVectorImpl<AnnotatedLine *> &Lines,
2832 tooling::Replacements &
Result) {
2834 const auto *Prev =
Tok.Previous;
2835 if (!Prev || Prev->isNot(tok::r_brace))
2837 const auto *LBrace = Prev->MatchingParen;
2838 return LBrace && LBrace->is(TT_FunctionLBrace);
2840 const auto &SourceMgr = Env.getSourceManager();
2841 const auto *End = Lines.end();
2842 for (
const auto *I = Lines.begin(); I != End; ++I) {
2843 const auto &
Line = *I;
2844 if (!
Line->Children.empty())
2845 removeSemi(Annotator,
Line->Children,
Result);
2846 if (!
Line->Affected)
2848 Annotator.calculateFormattingInformation(*Line);
2849 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2850 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2851 Token = Token->
Next) {
2852 if (Token->
isNot(tok::semi) ||
2853 (!Token->
Optional && !PrecededByFunctionRBrace(*Token))) {
2857 assert(
Next || Token ==
Line->Last);
2858 if (!
Next && NextLine)
2859 Next = NextLine->First;
2860 replaceToken(*Token,
Next, SourceMgr,
Result);
2866class EnumTrailingCommaEditor :
public TokenAnalyzer {
2868 EnumTrailingCommaEditor(
const Environment &Env,
const FormatStyle &Style)
2869 : TokenAnalyzer(Env, Style) {}
2871 std::pair<tooling::Replacements, unsigned>
2872 analyze(TokenAnnotator &Annotator,
2873 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2874 FormatTokenLexer &Tokens)
override {
2875 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2876 tooling::Replacements
Result;
2877 editEnumTrailingComma(AnnotatedLines,
Result);
2882 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2883 tooling::Replacements &
Result) {
2884 bool InEnumBraces =
false;
2886 const auto &SourceMgr = Env.getSourceManager();
2887 for (
auto *Line : Lines) {
2888 if (!
Line->Children.empty())
2889 editEnumTrailingComma(
Line->Children,
Result);
2891 Token = Token->
Next) {
2892 if (Token->
isNot(TT_EnumRBrace)) {
2893 if (Token->
is(TT_EnumLBrace))
2894 InEnumBraces =
true;
2895 else if (InEnumBraces && Token->
isNot(tok::comment))
2896 BeforeRBrace =
Line->Affected ? Token :
nullptr;
2899 InEnumBraces =
false;
2900 if (!BeforeRBrace || BeforeRBrace->HasEnumTrailingCommaHandled) {
2904 if (BeforeRBrace->is(tok::comma)) {
2906 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr,
Result);
2908 cantFail(
Result.add(tooling::Replacement(
2909 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0,
",")));
2911 BeforeRBrace->HasEnumTrailingCommaHandled =
true;
2912 BeforeRBrace =
nullptr;
2918class JavaScriptRequoter :
public TokenAnalyzer {
2920 JavaScriptRequoter(
const Environment &Env,
const FormatStyle &Style)
2921 : TokenAnalyzer(Env, Style) {}
2923 std::pair<tooling::Replacements, unsigned>
2924 analyze(TokenAnnotator &Annotator,
2925 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2926 FormatTokenLexer &Tokens)
override {
2927 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2928 tooling::Replacements
Result;
2929 requoteJSStringLiteral(AnnotatedLines,
Result);
2936 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2937 tooling::Replacements &
Result) {
2938 for (AnnotatedLine *Line : Lines) {
2939 requoteJSStringLiteral(
Line->Children,
Result);
2940 if (!
Line->Affected)
2943 FormatTok = FormatTok->Next) {
2944 StringRef Input = FormatTok->TokenText;
2945 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2949 !Input.starts_with(
"\"")) ||
2951 !Input.starts_with(
"\'"))) {
2957 SourceLocation Start = FormatTok->Tok.getLocation();
2958 auto Replace = [&](SourceLocation Start,
unsigned Length,
2959 StringRef ReplacementText) {
2960 auto Err =
Result.add(tooling::Replacement(
2961 Env.getSourceManager(), Start, Length, ReplacementText));
2965 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2969 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2970 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2971 IsSingle ?
"'" :
"\"");
2974 bool Escaped =
false;
2975 for (
size_t i = 1; i < Input.size() - 1; i++) {
2978 if (!Escaped && i + 1 < Input.size() &&
2979 ((IsSingle && Input[i + 1] ==
'"') ||
2980 (!IsSingle && Input[i + 1] ==
'\''))) {
2983 Replace(Start.getLocWithOffset(i), 1,
"");
2990 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2992 Replace(Start.getLocWithOffset(i), 0,
"\\");
3006class Formatter :
public TokenAnalyzer {
3008 Formatter(
const Environment &Env,
const FormatStyle &Style,
3009 FormattingAttemptStatus *Status)
3010 : TokenAnalyzer(Env, Style), Status(Status) {}
3012 std::pair<tooling::Replacements, unsigned>
3013 analyze(TokenAnnotator &Annotator,
3014 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3015 FormatTokenLexer &Tokens)
override {
3016 tooling::Replacements
Result;
3017 deriveLocalStyle(AnnotatedLines);
3018 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3019 for (AnnotatedLine *Line : AnnotatedLines)
3020 Annotator.calculateFormattingInformation(*Line);
3021 Annotator.setCommentLineLevels(AnnotatedLines);
3023 WhitespaceManager Whitespaces(
3024 Env.getSourceManager(), Style,
3026 ? WhitespaceManager::inputUsesCRLF(
3027 Env.getSourceManager().getBufferData(Env.getFileID()),
3030 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
3031 Env.getSourceManager(), Whitespaces, Encoding,
3032 BinPackInconclusiveFunctions);
3034 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
3035 Tokens.getKeywords(), Env.getSourceManager(),
3037 .format(AnnotatedLines,
false,
3040 Env.getFirstStartColumn(),
3041 Env.getNextStartColumn(),
3042 Env.getLastStartColumn());
3043 for (
const auto &R : Whitespaces.generateReplacements())
3045 return std::make_pair(
Result, 0);
3046 return std::make_pair(
Result, Penalty);
3051 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3052 for (
const AnnotatedLine *Line : Lines) {
3053 if (hasCpp03IncompatibleFormat(
Line->Children))
3056 if (!
Tok->hasWhitespaceBefore()) {
3057 if (
Tok->is(tok::coloncolon) &&
Tok->Previous->is(TT_TemplateOpener))
3059 if (
Tok->is(TT_TemplateCloser) &&
3060 Tok->Previous->is(TT_TemplateCloser)) {
3069 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3070 int AlignmentDiff = 0;
3072 for (
const AnnotatedLine *Line : Lines) {
3073 AlignmentDiff += countVariableAlignments(
Line->Children);
3076 if (
Tok->isNot(TT_PointerOrReference))
3079 const auto *Prev =
Tok->Previous;
3080 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
3081 const bool SpaceBefore =
Tok->hasWhitespaceBefore();
3084 while (
Tok->Next &&
Tok->Next->is(TT_PointerOrReference))
3088 const bool FollowedByName =
Next &&
Next->Tok.getIdentifierInfo();
3089 const bool SpaceAfter =
Next &&
Next->hasWhitespaceBefore();
3091 if ((!PrecededByName && !FollowedByName) ||
3093 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
3097 if ((PrecededByName && SpaceBefore) ||
3098 (FollowedByName && !SpaceAfter)) {
3101 }
else if ((PrecededByName && !SpaceBefore) ||
3102 (FollowedByName && SpaceAfter)) {
3109 return AlignmentDiff;
3113 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3114 bool HasBinPackedFunction =
false;
3115 bool HasOnePerLineFunction =
false;
3116 for (AnnotatedLine *Line : AnnotatedLines) {
3117 if (!
Line->First->Next)
3121 if (
Tok->is(PPK_BinPacked))
3122 HasBinPackedFunction =
true;
3123 if (
Tok->is(PPK_OnePerLine))
3124 HasOnePerLineFunction =
true;
3129 if (Style.DerivePointerAlignment) {
3130 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
3131 if (NetRightCount > 0)
3133 else if (NetRightCount < 0)
3138 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
3142 BinPackInconclusiveFunctions =
3143 HasBinPackedFunction || !HasOnePerLineFunction;
3146 bool BinPackInconclusiveFunctions;
3147 FormattingAttemptStatus *Status;
3161class TrailingCommaInserter :
public TokenAnalyzer {
3163 TrailingCommaInserter(
const Environment &Env,
const FormatStyle &Style)
3164 : TokenAnalyzer(Env, Style) {}
3166 std::pair<tooling::Replacements, unsigned>
3167 analyze(TokenAnnotator &Annotator,
3168 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3169 FormatTokenLexer &Tokens)
override {
3170 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3171 tooling::Replacements
Result;
3172 insertTrailingCommas(AnnotatedLines,
Result);
3179 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
3180 tooling::Replacements &
Result) {
3181 for (AnnotatedLine *Line : Lines) {
3182 insertTrailingCommas(
Line->Children,
Result);
3183 if (!
Line->Affected)
3186 FormatTok = FormatTok->Next) {
3187 if (FormatTok->NewlinesBefore == 0)
3190 if (!Matching || !FormatTok->getPreviousNonComment())
3192 if (!(FormatTok->is(tok::r_square) &&
3193 Matching->is(TT_ArrayInitializerLSquare)) &&
3194 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
3197 FormatToken *Prev = FormatTok->getPreviousNonComment();
3198 if (Prev->is(tok::comma) || Prev->is(tok::semi))
3202 SourceLocation Start =
3203 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
3207 unsigned ColumnNumber =
3208 Env.getSourceManager().getSpellingColumnNumber(Start);
3209 if (ColumnNumber > Style.ColumnLimit)
3214 tooling::Replacement(Env.getSourceManager(), Start, 0,
",")));
3222class Cleaner :
public TokenAnalyzer {
3224 Cleaner(
const Environment &Env,
const FormatStyle &Style)
3225 : TokenAnalyzer(Env, Style),
3226 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
3229 std::pair<tooling::Replacements, unsigned>
3230 analyze(TokenAnnotator &Annotator,
3231 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3232 FormatTokenLexer &Tokens)
override {
3240 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3242 checkEmptyNamespace(AnnotatedLines);
3244 for (
auto *Line : AnnotatedLines)
3247 return {generateFixes(), 0};
3251 void cleanupLine(AnnotatedLine *Line) {
3252 for (
auto *Child :
Line->Children)
3255 if (
Line->Affected) {
3256 cleanupRight(
Line->First, tok::comma, tok::comma);
3257 cleanupRight(
Line->First, TT_CtorInitializerColon, tok::comma);
3258 cleanupRight(
Line->First, tok::l_paren, tok::comma);
3259 cleanupLeft(
Line->First, tok::comma, tok::r_paren);
3260 cleanupLeft(
Line->First, TT_CtorInitializerComma, tok::l_brace);
3261 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::l_brace);
3262 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::equal);
3266 bool containsOnlyComments(
const AnnotatedLine &Line) {
3268 if (
Tok->isNot(tok::comment))
3274 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3275 std::set<unsigned> DeletedLines;
3276 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
3277 auto &
Line = *AnnotatedLines[i];
3278 if (
Line.startsWithNamespace())
3279 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
3282 for (
auto Line : DeletedLines) {
3295 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3296 unsigned CurrentLine,
unsigned &NewLine,
3297 std::set<unsigned> &DeletedLines) {
3298 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
3299 if (Style.BraceWrapping.AfterNamespace) {
3303 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
3304 NewLine = CurrentLine;
3307 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
3310 while (++CurrentLine < End) {
3311 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
3314 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
3315 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
3319 CurrentLine = NewLine;
3323 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
3328 NewLine = CurrentLine;
3332 NewLine = CurrentLine;
3333 if (CurrentLine >= End)
3337 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
3338 AnnotatedLines[InitLine]->First->Tok.getLocation(),
3339 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
3343 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
3344 DeletedLines.insert(i);
3353 template <
typename LeftKind,
typename RightKind>
3354 void cleanupPair(
FormatToken *Start, LeftKind LK, RightKind RK,
3357 for (
auto *Res =
Tok.Next; Res; Res = Res->Next) {
3358 if (Res->isNot(tok::comment) &&
3359 DeletedTokens.find(Res) == DeletedTokens.end()) {
3365 for (
auto *Left = Start;
Left;) {
3366 auto *
Right = NextNotDeleted(*Left);
3370 deleteToken(DeleteLeft ? Left : Right);
3382 template <
typename LeftKind,
typename RightKind>
3383 void cleanupLeft(
FormatToken *Start, LeftKind LK, RightKind RK) {
3384 cleanupPair(Start, LK, RK,
true);
3387 template <
typename LeftKind,
typename RightKind>
3388 void cleanupRight(
FormatToken *Start, LeftKind LK, RightKind RK) {
3389 cleanupPair(Start, LK, RK,
false);
3395 DeletedTokens.insert(
Tok);
3398 tooling::Replacements generateFixes() {
3399 tooling::Replacements Fixes;
3400 SmallVector<FormatToken *> Tokens;
3401 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
3402 std::back_inserter(Tokens));
3408 while (Idx < Tokens.size()) {
3409 unsigned St = Idx, End = Idx;
3410 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3412 auto SR = CharSourceRange::getCharRange(Tokens[St]->
Tok.getLocation(),
3413 Tokens[End]->Tok.getEndLoc());
3415 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR,
""));
3419 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3420 assert(
false &&
"Fixes must not conflict!");
3431 struct FormatTokenLess {
3432 FormatTokenLess(
const SourceManager &SM) : SM(SM) {}
3435 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3436 RHS->Tok.getLocation());
3438 const SourceManager &SM;
3442 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3445class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
3447 ObjCHeaderStyleGuesser(
const Environment &Env,
const FormatStyle &Style)
3448 : TokenAnalyzer(Env, Style), IsObjC(
false) {}
3450 std::pair<tooling::Replacements, unsigned>
3451 analyze(TokenAnnotator &Annotator,
3452 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3453 FormatTokenLexer &Tokens)
override {
3455 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
3456 Tokens.getKeywords());
3457 tooling::Replacements
Result;
3461 bool isObjC() {
return IsObjC; }
3465 guessIsObjC(
const SourceManager &SourceManager,
3466 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3467 const AdditionalKeywords &Keywords) {
3469 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3484 "FOUNDATION_EXPORT",
3485 "FOUNDATION_EXTERN",
3486 "NSAffineTransform",
3488 "NSAttributedString",
3507 "NSInvocationOperation",
3511 "NSMutableAttributedString",
3512 "NSMutableCharacterSet",
3514 "NSMutableDictionary",
3515 "NSMutableIndexSet",
3516 "NSMutableOrderedSet",
3520 "NSNumberFormatter",
3524 "NSOperationQueuePriority",
3528 "NSQualityOfService",
3531 "NSRegularExpression",
3542 "NS_ASSUME_NONNULL_BEGIN",
3546 assert(llvm::is_sorted(FoundationIdentifiers));
3548 for (
auto *Line : AnnotatedLines) {
3549 if (
Line->First && (
Line->First->TokenText.starts_with(
"#") ||
3550 Line->First->TokenText ==
"__pragma" ||
3551 Line->First->TokenText ==
"_Pragma")) {
3555 FormatTok = FormatTok->Next) {
3556 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3557 (FormatTok->isNot(tok::objc_not_keyword) ||
3558 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3560 (FormatTok->Tok.isAnyIdentifier() &&
3561 llvm::binary_search(FoundationIdentifiers,
3562 FormatTok->TokenText)) ||
3563 FormatTok->is(TT_ObjCStringLiteral) ||
3564 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3565 Keywords.kw_NS_ERROR_ENUM,
3566 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3567 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3568 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3569 TT_ObjCProperty, TT_ObjCSelector)) {
3570 LLVM_DEBUG(llvm::dbgs()
3571 <<
"Detected ObjC at location "
3572 << FormatTok->Tok.getLocation().printToString(
3574 <<
" token: " << FormatTok->TokenText <<
" token type: "
3579 if (guessIsObjC(SourceManager,
Line->Children, Keywords))
3596struct JavaImportDirective {
3597 StringRef Identifier;
3600 SmallVector<StringRef> AssociatedCommentLines;
3609 for (
const auto &Range : Ranges) {
3610 if (Range.getOffset() < End &&
3611 Range.getOffset() + Range.getLength() > Start) {
3626static std::pair<unsigned, unsigned>
3629 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3630 unsigned OffsetToEOL = 0;
3631 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3632 unsigned Start = Includes[Indices[i]].Offset;
3633 unsigned End = Start + Includes[Indices[i]].Text.size();
3634 if (!(Cursor >= Start && Cursor < End))
3636 CursorIndex = Indices[i];
3637 OffsetToEOL = End - Cursor;
3640 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3644 return std::make_pair(CursorIndex, OffsetToEOL);
3649 std::string NewCode;
3650 size_t Pos = 0, LastPos = 0;
3653 Pos = Code.find(
"\r\n", LastPos);
3654 if (Pos == LastPos) {
3658 if (Pos == std::string::npos) {
3659 NewCode += Code.substr(LastPos);
3662 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3664 }
while (Pos != std::string::npos);
3682 const unsigned IncludesBeginOffset = Includes.front().Offset;
3683 const unsigned IncludesEndOffset =
3684 Includes.back().Offset + Includes.back().Text.size();
3685 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3686 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3689 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3691 if (Style.SortIncludes.Enabled) {
3692 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3693 if (Includes[LHSI].Priority != Includes[RHSI].Priority)
3694 return Includes[LHSI].Priority < Includes[RHSI].Priority;
3696 auto LHSStem = Includes[LHSI].Filename;
3697 auto RHSStem = Includes[RHSI].Filename;
3700 if (Style.SortIncludes.IgnoreExtension) {
3701 LHSStemStorage = Includes[LHSI].Filename;
3702 RHSStemStorage = Includes[RHSI].Filename;
3703 llvm::sys::path::replace_extension(LHSStemStorage,
"");
3704 llvm::sys::path::replace_extension(RHSStemStorage,
"");
3705 LHSStem = LHSStemStorage;
3706 RHSStem = RHSStemStorage;
3709 std::string LHSStemLower, RHSStemLower;
3710 std::string LHSFilenameLower, RHSFilenameLower;
3711 if (Style.SortIncludes.IgnoreCase) {
3712 LHSStemLower = LHSStem.lower();
3713 RHSStemLower = RHSStem.lower();
3714 LHSFilenameLower = Includes[LHSI].Filename.lower();
3715 RHSFilenameLower = Includes[RHSI].Filename.lower();
3718 const auto Compare = Style.SortIncludes.Natural
3719 ? &StringRef::compare_numeric
3720 : &StringRef::compare;
3722 while (Style.SortIncludes.FilesBeforeFolders) {
3723 auto [LHead, LTail] = LHSStem.split(
'/');
3724 auto [RHead, RTail] = RHSStem.split(
'/');
3726 bool LIsFile = LTail.empty();
3727 bool RIsFile = RTail.empty();
3730 if (LIsFile != RIsFile)
3739 if (Style.SortIncludes.IgnoreCase) {
3740 int Cmp = std::invoke(Compare, StringRef(LHead.lower()),
3741 StringRef(RHead.lower()));
3745 if (
int Cmp = std::invoke(Compare, LHead, RHead);
Cmp != 0)
3753 if (Style.SortIncludes.IgnoreCase) {
3754 int Cmp = std::invoke(Compare, StringRef(LHSStemLower), RHSStemLower);
3759 if (
int Cmp = std::invoke(Compare, LHSStem, RHSStem);
Cmp != 0)
3762 if (Style.SortIncludes.IgnoreCase) {
3764 std::invoke(Compare, StringRef(LHSFilenameLower), RHSFilenameLower);
3768 return std::invoke(Compare, Includes[LHSI].Filename,
3769 Includes[RHSI].Filename) < 0;
3775 unsigned CursorIndex;
3777 unsigned CursorToEOLOffset;
3779 std::tie(CursorIndex, CursorToEOLOffset) =
3784 Indices.erase(llvm::unique(Indices,
3785 [&](
unsigned LHSI,
unsigned RHSI) {
3786 return Includes[LHSI].Text.trim() ==
3787 Includes[RHSI].Text.trim();
3791 int CurrentCategory = Includes.front().Category;
3799 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3804 const auto OldCursor = Cursor ? *Cursor : 0;
3806 for (
unsigned Index : Indices) {
3807 if (!result.empty()) {
3809 if (Style.IncludeStyle.IncludeBlocks ==
3811 CurrentCategory != Includes[Index].Category) {
3815 result += Includes[Index].Text;
3816 if (Cursor && CursorIndex == Index)
3817 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3818 CurrentCategory = Includes[Index].Category;
3821 if (Cursor && *Cursor >= IncludesEndOffset)
3822 *Cursor += result.size() - IncludesBlockSize;
3827 IncludesBeginOffset, IncludesBlockSize)))) {
3829 *Cursor = OldCursor;
3834 FileName, Includes.front().Offset, IncludesBlockSize, result));
3838 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3848 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3849 .StartsWith(
"\xEF\xBB\xBF", 3)
3851 unsigned SearchFrom = 0;
3863 bool FirstIncludeBlock =
true;
3864 bool MainIncludeFound =
false;
3865 bool FormattingOff =
false;
3868 llvm::Regex RawStringRegex(
3869 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3871 std::string RawStringTermination =
")\"";
3873 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3874 size_t Pos = SearchFrom;
3875 if (Code[SearchFrom] !=
'\n') {
3878 Pos = Code.find(
'\n', Pos);
3879 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3883 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3885 StringRef Trimmed =
Line.trim();
3890 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3891 std::string CharSequence = RawStringMatches[1].str();
3892 RawStringTermination =
")" + CharSequence +
"\"";
3893 FormattingOff =
true;
3896 if (Trimmed.contains(RawStringTermination))
3897 FormattingOff =
false;
3899 bool IsBlockComment =
false;
3902 FormattingOff =
true;
3904 FormattingOff =
false;
3905 }
else if (Trimmed.starts_with(
"/*")) {
3906 IsBlockComment =
true;
3907 Pos = Code.find(
"*/", SearchFrom + 2);
3910 const bool EmptyLineSkipped =
3913 Style.IncludeStyle.IncludeBlocks ==
3916 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3917 if (!FormattingOff && !MergeWithNextLine) {
3918 if (!IsBlockComment &&
3920 StringRef IncludeName = Matches[2];
3921 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3926 Pos = Code.find(
"*/", SearchFrom);
3928 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3932 !MainIncludeFound && FirstIncludeBlock);
3934 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3936 MainIncludeFound =
true;
3937 IncludesInBlock.push_back(
3938 {IncludeName,
Line, Prev, Category, Priority});
3939 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3942 IncludesInBlock.clear();
3943 if (Trimmed.starts_with(
"#pragma hdrstop"))
3944 FirstIncludeBlock =
true;
3946 FirstIncludeBlock =
false;
3949 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3952 if (!MergeWithNextLine)
3954 SearchFrom = Pos + 1;
3956 if (!IncludesInBlock.empty()) {
3967 StringRef ImportIdentifier) {
3968 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3969 unsigned LongestMatchLength = 0;
3970 for (
unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3971 const std::string &GroupPrefix = Style.JavaImportGroups[I];
3972 if (ImportIdentifier.starts_with(GroupPrefix) &&
3973 GroupPrefix.length() > LongestMatchLength) {
3974 LongestMatchIndex = I;
3975 LongestMatchLength = GroupPrefix.length();
3978 return LongestMatchIndex;
3990 unsigned ImportsBeginOffset = Imports.front().Offset;
3991 unsigned ImportsEndOffset =
3992 Imports.back().Offset + Imports.back().Text.size();
3993 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3994 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3998 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
4001 for (
const JavaImportDirective &Import : Imports)
4004 bool StaticImportAfterNormalImport =
4006 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
4008 return std::make_tuple(!Imports[LHSI].IsStatic ^
4009 StaticImportAfterNormalImport,
4011 std::make_tuple(!Imports[RHSI].IsStatic ^
4012 StaticImportAfterNormalImport,
4017 Indices.erase(llvm::unique(Indices,
4018 [&](
unsigned LHSI,
unsigned RHSI) {
4019 return Imports[LHSI].Text == Imports[RHSI].Text;
4023 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
4027 for (
unsigned Index : Indices) {
4028 if (!result.empty()) {
4030 if (CurrentIsStatic != Imports[Index].IsStatic ||
4035 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
4036 result += CommentLine;
4039 result += Imports[Index].Text;
4040 CurrentIsStatic = Imports[Index].IsStatic;
4047 Imports.front().Offset, ImportsBlockSize)))) {
4052 ImportsBlockSize, result));
4056 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
4064 JavaImportRegexPattern(
"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;");
4066constexpr StringRef JavaPackageRegexPattern(
"^package[\t ]");
4075 bool HasImport =
false;
4076 llvm::Regex ImportRegex(JavaImportRegexPattern);
4077 llvm::Regex PackageRegex(JavaPackageRegexPattern);
4082 for (
bool FormattingOff =
false;;) {
4083 auto Pos = Code.find(
'\n', Prev);
4084 auto GetLine = [&] {
4085 return Code.substr(Prev,
4086 (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
4088 StringRef
Line = GetLine();
4090 StringRef Trimmed =
Line.trim();
4091 if (Trimmed.empty() || PackageRegex.match(Trimmed)) {
4094 FormattingOff =
true;
4096 FormattingOff =
false;
4097 }
else if (Trimmed.starts_with(
"//")) {
4100 AssociatedCommentLines.push_back(
Line);
4101 }
else if (Trimmed.starts_with(
"/*")) {
4102 Pos = Code.find(
"*/", Pos + 2);
4103 if (Pos != StringRef::npos)
4104 Pos = Code.find(
'\n', Pos + 2);
4109 AssociatedCommentLines.push_back(
Line);
4111 }
else if (ImportRegex.match(Trimmed, &Matches)) {
4112 if (FormattingOff) {
4117 StringRef
Static = Matches[1];
4118 StringRef Identifier = Matches[2];
4119 bool IsStatic =
false;
4120 if (
Static.contains(
"static"))
4122 ImportsInBlock.push_back(
4123 {Identifier,
Line, Prev, AssociatedCommentLines, IsStatic});
4125 AssociatedCommentLines.clear();
4131 if (Pos == StringRef::npos || Pos + 1 == Code.size())
4144 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
4147bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
4151 StringRef
FileName,
unsigned *Cursor) {
4153 if (!Style.SortIncludes.Enabled || Style.DisableFormat)
4157 if (Style.isJavaScript()) {
4169template <
typename T>
4174 if (Replaces.
empty())
4177 auto NewCode = applyAllReplacements(Code, Replaces);
4179 return NewCode.takeError();
4184 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
4186 return Replaces.
merge(FormatReplaces);
4195 std::vector<tooling::Range> Ranges,
4199 auto SortedReplaces =
4201 if (!SortedReplaces)
4202 return SortedReplaces.takeError();
4206 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
4207 std::vector<tooling::Range> Ranges,
4217 return Replace.
getOffset() == std::numeric_limits<unsigned>::max() &&
4223inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
4224 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
4225 Replace.getLength() == 1;
4229tooling::Replacements
4230fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
4231 const FormatStyle &Style) {
4235 tooling::Replacements HeaderInsertions;
4236 std::set<StringRef> HeadersToDelete;
4237 tooling::Replacements
Result;
4238 for (
const auto &R : Replaces) {
4239 if (isHeaderInsertion(R)) {
4242 consumeError(HeaderInsertions.add(R));
4243 }
else if (isHeaderDeletion(R)) {
4244 HeadersToDelete.insert(
R.getReplacementText());
4245 }
else if (
R.getOffset() == std::numeric_limits<unsigned>::max()) {
4246 llvm::errs() <<
"Insertions other than header #include insertion are "
4248 <<
R.getReplacementText() <<
"\n";
4250 consumeError(
Result.add(R));
4253 if (HeaderInsertions.empty() && HeadersToDelete.empty())
4256 StringRef
FileName = Replaces.begin()->getFilePath();
4259 for (
const auto &Header : HeadersToDelete) {
4260 tooling::Replacements Replaces =
4261 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
4262 for (
const auto &R : Replaces) {
4263 auto Err =
Result.add(R);
4266 llvm::errs() <<
"Failed to add header deletion replacement for "
4267 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
4272 SmallVector<StringRef, 4> Matches;
4273 SmallVector<tooling::HeaderIncludes::HeaderToInsert, 4> HeadersToInsert;
4274 for (
const auto &R : HeaderInsertions) {
4278 assert(Matched &&
"Header insertion replacement must have replacement text "
4281 auto IncludeName = Matches[2];
4282 HeadersToInsert.emplace_back(IncludeName,
4285 for (
const auto &Replace : Includes.insert(HeadersToInsert)) {
4286 auto Err =
Result.add(Replace);
4288 consumeError(std::move(Err));
4289 unsigned NewOffset =
Result.getShiftedCodePosition(Replace.getOffset());
4290 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
4291 Replace.getReplacementText());
4300Expected<tooling::Replacements>
4305 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
4312 fixCppIncludeInsertions(Code, Replaces, Style);
4317std::pair<tooling::Replacements, unsigned>
4320 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef
FileName,
4353 if (Style.isJson()) {
4354 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
4356 NextStartColumn, LastStartColumn);
4361 Formatter(*Env, Style, Status).process().first;
4363 if (Code.starts_with(
"x = ")) {
4364 Replaces = Replaces.
merge(
4368 if (applyAllReplacements(Code, Replaces))
4369 return {Replaces, 0};
4374 NextStartColumn, LastStartColumn);
4392 if (Style.isCpp()) {
4399 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4400 return ParensRemover(Env, S).process(
true);
4404 if (Style.InsertBraces) {
4407 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4408 return BracesInserter(Env, S).process(
true);
4412 if (Style.RemoveBracesLLVM) {
4415 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4416 return BracesRemover(Env, S).process(
true);
4420 if (Style.RemoveSemicolon) {
4423 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4424 return SemiRemover(Env, S).process();
4430 return EnumTrailingCommaEditor(Env, Expanded)
4435 if (Style.FixNamespaceComments) {
4449 !Style.ObjCPropertyAttributeOrder.empty()) {
4455 if (Style.isJavaScript() &&
4458 return JavaScriptRequoter(Env, Expanded).process(
true);
4463 return Formatter(Env, Expanded, Status).process();
4472 if (Style.isJavaScript() &&
4475 return TrailingCommaInserter(Env, Expanded).process();
4479 std::optional<std::string> CurrentCode;
4481 unsigned Penalty = 0;
4482 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
4483 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
4484 auto NewCode = applyAllReplacements(
4485 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
4487 Fixes = Fixes.
merge(PassFixes.first);
4488 Penalty += PassFixes.second;
4490 CurrentCode = std::move(*NewCode);
4494 FirstStartColumn, NextStartColumn, LastStartColumn);
4507 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4508 if (OriginalCode != Fix.getReplacementText()) {
4509 auto Err = NonNoOpFixes.
add(Fix);
4511 llvm::errs() <<
"Error adding replacements : "
4512 <<
toString(std::move(Err)) <<
"\n";
4516 Fixes = std::move(NonNoOpFixes);
4519 return {Fixes, Penalty};
4543 return Cleaner(*Env, Style).process().first;
4548 StringRef
FileName,
bool *IncompleteFormat) {
4551 if (!Status.FormatComplete)
4552 *IncompleteFormat =
true;
4579 auto LexingStd = Style.Standard;
4586 switch (Style.Language) {
4593 LangOpts.CXXOperatorNames = 1;
4594 LangOpts.CPlusPlus11 = SinceCpp11;
4597 LangOpts.CPlusPlus20 = SinceCpp20;
4602 LangOpts.CPlusPlus = 1;
4605 LangOpts.Char8 = SinceCpp20;
4606 LangOpts.AllowLiteralDigitSeparator = LangOpts.CPlusPlus14 || LangOpts.C23;
4610 LangOpts.Digraphs = SinceCpp11;
4612 LangOpts.LineComment = 1;
4615 LangOpts.MicrosoftExt = 1;
4616 LangOpts.DeclSpecKeyword = 1;
4623 "Set coding style. <string> can be:\n"
4624 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4625 " Mozilla, WebKit.\n"
4626 "2. 'file' to load style configuration from a\n"
4627 " .clang-format file in one of the parent directories\n"
4628 " of the source file (for stdin, see --assume-filename).\n"
4629 " If no .clang-format file is found, falls back to\n"
4630 " --fallback-style.\n"
4631 " --style=file is the default.\n"
4632 "3. 'file:<format_file_path>' to explicitly specify\n"
4633 " the configuration file.\n"
4634 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4635 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4638 static constexpr std::array<llvm::StringLiteral, 2> TemplateSuffixes{
4642 for (
auto Suffix : TemplateSuffixes)
4650 if (
FileName.ends_with_insensitive(
".js") ||
4651 FileName.ends_with_insensitive(
".mjs") ||
4652 FileName.ends_with_insensitive(
".cjs") ||
4653 FileName.ends_with_insensitive(
".ts")) {
4658 if (
FileName.ends_with_insensitive(
".proto") ||
4659 FileName.ends_with_insensitive(
".protodevel")) {
4665 if (
FileName.ends_with_insensitive(
".txtpb") ||
4666 FileName.ends_with_insensitive(
".textpb") ||
4667 FileName.ends_with_insensitive(
".pb.txt") ||
4668 FileName.ends_with_insensitive(
".textproto") ||
4669 FileName.ends_with_insensitive(
".asciipb")) {
4672 if (
FileName.ends_with_insensitive(
".td"))
4674 if (
FileName.ends_with_insensitive(
".cs"))
4676 if (
FileName.ends_with_insensitive(
".json") ||
4677 FileName.ends_with_insensitive(
".ipynb")) {
4680 if (
FileName.ends_with_insensitive(
".sv") ||
4681 FileName.ends_with_insensitive(
".svh") ||
4682 FileName.ends_with_insensitive(
".v") ||
4683 FileName.ends_with_insensitive(
".vh")) {
4694 LangOpts.CPlusPlus = 1;
4695 LangOpts.LineComment = 1;
4697 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);
4701 auto Text = StringRef(SourceMgr.getCharacterData(
Tok.getLocation()),
4703 if (!
Text.consume_front(
"// clang-format Language:"))
4721 auto Extension = llvm::sys::path::extension(
FileName);
4724 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4733 if (Guesser.isObjC())
4737 return GuessedLanguage;
4745llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4748 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4750 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4751 FS->getBufferForFile(ConfigFile);
4752 if (
auto EC =
Text.getError())
4755 DiagHandler,
nullptr,
4763 StringRef FallbackStyleName, StringRef Code,
4764 llvm::vfs::FileSystem *FS,
4765 bool AllowUnknownOptions,
4766 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4774 if (StyleName.starts_with(
"{")) {
4776 StringRef Source =
"<command-line>";
4777 if (std::error_code ec =
4779 AllowUnknownOptions, DiagHandler)) {
4783 if (Style.InheritConfig.empty())
4786 ChildFormatTextToApply.emplace_back(
4787 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4791 FS = llvm::vfs::getRealFileSystem().get();
4794 const bool IsDotHFile =
FileName.ends_with(
".h");
4797 if (Style.InheritConfig.empty() &&
4798 StyleName.starts_with_insensitive(
"file:")) {
4799 auto ConfigFile = StyleName.substr(5);
4800 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4802 DiagHandler, IsDotHFile);
4803 if (
auto EC =
Text.getError()) {
4808 LLVM_DEBUG(llvm::dbgs()
4809 <<
"Using configuration file " << ConfigFile <<
"\n");
4811 if (Style.InheritConfig.empty())
4817 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4823 if (Style.InheritConfig.empty() && !StyleName.equals_insensitive(
"file")) {
4826 if (Style.InheritConfig.empty())
4830 using namespace llvm::sys::path;
4834 if (std::error_code EC = FS->makeAbsolute(Path))
4837 auto Normalize = [](String &Path) {
4838 Path = convert_to_slash(Path);
4839 remove_dots(Path,
true, Style::posix);
4845 Style.InheritConfig.clear();
4847 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4849 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4850 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4853 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4856 static_cast<void>(EC);
4862 FilesToLookFor.push_back(
".clang-format");
4863 FilesToLookFor.push_back(
"_clang-format");
4865 llvm::StringSet<> Directories;
4866 bool Redirected =
false;
4867 String Dir, UnsuitableConfigFiles;
4868 for (StringRef Directory = Path; !Directory.empty();
4869 Directory = Redirected ? Dir.str() : parent_path(Directory)) {
4870 auto Status = FS->status(Directory);
4872 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4879 for (
const auto &F : FilesToLookFor) {
4880 String ConfigFile(Directory);
4882 append(ConfigFile, F);
4883 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4885 Status = FS->status(ConfigFile);
4887 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4891 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4893 DiagHandler, IsDotHFile);
4894 if (
auto EC =
Text.getError()) {
4899 if (!UnsuitableConfigFiles.empty())
4900 UnsuitableConfigFiles.append(
", ");
4901 UnsuitableConfigFiles.append(ConfigFile);
4905 LLVM_DEBUG(llvm::dbgs()
4906 <<
"Using configuration file " << ConfigFile <<
"\n");
4908 if (Style.InheritConfig.empty()) {
4909 if (!ChildFormatTextToApply.empty()) {
4910 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4911 applyChildFormatTexts(&Style);
4916 if (!Directories.insert(Directory).second) {
4918 "Loop detected when inheriting configuration file in " + Directory);
4921 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4923 if (Style.InheritConfig ==
"..") {
4928 llvm::sys::fs::expand_tilde(Style.InheritConfig, ExpandedDir);
4929 Normalize(ExpandedDir);
4930 if (is_absolute(ExpandedDir, Style::posix)) {
4933 Dir = Directory.str();
4934 append(Dir, Style::posix, ExpandedDir);
4939 Style.InheritConfig.clear();
4941 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4951 if (!UnsuitableConfigFiles.empty()) {
4954 UnsuitableConfigFiles);
4957 if (!ChildFormatTextToApply.empty()) {
4958 LLVM_DEBUG(llvm::dbgs()
4959 <<
"Applying child configurations on fallback style\n");
4960 applyChildFormatTexts(&FallbackStyle);
4963 return FallbackStyle;
4967 if (Comment == (
On ?
"/* clang-format on */" :
"/* clang-format off */"))
4970 static const char ClangFormatOn[] =
"// clang-format on";
4971 static const char ClangFormatOff[] =
"// clang-format off";
4972 const unsigned Size = (
On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4974 return Comment.starts_with(
On ? ClangFormatOn : ClangFormatOff) &&
4975 (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 __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)