diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-25 18:55:14 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-25 18:55:14 +0000 |
commit | 51ffb0c9d43b2d3fd210e51ecdd67ba5d1790d70 (patch) | |
tree | b54f10a7404e78f0acec5514b3c70a0c0d13c704 /lib/Sema/SemaTemplateDeduction.cpp | |
parent | 5b6d70e2dece713de82612ffbac2f2bc5c367f73 (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.cpp | 56 |
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>( |