summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-01 22:01:06 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-01 22:01:06 +0000
commitff6cbdf806da9fb5a62ebf7721660940d4bbb838 (patch)
tree32f70cd644e774775cdb7a83630a2e531dc769ad /clang/lib/Sema/SemaTemplateInstantiate.cpp
parentaffb68bd08a2cd0f1e4dbeacfbdc1acc14c589ba (diff)
downloadbcm5719-llvm-ff6cbdf806da9fb5a62ebf7721660940d4bbb838.tar.gz
bcm5719-llvm-ff6cbdf806da9fb5a62ebf7721660940d4bbb838.zip
Keep track of more information within the template instantiation stack, e.g.,
by distinguishing between substitution that occurs for template argument deduction vs. explicitly-specifiad template arguments. This is used both to improve diagnostics and to make sure we only provide SFINAE in those cases where SFINAE should apply. In addition, deal with the sticky issue where SFINAE only considers substitution of template arguments into the *type* of a function template; we need to issue hard errors beyond this point, as test/SemaTemplate/operator-template.cpp illustrates. llvm-svn: 74651
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp79
1 files changed, 59 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3bc1cf9504b..6c2dc77b4cc 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -100,6 +100,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
SourceLocation PointOfInstantiation,
+ FunctionTemplateDecl *FunctionTemplate,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ SourceRange InstantiationRange)
+: SemaRef(SemaRef) {
+
+ Invalid = CheckInstantiationDepth(PointOfInstantiation,
+ InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind = Kind;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Entity = reinterpret_cast<uintptr_t>(FunctionTemplate);
+ Inst.TemplateArgs = TemplateArgs;
+ Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ Invalid = false;
+ }
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+ SourceLocation PointOfInstantiation,
ClassTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
@@ -111,7 +135,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
if (!Invalid) {
ActiveTemplateInstantiation Inst;
Inst.Kind
- = ActiveTemplateInstantiation::PartialSpecDeductionInstantiation;
+ = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec);
Inst.TemplateArgs = TemplateArgs;
@@ -148,6 +172,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
/// \brief Prints the current instantiation stack through a series of
/// notes.
void Sema::PrintInstantiationStack() {
+ // FIXME: In all of these cases, we need to show the template arguments
for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
@@ -183,7 +208,7 @@ void Sema::PrintInstantiationStack() {
TemplateDecl *Template = cast<TemplateDecl>((Decl *)Active->Entity);
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
- Active->TemplateArgs,
+ Active->TemplateArgs,
Active->NumTemplateArgs,
Context.PrintingPolicy);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
@@ -193,18 +218,31 @@ void Sema::PrintInstantiationStack() {
break;
}
- case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation: {
- ClassTemplatePartialSpecializationDecl *PartialSpec
- = cast<ClassTemplatePartialSpecializationDecl>((Decl *)Active->Entity);
- // FIXME: The active template instantiation's template arguments
- // are interesting, too. We should add something like [with T =
- // foo, U = bar, etc.] to the string.
+ case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
+ FunctionTemplateDecl *FnTmpl
+ = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
- diag::note_partial_spec_deduct_instantiation_here)
- << Context.getTypeDeclType(PartialSpec)
- << Active->InstantiationRange;
+ diag::note_explicit_template_arg_substitution_here)
+ << FnTmpl << Active->InstantiationRange;
break;
}
+
+ case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+ if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ = dyn_cast<ClassTemplatePartialSpecializationDecl>(
+ (Decl *)Active->Entity)) {
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ diag::note_partial_spec_deduct_instantiation_here)
+ << Context.getTypeDeclType(PartialSpec)
+ << Active->InstantiationRange;
+ } else {
+ FunctionTemplateDecl *FnTmpl
+ = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ diag::note_function_template_deduction_instantiation_here)
+ << FnTmpl << Active->InstantiationRange;
+ }
+ break;
}
}
@@ -219,19 +257,20 @@ bool Sema::isSFINAEContext() const {
++Active) {
switch(Active->Kind) {
- case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation:
- // We're in a template argument deduction context, so SFINAE
- // applies.
- return true;
-
+ case ActiveTemplateInstantiation::TemplateInstantiation:
+ // This is a template instantiation, so there is no SFINAE.
+ return false;
+
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
// A default template argument instantiation may or may not be a
// SFINAE context; look further up the stack.
break;
-
- case ActiveTemplateInstantiation::TemplateInstantiation:
- // This is a template instantiation, so there is no SFINAE.
- return false;
+
+ case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution:
+ case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+ // We're either substitution explicitly-specified template arguments
+ // or deduced template arguments, so SFINAE applies.
+ return true;
}
}
OpenPOWER on IntegriCloud