summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ClangFormatStyleOptions.rst14
-rw-r--r--clang/include/clang/Format/Format.h3
-rw-r--r--clang/lib/Format/Format.cpp32
-rw-r--r--clang/unittests/Format/FormatTest.cpp42
4 files changed, 85 insertions, 6 deletions
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 332fe3becda..c7981cfcdf1 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -148,6 +148,9 @@ the configuration (without a prefix: ``Auto``).
E.g., this allows ``if (a) { return; }`` to be put on a single line.
+**AllowShortCaseLabelsOnASingleLine** (``bool``)
+ If ``true``, short case labels will be contracted to a single line.
+
**AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``)
Dependent on the value, ``int f() { return 0; }`` can be put
on a single line.
@@ -257,7 +260,7 @@ the configuration (without a prefix: ``Auto``).
**DerivePointerAlignment** (``bool``)
If ``true``, analyze the formatted file for the most common
- alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback.
+ alignment of & and *. ``PointerAlignment`` is then used only as fallback.
**DisableFormat** (``bool``)
Disables formatting at all.
@@ -374,6 +377,9 @@ the configuration (without a prefix: ``Auto``).
Align pointer in the middle.
+**SpaceAfterCStyleCast** (``bool``)
+ If ``true``, a space may be inserted after C style casts.
+
**SpaceBeforeAssignmentOperators** (``bool``)
If ``false``, spaces will be removed before assignment operators.
@@ -411,9 +417,6 @@ the configuration (without a prefix: ``Auto``).
**SpacesInCStyleCastParentheses** (``bool``)
If ``true``, spaces may be inserted into C style casts.
-**SpaceAfterCStyleCast** (``bool``)
- If ``true``, a space may be inserted after C style casts.
-
**SpacesInContainerLiterals** (``bool``)
If ``true``, spaces are inserted inside container literals (e.g.
ObjC and Javascript array and dict literals).
@@ -422,8 +425,7 @@ the configuration (without a prefix: ``Auto``).
If ``true``, spaces will be inserted after '(' and before ')'.
**SpacesInSquareBrackets** (``bool``)
- If ``true``, spaces will be inserted after '[' and before ']' in array
- declarations and element access expressions, but not in lambdas.
+ If ``true``, spaces will be inserted after '[' and before ']'.
**Standard** (``LanguageStandard``)
Format compatible with this standard, e.g. use
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index a6d17542e4c..abf505922ee 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -195,6 +195,9 @@ struct FormatStyle {
/// single line.
bool AllowShortLoopsOnASingleLine;
+ /// \brief If \c true, short case labels will be contracted to a single line.
+ bool AllowShortCaseLabelsOnASingleLine;
+
/// \brief Different styles for merging short functions containing at most one
/// statement.
enum ShortFunctionStyle {
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 7e243b6e0ed..5b2f222bfc5 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -167,6 +167,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowAllParametersOfDeclarationOnNextLine);
IO.mapOptional("AllowShortBlocksOnASingleLine",
Style.AllowShortBlocksOnASingleLine);
+ IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
+ Style.AllowShortCaseLabelsOnASingleLine);
IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
@@ -313,6 +315,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
LLVMStyle.AllowShortBlocksOnASingleLine = false;
+ LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = false;
@@ -642,6 +645,11 @@ public:
? tryMergeSimpleControlStatement(I, E, Limit)
: 0;
}
+ if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
+ return Style.AllowShortCaseLabelsOnASingleLine
+ ? tryMergeShortCaseLabels(I, E, Limit)
+ : 0;
+ }
if (TheLine->InPPDirective &&
(TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
return tryMergeSimplePPDirective(I, E, Limit);
@@ -694,6 +702,30 @@ private:
return 1;
}
+ unsigned tryMergeShortCaseLabels(
+ SmallVectorImpl<AnnotatedLine *>::const_iterator I,
+ SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
+ if (Limit == 0 || I + 1 == E ||
+ I[1]->First->isOneOf(tok::kw_case, tok::kw_default))
+ return 0;
+ unsigned NumStmts = 0;
+ unsigned Length = 0;
+ for (; NumStmts < 3; ++NumStmts) {
+ if (I + 1 + NumStmts == E)
+ break;
+ const AnnotatedLine *Line = I[1 + NumStmts];
+ if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
+ break;
+ if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
+ tok::kw_while))
+ return 0;
+ Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
+ }
+ if (NumStmts == 0 || NumStmts == 3 || Length > Limit)
+ return 0;
+ return NumStmts;
+ }
+
unsigned
tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
SmallVectorImpl<AnnotatedLine *>::const_iterator E,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 6f00acf38f3..8b8aaf1b4a6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -700,6 +700,47 @@ TEST_F(FormatTest, CaseRanges) {
"}");
}
+TEST_F(FormatTest, ShortCaseLabels) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AllowShortCaseLabelsOnASingleLine = true;
+ verifyFormat("switch (a) {\n"
+ "case 1: x = 1; break;\n"
+ "case 2: return;\n"
+ "case 3:\n"
+ "case 4:\n"
+ "case 5: return;\n"
+ "default: y = 1; break;\n"
+ "}",
+ Style);
+ verifyFormat("switch (a) {\n"
+ "case 1: {\n"
+ "}\n"
+ "case 2: {\n"
+ " return;\n"
+ "}\n"
+ "case 3: {\n"
+ " x = 1;\n"
+ " return;\n"
+ "}\n"
+ "case 4:\n"
+ " if (x)\n"
+ " return;\n"
+ "}",
+ Style);
+ Style.ColumnLimit = 21;
+ verifyFormat("switch (a) {\n"
+ "case 1: x = 1; break;\n"
+ "case 2: return;\n"
+ "case 3:\n"
+ "case 4:\n"
+ "case 5: return;\n"
+ "default:\n"
+ " y = 1;\n"
+ " break;\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, FormatsLabels) {
verifyFormat("void f() {\n"
" some_code();\n"
@@ -8316,6 +8357,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
CHECK_PARSE_BOOL(AlwaysBreakAfterDefinitionReturnType);
OpenPOWER on IntegriCloud