From e3ffc2f4a9a6585a0a803b5d0cf2c964cecf91bc Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 15 Nov 2007 13:05:42 +0000 Subject: [PATCH] Finish up variadic methods/messages. llvm-svn: 44172 --- clang/AST/Expr.cpp | 20 ++++++++++---------- clang/Parse/ParseObjc.cpp | 16 +++++++++++----- clang/Sema/Sema.h | 10 ++++++---- clang/Sema/SemaExpr.cpp | 10 +++++----- clang/include/clang/AST/Expr.h | 14 ++++++++------ clang/include/clang/Parse/Action.h | 9 +++++---- 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/clang/AST/Expr.cpp b/clang/AST/Expr.cpp index 10f0895695eb..fa1a3c95fff1 100644 --- a/clang/AST/Expr.cpp +++ b/clang/AST/Expr.cpp @@ -898,14 +898,14 @@ unsigned OCUVectorElementExpr::getEncodedElementAccess() const { ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo, QualType retType, ObjcMethodDecl *mproto, SourceLocation LBrac, SourceLocation RBrac, - Expr **ArgExprs) + Expr **ArgExprs, unsigned nargs) : Expr(ObjCMessageExprClass, retType), SelName(selInfo), MethodProto(mproto), ClassName(0) { - unsigned numArgs = selInfo.getNumArgs(); - SubExprs = new Expr*[numArgs+1]; + NumArgs = nargs; + SubExprs = new Expr*[NumArgs+1]; SubExprs[RECEIVER] = receiver; - if (numArgs) { - for (unsigned i = 0; i != numArgs; ++i) + if (NumArgs) { + for (unsigned i = 0; i != NumArgs; ++i) SubExprs[i+ARGS_START] = static_cast(ArgExprs[i]); } LBracloc = LBrac; @@ -917,14 +917,14 @@ ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo, ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, QualType retType, ObjcMethodDecl *mproto, SourceLocation LBrac, SourceLocation RBrac, - Expr **ArgExprs) + Expr **ArgExprs, unsigned nargs) : Expr(ObjCMessageExprClass, retType), SelName(selInfo), MethodProto(mproto), ClassName(clsName) { - unsigned numArgs = selInfo.getNumArgs(); - SubExprs = new Expr*[numArgs+1]; + NumArgs = nargs; + SubExprs = new Expr*[NumArgs+1]; SubExprs[RECEIVER] = 0; - if (numArgs) { - for (unsigned i = 0; i != numArgs; ++i) + if (NumArgs) { + for (unsigned i = 0; i != NumArgs; ++i) SubExprs[i+ARGS_START] = static_cast(ArgExprs[i]); } LBracloc = LBrac; diff --git a/clang/Parse/ParseObjc.cpp b/clang/Parse/ParseObjc.cpp index be33f86f0ccf..bc4bcbe901e1 100644 --- a/clang/Parse/ParseObjc.cpp +++ b/clang/Parse/ParseObjc.cpp @@ -1291,9 +1291,15 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { } // Parse the, optional, argument list, comma separated. while (Tok.is(tok::comma)) { - ConsumeToken(); - /// Parse the expression after ',' - ParseAssignmentExpression(); + ConsumeToken(); // Eat the ','. + /// Parse the expression after ',' + ExprResult Res = ParseAssignmentExpression(); + if (Res.isInvalid) { + SkipUntil(tok::identifier); + return Res; + } + // We have a valid expression. + KeyExprs.push_back(Res.Val); } } else if (!selIdent) { Diag(Tok, diag::err_expected_ident); // missing selector name. @@ -1317,9 +1323,9 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { if (ReceiverName) return Actions.ActOnClassMessage(CurScope, ReceiverName, Sel, LBracloc, RBracloc, - &KeyExprs[0]); + &KeyExprs[0], KeyExprs.size()); return Actions.ActOnInstanceMessage(ReceiverExpr, Sel, LBracloc, RBracloc, - &KeyExprs[0]); + &KeyExprs[0], KeyExprs.size()); } Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index a1026448867a..4ed71f7388d1 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -565,18 +565,20 @@ public: // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions - // is obtained from Sel.getNumArgs(). + // is obtained from NumArgs. virtual ExprResult ActOnClassMessage( Scope *S, IdentifierInfo *receivingClassName, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs); + SourceLocation lbrac, SourceLocation rbrac, + ExprTy **ArgExprs, unsigned NumArgs); // ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions - // is obtained from Sel.getNumArgs(). + // is obtained from NumArgs. virtual ExprResult ActOnInstanceMessage( ExprTy *receiver, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs); + SourceLocation lbrac, SourceLocation rbrac, + ExprTy **ArgExprs, unsigned NumArgs); private: // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1). diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 42961df16746..416661ee6c4e 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -2124,7 +2124,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Sema::ExprResult Sema::ActOnClassMessage( Scope *S, IdentifierInfo *receiverName, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args) + SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) { assert(receiverName && "missing receiver class name"); @@ -2142,7 +2142,7 @@ Sema::ExprResult Sema::ActOnClassMessage( SourceLocation(), ReceiverExpr.Val); return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac, - Args); + Args, NumArgs); } // class method if (ClassDecl) @@ -2168,7 +2168,7 @@ Sema::ExprResult Sema::ActOnClassMessage( } } return new ObjCMessageExpr(receiverName, Sel, returnType, Method, - lbrac, rbrac, ArgExprs); + lbrac, rbrac, ArgExprs, NumArgs); } // ActOnInstanceMessage - used for both unary and keyword messages. @@ -2176,7 +2176,7 @@ Sema::ExprResult Sema::ActOnClassMessage( // is obtained from Sel.getNumArgs(). Sema::ExprResult Sema::ActOnInstanceMessage( ExprTy *receiver, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args) + SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) { assert(receiver && "missing receiver expression"); @@ -2250,5 +2250,5 @@ Sema::ExprResult Sema::ActOnInstanceMessage( } } return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, - ArgExprs); + ArgExprs, NumArgs); } diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 66dac91e211d..6ba60f22095c 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1292,6 +1292,8 @@ class ObjCMessageExpr : public Expr { Expr **SubExprs; + unsigned NumArgs; + // A unigue name for this message. Selector SelName; @@ -1309,12 +1311,12 @@ public: ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, QualType retType, ObjcMethodDecl *methDecl, SourceLocation LBrac, SourceLocation RBrac, - Expr **ArgExprs); + Expr **ArgExprs, unsigned NumArgs); // constructor for instance messages. ObjCMessageExpr(Expr *receiver, Selector selInfo, QualType retType, ObjcMethodDecl *methDecl, SourceLocation LBrac, SourceLocation RBrac, - Expr **ArgExprs); + Expr **ArgExprs, unsigned NumArgs); ~ObjCMessageExpr() { delete [] SubExprs; } @@ -1332,20 +1334,20 @@ public: IdentifierInfo *getClassName() { return ClassName; } /// getNumArgs - Return the number of actual arguments to this call. - unsigned getNumArgs() const { return SelName.getNumArgs(); } + unsigned getNumArgs() const { return NumArgs; } /// getArg - Return the specified argument. Expr *getArg(unsigned Arg) { - assert(Arg < SelName.getNumArgs() && "Arg access out of range!"); + assert(Arg < NumArgs && "Arg access out of range!"); return SubExprs[Arg+ARGS_START]; } const Expr *getArg(unsigned Arg) const { - assert(Arg < SelName.getNumArgs() && "Arg access out of range!"); + assert(Arg < NumArgs && "Arg access out of range!"); return SubExprs[Arg+ARGS_START]; } /// setArg - Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { - assert(Arg < SelName.getNumArgs() && "Arg access out of range!"); + assert(Arg < NumArgs && "Arg access out of range!"); SubExprs[Arg+ARGS_START] = ArgExpr; } SourceRange getSourceRange() const { return SourceRange(LBracloc, RBracloc); } diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index e2aa1bad402c..2e8b4de927b0 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -590,22 +590,23 @@ public: // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions - // is obtained from Sel.getNumArgs(). + // is obtained from NumArgs. virtual ExprResult ActOnClassMessage( Scope *S, IdentifierInfo *receivingClassName, Selector Sel, SourceLocation lbrac, SourceLocation rbrac, - ExprTy **ArgExprs) { + ExprTy **ArgExprs, unsigned NumArgs) { return 0; } // ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions - // is obtained from Sel.getNumArgs(). + // is obtained from NumArgs. virtual ExprResult ActOnInstanceMessage( ExprTy *receiver, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs) { + SourceLocation lbrac, SourceLocation rbrac, + ExprTy **ArgExprs, unsigned NumArgs) { return 0; } virtual DeclTy *ActOnForwardClassDeclaration(