aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-25 18:55:14 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-25 18:55:14 +0000
commit51ffb0c9d43b2d3fd210e51ecdd67ba5d1790d70 (patch)
treeb54f10a7404e78f0acec5514b3c70a0c0d13c704 /lib/Sema/SemaTemplateDeduction.cpp
parent5b6d70e2dece713de82612ffbac2f2bc5c367f73 (diff)
Implement support for default template arguments of function templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89874 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp56
1 files changed, 41 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index c5571d1643..06b2dec590 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1272,18 +1272,56 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
+ // Template argument deduction for function templates in a SFINAE context.
+ // Trap any errors that might occur.
+ SFINAETrap Trap(*this);
+
+ // Enter a new template instantiation context while we instantiate the
+ // actual function declaration.
+ InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+ FunctionTemplate, Deduced.data(), Deduced.size(),
+ ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+ if (Inst)
+ return TDK_InstantiationDepth;
+
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
TemplateArgumentListBuilder Builder(TemplateParams, Deduced.size());
for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
- if (Deduced[I].isNull()) {
+ if (!Deduced[I].isNull()) {
+ Builder.Append(Deduced[I]);
+ continue;
+ }
+
+ // Substitute into the default template argument, if available.
+ NamedDecl *Param = FunctionTemplate->getTemplateParameters()->getParam(I);
+ TemplateArgumentLoc DefArg
+ = SubstDefaultTemplateArgumentIfAvailable(FunctionTemplate,
+ FunctionTemplate->getLocation(),
+ FunctionTemplate->getSourceRange().getEnd(),
+ Param,
+ Builder);
+
+ // If there was no default argument, deduction is incomplete.
+ if (DefArg.getArgument().isNull()) {
Info.Param = makeTemplateParameter(
- const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+ const_cast<NamedDecl *>(TemplateParams->getParam(I)));
return TDK_Incomplete;
}
+
+ // Check whether we can actually use the default argument.
+ if (CheckTemplateArgument(Param, DefArg,
+ FunctionTemplate,
+ FunctionTemplate->getLocation(),
+ FunctionTemplate->getSourceRange().getEnd(),
+ Builder)) {
+ Info.Param = makeTemplateParameter(
+ const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+ return TDK_SubstitutionFailure;
+ }
- Builder.Append(Deduced[I]);
+ // If we get here, we successfully used the default template argument.
}
// Form the template argument list from the deduced template arguments.
@@ -1291,18 +1329,6 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
= new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
Info.reset(DeducedArgumentList);
- // Template argument deduction for function templates in a SFINAE context.
- // Trap any errors that might occur.
- SFINAETrap Trap(*this);
-
- // Enter a new template instantiation context while we instantiate the
- // actual function declaration.
- InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
- FunctionTemplate, Deduced.data(), Deduced.size(),
- ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
- if (Inst)
- return TDK_InstantiationDepth;
-
// Substitute the deduced template arguments into the function template
// declaration to produce the function template specialization.
Specialization = cast_or_null<FunctionDecl>(