QualType InstantiationTy;
if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
InstantiationTy = Context.getTypeDeclType(TD);
- else
- InstantiationTy = cast<FunctionDecl>(Instantiation)->getType();
if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) {
// Say nothing
} else if (PatternDef) {
// we're lexically inside it.
Instantiation->setInvalidDecl();
} else if (InstantiatedFromMember) {
- Diag(PointOfInstantiation,
- diag::err_implicit_instantiate_member_undefined)
- << InstantiationTy;
- Diag(Pattern->getLocation(), diag::note_member_declared_at);
+ if (isa<FunctionDecl>(Instantiation)) {
+ Diag(PointOfInstantiation,
+ diag::err_explicit_instantiation_undefined_member)
+ << 1 << Instantiation->getDeclName() << Instantiation->getDeclContext();
+ } else {
+ Diag(PointOfInstantiation,
+ diag::err_implicit_instantiate_member_undefined)
+ << InstantiationTy;
+ }
+ Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
+ ? diag::note_explicit_instantiation_here
+ : diag::note_member_declared_at);
} else {
- Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
- << (TSK != TSK_ImplicitInstantiation)
- << InstantiationTy;
- Diag(Pattern->getLocation(), diag::note_template_decl_here);
+ if (isa<FunctionDecl>(Instantiation))
+ Diag(PointOfInstantiation,
+ diag::err_explicit_instantiation_undefined_func_template)
+ << Pattern;
+ else
+ Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
+ << (TSK != TSK_ImplicitInstantiation)
+ << InstantiationTy;
+ Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
+ ? diag::note_explicit_instantiation_here
+ : diag::note_template_decl_here);
}
// In general, Instantiation isn't marked invalid to get more than one
const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();
assert(PatternDecl && "instantiating a non-template");
- Stmt *Pattern = PatternDecl->getBody(PatternDecl);
- assert(PatternDecl && "template definition is not a template");
- if (!Pattern) {
- // Try to find a defaulted definition
- PatternDecl->isDefined(PatternDecl);
- }
- assert(PatternDecl && "template definition is not a template");
+ const FunctionDecl *PatternDef = PatternDecl->getDefinition();
+ Stmt *Pattern = PatternDef->getBody(PatternDef);
+ if (PatternDef)
+ PatternDecl = PatternDef;
// FIXME: We need to track the instantiation stack in order to know which
// definitions should be visible within this instantiation.
if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
Function->getInstantiatedFromMemberFunction(),
- PatternDecl, PatternDecl, TSK,
- /*Complain*/DefinitionRequired))
- return;
-
+ PatternDecl, PatternDef, TSK,
+ /*Complain*/DefinitionRequired)) {
+ if (DefinitionRequired)
+ Function->setInvalidDecl();
+ else if (TSK == TSK_ExplicitInstantiationDefinition) {
+ // Try again at the end of the translation unit (at which point a
+ // definition will be required).
+ assert(!Recursive);
+ PendingInstantiations.push_back(
+ std::make_pair(Function, PointOfInstantiation));
+ } else if (TSK == TSK_ImplicitInstantiation) {
+ if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
+ Diag(PointOfInstantiation, diag::warn_func_template_missing)
+ << Function;
+ Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
+ if (getLangOpts().CPlusPlus11)
+ Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
+ << Function;
+ }
+ }
+ return;
+ }
// Postpone late parsed template instantiations.
if (PatternDecl->isLateTemplateParsed() &&
Pattern = PatternDecl->getBody(PatternDecl);
}
- // FIXME: Check if we could sink these diagnostics in
- // DiagnoseUninstantiableTemplate.
- if (!Pattern && !PatternDecl->isDefaulted()) {
- 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);
- Function->setInvalidDecl();
- } else if (TSK == TSK_ExplicitInstantiationDefinition) {
- assert(!Recursive);
- PendingInstantiations.push_back(
- std::make_pair(Function, PointOfInstantiation));
- } else if (TSK == TSK_ImplicitInstantiation) {
- if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
- Diag(PointOfInstantiation, diag::warn_func_template_missing)
- << Function;
- Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
- if (getLangOpts().CPlusPlus11)
- Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
- << Function;
- }
- }
-
- return;
- }
+ // Note, we should never try to instantiate a deleted function template.
+ assert((Pattern || PatternDecl->isDefaulted()) &&
+ "unexpected kind of function template definition");
// C++1y [temp.explicit]p10:
// Except for inline functions, declarations with types deduced from their