diff options
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 15 | ||||
-rw-r--r-- | lib/Parse/ParseInit.cpp | 38 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 19 |
3 files changed, 45 insertions, 27 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 965f764dcf..ad422642e4 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -637,11 +637,9 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, IdentifierInfo &II = *Tok.getIdentifierInfo(); SourceLocation ILoc = ConsumeToken(); - // Support 'Class.property' notation. We don't use - // isTokObjCMessageIdentifierReceiver(), since it allows 'super' (which is - // inappropriate here). + // Support 'Class.property' and 'super.property' notation. if (getLang().ObjC1 && Tok.is(tok::period) && - Actions.getTypeName(II, ILoc, CurScope)) { + (Actions.getTypeName(II, ILoc, CurScope) || II.isStr("super"))) { SourceLocation DotLoc = ConsumeToken(); if (Tok.isNot(tok::identifier)) { @@ -1441,6 +1439,15 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // returns the parsed type to the callee. return OwningExprResult(Actions); } + + + // Reject the cast of super idiom in ObjC. + if (Tok.is(tok::identifier) && getLang().ObjC1 && + Tok.getIdentifierInfo()->isStr("super")) { + Diag(Tok.getLocation(), diag::err_illegal_super_cast) + << SourceRange(OpenLoc, RParenLoc); + return ExprError(); + } // Parse the cast-expression that follows it next. // TODO: For cast expression with CastTy. diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index 9154d8d599..57751c9c3f 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -124,23 +124,27 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { // SourceLocation StartLoc = ConsumeBracket(); - // If Objective-C is enabled and this is a typename or other identifier - // receiver, parse this as a message send expression. - if (getLang().ObjC1 && isTokObjCMessageIdentifierReceiver()) { - // If we have exactly one array designator, this used the GNU - // 'designation: array-designator' extension, otherwise there should be no - // designators at all! - if (Desig.getNumDesignators() == 1 && - (Desig.getDesignator(0).isArrayDesignator() || - Desig.getDesignator(0).isArrayRangeDesignator())) - Diag(StartLoc, diag::ext_gnu_missing_equal_designator); - else if (Desig.getNumDesignators() > 0) - Diag(Tok, diag::err_expected_equal_designator); - - IdentifierInfo *Name = Tok.getIdentifierInfo(); - SourceLocation NameLoc = ConsumeToken(); - return ParseAssignmentExprWithObjCMessageExprStart( - StartLoc, NameLoc, Name, ExprArg(Actions)); + // If Objective-C is enabled and this is a typename (class message send) or + // 'super', parse this as a message send expression. + if (getLang().ObjC1 && Tok.is(tok::identifier)) { + IdentifierInfo *II = Tok.getIdentifierInfo(); + + if (II == Ident_super || Actions.getTypeName(*II, Tok.getLocation(), + CurScope)) { + // If we have exactly one array designator, this used the GNU + // 'designation: array-designator' extension, otherwise there should be no + // designators at all! + if (Desig.getNumDesignators() == 1 && + (Desig.getDesignator(0).isArrayDesignator() || + Desig.getDesignator(0).isArrayRangeDesignator())) + Diag(StartLoc, diag::ext_gnu_missing_equal_designator); + else if (Desig.getNumDesignators() > 0) + Diag(Tok, diag::err_expected_equal_designator); + + SourceLocation NameLoc = ConsumeToken(); + return ParseAssignmentExprWithObjCMessageExprStart( + StartLoc, NameLoc, II, ExprArg(Actions)); + } } // Note that we parse this as an assignment expression, not a constant diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index cd42aee255..6e31f0f63c 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1709,6 +1709,7 @@ Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { /// '[' objc-receiver objc-message-args ']' /// /// objc-receiver: +/// 'super' /// expression /// class-name /// type-name @@ -1716,16 +1717,22 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() { assert(Tok.is(tok::l_square) && "'[' expected"); SourceLocation LBracLoc = ConsumeBracket(); // consume '[' - // Parse receiver - if (isTokObjCMessageIdentifierReceiver()) { - IdentifierInfo *ReceiverName = Tok.getIdentifierInfo(); - if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) { + if (Tok.is(tok::identifier)) { + IdentifierInfo *II = Tok.getIdentifierInfo(); + + // If this is '[' 'super', then this is a magic superclass message. + // We parse '[' 'super' '.' 'foo' as an expression? + // FIXME: Not in ParseInit.cpp? + if ((II == Ident_super && GetLookAheadToken(1).isNot(tok::period)) || + // Check to see if this is a typename. If so, it is a class message. + Actions.getTypeName(*II, Tok.getLocation(), CurScope)) { SourceLocation NameLoc = ConsumeToken(); - return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, + return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, II, ExprArg(Actions)); } } - + + // Otherwise, an arbitrary expression can be the receiver of a send. OwningExprResult Res(ParseExpression()); if (Res.isInvalid()) { SkipUntil(tok::r_square); |