[cfe-commits] r114929 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Sema/Sema.h lib/AST/DeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp

Douglas Gregor dgregor at apple.com
Mon Sep 27 17:00:00 PDT 2010


Author: dgregor
Date: Mon Sep 27 19:00:00 2010
New Revision: 114929

URL: http://llvm.org/viewvc/llvm-project?rev=114929&view=rev
Log:
Centralize the management of CXXRecordDecl::DefinitionData's
HasTrivialConstructor, HasTrivialCopyConstructor,
HasTrivialCopyAssignment, and HasTrivialDestructor bits in
CXXRecordDecl's methods. This completes all but the Abstract bit and
the set of conversion functions, both of which will require a bit of
extra work. The majority of <rdar://problem/8459981> is now
implemented (but not all of it).

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Sep 27 19:00:00 2010
@@ -688,10 +688,6 @@
   /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
   bool isAggregate() const { return data().Aggregate; }
 
-  /// setMethodAsVirtual - Make input method virtual and set the necesssary 
-  /// special function bits and other bits accordingly.
-  void setMethodAsVirtual(FunctionDecl *Method);
-
   /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
   /// that is an aggregate that has no non-static non-POD data members, no
   /// reference data members, no user-defined copy assignment operator and no
@@ -719,42 +715,22 @@
   // (C++ [class.ctor]p5)
   bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
 
-  // setHasTrivialConstructor - Set whether this class has a trivial constructor
-  // (C++ [class.ctor]p5)
-  void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
-
   // hasTrivialCopyConstructor - Whether this class has a trivial copy
   // constructor (C++ [class.copy]p6)
   bool hasTrivialCopyConstructor() const {
     return data().HasTrivialCopyConstructor;
   }
 
-  // setHasTrivialCopyConstructor - Set whether this class has a trivial
-  // copy constructor (C++ [class.copy]p6)
-  void setHasTrivialCopyConstructor(bool TC) {
-    data().HasTrivialCopyConstructor = TC;
-  }
-
   // hasTrivialCopyAssignment - Whether this class has a trivial copy
   // assignment operator (C++ [class.copy]p11)
   bool hasTrivialCopyAssignment() const {
     return data().HasTrivialCopyAssignment;
   }
 
-  // setHasTrivialCopyAssignment - Set whether this class has a
-  // trivial copy assignment operator (C++ [class.copy]p11)
-  void setHasTrivialCopyAssignment(bool TC) {
-    data().HasTrivialCopyAssignment = TC;
-  }
-
   // hasTrivialDestructor - Whether this class has a trivial destructor
   // (C++ [class.dtor]p3)
   bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
 
-  // setHasTrivialDestructor - Set whether this class has a trivial destructor
-  // (C++ [class.dtor]p3)
-  void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
-
   /// \brief If this record is an instantiation of a member class,
   /// retrieves the member class from which it was instantiated.
   ///

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Sep 27 19:00:00 2010
@@ -2584,13 +2584,6 @@
                                        bool Virtual, AccessSpecifier Access,
                                        TypeSourceInfo *TInfo);
 
-  /// SetClassDeclAttributesFromBase - Copies class decl traits
-  /// (such as whether the class has a trivial constructor,
-  /// trivial destructor etc) from the given base class.
-  void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
-                                      const CXXRecordDecl *BaseClass,
-                                      bool BaseIsVirtual);
-
   BaseResult ActOnBaseSpecifier(Decl *classdecl,
                                 SourceRange SpecifierRange,
                                 bool Virtual, AccessSpecifier Access,

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Sep 27 19:00:00 2010
@@ -134,7 +134,45 @@
       //    T is a class type, but not a union type, with ... no virtual base
       //    classes
       data().Empty = false;
+      
+      // C++ [class.ctor]p5:
+      //   A constructor is trivial if its class has no virtual base classes.
+      data().HasTrivialConstructor = false;
+      
+      // C++ [class.copy]p6:
+      //   A copy constructor is trivial if its class has no virtual base 
+      //   classes.
+      data().HasTrivialCopyConstructor = false;
+      
+      // C++ [class.copy]p11:
+      //   A copy assignment operator is trivial if its class has no virtual
+      //   base classes.
+      data().HasTrivialCopyAssignment = false;
+    } else {
+      // C++ [class.ctor]p5:
+      //   A constructor is trivial if all the direct base classes of its
+      //   class have trivial constructors.
+      if (!BaseClassDecl->hasTrivialConstructor())
+        data().HasTrivialConstructor = false;
+      
+      // C++ [class.copy]p6:
+      //   A copy constructor is trivial if all the direct base classes of its
+      //   class have trivial copy constructors.
+      if (!BaseClassDecl->hasTrivialCopyConstructor())
+        data().HasTrivialCopyConstructor = false;
+      
+      // C++ [class.copy]p11:
+      //   A copy assignment operator is trivial if all the direct base classes
+      //   of its class have trivial copy assignment operators.
+      if (!BaseClassDecl->hasTrivialCopyAssignment())
+        data().HasTrivialCopyAssignment = false;
     }
+    
+    // C++ [class.ctor]p3:
+    //   A destructor is trivial if all the direct base classes of its class
+    //   have trivial destructors.
+    if (!BaseClassDecl->hasTrivialDestructor())
+      data().HasTrivialDestructor = false;
   }
   
   if (VBases.empty())
@@ -309,6 +347,12 @@
       //   A class that declares or inherits a virtual function is called a 
       //   polymorphic class.
       data().Polymorphic = true;
+      
+      // None of the special member functions are trivial.
+      data().HasTrivialConstructor = false;
+      data().HasTrivialCopyConstructor = false;
+      data().HasTrivialCopyAssignment = false;
+      // FIXME: Destructor?
     }
   }
   
@@ -384,6 +428,13 @@
     //   destructor.
     data().PlainOldData = false;
     
+    // C++ [class.dtor]p3: 
+    //   A destructor is trivial if it is an implicitly-declared destructor and
+    //   [...].
+    //
+    // FIXME: C++0x: don't do this for "= default" destructors
+    data().HasTrivialDestructor = false;
+    
     return;
   }
   
@@ -453,6 +504,22 @@
     QualType T = Context.getBaseElementType(Field->getType());
     if (!T->isPODType())
       data().PlainOldData = false;
+    if (T->isReferenceType())
+      data().HasTrivialConstructor = false;
+    
+    if (const RecordType *RecordTy = T->getAs<RecordType>()) {
+      CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
+      if (FieldRec->getDefinition()) {
+        if (!FieldRec->hasTrivialConstructor())
+          data().HasTrivialConstructor = false;
+        if (!FieldRec->hasTrivialCopyConstructor())
+          data().HasTrivialCopyConstructor = false;
+        if (!FieldRec->hasTrivialCopyAssignment())
+          data().HasTrivialCopyAssignment = false;
+        if (!FieldRec->hasTrivialDestructor())
+          data().HasTrivialDestructor = false;
+      }
+    }
     
     // If this is not a zero-length bit-field, then the class is not empty.
     if (data().Empty) {
@@ -649,13 +716,6 @@
   llvm_unreachable("conversion not found in set!");
 }
 
-void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
-  Method->setVirtualAsWritten(true);
-  setHasTrivialConstructor(false);
-  setHasTrivialCopyConstructor(false);
-  setHasTrivialCopyAssignment(false);
-}
-
 CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
     return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Sep 27 19:00:00 2010
@@ -3425,8 +3425,7 @@
         << FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc());
     } else {
       // Okay: Add virtual to the method.
-      CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC);
-      CurClass->setMethodAsVirtual(NewFD);
+      NewFD->setVirtualAsWritten(true);
     }
   }
 
@@ -3927,11 +3926,6 @@
           return NewFD->setInvalidDecl();
         }
       }
-
-      // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly-
-      // declared destructor.
-      // FIXME: C++0x: don't do this for "= default" destructors
-      Record->setHasTrivialDestructor(false);
     } else if (CXXConversionDecl *Conversion
                = dyn_cast<CXXConversionDecl>(NewFD)) {
       ActOnConversionDeclarator(Conversion);
@@ -6185,23 +6179,9 @@
   }
 
   if (!InvalidDecl && getLangOptions().CPlusPlus) {
-    CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record);
-
-    if (T->isReferenceType())
-      CXXRecord->setHasTrivialConstructor(false);
-
     if (const RecordType *RT = EltTy->getAs<RecordType>()) {
       CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
       if (RDecl->getDefinition()) {
-        if (!RDecl->hasTrivialConstructor())
-          CXXRecord->setHasTrivialConstructor(false);
-        if (!RDecl->hasTrivialCopyConstructor())
-          CXXRecord->setHasTrivialCopyConstructor(false);
-        if (!RDecl->hasTrivialCopyAssignment())
-          CXXRecord->setHasTrivialCopyAssignment(false);
-        if (!RDecl->hasTrivialDestructor())
-          CXXRecord->setHasTrivialDestructor(false);
-
         // C++ 9.5p1: An object of a class with a non-trivial
         // constructor, a non-trivial copy constructor, a non-trivial
         // destructor, or a non-trivial copy assignment operator

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Sep 27 19:00:00 2010
@@ -502,8 +502,6 @@
     return 0;
   }
 
-  SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
-
   if (BaseDecl->isInvalidDecl())
     Class->setInvalidDecl();
   
@@ -513,49 +511,6 @@
                                         Access, TInfo);
 }
 
-void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
-                                          const CXXRecordDecl *BaseClass,
-                                          bool BaseIsVirtual) {
-  if (BaseIsVirtual) {
-    // C++ [class.ctor]p5:
-    //   A constructor is trivial if its class has no virtual base classes.
-    Class->setHasTrivialConstructor(false);
-
-    // C++ [class.copy]p6:
-    //   A copy constructor is trivial if its class has no virtual base classes.
-    Class->setHasTrivialCopyConstructor(false);
-
-    // C++ [class.copy]p11:
-    //   A copy assignment operator is trivial if its class has no virtual
-    //   base classes.
-    Class->setHasTrivialCopyAssignment(false);
-  } else {
-    // C++ [class.ctor]p5:
-    //   A constructor is trivial if all the direct base classes of its
-    //   class have trivial constructors.
-    if (!BaseClass->hasTrivialConstructor())
-      Class->setHasTrivialConstructor(false);
-
-    // C++ [class.copy]p6:
-    //   A copy constructor is trivial if all the direct base classes of its
-    //   class have trivial copy constructors.
-    if (!BaseClass->hasTrivialCopyConstructor())
-      Class->setHasTrivialCopyConstructor(false);
-
-    // C++ [class.copy]p11:
-    //   A copy assignment operator is trivial if all the direct base classes
-    //   of its class have trivial copy assignment operators.
-    if (!BaseClass->hasTrivialCopyAssignment())
-      Class->setHasTrivialCopyAssignment(false);
-  }
-
-  // C++ [class.ctor]p3:
-  //   A destructor is trivial if all the direct base classes of its class
-  //   have trivial destructors.
-  if (!BaseClass->hasTrivialDestructor())
-    Class->setHasTrivialDestructor(false);
-}
-
 /// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
 /// one entry in the base class list of a class specifier, for
 /// example:

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Sep 27 19:00:00 2010
@@ -1091,13 +1091,6 @@
          Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
        Base != BaseEnd; ++Base) {
     if (!Base->getType()->isDependentType()) {
-      const CXXRecordDecl *BaseDecl =
-        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-      
-      // Make sure to set the attributes from the base.
-      SetClassDeclAttributesFromBase(Instantiation, BaseDecl, 
-                                     Base->isVirtual());
-      
       InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
       continue;
     }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Sep 27 19:00:00 2010
@@ -1996,10 +1996,9 @@
   if (InitFunctionInstantiation(New, Tmpl))
     return true;
 
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
   New->setAccess(Tmpl->getAccess());
   if (Tmpl->isVirtualAsWritten())
-    Record->setMethodAsVirtual(New);
+    New->setVirtualAsWritten(true);
 
   // FIXME: attributes
   // FIXME: New needs a pointer to Tmpl





More information about the cfe-commits mailing list