one piece of code is responsible for the lifetime of every aggregate
slot.  The easiest way to do that was to bundle up the information
we care about for aggregate slots into a new structure which demands
that its creators at least consider the question.

I could probably be convinced that the ObjC 'needs GC' bit should
be rolled into this structure.
Implement generalized copy elision.  The main obstacle here is that
IR-generation must be much more careful about making sure that exactly



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113962 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index c9dae17..4e65b9c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1648,46 +1648,31 @@
   return E;
 }
 
-const Expr *Expr::getTemporaryObject() const {
+/// isTemporaryObject - Determines if this expression produces a
+/// temporary of the given class type.
+bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
+  if (!C.hasSameUnqualifiedType(getType(), C.getTypeDeclType(TempTy)))
+    return false;
+
   const Expr *E = skipTemporaryBindingsAndNoOpCasts(this);
 
-  // A cast can produce a temporary object. The object's construction
-  // is represented as a CXXConstructExpr.
-  if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
-    // Only user-defined and constructor conversions can produce
-    // temporary objects.
-    if (Cast->getCastKind() != CK_ConstructorConversion &&
-        Cast->getCastKind() != CK_UserDefinedConversion)
-      return 0;
+  // pr-values of class type are always temporaries.
+  if (!E->Classify(C).isPRValue()) return false;
 
-    // Strip off temporary bindings and no-op casts.
-    const Expr *Sub = skipTemporaryBindingsAndNoOpCasts(Cast->getSubExpr());
-
-    // If this is a constructor conversion, see if we have an object
-    // construction.
-    if (Cast->getCastKind() == CK_ConstructorConversion)
-      return dyn_cast<CXXConstructExpr>(Sub);
-
-    // If this is a user-defined conversion, see if we have a call to
-    // a function that itself returns a temporary object.
-    if (Cast->getCastKind() == CK_UserDefinedConversion)
-      if (const CallExpr *CE = dyn_cast<CallExpr>(Sub))
-        if (CE->getCallReturnType()->isRecordType())
-          return CE;
-
-    return 0;
+  // Black-list implicit derived-to-base conversions, which are the
+  // only way we can get a pr-value of class type that doesn't refer
+  // to a temporary of that type.
+  if (isa<ImplicitCastExpr>(E)) {
+    switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
+    case CK_DerivedToBase:
+    case CK_UncheckedDerivedToBase:
+      return false;
+    default:
+      break;
+    }
   }
 
-  // A call returning a class type returns a temporary.
-  if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
-    if (CE->getCallReturnType()->isRecordType())
-      return CE;
-
-    return 0;
-  }
-
-  // Explicit temporary object constructors create temporaries.
-  return dyn_cast<CXXTemporaryObjectExpr>(E);
+  return true;
 }
 
 /// hasAnyTypeDependentArguments - Determines if any of the expressions