Index: Driver/RewriteTest.cpp =================================================================== --- Driver/RewriteTest.cpp (revision 46808) +++ Driver/RewriteTest.cpp (working copy) @@ -746,7 +746,7 @@ ObjCIvarDecl *D = IV->getDecl(); if (IV->isFreeIvar()) { Expr *Replacement = new MemberExpr(IV->getBase(), true, D, - IV->getLocation()); + IV->getLocation(), D->getType()); ReplaceStmt(IV, Replacement); delete IV; return Replacement; Index: Sema/SemaExpr.cpp =================================================================== --- Sema/SemaExpr.cpp (revision 46808) +++ Sema/SemaExpr.cpp (working copy) @@ -532,7 +542,15 @@ if (!MemberDecl) return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(), SourceRange(MemberLoc)); - return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl, MemberLoc); + + // Figure out the type of the member; see C99 6.5.2.3p3 + QualType MemberType = MemberDecl->getType(); + unsigned combinedQualifiers = + MemberType.getQualifiers() | BaseType.getQualifiers(); + MemberType = MemberType.getQualifiedType(combinedQualifiers); + + return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl, + MemberLoc, MemberType); } else if (BaseType->isOCUVectorType() && OpKind == tok::period) { // Component access limited to variables (reject vec4.rg.g). if (!isa(BaseExpr)) @@ -2050,8 +2073,9 @@ // FIXME: C++: Verify that MemberDecl isn't a static field. // FIXME: Verify that MemberDecl isn't a bitfield. - - Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd); + // MemberDecl->getType() doesn't get the right qualifiers, but it doesn't + // matter here. + Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd, MemberDecl->getType()); } return new UnaryOperator(Res, UnaryOperator::OffsetOf, Context.getSizeType(), Index: AST/StmtSerialization.cpp =================================================================== --- AST/StmtSerialization.cpp (revision 46808) +++ AST/StmtSerialization.cpp (working copy) @@ -686,6 +686,7 @@ S.EmitPtr(MemberDecl); S.EmitBool(IsArrow); S.EmitOwnedPtr(Base); + S.Emit(getType()); } MemberExpr* MemberExpr::CreateImpl(Deserializer& D) { @@ -693,8 +694,9 @@ FieldDecl* MemberDecl = cast(D.ReadPtr()); bool IsArrow = D.ReadBool(); Expr* base = D.ReadOwnedPtr(); + QualType T = QualType::ReadVal(D); - return new MemberExpr(base,IsArrow,MemberDecl,L); + return new MemberExpr(base,IsArrow,MemberDecl,L,T); } void NullStmt::EmitImpl(Serializer& S) const { Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h (revision 46808) +++ include/clang/AST/Expr.h (working copy) @@ -650,10 +650,11 @@ SourceLocation MemberLoc; bool IsArrow; // True if this is "X->F", false if this is "X.F". public: - MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l) - : Expr(MemberExprClass, memberdecl->getType()), + MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l, + QualType ty) + : Expr(MemberExprClass, ty), Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {} - + Expr *getBase() const { return Base; } FieldDecl *getMemberDecl() const { return MemberDecl; } bool isArrow() const { return IsArrow; }