diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-09-28 00:00:00 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-09-28 00:00:00 +0000 |
| commit | 1f93ffb3e68136759e7eb141c5d753335a0c234a (patch) | |
| tree | b4a2da40b1e64be9b0ed184f5017c6f9a8b099dd /clang/lib/AST/DeclCXX.cpp | |
| parent | 8fd3244af3fd908e3649170f32465ca169294e63 (diff) | |
| download | bcm5719-llvm-1f93ffb3e68136759e7eb141c5d753335a0c234a.tar.gz bcm5719-llvm-1f93ffb3e68136759e7eb141c5d753335a0c234a.zip | |
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).
llvm-svn: 114929
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 151d333afcc..3e6d8b379ff 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -134,7 +134,45 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // 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 @@ CXXRecordDecl::addedMember(Decl *D) { // 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 @@ CXXRecordDecl::addedMember(Decl *D) { // 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 @@ CXXRecordDecl::addedMember(Decl *D) { 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 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { 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()); |

