]> granicus.if.org Git - clang/commitdiff
clang-format: Allow braced initializers in template arguments of class
authorDaniel Jasper <djasper@google.com>
Mon, 18 May 2015 12:52:00 +0000 (12:52 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 18 May 2015 12:52:00 +0000 (12:52 +0000)
specializations.

Before:
  template <class T>
      struct S < std::is_arithmetic<T> {
  } > {};

After:
  template <class T> struct S<std::is_arithmetic<T>{}> {};

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237565 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/UnwrappedLineParser.cpp
lib/Format/UnwrappedLineParser.h
unittests/Format/FormatTest.cpp

index b596553bc0192925cde49dda63cd077d6bbbc991..d0a8cfbe69f7e5946b64e4a9f435e64ec200c4c6 100644 (file)
@@ -302,7 +302,7 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
   } while (!eof());
 }
 
-void UnwrappedLineParser::calculateBraceTypes() {
+void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
   // We'll parse forward through the tokens until we hit
   // a closing brace or eof - note that getNextToken() will
   // parse macros, so this will magically work inside macro
@@ -348,9 +348,10 @@ void UnwrappedLineParser::calculateBraceTypes() {
             //
             // We exclude + and - as they can be ObjC visibility modifiers.
             ProbablyBracedList =
-                NextTok->isOneOf(tok::comma, tok::semi, tok::period, tok::colon,
+                NextTok->isOneOf(tok::comma, tok::period, tok::colon,
                                  tok::r_paren, tok::r_square, tok::l_brace,
                                  tok::l_paren, tok::ellipsis) ||
+                (NextTok->is(tok::semi) && !ExpectClassBody) ||
                 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
           }
           if (ProbablyBracedList) {
@@ -1015,9 +1016,9 @@ void UnwrappedLineParser::tryToParseJSFunction() {
   parseChildBlock();
 }
 
-bool UnwrappedLineParser::tryToParseBracedList() {
+bool UnwrappedLineParser::tryToParseBracedList(bool ExpectClassBody) {
   if (FormatTok->BlockKind == BK_Unknown)
-    calculateBraceTypes();
+    calculateBraceTypes(ExpectClassBody);
   assert(FormatTok->BlockKind != BK_Unknown);
   if (FormatTok->BlockKind == BK_Block)
     return false;
@@ -1104,9 +1105,8 @@ void UnwrappedLineParser::parseParens() {
       tryToParseLambda();
       break;
     case tok::l_brace:
-      if (!tryToParseBracedList()) {
+      if (!tryToParseBracedList())
         parseChildBlock();
-      }
       break;
     case tok::at:
       nextToken();
@@ -1146,9 +1146,8 @@ void UnwrappedLineParser::parseSquare() {
       parseSquare();
       break;
     case tok::l_brace: {
-      if (!tryToParseBracedList()) {
+      if (!tryToParseBracedList())
         parseChildBlock();
-      }
       break;
     }
     case tok::at:
@@ -1571,8 +1570,11 @@ void UnwrappedLineParser::parseRecord() {
   // and thus rule out the record production in case there is no template
   // (this would still leave us with an ambiguity between template function
   // and class declarations).
-  if (FormatTok->Tok.is(tok::colon) || FormatTok->Tok.is(tok::less)) {
-    while (!eof() && FormatTok->Tok.isNot(tok::l_brace)) {
+  if (FormatTok->isOneOf(tok::colon, tok::less)) {
+    while (!eof()) {
+      if (FormatTok->is(tok::l_brace) &&
+          !tryToParseBracedList(/*ExpectClassBody=*/true))
+        break;
       if (FormatTok->Tok.is(tok::semi))
         return;
       nextToken();
index 06c80e1387d7c8cdfecc391022bc15a901c6c4d2..a75845f5d837996c12c317e871ee9f0cb44eda2c 100644 (file)
@@ -82,7 +82,7 @@ private:
   void parsePPEndIf();
   void parsePPUnknown();
   void parseStructuralElement();
-  bool tryToParseBracedList();
+  bool tryToParseBracedList(bool ExpectClassBody = false);
   bool parseBracedList(bool ContinueOnSemicolons = false);
   void parseParens();
   void parseSquare();
@@ -113,7 +113,7 @@ private:
   void readToken();
   void flushComments(bool NewlineBeforeNext);
   void pushToken(FormatToken *Tok);
-  void calculateBraceTypes();
+  void calculateBraceTypes(bool ExpectClassBody);
 
   // Marks a conditional compilation edge (for example, an '#if', '#ifdef',
   // '#else' or merge conflict marker). If 'Unreachable' is true, assumes
index 5e69e05d4a455fe1a2c4df73cb384377854dd831..f41928fe725273beb588fffb6efe39fe9ca36737 100644 (file)
@@ -5257,6 +5257,7 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) {
   verifyFormat("struct A<std::enable_if<sizeof(T2) < sizeof(int32)>::type>;");
   verifyFormat("struct A<std::enable_if<sizeof(T2) ? sizeof(int32) : "
                "sizeof(char)>::type>;");
+  verifyFormat("template <class T> struct S<std::is_arithmetic<T>{}> {};");
 
   // Not template parameters.
   verifyFormat("return a < b && c > d;");