diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-30 22:23:08 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-30 22:23:08 +0000 |
commit | bd6c76fd53e3674d5bbfefe471e2ae657ce69d0c (patch) | |
tree | d3ade1225866531dca7104675d56fdb90aef2245 | |
parent | c2b9b367b9fd9ca200de4cacf3c3539bc7fafede (diff) |
Improve parser recovery when we try to parse a call expression but the
called function itself is invalid (e.g., because of a semantic error
referring to that declaration). Fixes <rdar://problem/8044142>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105175 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 9 | ||||
-rw-r--r-- | test/Index/complete-exprs.c | 7 |
2 files changed, 15 insertions, 1 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 7be1a1994e..8fb71c3ff6 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -580,7 +580,8 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, TypeOfCast, CastTy, RParenLoc); - if (Res.isInvalid()) return move(Res); + if (Res.isInvalid()) + return move(Res); } switch (ParenExprType) { @@ -672,6 +673,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, Name.setIdentifier(&II, ILoc); Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, Tok.is(tok::l_paren), false); + // These can be followed by postfix-expr pieces. return ParsePostfixExpressionSuffix(move(Res)); } @@ -981,6 +983,11 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { Loc = ConsumeParen(); + if (LHS.isInvalid()) { + SkipUntil(tok::r_paren); + return ExprError(); + } + if (Tok.is(tok::code_completion)) { Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0); ConsumeCodeCompletionToken(); diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c index 1b55c78be2..fe30d33297 100644 --- a/test/Index/complete-exprs.c +++ b/test/Index/complete-exprs.c @@ -7,6 +7,9 @@ int test(int i, int j, int k, int l) { return i | j | k & l; } +struct X f1 = { 17 }; +void f2() { f1(17); } + // RUN: c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: macro definition:{TypedText __VERSION__} (70) // CHECK-CC1: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (12) @@ -28,3 +31,7 @@ int test(int i, int j, int k, int l) { // CHECK-CC2: NotImplemented:{TypedText float} (40) // CHECK-CC2: ParmDecl:{ResultType int}{TypedText j} (8) // CHECK-CC2: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30) +// RUN: c-index-test -code-completion-at=%s:11:16 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s +// CHECK-CC4: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50) +// CHECK-CC4: VarDecl:{ResultType struct X}{TypedText f1} (50) + |