Add support for the __has_trivial_destructor type trait.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69345 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e3195a9..9fd6226 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -380,6 +380,12 @@
Class->setHasTrivialConstructor(cast<CXXRecordDecl>(BaseDecl)->
hasTrivialConstructor());
}
+
+ // C++ [class.ctor]p3:
+ // A destructor is trivial if all the direct base classes of its class
+ // have trivial destructors.
+ Class->setHasTrivialDestructor(cast<CXXRecordDecl>(BaseDecl)->
+ hasTrivialDestructor());
// Create the base specifier.
// FIXME: Allocate via ASTContext?
@@ -952,7 +958,7 @@
if (RD->isAbstract())
AbstractClassUsageDiagnoser(*this, RD);
- if (RD->hasTrivialConstructor()) {
+ if (RD->hasTrivialConstructor() || RD->hasTrivialDestructor()) {
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i) {
// All the nonstatic data members must have trivial constructors.
@@ -962,10 +968,16 @@
if (const RecordType *RT = FTy->getAsRecordType()) {
CXXRecordDecl *FieldRD = cast<CXXRecordDecl>(RT->getDecl());
- if (!FieldRD->hasTrivialConstructor()) {
+
+ if (!FieldRD->hasTrivialConstructor())
RD->setHasTrivialConstructor(false);
+ if (!FieldRD->hasTrivialDestructor())
+ RD->setHasTrivialDestructor(false);
+
+ // If RD has neither a trivial constructor nor a trivial destructor
+ // we don't need to continue checking.
+ if (!RD->hasTrivialConstructor() && !RD->hasTrivialDestructor())
break;
- }
}
}
}