aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaTemplate.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp39
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;
}