diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-10 01:32:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-10 01:32:12 +0000 |
commit | 7bdcc4a9da8ccbafb15872083f551366cdaf3b51 (patch) | |
tree | bb52354737aeaa0e413fe20cb96e321ba9e47aac /clang/lib/Parse/ParseExprCXX.cpp | |
parent | 076b3041c0706a957766f7e5e885f05b2eaf255e (diff) | |
download | llvm-7bdcc4a9da8ccbafb15872083f551366cdaf3b51.zip llvm-7bdcc4a9da8ccbafb15872083f551366cdaf3b51.tar.gz llvm-7bdcc4a9da8ccbafb15872083f551366cdaf3b51.tar.bz2 |
Disambiguation of '[[':
* In C++11, '[[' is ill-formed unless it starts an attribute-specifier. Reject
array sizes and array indexes which begin with a lambda-expression. Recover by
parsing the lambda as a lambda.
* In Objective-C++11, either '[' could be the start of a message-send.
Fully disambiguate this case: it turns out that the grammars of message-sends,
lambdas and attributes do not actually overlap. Accept any occurrence of '[['
where either '[' starts a message send, but reject a lambda in an array index
just like in C++11 mode.
Implement a couple of changes to the attribute wording which occurred after our
attributes implementation landed:
* In a function-declaration, the attributes go after the exception specification,
not after the right paren.
* A reference type can have attributes applied.
* An 'identifier' in an attribute can also be a keyword. Support for alternative
tokens (iso646 keywords) in attributes to follow.
And some bug fixes:
* Parse attributes after declarator-ids, even if they are not simple identifiers.
* Do not accept attributes after a parenthesized declarator.
* Accept attributes after an array size in a new-type-id.
* Partially disamiguate 'delete' followed by a lambda. More work is required
here for the case where the lambda-introducer is '[]'.
llvm-svn: 154369
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 0b7b2d9..2af7482 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1817,7 +1817,9 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, bool isNew = Tok.getKind() == tok::kw_new; // Consume the 'new' or 'delete'. SymbolLocations[SymbolIdx++] = ConsumeToken(); - if (Tok.is(tok::l_square)) { + // Check for array new/delete. + if (Tok.is(tok::l_square) && + (!getLangOpts().CPlusPlus0x || NextToken().isNot(tok::l_square))) { // Consume the '[' and ']'. BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); @@ -2346,6 +2348,10 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { // Parse the array dimensions. bool first = true; while (Tok.is(tok::l_square)) { + // An array-size expression can't start with a lambda. + if (CheckProhibitedCXX11Attribute()) + continue; + BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); @@ -2360,13 +2366,16 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { T.consumeClose(); - ParsedAttributes attrs(AttrFactory); + // Attributes here appertain to the array type. C++11 [expr.new]p5. + ParsedAttributes Attrs(AttrFactory); + MaybeParseCXX0XAttributes(Attrs); + D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, Size.release(), T.getOpenLocation(), T.getCloseLocation()), - attrs, T.getCloseLocation()); + Attrs, T.getCloseLocation()); if (T.getCloseLocation().isInvalid()) return; @@ -2418,7 +2427,11 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { // Array delete? bool ArrayDelete = false; - if (Tok.is(tok::l_square)) { + if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) { + // FIXME: This could be the start of a lambda-expression. We should + // disambiguate this, but that will require arbitrary lookahead if + // the next token is '(': + // delete [](int*){ /* ... */ ArrayDelete = true; BalancedDelimiterTracker T(*this, tok::l_square); |