diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 39 |
2 files changed, 40 insertions, 20 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) { diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index fb34d9f1da..2481bd004d 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2320,6 +2320,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, Stmt *Pattern = 0; if (PatternDecl) Pattern = PatternDecl->getBody(PatternDecl); + if (!Pattern) + // Try to find a defaulted definition + PatternDecl->isDefined(PatternDecl); // Postpone late parsed template instantiations. if (PatternDecl && PatternDecl->isLateTemplateParsed() && @@ -2337,7 +2340,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, Pattern = PatternDecl->getBody(PatternDecl); } - if (!Pattern) { + if (!Pattern && !PatternDecl->isDefaulted()) { if (DefinitionRequired) { if (Function->getPrimaryTemplate()) Diag(PointOfInstantiation, @@ -2432,21 +2435,29 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Function, 0, false, PatternDecl); - // If this is a constructor, instantiate the member initializers. - if (const CXXConstructorDecl *Ctor = - dyn_cast<CXXConstructorDecl>(PatternDecl)) { - InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor, - TemplateArgs); - } + if (PatternDecl->isDefaulted()) { + ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true); - // Instantiate the function body. - StmtResult Body = SubstStmt(Pattern, TemplateArgs); + SetDeclDefaulted(Function, PatternDecl->getLocation()); - if (Body.isInvalid()) - Function->setInvalidDecl(); - - ActOnFinishFunctionBody(Function, Body.get(), - /*IsInstantiation=*/true); + return; + } else { + // If this is a constructor, instantiate the member initializers. + if (const CXXConstructorDecl *Ctor = + dyn_cast<CXXConstructorDecl>(PatternDecl)) { + InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor, + TemplateArgs); + } + + // Instantiate the function body. + StmtResult Body = SubstStmt(Pattern, TemplateArgs); + + if (Body.isInvalid()) + Function->setInvalidDecl(); + + ActOnFinishFunctionBody(Function, Body.get(), + /*IsInstantiation=*/true); + } PerformDependentDiagnostics(PatternDecl, TemplateArgs); |