summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-08-23 19:41:39 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-08-23 19:41:39 +0000
commit6f4e2e038d5e72f8860512502c2ba72882eb0f75 (patch)
treead99b28220111579f6866e80c0212880df45c468 /clang/lib/Sema/SemaTemplate.cpp
parentfd49c73f116d3748e2d4f768128ac33247d375a3 (diff)
downloadbcm5719-llvm-6f4e2e038d5e72f8860512502c2ba72882eb0f75.tar.gz
bcm5719-llvm-6f4e2e038d5e72f8860512502c2ba72882eb0f75.zip
Fix regression introduced by r279164: only pass definitions as the PatternDef
to DiagnoseUninstantiableTemplate, teach hasVisibleDefinition to correctly determine whether a function definition is visible, and mark both the function and the template as visible when merging function template definitions to provide hasVisibleDefinition with the relevant information. The change to always pass the right declaration as the PatternDef to DiagnoseUninstantiableTemplate also caused those checks to happen before other diagnostics in InstantiateFunctionDefinition, giving worse diagnostics for the same situations, so I sunk the relevant diagnostics into DiagnoseUninstantiableTemplate. Those parts of this patch are based on changes in reviews.llvm.org/D23492 by Vassil Vassilev. This reinstates r279486, reverted in r279500, with a fix to DiagnoseUninstantiableTemplate to only mark uninstantiable explicit instantiation declarations as invalid if we actually diagnosed them. (When we trigger an explicit instantiation of a class member from an explicit instantiation declaration for the class, it's OK if there is no corresponding definition and we certainly don't want to mark the member invalid in that case.) This previously caused a build failure during bootstrap. llvm-svn: 279557
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp39
1 files changed, 26 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ede1c5bcc64..ea0357a3359 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -483,15 +483,13 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
return false;
}
+ if (!Complain || (PatternDef && PatternDef->isInvalidDecl()))
+ return true;
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) {
+ if (PatternDef) {
Diag(PointOfInstantiation,
diag::err_template_instantiate_within_definition)
<< (TSK != TSK_ImplicitInstantiation)
@@ -500,15 +498,30 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
// 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
OpenPOWER on IntegriCloud