26#include "llvm/ADT/Sequence.h"
27#include "llvm/ADT/StringSet.h"
31#define DEBUG_TYPE "format-formatter"
50struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeNoexceptSpecifierStyle> {
59template <>
struct MappingTraits<
FormatStyle::AlignConsecutiveStyle> {
62 IO.enumCase(
Value,
"Consecutive",
69 IO.enumCase(
Value,
"AcrossEmptyLines",
76 IO.enumCase(
Value,
"AcrossComments",
83 IO.enumCase(
Value,
"AcrossEmptyLinesAndComments",
92 IO.enumCase(
Value,
"true",
103 IO.mapOptional(
"Enabled",
Value.Enabled);
104 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
105 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
106 IO.mapOptional(
"AlignCompound",
Value.AlignCompound);
107 IO.mapOptional(
"AlignFunctionDeclarations",
108 Value.AlignFunctionDeclarations);
109 IO.mapOptional(
"AlignFunctionPointers",
Value.AlignFunctionPointers);
110 IO.mapOptional(
"EnumAssignments",
Value.EnumAssignments);
111 IO.mapOptional(
"PadOperators",
Value.PadOperators);
116struct MappingTraits<
FormatStyle::ShortCaseStatementsAlignmentStyle> {
119 IO.mapOptional(
"Enabled",
Value.Enabled);
120 IO.mapOptional(
"AcrossEmptyLines",
Value.AcrossEmptyLines);
121 IO.mapOptional(
"AcrossComments",
Value.AcrossComments);
122 IO.mapOptional(
"AlignCaseArrows",
Value.AlignCaseArrows);
123 IO.mapOptional(
"AlignCaseColons",
Value.AlignCaseColons);
128struct ScalarEnumerationTraits<
FormatStyle::AttributeBreakingStyle> {
138struct ScalarEnumerationTraits<
FormatStyle::ArrayInitializerAlignmentStyle> {
147template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
157template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackArgumentsStyle> {
170struct ScalarEnumerationTraits<
FormatStyle::BinPackParametersStyle> {
183template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
192struct ScalarEnumerationTraits<
FormatStyle::BitFieldColonSpacingStyle> {
202template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
216template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
219 IO.mapOptional(
"AfterClass", Wrapping.
AfterClass);
221 IO.mapOptional(
"AfterEnum", Wrapping.
AfterEnum);
226 IO.mapOptional(
"AfterStruct", Wrapping.
AfterStruct);
227 IO.mapOptional(
"AfterUnion", Wrapping.
AfterUnion);
228 IO.mapOptional(
"BeforeCatch", Wrapping.
BeforeCatch);
229 IO.mapOptional(
"BeforeElse", Wrapping.
BeforeElse);
231 IO.mapOptional(
"BeforeWhile", Wrapping.
BeforeWhile);
253struct ScalarEnumerationTraits<
254 FormatStyle::BraceWrappingAfterControlStatementStyle> {
269struct ScalarEnumerationTraits<
270 FormatStyle::BreakBeforeConceptDeclarationsStyle> {
284struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeInlineASMColonStyle> {
294struct ScalarEnumerationTraits<
FormatStyle::BreakBinaryOperationsStyle> {
303template <>
struct ScalarTraits<
clang::tok::TokenKind> {
305 llvm::raw_ostream &Out) {
312 static StringRef
input(StringRef Scalar,
void *,
315#define PUNCTUATOR(Name, Spelling) \
316 if (Scalar == Spelling) { \
317 Value = clang::tok::Name; \
320#include "clang/Basic/TokenKinds.def"
321 return "unknown operator";
324 static QuotingType
mustQuote(StringRef) {
return QuotingType::None; }
327template <>
struct MappingTraits<
FormatStyle::BinaryOperationBreakRule> {
329 IO.mapOptional(
"Operators",
Value.Operators);
331 if (!IO.outputting())
333 IO.mapOptional(
"Style",
Value.Style);
334 IO.mapOptional(
"MinChainLength",
Value.MinChainLength);
338template <>
struct MappingTraits<
FormatStyle::BreakBinaryOperationsOptions> {
341 IO.enumCase(
Value,
"Never",
344 IO.enumCase(
Value,
"OnePerLine",
347 IO.enumCase(
Value,
"RespectPrecedence",
354 IO.mapOptional(
"Default",
Value.Default);
355 IO.mapOptional(
"PerOperator",
Value.PerOperator);
360struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
371struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
382struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
396template <>
struct ScalarEnumerationTraits<
FormatStyle::BracedListStyle> {
408template <>
struct ScalarEnumerationTraits<
FormatStyle::DAGArgStyle> {
417struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
431struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
446struct ScalarEnumerationTraits<
FormatStyle::EmptyLineAfterAccessModifierStyle> {
456struct ScalarEnumerationTraits<
468struct ScalarEnumerationTraits<
FormatStyle::EnumTrailingCommaStyle> {
477struct ScalarEnumerationTraits<
FormatStyle::IndentExternBlockStyle> {
487template <>
struct MappingTraits<
FormatStyle::IntegerLiteralSeparatorStyle> {
489 IO.mapOptional(
"Binary",
Base.Binary);
490 IO.mapOptional(
"BinaryMinDigitsInsert",
Base.BinaryMinDigitsInsert);
491 IO.mapOptional(
"BinaryMaxDigitsRemove",
Base.BinaryMaxDigitsRemove);
492 IO.mapOptional(
"Decimal",
Base.Decimal);
493 IO.mapOptional(
"DecimalMinDigitsInsert",
Base.DecimalMinDigitsInsert);
494 IO.mapOptional(
"DecimalMaxDigitsRemove",
Base.DecimalMaxDigitsRemove);
495 IO.mapOptional(
"Hex",
Base.Hex);
496 IO.mapOptional(
"HexMinDigitsInsert",
Base.HexMinDigitsInsert);
497 IO.mapOptional(
"HexMaxDigitsRemove",
Base.HexMaxDigitsRemove);
500 IO.mapOptional(
"BinaryMinDigits",
Base.BinaryMinDigitsInsert);
501 IO.mapOptional(
"DecimalMinDigits",
Base.DecimalMinDigitsInsert);
502 IO.mapOptional(
"HexMinDigits",
Base.HexMinDigitsInsert);
506template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
514template <>
struct MappingTraits<
FormatStyle::KeepEmptyLinesStyle> {
516 IO.mapOptional(
"AtEndOfFile",
Value.AtEndOfFile);
517 IO.mapOptional(
"AtStartOfBlock",
Value.AtStartOfBlock);
518 IO.mapOptional(
"AtStartOfFile",
Value.AtStartOfFile);
522template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
538template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
560struct ScalarEnumerationTraits<
FormatStyle::LambdaBodyIndentationKind> {
568template <>
struct ScalarEnumerationTraits<
FormatStyle::LineEndingStyle> {
578struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
588struct ScalarEnumerationTraits<
FormatStyle::NumericLiteralComponentStyle> {
597template <>
struct MappingTraits<
FormatStyle::NumericLiteralCaseStyle> {
599 IO.mapOptional(
"ExponentLetter",
Value.ExponentLetter);
600 IO.mapOptional(
"HexDigit",
Value.HexDigit);
601 IO.mapOptional(
"Prefix",
Value.Prefix);
602 IO.mapOptional(
"Suffix",
Value.Suffix);
606template <>
struct ScalarEnumerationTraits<
FormatStyle::OperandAlignmentStyle> {
610 IO.enumCase(
Value,
"AlignAfterOperator",
619template <>
struct MappingTraits<
FormatStyle::PackParametersStyle> {
621 IO.mapOptional(
"BinPack",
Value.BinPack);
622 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
627struct ScalarEnumerationTraits<
FormatStyle::PackConstructorInitializersStyle> {
638template <>
struct MappingTraits<
FormatStyle::PackArgumentsStyle> {
640 IO.mapOptional(
"BinPack",
Value.BinPack);
641 IO.mapOptional(
"BreakAfter",
Value.BreakAfter);
645template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
658struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
668struct ScalarEnumerationTraits<
FormatStyle::QualifierAlignmentStyle> {
679 IO.mapOptional(
"Language", Format.Language);
680 IO.mapOptional(
"Delimiters", Format.Delimiters);
681 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
682 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
683 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
687template <>
struct ScalarEnumerationTraits<
FormatStyle::ReflowCommentsStyle> {
699struct ScalarEnumerationTraits<
FormatStyle::ReferenceAlignmentStyle> {
709struct ScalarEnumerationTraits<
FormatStyle::RemoveParenthesesStyle> {
712 IO.enumCase(
Value,
"MultipleParentheses",
719struct ScalarEnumerationTraits<
FormatStyle::RequiresClausePositionStyle> {
731struct ScalarEnumerationTraits<
FormatStyle::RequiresExpressionIndentationKind> {
740struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
747 IO.enumCase(
Value,
"TopLevelDefinitions",
754struct ScalarEnumerationTraits<
FormatStyle::BreakBeforeReturnTypeStyle> {
761 IO.enumCase(
Value,
"TopLevelDefinitions",
767struct ScalarEnumerationTraits<
FormatStyle::SeparateDefinitionStyle> {
775template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortBlockStyle> {
785template <>
struct MappingTraits<
FormatStyle::ShortFunctionStyle> {
788 IO.enumCase(
Value,
"Empty",
790 IO.enumCase(
Value,
"Inline",
792 IO.enumCase(
Value,
"InlineOnly",
802 IO.mapOptional(
"Empty",
Value.Empty);
803 IO.mapOptional(
"Inline",
Value.Inline);
804 IO.mapOptional(
"Other",
Value.Other);
808template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortIfStyle> {
822template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortLambdaStyle> {
833template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortRecordStyle> {
842template <>
struct MappingTraits<
FormatStyle::SortIncludesOptions> {
845 IO.enumCase(
Value,
"CaseInsensitive",
850 IO.enumCase(
Value,
"CaseSensitive",
855 IO.enumCase(
Value,
"Natural",
863 IO.enumCase(
Value,
"true",
871 IO.mapOptional(
"Enabled",
Value.Enabled);
872 IO.mapOptional(
"IgnoreCase",
Value.IgnoreCase);
873 IO.mapOptional(
"IgnoreExtension",
Value.IgnoreExtension);
874 IO.mapOptional(
"Natural",
Value.Natural);
879struct ScalarEnumerationTraits<
FormatStyle::SortJavaStaticImportOptions> {
888struct ScalarEnumerationTraits<
FormatStyle::SortUsingDeclarationsOptions> {
893 IO.enumCase(
Value,
"LexicographicNumeric",
903struct ScalarEnumerationTraits<
FormatStyle::SpaceAroundPointerQualifiersStyle> {
913template <>
struct MappingTraits<
FormatStyle::SpaceBeforeParensCustom> {
917 IO.mapOptional(
"AfterFunctionDefinitionName",
919 IO.mapOptional(
"AfterFunctionDeclarationName",
922 IO.mapOptional(
"AfterNot", Spacing.
AfterNot);
926 IO.mapOptional(
"AfterRequiresInExpression",
928 IO.mapOptional(
"BeforeNonEmptyParentheses",
934struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensStyle> {
937 IO.enumCase(
Value,
"ControlStatements",
939 IO.enumCase(
Value,
"ControlStatementsExceptControlMacros",
941 IO.enumCase(
Value,
"NonEmptyParentheses",
949 IO.enumCase(
Value,
"ControlStatementsExceptForEachMacros",
955struct ScalarEnumerationTraits<
FormatStyle::SpaceInEmptyBracesStyle> {
963template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInAnglesStyle> {
976struct ScalarEnumerationTraits<
FormatStyle::SpacesInBlockCommentsStyle> {
985template <>
struct MappingTraits<
FormatStyle::SpacesInLineComment> {
988 int signedMaximum =
static_cast<int>(Space.
Maximum);
989 IO.mapOptional(
"Minimum", Space.
Minimum);
990 IO.mapOptional(
"Maximum", signedMaximum);
991 Space.
Maximum =
static_cast<unsigned>(signedMaximum);
993 if (Space.
Maximum < std::numeric_limits<unsigned>::max())
998template <>
struct MappingTraits<
FormatStyle::SpacesInParensCustom> {
1004 IO.mapOptional(
"Other", Spaces.
Other);
1008template <>
struct ScalarEnumerationTraits<
FormatStyle::SpacesInParensStyle> {
1015template <>
struct ScalarEnumerationTraits<
FormatStyle::TrailingCommaStyle> {
1023struct ScalarEnumerationTraits<
FormatStyle::TrailingCommentsAlignmentKinds> {
1032template <>
struct MappingTraits<
FormatStyle::TrailingCommentsAlignmentStyle> {
1035 IO.enumCase(
Value,
"Leave",
1039 IO.enumCase(
Value,
"Always",
1043 IO.enumCase(
Value,
"Never",
1048 IO.enumCase(
Value,
"true",
1051 IO.enumCase(
Value,
"false",
1058 IO.mapOptional(
"AlignPPAndNotPP",
Value.AlignPPAndNotPP);
1059 IO.mapOptional(
"Kind",
Value.Kind);
1060 IO.mapOptional(
"OverEmptyLines",
Value.OverEmptyLines);
1071 IO.enumCase(
Value,
"ForContinuationAndIndentation",
1078struct ScalarEnumerationTraits<
1079 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {
1092 IO.mapOptional(
"Language", Style.Language);
1094 StringRef BasedOnStyle;
1095 if (IO.outputting()) {
1096 StringRef Styles[] = {
"LLVM",
"Google",
"Chromium",
"Mozilla",
1097 "WebKit",
"GNU",
"Microsoft",
"clang-format"};
1098 for (StringRef StyleName : Styles) {
1100 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
1101 Style == PredefinedStyle) {
1102 BasedOnStyle = StyleName;
1107 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
1108 if (!BasedOnStyle.empty()) {
1112 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
1113 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
1116 Style.Language = OldLanguage;
1131 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive(
"google") ||
1132 BasedOnStyle.equals_insensitive(
"chromium");
1133 bool OnCurrentLine = IsGoogleOrChromium;
1134 bool OnNextLine =
true;
1136 bool BreakBeforeInheritanceComma =
false;
1137 bool BreakConstructorInitializersBeforeComma =
false;
1139 bool DeriveLineEnding =
true;
1140 bool UseCRLF =
false;
1142 bool SpaceInEmptyBlock =
false;
1143 bool SpaceInEmptyParentheses =
false;
1144 bool SpacesInConditionalStatement =
false;
1145 bool SpacesInCStyleCastParentheses =
false;
1146 bool SpacesInParentheses =
false;
1148 if (IO.outputting()) {
1149 IO.mapOptional(
"AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
1153 if (IsGoogleOrChromium) {
1156 Language = ((
FormatStyle *)IO.getContext())->Language;
1161 }
else if (BasedOnStyle.equals_insensitive(
"webkit")) {
1164 IO.mapOptional(
"AlignAfterOpenBracket", LocalBAS);
1168 Style.AlignAfterOpenBracket =
false;
1169 Style.BreakAfterOpenBracketBracedList =
false;
1170 Style.BreakAfterOpenBracketFunction =
false;
1171 Style.BreakAfterOpenBracketIf =
false;
1172 Style.BreakAfterOpenBracketLoop =
false;
1173 Style.BreakAfterOpenBracketSwitch =
false;
1174 Style.BreakBeforeCloseBracketBracedList =
false;
1175 Style.BreakBeforeCloseBracketFunction =
false;
1176 Style.BreakBeforeCloseBracketIf =
false;
1177 Style.BreakBeforeCloseBracketLoop =
false;
1178 Style.BreakBeforeCloseBracketSwitch =
false;
1181 Style.AlignAfterOpenBracket =
true;
1182 Style.BreakAfterOpenBracketBracedList =
true;
1183 Style.BreakAfterOpenBracketFunction =
true;
1184 Style.BreakAfterOpenBracketIf =
true;
1185 Style.BreakAfterOpenBracketLoop =
false;
1186 Style.BreakAfterOpenBracketSwitch =
false;
1187 Style.BreakBeforeCloseBracketBracedList =
true;
1188 Style.BreakBeforeCloseBracketFunction =
true;
1189 Style.BreakBeforeCloseBracketIf =
true;
1190 Style.BreakBeforeCloseBracketLoop =
false;
1191 Style.BreakBeforeCloseBracketSwitch =
false;
1194 Style.AlignAfterOpenBracket =
true;
1195 Style.BreakAfterOpenBracketBracedList =
true;
1196 Style.BreakAfterOpenBracketFunction =
true;
1197 Style.BreakAfterOpenBracketIf =
true;
1198 Style.BreakAfterOpenBracketLoop =
false;
1199 Style.BreakAfterOpenBracketSwitch =
false;
1200 Style.BreakBeforeCloseBracketBracedList =
false;
1201 Style.BreakBeforeCloseBracketFunction =
false;
1202 Style.BreakBeforeCloseBracketIf =
false;
1203 Style.BreakBeforeCloseBracketLoop =
false;
1204 Style.BreakBeforeCloseBracketSwitch =
false;
1207 Style.AlignAfterOpenBracket =
true;
1208 Style.BreakAfterOpenBracketBracedList =
false;
1209 Style.BreakAfterOpenBracketFunction =
false;
1210 Style.BreakAfterOpenBracketIf =
false;
1211 Style.BreakAfterOpenBracketLoop =
false;
1212 Style.BreakAfterOpenBracketSwitch =
false;
1213 Style.BreakBeforeCloseBracketBracedList =
false;
1214 Style.BreakBeforeCloseBracketFunction =
false;
1215 Style.BreakBeforeCloseBracketIf =
false;
1216 Style.BreakBeforeCloseBracketLoop =
false;
1217 Style.BreakBeforeCloseBracketSwitch =
false;
1225 if (!IO.outputting()) {
1226 IO.mapOptional(
"AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
1227 IO.mapOptional(
"AllowAllConstructorInitializersOnNextLine", OnNextLine);
1228 IO.mapOptional(
"AlwaysBreakAfterReturnType", Style.BreakAfterReturnType);
1229 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
1230 Style.BreakTemplateDeclarations);
1231 IO.mapOptional(
"BinPackArguments", Style.PackArguments.BinPack);
1232 IO.mapOptional(
"BinPackParameters", Style.PackParameters.BinPack);
1233 IO.mapOptional(
"BreakBeforeInheritanceComma",
1234 BreakBeforeInheritanceComma);
1235 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
1236 BreakConstructorInitializersBeforeComma);
1237 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
1239 IO.mapOptional(
"DeriveLineEnding", DeriveLineEnding);
1240 IO.mapOptional(
"DerivePointerBinding", Style.DerivePointerAlignment);
1241 IO.mapOptional(
"KeepEmptyLinesAtEOF", Style.KeepEmptyLines.AtEndOfFile);
1242 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
1243 Style.KeepEmptyLines.AtStartOfBlock);
1244 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
1245 Style.IndentWrappedFunctionNames);
1246 IO.mapOptional(
"IndentRequires", Style.IndentRequiresClause);
1247 IO.mapOptional(
"PointerBindsToType", Style.PointerAlignment);
1248 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
1249 Style.SpaceBeforeParens);
1250 IO.mapOptional(
"SpaceInEmptyBlock", SpaceInEmptyBlock);
1251 IO.mapOptional(
"SpaceInEmptyParentheses", SpaceInEmptyParentheses);
1252 IO.mapOptional(
"SpacesInConditionalStatement",
1253 SpacesInConditionalStatement);
1254 IO.mapOptional(
"SpacesInCStyleCastParentheses",
1255 SpacesInCStyleCastParentheses);
1256 IO.mapOptional(
"SpacesInParentheses", SpacesInParentheses);
1257 IO.mapOptional(
"UseCRLF", UseCRLF);
1260 IO.mapOptional(
"AccessModifierOffset", Style.AccessModifierOffset);
1261 IO.mapOptional(
"AlignArrayOfStructures", Style.AlignArrayOfStructures);
1262 IO.mapOptional(
"AlignConsecutiveAssignments",
1263 Style.AlignConsecutiveAssignments);
1264 IO.mapOptional(
"AlignConsecutiveBitFields",
1265 Style.AlignConsecutiveBitFields);
1266 IO.mapOptional(
"AlignConsecutiveDeclarations",
1267 Style.AlignConsecutiveDeclarations);
1268 IO.mapOptional(
"AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
1269 IO.mapOptional(
"AlignConsecutiveShortCaseStatements",
1270 Style.AlignConsecutiveShortCaseStatements);
1271 IO.mapOptional(
"AlignConsecutiveTableGenBreakingDAGArgColons",
1272 Style.AlignConsecutiveTableGenBreakingDAGArgColons);
1273 IO.mapOptional(
"AlignConsecutiveTableGenCondOperatorColons",
1274 Style.AlignConsecutiveTableGenCondOperatorColons);
1275 IO.mapOptional(
"AlignConsecutiveTableGenDefinitionColons",
1276 Style.AlignConsecutiveTableGenDefinitionColons);
1277 IO.mapOptional(
"AlignEscapedNewlines", Style.AlignEscapedNewlines);
1278 IO.mapOptional(
"AlignOperands", Style.AlignOperands);
1279 IO.mapOptional(
"AlignTrailingComments", Style.AlignTrailingComments);
1280 IO.mapOptional(
"AllowAllArgumentsOnNextLine",
1281 Style.AllowAllArgumentsOnNextLine);
1282 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
1283 Style.AllowAllParametersOfDeclarationOnNextLine);
1284 IO.mapOptional(
"AllowBreakBeforeNoexceptSpecifier",
1285 Style.AllowBreakBeforeNoexceptSpecifier);
1286 IO.mapOptional(
"AllowBreakBeforeQtProperty",
1287 Style.AllowBreakBeforeQtProperty);
1288 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
1289 Style.AllowShortBlocksOnASingleLine);
1290 IO.mapOptional(
"AllowShortCaseExpressionOnASingleLine",
1291 Style.AllowShortCaseExpressionOnASingleLine);
1292 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
1293 Style.AllowShortCaseLabelsOnASingleLine);
1294 IO.mapOptional(
"AllowShortCompoundRequirementOnASingleLine",
1295 Style.AllowShortCompoundRequirementOnASingleLine);
1296 IO.mapOptional(
"AllowShortEnumsOnASingleLine",
1297 Style.AllowShortEnumsOnASingleLine);
1298 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
1299 Style.AllowShortFunctionsOnASingleLine);
1300 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
1301 Style.AllowShortIfStatementsOnASingleLine);
1302 IO.mapOptional(
"AllowShortLambdasOnASingleLine",
1303 Style.AllowShortLambdasOnASingleLine);
1304 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
1305 Style.AllowShortLoopsOnASingleLine);
1306 IO.mapOptional(
"AllowShortNamespacesOnASingleLine",
1307 Style.AllowShortNamespacesOnASingleLine);
1308 IO.mapOptional(
"AllowShortRecordOnASingleLine",
1309 Style.AllowShortRecordOnASingleLine);
1310 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
1311 Style.AlwaysBreakAfterDefinitionReturnType);
1312 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
1313 Style.AlwaysBreakBeforeMultilineStrings);
1314 IO.mapOptional(
"AttributeMacros", Style.AttributeMacros);
1315 IO.mapOptional(
"BinPackLongBracedList", Style.BinPackLongBracedList);
1316 IO.mapOptional(
"BitFieldColonSpacing", Style.BitFieldColonSpacing);
1317 IO.mapOptional(
"BracedInitializerIndentWidth",
1318 Style.BracedInitializerIndentWidth);
1319 IO.mapOptional(
"BraceWrapping", Style.BraceWrapping);
1320 IO.mapOptional(
"BreakAdjacentStringLiterals",
1321 Style.BreakAdjacentStringLiterals);
1322 IO.mapOptional(
"BreakAfterAttributes", Style.BreakAfterAttributes);
1323 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
1324 Style.BreakAfterJavaFieldAnnotations);
1325 IO.mapOptional(
"BreakAfterOpenBracketBracedList",
1326 Style.BreakAfterOpenBracketBracedList);
1327 IO.mapOptional(
"BreakAfterOpenBracketFunction",
1328 Style.BreakAfterOpenBracketFunction);
1329 IO.mapOptional(
"BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf);
1330 IO.mapOptional(
"BreakAfterOpenBracketLoop",
1331 Style.BreakAfterOpenBracketLoop);
1332 IO.mapOptional(
"BreakAfterOpenBracketSwitch",
1333 Style.BreakAfterOpenBracketSwitch);
1334 IO.mapOptional(
"BreakAfterReturnType", Style.BreakAfterReturnType);
1335 IO.mapOptional(
"BreakArrays", Style.BreakArrays);
1336 IO.mapOptional(
"BreakBeforeBinaryOperators",
1337 Style.BreakBeforeBinaryOperators);
1338 IO.mapOptional(
"BreakBeforeCloseBracketBracedList",
1339 Style.BreakBeforeCloseBracketBracedList);
1340 IO.mapOptional(
"BreakBeforeCloseBracketFunction",
1341 Style.BreakBeforeCloseBracketFunction);
1342 IO.mapOptional(
"BreakBeforeCloseBracketIf",
1343 Style.BreakBeforeCloseBracketIf);
1344 IO.mapOptional(
"BreakBeforeCloseBracketLoop",
1345 Style.BreakBeforeCloseBracketLoop);
1346 IO.mapOptional(
"BreakBeforeCloseBracketSwitch",
1347 Style.BreakBeforeCloseBracketSwitch);
1348 IO.mapOptional(
"BreakBeforeConceptDeclarations",
1349 Style.BreakBeforeConceptDeclarations);
1350 IO.mapOptional(
"BreakBeforeBraces", Style.BreakBeforeBraces);
1351 IO.mapOptional(
"BreakBeforeInlineASMColon",
1352 Style.BreakBeforeInlineASMColon);
1353 IO.mapOptional(
"BreakBeforeReturnType", Style.BreakBeforeReturnType);
1354 IO.mapOptional(
"BreakBeforeTemplateCloser",
1355 Style.BreakBeforeTemplateCloser);
1356 IO.mapOptional(
"BreakBeforeTernaryOperators",
1357 Style.BreakBeforeTernaryOperators);
1358 IO.mapOptional(
"BreakBinaryOperations", Style.BreakBinaryOperations);
1359 IO.mapOptional(
"BreakConstructorInitializers",
1360 Style.BreakConstructorInitializers);
1361 IO.mapOptional(
"BreakFunctionDeclarationParameters",
1362 Style.BreakFunctionDeclarationParameters);
1363 IO.mapOptional(
"BreakFunctionDefinitionParameters",
1364 Style.BreakFunctionDefinitionParameters);
1365 IO.mapOptional(
"BreakInheritanceList", Style.BreakInheritanceList);
1366 IO.mapOptional(
"BreakStringLiterals", Style.BreakStringLiterals);
1367 IO.mapOptional(
"BreakTemplateDeclarations",
1368 Style.BreakTemplateDeclarations);
1369 IO.mapOptional(
"ColumnLimit", Style.ColumnLimit);
1370 IO.mapOptional(
"CommentPragmas", Style.CommentPragmas);
1371 IO.mapOptional(
"CompactNamespaces", Style.CompactNamespaces);
1372 IO.mapOptional(
"ConstructorInitializerIndentWidth",
1373 Style.ConstructorInitializerIndentWidth);
1374 IO.mapOptional(
"ContinuationIndentWidth", Style.ContinuationIndentWidth);
1375 IO.mapOptional(
"Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
1376 IO.mapOptional(
"DerivePointerAlignment", Style.DerivePointerAlignment);
1377 IO.mapOptional(
"DisableFormat", Style.DisableFormat);
1378 IO.mapOptional(
"EmptyLineAfterAccessModifier",
1379 Style.EmptyLineAfterAccessModifier);
1380 IO.mapOptional(
"EmptyLineBeforeAccessModifier",
1381 Style.EmptyLineBeforeAccessModifier);
1382 IO.mapOptional(
"EnumTrailingComma", Style.EnumTrailingComma);
1383 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
1384 Style.ExperimentalAutoDetectBinPacking);
1385 IO.mapOptional(
"FixNamespaceComments", Style.FixNamespaceComments);
1386 IO.mapOptional(
"ForEachMacros", Style.ForEachMacros);
1387 IO.mapOptional(
"IfMacros", Style.IfMacros);
1388 IO.mapOptional(
"IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
1389 IO.mapOptional(
"IncludeCategories", Style.IncludeStyle.IncludeCategories);
1390 IO.mapOptional(
"IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
1391 IO.mapOptional(
"IncludeIsMainSourceRegex",
1392 Style.IncludeStyle.IncludeIsMainSourceRegex);
1393 IO.mapOptional(
"IndentAccessModifiers", Style.IndentAccessModifiers);
1394 IO.mapOptional(
"IndentCaseBlocks", Style.IndentCaseBlocks);
1395 IO.mapOptional(
"IndentCaseLabels", Style.IndentCaseLabels);
1396 IO.mapOptional(
"IndentExportBlock", Style.IndentExportBlock);
1397 IO.mapOptional(
"IndentExternBlock", Style.IndentExternBlock);
1398 IO.mapOptional(
"IndentGotoLabels", Style.IndentGotoLabels);
1399 IO.mapOptional(
"IndentPPDirectives", Style.IndentPPDirectives);
1400 IO.mapOptional(
"IndentRequiresClause", Style.IndentRequiresClause);
1401 IO.mapOptional(
"IndentWidth", Style.IndentWidth);
1402 IO.mapOptional(
"IndentWrappedFunctionNames",
1403 Style.IndentWrappedFunctionNames);
1404 IO.mapOptional(
"InsertBraces", Style.InsertBraces);
1405 IO.mapOptional(
"InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
1406 IO.mapOptional(
"InsertTrailingCommas", Style.InsertTrailingCommas);
1407 IO.mapOptional(
"IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
1408 IO.mapOptional(
"JavaImportGroups", Style.JavaImportGroups);
1409 IO.mapOptional(
"JavaScriptQuotes", Style.JavaScriptQuotes);
1410 IO.mapOptional(
"JavaScriptWrapImports", Style.JavaScriptWrapImports);
1411 IO.mapOptional(
"KeepEmptyLines", Style.KeepEmptyLines);
1412 IO.mapOptional(
"KeepFormFeed", Style.KeepFormFeed);
1413 IO.mapOptional(
"LambdaBodyIndentation", Style.LambdaBodyIndentation);
1414 IO.mapOptional(
"LineEnding", Style.LineEnding);
1415 IO.mapOptional(
"MacroBlockBegin", Style.MacroBlockBegin);
1416 IO.mapOptional(
"MacroBlockEnd", Style.MacroBlockEnd);
1417 IO.mapOptional(
"Macros", Style.Macros);
1418 IO.mapOptional(
"MacrosSkippedByRemoveParentheses",
1419 Style.MacrosSkippedByRemoveParentheses);
1420 IO.mapOptional(
"MainIncludeChar", Style.IncludeStyle.MainIncludeChar);
1421 IO.mapOptional(
"MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
1422 IO.mapOptional(
"NamespaceIndentation", Style.NamespaceIndentation);
1423 IO.mapOptional(
"NamespaceMacros", Style.NamespaceMacros);
1424 IO.mapOptional(
"NumericLiteralCase", Style.NumericLiteralCase);
1425 IO.mapOptional(
"ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
1426 IO.mapOptional(
"ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
1427 IO.mapOptional(
"ObjCBreakBeforeNestedBlockParam",
1428 Style.ObjCBreakBeforeNestedBlockParam);
1429 IO.mapOptional(
"ObjCPropertyAttributeOrder",
1430 Style.ObjCPropertyAttributeOrder);
1431 IO.mapOptional(
"ObjCSpaceAfterMethodDeclarationPrefix",
1432 Style.ObjCSpaceAfterMethodDeclarationPrefix);
1433 IO.mapOptional(
"ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
1434 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
1435 Style.ObjCSpaceBeforeProtocolList);
1436 IO.mapOptional(
"OneLineFormatOffRegex", Style.OneLineFormatOffRegex);
1437 IO.mapOptional(
"PackArguments", Style.PackArguments);
1438 IO.mapOptional(
"PackConstructorInitializers",
1439 Style.PackConstructorInitializers);
1440 IO.mapOptional(
"PackParameters", Style.PackParameters);
1441 IO.mapOptional(
"PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
1442 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
1443 Style.PenaltyBreakBeforeFirstCallParameter);
1444 IO.mapOptional(
"PenaltyBreakBeforeMemberAccess",
1445 Style.PenaltyBreakBeforeMemberAccess);
1446 IO.mapOptional(
"PenaltyBreakComment", Style.PenaltyBreakComment);
1447 IO.mapOptional(
"PenaltyBreakFirstLessLess",
1448 Style.PenaltyBreakFirstLessLess);
1449 IO.mapOptional(
"PenaltyBreakOpenParenthesis",
1450 Style.PenaltyBreakOpenParenthesis);
1451 IO.mapOptional(
"PenaltyBreakScopeResolution",
1452 Style.PenaltyBreakScopeResolution);
1453 IO.mapOptional(
"PenaltyBreakString", Style.PenaltyBreakString);
1454 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
1455 Style.PenaltyBreakTemplateDeclaration);
1456 IO.mapOptional(
"PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
1457 IO.mapOptional(
"PenaltyIndentedWhitespace",
1458 Style.PenaltyIndentedWhitespace);
1459 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
1460 Style.PenaltyReturnTypeOnItsOwnLine);
1461 IO.mapOptional(
"PointerAlignment", Style.PointerAlignment);
1462 IO.mapOptional(
"PPIndentWidth", Style.PPIndentWidth);
1463 IO.mapOptional(
"QualifierAlignment", Style.QualifierAlignment);
1466 Style.QualifierOrder = {
"type",
"const",
"volatile"};
1468 Style.QualifierOrder = {
"const",
"volatile",
"type"};
1470 IO.mapOptional(
"QualifierOrder", Style.QualifierOrder);
1471 IO.mapOptional(
"RawStringFormats", Style.RawStringFormats);
1472 IO.mapOptional(
"ReferenceAlignment", Style.ReferenceAlignment);
1473 IO.mapOptional(
"ReflowComments", Style.ReflowComments);
1474 IO.mapOptional(
"RemoveBracesLLVM", Style.RemoveBracesLLVM);
1475 IO.mapOptional(
"RemoveEmptyLinesInUnwrappedLines",
1476 Style.RemoveEmptyLinesInUnwrappedLines);
1477 IO.mapOptional(
"RemoveParentheses", Style.RemoveParentheses);
1478 IO.mapOptional(
"RemoveSemicolon", Style.RemoveSemicolon);
1479 IO.mapOptional(
"RequiresClausePosition", Style.RequiresClausePosition);
1480 IO.mapOptional(
"RequiresExpressionIndentation",
1481 Style.RequiresExpressionIndentation);
1482 IO.mapOptional(
"SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
1483 IO.mapOptional(
"ShortNamespaceLines", Style.ShortNamespaceLines);
1484 IO.mapOptional(
"SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
1485 IO.mapOptional(
"SortIncludes", Style.SortIncludes);
1486 IO.mapOptional(
"SortJavaStaticImport", Style.SortJavaStaticImport);
1487 IO.mapOptional(
"SortUsingDeclarations", Style.SortUsingDeclarations);
1488 IO.mapOptional(
"SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
1489 IO.mapOptional(
"SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
1490 IO.mapOptional(
"SpaceAfterOperatorKeyword",
1491 Style.SpaceAfterOperatorKeyword);
1492 IO.mapOptional(
"SpaceAfterTemplateKeyword",
1493 Style.SpaceAfterTemplateKeyword);
1494 IO.mapOptional(
"SpaceAroundPointerQualifiers",
1495 Style.SpaceAroundPointerQualifiers);
1496 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
1497 Style.SpaceBeforeAssignmentOperators);
1498 IO.mapOptional(
"SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
1499 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
1500 Style.SpaceBeforeCpp11BracedList);
1501 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
1502 Style.SpaceBeforeCtorInitializerColon);
1503 IO.mapOptional(
"SpaceBeforeEnumUnderlyingTypeColon",
1504 Style.SpaceBeforeEnumUnderlyingTypeColon);
1505 IO.mapOptional(
"SpaceBeforeInheritanceColon",
1506 Style.SpaceBeforeInheritanceColon);
1507 IO.mapOptional(
"SpaceBeforeJsonColon", Style.SpaceBeforeJsonColon);
1508 IO.mapOptional(
"SpaceBeforeParens", Style.SpaceBeforeParens);
1509 IO.mapOptional(
"SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
1510 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
1511 Style.SpaceBeforeRangeBasedForLoopColon);
1512 IO.mapOptional(
"SpaceBeforeSquareBrackets",
1513 Style.SpaceBeforeSquareBrackets);
1514 IO.mapOptional(
"SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
1515 IO.mapOptional(
"SpacesBeforeTrailingComments",
1516 Style.SpacesBeforeTrailingComments);
1517 IO.mapOptional(
"SpacesInAngles", Style.SpacesInAngles);
1518 IO.mapOptional(
"SpacesInBlockComments", Style.SpacesInBlockComments);
1519 IO.mapOptional(
"SpacesInContainerLiterals",
1520 Style.SpacesInContainerLiterals);
1521 IO.mapOptional(
"SpacesInLineCommentPrefix",
1522 Style.SpacesInLineCommentPrefix);
1523 IO.mapOptional(
"SpacesInParens", Style.SpacesInParens);
1524 IO.mapOptional(
"SpacesInParensOptions", Style.SpacesInParensOptions);
1525 IO.mapOptional(
"SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
1526 IO.mapOptional(
"Standard", Style.Standard);
1527 IO.mapOptional(
"StatementAttributeLikeMacros",
1528 Style.StatementAttributeLikeMacros);
1529 IO.mapOptional(
"StatementMacros", Style.StatementMacros);
1530 IO.mapOptional(
"TableGenBreakingDAGArgOperators",
1531 Style.TableGenBreakingDAGArgOperators);
1532 IO.mapOptional(
"TableGenBreakInsideDAGArg",
1533 Style.TableGenBreakInsideDAGArg);
1534 IO.mapOptional(
"TabWidth", Style.TabWidth);
1535 IO.mapOptional(
"TemplateNames", Style.TemplateNames);
1536 IO.mapOptional(
"TypeNames", Style.TypeNames);
1537 IO.mapOptional(
"TypenameMacros", Style.TypenameMacros);
1538 IO.mapOptional(
"UseTab", Style.UseTab);
1539 IO.mapOptional(
"VariableTemplates", Style.VariableTemplates);
1540 IO.mapOptional(
"VerilogBreakBetweenInstancePorts",
1541 Style.VerilogBreakBetweenInstancePorts);
1542 IO.mapOptional(
"WhitespaceSensitiveMacros",
1543 Style.WhitespaceSensitiveMacros);
1544 IO.mapOptional(
"WrapNamespaceBodyWithEmptyLines",
1545 Style.WrapNamespaceBodyWithEmptyLines);
1552 if (Style.AlwaysBreakAfterDefinitionReturnType ==
1555 }
else if (Style.AlwaysBreakAfterDefinitionReturnType ==
1563 if (BreakBeforeInheritanceComma &&
1571 if (BreakConstructorInitializersBeforeComma &&
1576 if (!IsGoogleOrChromium) {
1579 Style.PackConstructorInitializers = OnNextLine
1583 }
else if (Style.PackConstructorInitializers ==
1587 else if (!OnNextLine)
1592 if (!DeriveLineEnding)
1600 if (SpaceInEmptyBlock &&
1606 (SpacesInParentheses || SpaceInEmptyParentheses ||
1607 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
1608 if (SpacesInParentheses) {
1610 Style.SpacesInParensOptions.ExceptDoubleParentheses =
false;
1611 Style.SpacesInParensOptions.InConditionalStatements =
true;
1612 Style.SpacesInParensOptions.InCStyleCasts =
1613 SpacesInCStyleCastParentheses;
1614 Style.SpacesInParensOptions.InEmptyParentheses =
1615 SpaceInEmptyParentheses;
1616 Style.SpacesInParensOptions.Other =
true;
1618 Style.SpacesInParensOptions = {};
1619 Style.SpacesInParensOptions.InConditionalStatements =
1620 SpacesInConditionalStatement;
1621 Style.SpacesInParensOptions.InCStyleCasts =
1622 SpacesInCStyleCastParentheses;
1623 Style.SpacesInParensOptions.InEmptyParentheses =
1624 SpaceInEmptyParentheses;
1636template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
1637 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
1642 if (Index >= Seq.size()) {
1643 assert(Index == Seq.size());
1648 Template = *((
const FormatStyle *)IO.getContext());
1651 Seq.resize(Index + 1, Template);
1657template <>
struct ScalarEnumerationTraits<
FormatStyle::IndentGotoLabelStyle> {
1685 return llvm::make_error<llvm::StringError>(Message,
1686 llvm::inconvertibleErrorCode());
1690 return "clang-format.parse_error";
1698 return "Invalid argument";
1700 return "Unsuitable";
1702 return "trailing comma insertion cannot be used with bin packing";
1704 return "Invalid qualifier specified in QualifierOrder";
1706 return "Duplicate qualifier specified in QualifierOrder";
1708 return "Missing type in QualifierOrder";
1710 return "Missing QualifierOrder";
1712 llvm_unreachable(
"unexpected parse error");
1953 LLVMStyle.
IfMacros.push_back(
"KJ_IF_MAYBE");
1956 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0,
false},
1957 {
"^(<|\"(gtest|gmock|isl|json)/)", 3, 0,
false},
1958 {
".*", 1, 0,
false}};
2046 1, std::numeric_limits<unsigned>::max()};
2120 {
"^<.*\\.h>", 1, 0,
false},
2121 {
"^<.*", 2, 0,
false},
2122 {
".*", 3, 0,
false}};
2162 "PARSE_PARTIAL_TEXT_PROTO",
2166 "ParseTextProtoOrDie",
2168 "ParsePartialTestProto",
2287 "com.google.android.apps.chrome",
2306 return ChromiumStyle;
2333 return MozillaStyle;
2338 Style.AccessModifierOffset = -4;
2339 Style.AlignAfterOpenBracket =
false;
2341 Style.AlignTrailingComments = {};
2347 Style.ColumnLimit = 0;
2349 Style.FixNamespaceComments =
false;
2350 Style.IndentWidth = 4;
2352 Style.ObjCBlockIndentWidth = 4;
2353 Style.ObjCSpaceAfterProperty =
true;
2355 Style.SpaceBeforeCpp11BracedList =
true;
2366 Style.BreakBeforeTernaryOperators =
true;
2367 Style.ColumnLimit = 79;
2369 Style.FixNamespaceComments =
false;
2370 Style.KeepFormFeed =
true;
2377 Style.ColumnLimit = 120;
2379 Style.IndentWidth = 4;
2382 Style.BraceWrapping.AfterClass =
true;
2384 Style.BraceWrapping.AfterEnum =
true;
2385 Style.BraceWrapping.AfterFunction =
true;
2386 Style.BraceWrapping.AfterNamespace =
true;
2387 Style.BraceWrapping.AfterObjCDeclaration =
true;
2388 Style.BraceWrapping.AfterStruct =
true;
2389 Style.BraceWrapping.AfterExternBlock =
true;
2390 Style.BraceWrapping.BeforeCatch =
true;
2391 Style.BraceWrapping.BeforeElse =
true;
2392 Style.BraceWrapping.BeforeWhile =
false;
2393 Style.PenaltyReturnTypeOnItsOwnLine = 1000;
2394 Style.AllowShortEnumsOnASingleLine =
false;
2396 Style.AllowShortCaseLabelsOnASingleLine =
false;
2398 Style.AllowShortLoopsOnASingleLine =
false;
2406 Style.InsertBraces =
true;
2407 Style.InsertNewlineAtEOF =
true;
2408 Style.IntegerLiteralSeparator.Decimal = 3;
2409 Style.IntegerLiteralSeparator.DecimalMinDigitsInsert = 5;
2411 Style.RemoveBracesLLVM =
true;
2412 Style.RemoveEmptyLinesInUnwrappedLines =
true;
2414 Style.RemoveSemicolon =
true;
2428 constexpr StringRef Prefix(
"inheritparentconfig=");
2430 if (Name.equals_insensitive(
"llvm"))
2432 else if (Name.equals_insensitive(
"chromium"))
2434 else if (Name.equals_insensitive(
"mozilla"))
2436 else if (Name.equals_insensitive(
"google"))
2438 else if (Name.equals_insensitive(
"webkit"))
2440 else if (Name.equals_insensitive(
"gnu"))
2442 else if (Name.equals_insensitive(
"microsoft"))
2444 else if (Name.equals_insensitive(
"clang-format"))
2446 else if (Name.equals_insensitive(
"none"))
2448 else if (Name.equals_insensitive(Prefix.drop_back()))
2449 Style->InheritConfig =
"..";
2450 else if (Name.size() > Prefix.size() && Name.starts_with_insensitive(Prefix))
2451 Style->InheritConfig = Name.substr(Prefix.size());
2461 if (Style->QualifierOrder.empty())
2465 for (
const auto &Qualifier : Style->QualifierOrder) {
2466 if (Qualifier ==
"type")
2470 if (token == tok::identifier)
2475 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
2476 Style->QualifierOrder.end());
2477 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
2478 LLVM_DEBUG(llvm::dbgs()
2479 <<
"Duplicate Qualifiers " << Style->QualifierOrder.size()
2480 <<
" vs " << UniqueQualifiers.size() <<
"\n");
2485 if (!llvm::is_contained(Style->QualifierOrder,
"type"))
2493 llvm::SourceMgr::DiagHandlerTy DiagHandler,
2494 void *DiagHandlerCtxt,
bool IsDotHFile) {
2498 if (Config.getBuffer().trim().empty())
2500 Style->StyleSet.Clear();
2501 std::vector<FormatStyle> Styles;
2502 llvm::yaml::Input Input(Config,
nullptr, DiagHandler,
2508 Input.setContext(Style);
2509 Input.setAllowUnknownKeys(AllowUnknownOptions);
2512 return Input.error();
2516 const auto StyleCount = Styles.size();
2519 for (
unsigned I = 1; I < StyleCount; ++I) {
2520 const auto Lang = Styles[I].Language;
2524 for (
unsigned J = 0; J < I; ++J) {
2526 LLVM_DEBUG(llvm::dbgs()
2527 <<
"Duplicate languages in the config file on positions "
2528 << J <<
" and " << I <<
'\n');
2534 int LanguagePos = -1;
2540 for (
unsigned I = 0; I < StyleCount; ++I) {
2541 const auto Lang = Styles[I].Language;
2555 if (LanguagePos < 0) {
2561 LanguagePos = CppPos;
2562 if (LanguagePos < 0)
2566 for (
const auto &S : llvm::reverse(llvm::drop_begin(Styles)))
2567 Style->StyleSet.Add(S);
2569 *Style = Styles[LanguagePos];
2571 if (LanguagePos == 0) {
2574 Style->StyleSet.Add(*Style);
2590 llvm::raw_string_ostream Stream(
Text);
2591 llvm::yaml::Output Output(Stream);
2598 Output << NonConstStyle;
2600 return Stream.str();
2603std::optional<FormatStyle>
2606 return std::nullopt;
2608 if (It == Styles->end())
2609 return std::nullopt;
2611 Style.StyleSet = *
this;
2616 assert(Style.Language !=
LK_None &&
2617 "Cannot add a style for LK_None to a StyleSet");
2619 !Style.StyleSet.Styles &&
2620 "Cannot add a style associated with an existing StyleSet to a StyleSet");
2622 Styles = std::make_shared<MapType>();
2623 (*Styles)[Style.Language] = std::move(Style);
2628std::optional<FormatStyle>
2637 StringRef
Text =
"") {
2640 if (
Next &&
Next->NewlinesBefore == 0 &&
Next->isNot(tok::eof)) {
2641 Start =
Tok.getLocation();
2642 Next->WhitespaceRange =
Token.WhitespaceRange;
2644 Start =
Token.WhitespaceRange.getBegin();
2647 cantFail(
Result.add(tooling::Replacement(SourceMgr, Range,
Text)));
2650class ParensRemover :
public TokenAnalyzer {
2652 ParensRemover(
const Environment &Env,
const FormatStyle &Style)
2653 : TokenAnalyzer(Env, Style) {}
2655 std::pair<tooling::Replacements, unsigned>
2656 analyze(TokenAnnotator &Annotator,
2657 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2658 FormatTokenLexer &Tokens)
override {
2659 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2660 tooling::Replacements
Result;
2661 removeParens(AnnotatedLines,
Result);
2666 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
2667 tooling::Replacements &
Result) {
2668 const auto &SourceMgr = Env.getSourceManager();
2669 for (
auto *Line : Lines) {
2670 if (!
Line->Children.empty())
2672 if (!
Line->Affected)
2674 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2675 Token = Token->
Next) {
2677 replaceToken(*Token, Token->
Next, SourceMgr,
Result,
" ");
2683class BracesInserter :
public TokenAnalyzer {
2685 BracesInserter(
const Environment &Env,
const FormatStyle &Style)
2686 : TokenAnalyzer(Env, Style) {}
2688 std::pair<tooling::Replacements, unsigned>
2689 analyze(TokenAnnotator &Annotator,
2690 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2691 FormatTokenLexer &Tokens)
override {
2692 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2693 tooling::Replacements
Result;
2694 insertBraces(AnnotatedLines,
Result);
2699 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2700 tooling::Replacements &
Result) {
2701 const auto &SourceMgr = Env.getSourceManager();
2702 int OpeningBraceSurplus = 0;
2703 for (AnnotatedLine *Line : Lines) {
2704 if (!
Line->Children.empty())
2706 if (!
Line->Affected && OpeningBraceSurplus == 0)
2709 Token = Token->
Next) {
2716 if (!
Line->Affected)
2718 Brace = Token->
is(tok::comment) ?
"\n{" :
"{";
2719 ++OpeningBraceSurplus;
2721 if (OpeningBraceSurplus == 0)
2730 cantFail(
Result.add(tooling::Replacement(SourceMgr, Start, 0,
Brace)));
2733 assert(OpeningBraceSurplus == 0);
2737class BracesRemover :
public TokenAnalyzer {
2739 BracesRemover(
const Environment &Env,
const FormatStyle &Style)
2740 : TokenAnalyzer(Env, Style) {}
2742 std::pair<tooling::Replacements, unsigned>
2743 analyze(TokenAnnotator &Annotator,
2744 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2745 FormatTokenLexer &Tokens)
override {
2746 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2747 tooling::Replacements
Result;
2748 removeBraces(AnnotatedLines,
Result);
2753 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
2754 tooling::Replacements &
Result) {
2755 const auto &SourceMgr = Env.getSourceManager();
2756 const auto *End = Lines.end();
2757 for (
const auto *I = Lines.begin(); I != End; ++I) {
2758 const auto &
Line = *I;
2759 if (!
Line->Children.empty())
2761 if (!
Line->Affected)
2763 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2764 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2765 Token = Token->
Next) {
2769 assert(
Next || Token ==
Line->Last);
2770 if (!
Next && NextLine)
2771 Next = NextLine->First;
2772 replaceToken(*Token,
Next, SourceMgr,
Result);
2778class SemiRemover :
public TokenAnalyzer {
2780 SemiRemover(
const Environment &Env,
const FormatStyle &Style)
2781 : TokenAnalyzer(Env, Style) {}
2783 std::pair<tooling::Replacements, unsigned>
2784 analyze(TokenAnnotator &Annotator,
2785 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2786 FormatTokenLexer &Tokens)
override {
2787 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2788 tooling::Replacements
Result;
2789 removeSemi(Annotator, AnnotatedLines,
Result);
2794 void removeSemi(TokenAnnotator &Annotator,
2795 SmallVectorImpl<AnnotatedLine *> &Lines,
2796 tooling::Replacements &
Result) {
2798 const auto *Prev =
Tok.Previous;
2799 if (!Prev || Prev->isNot(tok::r_brace))
2801 const auto *LBrace = Prev->MatchingParen;
2802 return LBrace && LBrace->is(TT_FunctionLBrace);
2804 const auto &SourceMgr = Env.getSourceManager();
2805 const auto *End = Lines.end();
2806 for (
const auto *I = Lines.begin(); I != End; ++I) {
2807 const auto &
Line = *I;
2808 if (!
Line->Children.empty())
2809 removeSemi(Annotator,
Line->Children,
Result);
2810 if (!
Line->Affected)
2812 Annotator.calculateFormattingInformation(*Line);
2813 const auto *NextLine = I + 1 == End ?
nullptr : I[1];
2814 for (
const auto *Token =
Line->First; Token && !Token->
Finalized;
2815 Token = Token->
Next) {
2816 if (Token->
isNot(tok::semi) ||
2817 (!Token->
Optional && !PrecededByFunctionRBrace(*Token))) {
2821 assert(
Next || Token ==
Line->Last);
2822 if (!
Next && NextLine)
2823 Next = NextLine->First;
2824 replaceToken(*Token,
Next, SourceMgr,
Result);
2830class EnumTrailingCommaEditor :
public TokenAnalyzer {
2832 EnumTrailingCommaEditor(
const Environment &Env,
const FormatStyle &Style)
2833 : TokenAnalyzer(Env, Style) {}
2835 std::pair<tooling::Replacements, unsigned>
2836 analyze(TokenAnnotator &Annotator,
2837 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2838 FormatTokenLexer &Tokens)
override {
2839 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2840 tooling::Replacements
Result;
2841 editEnumTrailingComma(AnnotatedLines,
Result);
2846 void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
2847 tooling::Replacements &
Result) {
2848 bool InEnumBraces =
false;
2850 const auto &SourceMgr = Env.getSourceManager();
2851 for (
auto *Line : Lines) {
2852 if (!
Line->Children.empty())
2853 editEnumTrailingComma(
Line->Children,
Result);
2855 Token = Token->
Next) {
2856 if (Token->
isNot(TT_EnumRBrace)) {
2857 if (Token->
is(TT_EnumLBrace))
2858 InEnumBraces =
true;
2859 else if (InEnumBraces && Token->
isNot(tok::comment))
2860 BeforeRBrace =
Line->Affected ? Token :
nullptr;
2863 InEnumBraces =
false;
2864 if (!BeforeRBrace || BeforeRBrace->HasEnumTrailingCommaHandled) {
2868 if (BeforeRBrace->is(tok::comma)) {
2870 replaceToken(*BeforeRBrace, BeforeRBrace->Next, SourceMgr,
Result);
2872 cantFail(
Result.add(tooling::Replacement(
2873 SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0,
",")));
2875 BeforeRBrace->HasEnumTrailingCommaHandled =
true;
2876 BeforeRBrace =
nullptr;
2882class JavaScriptRequoter :
public TokenAnalyzer {
2884 JavaScriptRequoter(
const Environment &Env,
const FormatStyle &Style)
2885 : TokenAnalyzer(Env, Style) {}
2887 std::pair<tooling::Replacements, unsigned>
2888 analyze(TokenAnnotator &Annotator,
2889 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2890 FormatTokenLexer &Tokens)
override {
2891 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2892 tooling::Replacements
Result;
2893 requoteJSStringLiteral(AnnotatedLines,
Result);
2900 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
2901 tooling::Replacements &
Result) {
2902 for (AnnotatedLine *Line : Lines) {
2903 requoteJSStringLiteral(
Line->Children,
Result);
2904 if (!
Line->Affected)
2907 FormatTok = FormatTok->Next) {
2908 StringRef Input = FormatTok->TokenText;
2909 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
2913 !Input.starts_with(
"\"")) ||
2915 !Input.starts_with(
"\'"))) {
2921 SourceLocation Start = FormatTok->Tok.getLocation();
2922 auto Replace = [&](SourceLocation Start,
unsigned Length,
2923 StringRef ReplacementText) {
2924 auto Err =
Result.add(tooling::Replacement(
2925 Env.getSourceManager(), Start, Length, ReplacementText));
2929 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
2933 Replace(Start, 1, IsSingle ?
"'" :
"\"");
2934 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
2935 IsSingle ?
"'" :
"\"");
2938 bool Escaped =
false;
2939 for (
size_t i = 1; i < Input.size() - 1; i++) {
2942 if (!Escaped && i + 1 < Input.size() &&
2943 ((IsSingle && Input[i + 1] ==
'"') ||
2944 (!IsSingle && Input[i + 1] ==
'\''))) {
2947 Replace(Start.getLocWithOffset(i), 1,
"");
2954 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
2956 Replace(Start.getLocWithOffset(i), 0,
"\\");
2970class Formatter :
public TokenAnalyzer {
2972 Formatter(
const Environment &Env,
const FormatStyle &Style,
2973 FormattingAttemptStatus *Status)
2974 : TokenAnalyzer(Env, Style), Status(Status) {}
2976 std::pair<tooling::Replacements, unsigned>
2977 analyze(TokenAnnotator &Annotator,
2978 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2979 FormatTokenLexer &Tokens)
override {
2980 tooling::Replacements
Result;
2981 deriveLocalStyle(AnnotatedLines);
2982 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2983 for (AnnotatedLine *Line : AnnotatedLines)
2984 Annotator.calculateFormattingInformation(*Line);
2985 Annotator.setCommentLineLevels(AnnotatedLines);
2987 WhitespaceManager Whitespaces(
2988 Env.getSourceManager(), Style,
2990 ? WhitespaceManager::inputUsesCRLF(
2991 Env.getSourceManager().getBufferData(Env.getFileID()),
2994 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
2995 Env.getSourceManager(), Whitespaces, Encoding,
2996 BinPackInconclusiveFunctions);
2998 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
2999 Tokens.getKeywords(), Env.getSourceManager(),
3001 .format(AnnotatedLines,
false,
3004 Env.getFirstStartColumn(),
3005 Env.getNextStartColumn(),
3006 Env.getLastStartColumn());
3007 for (
const auto &R : Whitespaces.generateReplacements())
3009 return std::make_pair(
Result, 0);
3010 return std::make_pair(
Result, Penalty);
3015 hasCpp03IncompatibleFormat(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3016 for (
const AnnotatedLine *Line : Lines) {
3017 if (hasCpp03IncompatibleFormat(
Line->Children))
3020 if (!
Tok->hasWhitespaceBefore()) {
3021 if (
Tok->is(tok::coloncolon) &&
Tok->Previous->is(TT_TemplateOpener))
3023 if (
Tok->is(TT_TemplateCloser) &&
3024 Tok->Previous->is(TT_TemplateCloser)) {
3033 int countVariableAlignments(
const SmallVectorImpl<AnnotatedLine *> &Lines) {
3034 int AlignmentDiff = 0;
3036 for (
const AnnotatedLine *Line : Lines) {
3037 AlignmentDiff += countVariableAlignments(
Line->Children);
3040 if (
Tok->isNot(TT_PointerOrReference))
3043 const auto *Prev =
Tok->Previous;
3044 const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
3045 const bool SpaceBefore =
Tok->hasWhitespaceBefore();
3048 while (
Tok->Next &&
Tok->Next->is(TT_PointerOrReference))
3052 const bool FollowedByName =
Next &&
Next->Tok.getIdentifierInfo();
3053 const bool SpaceAfter =
Next &&
Next->hasWhitespaceBefore();
3055 if ((!PrecededByName && !FollowedByName) ||
3057 (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
3061 if ((PrecededByName && SpaceBefore) ||
3062 (FollowedByName && !SpaceAfter)) {
3065 }
else if ((PrecededByName && !SpaceBefore) ||
3066 (FollowedByName && SpaceAfter)) {
3073 return AlignmentDiff;
3077 deriveLocalStyle(
const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3078 bool HasBinPackedFunction =
false;
3079 bool HasOnePerLineFunction =
false;
3080 for (AnnotatedLine *Line : AnnotatedLines) {
3081 if (!
Line->First->Next)
3085 if (
Tok->is(PPK_BinPacked))
3086 HasBinPackedFunction =
true;
3087 if (
Tok->is(PPK_OnePerLine))
3088 HasOnePerLineFunction =
true;
3093 if (Style.DerivePointerAlignment) {
3094 const auto NetRightCount = countVariableAlignments(AnnotatedLines);
3095 if (NetRightCount > 0)
3097 else if (NetRightCount < 0)
3102 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
3106 BinPackInconclusiveFunctions =
3107 HasBinPackedFunction || !HasOnePerLineFunction;
3110 bool BinPackInconclusiveFunctions;
3111 FormattingAttemptStatus *Status;
3125class TrailingCommaInserter :
public TokenAnalyzer {
3127 TrailingCommaInserter(
const Environment &Env,
const FormatStyle &Style)
3128 : TokenAnalyzer(Env, Style) {}
3130 std::pair<tooling::Replacements, unsigned>
3131 analyze(TokenAnnotator &Annotator,
3132 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3133 FormatTokenLexer &Tokens)
override {
3134 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3135 tooling::Replacements
Result;
3136 insertTrailingCommas(AnnotatedLines,
Result);
3143 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
3144 tooling::Replacements &
Result) {
3145 for (AnnotatedLine *Line : Lines) {
3146 insertTrailingCommas(
Line->Children,
Result);
3147 if (!
Line->Affected)
3150 FormatTok = FormatTok->Next) {
3151 if (FormatTok->NewlinesBefore == 0)
3154 if (!Matching || !FormatTok->getPreviousNonComment())
3156 if (!(FormatTok->is(tok::r_square) &&
3157 Matching->is(TT_ArrayInitializerLSquare)) &&
3158 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {
3161 FormatToken *Prev = FormatTok->getPreviousNonComment();
3162 if (Prev->is(tok::comma) || Prev->is(tok::semi))
3166 SourceLocation Start =
3167 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
3171 unsigned ColumnNumber =
3172 Env.getSourceManager().getSpellingColumnNumber(Start);
3173 if (ColumnNumber > Style.ColumnLimit)
3178 tooling::Replacement(Env.getSourceManager(), Start, 0,
",")));
3186class Cleaner :
public TokenAnalyzer {
3188 Cleaner(
const Environment &Env,
const FormatStyle &Style)
3189 : TokenAnalyzer(Env, Style),
3190 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
3193 std::pair<tooling::Replacements, unsigned>
3194 analyze(TokenAnnotator &Annotator,
3195 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3196 FormatTokenLexer &Tokens)
override {
3204 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
3206 checkEmptyNamespace(AnnotatedLines);
3208 for (
auto *Line : AnnotatedLines)
3211 return {generateFixes(), 0};
3215 void cleanupLine(AnnotatedLine *Line) {
3216 for (
auto *Child :
Line->Children)
3219 if (
Line->Affected) {
3220 cleanupRight(
Line->First, tok::comma, tok::comma);
3221 cleanupRight(
Line->First, TT_CtorInitializerColon, tok::comma);
3222 cleanupRight(
Line->First, tok::l_paren, tok::comma);
3223 cleanupLeft(
Line->First, tok::comma, tok::r_paren);
3224 cleanupLeft(
Line->First, TT_CtorInitializerComma, tok::l_brace);
3225 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::l_brace);
3226 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::equal);
3230 bool containsOnlyComments(
const AnnotatedLine &Line) {
3232 if (
Tok->isNot(tok::comment))
3238 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
3239 std::set<unsigned> DeletedLines;
3240 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
3241 auto &
Line = *AnnotatedLines[i];
3242 if (
Line.startsWithNamespace())
3243 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
3246 for (
auto Line : DeletedLines) {
3259 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3260 unsigned CurrentLine,
unsigned &NewLine,
3261 std::set<unsigned> &DeletedLines) {
3262 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
3263 if (Style.BraceWrapping.AfterNamespace) {
3267 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
3268 NewLine = CurrentLine;
3271 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
3274 while (++CurrentLine < End) {
3275 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
3278 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
3279 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
3283 CurrentLine = NewLine;
3287 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
3292 NewLine = CurrentLine;
3296 NewLine = CurrentLine;
3297 if (CurrentLine >= End)
3301 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
3302 AnnotatedLines[InitLine]->First->Tok.getLocation(),
3303 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {
3307 for (
unsigned i = InitLine; i <= CurrentLine; ++i)
3308 DeletedLines.insert(i);
3317 template <
typename LeftKind,
typename RightKind>
3318 void cleanupPair(
FormatToken *Start, LeftKind LK, RightKind RK,
3321 for (
auto *Res =
Tok.Next; Res; Res = Res->Next) {
3322 if (Res->isNot(tok::comment) &&
3323 DeletedTokens.find(Res) == DeletedTokens.end()) {
3329 for (
auto *Left = Start;
Left;) {
3330 auto *
Right = NextNotDeleted(*Left);
3334 deleteToken(DeleteLeft ? Left : Right);
3346 template <
typename LeftKind,
typename RightKind>
3347 void cleanupLeft(
FormatToken *Start, LeftKind LK, RightKind RK) {
3348 cleanupPair(Start, LK, RK,
true);
3351 template <
typename LeftKind,
typename RightKind>
3352 void cleanupRight(
FormatToken *Start, LeftKind LK, RightKind RK) {
3353 cleanupPair(Start, LK, RK,
false);
3359 DeletedTokens.insert(
Tok);
3362 tooling::Replacements generateFixes() {
3363 tooling::Replacements Fixes;
3364 SmallVector<FormatToken *> Tokens;
3365 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
3366 std::back_inserter(Tokens));
3372 while (Idx < Tokens.size()) {
3373 unsigned St = Idx, End = Idx;
3374 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
3376 auto SR = CharSourceRange::getCharRange(Tokens[St]->
Tok.getLocation(),
3377 Tokens[End]->Tok.getEndLoc());
3379 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR,
""));
3383 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3384 assert(
false &&
"Fixes must not conflict!");
3395 struct FormatTokenLess {
3396 FormatTokenLess(
const SourceManager &SM) : SM(SM) {}
3399 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
3400 RHS->Tok.getLocation());
3402 const SourceManager &SM;
3406 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
3409class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
3411 ObjCHeaderStyleGuesser(
const Environment &Env,
const FormatStyle &Style)
3412 : TokenAnalyzer(Env, Style), IsObjC(
false) {}
3414 std::pair<tooling::Replacements, unsigned>
3415 analyze(TokenAnnotator &Annotator,
3416 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3417 FormatTokenLexer &Tokens)
override {
3419 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
3420 Tokens.getKeywords());
3421 tooling::Replacements
Result;
3425 bool isObjC() {
return IsObjC; }
3429 guessIsObjC(
const SourceManager &SourceManager,
3430 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
3431 const AdditionalKeywords &Keywords) {
3433 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
3448 "FOUNDATION_EXPORT",
3449 "FOUNDATION_EXTERN",
3450 "NSAffineTransform",
3452 "NSAttributedString",
3471 "NSInvocationOperation",
3475 "NSMutableAttributedString",
3476 "NSMutableCharacterSet",
3478 "NSMutableDictionary",
3479 "NSMutableIndexSet",
3480 "NSMutableOrderedSet",
3484 "NSNumberFormatter",
3488 "NSOperationQueuePriority",
3492 "NSQualityOfService",
3495 "NSRegularExpression",
3506 "NS_ASSUME_NONNULL_BEGIN",
3510 assert(llvm::is_sorted(FoundationIdentifiers));
3512 for (
auto *Line : AnnotatedLines) {
3513 if (
Line->First && (
Line->First->TokenText.starts_with(
"#") ||
3514 Line->First->TokenText ==
"__pragma" ||
3515 Line->First->TokenText ==
"_Pragma")) {
3519 FormatTok = FormatTok->Next) {
3520 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
3521 (FormatTok->isNot(tok::objc_not_keyword) ||
3522 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
3524 (FormatTok->Tok.isAnyIdentifier() &&
3525 llvm::binary_search(FoundationIdentifiers,
3526 FormatTok->TokenText)) ||
3527 FormatTok->is(TT_ObjCStringLiteral) ||
3528 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
3529 Keywords.kw_NS_ERROR_ENUM,
3530 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
3531 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
3532 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
3533 TT_ObjCProperty, TT_ObjCSelector)) {
3534 LLVM_DEBUG(llvm::dbgs()
3535 <<
"Detected ObjC at location "
3536 << FormatTok->Tok.getLocation().printToString(
3538 <<
" token: " << FormatTok->TokenText <<
" token type: "
3543 if (guessIsObjC(SourceManager,
Line->Children, Keywords))
3560struct JavaImportDirective {
3561 StringRef Identifier;
3564 SmallVector<StringRef> AssociatedCommentLines;
3573 for (
const auto &Range : Ranges) {
3574 if (Range.getOffset() < End &&
3575 Range.getOffset() + Range.getLength() > Start) {
3590static std::pair<unsigned, unsigned>
3593 unsigned CursorIndex = std::numeric_limits<unsigned>::max();
3594 unsigned OffsetToEOL = 0;
3595 for (
int i = 0, e = Includes.size(); i != e; ++i) {
3596 unsigned Start = Includes[Indices[i]].Offset;
3597 unsigned End = Start + Includes[Indices[i]].Text.size();
3598 if (!(Cursor >= Start && Cursor < End))
3600 CursorIndex = Indices[i];
3601 OffsetToEOL = End - Cursor;
3604 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
3608 return std::make_pair(CursorIndex, OffsetToEOL);
3613 std::string NewCode;
3614 size_t Pos = 0, LastPos = 0;
3617 Pos = Code.find(
"\r\n", LastPos);
3618 if (Pos == LastPos) {
3622 if (Pos == std::string::npos) {
3623 NewCode += Code.substr(LastPos);
3626 NewCode += Code.substr(LastPos, Pos - LastPos) +
"\n";
3628 }
while (Pos != std::string::npos);
3646 const unsigned IncludesBeginOffset = Includes.front().Offset;
3647 const unsigned IncludesEndOffset =
3648 Includes.back().Offset + Includes.back().Text.size();
3649 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
3650 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
3653 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
3655 if (Style.SortIncludes.Enabled) {
3656 stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3657 if (Includes[LHSI].Priority != Includes[RHSI].Priority)
3658 return Includes[LHSI].Priority < Includes[RHSI].Priority;
3660 auto LHSStem = Includes[LHSI].Filename;
3661 auto RHSStem = Includes[RHSI].Filename;
3664 if (Style.SortIncludes.IgnoreExtension) {
3665 LHSStemStorage = Includes[LHSI].Filename;
3666 RHSStemStorage = Includes[RHSI].Filename;
3667 llvm::sys::path::replace_extension(LHSStemStorage,
"");
3668 llvm::sys::path::replace_extension(RHSStemStorage,
"");
3669 LHSStem = LHSStemStorage;
3670 RHSStem = RHSStemStorage;
3673 std::string LHSStemLower, RHSStemLower;
3674 std::string LHSFilenameLower, RHSFilenameLower;
3675 if (Style.SortIncludes.IgnoreCase) {
3676 LHSStemLower = LHSStem.lower();
3677 RHSStemLower = RHSStem.lower();
3678 LHSFilenameLower = Includes[LHSI].Filename.lower();
3679 RHSFilenameLower = Includes[RHSI].Filename.lower();
3682 const auto Compare = Style.SortIncludes.Natural
3683 ? &StringRef::compare_numeric
3684 : &StringRef::compare;
3686 if (Style.SortIncludes.IgnoreCase) {
3687 int Cmp = std::invoke(Compare, StringRef(LHSStemLower), RHSStemLower);
3692 if (
int Cmp = std::invoke(Compare, LHSStem, RHSStem);
Cmp != 0)
3695 if (Style.SortIncludes.IgnoreCase) {
3697 std::invoke(Compare, StringRef(LHSFilenameLower), RHSFilenameLower);
3701 return std::invoke(Compare, Includes[LHSI].Filename,
3702 Includes[RHSI].Filename) < 0;
3708 unsigned CursorIndex;
3710 unsigned CursorToEOLOffset;
3712 std::tie(CursorIndex, CursorToEOLOffset) =
3717 Indices.erase(llvm::unique(Indices,
3718 [&](
unsigned LHSI,
unsigned RHSI) {
3719 return Includes[LHSI].Text.trim() ==
3720 Includes[RHSI].Text.trim();
3724 int CurrentCategory = Includes.front().Category;
3732 if (Indices.size() == Includes.size() && is_sorted(Indices) &&
3737 const auto OldCursor = Cursor ? *Cursor : 0;
3739 for (
unsigned Index : Indices) {
3740 if (!result.empty()) {
3742 if (Style.IncludeStyle.IncludeBlocks ==
3744 CurrentCategory != Includes[Index].Category) {
3748 result += Includes[Index].Text;
3749 if (Cursor && CursorIndex == Index)
3750 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
3751 CurrentCategory = Includes[Index].Category;
3754 if (Cursor && *Cursor >= IncludesEndOffset)
3755 *Cursor += result.size() - IncludesBlockSize;
3760 IncludesBeginOffset, IncludesBlockSize)))) {
3762 *Cursor = OldCursor;
3767 FileName, Includes.front().Offset, IncludesBlockSize, result));
3771 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3781 unsigned Prev = llvm::StringSwitch<size_t>(Code)
3782 .StartsWith(
"\xEF\xBB\xBF", 3)
3784 unsigned SearchFrom = 0;
3796 bool FirstIncludeBlock =
true;
3797 bool MainIncludeFound =
false;
3798 bool FormattingOff =
false;
3801 llvm::Regex RawStringRegex(
3802 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
3804 std::string RawStringTermination =
")\"";
3806 for (
const auto Size = Code.size(); SearchFrom < Size;) {
3807 size_t Pos = SearchFrom;
3808 if (Code[SearchFrom] !=
'\n') {
3811 Pos = Code.find(
'\n', Pos);
3812 }
while (Pos != StringRef::npos && Code[Pos - 1] ==
'\\');
3816 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
3818 StringRef Trimmed =
Line.trim();
3823 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
3824 std::string CharSequence = RawStringMatches[1].str();
3825 RawStringTermination =
")" + CharSequence +
"\"";
3826 FormattingOff =
true;
3829 if (Trimmed.contains(RawStringTermination))
3830 FormattingOff =
false;
3832 bool IsBlockComment =
false;
3835 FormattingOff =
true;
3837 FormattingOff =
false;
3838 }
else if (Trimmed.starts_with(
"/*")) {
3839 IsBlockComment =
true;
3840 Pos = Code.find(
"*/", SearchFrom + 2);
3843 const bool EmptyLineSkipped =
3846 Style.IncludeStyle.IncludeBlocks ==
3849 bool MergeWithNextLine = Trimmed.ends_with(
"\\");
3850 if (!FormattingOff && !MergeWithNextLine) {
3851 if (!IsBlockComment &&
3853 StringRef IncludeName = Matches[2];
3854 if (Trimmed.contains(
"/*") && !Trimmed.contains(
"*/")) {
3859 Pos = Code.find(
"*/", SearchFrom);
3861 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
3865 !MainIncludeFound && FirstIncludeBlock);
3867 IncludeName, !MainIncludeFound && FirstIncludeBlock);
3869 MainIncludeFound =
true;
3870 IncludesInBlock.push_back(
3871 {IncludeName,
Line, Prev, Category, Priority});
3872 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
3875 IncludesInBlock.clear();
3876 if (Trimmed.starts_with(
"#pragma hdrstop"))
3877 FirstIncludeBlock =
true;
3879 FirstIncludeBlock =
false;
3882 if (Pos == StringRef::npos || Pos + 1 == Code.size())
3885 if (!MergeWithNextLine)
3887 SearchFrom = Pos + 1;
3889 if (!IncludesInBlock.empty()) {
3900 StringRef ImportIdentifier) {
3901 unsigned LongestMatchIndex = std::numeric_limits<unsigned>::max();
3902 unsigned LongestMatchLength = 0;
3903 for (
unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
3904 const std::string &GroupPrefix = Style.JavaImportGroups[I];
3905 if (ImportIdentifier.starts_with(GroupPrefix) &&
3906 GroupPrefix.length() > LongestMatchLength) {
3907 LongestMatchIndex = I;
3908 LongestMatchLength = GroupPrefix.length();
3911 return LongestMatchIndex;
3923 unsigned ImportsBeginOffset = Imports.front().Offset;
3924 unsigned ImportsEndOffset =
3925 Imports.back().Offset + Imports.back().Text.size();
3926 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
3927 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
3931 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
3934 for (
const JavaImportDirective &Import : Imports)
3937 bool StaticImportAfterNormalImport =
3939 sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
3941 return std::make_tuple(!Imports[LHSI].IsStatic ^
3942 StaticImportAfterNormalImport,
3944 std::make_tuple(!Imports[RHSI].IsStatic ^
3945 StaticImportAfterNormalImport,
3950 Indices.erase(llvm::unique(Indices,
3951 [&](
unsigned LHSI,
unsigned RHSI) {
3952 return Imports[LHSI].Text == Imports[RHSI].Text;
3956 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
3960 for (
unsigned Index : Indices) {
3961 if (!result.empty()) {
3963 if (CurrentIsStatic != Imports[Index].IsStatic ||
3968 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
3969 result += CommentLine;
3972 result += Imports[Index].Text;
3973 CurrentIsStatic = Imports[Index].IsStatic;
3980 Imports.front().Offset, ImportsBlockSize)))) {
3985 ImportsBlockSize, result));
3989 llvm::errs() <<
toString(std::move(Err)) <<
"\n";
3997 JavaImportRegexPattern(
"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;");
3999constexpr StringRef JavaPackageRegexPattern(
"^package[\t ]");
4008 bool HasImport =
false;
4009 llvm::Regex ImportRegex(JavaImportRegexPattern);
4010 llvm::Regex PackageRegex(JavaPackageRegexPattern);
4015 for (
bool FormattingOff =
false;;) {
4016 auto Pos = Code.find(
'\n', Prev);
4017 auto GetLine = [&] {
4018 return Code.substr(Prev,
4019 (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
4021 StringRef
Line = GetLine();
4023 StringRef Trimmed =
Line.trim();
4024 if (Trimmed.empty() || PackageRegex.match(Trimmed)) {
4027 FormattingOff =
true;
4029 FormattingOff =
false;
4030 }
else if (Trimmed.starts_with(
"//")) {
4033 AssociatedCommentLines.push_back(
Line);
4034 }
else if (Trimmed.starts_with(
"/*")) {
4035 Pos = Code.find(
"*/", Pos + 2);
4036 if (Pos != StringRef::npos)
4037 Pos = Code.find(
'\n', Pos + 2);
4042 AssociatedCommentLines.push_back(
Line);
4044 }
else if (ImportRegex.match(Trimmed, &Matches)) {
4045 if (FormattingOff) {
4050 StringRef
Static = Matches[1];
4051 StringRef Identifier = Matches[2];
4052 bool IsStatic =
false;
4053 if (
Static.contains(
"static"))
4055 ImportsInBlock.push_back(
4056 {Identifier,
Line, Prev, AssociatedCommentLines, IsStatic});
4058 AssociatedCommentLines.clear();
4064 if (Pos == StringRef::npos || Pos + 1 == Code.size())
4077 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
4080bool isLikelyXml(StringRef Code) {
return Code.ltrim().starts_with(
"<"); }
4084 StringRef
FileName,
unsigned *Cursor) {
4086 if (!Style.SortIncludes.Enabled || Style.DisableFormat)
4090 if (Style.isJavaScript()) {
4102template <
typename T>
4107 if (Replaces.
empty())
4110 auto NewCode = applyAllReplacements(Code, Replaces);
4112 return NewCode.takeError();
4117 ProcessFunc(Style, *NewCode, ChangedRanges,
FileName);
4119 return Replaces.
merge(FormatReplaces);
4128 std::vector<tooling::Range> Ranges,
4132 auto SortedReplaces =
4134 if (!SortedReplaces)
4135 return SortedReplaces.takeError();
4139 auto Reformat = [](
const FormatStyle &Style, StringRef Code,
4140 std::vector<tooling::Range> Ranges,
4150 return Replace.
getOffset() == std::numeric_limits<unsigned>::max() &&
4156inline bool isHeaderDeletion(
const tooling::Replacement &Replace) {
4157 return Replace.getOffset() == std::numeric_limits<unsigned>::max() &&
4158 Replace.getLength() == 1;
4162tooling::Replacements
4163fixCppIncludeInsertions(StringRef Code,
const tooling::Replacements &Replaces,
4164 const FormatStyle &Style) {
4168 tooling::Replacements HeaderInsertions;
4169 std::set<StringRef> HeadersToDelete;
4170 tooling::Replacements
Result;
4171 for (
const auto &R : Replaces) {
4172 if (isHeaderInsertion(R)) {
4175 consumeError(HeaderInsertions.add(R));
4176 }
else if (isHeaderDeletion(R)) {
4177 HeadersToDelete.insert(
R.getReplacementText());
4178 }
else if (
R.getOffset() == std::numeric_limits<unsigned>::max()) {
4179 llvm::errs() <<
"Insertions other than header #include insertion are "
4181 <<
R.getReplacementText() <<
"\n";
4183 consumeError(
Result.add(R));
4186 if (HeaderInsertions.empty() && HeadersToDelete.empty())
4189 StringRef
FileName = Replaces.begin()->getFilePath();
4192 for (
const auto &Header : HeadersToDelete) {
4193 tooling::Replacements Replaces =
4194 Includes.remove(Header.trim(
"\"<>"), Header.starts_with(
"<"));
4195 for (
const auto &R : Replaces) {
4196 auto Err =
Result.add(R);
4199 llvm::errs() <<
"Failed to add header deletion replacement for "
4200 << Header <<
": " <<
toString(std::move(Err)) <<
"\n";
4205 SmallVector<StringRef, 4> Matches;
4206 for (
const auto &R : HeaderInsertions) {
4210 assert(Matched &&
"Header insertion replacement must have replacement text "
4213 auto IncludeName = Matches[2];
4215 Includes.insert(IncludeName.trim(
"\"<>"), IncludeName.starts_with(
"<"),
4218 auto Err =
Result.add(*Replace);
4220 consumeError(std::move(Err));
4221 unsigned NewOffset =
4222 Result.getShiftedCodePosition(Replace->getOffset());
4223 auto Shifted = tooling::Replacement(
FileName, NewOffset, 0,
4224 Replace->getReplacementText());
4234Expected<tooling::Replacements>
4239 auto Cleanup = [](
const FormatStyle &Style, StringRef Code,
4246 fixCppIncludeInsertions(Code, Replaces, Style);
4251std::pair<tooling::Replacements, unsigned>
4254 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef
FileName,
4287 if (Style.isJson()) {
4288 std::vector<tooling::Range> Ranges(1,
tooling::Range(0, Code.size()));
4290 NextStartColumn, LastStartColumn);
4295 Formatter(*Env, Style, Status).process().first;
4297 if (Code.starts_with(
"x = ")) {
4298 Replaces = Replaces.
merge(
4302 if (applyAllReplacements(Code, Replaces))
4303 return {Replaces, 0};
4308 NextStartColumn, LastStartColumn);
4326 if (Style.isCpp()) {
4333 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4334 return ParensRemover(Env, S).process(
true);
4338 if (Style.InsertBraces) {
4341 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4342 return BracesInserter(Env, S).process(
true);
4346 if (Style.RemoveBracesLLVM) {
4349 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4350 return BracesRemover(Env, S).process(
true);
4354 if (Style.RemoveSemicolon) {
4357 Passes.emplace_back([&, S = std::move(S)](
const Environment &Env) {
4358 return SemiRemover(Env, S).process();
4364 return EnumTrailingCommaEditor(Env, Expanded)
4369 if (Style.FixNamespaceComments) {
4389 !Style.ObjCPropertyAttributeOrder.empty()) {
4395 if (Style.isJavaScript() &&
4398 return JavaScriptRequoter(Env, Expanded).process(
true);
4403 return Formatter(Env, Expanded, Status).process();
4406 if (Style.isJavaScript() &&
4409 return TrailingCommaInserter(Env, Expanded).process();
4413 std::optional<std::string> CurrentCode;
4415 unsigned Penalty = 0;
4416 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
4417 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
4418 auto NewCode = applyAllReplacements(
4419 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
4421 Fixes = Fixes.
merge(PassFixes.first);
4422 Penalty += PassFixes.second;
4424 CurrentCode = std::move(*NewCode);
4428 FirstStartColumn, NextStartColumn, LastStartColumn);
4441 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
4442 if (OriginalCode != Fix.getReplacementText()) {
4443 auto Err = NonNoOpFixes.
add(Fix);
4445 llvm::errs() <<
"Error adding replacements : "
4446 <<
toString(std::move(Err)) <<
"\n";
4450 Fixes = std::move(NonNoOpFixes);
4453 return {Fixes, Penalty};
4477 return Cleaner(*Env, Style).process().first;
4482 StringRef
FileName,
bool *IncompleteFormat) {
4485 if (!Status.FormatComplete)
4486 *IncompleteFormat =
true;
4513 auto LexingStd = Style.Standard;
4520 switch (Style.Language) {
4527 LangOpts.CXXOperatorNames = 1;
4528 LangOpts.CPlusPlus11 = SinceCpp11;
4531 LangOpts.CPlusPlus20 = SinceCpp20;
4536 LangOpts.CPlusPlus = 1;
4539 LangOpts.Char8 = SinceCpp20;
4540 LangOpts.AllowLiteralDigitSeparator = LangOpts.CPlusPlus14 || LangOpts.C23;
4544 LangOpts.Digraphs = SinceCpp11;
4546 LangOpts.LineComment = 1;
4549 LangOpts.MicrosoftExt = 1;
4550 LangOpts.DeclSpecKeyword = 1;
4557 "Set coding style. <string> can be:\n"
4558 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
4559 " Mozilla, WebKit.\n"
4560 "2. 'file' to load style configuration from a\n"
4561 " .clang-format file in one of the parent directories\n"
4562 " of the source file (for stdin, see --assume-filename).\n"
4563 " If no .clang-format file is found, falls back to\n"
4564 " --fallback-style.\n"
4565 " --style=file is the default.\n"
4566 "3. 'file:<format_file_path>' to explicitly specify\n"
4567 " the configuration file.\n"
4568 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"
4569 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
4572 static constexpr std::array<llvm::StringLiteral, 2> TemplateSuffixes{
4576 for (
auto Suffix : TemplateSuffixes)
4584 if (
FileName.ends_with_insensitive(
".js") ||
4585 FileName.ends_with_insensitive(
".mjs") ||
4586 FileName.ends_with_insensitive(
".cjs") ||
4587 FileName.ends_with_insensitive(
".ts")) {
4592 if (
FileName.ends_with_insensitive(
".proto") ||
4593 FileName.ends_with_insensitive(
".protodevel")) {
4599 if (
FileName.ends_with_insensitive(
".txtpb") ||
4600 FileName.ends_with_insensitive(
".textpb") ||
4601 FileName.ends_with_insensitive(
".pb.txt") ||
4602 FileName.ends_with_insensitive(
".textproto") ||
4603 FileName.ends_with_insensitive(
".asciipb")) {
4606 if (
FileName.ends_with_insensitive(
".td"))
4608 if (
FileName.ends_with_insensitive(
".cs"))
4610 if (
FileName.ends_with_insensitive(
".json") ||
4611 FileName.ends_with_insensitive(
".ipynb")) {
4614 if (
FileName.ends_with_insensitive(
".sv") ||
4615 FileName.ends_with_insensitive(
".svh") ||
4616 FileName.ends_with_insensitive(
".v") ||
4617 FileName.ends_with_insensitive(
".vh")) {
4628 LangOpts.CPlusPlus = 1;
4629 LangOpts.LineComment = 1;
4631 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);
4635 auto Text = StringRef(SourceMgr.getCharacterData(
Tok.getLocation()),
4637 if (!
Text.consume_front(
"// clang-format Language:"))
4655 auto Extension = llvm::sys::path::extension(
FileName);
4658 if (!Code.empty() && (Extension.empty() || Extension ==
".h")) {
4667 if (Guesser.isObjC())
4671 return GuessedLanguage;
4679llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
4682 llvm::SourceMgr::DiagHandlerTy DiagHandler,
4684 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4685 FS->getBufferForFile(ConfigFile);
4686 if (
auto EC =
Text.getError())
4689 DiagHandler,
nullptr,
4697 StringRef FallbackStyleName, StringRef Code,
4698 llvm::vfs::FileSystem *FS,
4699 bool AllowUnknownOptions,
4700 llvm::SourceMgr::DiagHandlerTy DiagHandler) {
4708 if (StyleName.starts_with(
"{")) {
4710 StringRef Source =
"<command-line>";
4711 if (std::error_code ec =
4713 AllowUnknownOptions, DiagHandler)) {
4717 if (Style.InheritConfig.empty())
4720 ChildFormatTextToApply.emplace_back(
4721 llvm::MemoryBuffer::getMemBuffer(StyleName, Source,
false));
4725 FS = llvm::vfs::getRealFileSystem().get();
4728 const bool IsDotHFile =
FileName.ends_with(
".h");
4731 if (Style.InheritConfig.empty() &&
4732 StyleName.starts_with_insensitive(
"file:")) {
4733 auto ConfigFile = StyleName.substr(5);
4734 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4736 DiagHandler, IsDotHFile);
4737 if (
auto EC =
Text.getError()) {
4742 LLVM_DEBUG(llvm::dbgs()
4743 <<
"Using configuration file " << ConfigFile <<
"\n");
4745 if (Style.InheritConfig.empty())
4751 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4757 if (Style.InheritConfig.empty() && !StyleName.equals_insensitive(
"file")) {
4760 if (Style.InheritConfig.empty())
4764 using namespace llvm::sys::path;
4768 if (std::error_code EC = FS->makeAbsolute(Path))
4771 auto Normalize = [](String &Path) {
4772 Path = convert_to_slash(Path);
4773 remove_dots(Path,
true, Style::posix);
4779 Style.InheritConfig.clear();
4781 auto dropDiagnosticHandler = [](
const llvm::SMDiagnostic &,
void *) {};
4783 auto applyChildFormatTexts = [&](
FormatStyle *Style) {
4784 for (
const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
4787 DiagHandler ? DiagHandler : dropDiagnosticHandler);
4790 static_cast<void>(EC);
4796 FilesToLookFor.push_back(
".clang-format");
4797 FilesToLookFor.push_back(
"_clang-format");
4799 llvm::StringSet<> Directories;
4800 bool Redirected =
false;
4801 String Dir, UnsuitableConfigFiles;
4802 for (StringRef Directory = Path; !Directory.empty();
4803 Directory = Redirected ? Dir.str() : parent_path(Directory)) {
4804 auto Status = FS->status(Directory);
4806 Status->getType() != llvm::sys::fs::file_type::directory_file) {
4813 for (
const auto &F : FilesToLookFor) {
4814 String ConfigFile(Directory);
4816 append(ConfigFile, F);
4817 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
4819 Status = FS->status(ConfigFile);
4821 Status->getType() != llvm::sys::fs::file_type::regular_file) {
4825 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
4827 DiagHandler, IsDotHFile);
4828 if (
auto EC =
Text.getError()) {
4833 if (!UnsuitableConfigFiles.empty())
4834 UnsuitableConfigFiles.append(
", ");
4835 UnsuitableConfigFiles.append(ConfigFile);
4839 LLVM_DEBUG(llvm::dbgs()
4840 <<
"Using configuration file " << ConfigFile <<
"\n");
4842 if (Style.InheritConfig.empty()) {
4843 if (!ChildFormatTextToApply.empty()) {
4844 LLVM_DEBUG(llvm::dbgs() <<
"Applying child configurations\n");
4845 applyChildFormatTexts(&Style);
4850 if (!Directories.insert(Directory).second) {
4852 "Loop detected when inheriting configuration file in " + Directory);
4855 LLVM_DEBUG(llvm::dbgs() <<
"Inherits parent configuration\n");
4857 if (Style.InheritConfig ==
"..") {
4862 llvm::sys::fs::expand_tilde(Style.InheritConfig, ExpandedDir);
4863 Normalize(ExpandedDir);
4864 if (is_absolute(ExpandedDir, Style::posix)) {
4867 Dir = Directory.str();
4868 append(Dir, Style::posix, ExpandedDir);
4873 Style.InheritConfig.clear();
4875 ChildFormatTextToApply.emplace_back(std::move(*
Text));
4885 if (!UnsuitableConfigFiles.empty()) {
4888 UnsuitableConfigFiles);
4891 if (!ChildFormatTextToApply.empty()) {
4892 LLVM_DEBUG(llvm::dbgs()
4893 <<
"Applying child configurations on fallback style\n");
4894 applyChildFormatTexts(&FallbackStyle);
4897 return FallbackStyle;
4901 if (Comment == (
On ?
"/* clang-format on */" :
"/* clang-format off */"))
4904 static const char ClangFormatOn[] =
"// clang-format on";
4905 static const char ClangFormatOff[] =
"// clang-format off";
4906 const unsigned Size = (
On ?
sizeof ClangFormatOn :
sizeof ClangFormatOff) - 1;
4908 return Comment.starts_with(
On ? ClangFormatOn : ClangFormatOff) &&
4909 (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)