From: Daniel Jasper Date: Mon, 18 May 2015 12:52:00 +0000 (+0000) Subject: clang-format: Allow braced initializers in template arguments of class X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b0cbc5dca10957ad0401e75a4e8e2465bc707a37;p=clang clang-format: Allow braced initializers in template arguments of class specializations. Before: template struct S < std::is_arithmetic { } > {}; After: template struct S{}> {}; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237565 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index b596553bc0..d0a8cfbe69 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -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(); diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 06c80e1387..a75845f5d8 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -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 diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 5e69e05d4a..f41928fe72 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -5257,6 +5257,7 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) { verifyFormat("struct A::type>;"); verifyFormat("struct A::type>;"); + verifyFormat("template struct S{}> {};"); // Not template parameters. verifyFormat("return a < b && c > d;");