diff options
author | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-05-23 23:14:04 +0000 |
---|---|---|
committer | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-05-23 23:14:04 +0000 |
commit | cd10dec673680fd18a2e5a27646173780c059d32 (patch) | |
tree | 64c35ae79c23d4e5bd7172e1cbaa4798af93857c /lib/Sema/SemaDeclCXX.cpp | |
parent | e6a11a62d1d66d10a87d81ed697348d66d59adf7 (diff) |
Implement explicit specialization of explicitly-defaulted constructors.
The general out-of-line case (including explicit instantiation mostly
works except that the definition is being lost somewhere between the AST
and CodeGen, so the definition is never emitted.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131933 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9d8ab641f1..e8f2f57a22 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6011,7 +6011,8 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor) { assert((Constructor->isDefaulted() && Constructor->isDefaultConstructor() && - !Constructor->isUsed(false) && !Constructor->isDeleted()) && + !Constructor->doesThisDeclarationHaveABody() && + !Constructor->isDeleted()) && "DefineImplicitDefaultConstructor - call it for implicit default ctor"); CXXRecordDecl *ClassDecl = Constructor->getParent(); @@ -6303,7 +6304,8 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor) { - assert((Destructor->isDefaulted() && !Destructor->isUsed(false)) && + assert((Destructor->isDefaulted() && + !Destructor->doesThisDeclarationHaveABody()) && "DefineImplicitDestructor - call it for implicit default dtor"); CXXRecordDecl *ClassDecl = Destructor->getParent(); assert(ClassDecl && "DefineImplicitDestructor - invalid destructor"); @@ -6750,7 +6752,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, assert((CopyAssignOperator->isDefaulted() && CopyAssignOperator->isOverloadedOperator() && CopyAssignOperator->getOverloadedOperator() == OO_Equal && - !CopyAssignOperator->isUsed(false)) && + !CopyAssignOperator->doesThisDeclarationHaveABody()) && "DefineImplicitCopyAssignment called for wrong function"); CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent(); @@ -7228,7 +7230,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *CopyConstructor) { assert((CopyConstructor->isDefaulted() && CopyConstructor->isCopyConstructor() && - !CopyConstructor->isUsed(false)) && + !CopyConstructor->doesThisDeclarationHaveABody()) && "DefineImplicitCopyConstructor - call it for implicit copy ctor"); CXXRecordDecl *ClassDecl = CopyConstructor->getParent(); @@ -8673,8 +8675,15 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { MD->setDefaulted(); MD->setExplicitlyDefaulted(); - // We'll check it when the record is done - if (MD == MD->getCanonicalDecl()) + // If this definition appears within the record, do the checking when + // the record is complete. + const FunctionDecl *Primary = MD; + if (MD->getTemplatedKind() != FunctionDecl::TK_NonTemplate) + // Find the uninstantiated declaration that actually had the '= default' + // on it. + MD->getTemplateInstantiationPattern()->isDefined(Primary); + + if (Primary == Primary->getCanonicalDecl()) return; switch (Member) { |