commit be0526987e99fa60466e663a4fa1a0ed51b74bea
Author: Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
Date:   Tue Oct 2 18:52:12 2012 -0400

    Remove SubobjectAdjustment

diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 9e17261..d2ee0d2 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -156,50 +156,6 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
   }
 }
 
-namespace {
-/// \brief An adjustment to be made to the temporary created when emitting a
-/// reference binding, which accesses a particular subobject of that temporary.
-  struct SubobjectAdjustment {
-    enum {
-      DerivedToBaseAdjustment,
-      FieldAdjustment,
-      MemberPointerAdjustment
-    } Kind;
-
-    union {
-      struct {
-        const CastExpr *BasePath;
-        const CXXRecordDecl *DerivedClass;
-      } DerivedToBase;
-
-      FieldDecl *Field;
-
-      struct {
-        const MemberPointerType *MPT;
-        llvm::Value *Ptr;
-      } Ptr;
-    };
-
-    SubobjectAdjustment(const CastExpr *BasePath,
-                        const CXXRecordDecl *DerivedClass)
-      : Kind(DerivedToBaseAdjustment) {
-      DerivedToBase.BasePath = BasePath;
-      DerivedToBase.DerivedClass = DerivedClass;
-    }
-
-    SubobjectAdjustment(FieldDecl *Field)
-      : Kind(FieldAdjustment) {
-      this->Field = Field;
-    }
-
-    SubobjectAdjustment(const MemberPointerType *MPT, llvm::Value *Ptr)
-      : Kind(MemberPointerAdjustment) {
-      this->Ptr.MPT = MPT;
-      this->Ptr.Ptr = Ptr;
-    }
-  };
-}
-
 static llvm::Value *
 CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type,
                          const NamedDecl *InitializedDecl) {
@@ -336,7 +292,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
       return ReferenceTemporary;
     }
     
-    SmallVector<SubobjectAdjustment, 2> Adjustments;
+    SmallVector<const Expr *, 2> Adjustments;
     while (true) {
       E = E->IgnoreParens();
 
@@ -345,9 +301,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
              CE->getCastKind() == CK_UncheckedDerivedToBase) &&
             E->getType()->isRecordType()) {
           E = CE->getSubExpr();
-          CXXRecordDecl *Derived 
-            = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
-          Adjustments.push_back(SubobjectAdjustment(CE, Derived));
+          Adjustments.push_back(CE);
           continue;
         }
 
@@ -358,9 +312,9 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
       } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
         if (!ME->isArrow() && ME->getBase()->isRValue()) {
           assert(ME->getBase()->getType()->isRecordType());
-          if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+          if (isa<FieldDecl>(ME->getMemberDecl())) {
             E = ME->getBase();
-            Adjustments.push_back(SubobjectAdjustment(Field));
+            Adjustments.push_back(ME);
             continue;
           }
         }
@@ -368,10 +322,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
         if (BO->isPtrMemOp()) {
           assert(BO->getLHS()->isRValue());
           E = BO->getLHS();
-          const MemberPointerType *MPT =
-              BO->getRHS()->getType()->getAs<MemberPointerType>();
-          llvm::Value *Ptr = CGF.EmitScalarExpr(BO->getRHS());
-          Adjustments.push_back(SubobjectAdjustment(MPT, Ptr));
+          Adjustments.push_back(BO);
         }
       }
 
@@ -415,41 +366,38 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
     if (!Adjustments.empty()) {
       llvm::Value *Object = RV.getAggregateAddr();
       for (unsigned I = Adjustments.size(); I != 0; --I) {
-        SubobjectAdjustment &Adjustment = Adjustments[I-1];
-        switch (Adjustment.Kind) {
-        case SubobjectAdjustment::DerivedToBaseAdjustment:
-          Object = 
-              CGF.GetAddressOfBaseClass(Object, 
-                                        Adjustment.DerivedToBase.DerivedClass, 
-                              Adjustment.DerivedToBase.BasePath->path_begin(),
-                              Adjustment.DerivedToBase.BasePath->path_end(),
-                                        /*NullCheckValue=*/false);
-          break;
-            
-        case SubobjectAdjustment::FieldAdjustment: {
+        const Expr *E = Adjustments[I-1];
+        if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+          const Expr *Sub = CE->getSubExpr();
+          const Decl *D = Sub->getType()->getAs<RecordType>()->getDecl();
+          const CXXRecordDecl *Derived = cast<CXXRecordDecl>(D);
+          Object = CGF.GetAddressOfBaseClass(Object, Derived,
+                                             CE->path_begin(),
+                                             CE->path_end(),
+                                             /*NullCheckValue=*/false);
+        } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+          FieldDecl *Field = cast<FieldDecl>(ME->getMemberDecl());
+
+
           LValue LV = CGF.MakeAddrLValue(Object, E->getType());
-          LV = CGF.EmitLValueForField(LV, Adjustment.Field);
+          LV = CGF.EmitLValueForField(LV, Field);
           if (LV.isSimple()) {
             Object = LV.getAddress();
-            break;
+          } else {
+            // For non-simple lvalues, we actually have to create a copy of
+            // the object we're binding to.
+            QualType T = Field->getType().getNonReferenceType()
+              .getUnqualifiedType();
+            Object = CreateReferenceTemporary(CGF, T, InitializedDecl);
+            LValue TempLV = CGF.MakeAddrLValue(Object, Field->getType());
+            CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV), TempLV);
           }
-          
-          // For non-simple lvalues, we actually have to create a copy of
-          // the object we're binding to.
-          QualType T = Adjustment.Field->getType().getNonReferenceType()
-                                                  .getUnqualifiedType();
-          Object = CreateReferenceTemporary(CGF, T, InitializedDecl);
-          LValue TempLV = CGF.MakeAddrLValue(Object,
-                                             Adjustment.Field->getType());
-          CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV), TempLV);
-          break;
-        }
-
-        case SubobjectAdjustment::MemberPointerAdjustment: {
+        } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+          const MemberPointerType *MPT =
+            BO->getRHS()->getType()->getAs<MemberPointerType>();
+          llvm::Value *Ptr = CGF.EmitScalarExpr(BO->getRHS());
           Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress(
-                        CGF, Object, Adjustment.Ptr.Ptr, Adjustment.Ptr.MPT);
-          break;
-        }
+                        CGF, Object, Ptr, MPT);
         }
       }
 
