Ejemplo n.º 1
0
Expr IRMutator2::mutate(const Expr &e) {
    return e.defined() ? ((const BaseExprNode *)e.get())->mutate_expr(this) : Expr();
}
Ejemplo n.º 2
0
/// Look up the given member of the given non-type-dependent
/// expression.  This can return in one of two ways:
///  * If it returns a sentinel null-but-valid result, the caller will
///    assume that lookup was performed and the results written into
///    the provided structure.  It will take over from there.
///  * Otherwise, the returned expression will be produced in place of
///    an ordinary member expression.
Action::OwningExprResult
Sema::LookupMemberExpr(LookupResult &R, Expr &BaseExpr,
                       SourceLocation OpLoc) {

  const Type *BaseType = BaseExpr.getType();
  assert(BaseType);

  SourceLocation MemberLoc = R.getNameLoc();
#if 0
  DeclarationName MemberName = R.getLookupName();

  // For later type-checking purposes, turn arrow accesses into dot
  // accesses.  The only access type we support that doesn't follow
  // the C equivalence "a->b === (*a).b" is ObjC property accesses,
  // and those never use arrows, so this is unaffected.
  if (IsArrow) {
    if (const PointerType *Ptr = BaseType->getAs<PointerType>())
      BaseType = Ptr->getPointeeType();
    else if (BaseType->isRecordType()) {
      // Recover from arrow accesses to records, e.g.:
      //   struct MyRecord foo;
      //   foo->bar
      // This is actually well-formed in C++ if MyRecord has an
      // overloaded operator->, but that should have been dealt with
      // by now.
      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
        << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
        << FixItHint::CreateReplacement(OpLoc, ".");
      IsArrow = false;
    } else if (BaseType->isFunctionType()) {
      goto fail;
    } else {
      Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
        << BaseType << BaseExpr.get()->getSourceRange();
      return ExprError();
    }
  }
#endif
  // spec#Selector: "If x is a pointer to a struct, x.y is shorthand for (*x).y"
  if (const PointerType *P = dyn_cast<PointerType>(BaseType))
    BaseType = P->getPointeeType();

  // Handle field access to simple records.
  if (const StructType *STy = BaseType->getAs<StructType>()) {
    if (LookupMemberExprInRecord(*this, R, //BaseExpr.get()->getSourceRange(),
                                 STy, OpLoc))
      return ExprError();

    // Returning valid-but-null is how we indicate to the caller that
    // the lookup result was filled in.
    return Owned((Expr *)0);
  }

#if 0
  // Failure cases.
 fail:

  // If the user is trying to apply . to a function name, it's probably
  // because they forgot parentheses to call that function.
  if (tryToRecoverWithCall(BaseExpr,
                           PDiag(diag::err_member_reference_needs_call),
                           /*complain*/ false,
                           IsArrow ? &isPointerToRecordType : &isRecordType)) {
    if (BaseExpr.isInvalid())
      return ExprError();
    BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc);
  }
#endif

  Diag(OpLoc, diag::typecheck_field_reference_struct)
    //<< BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
    << BaseType << SourceRange(MemberLoc, MemberLoc);

  return ExprError();
}