diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-07-01 19:09:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-07-01 19:09:28 +0000 |
commit | fabd43a5e3e9e5b8950ea7d110bbf1cd962365c0 (patch) | |
tree | 041d18404a0058fa84bb2d6f330d64d961fe53dc | |
parent | 598a8543ec4c22e7f0a27e7ff2cf7e49cfa4e4ff (diff) |
Move the implicit declaration of a constructor out to a separate
method. No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107415 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/Sema.h | 14 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 144 |
2 files changed, 90 insertions, 68 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 1c9e77143f..c4765a39ce 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2225,10 +2225,22 @@ public: void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor); + /// \brief Declare the implicit destructor for the given class. + /// + /// \param S The scope of the class, which may be NULL if this is a + /// template instantiation. + /// + /// \param ClassDecl The class declaration into which the implicit + /// destructor will be added. + /// + /// \returns The implicitly-declared destructor. + CXXDestructorDecl *DeclareImplicitDestructor(Scope *S, + CXXRecordDecl *ClassDecl); + /// DefineImplicitDestructor - Checks for feasibility of /// defining this destructor as the default destructor. void DefineImplicitDestructor(SourceLocation CurrentLocation, - CXXDestructorDecl *Destructor); + CXXDestructorDecl *Destructor); /// \brief Declare the implicit copy constructor for the given class. /// diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d710321939..cb454581d1 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2698,73 +2698,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, if (!ClassDecl->hasUserDeclaredCopyAssignment()) DeclareImplicitCopyAssignment(S, ClassDecl); - if (!ClassDecl->hasUserDeclaredDestructor()) { - // C++ [class.dtor]p2: - // If a class has no user-declared destructor, a destructor is - // declared implicitly. An implicitly-declared destructor is an - // inline public member of its class. - - // C++ [except.spec]p14: - // An implicitly declared special member function (Clause 12) shall have - // an exception-specification. - ImplicitExceptionSpecification ExceptSpec(Context); - - // Direct base-class destructors. - for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), - BEnd = ClassDecl->bases_end(); - B != BEnd; ++B) { - if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) - ExceptSpec.CalledDecl( - cast<CXXRecordDecl>(BaseType->getDecl())->getDestructor()); - } - - // Virtual base-class destructors. - for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), - BEnd = ClassDecl->vbases_end(); - B != BEnd; ++B) { - if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) - ExceptSpec.CalledDecl( - cast<CXXRecordDecl>(BaseType->getDecl())->getDestructor()); - } - - // Field destructors. - for (RecordDecl::field_iterator F = ClassDecl->field_begin(), - FEnd = ClassDecl->field_end(); - F != FEnd; ++F) { - if (const RecordType *RecordTy - = Context.getBaseElementType(F->getType())->getAs<RecordType>()) - ExceptSpec.CalledDecl( - cast<CXXRecordDecl>(RecordTy->getDecl())->getDestructor()); - } - - QualType Ty = Context.getFunctionType(Context.VoidTy, - 0, 0, false, 0, - ExceptSpec.hasExceptionSpecification(), - ExceptSpec.hasAnyExceptionSpecification(), - ExceptSpec.size(), - ExceptSpec.data(), - FunctionType::ExtInfo()); - - DeclarationName Name - = Context.DeclarationNames.getCXXDestructorName(ClassType); - CXXDestructorDecl *Destructor - = CXXDestructorDecl::Create(Context, ClassDecl, - ClassDecl->getLocation(), Name, Ty, - /*isInline=*/true, - /*isImplicitlyDeclared=*/true); - Destructor->setAccess(AS_public); - Destructor->setImplicit(); - Destructor->setTrivial(ClassDecl->hasTrivialDestructor()); - if (S) - PushOnScopeChains(Destructor, S, true); - else - ClassDecl->addDecl(Destructor); - - // This could be uniqued if it ever proves significant. - Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty)); - - AddOverriddenMethods(ClassDecl, Destructor); - } + if (!ClassDecl->hasUserDeclaredDestructor()) + DeclareImplicitDestructor(S, ClassDecl); } void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) { @@ -4255,6 +4190,81 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, } } +CXXDestructorDecl *Sema::DeclareImplicitDestructor(Scope *S, + CXXRecordDecl *ClassDecl) { + // C++ [class.dtor]p2: + // If a class has no user-declared destructor, a destructor is + // declared implicitly. An implicitly-declared destructor is an + // inline public member of its class. + + // C++ [except.spec]p14: + // An implicitly declared special member function (Clause 12) shall have + // an exception-specification. + ImplicitExceptionSpecification ExceptSpec(Context); + + // Direct base-class destructors. + for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), + BEnd = ClassDecl->bases_end(); + B != BEnd; ++B) { + if (B->isVirtual()) // Handled below. + continue; + + if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) + ExceptSpec.CalledDecl( + cast<CXXRecordDecl>(BaseType->getDecl())->getDestructor()); + } + + // Virtual base-class destructors. + for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), + BEnd = ClassDecl->vbases_end(); + B != BEnd; ++B) { + if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) + ExceptSpec.CalledDecl( + cast<CXXRecordDecl>(BaseType->getDecl())->getDestructor()); + } + + // Field destructors. + for (RecordDecl::field_iterator F = ClassDecl->field_begin(), + FEnd = ClassDecl->field_end(); + F != FEnd; ++F) { + if (const RecordType *RecordTy + = Context.getBaseElementType(F->getType())->getAs<RecordType>()) + ExceptSpec.CalledDecl( + cast<CXXRecordDecl>(RecordTy->getDecl())->getDestructor()); + } + + QualType Ty = Context.getFunctionType(Context.VoidTy, + 0, 0, false, 0, + ExceptSpec.hasExceptionSpecification(), + ExceptSpec.hasAnyExceptionSpecification(), + ExceptSpec.size(), + ExceptSpec.data(), + FunctionType::ExtInfo()); + + CanQualType ClassType + = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl)); + DeclarationName Name + = Context.DeclarationNames.getCXXDestructorName(ClassType); + CXXDestructorDecl *Destructor + = CXXDestructorDecl::Create(Context, ClassDecl, + ClassDecl->getLocation(), Name, Ty, + /*isInline=*/true, + /*isImplicitlyDeclared=*/true); + Destructor->setAccess(AS_public); + Destructor->setImplicit(); + Destructor->setTrivial(ClassDecl->hasTrivialDestructor()); + if (S) + PushOnScopeChains(Destructor, S, true); + else + ClassDecl->addDecl(Destructor); + + // This could be uniqued if it ever proves significant. + Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty)); + + AddOverriddenMethods(ClassDecl, Destructor); + return Destructor; +} + void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor) { assert((Destructor->isImplicit() && !Destructor->isUsed(false)) && |