Remove CXXRecordDecl flags which are unused after r158289.

We need an efficient mechanism to determine whether a defaulted default
constructor is constexpr, in order to determine whether a class is a literal
type, so keep the incrementally-built form on CXXRecordDecl. Remove the
on-demand computation of same, so that we only have one method for determining
whether a default constructor is constexpr. This doesn't affect correctness,
since default constructor lookup is much simpler than selecting a constructor
for copying or moving.

We don't need a corresponding mechanism for defaulted copy or move constructors,
since they can't affect whether a type is a literal type. Conversely, checking
whether such functions are constexpr can require non-trivial effort, so we defer
such checks until the copy or move constructor is required.

Thus we now only compute whether a copy or move constructor is constexpr on
demand, and only compute whether a default constructor is constexpr in advance.
This is unfortunate, but seems like the best solution.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158290 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 648c082..4bd1c32 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3897,8 +3897,17 @@
   // In the definition of a constexpr constructor [...]
   switch (CSM) {
   case Sema::CXXDefaultConstructor:
+    // Since default constructor lookup is essentially trivial (and cannot
+    // involve, for instance, template instantiation), we compute whether a
+    // defaulted default constructor is constexpr directly within CXXRecordDecl.
+    //
+    // This is important for performance; we need to know whether the default
+    // constructor is constexpr to determine whether the type is a literal type.
+    return ClassDecl->defaultedDefaultConstructorIsConstexpr();
+
   case Sema::CXXCopyConstructor:
   case Sema::CXXMoveConstructor:
+    // For copy or move constructors, we need to perform overload resolution.
     break;
 
   case Sema::CXXCopyAssignment:
@@ -3911,11 +3920,12 @@
   //   -- if the class is a non-empty union, or for each non-empty anonymous
   //      union member of a non-union class, exactly one non-static data member
   //      shall be initialized; [DR1359]
+  //
+  // If we squint, this is guaranteed, since exactly one non-static data member
+  // will be initialized (if the constructor isn't deleted), we just don't know
+  // which one.
   if (ClassDecl->isUnion())
-    // FIXME: In the default constructor case, we should check that the
-    // in-class initializer is actually a constant expression.
-    return CSM != Sema::CXXDefaultConstructor ||
-           ClassDecl->hasInClassInitializer();
+    return true;
 
   //   -- the class shall not have any virtual base classes;
   if (ClassDecl->getNumVBases())
@@ -3943,29 +3953,11 @@
        F != FEnd; ++F) {
     if (F->isInvalidDecl())
       continue;
-    if (CSM == Sema::CXXDefaultConstructor && F->hasInClassInitializer()) {
-      // -- every assignment-expression that is an initializer-clause appearing
-      //    directly or indirectly within a brace-or-equal-initializer for a
-      //    non-static data member [...] shall be a constant expression;
-      //
-      // We consider this bullet to be a defect, since it results in this type
-      // having a non-constexpr default constructor:
-      //   struct S {
-      //     int a = 0;
-      //     int b = a;
-      //   };
-      // FIXME: We should still check that the constructor selected for this
-      // initialization (if any) is constexpr.
-    } else if (const RecordType *RecordTy =
-                   S.Context.getBaseElementType(F->getType())->
-                       getAs<RecordType>()) {
+    if (const RecordType *RecordTy =
+            S.Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
       if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM, ConstArg))
         return false;
-    } else if (CSM == Sema::CXXDefaultConstructor) {
-      // No in-class initializer, and not a class type. This member isn't going
-      // to be initialized.
-      return false;
     }
   }