diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 6 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 39 |
3 files changed, 45 insertions, 9 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 80f3663021..9b46f77c13 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3197,11 +3197,13 @@ public: void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, - bool Recursive = false); + bool Recursive = false, + bool DefinitionRequired = false); void InstantiateStaticDataMemberDefinition( SourceLocation PointOfInstantiation, VarDecl *Var, - bool Recursive = false); + bool Recursive = false, + bool DefinitionRequired = false); void InstantiateMemInitializers(CXXConstructorDecl *New, const CXXConstructorDecl *Tmpl, diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 04580b70b8..aa0c034a55 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3657,8 +3657,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, CXXRecordDecl *Def = cast_or_null<CXXRecordDecl>(Pattern->getDefinition(Context)); if (!Def) { - Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member_class) - << Record->getDeclName() << Record->getDeclContext(); + Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member) + << 0 << Record->getDeclName() << Record->getDeclContext(); Diag(Pattern->getLocation(), diag::note_forward_declaration) << Pattern; return true; @@ -3787,7 +3787,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, // FIXME: Check for prior specializations and such. Prev->setTemplateSpecializationKind(TSK); if (TSK == TSK_ExplicitInstantiationDefinition) - InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false); + InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false, + /*DefinitionRequired=*/true); // FIXME: Create an ExplicitInstantiation node? return DeclPtrTy(); @@ -3887,7 +3888,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, // definition. if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization, - false); + false, /*DefinitionRequired=*/true); Specialization->setTemplateSpecializationKind(TSK); break; diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 060cc55983..ca05d59aba 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1044,9 +1044,14 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, /// /// \param Recursive if true, recursively instantiates any functions that /// are required by this instantiation. +/// +/// \param DefinitionRequired if true, then we are performing an explicit +/// instantiation where the body of the function is required. Complain if +/// there is no such body. void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, - bool Recursive) { + bool Recursive, + bool DefinitionRequired) { if (Function->isInvalidDecl()) return; @@ -1075,8 +1080,24 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (PatternDecl) Pattern = PatternDecl->getBody(PatternDecl); - if (!Pattern) + if (!Pattern) { + if (DefinitionRequired) { + if (Function->getPrimaryTemplate()) + Diag(PointOfInstantiation, + diag::err_explicit_instantiation_undefined_func_template) + << Function->getPrimaryTemplate(); + else + Diag(PointOfInstantiation, + diag::err_explicit_instantiation_undefined_member) + << 1 << Function->getDeclName() << Function->getDeclContext(); + + if (PatternDecl) + Diag(PatternDecl->getLocation(), + diag::note_explicit_instantiation_here); + } + return; + } // C++0x [temp.explicit]p9: // Except for inline functions, other explicit instantiation declarations @@ -1161,10 +1182,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, /// /// \param Recursive if true, recursively instantiates any functions that /// are required by this instantiation. +/// +/// \param DefinitionRequired if true, then we are performing an explicit +/// instantiation where an out-of-line definition of the member variable +/// is required. Complain if there is no such definition. void Sema::InstantiateStaticDataMemberDefinition( SourceLocation PointOfInstantiation, VarDecl *Var, - bool Recursive) { + bool Recursive, + bool DefinitionRequired) { if (Var->isInvalidDecl()) return; @@ -1187,6 +1213,13 @@ void Sema::InstantiateStaticDataMemberDefinition( // so we won't perform any instantiation. Rather, we rely on the user to // instantiate this definition (or provide a specialization for it) in // another translation unit. + if (DefinitionRequired) { + Diag(PointOfInstantiation, + diag::err_explicit_instantiation_undefined_member) + << 2 << Var->getDeclName() << Var->getDeclContext(); + Diag(Def->getLocation(), diag::note_explicit_instantiation_here); + } + return; } |