[cfe-commits] r158290 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/ASTImporter.cpp lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Jun 10 00:07:24 PDT 2012


Author: rsmith
Date: Sun Jun 10 02:07:24 2012
New Revision: 158290

URL: http://llvm.org/viewvc/llvm-project?rev=158290&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sun Jun 10 02:07:24 2012
@@ -385,26 +385,10 @@
     /// constructor for this class would be constexpr.
     bool DefaultedDefaultConstructorIsConstexpr : 1;
 
-    /// DefaultedCopyConstructorIsConstexpr - True if a defaulted copy
-    /// constructor for this class would be constexpr.
-    bool DefaultedCopyConstructorIsConstexpr : 1;
-
-    /// DefaultedMoveConstructorIsConstexpr - True if a defaulted move
-    /// constructor for this class would be constexpr.
-    bool DefaultedMoveConstructorIsConstexpr : 1;
-
     /// HasConstexprDefaultConstructor - True if this class has a constexpr
     /// default constructor (either user-declared or implicitly declared).
     bool HasConstexprDefaultConstructor : 1;
 
-    /// HasConstexprCopyConstructor - True if this class has a constexpr copy
-    /// constructor (either user-declared or implicitly declared).
-    bool HasConstexprCopyConstructor : 1;
-
-    /// HasConstexprMoveConstructor - True if this class has a constexpr move
-    /// constructor (either user-declared or implicitly declared).
-    bool HasConstexprMoveConstructor : 1;
-
     /// HasTrivialCopyConstructor - True when this class has a trivial copy
     /// constructor.
     ///
@@ -1105,18 +1089,6 @@
            (!isUnion() || hasInClassInitializer());
   }
 
-  /// defaultedCopyConstructorIsConstexpr - Whether a defaulted copy
-  /// constructor for this class would be constexpr.
-  bool defaultedCopyConstructorIsConstexpr() const {
-    return data().DefaultedCopyConstructorIsConstexpr;
-  }
-
-  /// defaultedMoveConstructorIsConstexpr - Whether a defaulted move
-  /// constructor for this class would be constexpr.
-  bool defaultedMoveConstructorIsConstexpr() const {
-    return data().DefaultedMoveConstructorIsConstexpr;
-  }
-
   /// hasConstexprDefaultConstructor - Whether this class has a constexpr
   /// default constructor.
   bool hasConstexprDefaultConstructor() const {
@@ -1125,22 +1097,6 @@
             defaultedDefaultConstructorIsConstexpr());
   }
 
-  /// hasConstexprCopyConstructor - Whether this class has a constexpr copy
-  /// constructor.
-  bool hasConstexprCopyConstructor() const {
-    return data().HasConstexprCopyConstructor ||
-           (!data().DeclaredCopyConstructor &&
-            data().DefaultedCopyConstructorIsConstexpr);
-  }
-
-  /// hasConstexprMoveConstructor - Whether this class has a constexpr move
-  /// constructor.
-  bool hasConstexprMoveConstructor() const {
-    return data().HasConstexprMoveConstructor ||
-           (needsImplicitMoveConstructor() &&
-            data().DefaultedMoveConstructorIsConstexpr);
-  }
-
   // hasTrivialCopyConstructor - Whether this class has a trivial copy
   // constructor (C++ [class.copy]p6, C++0x [class.copy]p13)
   bool hasTrivialCopyConstructor() const {

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Jun 10 02:07:24 2012
@@ -1858,14 +1858,8 @@
       = FromData.HasConstexprNonCopyMoveConstructor;
     ToData.DefaultedDefaultConstructorIsConstexpr
       = FromData.DefaultedDefaultConstructorIsConstexpr;
-    ToData.DefaultedCopyConstructorIsConstexpr
-      = FromData.DefaultedCopyConstructorIsConstexpr;
-    ToData.DefaultedMoveConstructorIsConstexpr
-      = FromData.DefaultedMoveConstructorIsConstexpr;
     ToData.HasConstexprDefaultConstructor
       = FromData.HasConstexprDefaultConstructor;
-    ToData.HasConstexprCopyConstructor = FromData.HasConstexprCopyConstructor;
-    ToData.HasConstexprMoveConstructor = FromData.HasConstexprMoveConstructor;
     ToData.HasTrivialCopyConstructor = FromData.HasTrivialCopyConstructor;
     ToData.HasTrivialMoveConstructor = FromData.HasTrivialMoveConstructor;
     ToData.HasTrivialCopyAssignment = FromData.HasTrivialCopyAssignment;

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sun Jun 10 02:07:24 2012
@@ -47,10 +47,7 @@
     HasTrivialDefaultConstructor(true),
     HasConstexprNonCopyMoveConstructor(false),
     DefaultedDefaultConstructorIsConstexpr(true),
-    DefaultedCopyConstructorIsConstexpr(true),
-    DefaultedMoveConstructorIsConstexpr(true),
-    HasConstexprDefaultConstructor(false), HasConstexprCopyConstructor(false),
-    HasConstexprMoveConstructor(false), HasTrivialCopyConstructor(true),
+    HasConstexprDefaultConstructor(false), HasTrivialCopyConstructor(true),
     HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true),
     HasTrivialMoveAssignment(true), HasTrivialDestructor(true),
     HasIrrelevantDestructor(true),
@@ -220,8 +217,6 @@
       //   In the definition of a constexpr constructor [...]
       //    -- the class shall not have any virtual base classes
       data().DefaultedDefaultConstructorIsConstexpr = false;
-      data().DefaultedCopyConstructorIsConstexpr = false;
-      data().DefaultedMoveConstructorIsConstexpr = false;
     } else {
       // C++ [class.ctor]p5:
       //   A default constructor is trivial [...] if:
@@ -260,25 +255,6 @@
       //   default constructor is constexpr.
       if (!BaseClassDecl->hasConstexprDefaultConstructor())
         data().DefaultedDefaultConstructorIsConstexpr = false;
-
-      // C++11 [class.copy]p13:
-      //   If the implicitly-defined constructor would satisfy the requirements
-      //   of a constexpr constructor, the implicitly-defined constructor is
-      //   constexpr.
-      // C++11 [dcl.constexpr]p4:
-      //    -- every constructor involved in initializing [...] base class
-      //       sub-objects shall be a constexpr constructor
-      if (!BaseClassDecl->hasConstexprCopyConstructor())
-        data().DefaultedCopyConstructorIsConstexpr = false;
-      if (BaseClassDecl->hasDeclaredMoveConstructor() ||
-          BaseClassDecl->needsImplicitMoveConstructor())
-        // FIXME: If the implicit move constructor generated for the base class
-        // would be ill-formed, the implicit move constructor generated for the
-        // derived class calls the base class' copy constructor.
-        data().DefaultedMoveConstructorIsConstexpr &=
-          BaseClassDecl->hasConstexprMoveConstructor();
-      else if (!BaseClassDecl->hasConstexprCopyConstructor())
-        data().DefaultedMoveConstructorIsConstexpr = false;
     }
     
     // C++ [class.ctor]p3:
@@ -471,11 +447,7 @@
 }
 
 void CXXRecordDecl::markedConstructorConstexpr(CXXConstructorDecl *CD) {
-  if (CD->isCopyConstructor())
-    data().HasConstexprCopyConstructor = true;
-  else if (CD->isMoveConstructor())
-    data().HasConstexprMoveConstructor = true;
-  else
+  if (!CD->isCopyOrMoveConstructor())
     data().HasConstexprNonCopyMoveConstructor = true;
 
   if (CD->isDefaultConstructor())
@@ -558,12 +530,8 @@
         }
       } else if (Constructor->isCopyConstructor()) {
         data().DeclaredCopyConstructor = true;
-        if (Constructor->isConstexpr())
-          data().HasConstexprCopyConstructor = true;
       } else if (Constructor->isMoveConstructor()) {
         data().DeclaredMoveConstructor = true;
-        if (Constructor->isConstexpr())
-          data().HasConstexprMoveConstructor = true;
       } else
         goto NotASpecialMember;
       return;
@@ -620,9 +588,6 @@
         //   user-provided [...]
         if (UserProvided)
           data().HasTrivialCopyConstructor = false;
-
-        if (Constructor->isConstexpr())
-          data().HasConstexprCopyConstructor = true;
       } else if (Constructor->isMoveConstructor()) {
         data().UserDeclaredMoveConstructor = true;
         data().DeclaredMoveConstructor = true;
@@ -632,9 +597,6 @@
         //   user-provided [...]
         if (UserProvided)
           data().HasTrivialMoveConstructor = false;
-
-        if (Constructor->isConstexpr())
-          data().HasConstexprMoveConstructor = true;
       }
     }
     if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) {
@@ -676,19 +638,9 @@
     // C++11 [class.dtor]p5: 
     //   A destructor is trivial if it is not user-provided and if
     //    -- the destructor is not virtual.
-    if (DD->isUserProvided() || DD->isVirtual()) {
+    if (DD->isUserProvided() || DD->isVirtual())
       data().HasTrivialDestructor = false;
-      // C++11 [dcl.constexpr]p1:
-      //   The constexpr specifier shall be applied only to [...] the
-      //   declaration of a static data member of a literal type.
-      // C++11 [basic.types]p10:
-      //   A type is a literal type if it is [...] a class type that [...] has
-      //   a trivial destructor.
-      data().DefaultedDefaultConstructorIsConstexpr = false;
-      data().DefaultedCopyConstructorIsConstexpr = false;
-      data().DefaultedMoveConstructorIsConstexpr = false;
-    }
-    
+
     return;
   }
   
@@ -939,27 +891,11 @@
           // The standard requires any in-class initializer to be a constant
           // expression. We consider this to be a defect.
           data().DefaultedDefaultConstructorIsConstexpr = false;
-
-        if (!FieldRec->hasConstexprCopyConstructor())
-          data().DefaultedCopyConstructorIsConstexpr = false;
-
-        if (FieldRec->hasDeclaredMoveConstructor() ||
-            FieldRec->needsImplicitMoveConstructor())
-          // FIXME: If the implicit move constructor generated for the member's
-          // class would be ill-formed, the implicit move constructor generated
-          // for this class calls the member's copy constructor.
-          data().DefaultedMoveConstructorIsConstexpr &=
-            FieldRec->hasConstexprMoveConstructor();
-        else if (!FieldRec->hasConstexprCopyConstructor())
-          data().DefaultedMoveConstructorIsConstexpr = false;
       }
     } else {
       // Base element type of field is a non-class type.
-      if (!T->isLiteralType()) {
-        data().DefaultedDefaultConstructorIsConstexpr = false;
-        data().DefaultedCopyConstructorIsConstexpr = false;
-        data().DefaultedMoveConstructorIsConstexpr = false;
-      } else if (!Field->hasInClassInitializer() && !isUnion())
+      if (!T->isLiteralType() ||
+          (!Field->hasInClassInitializer() && !isUnion()))
         data().DefaultedDefaultConstructorIsConstexpr = false;
     }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Jun 10 02:07:24 2012
@@ -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;
     }
   }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Jun 10 02:07:24 2012
@@ -1094,11 +1094,7 @@
   Data.HasTrivialDefaultConstructor = Record[Idx++];
   Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
   Data.DefaultedDefaultConstructorIsConstexpr = Record[Idx++];
-  Data.DefaultedCopyConstructorIsConstexpr = Record[Idx++];
-  Data.DefaultedMoveConstructorIsConstexpr = Record[Idx++];
   Data.HasConstexprDefaultConstructor = Record[Idx++];
-  Data.HasConstexprCopyConstructor = Record[Idx++];
-  Data.HasConstexprMoveConstructor = Record[Idx++];
   Data.HasTrivialCopyConstructor = Record[Idx++];
   Data.HasTrivialMoveConstructor = Record[Idx++];
   Data.HasTrivialCopyAssignment = Record[Idx++];

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=158290&r1=158289&r2=158290&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Jun 10 02:07:24 2012
@@ -4313,11 +4313,7 @@
   Record.push_back(Data.HasTrivialDefaultConstructor);
   Record.push_back(Data.HasConstexprNonCopyMoveConstructor);
   Record.push_back(Data.DefaultedDefaultConstructorIsConstexpr);
-  Record.push_back(Data.DefaultedCopyConstructorIsConstexpr);
-  Record.push_back(Data.DefaultedMoveConstructorIsConstexpr);
   Record.push_back(Data.HasConstexprDefaultConstructor);
-  Record.push_back(Data.HasConstexprCopyConstructor);
-  Record.push_back(Data.HasConstexprMoveConstructor);
   Record.push_back(Data.HasTrivialCopyConstructor);
   Record.push_back(Data.HasTrivialMoveConstructor);
   Record.push_back(Data.HasTrivialCopyAssignment);





More information about the cfe-commits mailing list