[cfe-commits] r172530 - in /cfe/trunk: lib/Format/UnwrappedLineParser.cpp lib/Format/UnwrappedLineParser.h unittests/Format/FormatTest.cpp

Manuel Klimek klimek at google.com
Tue Jan 15 05:38:33 PST 2013


Author: klimek
Date: Tue Jan 15 07:38:33 2013
New Revision: 172530

URL: http://llvm.org/viewvc/llvm-project?rev=172530&view=rev
Log:
Fixes various bugs around the keywords class, struct and union.

This switches to parsing record definitions only if we can clearly
identify them. We're specifically allowing common patterns for
visibility control through macros and attributes, but we cannot
currently fix all instances. This fixes all known bugs we have though.

Before:
static class A f() {
  return g();
} int x;

After:
static class A f() {
  return g();
}
int x;

Modified:
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.h
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=172530&r1=172529&r2=172530&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Jan 15 07:38:33 2013
@@ -320,8 +320,10 @@
     case tok::kw_struct: // fallthrough
     case tok::kw_union:  // fallthrough
     case tok::kw_class:
-      parseStructClassOrBracedList();
-      return;
+      parseRecord();
+      // A record declaration or definition is always the start of a structural
+      // element.
+      break;
     case tok::semi:
       nextToken();
       addUnwrappedLine();
@@ -569,30 +571,29 @@
   } while (!eof());
 }
 
-void UnwrappedLineParser::parseStructClassOrBracedList() {
+void UnwrappedLineParser::parseRecord() {
   nextToken();
-  do {
-    switch (FormatTok.Tok.getKind()) {
-    case tok::l_brace:
-      // FIXME: Think about how to resolve the error handling here.
-      parseBlock();
-      parseStructuralElement();
-      return;
-    case tok::semi:
-      nextToken();
-      addUnwrappedLine();
-      return;
-    case tok::equal:
+  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 'class' and the class name.
+    if (FormatTok.Tok.is(tok::l_paren)) {
+      parseParens();
+    }
+    if (FormatTok.Tok.is(tok::identifier))
       nextToken();
-      if (FormatTok.Tok.is(tok::l_brace)) {
-        parseBracedList();
+
+    if (FormatTok.Tok.is(tok::colon)) {
+      while (FormatTok.Tok.isNot(tok::l_brace)) {
+        if (FormatTok.Tok.is(tok::semi))
+          return;
+        nextToken();
       }
-      break;
-    default:
-      nextToken();
-      break;
     }
-  } while (!eof());
+  }
+  if (FormatTok.Tok.is(tok::l_brace))
+    parseBlock();
 }
 
 void UnwrappedLineParser::parseObjCProtocolList() {

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=172530&r1=172529&r2=172530&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Tue Jan 15 07:38:33 2013
@@ -146,7 +146,7 @@
   void parseNamespace();
   void parseAccessSpecifier();
   void parseEnum();
-  void parseStructClassOrBracedList();
+  void parseRecord();
   void parseObjCProtocolList();
   void parseObjCUntilAtEnd();
   void parseObjCInterfaceOrImplementation();

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=172530&r1=172529&r2=172530&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Jan 15 07:38:33 2013
@@ -1290,8 +1290,37 @@
                "}");
 }
 
-TEST_F(FormatTest, BracedInitListWithElaboratedTypeSpecifier) {
+TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
+  // Elaborate type variable declarations.
   verifyFormat("struct foo a = { bar };\nint n;");
+  verifyFormat("class foo a = { bar };\nint n;");
+  verifyFormat("union foo a = { bar };\nint n;");
+
+  // Elaborate types inside function definitions.
+  verifyFormat("struct foo f() {}\nint n;");
+  verifyFormat("class foo f() {}\nint n;");
+  verifyFormat("union foo f() {}\nint n;");
+
+  // Templates.
+  verifyFormat("template <class X> void f() {}\nint n;");
+  verifyFormat("template <struct X> void f() {}\nint n;");
+  verifyFormat("template <union X> void f() {}\nint n;");
+
+  // Actual definitions...
+  verifyFormat("struct {} n;");
+  verifyFormat("template <template <class T, class Y>, class Z > class X {} n;");
+  verifyFormat("union Z {\n  int n;\n} x;");
+  verifyFormat("class MACRO Z {} n;");
+  verifyFormat("class MACRO(X) Z {} n;");
+  verifyFormat("class __attribute__(X) Z {} n;");
+  verifyFormat("class __declspec(X) Z {} n;");
+
+  // Elaborate types where incorrectly parsing the structural element would
+  // break the indent.
+  verifyFormat("if (true)\n"
+               "  class X x;\n"
+               "else\n"
+               "  f();\n");
 }
 
 // FIXME: This breaks the order of the unwrapped lines:





More information about the cfe-commits mailing list