aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprCXX.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-09-13 20:56:31 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-09-13 20:56:31 +0000
commit0dfd848fa4c9664852ba8c929a8bd3fce93ddca2 (patch)
tree0075127b0a0b4c7672d65e24bf8a23d56cd06040 /lib/AST/ExprCXX.cpp
parent8c6b9135fc7d5631cce52779a991897a1b76e47a (diff)
Eagerly evaluate type traits in Sema instead of lazily in AST. They actually need Sema access to be correct, fixes coming up.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113782 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprCXX.cpp')
-rw-r--r--lib/AST/ExprCXX.cpp198
1 files changed, 0 insertions, 198 deletions
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index fd22db277b..a6aeef1ba8 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -327,204 +327,6 @@ StmtIterator DependentScopeDeclRefExpr::child_end() {
return child_iterator();
}
-bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
- QualType T = getQueriedType();
- switch(UTT) {
- default: assert(false && "Unknown type trait or not implemented");
- case UTT_IsPOD: return T->isPODType();
- case UTT_IsLiteral: return T->isLiteralType();
- case UTT_IsClass: // Fallthrough
- case UTT_IsUnion:
- if (const RecordType *Record = T->getAs<RecordType>()) {
- bool Union = Record->getDecl()->isUnion();
- return UTT == UTT_IsUnion ? Union : !Union;
- }
- return false;
- case UTT_IsEnum: return T->isEnumeralType();
- case UTT_IsPolymorphic:
- if (const RecordType *Record = T->getAs<RecordType>()) {
- // Type traits are only parsed in C++, so we've got CXXRecords.
- return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
- }
- return false;
- case UTT_IsAbstract:
- if (const RecordType *RT = T->getAs<RecordType>())
- return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
- return false;
- case UTT_IsEmpty:
- if (const RecordType *Record = T->getAs<RecordType>()) {
- return !Record->getDecl()->isUnion()
- && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
- }
- return false;
- case UTT_HasTrivialConstructor:
- // 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 (T->isPODType())
- return true;
- if (const RecordType *RT =
- C.getBaseElementType(T)->getAs<RecordType>())
- return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
- return false;
- 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 (T->isPODType() || T->isReferenceType())
- return true;
- if (const RecordType *RT = T->getAs<RecordType>())
- 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(T).isConstQualified())
- return false;
- if (T->isPODType())
- return true;
- if (const RecordType *RT = T->getAs<RecordType>())
- 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 (T->isPODType() || T->isReferenceType())
- return true;
- if (const RecordType *RT =
- C.getBaseElementType(T)->getAs<RecordType>())
- return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
- return false;
- // TODO: Propagate nothrowness for implicitly declared special members.
- case UTT_HasNothrowAssign:
- // 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 __has_trivial_assign (type)
- // is true then the trait is true, else if type is a cv class
- // or union type with copy assignment operators that are known
- // not to throw an exception then the trait is true, else it is
- // false.
- if (C.getBaseElementType(T).isConstQualified())
- return false;
- if (T->isReferenceType())
- return false;
- if (T->isPODType())
- return true;
- if (const RecordType *RT = T->getAs<RecordType>()) {
- CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->hasTrivialCopyAssignment())
- return true;
-
- bool FoundAssign = false;
- bool AllNoThrow = true;
- DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal);
- DeclContext::lookup_const_iterator Op, OpEnd;
- for (llvm::tie(Op, OpEnd) = RD->lookup(Name);
- Op != OpEnd; ++Op) {
- CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
- if (Operator->isCopyAssignmentOperator()) {
- FoundAssign = true;
- const FunctionProtoType *CPT
- = Operator->getType()->getAs<FunctionProtoType>();
- if (!CPT->hasEmptyExceptionSpec()) {
- AllNoThrow = false;
- break;
- }
- }
- }
-
- return FoundAssign && AllNoThrow;
- }
- return false;
- case UTT_HasNothrowCopy:
- // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
- // If __has_trivial_copy (type) is true then the trait is true, else
- // if type is a cv class or union type with copy constructors that are
- // known not to throw an exception then the trait is true, else it is
- // false.
- if (T->isPODType() || T->isReferenceType())
- return true;
- if (const RecordType *RT = T->getAs<RecordType>()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->hasTrivialCopyConstructor())
- return true;
-
- bool FoundConstructor = false;
- bool AllNoThrow = true;
- unsigned FoundTQs;
- DeclarationName ConstructorName
- = C.DeclarationNames.getCXXConstructorName(C.getCanonicalType(T));
- DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = RD->lookup(ConstructorName);
- Con != ConEnd; ++Con) {
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
- if (Constructor->isCopyConstructor(FoundTQs)) {
- FoundConstructor = true;
- const FunctionProtoType *CPT
- = Constructor->getType()->getAs<FunctionProtoType>();
- if (!CPT->hasEmptyExceptionSpec()) {
- AllNoThrow = false;
- break;
- }
- }
- }
-
- return FoundConstructor && AllNoThrow;
- }
- return false;
- case UTT_HasNothrowConstructor:
- // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
- // If __has_trivial_constructor (type) is true then the trait is
- // true, else if type is a cv class or union type (or array
- // thereof) with a default constructor that is known not to
- // throw an exception then the trait is true, else it is false.
- if (T->isPODType())
- return true;
- if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->hasTrivialConstructor())
- return true;
-
- if (CXXConstructorDecl *Constructor = RD->getDefaultConstructor()) {
- const FunctionProtoType *CPT
- = Constructor->getType()->getAs<FunctionProtoType>();
- // TODO: check whether evaluating default arguments can throw.
- // For now, we'll be conservative and assume that they can throw.
- if (CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0)
- return true;
- }
- }
- return false;
- case UTT_HasVirtualDestructor:
- // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
- // If type is a class type with a virtual destructor ([class.dtor])
- // then the trait is true, else it is false.
- if (const RecordType *Record = T->getAs<RecordType>()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
- if (CXXDestructorDecl *Destructor = RD->getDestructor())
- return Destructor->isVirtual();
- }
- return false;
- }
-}
-
SourceRange CXXConstructExpr::getSourceRange() const {
// FIXME: Should we know where the parentheses are, if there are any?
for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {