aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format')
-rw-r--r--clang/lib/Format/Format.cpp4
-rw-r--r--clang/lib/Format/FormatToken.h3
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp2
-rw-r--r--clang/lib/Format/UnwrappedLineFormatter.cpp6
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp46
-rw-r--r--clang/lib/Format/UnwrappedLineParser.h2
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp22
-rw-r--r--clang/lib/Format/WhitespaceManager.h2
8 files changed, 68 insertions, 19 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index c8d8ec3..c4eac1c 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -100,6 +100,7 @@ struct MappingTraits<FormatStyle::ShortCaseStatementsAlignmentStyle> {
IO.mapOptional("Enabled", Value.Enabled);
IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);
IO.mapOptional("AcrossComments", Value.AcrossComments);
+ IO.mapOptional("AlignCaseArrows", Value.AlignCaseArrows);
IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);
}
};
@@ -911,6 +912,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowBreakBeforeNoexceptSpecifier);
IO.mapOptional("AllowShortBlocksOnASingleLine",
Style.AllowShortBlocksOnASingleLine);
+ IO.mapOptional("AllowShortCaseExpressionOnASingleLine",
+ Style.AllowShortCaseExpressionOnASingleLine);
IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
Style.AllowShortCaseLabelsOnASingleLine);
IO.mapOptional("AllowShortCompoundRequirementOnASingleLine",
@@ -1423,6 +1426,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never;
LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
+ LLVMStyle.AllowShortCaseExpressionOnASingleLine = true;
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
LLVMStyle.AllowShortEnumsOnASingleLine = true;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 28b6488..95f16fd 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -38,6 +38,7 @@ namespace format {
/* l_brace of a block that is not the body of a (e.g. loop) statement. */ \
TYPE(BlockLBrace) \
TYPE(BracedListLBrace) \
+ TYPE(CaseLabelArrow) \
/* The colon at the end of a case label. */ \
TYPE(CaseLabelColon) \
TYPE(CastRParen) \
@@ -148,6 +149,8 @@ namespace format {
TYPE(StructLBrace) \
TYPE(StructRBrace) \
TYPE(StructuredBindingLSquare) \
+ TYPE(SwitchExpressionLabel) \
+ TYPE(SwitchExpressionLBrace) \
TYPE(TableGenBangOperator) \
TYPE(TableGenCondOperator) \
TYPE(TableGenCondOperatorColon) \
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d366ae2..e935d3e 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5051,6 +5051,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return true; // "x! as string", "x! in y"
}
} else if (Style.Language == FormatStyle::LK_Java) {
+ if (Left.is(TT_CaseLabelArrow) || Right.is(TT_CaseLabelArrow))
+ return true;
if (Left.is(tok::r_square) && Right.is(tok::l_brace))
return true;
// spaces inside square brackets.
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 4ae54e5..4d53361 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -515,6 +515,12 @@ private:
}
}
+ if (TheLine->First->is(TT_SwitchExpressionLabel)) {
+ return Style.AllowShortCaseExpressionOnASingleLine
+ ? tryMergeShortCaseLabels(I, E, Limit)
+ : 0;
+ }
+
if (TheLine->Last->is(tok::l_brace)) {
bool ShouldMerge = false;
// Try to merge records.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index f71661d..71557b1 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -430,9 +430,9 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
unsigned StoredPosition = Tokens->getPosition();
auto *Next = Tokens->getNextNonComment();
FormatTok = Tokens->setPosition(StoredPosition);
- if (Next->isNot(tok::colon)) {
- // default not followed by ':' is not a case label; treat it like
- // an identifier.
+ if (!Next->isOneOf(tok::colon, tok::arrow)) {
+ // default not followed by `:` or `->` is not a case label; treat it
+ // like an identifier.
parseStructuralElement();
break;
}
@@ -451,6 +451,7 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
}
if (!SwitchLabelEncountered &&
(Style.IndentCaseLabels ||
+ (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
(Line->InPPDirective && Line->Level == 1))) {
++Line->Level;
}
@@ -1519,9 +1520,9 @@ void UnwrappedLineParser::parseStructuralElement(
// 'switch: string' field declaration.
break;
}
- parseSwitch();
+ parseSwitch(/*IsExpr=*/false);
return;
- case tok::kw_default:
+ case tok::kw_default: {
// In Verilog default along with other labels are handled in the next loop.
if (Style.isVerilog())
break;
@@ -1529,14 +1530,22 @@ void UnwrappedLineParser::parseStructuralElement(
// 'default: string' field declaration.
break;
}
+ auto *Default = FormatTok;
nextToken();
if (FormatTok->is(tok::colon)) {
FormatTok->setFinalizedType(TT_CaseLabelColon);
parseLabel();
return;
}
+ if (FormatTok->is(tok::arrow)) {
+ FormatTok->setFinalizedType(TT_CaseLabelArrow);
+ Default->setFinalizedType(TT_SwitchExpressionLabel);
+ parseLabel();
+ return;
+ }
// e.g. "default void f() {}" in a Java interface.
break;
+ }
case tok::kw_case:
// Proto: there are no switch/case statements.
if (Style.Language == FormatStyle::LK_Proto) {
@@ -2062,6 +2071,11 @@ void UnwrappedLineParser::parseStructuralElement(
case tok::kw_new:
parseNew();
break;
+ case tok::kw_switch:
+ if (Style.Language == FormatStyle::LK_Java)
+ parseSwitch(/*IsExpr=*/true);
+ nextToken();
+ break;
case tok::kw_case:
// Proto: there are no switch/case statements.
if (Style.Language == FormatStyle::LK_Proto) {
@@ -2589,6 +2603,9 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
else
nextToken();
break;
+ case tok::kw_switch:
+ parseSwitch(/*IsExpr=*/true);
+ break;
case tok::kw_requires: {
auto RequiresToken = FormatTok;
nextToken();
@@ -3246,6 +3263,7 @@ void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) {
void UnwrappedLineParser::parseCaseLabel() {
assert(FormatTok->is(tok::kw_case) && "'case' expected");
+ auto *Case = FormatTok;
// FIXME: fix handling of complex expressions here.
do {
@@ -3254,11 +3272,16 @@ void UnwrappedLineParser::parseCaseLabel() {
FormatTok->setFinalizedType(TT_CaseLabelColon);
break;
}
+ if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::arrow)) {
+ FormatTok->setFinalizedType(TT_CaseLabelArrow);
+ Case->setFinalizedType(TT_SwitchExpressionLabel);
+ break;
+ }
} while (!eof());
parseLabel();
}
-void UnwrappedLineParser::parseSwitch() {
+void UnwrappedLineParser::parseSwitch(bool IsExpr) {
assert(FormatTok->is(tok::kw_switch) && "'switch' expected");
nextToken();
if (FormatTok->is(tok::l_paren))
@@ -3268,10 +3291,15 @@ void UnwrappedLineParser::parseSwitch() {
if (FormatTok->is(tok::l_brace)) {
CompoundStatementIndenter Indenter(this, Style, Line->Level);
- FormatTok->setFinalizedType(TT_ControlStatementLBrace);
- parseBlock();
+ FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace
+ : TT_ControlStatementLBrace);
+ if (IsExpr)
+ parseChildBlock();
+ else
+ parseBlock();
setPreviousRBraceType(TT_ControlStatementRBrace);
- addUnwrappedLine();
+ if (!IsExpr)
+ addUnwrappedLine();
} else {
addUnwrappedLine();
++Line->Level;
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index e2cf28c..2a0fe19 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -157,7 +157,7 @@ private:
void parseDoWhile();
void parseLabel(bool LeftAlignLabel = false);
void parseCaseLabel();
- void parseSwitch();
+ void parseSwitch(bool IsExpr);
void parseNamespace();
bool parseModuleImport();
void parseNew();
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 44fd807..ed06d609 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -107,7 +107,8 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() {
llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
calculateLineBreakInformation();
alignConsecutiveMacros();
- alignConsecutiveShortCaseStatements();
+ alignConsecutiveShortCaseStatements(/*IsExpr=*/true);
+ alignConsecutiveShortCaseStatements(/*IsExpr=*/false);
alignConsecutiveDeclarations();
alignConsecutiveBitFields();
alignConsecutiveAssignments();
@@ -878,22 +879,27 @@ void WhitespaceManager::alignConsecutiveColons(
Changes, /*StartAt=*/0, AlignStyle);
}
-void WhitespaceManager::alignConsecutiveShortCaseStatements() {
+void WhitespaceManager::alignConsecutiveShortCaseStatements(bool IsExpr) {
if (!Style.AlignConsecutiveShortCaseStatements.Enabled ||
- !Style.AllowShortCaseLabelsOnASingleLine) {
+ !(IsExpr ? Style.AllowShortCaseExpressionOnASingleLine
+ : Style.AllowShortCaseLabelsOnASingleLine)) {
return;
}
+ const auto Type = IsExpr ? TT_CaseLabelArrow : TT_CaseLabelColon;
+ const auto &Option = Style.AlignConsecutiveShortCaseStatements;
+ const bool AlignArrowOrColon =
+ IsExpr ? Option.AlignCaseArrows : Option.AlignCaseColons;
+
auto Matches = [&](const Change &C) {
- if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons)
- return C.Tok->is(TT_CaseLabelColon);
+ if (AlignArrowOrColon)
+ return C.Tok->is(Type);
// Ignore 'IsInsideToken' to allow matching trailing comments which
// need to be reflowed as that causes the token to appear in two
// different changes, which will cause incorrect alignment as we'll
// reflow early due to detecting multiple aligning tokens per line.
- return !C.IsInsideToken && C.Tok->Previous &&
- C.Tok->Previous->is(TT_CaseLabelColon);
+ return !C.IsInsideToken && C.Tok->Previous && C.Tok->Previous->is(Type);
};
unsigned MinColumn = 0;
@@ -944,7 +950,7 @@ void WhitespaceManager::alignConsecutiveShortCaseStatements() {
if (Changes[I].Tok->isNot(tok::comment))
LineIsComment = false;
- if (Changes[I].Tok->is(TT_CaseLabelColon)) {
+ if (Changes[I].Tok->is(Type)) {
LineIsEmptyCase =
!Changes[I].Tok->Next || Changes[I].Tok->Next->isTrailingComment();
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index 98cf4a2..7b91d8b 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -233,7 +233,7 @@ private:
void alignChainedConditionals();
/// Align consecutive short case statements over all \c Changes.
- void alignConsecutiveShortCaseStatements();
+ void alignConsecutiveShortCaseStatements(bool IsExpr);
/// Align consecutive TableGen DAGArg colon over all \c Changes.
void alignConsecutiveTableGenBreakingDAGArgColons();