Action::OwningExprResult Sema::ActOnSelectorExpr(ExprArg BaseExpr, SourceLocation OpLoc, SourceLocation IILoc, IdentifierInfo *II) { Expr *Base = BaseExpr.takeAs<Expr>(); // Note: This will fail for all ExprEmpty()s getting passed in (atm for all // numeric literals etc) assert(Base && "no base expression"); // If base is a var, this is a lookup into its type (struct or interface) // If base is a type, this could be a MethodExpr. LookupResult R(*this, II, IILoc, LookupMemberName); OwningExprResult BaseResult = Owned(Base); OwningExprResult Result = LookupMemberExpr(R, *Base, OpLoc); if (BaseResult.isInvalid()) return ExprError(); Base = BaseResult.takeAs<Expr>(); if (Result.isInvalid()) { Owned(Base); return ExprError(); } if (Result.get()) { return Result; } Result = BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, R); return Result; }
bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, SourceLocation lbrac, SourceLocation rbrac, QualType &ReturnType) { if (!Method) { // Apply default argument promotion as for (C99 6.5.2.2p6). for (unsigned i = 0; i != NumArgs; i++) { if (Args[i]->isTypeDependent()) continue; DefaultArgumentPromotion(Args[i]); } unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found : diag::warn_inst_method_not_found; Diag(lbrac, DiagID) << Sel << isClassMessage << SourceRange(lbrac, rbrac); ReturnType = Context.getObjCIdType(); return false; } ReturnType = Method->getSendResultType(); unsigned NumNamedArgs = Sel.getNumArgs(); // Method might have more arguments than selector indicates. This is due // to addition of c-style arguments in method. if (Method->param_size() > Sel.getNumArgs()) NumNamedArgs = Method->param_size(); // FIXME. This need be cleaned up. if (NumArgs < NumNamedArgs) { Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2 << NumNamedArgs << NumArgs; return false; } bool IsError = false; for (unsigned i = 0; i < NumNamedArgs; i++) { // We can't do any type-checking on a type-dependent argument. if (Args[i]->isTypeDependent()) continue; Expr *argExpr = Args[i]; ParmVarDecl *Param = Method->param_begin()[i]; assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); if (RequireCompleteType(argExpr->getSourceRange().getBegin(), Param->getType(), PDiag(diag::err_call_incomplete_argument) << argExpr->getSourceRange())) return true; InitializedEntity Entity = InitializedEntity::InitializeParameter(Param); OwningExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(argExpr->Retain())); if (ArgE.isInvalid()) IsError = true; else Args[i] = ArgE.takeAs<Expr>(); } // Promote additional arguments to variadic methods. if (Method->isVariadic()) { for (unsigned i = NumNamedArgs; i < NumArgs; ++i) { if (Args[i]->isTypeDependent()) continue; IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0); } } else { // Check for extra arguments to non-variadic methods. if (NumArgs != NumNamedArgs) { Diag(Args[NumNamedArgs]->getLocStart(), diag::err_typecheck_call_too_many_args) << 2 /*method*/ << NumNamedArgs << NumArgs << Method->getSourceRange() << SourceRange(Args[NumNamedArgs]->getLocStart(), Args[NumArgs-1]->getLocEnd()); } } DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs); return IsError; }