Fixes various problems around enum parsing.

Very similar to what we do for record definitions:
- tighten down what is an enum definition, so that we don't mistake a
  function for an enum
- allow common idioms around declarations (we'll want to handle that
  more centrally in the future)

We now correctly format:
enum X f() {
  a();
  return 42;
}

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173075 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index c054ef6..2d6c5cf 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -329,7 +329,7 @@
     switch (FormatTok.Tok.getKind()) {
     case tok::kw_enum:
       parseEnum();
-      return;
+      break;
     case tok::kw_struct:
     case tok::kw_union:
     case tok::kw_class:
@@ -580,39 +580,50 @@
 }
 
 void UnwrappedLineParser::parseEnum() {
-  bool HasContents = false;
-  do {
-    switch (FormatTok.Tok.getKind()) {
-    case tok::l_brace:
-      nextToken();
-      addUnwrappedLine();
-      ++Line->Level;
-      parseComments();
-      break;
-    case tok::l_paren:
+  nextToken();
+  if (FormatTok.Tok.is(tok::identifier) ||
+      FormatTok.Tok.is(tok::kw___attribute) ||
+      FormatTok.Tok.is(tok::kw___declspec)) {
+    nextToken();
+    // We can have macros or attributes in between 'enum' and the enum name.
+    if (FormatTok.Tok.is(tok::l_paren)) {
       parseParens();
-      break;
-    case tok::comma:
-      nextToken();
-      addUnwrappedLine();
-      parseComments();
-      break;
-    case tok::r_brace:
-      if (HasContents)
-        addUnwrappedLine();
-      --Line->Level;
-      nextToken();
-      break;
-    case tok::semi:
-      nextToken();
-      addUnwrappedLine();
-      return;
-    default:
-      HasContents = true;
-      nextToken();
-      break;
     }
-  } while (!eof());
+    if (FormatTok.Tok.is(tok::identifier))
+      nextToken();
+  }
+  if (FormatTok.Tok.is(tok::l_brace)) {
+    nextToken();
+    addUnwrappedLine();
+    ++Line->Level;
+    do {
+      switch (FormatTok.Tok.getKind()) {
+      case tok::comment:
+        // FIXME: Handle comments centrally, instead of special casing
+        // them everywhere.
+        parseComments();
+        break;
+      case tok::l_paren:
+        parseParens();
+        break;
+      case tok::r_brace:
+        addUnwrappedLine();
+        nextToken();
+        --Line->Level;
+        return;
+      case tok::comma:
+        nextToken();
+        addUnwrappedLine();
+        break;
+      default:
+        nextToken();
+        break;
+      }
+    } while (!eof());
+  }
+  // We fall through to parsing a structural element afterwards, so that in
+  // enum A {} n, m;
+  // "} n, m;" will end up in one unwrapped line.
 }
 
 void UnwrappedLineParser::parseRecord() {
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index bda3196..c9b255c 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -499,6 +499,10 @@
                "};");
   verifyFormat("enum {\n"
                "};");
+  verifyFormat("enum X E {\n} d;");
+  verifyFormat("enum __attribute__((...)) E {\n} d;");
+  verifyFormat("enum __declspec__((...)) E {\n} d;");
+  verifyFormat("enum X f() {\n  a();\n  return 42;\n}");
 }
 
 TEST_F(FormatTest, FormatsBitfields) {