Extract a common structure for holding information about the definition
of a C++ record.  Exposed a lot of problems where various routines were
silently doing The Wrong Thing (or The Acceptable Thing in The Wrong Order)
when presented with a non-definition.  Also cuts down on memory usage.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95330 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 850308e..9033137 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -72,18 +72,17 @@
       if (const RecordType *RecordT = T->getAs<RecordType>()) {
         CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
         // C++ [expr.typeid]p3:
+        //   [...] If the type of the expression is a class type, the class
+        //   shall be completely-defined.
+        if (RequireCompleteType(OpLoc, T, diag::err_incomplete_typeid))
+          return ExprError();
+
+        // C++ [expr.typeid]p3:
         //   When typeid is applied to an expression other than an lvalue of a
         //   polymorphic class type [...] [the] expression is an unevaluated
         //   operand. [...]
         if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid)
           isUnevaluatedOperand = false;
-        else {
-          // C++ [expr.typeid]p3:
-          //   [...] If the type of the expression is a class type, the class
-          //   shall be completely-defined.
-          if (RequireCompleteType(OpLoc, T, diag::err_incomplete_typeid))
-            return ExprError();
-        }
       }
 
       // C++ [expr.typeid]p4:
@@ -1985,10 +1984,8 @@
   if (!RT)
     return Owned(E);
 
-  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  if (RD->hasTrivialDestructor())
-    return Owned(E);
-
+  // If this is the result of a call expression, our source might
+  // actually be a reference, in which case we shouldn't bind.
   if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
     QualType Ty = CE->getCallee()->getType();
     if (const PointerType *PT = Ty->getAs<PointerType>())
@@ -1998,6 +1995,13 @@
     if (FTy->getResultType()->isReferenceType())
       return Owned(E);
   }
+
+  // That should be enough to guarantee that this type is complete.
+  // If it has a trivial destructor, we can avoid the extra copy.
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (RD->hasTrivialDestructor())
+    return Owned(E);
+
   CXXTemporary *Temp = CXXTemporary::Create(Context,
                                             RD->getDestructor(Context));
   ExprTemporaries.push_back(Temp);