Example #1
0
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;
}
Example #2
0
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;
}