diff options
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 4 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 1 |
3 files changed, 15 insertions, 12 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b596553bc01..d0a8cfbe69f 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/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/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 06c80e1387d..a75845f5d83 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/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/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 5e69e05d4a4..f41928fe725 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -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;"); |