diff options
Diffstat (limited to 'clang/lib/Parse/ParseTentative.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index e2e16ca63d1e..4d69fb4693fb 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1031,6 +1031,10 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, // direct-declarator '[' constant-expression[opt] ']' // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' TPR = TryParseBracketDeclarator(); + } else if (Tok.is(tok::kw_requires)) { + // declarator requires-clause + // A requires clause indicates a function declaration. + TPR = TPResult::True; } else { break; } @@ -2014,7 +2018,6 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration, /// 'throw' '(' type-id-list[opt] ')' /// Parser::TPResult Parser::TryParseFunctionDeclarator() { - // The '(' is already parsed. TPResult TPR = TryParseParameterDeclarationClause(); @@ -2066,9 +2069,21 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() { /// Parser::TPResult Parser::TryParseBracketDeclarator() { ConsumeBracket(); - if (!SkipUntil(tok::r_square, StopAtSemi)) + + // A constant-expression cannot begin with a '{', but the + // expr-or-braced-init-list of a postfix-expression can. + if (Tok.is(tok::l_brace)) + return TPResult::False; + + if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch)) return TPResult::Error; + // If we hit a comma before the ']', this is not a constant-expression, + // but might still be the expr-or-braced-init-list of a postfix-expression. + if (Tok.isNot(tok::r_square)) + return TPResult::False; + + ConsumeBracket(); return TPResult::Ambiguous; } |