aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-04-16 00:08:20 +0000
committerAnders Carlsson <andersca@mac.com>2009-04-16 00:08:20 +0000
commit347ba89dec89091868982434154c3508085b727a (patch)
tree770e8cc2ec6d9760467566b8bdc8683a6df90224 /lib/Sema/SemaDeclCXX.cpp
parent94cd5d1397bb1a8bcd109602aa38dd787b164c22 (diff)
Add support for the __has_trivial_constructor type trait.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69245 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index cc70dc4a5c..ec1ed4668a 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -369,6 +369,18 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
Class->setAggregate(false);
Class->setPOD(false);
+ if (Virtual) {
+ // C++ [class.ctor]p5:
+ // A constructor is trivial if its class has no virtual base classes.
+ Class->setHasTrivialConstructor(false);
+ } else {
+ // C++ [class.ctor]p5:
+ // A constructor is trivial if all the direct base classes of its
+ // class have trivial constructors.
+ Class->setHasTrivialConstructor(cast<CXXRecordDecl>(BaseDecl)->
+ hasTrivialConstructor());
+ }
+
// Create the base specifier.
// FIXME: Allocate via ASTContext?
return new CXXBaseSpecifier(SpecifierRange, Virtual,
@@ -940,6 +952,24 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
if (RD->isAbstract())
AbstractClassUsageDiagnoser(*this, RD);
+ if (RD->hasTrivialConstructor()) {
+ 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.
+ QualType FTy = i->getType();
+ while (const ArrayType *AT = Context.getAsArrayType(FTy))
+ FTy = AT->getElementType();
+
+ if (const RecordType *RT = FTy->getAsRecordType()) {
+ CXXRecordDecl *FieldRD = cast<CXXRecordDecl>(RT->getDecl());
+ if (!FieldRD->hasTrivialConstructor()) {
+ RD->setHasTrivialConstructor(false);
+ break;
+ }
+ }
+ }
+ }
+
if (!Template)
AddImplicitlyDeclaredMembersToClass(RD);
}