diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-13 20:56:31 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-13 20:56:31 +0000 |
commit | 0dfd848fa4c9664852ba8c929a8bd3fce93ddca2 (patch) | |
tree | 0075127b0a0b4c7672d65e24bf8a23d56cd06040 /lib/AST/ExprCXX.cpp | |
parent | 8c6b9135fc7d5631cce52779a991897a1b76e47a (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.cpp | 198 |
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) { |