diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index bf2517f..6eb8209 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -160,12 +160,14 @@
     if (!E) return false;
 
     E = E->IgnoreParenCasts();
+
+    // Also look through property-getter sugar.
+    if (PseudoObjectExpr *pseudoOp = dyn_cast<PseudoObjectExpr>(E))
+      E = pseudoOp->getResultExpr()->IgnoreImplicit();
+
     if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E))
       return (ME->isInstanceMessage() && ME->getSelector() == DelegateSel);
 
-    if (ObjCPropertyRefExpr *propE = dyn_cast<ObjCPropertyRefExpr>(E))
-      return propE->getGetterSelector() == DelegateSel;
-
     return false;
   }
 
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 69fb2e8..3bfa15c 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -236,7 +236,15 @@
       }
     }
 
-    if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getSubExpr())){
+    Expr *subExpr = E->getSubExpr();
+
+    // Look through pseudo-object expressions.
+    if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) {
+      subExpr = pseudo->getResultExpr();
+      assert(subExpr && "no result for pseudo-object of non-void type?");
+    }
+
+    if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) {
       if (implCE->getCastKind() == CK_ARCConsumeObject)
         return rewriteToBridgedCast(E, OBC_BridgeRetained);
       if (implCE->getCastKind() == CK_ARCReclaimReturnedObject)
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 7c533bc..d1f08aa 100644
--- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -78,6 +78,15 @@
     return true;
   }
 
+  bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
+    if (isZeroingPropIvar(POE) && isRemovable(POE)) {
+      Transaction Trans(Pass.TA);
+      Pass.TA.removeStmt(POE);
+    }
+
+    return true;
+  }
+
   bool VisitBinaryOperator(BinaryOperator *BOE) {
     if (isZeroingPropIvar(BOE) && isRemovable(BOE)) {
       Transaction Trans(Pass.TA);
@@ -142,17 +151,21 @@
   }
 
   bool isZeroingPropIvar(Expr *E) {
-    BinaryOperator *BOE = dyn_cast_or_null<BinaryOperator>(E);
-    if (!BOE) return false;
+    E = E->IgnoreParens();
+    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E))
+      return isZeroingPropIvar(BO);
+    if (PseudoObjectExpr *PO = dyn_cast<PseudoObjectExpr>(E))
+      return isZeroingPropIvar(PO);
+    return false;
+  }
 
+  bool isZeroingPropIvar(BinaryOperator *BOE) {
     if (BOE->getOpcode() == BO_Comma)
       return isZeroingPropIvar(BOE->getLHS()) &&
              isZeroingPropIvar(BOE->getRHS());
 
     if (BOE->getOpcode() != BO_Assign)
-        return false;
-
-    ASTContext &Ctx = Pass.Ctx;
+      return false;
 
     Expr *LHS = BOE->getLHS();
     if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) {
@@ -172,25 +185,38 @@
       if (!IvarBacksPropertySynthesis)
         return false;
     }
-    else if (ObjCPropertyRefExpr *PropRefExp = dyn_cast<ObjCPropertyRefExpr>(LHS)) {
-      // TODO: Using implicit property decl.
-      if (PropRefExp->isImplicitProperty())
-        return false;
-      if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) {
-        if (!SynthesizedProperties.count(PDecl))
-          return false;
-      }
-    }
     else
         return false;
 
-    Expr *RHS = BOE->getRHS();
-    bool RHSIsNull = RHS->isNullPointerConstant(Ctx,
-                                                Expr::NPC_ValueDependentIsNull);
-    if (RHSIsNull)
+    return isZero(BOE->getRHS());
+  }
+
+  bool isZeroingPropIvar(PseudoObjectExpr *PO) {
+    BinaryOperator *BO = dyn_cast<BinaryOperator>(PO->getSyntacticForm());
+    if (!BO) return false;
+    if (BO->getOpcode() != BO_Assign) return false;
+
+    ObjCPropertyRefExpr *PropRefExp =
+      dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParens());
+    if (!PropRefExp) return false;
+
+    // TODO: Using implicit property decl.
+    if (PropRefExp->isImplicitProperty())
+      return false;
+
+    if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) {
+      if (!SynthesizedProperties.count(PDecl))
+        return false;
+    }
+
+    return isZero(cast<OpaqueValueExpr>(BO->getRHS())->getSourceExpr());
+  }
+
+  bool isZero(Expr *E) {
+    if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull))
       return true;
 
-    return isZeroingPropIvar(RHS);
+    return isZeroingPropIvar(E);
   }
 };
 
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index a4daea2..4c31bbd 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -640,7 +640,11 @@
 }
 
 DeclContext *Decl::getNonClosureContext() {
-  DeclContext *DC = getDeclContext();
+  return getDeclContext()->getNonClosureAncestor();
+}
+
+DeclContext *DeclContext::getNonClosureAncestor() {
+  DeclContext *DC = this;
 
   // This is basically "while (DC->isClosure()) DC = DC->getParent();"
   // except that it's significantly more efficient to cast to a known
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 3239973..6eb6116 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1694,6 +1694,19 @@
     R1 = getSourceRange();
     return true;
 
+  case PseudoObjectExprClass: {
+    const PseudoObjectExpr *PO = cast<PseudoObjectExpr>(this);
+
+    // Only complain about things that have the form of a getter.
+    if (isa<UnaryOperator>(PO->getSyntacticForm()) ||
+        isa<BinaryOperator>(PO->getSyntacticForm()))
+      return false;
+
+    Loc = getExprLoc();
+    R1 = getSourceRange();
+    return true;
+  }
+
   case StmtExprClass: {
     // Statement exprs don't logically have side effects themselves, but are
     // sometimes used in macros in ways that give them a type that is unused.
@@ -2598,6 +2611,9 @@
   } else if (const MaterializeTemporaryExpr *M 
                                    = dyn_cast<MaterializeTemporaryExpr>(this)) {
     return M->GetTemporaryExpr()->isNullPointerConstant(Ctx, NPC);
+  } else if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(this)) {
+    if (const Expr *Source = OVE->getSourceExpr())
+      return Source->isNullPointerConstant(Ctx, NPC);
   }
 
   // C++0x nullptr_t is always a null pointer constant.
@@ -3306,6 +3322,72 @@
   return cast<OpaqueValueExpr>(e);
 }
 
+PseudoObjectExpr *PseudoObjectExpr::Create(ASTContext &Context, EmptyShell sh,
+                                           unsigned numSemanticExprs) {
+  void *buffer = Context.Allocate(sizeof(PseudoObjectExpr) +
+                                    (1 + numSemanticExprs) * sizeof(Expr*),
+                                  llvm::alignOf<PseudoObjectExpr>());
+  return new(buffer) PseudoObjectExpr(sh, numSemanticExprs);
+}
+
+PseudoObjectExpr::PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs)
+  : Expr(PseudoObjectExprClass, shell) {
+  PseudoObjectExprBits.NumSubExprs = numSemanticExprs + 1;
+}
+
+PseudoObjectExpr *PseudoObjectExpr::Create(ASTContext &C, Expr *syntax,
+                                           ArrayRef<Expr*> semantics,
+                                           unsigned resultIndex) {
+  assert(syntax && "no syntactic expression!");
+  assert(semantics.size() && "no semantic expressions!");
+
+  QualType type;
+  ExprValueKind VK;
+  if (resultIndex == NoResult) {
+    type = C.VoidTy;
+    VK = VK_RValue;
+  } else {
+    assert(resultIndex < semantics.size());
+    type = semantics[resultIndex]->getType();
+    VK = semantics[resultIndex]->getValueKind();
+    assert(semantics[resultIndex]->getObjectKind() == OK_Ordinary);
+  }
+
+  void *buffer = C.Allocate(sizeof(PseudoObjectExpr) +
+                              (1 + semantics.size()) * sizeof(Expr*),
+                            llvm::alignOf<PseudoObjectExpr>());
+  return new(buffer) PseudoObjectExpr(type, VK, syntax, semantics,
+                                      resultIndex);
+}
+
+PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
+                                   Expr *syntax, ArrayRef<Expr*> semantics,
+                                   unsigned resultIndex)
+  : Expr(PseudoObjectExprClass, type, VK, OK_Ordinary,
+         /*filled in at end of ctor*/ false, false, false, false) {
+  PseudoObjectExprBits.NumSubExprs = semantics.size() + 1;
+  PseudoObjectExprBits.ResultIndex = resultIndex + 1;
+
+  for (unsigned i = 0, e = semantics.size() + 1; i != e; ++i) {
+    Expr *E = (i == 0 ? syntax : semantics[i-1]);
+    getSubExprsBuffer()[i] = E;
+
+    if (E->isTypeDependent())
+      ExprBits.TypeDependent = true;
+    if (E->isValueDependent())
+      ExprBits.ValueDependent = true;
+    if (E->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
+    if (E->containsUnexpandedParameterPack())
+      ExprBits.ContainsUnexpandedParameterPack = true;
+
+    if (isa<OpaqueValueExpr>(E))
+      assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != 0 &&
+             "opaque-value semantic expressions for pseudo-object "
+             "operations must have sources");
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //  ExprIterator.
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 594ae69..1251b96 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -232,6 +232,11 @@
     return ClassifyExprValueKind(Lang, E,
                                  cast<OpaqueValueExpr>(E)->getValueKind());
 
+    // Pseudo-object expressions can produce l-values with reference magic.
+  case Expr::PseudoObjectExprClass:
+    return ClassifyExprValueKind(Lang, E,
+                                 cast<PseudoObjectExpr>(E)->getValueKind());
+
     // Implicit casts are lvalues if they're lvalue casts. Other than that, we
     // only specifically record class temporaries.
   case Expr::ImplicitCastExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 3011b7f..9c9e473 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -3450,6 +3450,7 @@
   case Expr::AsTypeExprClass:
   case Expr::ObjCIndirectCopyRestoreExprClass:
   case Expr::MaterializeTemporaryExprClass:
+  case Expr::PseudoObjectExprClass:
   case Expr::AtomicExprClass:
     return ICEDiag(2, E->getLocStart());
 
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 889cf51..b2e1d20 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2257,6 +2257,7 @@
   case Expr::CXXNoexceptExprClass:
   case Expr::CUDAKernelCallExprClass:
   case Expr::AsTypeExprClass:
+  case Expr::PseudoObjectExprClass:
   case Expr::AtomicExprClass:
   {
     // As bad as this diagnostic is, it's better than crashing.
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 54e62fe..2248343 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -148,6 +148,7 @@
     void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
     void VisitAddrLabelExpr(AddrLabelExpr *Node);
     void VisitBlockExpr(BlockExpr *Node);
+    void VisitOpaqueValueExpr(OpaqueValueExpr *Node);
 
     // C++
     void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
@@ -524,6 +525,15 @@
   DumpSubTree(block->getBody());
 }
 
+void StmtDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
+  DumpExpr(Node);
+
+  if (Expr *Source = Node->getSourceExpr()) {
+    OS << '\n';
+    DumpSubTree(Source);
+  }
+}
+
 // GNU extensions.
 
 void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 5b1654c..04617bf 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1027,6 +1027,10 @@
   OS << ")";
 }
 
+void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
+  PrintExpr(Node->getSyntacticForm());
+}
+
 void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
   const char *Name = 0;
   switch (Node->getOp()) {
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index db97e59..5a6b771 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -475,6 +475,15 @@
   }
 }
 
+void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
+  VisitExpr(S);
+  for (PseudoObjectExpr::const_semantics_iterator
+         i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
+    // Normally, we would not profile the source expressions of OVEs.
+    if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
+      Visit(OVE->getSourceExpr());
+}
+
 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
   VisitExpr(S);
   ID.AddInteger(S->getOp());
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 48888f6..7387921 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -344,6 +344,7 @@
   CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
   CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
   CFGBlock *VisitReturnStmt(ReturnStmt *R);
+  CFGBlock *VisitPseudoObjectExpr(PseudoObjectExpr *E);
   CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
                                           AddStmtChoice asc);
   CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc);
@@ -981,6 +982,9 @@
     case Stmt::OpaqueValueExprClass:
       return Block;
 
+    case Stmt::PseudoObjectExprClass:
+      return VisitPseudoObjectExpr(cast<PseudoObjectExpr>(S));
+
     case Stmt::ReturnStmtClass:
       return VisitReturnStmt(cast<ReturnStmt>(S));
 
@@ -1907,6 +1911,31 @@
   return NYS();
 }
 
+CFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+  autoCreateBlock();
+
+  // Add the PseudoObject as the last thing.
+  appendStmt(Block, E);
+
+  CFGBlock *lastBlock = Block;  
+
+  // Before that, evaluate all of the semantics in order.  In
+  // CFG-land, that means appending them in reverse order.
+  for (unsigned i = E->getNumSemanticExprs(); i != 0; ) {
+    Expr *Semantic = E->getSemanticExpr(--i);
+
+    // If the semantic is an opaque value, we're being asked to bind
+    // it to its source expression.
+    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
+      Semantic = OVE->getSourceExpr();
+
+    if (CFGBlock *B = Visit(Semantic))
+      lastBlock = B;
+  }
+
+  return lastBlock;
+}
+
 CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
   CFGBlock *LoopSuccessor = NULL;
 
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index cd6f09f..f0dbc53 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -288,6 +288,18 @@
       }
       break;
     }
+    case Stmt::PseudoObjectExprClass: {
+      // A pseudo-object operation only directly consumes its result
+      // expression.
+      Expr *child = cast<PseudoObjectExpr>(S)->getResultExpr();
+      if (!child) return;
+      if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child))
+        child = OV->getSourceExpr();
+      child = child->IgnoreParens();
+      val.liveStmts = LV.SSetFact.add(val.liveStmts, child);
+      return;
+    }
+
     // FIXME: These cases eventually shouldn't be needed.
     case Stmt::ExprWithCleanupsClass: {
       S = cast<ExprWithCleanups>(S)->getSubExpr();
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 9ad3ae8..d737114 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -672,6 +672,8 @@
     return EmitStringLiteralLValue(cast<StringLiteral>(E));
   case Expr::ObjCEncodeExprClass:
     return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
+  case Expr::PseudoObjectExprClass:
+    return EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E));
 
   case Expr::BlockDeclRefExprClass:
     return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E));
@@ -2768,3 +2770,86 @@
   cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpaccuracy,
                                             Node);
 }
+
+namespace {
+  struct LValueOrRValue {
+    LValue LV;
+    RValue RV;
+  };
+}
+
+static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
+                                           const PseudoObjectExpr *E,
+                                           bool forLValue,
+                                           AggValueSlot slot) {
+  llvm::SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
+
+  // Find the result expression, if any.
+  const Expr *resultExpr = E->getResultExpr();
+  LValueOrRValue result;
+
+  for (PseudoObjectExpr::const_semantics_iterator
+         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
+    const Expr *semantic = *i;
+
+    // If this semantic expression is an opaque value, bind it
+    // to the result of its source expression.
+    if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
+
+      // If this is the result expression, we may need to evaluate
+      // directly into the slot.
+      typedef CodeGenFunction::OpaqueValueMappingData OVMA;
+      OVMA opaqueData;
+      if (ov == resultExpr && ov->isRValue() && !forLValue &&
+          CodeGenFunction::hasAggregateLLVMType(ov->getType()) &&
+          !ov->getType()->isAnyComplexType()) {
+        CGF.EmitAggExpr(ov->getSourceExpr(), slot);
+
+        LValue LV = CGF.MakeAddrLValue(slot.getAddr(), ov->getType());
+        opaqueData = OVMA::bind(CGF, ov, LV);
+        result.RV = slot.asRValue();
+
+      // Otherwise, emit as normal.
+      } else {
+        opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
+
+        // If this is the result, also evaluate the result now.
+        if (ov == resultExpr) {
+          if (forLValue)
+            result.LV = CGF.EmitLValue(ov);
+          else
+            result.RV = CGF.EmitAnyExpr(ov, slot);
+        }
+      }
+
+      opaques.push_back(opaqueData);
+
+    // Otherwise, if the expression is the result, evaluate it
+    // and remember the result.
+    } else if (semantic == resultExpr) {
+      if (forLValue)
+        result.LV = CGF.EmitLValue(semantic);
+      else
+        result.RV = CGF.EmitAnyExpr(semantic, slot);
+
+    // Otherwise, evaluate the expression in an ignored context.
+    } else {
+      CGF.EmitIgnoredExpr(semantic);
+    }
+  }
+
+  // Unbind all the opaques now.
+  for (unsigned i = 0, e = opaques.size(); i != e; ++i)
+    opaques[i].unbind(CGF);
+
+  return result;
+}
+
+RValue CodeGenFunction::EmitPseudoObjectRValue(const PseudoObjectExpr *E,
+                                               AggValueSlot slot) {
+  return emitPseudoObjectExpr(*this, E, false, slot).RV;
+}
+
+LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) {
+  return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV;
+}
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 0fa1433..ffbc2e0 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -148,6 +148,15 @@
   void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
   void VisitOpaqueValueExpr(OpaqueValueExpr *E);
 
+  void VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+    if (E->isGLValue()) {
+      LValue LV = CGF.EmitPseudoObjectLValue(E);
+      return EmitFinalDestCopy(E, LV);
+    }
+
+    CGF.EmitPseudoObjectRValue(E, EnsureSlot(E->getType()));
+  }
+
   void VisitVAArgExpr(VAArgExpr *E);
 
   void EmitInitializationToLValue(Expr *E, LValue Address);
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index b6c416b..c09278c 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -137,6 +137,10 @@
     return CGF.getOpaqueRValueMapping(E).getComplexVal();
   }
 
+  ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+    return CGF.EmitPseudoObjectRValue(E).getComplexVal();
+  }
+
   // FIXME: CompoundLiteralExpr
 
   ComplexPairTy EmitCast(CastExpr::CastKind CK, Expr *Op, QualType DestTy);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 50c5057..83ca159 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -197,6 +197,10 @@
     return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
   }
 
+  Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+    return CGF.EmitPseudoObjectRValue(E).getScalarVal();
+  }
+
   Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
     if (E->isGLValue())
       return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E));
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 0cd98ee..f164103 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -2231,6 +2231,59 @@
   return true;
 }
 
+/// Try to emit a PseudoObjectExpr at +1.
+///
+/// This massively duplicates emitPseudoObjectRValue.
+static TryEmitResult tryEmitARCRetainPseudoObject(CodeGenFunction &CGF,
+                                                  const PseudoObjectExpr *E) {
+  llvm::SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
+
+  // Find the result expression.
+  const Expr *resultExpr = E->getResultExpr();
+  assert(resultExpr);
+  TryEmitResult result;
+
+  for (PseudoObjectExpr::const_semantics_iterator
+         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
+    const Expr *semantic = *i;
+
+    // If this semantic expression is an opaque value, bind it
+    // to the result of its source expression.
+    if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
+      typedef CodeGenFunction::OpaqueValueMappingData OVMA;
+      OVMA opaqueData;
+
+      // If this semantic is the result of the pseudo-object
+      // expression, try to evaluate the source as +1.
+      if (ov == resultExpr) {
+        assert(!OVMA::shouldBindAsLValue(ov));
+        result = tryEmitARCRetainScalarExpr(CGF, ov->getSourceExpr());
+        opaqueData = OVMA::bind(CGF, ov, RValue::get(result.getPointer()));
+
+      // Otherwise, just bind it.
+      } else {
+        opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
+      }
+      opaques.push_back(opaqueData);
+
+    // Otherwise, if the expression is the result, evaluate it
+    // and remember the result.
+    } else if (semantic == resultExpr) {
+      result = tryEmitARCRetainScalarExpr(CGF, semantic);
+
+    // Otherwise, evaluate the expression in an ignored context.
+    } else {
+      CGF.EmitIgnoredExpr(semantic);
+    }
+  }
+
+  // Unbind all the opaques now.
+  for (unsigned i = 0, e = opaques.size(); i != e; ++i)
+    opaques[i].unbind(CGF);
+
+  return result;
+}
+
 static TryEmitResult
 tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
   // Look through cleanups.
@@ -2356,6 +2409,17 @@
       llvm::Value *result = emitARCRetainCall(CGF, e);
       if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
       return TryEmitResult(result, true);
+
+    // Look through pseudo-object expressions.
+    } else if (const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
+      TryEmitResult result
+        = tryEmitARCRetainPseudoObject(CGF, pseudo);
+      if (resultType) {
+        llvm::Value *value = result.getPointer();
+        value = CGF.Builder.CreateBitCast(value, resultType);
+        result.setPointer(value);
+      }
+      return result;
     }
 
     // Conservatively halt the search at any other expression kind.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index 489e600..bc94e8e 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -27,6 +27,7 @@
   class ObjCPropertyRefExpr;
 
 namespace CodeGen {
+  class AggValueSlot;
   class CGBitFieldInfo;
 
 /// RValue - This trivial value class is used to represent the result of an
@@ -452,7 +453,7 @@
   RValue asRValue() const {
     return RValue::getAggregate(getAddr(), isVolatile());
   }
-  
+
   void setZeroed(bool V = true) { ZeroedFlag = V; }
   IsZeroed_t isZeroed() const {
     return IsZeroed_t(ZeroedFlag);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 4940e21..0b31ce4 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -950,20 +950,86 @@
 
   public:
     PeepholeProtection() : Inst(0) {}
-  };  
+  };
 
-  /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
-  class OpaqueValueMapping {
-    CodeGenFunction &CGF;
+  /// A non-RAII class containing all the information about a bound
+  /// opaque value.  OpaqueValueMapping, below, is a RAII wrapper for
+  /// this which makes individual mappings very simple; using this
+  /// class directly is useful when you have a variable number of
+  /// opaque values or don't want the RAII functionality for some
+  /// reason.
+  class OpaqueValueMappingData {
     const OpaqueValueExpr *OpaqueValue;
     bool BoundLValue;
     CodeGenFunction::PeepholeProtection Protection;
 
+    OpaqueValueMappingData(const OpaqueValueExpr *ov,
+                           bool boundLValue)
+      : OpaqueValue(ov), BoundLValue(boundLValue) {}
   public:
+    OpaqueValueMappingData() : OpaqueValue(0) {}
+
     static bool shouldBindAsLValue(const Expr *expr) {
       return expr->isGLValue() || expr->getType()->isRecordType();
     }
 
+    static OpaqueValueMappingData bind(CodeGenFunction &CGF,
+                                       const OpaqueValueExpr *ov,
+                                       const Expr *e) {
+      if (shouldBindAsLValue(ov))
+        return bind(CGF, ov, CGF.EmitLValue(e));
+      return bind(CGF, ov, CGF.EmitAnyExpr(e));
+    }
+
+    static OpaqueValueMappingData bind(CodeGenFunction &CGF,
+                                       const OpaqueValueExpr *ov,
+                                       const LValue &lv) {
+      assert(shouldBindAsLValue(ov));
+      CGF.OpaqueLValues.insert(std::make_pair(ov, lv));
+      return OpaqueValueMappingData(ov, true);
+    }
+
+    static OpaqueValueMappingData bind(CodeGenFunction &CGF,
+                                       const OpaqueValueExpr *ov,
+                                       const RValue &rv) {
+      assert(!shouldBindAsLValue(ov));
+      CGF.OpaqueRValues.insert(std::make_pair(ov, rv));
+
+      OpaqueValueMappingData data(ov, false);
+
+      // Work around an extremely aggressive peephole optimization in
+      // EmitScalarConversion which assumes that all other uses of a
+      // value are extant.
+      data.Protection = CGF.protectFromPeepholes(rv);
+
+      return data;
+    }
+
+    bool isValid() const { return OpaqueValue != 0; }
+    void clear() { OpaqueValue = 0; }
+
+    void unbind(CodeGenFunction &CGF) {
+      assert(OpaqueValue && "no data to unbind!");
+
+      if (BoundLValue) {
+        CGF.OpaqueLValues.erase(OpaqueValue);
+      } else {
+        CGF.OpaqueRValues.erase(OpaqueValue);
+        CGF.unprotectFromPeepholes(Protection);
+      }
+    }
+  };
+
+  /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
+  class OpaqueValueMapping {
+    CodeGenFunction &CGF;
+    OpaqueValueMappingData Data;
+
+  public:
+    static bool shouldBindAsLValue(const Expr *expr) {
+      return OpaqueValueMappingData::shouldBindAsLValue(expr);
+    }
+
     /// Build the opaque value mapping for the given conditional
     /// operator if it's the GNU ?: extension.  This is a common
     /// enough pattern that the convenience operator is really
@@ -971,75 +1037,34 @@
     ///
     OpaqueValueMapping(CodeGenFunction &CGF,
                        const AbstractConditionalOperator *op) : CGF(CGF) {
-      if (isa<ConditionalOperator>(op)) {
-        OpaqueValue = 0;
-        BoundLValue = false;
+      if (isa<ConditionalOperator>(op))
+        // Leave Data empty.
         return;
-      }
 
       const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op);
-      init(e->getOpaqueValue(), e->getCommon());
+      Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(),
+                                          e->getCommon());
     }
 
     OpaqueValueMapping(CodeGenFunction &CGF,
                        const OpaqueValueExpr *opaqueValue,
                        LValue lvalue)
-      : CGF(CGF), OpaqueValue(opaqueValue), BoundLValue(true) {
-      assert(opaqueValue && "no opaque value expression!");
-      assert(shouldBindAsLValue(opaqueValue));
-      initLValue(lvalue);
+      : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) {
     }
 
     OpaqueValueMapping(CodeGenFunction &CGF,
                        const OpaqueValueExpr *opaqueValue,
                        RValue rvalue)
-      : CGF(CGF), OpaqueValue(opaqueValue), BoundLValue(false) {
-      assert(opaqueValue && "no opaque value expression!");
-      assert(!shouldBindAsLValue(opaqueValue));
-      initRValue(rvalue);
+      : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) {
     }
 
     void pop() {
-      assert(OpaqueValue && "mapping already popped!");
-      popImpl();
-      OpaqueValue = 0;
+      Data.unbind(CGF);
+      Data.clear();
     }
 
     ~OpaqueValueMapping() {
-      if (OpaqueValue) popImpl();
-    }
-
-  private:
-    void popImpl() {
-      if (BoundLValue)
-        CGF.OpaqueLValues.erase(OpaqueValue);
-      else {
-        CGF.OpaqueRValues.erase(OpaqueValue);
-        CGF.unprotectFromPeepholes(Protection);
-      }
-    }
-
-    void init(const OpaqueValueExpr *ov, const Expr *e) {
-      OpaqueValue = ov;
-      BoundLValue = shouldBindAsLValue(ov);
-      assert(BoundLValue == shouldBindAsLValue(e)
-             && "inconsistent expression value kinds!");
-      if (BoundLValue)
-        initLValue(CGF.EmitLValue(e));
-      else
-        initRValue(CGF.EmitAnyExpr(e));
-    }
-
-    void initLValue(const LValue &lv) {
-      CGF.OpaqueLValues.insert(std::make_pair(OpaqueValue, lv));
-    }
-
-    void initRValue(const RValue &rv) {
-      // Work around an extremely aggressive peephole optimization in
-      // EmitScalarConversion which assumes that all other uses of a
-      // value are extant.
-      Protection = CGF.protectFromPeepholes(rv);
-      CGF.OpaqueRValues.insert(std::make_pair(OpaqueValue, rv));
+      if (Data.isValid()) Data.unbind(CGF);
     }
   };
   
@@ -2015,6 +2040,10 @@
   LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
   LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
 
+  RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
+                                AggValueSlot slot = AggValueSlot::ignored());
+  LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e);
+
   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar);
   LValue EmitLValueForAnonRecordField(llvm::Value* Base,
diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp
index 1af9a6c..428418a 100644
--- a/lib/Rewrite/RewriteObjC.cpp
+++ b/lib/Rewrite/RewriteObjC.cpp
@@ -138,12 +138,6 @@
     
     llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
 
-    // This maps a property to it's assignment statement.
-    llvm::DenseMap<Expr *, BinaryOperator *> PropSetters;
-    // This maps a property to it's synthesied message expression.
-    // This allows us to rewrite chained getters (e.g. o.a.b.c).
-    llvm::DenseMap<Expr *, Stmt *> PropGetters;
-
     // This maps an original source AST to it's rewritten form. This allows
     // us to avoid rewriting the same node twice (which is very uncommon).
     // This is needed to support some of the exotic property rewriting.
@@ -154,6 +148,19 @@
     VarDecl *GlobalVarDecl;
 
     bool DisableReplaceStmt;
+    class DisableReplaceStmtScope {
+      RewriteObjC &R;
+      bool SavedValue;
+
+    public:
+      DisableReplaceStmtScope(RewriteObjC &R)
+        : R(R), SavedValue(R.DisableReplaceStmt) {
+        R.DisableReplaceStmt = true;
+      }
+      ~DisableReplaceStmtScope() {
+        R.DisableReplaceStmt = SavedValue;
+      }
+    };
 
     static const int OBJC_ABI_VERSION = 7;
   public:
@@ -186,7 +193,7 @@
         return; // We can't rewrite the same node twice.
 
       if (DisableReplaceStmt)
-        return; // Used when rewriting the assignment of a property setter.
+        return;
 
       // If replacement succeeded or warning disabled return with no warning.
       if (!Rewrite.ReplaceStmt(Old, New)) {
@@ -200,6 +207,9 @@
     }
 
     void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      if (DisableReplaceStmt)
+        return;
+
       // Measure the old text.
       int Size = Rewrite.getRangeSize(SrcRange);
       if (Size == -1) {
@@ -282,18 +292,14 @@
 
     // Expression Rewriting.
     Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
-    void CollectPropertySetters(Stmt *S);
 
     Stmt *CurrentBody;
     ParentMap *PropParentMap; // created lazily.
 
     Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
-    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
-                                 bool &replaced);
-    Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
-    Stmt *RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr);
-    Stmt *RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr *newStmt,
-                                SourceRange SrcRange);
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
+    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
     Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
     Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
@@ -1281,184 +1287,173 @@
               "/* @end */");
 }
 
-Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr *newStmt,
-                                         SourceRange SrcRange) {
-  ObjCMethodDecl *OMD = 0;
-  QualType Ty;
-  Selector Sel;
-  Stmt *Receiver = 0;
-  bool Super = false;
-  QualType SuperTy;
-  SourceLocation SuperLocation;
-  SourceLocation SelectorLoc;
-  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ObjCImplicitSetterGetterRefExpr.
-  // This allows us to reuse all the fun and games in SynthMessageExpr().
-  if (ObjCPropertyRefExpr *PropRefExpr =
-        dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS())) {
-    SelectorLoc = PropRefExpr->getLocation();
-    if (PropRefExpr->isExplicitProperty()) {
-      ObjCPropertyDecl *PDecl = PropRefExpr->getExplicitProperty();
-      OMD = PDecl->getSetterMethodDecl();
-      Ty = PDecl->getType();
-      Sel = PDecl->getSetterName();
-    } else {
-      OMD = PropRefExpr->getImplicitPropertySetter();
-      Sel = OMD->getSelector();
-      Ty = (*OMD->param_begin())->getType();
-    }
-    Super = PropRefExpr->isSuperReceiver();
-    if (!Super) {
-      Receiver = PropRefExpr->getBase();
-    } else {
-      SuperTy = PropRefExpr->getSuperReceiverType();
-      SuperLocation = PropRefExpr->getReceiverLocation();
-    }
-  }
-  
-  assert(OMD && "RewritePropertyOrImplicitSetter - null OMD");
+Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
 
-  ObjCMessageExpr *MsgExpr;
-  if (Super)
-    MsgExpr = ObjCMessageExpr::Create(*Context, 
-                                      Ty.getNonReferenceType(),
-                                      Expr::getValueKindForType(Ty),
-                                      /*FIXME?*/SourceLocation(),
-                                      SuperLocation,
-                                      /*IsInstanceSuper=*/true,
-                                      SuperTy,
-                                      Sel, SelectorLoc, OMD,
-                                      newStmt,
-                                      /*FIXME:*/SourceLocation());
-  else {
-    // FIXME. Refactor this into common code with that in 
-    // RewritePropertyOrImplicitGetter
-    assert(Receiver && "RewritePropertyOrImplicitSetter - null Receiver");
-    if (Expr *Exp = dyn_cast<Expr>(Receiver))
-      if (PropGetters[Exp])
-        // This allows us to handle chain/nested property/implicit getters.
-        Receiver = PropGetters[Exp];
-  
-    MsgExpr = ObjCMessageExpr::Create(*Context, 
-                                      Ty.getNonReferenceType(),
-                                      Expr::getValueKindForType(Ty),
-                                      /*FIXME: */SourceLocation(),
-                                      cast<Expr>(Receiver),
-                                      Sel, SelectorLoc, OMD,
-                                      newStmt,
-                                      /*FIXME:*/SourceLocation());
-  }
-  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
+                            PseudoOp->getNumSemanticExprs() - 1));
 
-  // Now do the actual rewrite.
-  ReplaceStmtWithRange(BinOp, ReplacingStmt, SrcRange);
-  //delete BinOp;
-  // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
-  // to things that stay around.
-  Context->Deallocate(MsgExpr);
-  return ReplacingStmt;
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base, *RHS;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    Base = 0;
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+
+    // Rebuild the RHS.
+    RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS();
+    RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr();
+    RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS));
+  }
+
+  // TODO: avoid this copy.
+  SmallVector<SourceLocation, 1> SelLocs;
+  OldMsg->getSelectorLocs(SelLocs);
+
+  ObjCMessageExpr *NewMsg;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
 }
 
-Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) {
-  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ImplicitGetter.
-  // This allows us to reuse all the fun and games in SynthMessageExpr().
-  Stmt *Receiver = 0;
-  ObjCMethodDecl *OMD = 0;
-  QualType Ty;
-  Selector Sel;
-  bool Super = false;
-  QualType SuperTy;
-  SourceLocation SuperLocation;
-  SourceLocation SelectorLoc;
-  if (ObjCPropertyRefExpr *PropRefExpr = 
-        dyn_cast<ObjCPropertyRefExpr>(PropOrGetterRefExpr)) {
-    SelectorLoc = PropRefExpr->getLocation();
-    if (PropRefExpr->isExplicitProperty()) {
-      ObjCPropertyDecl *PDecl = PropRefExpr->getExplicitProperty();
-      OMD = PDecl->getGetterMethodDecl();
-      Ty = PDecl->getType();
-      Sel = PDecl->getGetterName();
-    } else {
-      OMD = PropRefExpr->getImplicitPropertyGetter();
-      Sel = OMD->getSelector();
-      Ty = OMD->getResultType();
+Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base = 0;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
     }
-    Super = PropRefExpr->isSuperReceiver();
-    if (!Super)
-      Receiver = PropRefExpr->getBase();
-    else {
-      SuperTy = PropRefExpr->getSuperReceiverType();
-      SuperLocation = PropRefExpr->getReceiverLocation();
-    }
-  }
-  
-  assert (OMD && "RewritePropertyOrImplicitGetter - OMD is null");
-  
-  ObjCMessageExpr *MsgExpr;
-  if (Super)
-    MsgExpr = ObjCMessageExpr::Create(*Context, 
-                                      Ty.getNonReferenceType(),
-                                      Expr::getValueKindForType(Ty),
-                                      PropOrGetterRefExpr->getLocStart(),
-                                      SuperLocation,
-                                      /*IsInstanceSuper=*/true,
-                                      SuperTy,
-                                      Sel, SelectorLoc, OMD,
-                                      ArrayRef<Expr*>(), 
-                                      PropOrGetterRefExpr->getLocEnd());
-  else {
-    assert (Receiver && "RewritePropertyOrImplicitGetter - Receiver is null");
-    if (Expr *Exp = dyn_cast<Expr>(Receiver))
-      if (PropGetters[Exp])
-        // This allows us to handle chain/nested property/implicit getters.
-        Receiver = PropGetters[Exp];
-    MsgExpr = ObjCMessageExpr::Create(*Context, 
-                                      Ty.getNonReferenceType(),
-                                      Expr::getValueKindForType(Ty),
-                                      PropOrGetterRefExpr->getLocStart(),
-                                      cast<Expr>(Receiver),
-                                      Sel, SelectorLoc, OMD,
-                                      ArrayRef<Expr*>(), 
-                                      PropOrGetterRefExpr->getLocEnd());
   }
 
-  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr, MsgExpr->getLocStart(),
-                                         MsgExpr->getLocEnd());
+  // Intentionally empty.
+  SmallVector<SourceLocation, 1> SelLocs;
+  SmallVector<Expr*, 1> Args;
 
-  if (!PropParentMap)
-    PropParentMap = new ParentMap(CurrentBody);
-  bool NestedPropertyRef = false;
-  Stmt *Parent = PropParentMap->getParent(PropOrGetterRefExpr);
-  ImplicitCastExpr*ICE=0;
-  if (Parent)
-    if ((ICE = dyn_cast<ImplicitCastExpr>(Parent))) {
-      assert((ICE->getCastKind() == CK_GetObjCProperty)
-             && "RewritePropertyOrImplicitGetter");
-      Parent = PropParentMap->getParent(Parent);
-      NestedPropertyRef = (Parent && isa<ObjCPropertyRefExpr>(Parent));
-    }
-  if (NestedPropertyRef) {
-    // We stash away the ReplacingStmt since actually doing the
-    // replacement/rewrite won't work for nested getters (e.g. obj.p.i)
-    PropGetters[ICE] = ReplacingStmt;
-    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
-    // to things that stay around.
-    Context->Deallocate(MsgExpr);
-    return PropOrGetterRefExpr; // return the original...
-  } else {
-    ReplaceStmt(PropOrGetterRefExpr, ReplacingStmt);
-    // delete PropRefExpr; elsewhere...
-    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
-    // to things that stay around.
-    Context->Deallocate(MsgExpr);
-    return ReplacingStmt;
+  ObjCMessageExpr *NewMsg;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc());
+    break;
   }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
 }
 
-Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
-                                          SourceLocation OrigStart,
-                                          bool &replaced) {
+Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
+  SourceRange OldRange = IV->getSourceRange();
+  Expr *BaseExpr = IV->getBase();
+
+  // Rewrite the base, but without actually doing replaces.
+  {
+    DisableReplaceStmtScope S(*this);
+    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
+    IV->setBase(BaseExpr);
+  }
+
   ObjCIvarDecl *D = IV->getDecl();
-  const Expr *BaseExpr = IV->getBase();
+
+  Expr *Replacement = IV;
   if (CurMethodDef) {
     if (BaseExpr->getType()->isObjCObjectPointerType()) {
       const ObjCInterfaceType *iFaceDecl =
@@ -1483,25 +1478,19 @@
                                                     CK_BitCast,
                                                     IV->getBase());
       // Don't forget the parens to enforce the proper binding.
-      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
-                                              IV->getBase()->getLocEnd(),
+      ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(),
+                                              OldRange.getEnd(),
                                               castExpr);
-      replaced = true;
       if (IV->isFreeIvar() &&
           CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
         MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
                                                   IV->getLocation(),
                                                   D->getType(),
                                                   VK_LValue, OK_Ordinary);
-        // delete IV; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-        return ME;
+        Replacement = ME;
+      } else {
+        IV->setBase(PE);
       }
-      // Get the new text
-      // Cannot delete IV->getBase(), since PE points to it.
-      // Replace the old base with the cast. This is important when doing
-      // embedded rewrites. For example, [newInv->_container addObject:0].
-      IV->setBase(PE);
-      return IV;
     }
   } else { // we are outside a method.
     assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
@@ -1532,36 +1521,15 @@
       // Don't forget the parens to enforce the proper binding.
       ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
                                     IV->getBase()->getLocEnd(), castExpr);
-      replaced = true;
       // Cannot delete IV->getBase(), since PE points to it.
       // Replace the old base with the cast. This is important when doing
       // embedded rewrites. For example, [newInv->_container addObject:0].
       IV->setBase(PE);
-      return IV;
     }
   }
-  return IV;
-}
 
-Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
-  for (Stmt::child_range CI = S->children(); CI; ++CI) {
-    if (*CI) {
-      Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
-      if (newStmt)
-        *CI = newStmt;
-    }
-  }
-  if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
-    SourceRange OrigStmtRange = S->getSourceRange();
-    Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
-                                           replaced);
-    return newStmt;
-  } 
-  if (ObjCMessageExpr *MsgRefExpr = dyn_cast<ObjCMessageExpr>(S)) {
-    Stmt *newStmt = SynthMessageExpr(MsgRefExpr);
-    return newStmt;
-  }
-  return S;
+  ReplaceStmtWithRange(IV, Replacement, OldRange);
+  return Replacement;  
 }
 
 /// SynthCountByEnumWithState - To print:
@@ -4753,6 +4721,9 @@
     return CondExpr;
   } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
     CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else if (const PseudoObjectExpr *POE
+               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
+    CPT = POE->getType()->castAs<BlockPointerType>();
   } else {
     assert(1 && "RewriteBlockClass: Bad type");
   }
@@ -5580,26 +5551,6 @@
 // Function Body / Expression rewriting
 //===----------------------------------------------------------------------===//
 
-// This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer().
-// The allows the main rewrite loop to associate all ObjCPropertyRefExprs with
-// their respective BinaryOperator. Without this knowledge, we'd need to rewrite
-// the ObjCPropertyRefExpr twice (once as a getter, and later as a setter).
-// Since the rewriter isn't capable of rewriting rewritten code, it's important
-// we get this right.
-void RewriteObjC::CollectPropertySetters(Stmt *S) {
-  // Perform a bottom up traversal of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI)
-      CollectPropertySetters(*CI);
-
-  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
-    if (BinOp->isAssignmentOp()) {
-      if (isa<ObjCPropertyRefExpr>(BinOp->getLHS()))
-        PropSetters[BinOp->getLHS()] = BinOp;
-    }
-  }
-}
-
 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
       isa<DoStmt>(S) || isa<ForStmt>(S))
@@ -5609,46 +5560,28 @@
     ObjCBcLabelNo.push_back(++BcLabelCount);
   }
 
+  // Pseudo-object operations and ivar references need special
+  // treatment because we're going to recursively rewrite them.
+  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
+    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
+      return RewritePropertyOrImplicitSetter(PseudoOp);
+    } else {
+      return RewritePropertyOrImplicitGetter(PseudoOp);
+    }
+  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    return RewriteObjCIvarRefExpr(IvarRefExpr);
+  }
+
   SourceRange OrigStmtRange = S->getSourceRange();
 
   // Perform a bottom up rewrite of all children.
   for (Stmt::child_range CI = S->children(); CI; ++CI)
     if (*CI) {
-      Stmt *newStmt;
-      Stmt *ChildStmt = (*CI);
-      if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(ChildStmt)) {
-        Expr *OldBase = IvarRefExpr->getBase();
-        bool replaced = false;
-        newStmt = RewriteObjCNestedIvarRefExpr(ChildStmt, replaced);
-        if (replaced) {
-          if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
-            ReplaceStmt(OldBase, IRE->getBase());
-          else
-            ReplaceStmt(ChildStmt, newStmt);
-        }
-      }
-      else
-        newStmt = RewriteFunctionBodyOrGlobalInitializer(ChildStmt);
+      Stmt *childStmt = (*CI);
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
       if (newStmt) {
-          if (Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(ChildStmt))
-            if (PropSetters[PropOrImplicitRefExpr] == S) {
-              S = newStmt;
-              newStmt = 0;
-            }
-        if (newStmt)
-          *CI = newStmt;
+        *CI = newStmt;
       }
-      // If dealing with an assignment with LHS being a property reference
-      // expression, the entire assignment tree is rewritten into a property
-      // setter messaging. This involvs the RHS too. Do not attempt to rewrite
-      // RHS again.
-      if (Expr *Exp = dyn_cast<Expr>(ChildStmt))
-        if (isa<ObjCPropertyRefExpr>(Exp)) {
-          if (PropSetters[Exp]) {
-            ++CI;
-            continue;
-          }
-        }
     }
 
   if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
@@ -5661,7 +5594,6 @@
     // Rewrite the block body in place.
     Stmt *SaveCurrentBody = CurrentBody;
     CurrentBody = BE->getBody();
-    CollectPropertySetters(CurrentBody);
     PropParentMap = 0;
     // block literal on rhs of a property-dot-sytax assignment
     // must be replaced by its synthesize ast so getRewrittenText
@@ -5689,67 +5621,6 @@
   if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
     return RewriteAtEncode(AtEncode);
 
-  if (isa<ObjCPropertyRefExpr>(S)) {
-    Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(S);
-    assert(PropOrImplicitRefExpr && "Property or implicit setter/getter is null");
-    
-    BinaryOperator *BinOp = PropSetters[PropOrImplicitRefExpr];
-    if (BinOp) {
-      // Because the rewriter doesn't allow us to rewrite rewritten code,
-      // we need to rewrite the right hand side prior to rewriting the setter.
-      DisableReplaceStmt = true;
-      // Save the source range. Even if we disable the replacement, the
-      // rewritten node will have been inserted into the tree. If the synthesized
-      // node is at the 'end', the rewriter will fail. Consider this:
-      //    self.errorHandler = handler ? handler :
-      //              ^(NSURL *errorURL, NSError *error) { return (BOOL)1; };
-      SourceRange SrcRange = BinOp->getSourceRange();
-      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(BinOp->getRHS());
-      // Need to rewrite the ivar access expression if need be.
-      if (isa<ObjCIvarRefExpr>(newStmt)) {
-        bool replaced = false;
-        newStmt = RewriteObjCNestedIvarRefExpr(newStmt, replaced);
-      }
-      
-      DisableReplaceStmt = false;
-      //
-      // Unlike the main iterator, we explicily avoid changing 'BinOp'. If
-      // we changed the RHS of BinOp, the rewriter would fail (since it needs
-      // to see the original expression). Consider this example:
-      //
-      // Foo *obj1, *obj2;
-      //
-      // obj1.i = [obj2 rrrr];
-      //
-      // 'BinOp' for the previous expression looks like:
-      //
-      // (BinaryOperator 0x231ccf0 'int' '='
-      //   (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i"
-      //     (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0))
-      //   (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr
-      //     (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0)))
-      //
-      // 'newStmt' represents the rewritten message expression. For example:
-      //
-      // (CallExpr 0x231d300 'id':'struct objc_object *'
-      //   (ParenExpr 0x231d2e0 'int (*)(id, SEL)'
-      //     (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)'
-      //       (CStyleCastExpr 0x231d220 'void *'
-      //         (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0))))
-      //
-      // Note that 'newStmt' is passed to RewritePropertyOrImplicitSetter so that it
-      // can be used as the setter argument. ReplaceStmt() will still 'see'
-      // the original RHS (since we haven't altered BinOp).
-      //
-      // This implies the Rewrite* routines can no longer delete the original
-      // node. As a result, we now leak the original AST nodes.
-      //
-      return RewritePropertyOrImplicitSetter(BinOp, dyn_cast<Expr>(newStmt), SrcRange);
-    } else {
-      return RewritePropertyOrImplicitGetter(PropOrImplicitRefExpr);
-    }
-  }
-  
   if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
     return RewriteAtSelector(AtSelector);
 
@@ -5930,7 +5801,6 @@
     if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
       CurFunctionDef = FD;
       CurFunctionDeclToDeclareForBlock = FD;
-      CollectPropertySetters(Body);
       CurrentBody = Body;
       Body =
        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
@@ -5951,7 +5821,6 @@
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
     if (CompoundStmt *Body = MD->getCompoundBody()) {
       CurMethodDef = MD;
-      CollectPropertySetters(Body);
       CurrentBody = Body;
       Body =
        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
@@ -5989,7 +5858,6 @@
     }
     if (VD->getInit()) {
       GlobalVarDecl = VD;
-      CollectPropertySetters(VD->getInit());
       CurrentBody = VD->getInit();
       RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
       CurrentBody = 0;
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 8cae040..8a33242 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -4213,6 +4213,26 @@
       continue;
     }
 
+    if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
+      // Only pay attention to pseudo-objects on property references.
+      ObjCPropertyRefExpr *pre
+        = dyn_cast<ObjCPropertyRefExpr>(pseudo->getSyntacticForm()
+                                              ->IgnoreParens());
+      if (!pre) return false;
+      if (pre->isImplicitProperty()) return false;
+      ObjCPropertyDecl *property = pre->getExplicitProperty();
+      if (!property->isRetaining() &&
+          !(property->getPropertyIvarDecl() &&
+            property->getPropertyIvarDecl()->getType()
+              .getObjCLifetime() == Qualifiers::OCL_Strong))
+          return false;
+
+      owner.Indirect = true;
+      e = const_cast<Expr*>(cast<OpaqueValueExpr>(pre->getBase())
+                              ->getSourceExpr());
+      continue;
+    }
+
     // Array ivars?
 
     return false;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index febd394..c6a5f1e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7468,7 +7468,7 @@
     // The operand must be either an l-value or a function designator
     if (!op->getType()->isFunctionType()) {
       // Use a special diagnostic for loads from property references.
-      if (isa<ObjCPropertyRefExpr>(op->IgnoreImplicit()->IgnoreParens())) {
+      if (isa<PseudoObjectExpr>(op)) {
         AddressOfError = AO_Property_Expansion;
       } else {
         // FIXME: emit more specific diag...
@@ -7483,9 +7483,6 @@
   } else if (op->getObjectKind() == OK_VectorComponent) {
     // The operand cannot be an element of a vector
     AddressOfError = AO_Vector_Element;
-  } else if (op->getObjectKind() == OK_ObjCProperty) {
-    // cannot take address of a property expression.
-    AddressOfError = AO_Property_Expansion;
   } else if (dcl) { // C99 6.5.3.2p1
     // We have an lvalue with a decl. Make sure the decl is not declared
     // with the register storage-class specifier.
@@ -8951,8 +8948,15 @@
       return;
   }
 
-  // Strip off any parens and casts.
-  StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr->IgnoreParenCasts());
+  // Ignore any parens, implicit casts (should only be
+  // array-to-pointer decays), and not-so-opaque values.  The last is
+  // important for making this trigger for property assignments.
+  SrcExpr = SrcExpr->IgnoreParenImpCasts();
+  if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
+    if (OV->getSourceExpr())
+      SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
+
+  StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
   if (!SL || !SL->isAscii())
     return;
 
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 019dc81..a9179dc 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -467,14 +467,13 @@
 
 bool Sema::isSelfExpr(Expr *receiver) {
   // 'self' is objc 'self' in an objc method only.
-  DeclContext *DC = CurContext;
-  while (isa<BlockDecl>(DC))
-    DC = DC->getParent();
-  if (DC && !isa<ObjCMethodDecl>(DC))
-    return false;
+  ObjCMethodDecl *method =
+    dyn_cast<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
+  if (!method) return false;
+
   receiver = receiver->IgnoreParenLValueCasts();
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
-    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
+    if (DRE->getDecl() == method->getSelfDecl())
       return true;
   return false;
 }
@@ -1725,6 +1724,12 @@
       return merge(left, Visit(e->getFalseExpr()));
     }
 
+    /// Look through pseudo-objects.
+    ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
+      // If we're getting here, we should always have a result.
+      return Visit(e->getResultExpr());
+    }
+
     /// Statement expressions are okay if their result expression is okay.
     ACCResult VisitStmtExpr(StmtExpr *e) {
       return Visit(e->getSubStmt()->body_back());
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 97fbe48..e0a6271 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -38,11 +38,364 @@
 using namespace clang;
 using namespace sema;
 
+namespace {
+  // Basically just a very focused copy of TreeTransform.
+  template <class T> struct Rebuilder {
+    Sema &S;
+    Rebuilder(Sema &S) : S(S) {}
+
+    T &getDerived() { return static_cast<T&>(*this); }
+
+    Expr *rebuild(Expr *e) {
+      // Fast path: nothing to look through.
+      if (typename T::specific_type *specific
+            = dyn_cast<typename T::specific_type>(e))
+        return getDerived().rebuildSpecific(specific);
+
+      // Otherwise, we should look through and rebuild anything that
+      // IgnoreParens would.
+
+      if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
+        e = rebuild(parens->getSubExpr());
+        return new (S.Context) ParenExpr(parens->getLParen(),
+                                         parens->getRParen(),
+                                         e);
+      }
+
+      if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
+        assert(uop->getOpcode() == UO_Extension);
+        e = rebuild(uop->getSubExpr());
+        return new (S.Context) UnaryOperator(e, uop->getOpcode(),
+                                             uop->getType(),
+                                             uop->getValueKind(),
+                                             uop->getObjectKind(),
+                                             uop->getOperatorLoc());
+      }
+
+      if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
+        assert(!gse->isResultDependent());
+        unsigned resultIndex = gse->getResultIndex();
+        unsigned numAssocs = gse->getNumAssocs();
+
+        SmallVector<Expr*, 8> assocs(numAssocs);
+        SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
+
+        for (unsigned i = 0; i != numAssocs; ++i) {
+          Expr *assoc = gse->getAssocExpr(i);
+          if (i == resultIndex) assoc = rebuild(assoc);
+          assocs[i] = assoc;
+          assocTypes[i] = gse->getAssocTypeSourceInfo(i);
+        }
+
+        return new (S.Context) GenericSelectionExpr(S.Context,
+                                                    gse->getGenericLoc(),
+                                                    gse->getControllingExpr(),
+                                                    assocTypes.data(),
+                                                    assocs.data(),
+                                                    numAssocs,
+                                                    gse->getDefaultLoc(),
+                                                    gse->getRParenLoc(),
+                                      gse->containsUnexpandedParameterPack(),
+                                                    resultIndex);
+      }
+
+      llvm_unreachable("bad expression to rebuild!");
+    }
+  };
+
+  struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> {
+    Expr *NewBase;
+    ObjCPropertyRefRebuilder(Sema &S, Expr *newBase)
+      : Rebuilder(S), NewBase(newBase) {}
+
+    typedef ObjCPropertyRefExpr specific_type;
+    Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) {
+      // Fortunately, the constraint that we're rebuilding something
+      // with a base limits the number of cases here.
+      assert(refExpr->getBase());
+
+      if (refExpr->isExplicitProperty()) {
+        return new (S.Context)
+          ObjCPropertyRefExpr(refExpr->getExplicitProperty(),
+                              refExpr->getType(), refExpr->getValueKind(),
+                              refExpr->getObjectKind(), refExpr->getLocation(),
+                              NewBase);
+      }
+      return new (S.Context)
+        ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(),
+                            refExpr->getImplicitPropertySetter(),
+                            refExpr->getType(), refExpr->getValueKind(),
+                            refExpr->getObjectKind(),refExpr->getLocation(),
+                            NewBase);
+    }
+  };
+
+  class PseudoOpBuilder {
+  public:
+    Sema &S;
+    unsigned ResultIndex;
+    SourceLocation GenericLoc;
+    SmallVector<Expr *, 4> Semantics;
+
+    PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
+      : S(S), ResultIndex(PseudoObjectExpr::NoResult),
+        GenericLoc(genericLoc) {}
+
+    /// Add a normal semantic expression.
+    void addSemanticExpr(Expr *semantic) {
+      Semantics.push_back(semantic);
+    }
+
+    /// Add the 'result' semantic expression.
+    void addResultSemanticExpr(Expr *resultExpr) {
+      assert(ResultIndex == PseudoObjectExpr::NoResult);
+      ResultIndex = Semantics.size();
+      Semantics.push_back(resultExpr);
+    }
+
+    ExprResult buildRValueOperation(Expr *op);
+    ExprResult buildAssignmentOperation(Scope *Sc,
+                                        SourceLocation opLoc,
+                                        BinaryOperatorKind opcode,
+                                        Expr *LHS, Expr *RHS);
+    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
+                                    UnaryOperatorKind opcode,
+                                    Expr *op);
+
+    ExprResult complete(Expr *syntacticForm);
+
+    OpaqueValueExpr *capture(Expr *op);
+    OpaqueValueExpr *captureValueAsResult(Expr *op);
+
+    void setResultToLastSemantic() {
+      assert(ResultIndex == PseudoObjectExpr::NoResult);
+      ResultIndex = Semantics.size() - 1;
+    }
+
+    /// Return true if assignments have a non-void result.
+    virtual bool assignmentsHaveResult() { return true; }
+
+    virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
+    virtual ExprResult buildGet() = 0;
+    virtual ExprResult buildSet(Expr *, SourceLocation,
+                                bool captureSetValueAsResult) = 0;
+  };
+
+  /// A PseudoOpBuilder for Objective-C @properties.
+  class ObjCPropertyOpBuilder : public PseudoOpBuilder {
+    ObjCPropertyRefExpr *RefExpr;
+    OpaqueValueExpr *InstanceReceiver;
+    ObjCMethodDecl *Getter;
+
+    ObjCMethodDecl *Setter;
+    Selector SetterSelector;
+
+  public:
+    ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
+      PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
+      InstanceReceiver(0), Getter(0), Setter(0) {
+    }
+
+    ExprResult buildRValueOperation(Expr *op);
+    ExprResult buildAssignmentOperation(Scope *Sc,
+                                        SourceLocation opLoc,
+                                        BinaryOperatorKind opcode,
+                                        Expr *LHS, Expr *RHS);
+    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
+                                    UnaryOperatorKind opcode,
+                                    Expr *op);
+
+    bool tryBuildGetOfReference(Expr *op, ExprResult &result);
+    bool findSetter();
+    bool findGetter();
+
+    Expr *rebuildAndCaptureObject(Expr *syntacticBase);
+    ExprResult buildGet();
+    ExprResult buildSet(Expr *op, SourceLocation, bool);
+  };
+}
+
+/// Capture the given expression in an OpaqueValueExpr.
+OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
+  // Make a new OVE whose source is the given expression.
+  OpaqueValueExpr *captured = 
+    new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
+                                    e->getValueKind());
+  captured->setSourceExpr(e);
+  
+  // Make sure we bind that in the semantics.
+  addSemanticExpr(captured);
+  return captured;
+}
+
+/// Capture the given expression as the result of this pseudo-object
+/// operation.  This routine is safe against expressions which may
+/// already be captured.
+///
+/// \param Returns the captured expression, which will be the
+///   same as the input if the input was already captured
+OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
+  assert(ResultIndex == PseudoObjectExpr::NoResult);
+
+  // If the expression hasn't already been captured, just capture it
+  // and set the new semantic 
+  if (!isa<OpaqueValueExpr>(e)) {
+    OpaqueValueExpr *cap = capture(e);
+    setResultToLastSemantic();
+    return cap;
+  }
+
+  // Otherwise, it must already be one of our semantic expressions;
+  // set ResultIndex to its index.
+  unsigned index = 0;
+  for (;; ++index) {
+    assert(index < Semantics.size() &&
+           "captured expression not found in semantics!");
+    if (e == Semantics[index]) break;
+  }
+  ResultIndex = index;
+  return cast<OpaqueValueExpr>(e);
+}
+
+/// The routine which creates the final PseudoObjectExpr.
+ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
+  return PseudoObjectExpr::Create(S.Context, syntactic,
+                                  Semantics, ResultIndex);
+}
+
+/// The main skeleton for building an r-value operation.
+ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
+  Expr *syntacticBase = rebuildAndCaptureObject(op);
+
+  ExprResult getExpr = buildGet();
+  if (getExpr.isInvalid()) return ExprError();
+  addResultSemanticExpr(getExpr.take());
+
+  return complete(syntacticBase);
+}
+
+/// The basic skeleton for building a simple or compound
+/// assignment operation.
+ExprResult
+PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
+                                          BinaryOperatorKind opcode,
+                                          Expr *LHS, Expr *RHS) {
+  assert(BinaryOperator::isAssignmentOp(opcode));
+
+  Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
+  OpaqueValueExpr *capturedRHS = capture(RHS);
+
+  Expr *syntactic;
+
+  ExprResult result;
+  if (opcode == BO_Assign) {
+    result = capturedRHS;
+    syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
+                                               opcode, capturedRHS->getType(),
+                                               capturedRHS->getValueKind(),
+                                               OK_Ordinary, opcLoc);
+  } else {
+    ExprResult opLHS = buildGet();
+    if (opLHS.isInvalid()) return ExprError();
+
+    // Build an ordinary, non-compound operation.
+    BinaryOperatorKind nonCompound =
+      BinaryOperator::getOpForCompoundAssignment(opcode);
+    result = S.BuildBinOp(Sc, opcLoc, nonCompound,
+                          opLHS.take(), capturedRHS);
+    if (result.isInvalid()) return ExprError();
+
+    syntactic =
+      new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
+                                             result.get()->getType(),
+                                             result.get()->getValueKind(),
+                                             OK_Ordinary,
+                                             opLHS.get()->getType(),
+                                             result.get()->getType(),
+                                             opcLoc);
+  }
+
+  // The result of the assignment, if not void, is the value set into
+  // the l-value.
+  result = buildSet(result.take(), opcLoc, assignmentsHaveResult());
+  if (result.isInvalid()) return ExprError();
+  addSemanticExpr(result.take());
+
+  return complete(syntactic);
+}
+
+/// The basic skeleton for building an increment or decrement
+/// operation.
+ExprResult
+PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
+                                      UnaryOperatorKind opcode,
+                                      Expr *op) {
+  assert(UnaryOperator::isIncrementDecrementOp(opcode));
+
+  Expr *syntacticOp = rebuildAndCaptureObject(op);
+
+  // Load the value.
+  ExprResult result = buildGet();
+  if (result.isInvalid()) return ExprError();
+
+  QualType resultType = result.get()->getType();
+
+  // That's the postfix result.
+  if (UnaryOperator::isPostfix(opcode) && assignmentsHaveResult()) {
+    result = capture(result.take());
+    setResultToLastSemantic();
+  }
+
+  // Add or subtract a literal 1.
+  llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
+  Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
+                                     GenericLoc);
+
+  if (UnaryOperator::isIncrementOp(opcode)) {
+    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
+  } else {
+    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
+  }
+  if (result.isInvalid()) return ExprError();
+
+  // Store that back into the result.  The value stored is the result
+  // of a prefix operation.
+  result = buildSet(result.take(), opcLoc,
+             UnaryOperator::isPrefix(opcode) && assignmentsHaveResult());
+  if (result.isInvalid()) return ExprError();
+  addSemanticExpr(result.take());
+
+  UnaryOperator *syntactic =
+    new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
+                                  VK_LValue, OK_Ordinary, opcLoc);
+  return complete(syntactic);
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Objective-C @property and implicit property references
+//===----------------------------------------------------------------------===//
+
+/// Look up a method in the receiver type of an Objective-C property
+/// reference.
 static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
                                             const ObjCPropertyRefExpr *PRE) {
   if (PRE->isObjectReceiver()) {
     const ObjCObjectPointerType *PT =
       PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
+
+    // Special case for 'self' in class method implementations.
+    if (PT->isObjCClassType() &&
+        S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
+      // This cast is safe because isSelfExpr is only true within
+      // methods.
+      ObjCMethodDecl *method =
+        cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
+      return S.LookupMethodInObjectType(sel,
+                 S.Context.getObjCInterfaceType(method->getClassInterface()),
+                                        /*instance*/ false);
+    }
+
     return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
   }
 
@@ -59,281 +412,374 @@
   return S.LookupMethodInObjectType(sel, IT, false);
 }
 
-ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
-  assert(E->getValueKind() == VK_LValue &&
-         E->getObjectKind() == OK_ObjCProperty);
-  const ObjCPropertyRefExpr *PRE = E->getObjCProperty();
+bool ObjCPropertyOpBuilder::findGetter() {
+  if (Getter) return true;
 
-  QualType ReceiverType;
-  if (PRE->isObjectReceiver())
-    ReceiverType = PRE->getBase()->getType();
-  else if (PRE->isSuperReceiver())
-    ReceiverType = PRE->getSuperReceiverType();
-  else
-    ReceiverType = Context.getObjCInterfaceType(PRE->getClassReceiver());
-    
-  ExprValueKind VK = VK_RValue;
-  QualType T;
-  if (PRE->isImplicitProperty()) {
-    if (ObjCMethodDecl *GetterMethod = 
-          PRE->getImplicitPropertyGetter()) {
-      T = getMessageSendResultType(ReceiverType, GetterMethod,
-                                   PRE->isClassReceiver(), 
-                                   PRE->isSuperReceiver());
-      VK = Expr::getValueKindForType(GetterMethod->getResultType());
+  Getter = LookupMethodInReceiverType(S, RefExpr->getGetterSelector(), RefExpr);
+  return (Getter != 0);
+}
+
+/// Try to find the most accurate setter declaration for the property
+/// reference.
+///
+/// \return true if a setter was found, in which case Setter 
+bool ObjCPropertyOpBuilder::findSetter() {
+  // For implicit properties, just trust the lookup we already did.
+  if (RefExpr->isImplicitProperty()) {
+    if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
+      Setter = setter;
+      SetterSelector = setter->getSelector();
+      return true;
     } else {
-      Diag(PRE->getLocation(), diag::err_getter_not_found)
-            << PRE->getBase()->getType();
-      return ExprError();
+      IdentifierInfo *getterName =
+        RefExpr->getImplicitPropertyGetter()->getSelector()
+          .getIdentifierInfoForSlot(0);
+      SetterSelector =
+        SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
+                                           S.PP.getSelectorTable(),
+                                           getterName);
+      return false;
     }
+  }
+
+  // For explicit properties, this is more involved.
+  ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
+  SetterSelector = prop->getSetterName();
+
+  // Do a normal method lookup first.
+  if (ObjCMethodDecl *setter =
+        LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
+    Setter = setter;
+    return true;
+  }
+
+  // That can fail in the somewhat crazy situation that we're
+  // type-checking a message send within the @interface declaration
+  // that declared the @property.  But it's not clear that that's
+  // valuable to support.
+
+  return false;
+}
+
+/// Capture the base object of an Objective-C property expression.
+Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
+  assert(InstanceReceiver == 0);
+
+  // If we have a base, capture it in an OVE and rebuild the syntactic
+  // form to use the OVE as its base.
+  if (RefExpr->isObjectReceiver()) {
+    InstanceReceiver = capture(RefExpr->getBase());
+
+    syntacticBase =
+      ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
+  }
+
+  return syntacticBase;
+}
+
+/// Load from an Objective-C property reference.
+ExprResult ObjCPropertyOpBuilder::buildGet() {
+  findGetter();
+  assert(Getter);
+  
+  QualType receiverType;
+  SourceLocation superLoc;
+  if (RefExpr->isClassReceiver()) {
+    receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
+  } else if (RefExpr->isSuperReceiver()) {
+    superLoc = RefExpr->getReceiverLocation();
+    receiverType = RefExpr->getSuperReceiverType();
   } else {
-    ObjCPropertyDecl *prop = PRE->getExplicitProperty();
+    assert(InstanceReceiver);
+    receiverType = InstanceReceiver->getType();
+  }
 
-    ObjCMethodDecl *getter =
-      LookupMethodInReceiverType(*this, prop->getGetterName(), PRE);
-    if (getter && !getter->hasRelatedResultType())
-      DiagnosePropertyAccessorMismatch(prop, getter, PRE->getLocation());
-    if (!getter) getter = prop->getGetterMethodDecl();
+  // Build a message-send.
+  ExprResult msg;
+  if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+    assert(InstanceReceiver || RefExpr->isSuperReceiver());
+    msg = S.BuildInstanceMessage(InstanceReceiver, receiverType, superLoc,
+                                 Getter->getSelector(), Getter,
+                                 GenericLoc, GenericLoc, GenericLoc,
+                                 MultiExprArg());
+  } else {
+    TypeSourceInfo *receiverTypeInfo = 0;
+    if (!RefExpr->isSuperReceiver())
+      receiverTypeInfo = S.Context.getTrivialTypeSourceInfo(receiverType);
 
-    // Figure out the type of the expression.  Mostly this is the
-    // result type of the getter, if possible.
-    if (getter) {
-      T = getMessageSendResultType(ReceiverType, getter, 
-                                   PRE->isClassReceiver(), 
-                                   PRE->isSuperReceiver());
-      VK = Expr::getValueKindForType(getter->getResultType());
+    msg = S.BuildClassMessage(receiverTypeInfo, receiverType, superLoc,
+                              Getter->getSelector(), Getter,
+                              GenericLoc, GenericLoc, GenericLoc,
+                              MultiExprArg());
+  }
+  return msg;
+}
 
-      // As a special case, if the method returns 'id', try to get a
-      // better type from the property.
-      if (VK == VK_RValue && T->isObjCIdType() &&
-          prop->getType()->isObjCRetainableType())
-        T = prop->getType();
-    } else {
-      T = prop->getType();
-      VK = Expr::getValueKindForType(T);
-      T = T.getNonLValueExprType(Context);
+/// Store to an Objective-C property reference.
+///
+/// \param bindSetValueAsResult - If true, capture the actual
+///   value being set as the value of the property operation.
+ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
+                                           bool captureSetValueAsResult) {
+  bool hasSetter = findSetter();
+  assert(hasSetter); (void) hasSetter;
+
+  QualType receiverType;
+  SourceLocation superLoc;
+  if (RefExpr->isClassReceiver()) {
+    receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
+  } else if (RefExpr->isSuperReceiver()) {
+    superLoc = RefExpr->getReceiverLocation();
+    receiverType = RefExpr->getSuperReceiverType();
+  } else {
+    assert(InstanceReceiver);
+    receiverType = InstanceReceiver->getType();
+  }
+
+  // Use assignment constraints when possible; they give us better
+  // diagnostics.  "When possible" basically means anything except a
+  // C++ class type.
+  if (!S.getLangOptions().CPlusPlus || !op->getType()->isRecordType()) {
+    QualType paramType = (*Setter->param_begin())->getType();
+    if (!S.getLangOptions().CPlusPlus || !paramType->isRecordType()) {
+      ExprResult opResult = op;
+      Sema::AssignConvertType assignResult
+        = S.CheckSingleAssignmentConstraints(paramType, opResult);
+      if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
+                                     op->getType(), opResult.get(),
+                                     Sema::AA_Assigning))
+        return ExprError();
+
+      op = opResult.take();
+      assert(op && "successful assignment left argument invalid?");
     }
   }
 
-  E->setType(T);
-  E = ImplicitCastExpr::Create(Context, T, CK_GetObjCProperty, E, 0, VK);
-  
-  ExprResult Result = MaybeBindToTemporary(E);
-  if (!Result.isInvalid())
-    E = Result.take();
+  // Arguments.
+  Expr *args[] = { op };
 
-  return Owned(E);
+  // Build a message-send.
+  ExprResult msg;
+  if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+    msg = S.BuildInstanceMessage(InstanceReceiver, receiverType, superLoc,
+                                 SetterSelector, Setter,
+                                 GenericLoc, GenericLoc, GenericLoc,
+                                 MultiExprArg(args, 1));
+  } else {
+    TypeSourceInfo *receiverTypeInfo = 0;
+    if (!RefExpr->isSuperReceiver())
+      receiverTypeInfo = S.Context.getTrivialTypeSourceInfo(receiverType);
+
+    msg = S.BuildClassMessage(receiverTypeInfo, receiverType, superLoc,
+                              SetterSelector, Setter,
+                              GenericLoc, GenericLoc, GenericLoc,
+                              MultiExprArg(args, 1));
+  }
+
+  if (!msg.isInvalid() && captureSetValueAsResult) {
+    ObjCMessageExpr *msgExpr =
+      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
+    Expr *arg = msgExpr->getArg(0);
+    msgExpr->setArg(0, captureValueAsResult(arg));
+  }
+
+  return msg;
 }
 
-namespace {
-  struct PseudoObjectInfo {
-    const ObjCPropertyRefExpr *RefExpr;
-    bool HasSetter;
-    Selector SetterSelector;
-    ParmVarDecl *SetterParam;
-    QualType SetterParamType;
-
-    void setSetter(ObjCMethodDecl *setter) {
-      HasSetter = true;
-      SetterParam = *setter->param_begin();
-      SetterParamType = SetterParam->getType().getUnqualifiedType();
-    }
-
-    PseudoObjectInfo(Sema &S, Expr *E)
-      : RefExpr(E->getObjCProperty()), HasSetter(false), SetterParam(0) {
-
-      assert(E->getValueKind() == VK_LValue &&
-             E->getObjectKind() == OK_ObjCProperty);
-
-      // Try to find a setter.
-
-      // For implicit properties, just trust the lookup we already did.
-      if (RefExpr->isImplicitProperty()) {
-        if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
-          setSetter(setter);
-          SetterSelector = setter->getSelector();
-        } else {
-          IdentifierInfo *getterName =
-            RefExpr->getImplicitPropertyGetter()->getSelector()
-              .getIdentifierInfoForSlot(0);
-          SetterSelector = 
-            SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
-                                               S.PP.getSelectorTable(),
-                                               getterName);
-        }
-        return;
-      }
-
-      // For explicit properties, this is more involved.
-      ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
-      SetterSelector = prop->getSetterName();
-
-      // Do a normal method lookup first.
-      if (ObjCMethodDecl *setter =
-            LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
-        setSetter(setter);
-        return;
-      }
-
-      // If that failed, trust the type on the @property declaration.
-      if (!prop->isReadOnly()) {
-        HasSetter = true;
-        SetterParamType = prop->getType().getUnqualifiedType();
-      }
-    }
-  };
-}
-
-/// Check an increment or decrement of a pseudo-object expression.
-ExprResult Sema::checkPseudoObjectIncDec(Scope *S, SourceLocation opcLoc,
-                                         UnaryOperatorKind opcode, Expr *op) {
-  assert(UnaryOperator::isIncrementDecrementOp(opcode));
-  PseudoObjectInfo info(*this, op);
-
-  // If there's no setter, we have no choice but to try to assign to
-  // the result of the getter.
-  if (!info.HasSetter) {
-    QualType resultType = info.RefExpr->getGetterResultType();
-    assert(!resultType.isNull() && "property has no setter and no getter!");
-
-    // Only do this if the getter returns an l-value reference type.
-    if (const LValueReferenceType *refType
-          = resultType->getAs<LValueReferenceType>()) {
-      op = ImplicitCastExpr::Create(Context, refType->getPointeeType(),
-                                    CK_GetObjCProperty, op, 0, VK_LValue);
-      return BuildUnaryOp(S, opcLoc, opcode, op);
-    }
-
-    // Otherwise, it's an error.
-    Diag(opcLoc, diag::err_nosetter_property_incdec)
-      << unsigned(info.RefExpr->isImplicitProperty())
-      << unsigned(UnaryOperator::isDecrementOp(opcode))
-      << info.SetterSelector
-      << op->getSourceRange();
+/// @property-specific behavior for doing lvalue-to-rvalue conversion.
+ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
+  // Explicit properties always have getters, but implicit ones don't.
+  // Check that before proceeding.
+  if (RefExpr->isImplicitProperty() &&
+      !RefExpr->getImplicitPropertyGetter()) {
+    S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
+      << RefExpr->getBase()->getType();
     return ExprError();
   }
 
-  // ++/-- behave like compound assignments, i.e. they need a getter.
-  QualType getterResultType = info.RefExpr->getGetterResultType();
-  if (getterResultType.isNull()) {
-    assert(info.RefExpr->isImplicitProperty());
-    Diag(opcLoc, diag::err_nogetter_property_incdec)
-      << unsigned(UnaryOperator::isDecrementOp(opcode))
-      << info.RefExpr->getImplicitPropertyGetter()->getSelector()
-      << op->getSourceRange();
-    return ExprError();
-  }
-
-  // HACK: change the type of the operand to prevent further placeholder
-  // transformation.
-  op->setType(getterResultType.getNonLValueExprType(Context));
-  op->setObjectKind(OK_Ordinary);
-  
-  ExprResult result = CreateBuiltinUnaryOp(opcLoc, opcode, op);
+  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
   if (result.isInvalid()) return ExprError();
 
-  // Change the object kind back.
-  op->setObjectKind(OK_ObjCProperty);
+  if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
+    S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
+                                       Getter, RefExpr->getLocation());
+
+  // As a special case, if the method returns 'id', try to get
+  // a better type from the property.
+  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
+      result.get()->getType()->isObjCIdType()) {
+    QualType propType = RefExpr->getExplicitProperty()->getType();
+    if (const ObjCObjectPointerType *ptr
+          = propType->getAs<ObjCObjectPointerType>()) {
+      if (!ptr->isObjCIdType())
+        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+    }
+  }
+
   return result;
 }
 
-ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
-                                             BinaryOperatorKind opcode,
-                                             Expr *LHS, Expr *RHS) {
+/// Try to build this as a call to a getter that returns a reference.
+///
+/// \return true if it was possible, whether or not it actually
+///   succeeded
+bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
+                                                   ExprResult &result) {
+  if (!S.getLangOptions().CPlusPlus) return false;
+
+  findGetter();
+  assert(Getter && "property has no setter and no getter!");
+
+  // Only do this if the getter returns an l-value reference type.
+  QualType resultType = Getter->getResultType();
+  if (!resultType->isLValueReferenceType()) return false;
+
+  result = buildRValueOperation(op);
+  return true;
+}
+
+/// @property-specific behavior for doing assignments.
+ExprResult
+ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
+                                                SourceLocation opcLoc,
+                                                BinaryOperatorKind opcode,
+                                                Expr *LHS, Expr *RHS) {
   assert(BinaryOperator::isAssignmentOp(opcode));
-  PseudoObjectInfo info(*this, LHS);
 
   // If there's no setter, we have no choice but to try to assign to
   // the result of the getter.
-  if (!info.HasSetter) {
-    QualType resultType = info.RefExpr->getGetterResultType();
-    assert(!resultType.isNull() && "property has no setter and no getter!");
-
-    // Only do this if the getter returns an l-value reference type.
-    if (const LValueReferenceType *refType
-          = resultType->getAs<LValueReferenceType>()) {
-      LHS = ImplicitCastExpr::Create(Context, refType->getPointeeType(),
-                                     CK_GetObjCProperty, LHS, 0, VK_LValue);
-      return BuildBinOp(S, opcLoc, opcode, LHS, RHS);
+  if (!findSetter()) {
+    ExprResult result;
+    if (tryBuildGetOfReference(LHS, result)) {
+      if (result.isInvalid()) return ExprError();
+      return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
     }
 
     // Otherwise, it's an error.
-    Diag(opcLoc, diag::err_nosetter_property_assignment)
-      << unsigned(info.RefExpr->isImplicitProperty())
-      << info.SetterSelector
+    S.Diag(opcLoc, diag::err_nosetter_property_assignment)
+      << unsigned(RefExpr->isImplicitProperty())
+      << SetterSelector
       << LHS->getSourceRange() << RHS->getSourceRange();
     return ExprError();
   }
 
   // If there is a setter, we definitely want to use it.
 
-  // If this is a simple assignment, just initialize the parameter
-  // with the RHS.
-  if (opcode == BO_Assign) {
-    LHS->setType(info.SetterParamType.getNonLValueExprType(Context));
-
-    // Under certain circumstances, we need to type-check the RHS as a
-    // straight-up parameter initialization.  This gives somewhat
-    // inferior diagnostics, so we try to avoid it.
-
-    if (RHS->isTypeDependent()) {
-      // Just build the expression.
-
-    } else if ((getLangOptions().CPlusPlus && LHS->getType()->isRecordType()) ||
-               (getLangOptions().ObjCAutoRefCount &&
-                info.SetterParam &&
-                info.SetterParam->hasAttr<NSConsumedAttr>())) {
-      InitializedEntity param = (info.SetterParam
-        ? InitializedEntity::InitializeParameter(Context, info.SetterParam)
-        : InitializedEntity::InitializeParameter(Context, info.SetterParamType,
-                                                 /*consumed*/ false));
-      ExprResult arg = PerformCopyInitialization(param, opcLoc, RHS);
-      if (arg.isInvalid()) return ExprError();
-      RHS = arg.take();
-
-      // Warn about assignments of +1 objects to unsafe pointers in ARC.
-      // CheckAssignmentOperands does this on the other path.
-      if (getLangOptions().ObjCAutoRefCount)
-        checkUnsafeExprAssigns(opcLoc, LHS, RHS);
-    } else {
-      ExprResult RHSResult = Owned(RHS);
-
-      LHS->setObjectKind(OK_Ordinary);
-      QualType resultType = CheckAssignmentOperands(LHS, RHSResult, opcLoc,
-                                                    /*compound*/ QualType());
-      LHS->setObjectKind(OK_ObjCProperty);
-
-      if (!RHSResult.isInvalid()) RHS = RHSResult.take();
-      if (resultType.isNull()) return ExprError();
-    }
-
-    // Warn about property sets in ARC that might cause retain cycles.
-    if (getLangOptions().ObjCAutoRefCount && !info.RefExpr->isSuperReceiver())
-      checkRetainCycles(const_cast<Expr*>(info.RefExpr->getBase()), RHS);
-
-    return new (Context) BinaryOperator(LHS, RHS, opcode, RHS->getType(),
-                                        RHS->getValueKind(),
-                                        RHS->getObjectKind(),
-                                        opcLoc);
-  }
-
-  // If this is a compound assignment, we need to use the getter, too.
-  QualType getterResultType = info.RefExpr->getGetterResultType();
-  if (getterResultType.isNull()) {
-    Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
+  // Verify that we can do a compound assignment.
+  if (opcode != BO_Assign && !findGetter()) {
+    S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
       << LHS->getSourceRange() << RHS->getSourceRange();
     return ExprError();
   }
 
-  // HACK: change the type of the LHS to prevent further placeholder
-  // transformation.
-  LHS->setType(getterResultType.getNonLValueExprType(Context));
-  LHS->setObjectKind(OK_Ordinary);
-  
-  ExprResult result = CreateBuiltinBinOp(opcLoc, opcode, LHS, RHS);
+  ExprResult result =
+    PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
   if (result.isInvalid()) return ExprError();
 
-  // Change the object kind back.
-  LHS->setObjectKind(OK_ObjCProperty);
+  // Various warnings about property assignments in ARC.
+  if (S.getLangOptions().ObjCAutoRefCount && InstanceReceiver) {
+    S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
+    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
+  }
+
   return result;
 }
+
+/// @property-specific behavior for doing increments and decrements.
+ExprResult
+ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
+                                            UnaryOperatorKind opcode,
+                                            Expr *op) {
+  // If there's no setter, we have no choice but to try to assign to
+  // the result of the getter.
+  if (!findSetter()) {
+    ExprResult result;
+    if (tryBuildGetOfReference(op, result)) {
+      if (result.isInvalid()) return ExprError();
+      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
+    }
+
+    // Otherwise, it's an error.
+    S.Diag(opcLoc, diag::err_nosetter_property_incdec)
+      << unsigned(RefExpr->isImplicitProperty())
+      << unsigned(UnaryOperator::isDecrementOp(opcode))
+      << SetterSelector
+      << op->getSourceRange();
+    return ExprError();
+  }
+
+  // If there is a setter, we definitely want to use it.
+
+  // We also need a getter.
+  if (!findGetter()) {
+    assert(RefExpr->isImplicitProperty());
+    S.Diag(opcLoc, diag::err_nogetter_property_incdec)
+      << unsigned(UnaryOperator::isDecrementOp(opcode))
+      << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME!
+      << op->getSourceRange();
+    return ExprError();
+  }
+
+  return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
+}
+
+//===----------------------------------------------------------------------===//
+//  General Sema routines.
+//===----------------------------------------------------------------------===//
+
+ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
+  Expr *opaqueRef = E->IgnoreParens();
+  if (ObjCPropertyRefExpr *refExpr
+        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
+    ObjCPropertyOpBuilder builder(*this, refExpr);
+    return builder.buildRValueOperation(E);
+  } else {
+    llvm_unreachable("unknown pseudo-object kind!");
+  }
+}
+
+/// Check an increment or decrement of a pseudo-object expression.
+ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
+                                         UnaryOperatorKind opcode, Expr *op) {
+  // Do nothing if the operand is dependent.
+  if (op->isTypeDependent())
+    return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
+                                       VK_RValue, OK_Ordinary, opcLoc);
+
+  assert(UnaryOperator::isIncrementDecrementOp(opcode));
+  Expr *opaqueRef = op->IgnoreParens();
+  if (ObjCPropertyRefExpr *refExpr
+        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
+    ObjCPropertyOpBuilder builder(*this, refExpr);
+    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
+  } else {
+    llvm_unreachable("unknown pseudo-object kind!");
+  }
+}
+
+ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
+                                             BinaryOperatorKind opcode,
+                                             Expr *LHS, Expr *RHS) {
+  // Do nothing if either argument is dependent.
+  if (LHS->isTypeDependent() || RHS->isTypeDependent())
+    return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
+                                        VK_RValue, OK_Ordinary, opcLoc);
+
+  // Filter out non-overload placeholder types in the RHS.
+  if (const BuiltinType *PTy = RHS->getType()->getAsPlaceholderType()) {
+    if (PTy->getKind() != BuiltinType::Overload) {
+      ExprResult result = CheckPlaceholderExpr(RHS);
+      if (result.isInvalid()) return ExprError();
+      RHS = result.take();
+    }
+  }
+
+  Expr *opaqueRef = LHS->IgnoreParens();
+  if (ObjCPropertyRefExpr *refExpr
+        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
+    ObjCPropertyOpBuilder builder(*this, refExpr);
+    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
+  } else {
+    llvm_unreachable("unknown pseudo-object kind!");
+  }
+}
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 8c99e8a..a34d838 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -198,7 +198,7 @@
       Diag(Loc, diag::warn_unused_result) << R1 << R2;
       return;
     }
-  } else if (isa<ObjCPropertyRefExpr>(E)) {
+  } else if (isa<PseudoObjectExpr>(E)) {
     DiagID = diag::warn_unused_property_expr;
   } else if (const CXXFunctionalCastExpr *FC
                                        = dyn_cast<CXXFunctionalCastExpr>(E)) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 5596a9a..f55e2a7 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -6103,6 +6103,22 @@
 
 template<typename Derived>
 ExprResult
+TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
+  // Rebuild the syntactic form.
+  ExprResult result = getDerived().TransformExpr(E->getSyntacticForm());
+  if (result.isInvalid()) return ExprError();
+
+  // If that gives us a pseudo-object result back, the pseudo-object
+  // expression must have been an lvalue-to-rvalue conversion which we
+  // should reapply.
+  if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
+    result = SemaRef.checkPseudoObjectRValue(result.take());
+
+  return result;
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
                                                 UnaryExprOrTypeTraitExpr *E) {
   if (E->isArgumentType()) {
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index e57ab19..ff306b0 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -775,6 +775,24 @@
   E->RParenLoc = ReadSourceLocation(Record, Idx);
 }
 
+void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+  VisitExpr(E);
+  unsigned numSemanticExprs = Record[Idx++];
+  assert(numSemanticExprs + 1 == E->PseudoObjectExprBits.NumSubExprs);
+  E->PseudoObjectExprBits.ResultIndex = Record[Idx++];
+
+  // Read the syntactic expression.
+  E->getSubExprsBuffer()[0] = Reader.ReadSubExpr();
+
+  // Read all the semantic expressions.
+  for (unsigned i = 0; i != numSemanticExprs; ++i) {
+    Expr *subExpr = Reader.ReadSubExpr();
+    if (isa<OpaqueValueExpr>(subExpr))
+      cast<OpaqueValueExpr>(subExpr)->setSourceExpr(Reader.ReadSubExpr());
+    E->getSubExprsBuffer()[i+1] = subExpr;
+  }
+}
+
 void ASTStmtReader::VisitAtomicExpr(AtomicExpr *E) {
   VisitExpr(E);
   E->setOp(AtomicExpr::AtomicOp(Record[Idx++]));
@@ -2059,6 +2077,12 @@
       S = new (Context) AsTypeExpr(Empty);
       break;
 
+    case EXPR_PSEUDO_OBJECT: {
+      unsigned numSemanticExprs = Record[ASTStmtReader::NumExprFields];
+      S = PseudoObjectExpr::Create(Context, Empty, numSemanticExprs);
+      break;
+    }
+
     case EXPR_ATOMIC:
       S = new (Context) AtomicExpr(Empty);
       break;
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 61570a8..a8c76b5 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -736,6 +736,25 @@
   Code = serialization::EXPR_GENERIC_SELECTION;
 }
 
+void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSemanticExprs());
+
+  // Push the result index.  Currently, this needs to exactly match
+  // the encoding used internally for ResultIndex.
+  unsigned result = E->getResultExprIndex();
+  result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
+  Record.push_back(result);
+
+  Writer.AddStmt(E->getSyntacticForm());
+  for (PseudoObjectExpr::semantics_iterator
+         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
+    Writer.AddStmt(*i);
+    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
+      Writer.AddStmt(OVE->getSourceExpr());
+  }
+}
+
 void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getOp());
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 471936c8..32cfa84 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -857,6 +857,21 @@
       Bldr.addNodes(Dst);
       break;
     }
+
+    case Stmt::PseudoObjectExprClass: {
+      Bldr.takeNodes(Pred);
+      const ProgramState *state = Pred->getState();
+      const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
+      if (const Expr *Result = PE->getResultExpr()) { 
+        SVal V = state->getSVal(Result);
+        Bldr.generateNode(S, Pred, state->BindExpr(S, V));
+      }
+      else
+        Bldr.generateNode(S, Pred, state->BindExpr(S, UnknownVal()));
+
+      Bldr.addNodes(Dst);
+      break;
+    }
   }
 }
 
