diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-23 23:49:00 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-23 23:49:00 +0000 |
commit | 79f83eda848b474a7839220bc98306ac8eb56c9f (patch) | |
tree | d32df6f4ff893e9c5f80ac484e74375327b63f96 /clang/lib/AST/ExprCXX.cpp | |
parent | 91ade1419748a8b092a6e634d2a126a01fb05f2d (diff) | |
download | bcm5719-llvm-79f83eda848b474a7839220bc98306ac8eb56c9f.tar.gz bcm5719-llvm-79f83eda848b474a7839220bc98306ac8eb56c9f.zip |
This patch fixes the implementations of the __has_trivial_destructor
and __has_trivial_constructor builtin pseudo-functions and
additionally implements __has_trivial_copy and __has_trivial_assign,
from John McCall!
llvm-svn: 76916
Diffstat (limited to 'clang/lib/AST/ExprCXX.cpp')
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 399c30255a8..fbefcd1ee8c 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -213,7 +213,7 @@ Stmt::child_iterator TemplateIdRefExpr::child_end() { return Stmt::child_iterator(); } -bool UnaryTypeTraitExpr::EvaluateTrait() const { +bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const { switch(UTT) { default: assert(false && "Unknown type trait or not implemented"); case UTT_IsPOD: return QueriedType->isPODType(); @@ -236,11 +236,58 @@ bool UnaryTypeTraitExpr::EvaluateTrait() const { return cast<CXXRecordDecl>(RT->getDecl())->isAbstract(); return false; case UTT_HasTrivialConstructor: - if (const RecordType *RT = QueriedType->getAsRecordType()) + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // If __is_pod (type) is true then the trait is true, else if type is + // a cv class or union type (or array thereof) with a trivial default + // constructor ([class.ctor]) then the trait is true, else it is false. + if (QueriedType->isPODType()) + return true; + if (const RecordType *RT = + C.getBaseElementType(QueriedType)->getAsRecordType()) return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor(); return false; - case UTT_HasTrivialDestructor: + case UTT_HasTrivialCopy: + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // If __is_pod (type) is true or type is a reference type then + // the trait is true, else if type is a cv class or union type + // with a trivial copy constructor ([class.copy]) then the trait + // is true, else it is false. + if (QueriedType->isPODType() || QueriedType->isReferenceType()) + return true; + if (const RecordType *RT = QueriedType->getAsRecordType()) + return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); + return false; + case UTT_HasTrivialAssign: + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // If type is const qualified or is a reference type then the + // trait is false. Otherwise if __is_pod (type) is true then the + // trait is true, else if type is a cv class or union type with + // a trivial copy assignment ([class.copy]) then the trait is + // true, else it is false. + // Note: the const and reference restrictions are interesting, + // given that const and reference members don't prevent a class + // from having a trivial copy assignment operator (but do cause + // errors if the copy assignment operator is actually used, q.v. + // [class.copy]p12). + + if (C.getBaseElementType(QueriedType).isConstQualified()) + return false; + if (QueriedType->isPODType()) + return true; if (const RecordType *RT = QueriedType->getAsRecordType()) + return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); + return false; + case UTT_HasTrivialDestructor: + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // If __is_pod (type) is true or type is a reference type + // then the trait is true, else if type is a cv class or union + // type (or array thereof) with a trivial destructor + // ([class.dtor]) then the trait is true, else it is + // false. + if (QueriedType->isPODType() || QueriedType->isReferenceType()) + return true; + if (const RecordType *RT = + C.getBaseElementType(QueriedType)->getAsRecordType()) return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); return false; } |