Expr IRMutator2::mutate(const Expr &e) { return e.defined() ? ((const BaseExprNode *)e.get())->mutate_expr(this) : Expr(); }
/// 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(); }