koalo created this revision.
koalo added reviewers: djasper, rsmith.
Herald added a subscriber: cfe-commits.

Before, clang-format has tried to put enums on a single line whenever possible 
(unless in styles where the opening brace was put on a seperate line anyway).
AllowShortEnumsOnASingleLine that defaults to true (matching the conventional 
behaviour) can be set to false to force enums on multiple lines.

This feature is requested from time to time, e.g. here 
<https://stackoverflow.com/questions/23072223/clang-format-style-options-for-enums>,
 and should be unobtrusive for users that do not set this option to false.


Repository:
  rC Clang

https://reviews.llvm.org/D54628

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -1521,6 +1521,24 @@
   verifyFormat("enum ShortEnum { A, B, C };");
   verifyGoogleFormat("enum ShortEnum { A, B, C };");
 
+  FormatStyle Style = getLLVMStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("enum Enum {\n"
+               "};",Style);
+  verifyFormat("enum {\n"
+               "};",Style);
+  verifyFormat("enum X E {\n"
+               "} d;",Style);
+  verifyFormat("enum __attribute__((...)) E {\n"
+               "} d;",Style);
+  verifyFormat("enum __declspec__((...)) E {\n"
+               "} d;",Style);
+  verifyFormat("enum ShortEnum {\n"
+               "  A,\n"
+               "  B,\n"
+               "  C\n"
+               "};",Style);
+
   EXPECT_EQ("enum KeepEmptyLines {\n"
             "  ONE,\n"
             "\n"
@@ -1589,6 +1607,19 @@
   verifyFormat("enum struct __attribute__((...)) E {} d;");
   verifyFormat("enum struct __declspec__((...)) E {} d;");
   verifyFormat("enum struct X f() {\n  a();\n  return 42;\n}");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("enum struct Enum {\n"
+               "};",Style);
+  verifyFormat("enum struct {\n"
+               "};",Style);
+  verifyFormat("enum struct X E {\n"
+               "} d;",Style);
+  verifyFormat("enum struct __attribute__((...)) E {\n"
+               "} d;",Style);
+  verifyFormat("enum struct __declspec__((...)) E {\n"
+               "} d;",Style);
 }
 
 TEST_F(FormatTest, FormatsEnumClass) {
@@ -1606,6 +1637,19 @@
   verifyFormat("enum class __attribute__((...)) E {} d;");
   verifyFormat("enum class __declspec__((...)) E {} d;");
   verifyFormat("enum class X f() {\n  a();\n  return 42;\n}");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("enum class Enum {\n"
+               "};",Style);
+  verifyFormat("enum class {\n"
+               "};",Style);
+  verifyFormat("enum class X E {\n"
+               "} d;",Style);
+  verifyFormat("enum class __attribute__((...)) E {\n"
+               "} d;",Style);
+  verifyFormat("enum class __declspec__((...)) E {\n"
+               "} d;",Style);
 }
 
 TEST_F(FormatTest, FormatsEnumTypes) {
@@ -1615,6 +1659,17 @@
                "};");
   verifyFormat("enum X : int { A, B };");
   verifyFormat("enum X : std::uint32_t { A, B };");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("enum X : int {\n"
+               "  A,\n"
+	       "  B\n"
+	       "};",Style);
+  verifyFormat("enum X : std::uint32_t {\n"
+               "  A,\n"
+	       "  B\n"
+	       "};",Style);
 }
 
 TEST_F(FormatTest, FormatsTypedefEnum) {
@@ -1641,6 +1696,16 @@
                "  THREE = 3\n"
                "} LongEnum;",
                Style);
+
+  Style = getLLVMStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("typedef enum {\n"
+               "} EmptyEnum;",Style);
+  verifyFormat("typedef enum {\n"
+               "  A,\n"
+	       "  B,\n"
+	       "  C\n"
+	       "} ShortEnum;",Style);
 }
 
 TEST_F(FormatTest, FormatsNSEnums) {
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2948,6 +2948,10 @@
   }
   if (Right.is(TT_InlineASMBrace))
     return Right.HasUnescapedNewline;
+  if (isAllmanBrace(Left) && !Style.AllowShortEnumsOnASingleLine &&
+      (Line.startsWith(tok::kw_enum) ||
+       Line.startsWith(tok::kw_typedef, tok::kw_enum)))
+    return true;
   if (isAllmanBrace(Left) || isAllmanBrace(Right))
     return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
            (Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -333,6 +333,8 @@
                    Style.AllowShortIfStatementsOnASingleLine);
     IO.mapOptional("AllowShortLoopsOnASingleLine",
                    Style.AllowShortLoopsOnASingleLine);
+    IO.mapOptional("AllowShortEnumsOnASingleLine",
+                   Style.AllowShortEnumsOnASingleLine);
     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
                    Style.AlwaysBreakAfterDefinitionReturnType);
     IO.mapOptional("AlwaysBreakAfterReturnType",
@@ -635,6 +637,7 @@
   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
+  LLVMStyle.AllowShortEnumsOnASingleLine = true;
   LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -249,6 +249,9 @@
   /// line.
   bool AllowShortLoopsOnASingleLine;
 
+  /// If ``true``, ``enum {A, B, C};`` can be put on a single line.
+  bool AllowShortEnumsOnASingleLine;
+
   /// Different ways to break after the function definition return type.
   /// This option is **deprecated** and is retained for backwards compatibility.
   enum DefinitionReturnTypeBreakingStyle {
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -374,6 +374,11 @@
   If ``true``, ``while (true) continue;`` can be put on a single
   line.
 
+**AllowShortEnumsOnASingleLine** (``bool``)
+  Allows contracting enums to a single line.
+
+  E.g., this allows ``enum {A, B, C};`` to be put on a single line.
+
 **AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``)
   The function definition return type breaking style to use.  This
   option is **deprecated** and is retained for backwards compatibility.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to