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::IndentExternBlockStyle> {
491template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
493 IO.mapOptional(
"Binary",
Base.Binary);
494 IO.mapOptional(
"BinaryMinDigitsInsert",
Base.BinaryMinDigitsInsert);
495 IO.mapOptional(
"BinaryMaxDigitsRemove",
Base.BinaryMaxDigitsRemove);
496 IO.mapOptional(
"Decimal",
Base.Decimal);
497 IO.mapOptional(
"DecimalMinDigitsInsert",
Base.DecimalMinDigitsInsert);
498 IO.mapOptional(
"DecimalMaxDigitsRemove",
Base.DecimalMaxDigitsRemove);
499 IO.mapOptional(
"Hex",
Base.Hex);
500 IO.mapOptional(
"HexMinDigitsInsert",
Base.HexMinDigitsInsert);
501 IO.mapOptional(
"HexMaxDigitsRemove",
Base.HexMaxDigitsRemove);
504 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigitsInsert);
505 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigitsInsert);
506 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigitsInsert);
510template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
518template <>
struct MappingTraits<
FormatStyle::KeepEmptyLinesStyle> {
520 IO.mapOptional(
"AtEndOfFile",
Value.AtEndOfFile);
521 IO.mapOptional(
"AtStartOfBlock",
Value.AtStartOfBlock);
522 IO.mapOptional(
"AtStartOfFile",
Value.AtStartOfFile);
526template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
542template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
564struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
572template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
582struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
592struct ScalarEnumerationTraits<
FormatStyle::NumericLiteralComponentStyle> {
601template <>
struct MappingTraits<
FormatStyle::NumericLiteralCaseStyle> {
603 IO.mapOptional(
"ExponentLetter",
Value.ExponentLetter);
604 IO.mapOptional(
"HexDigit",
Value.HexDigit);
605 IO.mapOptional(
"Prefix",
Value.Prefix);
606 IO.mapOptional(
"Suffix",
Value.Suffix);
610template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
614 IO.enumCase(
Value,
"AlignAfterOperator",
623template <>
struct MappingTraits<
FormatStyle::PackParametersStyle> {
625 IO.mapOptional(
"BinPack",
Value.BinPack);
626 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
631struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
642template <>
struct MappingTraits<
FormatStyle::PackArgumentsStyle> {
644 IO.mapOptional(
"BinPack",
Value.BinPack);
645 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
649template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
662struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
672struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
683 IO.mapOptional(
"Language", Format.Language);
684 IO.mapOptional(
"Delimiters", Format.Delimiters);
685 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
686 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
687 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
691template <>
struct ScalarEnumerationTraits<
FormatStyle::ReflowCommentsStyle> {
703struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
713struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
716 IO.enumCase(
Value,
"MultipleParentheses",
723struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
735struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
744struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
751 IO.enumCase(
Value,
"TopLevelDefinitions",
758struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeReturnTypeStyle> {
765 IO.enumCase(
Value,
"TopLevelDefinitions",
771struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
779template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
789template <>
struct MappingTraits<
FormatStyle::ShortFunctionStyle> {
792 IO.enumCase(
Value,
"Empty",
794 IO.enumCase(
Value,
"Inline",
796 IO.enumCase(
Value,
"InlineOnly",
806 IO.mapOptional(
"Empty",
Value.Empty);
807 IO.mapOptional(
"Inline",
Value.Inline);
808 IO.mapOptional(
"Other",
Value.Other);
812template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
826template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
837template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortRecordStyle> {
846template <>
struct MappingTraits<
FormatStyle::SortIncludesOptions> {
849 IO.enumCase(
Value,
"CaseInsensitive",
855 IO.enumCase(
Value,
"CaseSensitive",
861 IO.enumCase(
Value,
"Natural",
870 IO.enumCase(
Value,
"true",
878 IO.mapOptional(
"Enabled",
Value.Enabled);
879 IO.mapOptional(
"IgnoreCase",
Value.IgnoreCase);
880 IO.mapOptional(
"IgnoreExtension",
Value.IgnoreExtension);
881 IO.mapOptional(
"Natural",
Value.Natural);
882 IO.mapOptional(
"FilesBeforeFolders",
Value.FilesBeforeFolders);
887struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
896struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
901 IO.enumCase(
Value,
"LexicographicNumeric",
911struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
921template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
925 IO.mapOptional(
"AfterFunctionDefinitionName",
927 IO.mapOptional(
"AfterFunctionDeclarationName",
930 IO.mapOptional(
"AfterNot", Spacing.
AfterNot);
934 IO.mapOptional(
"AfterRequiresInExpression",
936 IO.mapOptional(
"BeforeNonEmptyParentheses",
942struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
945 IO.enumCase(
Value,
"ControlStatements",
947 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
949 IO.enumCase(
Value,
"NonEmptyParentheses",
957 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
963struct ScalarEnumerationTraits<
FormatStyle::SpaceInEmptyBracesStyle> {
971template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
984struct ScalarEnumerationTraits<
FormatStyle::SpacesInBlockCommentsStyle> {
993template <>
struct MappingTraits<
FormatStyle::SpacesInLineComment> {
996 int signedMaximum =
static_cast<int>(Space.
Maximum);
997 IO.mapOptional(
"Minimum", Space.
Minimum);
998 IO.mapOptional(
"Maximum", signedMaximum);
999 Space.
Maximum =
static_cast<unsigned>(signedMaximum);
1001 if (Space.
Maximum < std::numeric_limits<unsigned>::max())
1012 IO.mapOptional(
"Other", Spaces.
Other);
1016template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
1023template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
1031struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
1040template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
1043 IO.enumCase(
Value,
"Leave",
1047 IO.enumCase(
Value,
"Always",
1051 IO.enumCase(
Value,
"Never",
1056 IO.enumCase(
Value,
"true",
1059 IO.enumCase(
Value,
"false",
1066 IO.mapOptional(
"AlignPPAndNotPP",
Value.AlignPPAndNotPP);
1067 IO.mapOptional(
"Kind",
Value.Kind);
1068 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
1079 IO.enumCase(
Value,
"ForContinuationAndIndentation",
1086struct ScalarEnumerationTraits<
1087 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
1100 IO.mapOptional(
"Language", Style.Language);
1102 StringRef BasedOnStyle;
1103 if (IO.outputting()) {
1104 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
1105 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
1106 for (StringRef StyleName : Styles) {
1108 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
1109 Style == PredefinedStyle) {
1110 BasedOnStyle = StyleName;
1115 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
1116 if (!BasedOnStyle.empty()) {
1120 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
1121 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
1124 Style.Language = OldLanguage;
1139 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
1140 BasedOnStyle.equals_insensitive(
"chromium");
1141 bool OnCurrentLine = IsGoogleOrChromium;
1142 bool OnNextLine =
true;
1144 bool BreakBeforeInheritanceComma =
false;
1145 bool BreakConstructorInitializersBeforeComma =
false;
1147 bool DeriveLineEnding =
true;
1148 bool UseCRLF =
false;
1150 bool SpaceInEmptyBlock =
false;
1151 bool SpaceInEmptyParentheses =
false;
1152 bool SpacesInConditionalStatement =
false;
1153 bool SpacesInCStyleCastParentheses =
false;
1154 bool SpacesInParentheses =
false;
1156 if (IO.outputting()) {
1157 IO.mapOptional(
"AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
1161 if (IsGoogleOrChromium) {
1164 Language = ((
FormatStyle *)IO.getContext())->Language;
1169 }
else if (BasedOnStyle.equals_insensitive(
"webkit")) {
1172 IO.mapOptional(
"AlignAfterOpenBracket", LocalBAS);
1176 Style.AlignAfterOpenBracket =
false;
1177 Style.BreakAfterOpenBracketBracedList =
false;
1178 Style.BreakAfterOpenBracketFunction =
false;
1179 Style.BreakAfterOpenBracketIf =
false;
1180 Style.BreakAfterOpenBracketLoop =
false;
1181 Style.BreakAfterOpenBracketSwitch =
false;
1182 Style.BreakBeforeCloseBracketBracedList =
false;
1183 Style.BreakBeforeCloseBracketFunction =
false;
1184 Style.BreakBeforeCloseBracketIf =
false;
1185 Style.BreakBeforeCloseBracketLoop =
false;
1186 Style.BreakBeforeCloseBracketSwitch =
false;
1189 Style.AlignAfterOpenBracket =
true;
1190 Style.BreakAfterOpenBracketBracedList =
true;
1191 Style.BreakAfterOpenBracketFunction =
true;
1192 Style.BreakAfterOpenBracketIf =
true;
1193 Style.BreakAfterOpenBracketLoop =
false;
1194 Style.BreakAfterOpenBracketSwitch =
false;
1195 Style.BreakBeforeCloseBracketBracedList =
true;
1196 Style.BreakBeforeCloseBracketFunction =
true;
1197 Style.BreakBeforeCloseBracketIf =
true;
1198 Style.BreakBeforeCloseBracketLoop =
false;
1199 Style.BreakBeforeCloseBracketSwitch =
false;
1202 Style.AlignAfterOpenBracket =
true;
1203 Style.BreakAfterOpenBracketBracedList =
true;
1204 Style.BreakAfterOpenBracketFunction =
true;
1205 Style.BreakAfterOpenBracketIf =
true;
1206 Style.BreakAfterOpenBracketLoop =
false;
1207 Style.BreakAfterOpenBracketSwitch =
false;
1208 Style.BreakBeforeCloseBracketBracedList =
false;
1209 Style.BreakBeforeCloseBracketFunction =
false;
1210 Style.BreakBeforeCloseBracketIf =
false;
1211 Style.BreakBeforeCloseBracketLoop =
false;
1212 Style.BreakBeforeCloseBracketSwitch =
false;
1215 Style.AlignAfterOpenBracket =
true;
1216 Style.BreakAfterOpenBracketBracedList =
false;
1217 Style.BreakAfterOpenBracketFunction =
false;
1218 Style.BreakAfterOpenBracketIf =
false;
1219 Style.BreakAfterOpenBracketLoop =
false;
1220 Style.BreakAfterOpenBracketSwitch =
false;
1221 Style.BreakBeforeCloseBracketBracedList =
false;
1222 Style.BreakBeforeCloseBracketFunction =
false;
1223 Style.BreakBeforeCloseBracketIf =
false;
1224 Style.BreakBeforeCloseBracketLoop =
false;
1225 Style.BreakBeforeCloseBracketSwitch =
false;
1233 if (!IO.outputting()) {
1234 IO.mapOptional(
"AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
1235 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
1236 IO.mapOptional(
"AlwaysBreakAfterReturnType", Style.BreakAfterReturnType);
1237 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
1238 Style.BreakTemplateDeclarations);
1239 IO.mapOptional(
"BinPackArguments", Style.PackArguments.BinPack);
1240 IO.mapOptional(
"BinPackParameters", Style.PackParameters.BinPack);
1241 IO.mapOptional(
"BreakBeforeInheritanceComma",
1242 BreakBeforeInheritanceComma);
1243 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
1244 BreakConstructorInitializersBeforeComma);
1245 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
1247 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
1248 IO.mapOptional(
"DerivePointerBinding", Style.DerivePointerAlignment);
1249 IO.mapOptional(
"KeepEmptyLinesAtEOF", Style.KeepEmptyLines.AtEndOfFile);
1250 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
1251 Style.KeepEmptyLines.AtStartOfBlock);
1252 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
1253 Style.IndentWrappedFunctionNames);
1254 IO.mapOptional(
"IndentRequires", Style.IndentRequiresClause);
1255 IO.mapOptional(
"PointerBindsToType", Style.PointerAlignment);
1256 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
1257 Style.SpaceBeforeParens);
1258 IO.mapOptional(
"SpaceInEmptyBlock", SpaceInEmptyBlock);
1259 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
1260 IO.mapOptional(
"SpacesInConditionalStatement",
1261 SpacesInConditionalStatement);
1262 IO.mapOptional(
"SpacesInCStyleCastParentheses",
1263 SpacesInCStyleCastParentheses);
1264 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
1265 IO.mapOptional(
"UseCRLF", UseCRLF);
1268 IO.mapOptional(
"AccessModifierOffset", Style.AccessModifierOffset);
1269 IO.mapOptional(
"AlignArrayOfStructures", Style.AlignArrayOfStructures);
1270 IO.mapOptional(
"AlignConsecutiveAssignments",
1271 Style.AlignConsecutiveAssignments);
1272 IO.mapOptional(
"AlignConsecutiveBitFields",
1273 Style.AlignConsecutiveBitFields);
1274 IO.mapOptional(
"AlignConsecutiveDeclarations",
1275 Style.AlignConsecutiveDeclarations);
1276 IO.mapOptional(
"AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
1277 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
1278 Style.AlignConsecutiveShortCaseStatements);
1279 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
1280 Style.AlignConsecutiveTableGenBreakingDAGArgColons);
1281 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
1282 Style.AlignConsecutiveTableGenCondOperatorColons);
1283 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
1284 Style.AlignConsecutiveTableGenDefinitionColons);
1285 IO.mapOptional(
"AlignEscapedNewlines", Style.AlignEscapedNewlines);
1286 IO.mapOptional(
"AlignOperands", Style.AlignOperands);
1287 IO.mapOptional(
"AlignTrailingComments", Style.AlignTrailingComments);
1288 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
1289 Style.AllowAllArgumentsOnNextLine);
1290 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
1291 Style.AllowAllParametersOfDeclarationOnNextLine);
1292 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
1293 Style.AllowBreakBeforeNoexceptSpecifier);
1294 IO.mapOptional(
"AllowBreakBeforeQtProperty",
1295 Style.AllowBreakBeforeQtProperty);
1296 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
1297 Style.AllowShortBlocksOnASingleLine);
1298 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
1299 Style.AllowShortCaseExpressionOnASingleLine);
1300 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
1301 Style.AllowShortCaseLabelsOnASingleLine);
1302 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
1303 Style.AllowShortCompoundRequirementOnASingleLine);
1304 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
1305 Style.AllowShortEnumsOnASingleLine);
1306 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
1307 Style.AllowShortFunctionsOnASingleLine);
1308 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
1309 Style.AllowShortIfStatementsOnASingleLine);
1310 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
1311 Style.AllowShortLambdasOnASingleLine);
1312 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
1313 Style.AllowShortLoopsOnASingleLine);
1314 IO.mapOptional(
"AllowShortNamespacesOnASingleLine",
1315 Style.AllowShortNamespacesOnASingleLine);
1316 IO.mapOptional(
"AllowShortRecordOnASingleLine",
1317 Style.AllowShortRecordOnASingleLine);
1318 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
1319 Style.AlwaysBreakAfterDefinitionReturnType);
1320 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
1321 Style.AlwaysBreakBeforeMultilineStrings);
1322 IO.mapOptional(
"AttributeMacros", Style.AttributeMacros);
1323 IO.mapOptional(
"BinPackLongBracedList", Style.BinPackLongBracedList);
1324 IO.mapOptional(
"BitFieldColonSpacing", Style.BitFieldColonSpacing);
1325 IO.mapOptional(
"BracedInitializerIndentWidth",
1326 Style.BracedInitializerIndentWidth);
1327 IO.mapOptional(
"BraceWrapping", Style.BraceWrapping);
1328 IO.mapOptional(
"BreakAdjacentStringLiterals",
1329 Style.BreakAdjacentStringLiterals);
1330 IO.mapOptional(
"BreakAfterAttributes", Style.BreakAfterAttributes);
1331 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
1332 Style.BreakAfterJavaFieldAnnotations);
1333 IO.mapOptional(
"BreakAfterOpenBracketBracedList",
1334 Style.BreakAfterOpenBracketBracedList);
1335 IO.mapOptional(
"BreakAfterOpenBracketFunction",
1336 Style.BreakAfterOpenBracketFunction);
1337 IO.mapOptional(
"BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf);
1338 IO.mapOptional(
"BreakAfterOpenBracketLoop",
1339 Style.BreakAfterOpenBracketLoop);
1340 IO.mapOptional(
"BreakAfterOpenBracketSwitch",
1341 Style.BreakAfterOpenBracketSwitch);
1342 IO.mapOptional(
"BreakAfterReturnType", Style.BreakAfterReturnType);
1343 IO.mapOptional(
"BreakArrays", Style.BreakArrays);
1344 IO.mapOptional(
"BreakBeforeBinaryOperators",
1345 Style.BreakBeforeBinaryOperators);
1346 IO.mapOptional(
"BreakBeforeCloseBracketBracedList",
1347 Style.BreakBeforeCloseBracketBracedList);
1348 IO.mapOptional(
"BreakBeforeCloseBracketFunction",
1349 Style.BreakBeforeCloseBracketFunction);
1350 IO.mapOptional(
"BreakBeforeCloseBracketIf",
1351 Style.BreakBeforeCloseBracketIf);
1352 IO.mapOptional(
"BreakBeforeCloseBracketLoop",
1353 Style.BreakBeforeCloseBracketLoop);
1354 IO.mapOptional(
"BreakBeforeCloseBracketSwitch",
1355 Style.BreakBeforeCloseBracketSwitch);
1356 IO.mapOptional(
"BreakBeforeConceptDeclarations",
1357 Style.BreakBeforeConceptDeclarations);
1358 IO.mapOptional(
"BreakBeforeBraces", Style.BreakBeforeBraces);
1359 IO.mapOptional(
"BreakBeforeInlineASMColon",
1360 Style.BreakBeforeInlineASMColon);
1361 IO.mapOptional(
"BreakBeforeReturnType", Style.BreakBeforeReturnType);
1362 IO.mapOptional(
"BreakBeforeTemplateCloser",
1363 Style.BreakBeforeTemplateCloser);
1364 IO.mapOptional(
"BreakBeforeTernaryOperators",
1365 Style.BreakBeforeTernaryOperators);
1366 IO.mapOptional(
"BreakBinaryOperations", Style.BreakBinaryOperations);
1367 IO.mapOptional(
"BreakConstructorInitializers",
1368 Style.BreakConstructorInitializers);
1369 IO.mapOptional(
"BreakFunctionDeclarationParameters",
1370 Style.BreakFunctionDeclarationParameters);
1371 IO.mapOptional(
"BreakFunctionDefinitionParameters",
1372 Style.BreakFunctionDefinitionParameters);
1373 IO.mapOptional(
"BreakInheritanceList", Style.BreakInheritanceList);
1374 IO.mapOptional(
"BreakStringLiterals", Style.BreakStringLiterals);
1375 IO.mapOptional(
"BreakTemplateDeclarations",
1376 Style.BreakTemplateDeclarations);
1377 IO.mapOptional(
"ColumnLimit", Style.ColumnLimit);
1378 IO.mapOptional(
"CommentPragmas", Style.CommentPragmas);
1379 IO.mapOptional(
"CompactNamespaces", Style.CompactNamespaces);
1380 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1381 Style.ConstructorInitializerIndentWidth);
1382 IO.mapOptional(
"ContinuationIndentWidth", Style.ContinuationIndentWidth);
1383 IO.mapOptional(
"Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
1384 IO.mapOptional(
"DerivePointerAlignment", Style.DerivePointerAlignment);
1385 IO.mapOptional(
"DisableFormat", Style.DisableFormat);
1386 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1387 Style.EmptyLineAfterAccessModifier);
1388 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1389 Style.EmptyLineBeforeAccessModifier);
1390 IO.mapOptional(
"EnumTrailingComma", Style.EnumTrailingComma);
1391 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1392 Style.ExperimentalAutoDetectBinPacking);
1393 IO.mapOptional(
"FixNamespaceComments", Style.FixNamespaceComments);
1394 IO.mapOptional(
"ForEachMacros", Style.ForEachMacros);
1395 IO.mapOptional(
"IfMacros", Style.IfMacros);
1396 IO.mapOptional(
"IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1397 IO.mapOptional(
"IncludeCategories", Style.IncludeStyle.IncludeCategories);
1398 IO.mapOptional(
"IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1399 IO.mapOptional(
"IncludeIsMainSourceRegex",
1400 Style.IncludeStyle.IncludeIsMainSourceRegex);
1401 IO.mapOptional(
"IndentAccessModifiers", Style.IndentAccessModifiers);
1402 IO.mapOptional(
"IndentCaseBlocks", Style.IndentCaseBlocks);
1403 IO.mapOptional(
"IndentCaseLabels", Style.IndentCaseLabels);
1404 IO.mapOptional(
"IndentExportBlock", Style.IndentExportBlock);
1405 IO.mapOptional(
"IndentExternBlock", Style.IndentExternBlock);
1406 IO.mapOptional(
"IndentGotoLabels", Style.IndentGotoLabels);
1407 IO.mapOptional(
"IndentPPDirectives", Style.IndentPPDirectives);
1408 IO.mapOptional(
"IndentRequiresClause", Style.IndentRequiresClause);
1409 IO.mapOptional(
"IndentWidth", Style.IndentWidth);
1410 IO.mapOptional(
"IndentWrappedFunctionNames",
1411 Style.IndentWrappedFunctionNames);
1412 IO.mapOptional(
"InsertBraces", Style.InsertBraces);
1413 IO.mapOptional(
"InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1414 IO.mapOptional(
"InsertTrailingCommas", Style.InsertTrailingCommas);
1415 IO.mapOptional(
"IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1416 IO.mapOptional(
"JavaImportGroups", Style.JavaImportGroups);
1417 IO.mapOptional(
"JavaScriptQuotes", Style.JavaScriptQuotes);
1418 IO.mapOptional(
"JavaScriptWrapImports", Style.JavaScriptWrapImports);
1419 IO.mapOptional(
"KeepEmptyLines", Style.KeepEmptyLines);
1420 IO.mapOptional(
"KeepFormFeed", Style.KeepFormFeed);
1421 IO.mapOptional(
"LambdaBodyIndentation", Style.LambdaBodyIndentation);
1422 IO.mapOptional(
"LineEnding", Style.LineEnding);
1423 IO.mapOptional(
"MacroBlockBegin", Style.MacroBlockBegin);
1424 IO.mapOptional(
"MacroBlockEnd", Style.MacroBlockEnd);
1425 IO.mapOptional(
"Macros", Style.Macros);
1426 IO.mapOptional(
"MacrosSkippedByRemoveParentheses",
1427 Style.MacrosSkippedByRemoveParentheses);
1428 IO.mapOptional(
"MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1429 IO.mapOptional(
"MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1430 IO.mapOptional(
"NamespaceIndentation", Style.NamespaceIndentation);
1431 IO.mapOptional(
"NamespaceMacros", Style.NamespaceMacros);
1432 IO.mapOptional(
"NumericLiteralCase", Style.NumericLiteralCase);
1433 IO.mapOptional(
"ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1434 IO.mapOptional(
"ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1435 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1436 Style.ObjCBreakBeforeNestedBlockParam);
1437 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1438 Style.ObjCPropertyAttributeOrder);
1439 IO.mapOptional(
"ObjCSpaceAfterMethodDeclarationPrefix",
1440 Style.ObjCSpaceAfterMethodDeclarationPrefix);
1441 IO.mapOptional(
"ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1442 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1443 Style.ObjCSpaceBeforeProtocolList);
1444 IO.mapOptional(
"OneLineFormatOffRegex", Style.OneLineFormatOffRegex);
1445 IO.mapOptional(
"PackArguments", Style.PackArguments);
1446 IO.mapOptional(
"PackConstructorInitializers",
1447 Style.PackConstructorInitializers);
1448 IO.mapOptional(
"PackParameters", Style.PackParameters);
1449 IO.mapOptional(
"PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1450 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1451 Style.PenaltyBreakBeforeFirstCallParameter);
1452 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1453 Style.PenaltyBreakBeforeMemberAccess);
1454 IO.mapOptional(
"PenaltyBreakComment", Style.PenaltyBreakComment);
1455 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1456 Style.PenaltyBreakFirstLessLess);
1457 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1458 Style.PenaltyBreakOpenParenthesis);
1459 IO.mapOptional(
"PenaltyBreakScopeResolution",
1460 Style.PenaltyBreakScopeResolution);
1461 IO.mapOptional(
"PenaltyBreakString", Style.PenaltyBreakString);
1462 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1463 Style.PenaltyBreakTemplateDeclaration);
1464 IO.mapOptional(
"PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1465 IO.mapOptional(
"PenaltyIndentedWhitespace",
1466 Style.PenaltyIndentedWhitespace);
1467 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1468 Style.PenaltyReturnTypeOnItsOwnLine);
1469 IO.mapOptional(
"PointerAlignment", Style.PointerAlignment);
1470 IO.mapOptional(
"PPIndentWidth", Style.PPIndentWidth);
1471 IO.mapOptional(
"QualifierAlignment", Style.QualifierAlignment);
1474 Style.QualifierOrder = {
"type",
"const",
"volatile"};
1476 Style.QualifierOrder = {
"const",
"volatile",
"type"};
1478 IO.mapOptional(
"QualifierOrder", Style.QualifierOrder);
1479 IO.mapOptional(
"RawStringFormats", Style.RawStringFormats);
1480 IO.mapOptional(
"ReferenceAlignment", Style.ReferenceAlignment);
1481 IO.mapOptional(
"ReflowComments", Style.ReflowComments);
1482 IO.mapOptional(
"RemoveBracesLLVM", Style.RemoveBracesLLVM);
1483 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1484 Style.RemoveEmptyLinesInUnwrappedLines);
1485 IO.mapOptional(
"RemoveParentheses", Style.RemoveParentheses);
1486 IO.mapOptional(
"RemoveSemicolon", Style.RemoveSemicolon);
1487 IO.mapOptional(
"RequiresClausePosition", Style.RequiresClausePosition);
1488 IO.mapOptional(
"RequiresExpressionIndentation",
1489 Style.RequiresExpressionIndentation);
1490 IO.mapOptional(
"SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1491 IO.mapOptional(
"ShortNamespaceLines", Style.ShortNamespaceLines);
1492 IO.mapOptional(
"SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1493 IO.mapOptional(
"SortIncludes", Style.SortIncludes);
1494 IO.mapOptional(
"SortJavaStaticImport", Style.SortJavaStaticImport);
1495 IO.mapOptional(
"SortUsingDeclarations", Style.SortUsingDeclarations);
1496 IO.mapOptional(
"SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1497 IO.mapOptional(
"SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1498 IO.mapOptional(
"SpaceAfterOperatorKeyword",
1499 Style.SpaceAfterOperatorKeyword);
1500 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1501 Style.SpaceAfterTemplateKeyword);
1502 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1503 Style.SpaceAroundPointerQualifiers);
1504 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1505 Style.SpaceBeforeAssignmentOperators);
1506 IO.mapOptional(
"SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1507 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1508 Style.SpaceBeforeCpp11BracedList);
1509 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1510 Style.SpaceBeforeCtorInitializerColon);
1511 IO.mapOptional(
"SpaceBeforeEnumUnderlyingTypeColon",
1512 Style.SpaceBeforeEnumUnderlyingTypeColon);
1513 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1514 Style.SpaceBeforeInheritanceColon);
1515 IO.mapOptional(
"SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1516 IO.mapOptional(
"SpaceBeforeParens", Style.SpaceBeforeParens);
1517 IO.mapOptional(
"SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1518 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1519 Style.SpaceBeforeRangeBasedForLoopColon);
1520 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1521 Style.SpaceBeforeSquareBrackets);
1522 IO.mapOptional(
"SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
1523 IO.mapOptional(
"SpacesBeforeTrailingComments",
1524 Style.SpacesBeforeTrailingComments);
1525 IO.mapOptional(
"SpacesInAngles", Style.SpacesInAngles);
1526 IO.mapOptional(
"SpacesInBlockComments", Style.SpacesInBlockComments);
1527 IO.mapOptional(
"SpacesInContainerLiterals",
1528 Style.SpacesInContainerLiterals);
1529 IO.mapOptional(
"SpacesInLineCommentPrefix",
1530 Style.SpacesInLineCommentPrefix);
1531 IO.mapOptional(
"SpacesInParens", Style.SpacesInParens);
1532 IO.mapOptional(
"SpacesInParensOptions", Style.SpacesInParensOptions);
1533 IO.mapOptional(
"SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1534 IO.mapOptional(
"Standard", Style.Standard);
1535 IO.mapOptional(
"StatementAttributeLikeMacros",
1536 Style.StatementAttributeLikeMacros);
1537 IO.mapOptional(
"StatementMacros", Style.StatementMacros);
1538 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1539 Style.TableGenBreakingDAGArgOperators);
1540 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1541 Style.TableGenBreakInsideDAGArg);
1542 IO.mapOptional(
"TabWidth", Style.TabWidth);
1543 IO.mapOptional(
"TemplateNames", Style.TemplateNames);
1544 IO.mapOptional(
"TypeNames", Style.TypeNames);
1545 IO.mapOptional(
"TypenameMacros", Style.TypenameMacros);
1546 IO.mapOptional(
"UseTab", Style.UseTab);
1547 IO.mapOptional(
"VariableTemplates", Style.VariableTemplates);
1548 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1549 Style.VerilogBreakBetweenInstancePorts);
1550 IO.mapOptional(
"WhitespaceSensitiveMacros",
1551 Style.WhitespaceSensitiveMacros);
1552 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1553 Style.WrapNamespaceBodyWithEmptyLines);
1560 if (Style.AlwaysBreakAfterDefinitionReturnType ==
1563 }
else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1571 if (BreakBeforeInheritanceComma &&
1579 if (BreakConstructorInitializersBeforeComma &&
1584 if (!IsGoogleOrChromium) {
1587 Style.PackConstructorInitializers = OnNextLine
1591 }
else if (Style.PackConstructorInitializers ==
1595 else if (!OnNextLine)
1600 if (!DeriveLineEnding)
1608 if (SpaceInEmptyBlock &&
1614 (SpacesInParentheses || SpaceInEmptyParentheses ||
1615 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1616 if (SpacesInParentheses) {
1618 Style.SpacesInParensOptions.ExceptDoubleParentheses =
false;
1619 Style.SpacesInParensOptions.InConditionalStatements =
true;
1620 Style.SpacesInParensOptions.InCStyleCasts =
1621 SpacesInCStyleCastParentheses;
1622 Style.SpacesInParensOptions.InEmptyParentheses =
1623 SpaceInEmptyParentheses;
1624 Style.SpacesInParensOptions.Other =
true;
1626 Style.SpacesInParensOptions = {};
1627 Style.SpacesInParensOptions.InConditionalStatements =
1628 SpacesInConditionalStatement;
1629 Style.SpacesInParensOptions.InCStyleCasts =
1630 SpacesInCStyleCastParentheses;
1631 Style.SpacesInParensOptions.InEmptyParentheses =
1632 SpaceInEmptyParentheses;
1644template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1645 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1650 if (Index >= Seq.size()) {
1651 assert(Index == Seq.size());
1656 Template = *((
const FormatStyle *)IO.getContext());
1659 Seq.resize(Index + 1, Template);
1665template <>
struct ScalarEnumerationTraits<
FormatStyle::IndentGotoLabelStyle> {
1693 return llvm::make_error<llvm::StringError>(Message,
1694 llvm::inconvertibleErrorCode());
1698 return "clang-format.parse_error";
1706 return "Invalid argument";
1708 return "Unsuitable";
1710 return "trailing comma insertion cannot be used with bin packing";
1712 return "Invalid qualifier specified in QualifierOrder";
1714 return "Duplicate qualifier specified in QualifierOrder";
1716 return "Missing type in QualifierOrder";
1718 return "Missing QualifierOrder";
1720 llvm_unreachable(
"unexpected parse error");
1971 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1974 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1975 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1976 {
".*", 1, 0,
false}};
2065 1, std::numeric_limits<unsigned>::max()};
2139 {
"^<.*\\.h>", 1, 0,
false},
2140 {
"^<.*", 2, 0,
false},
2141 {
".*", 3, 0,
false}};
2181 "PARSE_PARTIAL_TEXT_PROTO",
2185 "ParseTextProtoOrDie",
2187 "ParsePartialTestProto",
2306 "com.google.android.apps.chrome",
2325 return ChromiumStyle;
2352 return MozillaStyle;
2357 Style.AccessModifierOffset = -4;
2358 Style.AlignAfterOpenBracket =
false;
2360 Style.AlignTrailingComments = {};
2366 Style.ColumnLimit = 0;
2368 Style.FixNamespaceComments =
false;
2369 Style.IndentWidth = 4;
2371 Style.ObjCBlockIndentWidth = 4;
2372 Style.ObjCSpaceAfterProperty =
true;
2374 Style.SpaceBeforeCpp11BracedList =
true;
2385 Style.BreakBeforeTernaryOperators =
true;
2386 Style.ColumnLimit = 79;
2388 Style.FixNamespaceComments =
false;
2389 Style.KeepFormFeed =
true;
2396 Style.ColumnLimit = 120;
2398 Style.IndentWidth = 4;
2401 Style.BraceWrapping.AfterClass =
true;
2403 Style.BraceWrapping.AfterEnum =
true;
2404 Style.BraceWrapping.AfterFunction =
true;
2405 Style.BraceWrapping.AfterNamespace =
true;
2406 Style.BraceWrapping.AfterObjCDeclaration =
true;
2407 Style.BraceWrapping.AfterStruct =
true;
2408 Style.BraceWrapping.AfterExternBlock =
true;
2409 Style.BraceWrapping.BeforeCatch =
true;
2410 Style.BraceWrapping.BeforeElse =
true;
2411 Style.BraceWrapping.BeforeWhile =
false;
2412 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
2413 Style.AllowShortEnumsOnASingleLine =
false;
2415 Style.AllowShortCaseLabelsOnASingleLine =
false;
2417 Style.AllowShortLoopsOnASingleLine =
false;
2425 Style.InsertBraces =
true;
2426 Style.InsertNewlineAtEOF =
true;
2427 Style.IntegerLiteralSeparator.Decimal = 3;
2428 Style.IntegerLiteralSeparator.DecimalMinDigitsInsert = 5;
2430 Style.RemoveBracesLLVM =
true;
2431 Style.RemoveEmptyLinesInUnwrappedLines =
true;
2433 Style.RemoveSemicolon =
true;
2447 constexpr StringRef Prefix(
"inheritparentconfig=");
2449 if (Name.equals_insensitive(
"llvm"))
2451 else if (Name.equals_insensitive(
"chromium"))
2453 else if (Name.equals_insensitive(
"mozilla"))
2455 else if (Name.equals_insensitive(
"google"))
2457 else if (Name.equals_insensitive(
"webkit"))
2459 else if (Name.equals_insensitive(
"gnu"))
2461 else if (Name.equals_insensitive(
"microsoft"))
2463 else if (Name.equals_insensitive(
"clang-format"))
2465 else if (Name.equals_insensitive(
"none"))
2467 else if (Name.equals_insensitive(Prefix.drop_back()))
2468 Style->InheritConfig =
"..";
2469 else if (Name.size() > Prefix.size() && Name.starts_with_insensitive(Prefix))
2470 Style->InheritConfig = Name.substr(Prefix.size());
2480 if (Style->QualifierOrder.empty())
2484 for (
const auto &Qualifier : Style->QualifierOrder) {
2485 if (Qualifier ==
"type")
2489 if (token == tok::identifier)
2494 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2495 Style->QualifierOrder.end());
2496 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2497 LLVM_DEBUG(llvm::dbgs()
2498 <<
"Duplicate Qualifiers " << Style->QualifierOrder.size()
2499 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2504 if (!llvm::is_contained(Style->QualifierOrder,
"type"))
2512 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2513 void *DiagHandlerCtxt,
bool IsDotHFile) {
2517 if (Config.getBuffer().trim().empty())
2519 Style->StyleSet.Clear();
2520 std::vector<FormatStyle> Styles;
2521 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2527 Input.setContext(Style);
2528 Input.setAllowUnknownKeys(AllowUnknownOptions);
2531 return Input.error();
2535 const auto StyleCount = Styles.size();
2538 for (
unsigned I = 1; I < StyleCount; ++I) {
2539 const auto Lang = Styles[I].Language;
2543 for (
unsigned J = 0; J < I; ++J) {
2545 LLVM_DEBUG(llvm::dbgs()
2546 <<
"Duplicate languages in the config file on positions "
2547 << J <<
" and " << I <<
'\n');
2553 int LanguagePos = -1;
2559 for (
unsigned I = 0; I < StyleCount; ++I) {
2560 const auto Lang = Styles[I].Language;
2574 if (LanguagePos < 0) {
2580 LanguagePos = CppPos;
2581 if (LanguagePos < 0)
2585 for (
const auto &S : llvm::reverse(llvm::drop_begin(Styles)))
2586 Style->StyleSet.Add(S);
2588 *Style = Styles[LanguagePos];
2590 if (LanguagePos == 0) {
2593 Style->StyleSet.Add(*Style);
2609 llvm::raw_string_ostream Stream(
Text);
2610 llvm::yaml::Output Output(Stream);
2617 Output << NonConstStyle;
2619 return Stream.str();
2622std::optional<FormatStyle>
2625 return std::nullopt;
2627 if (It == Styles->end())
2628 return std::nullopt;
2630 Style.StyleSet = *
this;
2635 assert(Style.Language !=
LK_None &&
2636 "Cannot add a style for LK_None to a StyleSet");
2638 !Style.StyleSet.Styles &&
2639 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2641 Styles = std::make_shared<MapType>();
2642 (*Styles)[Style.Language] = std::move(Style);
2647std::optional<FormatStyle>
2656 StringRef
Text =
"") {
2659 if (
Next &&
Next->NewlinesBefore == 0 &&
Next->isNot(tok::eof)) {
2660 Start =
Tok.getLocation();
2661 Next->WhitespaceRange =
Token.WhitespaceRange;
2663 Start =
Token.WhitespaceRange.getBegin();
2666 cantFail(
Result.add(tooling::Replacement(SourceMgr, Range,
Text)));
2669class ParensRemover :
public TokenAnalyzer {
2671 ParensRemover(
const Environment &Env,
const FormatStyle &Style)
2672 : TokenAnalyzer(Env, Style) {}
2674 std::pair<tooling::Replacements, unsigned>
2675 analyze(TokenAnnotator &Annotator,
2676 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2677 FormatTokenLexer &Tokens)
override {
2678 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2679 tooling::Replacements
Result;
2680 removeParens(AnnotatedLines,
Result);
2685 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2686 tooling::Replacements &
Result) {
2687 const auto &SourceMgr = Env.getSourceManager();
2688 for (
auto *Line : Lines) {
2689 if (!
Line->Children.empty())
2691 if (!
Line->Affected)
2693 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2694 Token = Token->
Next) {
2696 replaceToken(*Token, Token->
Next, SourceMgr,
Result,
" ");
2702class BracesInserter :
public TokenAnalyzer {
2704 BracesInserter(
const Environment &Env,
const FormatStyle &Style)
2705 : TokenAnalyzer(Env, Style) {}
2707 std::pair<tooling::Replacements, unsigned>
2708 analyze(TokenAnnotator &Annotator,
2709 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2710 FormatTokenLexer &Tokens)
override {
2711 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2712 tooling::Replacements
Result;
2713 insertBraces(AnnotatedLines,
Result);
2718 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2719 tooling::Replacements &
Result) {
2720 const auto &SourceMgr = Env.getSourceManager();
2721 int OpeningBraceSurplus = 0;
2722 for (AnnotatedLine *Line : Lines) {
2723 if (!
Line->Children.empty())
2725 if (!
Line->Affected && OpeningBraceSurplus == 0)
2728 Token = Token->
Next) {
2735 if (!
Line->Affected)
2737 Brace = Token->
is(tok::comment) ?
"\n{" :
"{";
2738 ++OpeningBraceSurplus;
2740 if (OpeningBraceSurplus == 0)
2749 cantFail(
Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2752 assert(OpeningBraceSurplus == 0);
2756class BracesRemover :
public TokenAnalyzer {
2758 BracesRemover(
const Environment &Env,
const FormatStyle &Style)
2759 : TokenAnalyzer(Env, Style) {}
2761 std::pair<tooling::Replacements, unsigned>
2762 analyze(TokenAnnotator &Annotator,
2763 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2764 FormatTokenLexer &Tokens)
override {
2765 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2766 tooling::Replacements
Result;
2767 removeBraces(AnnotatedLines,
Result);
2772 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2773 tooling::Replacements &
Result) {
2774 const auto &SourceMgr = Env.getSourceManager();
2775 const auto *End = Lines.end();
2776 for (
const auto *I = Lines.begin(); I != End; ++I) {
2777 const auto &
Line = *I;
2778 if (!
Line->Children.empty())
2780 if (!
Line->Affected)
2782 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2783 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2784 Token = Token->
Next) {
2788 assert(
Next || Token ==
Line->Last);
2789 if (!
Next && NextLine)
2790 Next = NextLine->First;
2791 replaceToken(*Token,
Next, SourceMgr,
Result);
2797class SemiRemover :
public TokenAnalyzer {
2799 SemiRemover(
const Environment &Env,
const FormatStyle &Style)
2800 : TokenAnalyzer(Env, Style) {}
2802 std::pair<tooling::Replacements, unsigned>
2803 analyze(TokenAnnotator &Annotator,
2804 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2805 FormatTokenLexer &Tokens)
override {
2806 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2807 tooling::Replacements
Result;
2808 removeSemi(Annotator, AnnotatedLines,
Result);
2813 void removeSemi(TokenAnnotator &Annotator,
2814 SmallVectorImpl<AnnotatedLine *> &Lines,
2815 tooling::Replacements &
Result) {
2817 const auto *Prev =
Tok.Previous;
2818 if (!Prev || Prev->isNot(tok::r_brace))
2820 const auto *LBrace = Prev->MatchingParen;
2821 return LBrace && LBrace->is(TT_FunctionLBrace);
2823 const auto &SourceMgr = Env.getSourceManager();
2824 const auto *End = Lines.end();
2825 for (
const auto *I = Lines.begin(); I != End; ++I) {
2826 const auto &
Line = *I;
2827 if (!
Line->Children.empty())
2828 removeSemi(Annotator,
Line->Children,
Result);
2829 if (!
Line->Affected)
2831 Annotator.calculateFormattingInformation(*Line);
2832 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2833 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2834 Token = Token->
Next) {
2835 if (Token->
isNot(tok::semi) ||
2836 (!Token->
Optional && !PrecededByFunctionRBrace(*Token))) {
2840 assert(
Next || Token ==
Line->Last);
2841 if (!
Next && NextLine)
2842 Next = NextLine->First;
2843 replaceToken(*Token,
Next, SourceMgr,
Result);
2849class EnumTrailingCommaEditor :
public TokenAnalyzer {
2851 EnumTrailingCommaEditor(
const Environment &Env,
const FormatStyle &Style)
2852 : TokenAnalyzer(Env, Style) {}
2854 std::pair<tooling::Replacements, unsigned>
2855 analyze(TokenAnnotator &Annotator,
2856 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2857 FormatTokenLexer &Tokens)
override {
2858 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2859 tooling::Replacements
Result;
2860 editEnumTrailingComma(AnnotatedLines,
Result);
2865 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2866 tooling::Replacements &
Result) {
2867 bool InEnumBraces =
false;
2869 const auto &SourceMgr = Env.getSourceManager();
2870 for (
auto *Line : Lines) {
2871 if (!
Line->Children.empty())
2872 editEnumTrailingComma(
Line->Children,
Result);
2874 Token = Token->
Next) {
2875 if (Token->
isNot(TT_EnumRBrace)) {
2876 if (Token->
is(TT_EnumLBrace))
2877 InEnumBraces =
true;
2878 else if (InEnumBraces && Token->
isNot(tok::comment))
2879 BeforeRBrace =
Line->Affected ? Token :
nullptr;
2882 InEnumBraces =
false;
2883 if (!BeforeRBrace || BeforeRBrace->HasEnumTrailingCommaHandled) {
2887 if (BeforeRBrace->is(tok::comma)) {
2889 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr,
Result);
2891 cantFail(
Result.add(tooling::Replacement(
2892 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0,
",")));
2894 BeforeRBrace->HasEnumTrailingCommaHandled =
true;
2895 BeforeRBrace =
nullptr;
2901class JavaScriptRequoter :
public TokenAnalyzer {
2903 JavaScriptRequoter(
const Environment &Env,
const FormatStyle &Style)
2904 : TokenAnalyzer(Env, Style) {}
2906 std::pair<tooling::Replacements, unsigned>
2907 analyze(TokenAnnotator &Annotator,
2908 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2909 FormatTokenLexer &Tokens)
override {
2910 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2911 tooling::Replacements
Result;
2912 requoteJSStringLiteral(AnnotatedLines,
Result);
2919 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2920 tooling::Replacements &
Result) {
2921 for (AnnotatedLine *Line : Lines) {
2922 requoteJSStringLiteral(
Line->Children,
Result);
2923 if (!
Line->Affected)
2926 FormatTok = FormatTok->Next) {
2927 StringRef Input = FormatTok->TokenText;
2928 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2932 !Input.starts_with(
"\"")) ||
2934 !Input.starts_with(
"\'"))) {
2940 SourceLocation Start = FormatTok->Tok.getLocation();
2941 auto Replace = [&](SourceLocation Start,
unsigned Length,
2942 StringRef ReplacementText) {
2943 auto Err =
Result.add(tooling::Replacement(
2944 Env.getSourceManager(), Start, Length, ReplacementText));
2948 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2952 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2953 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2954 IsSingle ?
"'" :
"\"");
2957 bool Escaped =
false;
2958 for (
size_t i = 1; i < Input.size() - 1; i++) {
2961 if (!Escaped && i + 1 < Input.size() &&
2962 ((IsSingle && Input[i + 1] ==
'"') ||
2963 (!IsSingle && Input[i + 1] ==
'\''))) {
2966 Replace(Start.getLocWithOffset(i), 1,
"");
2973 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2975 Replace(Start.getLocWithOffset(i), 0,
"\\");
2989class Formatter :
public TokenAnalyzer {
2991 Formatter(
const Environment &Env,
const FormatStyle &Style,
2992 FormattingAttemptStatus *Status)
2993 : TokenAnalyzer(Env, Style), Status(Status) {}
2995 std::pair<tooling::Replacements, unsigned>
2996 analyze(TokenAnnotator &Annotator,
2997 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2998 FormatTokenLexer &Tokens)
override {
2999 tooling::Replacements
Result;
3000 deriveLocalStyle(AnnotatedLines);
3001 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3002 for (AnnotatedLine *Line : AnnotatedLines)
3003 Annotator.calculateFormattingInformation(*Line);
3004 Annotator.setCommentLineLevels(AnnotatedLines);
3006 WhitespaceManager Whitespaces(
3007 Env.getSourceManager(), Style,
3009 ? WhitespaceManager::inputUsesCRLF(
3010 Env.getSourceManager().getBufferData(Env.getFileID()),
3013 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
3014 Env.getSourceManager(), Whitespaces, Encoding,
3015 BinPackInconclusiveFunctions);
3017 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
3018 Tokens.getKeywords(), Env.getSourceManager(),
3020 .format(AnnotatedLines,
false,
3023 Env.getFirstStartColumn(),
3024 Env.getNextStartColumn(),
3025 Env.getLastStartColumn());
3026 for (
const auto &R : Whitespaces.generateReplacements())
3028 return std::make_pair(
Result, 0);
3029 return std::make_pair(
Result, Penalty);
3034 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3035 for (
const AnnotatedLine *Line : Lines) {
3036 if (hasCpp03IncompatibleFormat(
Line->Children))
3039 if (!
Tok->hasWhitespaceBefore()) {
3040 if (
Tok->is(tok::coloncolon) &&
Tok->Previous->is(TT_TemplateOpener))
3042 if (
Tok->is(TT_TemplateCloser) &&
3043 Tok->Previous->is(TT_TemplateCloser)) {
3052 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3053 int AlignmentDiff = 0;
3055 for (
const AnnotatedLine *Line : Lines) {
3056 AlignmentDiff += countVariableAlignments(
Line->Children);
3059 if (
Tok->isNot(TT_PointerOrReference))
3062 const auto *Prev =
Tok->Previous;
3063 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
3064 const bool SpaceBefore =
Tok->hasWhitespaceBefore();
3067 while (
Tok->Next &&
Tok->Next->is(TT_PointerOrReference))
3071 const bool FollowedByName =
Next &&
Next->Tok.getIdentifierInfo();
3072 const bool SpaceAfter =
Next &&
Next->hasWhitespaceBefore();
3074 if ((!PrecededByName && !FollowedByName) ||
3076 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
3080 if ((PrecededByName && SpaceBefore) ||
3081 (FollowedByName && !SpaceAfter)) {
3084 }
else if ((PrecededByName && !SpaceBefore) ||
3085 (FollowedByName && SpaceAfter)) {
3092 return AlignmentDiff;
3096 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3097 bool HasBinPackedFunction =
false;
3098 bool HasOnePerLineFunction =
false;
3099 for (AnnotatedLine *Line : AnnotatedLines) {
3100 if (!
Line->First->Next)
3104 if (
Tok->is(PPK_BinPacked))
3105 HasBinPackedFunction =
true;
3106 if (
Tok->is(PPK_OnePerLine))
3107 HasOnePerLineFunction =
true;
3112 if (Style.DerivePointerAlignment) {
3113 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
3114 if (NetRightCount > 0)
3116 else if (NetRightCount < 0)
3121 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
3125 BinPackInconclusiveFunctions =
3126 HasBinPackedFunction || !HasOnePerLineFunction;
3129 bool BinPackInconclusiveFunctions;
3130 FormattingAttemptStatus *Status;
3144class TrailingCommaInserter :
public TokenAnalyzer {
3146 TrailingCommaInserter(
const Environment &Env,
const FormatStyle &Style)
3147 : TokenAnalyzer(Env, Style) {}
3149 std::pair<tooling::Replacements, unsigned>
3150 analyze(TokenAnnotator &Annotator,
3151 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3152 FormatTokenLexer &Tokens)
override {
3153 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3154 tooling::Replacements
Result;
3155 insertTrailingCommas(AnnotatedLines,
Result);
3162 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
3163 tooling::Replacements &
Result) {
3164 for (AnnotatedLine *Line : Lines) {
3165 insertTrailingCommas(
Line->Children,
Result);
3166 if (!
Line->Affected)
3169 FormatTok = FormatTok->Next) {
3170 if (FormatTok->NewlinesBefore == 0)
3173 if (!Matching || !FormatTok->getPreviousNonComment())
3175 if (!(FormatTok->is(tok::r_square) &&
3176 Matching->is(TT_ArrayInitializerLSquare)) &&
3177 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
3180 FormatToken *Prev = FormatTok->getPreviousNonComment();
3181 if (Prev->is(tok::comma) || Prev->is(tok::semi))
3185 SourceLocation Start =
3186 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
3190 unsigned ColumnNumber =
3191 Env.getSourceManager().getSpellingColumnNumber(Start);
3192 if (ColumnNumber > Style.ColumnLimit)
3197 tooling::Replacement(Env.getSourceManager(), Start, 0,
",")));
3205class Cleaner :
public TokenAnalyzer {
3207 Cleaner(
const Environment &Env,
const FormatStyle &Style)
3208 : TokenAnalyzer(Env, Style),
3209 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
3212 std::pair<tooling::Replacements, unsigned>
3213 analyze(TokenAnnotator &Annotator,
3214 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3215 FormatTokenLexer &Tokens)
override {
3223 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3225 checkEmptyNamespace(AnnotatedLines);
3227 for (
auto *Line : AnnotatedLines)
3230 return {generateFixes(), 0};
3234 void cleanupLine(AnnotatedLine *Line) {
3235 for (
auto *Child :
Line->Children)
3238 if (
Line->Affected) {
3239 cleanupRight(
Line->First, tok::comma, tok::comma);
3240 cleanupRight(
Line->First, TT_CtorInitializerColon, tok::comma);
3241 cleanupRight(
Line->First, tok::l_paren, tok::comma);
3242 cleanupLeft(
Line->First, tok::comma, tok::r_paren);
3243 cleanupLeft(
Line->First, TT_CtorInitializerComma, tok::l_brace);
3244 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::l_brace);
3245 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::equal);
3249 bool containsOnlyComments(
const AnnotatedLine &Line) {
3251 if (
Tok->isNot(tok::comment))
3257 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3258 std::set<unsigned> DeletedLines;
3259 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
3260 auto &
Line = *AnnotatedLines[i];
3261 if (
Line.startsWithNamespace())
3262 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
3265 for (
auto Line : DeletedLines) {
3278 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3279 unsigned CurrentLine,
unsigned &NewLine,
3280 std::set<unsigned> &DeletedLines) {
3281 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
3282 if (Style.BraceWrapping.AfterNamespace) {
3286 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
3287 NewLine = CurrentLine;
3290 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
3293 while (++CurrentLine < End) {
3294 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
3297 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
3298 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
3302 CurrentLine = NewLine;
3306 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
3311 NewLine = CurrentLine;
3315 NewLine = CurrentLine;
3316 if (CurrentLine >= End)
3320 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
3321 AnnotatedLines[InitLine]->First->Tok.getLocation(),
3322 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
3326 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
3327 DeletedLines.insert(i);
3336 template <
typename LeftKind,
typename RightKind>
3337 void cleanupPair(
FormatToken *Start, LeftKind LK, RightKind RK,
3340 for (
auto *Res =
Tok.Next; Res; Res = Res->Next) {
3341 if (Res->isNot(tok::comment) &&
3342 DeletedTokens.find(Res) == DeletedTokens.end()) {
3348 for (
auto *Left = Start;
Left;) {
3349 auto *
Right = NextNotDeleted(*Left);
3353 deleteToken(DeleteLeft ? Left : Right);
3365 template <
typename LeftKind,
typename RightKind>
3366 void cleanupLeft(
FormatToken *Start, LeftKind LK, RightKind RK) {
3367 cleanupPair(Start, LK, RK,
true);
3370 template <
typename LeftKind,
typename RightKind>
3371 void cleanupRight(
FormatToken *Start, LeftKind LK, RightKind RK) {
3372 cleanupPair(Start, LK, RK,
false);
3378 DeletedTokens.insert(
Tok);
3381 tooling::Replacements generateFixes() {
3382 tooling::Replacements Fixes;
3383 SmallVector<FormatToken *> Tokens;
3384 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
3385 std::back_inserter(Tokens));
3391 while (Idx < Tokens.size()) {
3392 unsigned St = Idx, End = Idx;
3393 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3395 auto SR = CharSourceRange::getCharRange(Tokens[St]->
Tok.getLocation(),
3396 Tokens[End]->Tok.getEndLoc());
3398 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR,
""));
3402 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3403 assert(
false &&
"Fixes must not conflict!");
3414 struct FormatTokenLess {
3415 FormatTokenLess(
const SourceManager &SM) : SM(SM) {}
3418 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3419 RHS->Tok.getLocation());
3421 const SourceManager &SM;
3425 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3428class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
3430 ObjCHeaderStyleGuesser(
const Environment &Env,
const FormatStyle &Style)
3431 : TokenAnalyzer(Env, Style), IsObjC(
false) {}
3433 std::pair<tooling::Replacements, unsigned>
3434 analyze(TokenAnnotator &Annotator,
3435 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3436 FormatTokenLexer &Tokens)
override {
3438 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
3439 Tokens.getKeywords());
3440 tooling::Replacements
Result;
3444 bool isObjC() {
return IsObjC; }
3448 guessIsObjC(
const SourceManager &SourceManager,
3449 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3450 const AdditionalKeywords &Keywords) {
3452 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3467 "FOUNDATION_EXPORT",
3468 "FOUNDATION_EXTERN",
3469 "NSAffineTransform",
3471 "NSAttributedString",
3490 "NSInvocationOperation",
3494 "NSMutableAttributedString",
3495 "NSMutableCharacterSet",
3497 "NSMutableDictionary",
3498 "NSMutableIndexSet",
3499 "NSMutableOrderedSet",
3503 "NSNumberFormatter",
3507 "NSOperationQueuePriority",
3511 "NSQualityOfService",
3514 "NSRegularExpression",
3525 "NS_ASSUME_NONNULL_BEGIN",
3529 assert(llvm::is_sorted(FoundationIdentifiers));
3531 for (
auto *Line : AnnotatedLines) {
3532 if (
Line->First && (
Line->First->TokenText.starts_with(
"#") ||
3533 Line->First->TokenText ==
"__pragma" ||
3534 Line->First->TokenText ==
"_Pragma")) {
3538 FormatTok = FormatTok->Next) {
3539 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3540 (FormatTok->isNot(tok::objc_not_keyword) ||
3541 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3543 (FormatTok->Tok.isAnyIdentifier() &&
3544 llvm::binary_search(FoundationIdentifiers,
3545 FormatTok->TokenText)) ||
3546 FormatTok->is(TT_ObjCStringLiteral) ||
3547 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3548 Keywords.kw_NS_ERROR_ENUM,
3549 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3550 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3551 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3552 TT_ObjCProperty, TT_ObjCSelector)) {
3553 LLVM_DEBUG(llvm::dbgs()
3554 <<
"Detected ObjC at location "
3555 << FormatTok->Tok.getLocation().printToString(
3557 <<
" token: " << FormatTok->TokenText <<
" token type: "
3562 if (guessIsObjC(SourceManager,
Line->Children, Keywords))
3579struct JavaImportDirective {
3580 StringRef Identifier;
3583 SmallVector<StringRef> AssociatedCommentLines;
3592 for (
const auto &Range : Ranges) {
3593 if (Range.getOffset() < End &&
3594 Range.getOffset() + Range.getLength() > Start) {
3609static std::pair<unsigned, unsigned>
3612 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3613 unsigned OffsetToEOL = 0;
3614 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3615 unsigned Start = Includes[Indices[i]].Offset;
3616 unsigned End = Start + Includes[Indices[i]].Text.size();
3617 if (!(Cursor >= Start && Cursor < End))
3619 CursorIndex = Indices[i];
3620 OffsetToEOL = End - Cursor;
3623 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3627 return std::make_pair(CursorIndex, OffsetToEOL);
3632 std::string NewCode;
3633 size_t Pos = 0, LastPos = 0;
3636 Pos = Code.find(
"\r\n", LastPos);
3637 if (Pos == LastPos) {
3641 if (Pos == std::string::npos) {
3642 NewCode += Code.substr(LastPos);
3645 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3647 }
while (Pos != std::string::npos);
3665 const unsigned IncludesBeginOffset = Includes.front().Offset;
3666 const unsigned IncludesEndOffset =
3667 Includes.back().Offset + Includes.back().Text.size();
3668 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3669 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3672 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3674 if (Style.SortIncludes.Enabled) {
3675 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3676 if (Includes[LHSI].Priority != Includes[RHSI].Priority)
3677 return Includes[LHSI].Priority < Includes[RHSI].Priority;
3679 auto LHSStem = Includes[LHSI].Filename;
3680 auto RHSStem = Includes[RHSI].Filename;
3683 if (Style.SortIncludes.IgnoreExtension) {
3684 LHSStemStorage = Includes[LHSI].Filename;
3685 RHSStemStorage = Includes[RHSI].Filename;
3686 llvm::sys::path::replace_extension(LHSStemStorage,
"");
3687 llvm::sys::path::replace_extension(RHSStemStorage,
"");
3688 LHSStem = LHSStemStorage;
3689 RHSStem = RHSStemStorage;
3692 std::string LHSStemLower, RHSStemLower;
3693 std::string LHSFilenameLower, RHSFilenameLower;
3694 if (Style.SortIncludes.IgnoreCase) {
3695 LHSStemLower = LHSStem.lower();
3696 RHSStemLower = RHSStem.lower();
3697 LHSFilenameLower = Includes[LHSI].Filename.lower();
3698 RHSFilenameLower = Includes[RHSI].Filename.lower();
3701 const auto Compare = Style.SortIncludes.Natural
3702 ? &StringRef::compare_numeric
3703 : &StringRef::compare;
3705 while (Style.SortIncludes.FilesBeforeFolders) {
3706 auto [LHead, LTail] = LHSStem.split(
'/');
3707 auto [RHead, RTail] = RHSStem.split(
'/');
3709 bool LIsFile = LTail.empty();
3710 bool RIsFile = RTail.empty();
3713 if (LIsFile != RIsFile)
3722 if (Style.SortIncludes.IgnoreCase) {
3723 int Cmp = std::invoke(Compare, StringRef(LHead.lower()),
3724 StringRef(RHead.lower()));
3728 if (
int Cmp = std::invoke(Compare, LHead, RHead);
Cmp != 0)
3736 if (Style.SortIncludes.IgnoreCase) {
3737 int Cmp = std::invoke(Compare, StringRef(LHSStemLower), RHSStemLower);
3742 if (
int Cmp = std::invoke(Compare, LHSStem, RHSStem);
Cmp != 0)
3745 if (Style.SortIncludes.IgnoreCase) {
3747 std::invoke(Compare, StringRef(LHSFilenameLower), RHSFilenameLower);
3751 return std::invoke(Compare, Includes[LHSI].Filename,
3752 Includes[RHSI].Filename) < 0;
3758 unsigned CursorIndex;
3760 unsigned CursorToEOLOffset;
3762 std::tie(CursorIndex, CursorToEOLOffset) =
3767 Indices.erase(llvm::unique(Indices,
3768 [&](
unsigned LHSI,
unsigned RHSI) {
3769 return Includes[LHSI].Text.trim() ==
3770 Includes[RHSI].Text.trim();
3774 int CurrentCategory = Includes.front().Category;
3782 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3787 const auto OldCursor = Cursor ? *Cursor : 0;
3789 for (
unsigned Index : Indices) {
3790 if (!result.empty()) {
3792 if (Style.IncludeStyle.IncludeBlocks ==
3794 CurrentCategory != Includes[Index].Category) {
3798 result += Includes[Index].Text;
3799 if (Cursor && CursorIndex == Index)
3800 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3801 CurrentCategory = Includes[Index].Category;
3804 if (Cursor && *Cursor >= IncludesEndOffset)
3805 *Cursor += result.size() - IncludesBlockSize;
3810 IncludesBeginOffset, IncludesBlockSize)))) {
3812 *Cursor = OldCursor;
3817 FileName, Includes.front().Offset, IncludesBlockSize, result));
3821 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3831 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3832 .StartsWith(
"\xEF\xBB\xBF", 3)
3834 unsigned SearchFrom = 0;
3846 bool FirstIncludeBlock =
true;
3847 bool MainIncludeFound =
false;
3848 bool FormattingOff =
false;
3851 llvm::Regex RawStringRegex(
3852 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3854 std::string RawStringTermination =
")\"";
3856 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3857 size_t Pos = SearchFrom;
3858 if (Code[SearchFrom] !=
'\n') {
3861 Pos = Code.find(
'\n', Pos);
3862 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3866 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3868 StringRef Trimmed =
Line.trim();
3873 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3874 std::string CharSequence = RawStringMatches[1].str();
3875 RawStringTermination =
")" + CharSequence +
"\"";
3876 FormattingOff =
true;
3879 if (Trimmed.contains(RawStringTermination))
3880 FormattingOff =
false;
3882 bool IsBlockComment =
false;
3885 FormattingOff =
true;
3887 FormattingOff =
false;
3888 }
else if (Trimmed.starts_with(
"/*")) {
3889 IsBlockComment =
true;
3890 Pos = Code.find(
"*/", SearchFrom + 2);
3893 const bool EmptyLineSkipped =
3896 Style.IncludeStyle.IncludeBlocks ==
3899 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3900 if (!FormattingOff && !MergeWithNextLine) {
3901 if (!IsBlockComment &&
3903 StringRef IncludeName = Matches[2];
3904 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3909 Pos = Code.find(
"*/", SearchFrom);
3911 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3915 !MainIncludeFound && FirstIncludeBlock);
3917 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3919 MainIncludeFound =
true;
3920 IncludesInBlock.push_back(
3921 {IncludeName,
Line, Prev, Category, Priority});
3922 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3925 IncludesInBlock.clear();
3926 if (Trimmed.starts_with(
"#pragma hdrstop"))
3927 FirstIncludeBlock =
true;
3929 FirstIncludeBlock =
false;
3932 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3935 if (!MergeWithNextLine)
3937 SearchFrom = Pos + 1;
3939 if (!IncludesInBlock.empty()) {
3950 StringRef ImportIdentifier) {
3951 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3952 unsigned LongestMatchLength = 0;
3953 for (
unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3954 const std::string &GroupPrefix = Style.JavaImportGroups[I];
3955 if (ImportIdentifier.starts_with(GroupPrefix) &&
3956 GroupPrefix.length() > LongestMatchLength) {
3957 LongestMatchIndex = I;
3958 LongestMatchLength = GroupPrefix.length();
3961 return LongestMatchIndex;
3973 unsigned ImportsBeginOffset = Imports.front().Offset;
3974 unsigned ImportsEndOffset =
3975 Imports.back().Offset + Imports.back().Text.size();
3976 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3977 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3981 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3984 for (
const JavaImportDirective &Import : Imports)
3987 bool StaticImportAfterNormalImport =
3989 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3991 return std::make_tuple(!Imports[LHSI].IsStatic ^
3992 StaticImportAfterNormalImport,
3994 std::make_tuple(!Imports[RHSI].IsStatic ^
3995 StaticImportAfterNormalImport,
4000 Indices.erase(llvm::unique(Indices,
4001 [&](
unsigned LHSI,
unsigned RHSI) {
4002 return Imports[LHSI].Text == Imports[RHSI].Text;
4006 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
4010 for (
unsigned Index : Indices) {
4011 if (!result.empty()) {
4013 if (CurrentIsStatic != Imports[Index].IsStatic ||
4018 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
4019 result += CommentLine;
4022 result += Imports[Index].Text;
4023 CurrentIsStatic = Imports[Index].IsStatic;
4030 Imports.front().Offset, ImportsBlockSize)))) {
4035 ImportsBlockSize, result));
4039 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
4047 JavaImportRegexPattern(
"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;");
4049constexpr StringRef JavaPackageRegexPattern(
"^package[\t ]");
4058 bool HasImport =
false;
4059 llvm::Regex ImportRegex(JavaImportRegexPattern);
4060 llvm::Regex PackageRegex(JavaPackageRegexPattern);
4065 for (
bool FormattingOff =
false;;) {
4066 auto Pos = Code.find(
'\n', Prev);
4067 auto GetLine = [&] {
4068 return Code.substr(Prev,
4069 (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
4071 StringRef
Line = GetLine();
4073 StringRef Trimmed =
Line.trim();
4074 if (Trimmed.empty() || PackageRegex.match(Trimmed)) {
4077 FormattingOff =
true;
4079 FormattingOff =
false;
4080 }
else if (Trimmed.starts_with(
"//")) {
4083 AssociatedCommentLines.push_back(
Line);
4084 }
else if (Trimmed.starts_with(
"/*")) {
4085 Pos = Code.find(
"*/", Pos + 2);
4086 if (Pos != StringRef::npos)
4087 Pos = Code.find(
'\n', Pos + 2);
4092 AssociatedCommentLines.push_back(
Line);
4094 }
else if (ImportRegex.match(Trimmed, &Matches)) {
4095 if (FormattingOff) {
4100 StringRef
Static = Matches[1];
4101 StringRef Identifier = Matches[2];
4102 bool IsStatic =
false;
4103 if (
Static.contains(
"static"))
4105 ImportsInBlock.push_back(
4106 {Identifier,
Line, Prev, AssociatedCommentLines, IsStatic});
4108 AssociatedCommentLines.clear();
4114 if (Pos == StringRef::npos || Pos + 1 == Code.size())
4127 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
4130bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
4134 StringRef
FileName,
unsigned *Cursor) {
4136 if (!Style.SortIncludes.Enabled || Style.DisableFormat)
4140 if (Style.isJavaScript()) {
4152template <
typename T>
4157 if (Replaces.
empty())
4160 auto NewCode = applyAllReplacements(Code, Replaces);
4162 return NewCode.takeError();
4167 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
4169 return Replaces.
merge(FormatReplaces);
4178 std::vector<tooling::Range> Ranges,
4182 auto SortedReplaces =
4184 if (!SortedReplaces)
4185 return SortedReplaces.takeError();
4189 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
4190 std::vector<tooling::Range> Ranges,
4200 return Replace.
getOffset() == std::numeric_limits<unsigned>::max() &&
4206inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
4207 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
4208 Replace.getLength() == 1;
4212tooling::Replacements
4213fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
4214 const FormatStyle &Style) {
4218 tooling::Replacements HeaderInsertions;
4219 std::set<StringRef> HeadersToDelete;
4220 tooling::Replacements
Result;
4221 for (
const auto &R : Replaces) {
4222 if (isHeaderInsertion(R)) {
4225 consumeError(HeaderInsertions.add(R));
4226 }
else if (isHeaderDeletion(R)) {
4227 HeadersToDelete.insert(
R.getReplacementText());
4228 }
else if (
R.getOffset() == std::numeric_limits<unsigned>::max()) {
4229 llvm::errs() <<
"Insertions other than header #include insertion are "
4231 <<
R.getReplacementText() <<
"\n";
4233 consumeError(
Result.add(R));
4236 if (HeaderInsertions.empty() && HeadersToDelete.empty())
4239 StringRef
FileName = Replaces.begin()->getFilePath();
4242 for (
const auto &Header : HeadersToDelete) {
4243 tooling::Replacements Replaces =
4244 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
4245 for (
const auto &R : Replaces) {
4246 auto Err =
Result.add(R);
4249 llvm::errs() <<
"Failed to add header deletion replacement for "
4250 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
4255 SmallVector<StringRef, 4> Matches;
4256 SmallVector<tooling::HeaderIncludes::HeaderToInsert, 4> HeadersToInsert;
4257 for (
const auto &R : HeaderInsertions) {
4261 assert(Matched &&
"Header insertion replacement must have replacement text "
4264 auto IncludeName = Matches[2];
4265 HeadersToInsert.emplace_back(IncludeName,
4268 for (
const auto &Replace : Includes.insert(HeadersToInsert)) {
4269 auto Err =
Result.add(Replace);
4271 consumeError(std::move(Err));
4272 unsigned NewOffset =
Result.getShiftedCodePosition(Replace.getOffset());
4273 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
4274 Replace.getReplacementText());
4283Expected<tooling::Replacements>
4288 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
4295 fixCppIncludeInsertions(Code, Replaces, Style);
4300std::pair<tooling::Replacements, unsigned>
4303 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef
FileName,
4336 if (Style.isJson()) {
4337 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
4339 NextStartColumn, LastStartColumn);
4344 Formatter(*Env, Style, Status).process().first;
4346 if (Code.starts_with(
"x = ")) {
4347 Replaces = Replaces.
merge(
4351 if (applyAllReplacements(Code, Replaces))
4352 return {Replaces, 0};
4357 NextStartColumn, LastStartColumn);
4375 if (Style.isCpp()) {
4382 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4383 return ParensRemover(Env, S).process(
true);
4387 if (Style.InsertBraces) {
4390 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4391 return BracesInserter(Env, S).process(
true);
4395 if (Style.RemoveBracesLLVM) {
4398 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4399 return BracesRemover(Env, S).process(
true);
4403 if (Style.RemoveSemicolon) {
4406 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4407 return SemiRemover(Env, S).process();
4413 return EnumTrailingCommaEditor(Env, Expanded)
4418 if (Style.FixNamespaceComments) {
4432 !Style.ObjCPropertyAttributeOrder.empty()) {
4438 if (Style.isJavaScript() &&
4441 return JavaScriptRequoter(Env, Expanded).process(
true);
4446 return Formatter(Env, Expanded, Status).process();
4455 if (Style.isJavaScript() &&
4458 return TrailingCommaInserter(Env, Expanded).process();
4462 std::optional<std::string> CurrentCode;
4464 unsigned Penalty = 0;
4465 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
4466 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
4467 auto NewCode = applyAllReplacements(
4468 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
4470 Fixes = Fixes.
merge(PassFixes.first);
4471 Penalty += PassFixes.second;
4473 CurrentCode = std::move(*NewCode);
4477 FirstStartColumn, NextStartColumn, LastStartColumn);
4490 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4491 if (OriginalCode != Fix.getReplacementText()) {
4492 auto Err = NonNoOpFixes.
add(Fix);
4494 llvm::errs() <<
"Error adding replacements : "
4495 <<
toString(std::move(Err)) <<
"\n";
4499 Fixes = std::move(NonNoOpFixes);
4502 return {Fixes, Penalty};
4526 return Cleaner(*Env, Style).process().first;
4531 StringRef
FileName,
bool *IncompleteFormat) {
4534 if (!Status.FormatComplete)
4535 *IncompleteFormat =
true;
4562 auto LexingStd = Style.Standard;
4569 switch (Style.Language) {
4576 LangOpts.CXXOperatorNames = 1;
4577 LangOpts.CPlusPlus11 = SinceCpp11;
4580 LangOpts.CPlusPlus20 = SinceCpp20;
4585 LangOpts.CPlusPlus = 1;
4588 LangOpts.Char8 = SinceCpp20;
4589 LangOpts.AllowLiteralDigitSeparator = LangOpts.CPlusPlus14 || LangOpts.C23;
4593 LangOpts.Digraphs = SinceCpp11;
4595 LangOpts.LineComment = 1;
4598 LangOpts.MicrosoftExt = 1;
4599 LangOpts.DeclSpecKeyword = 1;
4606 "Set coding style. <string> can be:\n"
4607 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4608 " Mozilla, WebKit.\n"
4609 "2. 'file' to load style configuration from a\n"
4610 " .clang-format file in one of the parent directories\n"
4611 " of the source file (for stdin, see --assume-filename).\n"
4612 " If no .clang-format file is found, falls back to\n"
4613 " --fallback-style.\n"
4614 " --style=file is the default.\n"
4615 "3. 'file:<format_file_path>' to explicitly specify\n"
4616 " the configuration file.\n"
4617 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4618 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4621 static constexpr std::array<llvm::StringLiteral, 2> TemplateSuffixes{
4625 for (
auto Suffix : TemplateSuffixes)
4633 if (
FileName.ends_with_insensitive(
".js") ||
4634 FileName.ends_with_insensitive(
".mjs") ||
4635 FileName.ends_with_insensitive(
".cjs") ||
4636 FileName.ends_with_insensitive(
".ts")) {
4641 if (
FileName.ends_with_insensitive(
".proto") ||
4642 FileName.ends_with_insensitive(
".protodevel")) {
4648 if (
FileName.ends_with_insensitive(
".txtpb") ||
4649 FileName.ends_with_insensitive(
".textpb") ||
4650 FileName.ends_with_insensitive(
".pb.txt") ||
4651 FileName.ends_with_insensitive(
".textproto") ||
4652 FileName.ends_with_insensitive(
".asciipb")) {
4655 if (
FileName.ends_with_insensitive(
".td"))
4657 if (
FileName.ends_with_insensitive(
".cs"))
4659 if (
FileName.ends_with_insensitive(
".json") ||
4660 FileName.ends_with_insensitive(
".ipynb")) {
4663 if (
FileName.ends_with_insensitive(
".sv") ||
4664 FileName.ends_with_insensitive(
".svh") ||
4665 FileName.ends_with_insensitive(
".v") ||
4666 FileName.ends_with_insensitive(
".vh")) {
4677 LangOpts.CPlusPlus = 1;
4678 LangOpts.LineComment = 1;
4680 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);
4684 auto Text = StringRef(SourceMgr.getCharacterData(
Tok.getLocation()),
4686 if (!
Text.consume_front(
"// clang-format Language:"))
4704 auto Extension = llvm::sys::path::extension(
FileName);
4707 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4716 if (Guesser.isObjC())
4720 return GuessedLanguage;
4728llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4731 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4733 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4734 FS->getBufferForFile(ConfigFile);
4735 if (
auto EC =
Text.getError())
4738 DiagHandler,
nullptr,
4746 StringRef FallbackStyleName, StringRef Code,
4747 llvm::vfs::FileSystem *FS,
4748 bool AllowUnknownOptions,
4749 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4757 if (StyleName.starts_with(
"{")) {
4759 StringRef Source =
"<command-line>";
4760 if (std::error_code ec =
4762 AllowUnknownOptions, DiagHandler)) {
4766 if (Style.InheritConfig.empty())
4769 ChildFormatTextToApply.emplace_back(
4770 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4774 FS = llvm::vfs::getRealFileSystem().get();
4777 const bool IsDotHFile =
FileName.ends_with(
".h");
4780 if (Style.InheritConfig.empty() &&
4781 StyleName.starts_with_insensitive(
"file:")) {
4782 auto ConfigFile = StyleName.substr(5);
4783 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4785 DiagHandler, IsDotHFile);
4786 if (
auto EC =
Text.getError()) {
4791 LLVM_DEBUG(llvm::dbgs()
4792 <<
"Using configuration file " << ConfigFile <<
"\n");
4794 if (Style.InheritConfig.empty())
4800 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4806 if (Style.InheritConfig.empty() && !StyleName.equals_insensitive(
"file")) {
4809 if (Style.InheritConfig.empty())
4813 using namespace llvm::sys::path;
4817 if (std::error_code EC = FS->makeAbsolute(Path))
4820 auto Normalize = [](String &Path) {
4821 Path = convert_to_slash(Path);
4822 remove_dots(Path,
true, Style::posix);
4828 Style.InheritConfig.clear();
4830 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4832 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4833 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4836 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4839 static_cast<void>(EC);
4845 FilesToLookFor.push_back(
".clang-format");
4846 FilesToLookFor.push_back(
"_clang-format");
4848 llvm::StringSet<> Directories;
4849 bool Redirected =
false;
4850 String Dir, UnsuitableConfigFiles;
4851 for (StringRef Directory = Path; !Directory.empty();
4852 Directory = Redirected ? Dir.str() : parent_path(Directory)) {
4853 auto Status = FS->status(Directory);
4855 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4862 for (
const auto &F : FilesToLookFor) {
4863 String ConfigFile(Directory);
4865 append(ConfigFile, F);
4866 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4868 Status = FS->status(ConfigFile);
4870 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4874 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4876 DiagHandler, IsDotHFile);
4877 if (
auto EC =
Text.getError()) {
4882 if (!UnsuitableConfigFiles.empty())
4883 UnsuitableConfigFiles.append(
", ");
4884 UnsuitableConfigFiles.append(ConfigFile);
4888 LLVM_DEBUG(llvm::dbgs()
4889 <<
"Using configuration file " << ConfigFile <<
"\n");
4891 if (Style.InheritConfig.empty()) {
4892 if (!ChildFormatTextToApply.empty()) {
4893 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4894 applyChildFormatTexts(&Style);
4899 if (!Directories.insert(Directory).second) {
4901 "Loop detected when inheriting configuration file in " + Directory);
4904 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4906 if (Style.InheritConfig ==
"..") {
4911 llvm::sys::fs::expand_tilde(Style.InheritConfig, ExpandedDir);
4912 Normalize(ExpandedDir);
4913 if (is_absolute(ExpandedDir, Style::posix)) {
4916 Dir = Directory.str();
4917 append(Dir, Style::posix, ExpandedDir);
4922 Style.InheritConfig.clear();
4924 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4934 if (!UnsuitableConfigFiles.empty()) {
4937 UnsuitableConfigFiles);
4940 if (!ChildFormatTextToApply.empty()) {
4941 LLVM_DEBUG(llvm::dbgs()
4942 <<
"Applying child configurations on fallback style\n");
4943 applyChildFormatTexts(&FallbackStyle);
4946 return FallbackStyle;
4950 if (Comment == (
On ?
"/* clang-format on */" :
"/* clang-format off */"))
4953 static const char ClangFormatOn[] =
"// clang-format on";
4954 static const char ClangFormatOff[] =
"// clang-format off";
4955 const unsigned Size = (
On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4957 return Comment.starts_with(
On ? ClangFormatOn : ClangFormatOff) &&
4958 (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
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)