Improve our handling of reference binding for subobjects of
temporaries. There are actually several interrelated fixes here:

  - When converting an object to a base class, it's only an lvalue
  cast when the original object was an lvalue and we aren't casting
  pointer-to-derived to pointer-to-base. Previously, we were
  misclassifying derived-to-base casts of class rvalues as lvalues,
  causing various oddities (including problems with reference binding
  not extending the lifetimes of some temporaries).

  - Teach the code for emitting a reference binding how to look
  through no-op casts and parentheses directly, since
  Expr::IgnoreParenNoOpCasts is just plain wrong for this. Also, make
  sure that we properly look through multiple levels of indirection
  from the temporary object, but destroy the actual temporary object;
  this fixes the reference-binding issue mentioned above.

  - Teach Objective-C message sends to bind the result as a temporary
    when needed. This is actually John's change, but it triggered the
    reference-binding problem above, so it's included here. Now John
    can actually test his return-slot improvements.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104434 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 74e64e5..17d85dc 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -211,9 +211,15 @@
     
     llvm::SmallVector<SubobjectAdjustment, 2> Adjustments;
     do {
-      if (const CastExpr *CE 
-                 = dyn_cast<CastExpr>(E->IgnoreParenNoopCasts(getContext()))) {
-        if (CE->getCastKind() == CastExpr::CK_DerivedToBase) {
+      if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+        E = PE->getSubExpr();
+        continue;
+      } 
+
+      if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+        if ((CE->getCastKind() == CastExpr::CK_DerivedToBase ||
+             CE->getCastKind() == CastExpr::CK_UncheckedDerivedToBase) &&
+            E->getType()->isRecordType()) {
           E = CE->getSubExpr();
           CXXRecordDecl *Derived 
             = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
@@ -221,9 +227,12 @@
                                                     Derived));
           continue;
         }
-      } else if (const MemberExpr *ME
-                      = dyn_cast<MemberExpr>(
-                                       E->IgnoreParenNoopCasts(getContext()))) {
+
+        if (CE->getCastKind() == CastExpr::CK_NoOp) {
+          E = CE->getSubExpr();
+          continue;
+        }
+      } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
         if (ME->getBase()->isLvalue(getContext()) != Expr::LV_Valid &&
             ME->getBase()->getType()->isRecordType()) {
           if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
@@ -234,7 +243,10 @@
           }
         }
       }
-    } while (false);
+
+      // Nothing changed.
+      break;
+    } while (true);
       
     Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
                             IsInitializer);