diff options
Diffstat (limited to 'lib/Parse/ParseInit.cpp')
-rw-r--r-- | lib/Parse/ParseInit.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index 123908d25a..b0735b3cab 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -129,13 +129,16 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { // send to 'super', parse this as a message send expression. if (getLang().ObjC1 && Tok.is(tok::identifier)) { IdentifierInfo *II = Tok.getIdentifierInfo(); - + SourceLocation IILoc = Tok.getLocation(); // Three cases. This is a message send to a type: [type foo] // This is a message send to super: [super foo] // This is a message sent to an expr: [super.bar foo] - if (Actions.getTypeName(*II, Tok.getLocation(), CurScope) || - (II == Ident_super && GetLookAheadToken(1).isNot(tok::period) && - CurScope->isInObjcMethodScope())) { + switch (Action::ObjCMessageKind Kind + = Actions.getObjCMessageKind(CurScope, II, IILoc, + II == Ident_super, + NextToken().is(tok::period))) { + case Action::ObjCSuperMessage: + case Action::ObjCClassMessage: { // If we have exactly one array designator, this used the GNU // 'designation: array-designator' extension, otherwise there should be no // designators at all! @@ -146,9 +149,47 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { else if (Desig.getNumDesignators() > 0) Diag(Tok, diag::err_expected_equal_designator); - SourceLocation NameLoc = ConsumeToken(); - return ParseAssignmentExprWithObjCMessageExprStart( - StartLoc, NameLoc, II, ExprArg(Actions)); + if (Kind == Action::ObjCSuperMessage) + return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, + ConsumeToken(), + 0, + ExprArg(Actions)); + + // FIXME: This code is redundant with ParseObjCMessageExpr. + // Create the type that corresponds to the identifier (which + // names an Objective-C class). + TypeTy *Type = 0; + if (TypeTy *TyName = Actions.getTypeName(*II, IILoc, CurScope)) { + DeclSpec DS; + const char *PrevSpec = 0; + unsigned DiagID = 0; + if (!DS.SetTypeSpecType(DeclSpec::TST_typename, IILoc, PrevSpec, + DiagID, TyName)) { + DS.SetRangeEnd(IILoc); + Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + TypeResult Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo); + if (!Ty.isInvalid()) + Type = Ty.get(); + } + } + + ConsumeToken(); // The identifier. + if (!Type) { + SkipUntil(tok::r_square); + return ExprError(); + } + + return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, + SourceLocation(), + Type, + ExprArg(Actions)); + } + + case Action::ObjCInstanceMessage: + // Fall through; we'll just parse the expression and + // (possibly) treat this like an Objective-C message send + // later. + break; } } |