diff options
| author | Douglas Gregor <dgregor@apple.com> | 2012-02-16 21:53:36 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2012-02-16 21:53:36 +0000 |
| commit | 6746c5d4873f25cafc98a07160d943b5017f807e (patch) | |
| tree | 84f94f47bc821af3e1609d0f105aea364a3a1f22 /clang/lib | |
| parent | 638252fb5ace7b90d24ba073217f654ffd3d6ab0 (diff) | |
| download | bcm5719-llvm-6746c5d4873f25cafc98a07160d943b5017f807e.tar.gz bcm5719-llvm-6746c5d4873f25cafc98a07160d943b5017f807e.zip | |
Improve recovery for lambda expressions that have 'mutable' or a
trailing return type but not a '()'. Recover by inserting the
parentheses. Thanks to Xeo on IRC for the example.
llvm-svn: 150727
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 7185e93a11d..d09dba25856 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -820,7 +820,53 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( DeclLoc, DeclEndLoc, D, TrailingReturnType), Attr, DeclEndLoc); + } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) { + // It's common to forget that one needs '()' before 'mutable' or the + // result type. Deal with this. + Diag(Tok, diag::err_lambda_missing_parens) + << Tok.is(tok::arrow) + << FixItHint::CreateInsertion(Tok.getLocation(), "() "); + SourceLocation DeclLoc = Tok.getLocation(); + SourceLocation DeclEndLoc = DeclLoc; + + // Parse 'mutable', if it's there. + SourceLocation MutableLoc; + if (Tok.is(tok::kw_mutable)) { + MutableLoc = ConsumeToken(); + DeclEndLoc = MutableLoc; + } + + // Parse the return type, if there is one. + ParsedType TrailingReturnType; + if (Tok.is(tok::arrow)) { + SourceRange Range; + TrailingReturnType = ParseTrailingReturnType(Range).get(); + if (Range.getEnd().isValid()) + DeclEndLoc = Range.getEnd(); + } + + ParsedAttributes Attr(AttrFactory); + D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, + /*isVariadic=*/false, + /*EllipsisLoc=*/SourceLocation(), + /*Params=*/0, /*NumParams=*/0, + /*TypeQuals=*/0, + /*RefQualifierIsLValueRef=*/true, + /*RefQualifierLoc=*/SourceLocation(), + /*ConstQualifierLoc=*/SourceLocation(), + /*VolatileQualifierLoc=*/SourceLocation(), + MutableLoc, + EST_None, + /*ESpecLoc=*/SourceLocation(), + /*Exceptions=*/0, + /*ExceptionRanges=*/0, + /*NumExceptions=*/0, + /*NoexceptExpr=*/0, + DeclLoc, DeclEndLoc, D, + TrailingReturnType), + Attr, DeclEndLoc); } + // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using // it. |

