aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-26 18:27:22 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-26 18:27:22 +0000
commit500d331eade2f5070b66ba51d777224f9fda6e1d (patch)
tree1bde7f5dd9d27f271a9f3e8eae3d9fcbf93ed381 /lib/Sema/SemaTemplateDeduction.cpp
parente8c9e9218f215ec6089f12b076c7b9d310fd5194 (diff)
Improve template argument deduction for reference parameters when
deducing template arguments from a function call. Plus, add a bunch of tests. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74301 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 03466f02a2..66e12fefe6 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -156,17 +156,49 @@ DeduceTemplateArguments(ASTContext &Context,
return Sema::TDK_Success;
}
+/// \brief Deduce the template arguments by comparing the parameter type and
+/// the argument type (C++ [temp.deduct.type]).
+///
+/// \param Context the AST context in which this deduction occurs.
+///
+/// \param TemplateParams the template parameters that we are deducing
+///
+/// \param ParamIn the parameter type
+///
+/// \param ArgIn the argument type
+///
+/// \param Info information about the template argument deduction itself
+///
+/// \param Deduced the deduced template arguments
+///
+/// \param ParamTypeWasReference if true, the original parameter type was
+/// a reference type (C++0x [temp.deduct.type]p4 bullet 1).
+///
+/// \returns the result of template argument deduction so far. Note that a
+/// "success" result means that template argument deduction has not yet failed,
+/// but it may still fail, later, for other reasons.
static Sema::TemplateDeductionResult
DeduceTemplateArguments(ASTContext &Context,
TemplateParameterList *TemplateParams,
QualType ParamIn, QualType ArgIn,
Sema::TemplateDeductionInfo &Info,
- llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
+ llvm::SmallVectorImpl<TemplateArgument> &Deduced,
+ bool ParamTypeWasReference = false) {
// We only want to look at the canonical types, since typedefs and
// sugar are not part of template argument deduction.
QualType Param = Context.getCanonicalType(ParamIn);
QualType Arg = Context.getCanonicalType(ArgIn);
+ // C++0x [temp.deduct.call]p4 bullet 1:
+ // - If the original P is a reference type, the deduced A (i.e., the type
+ // referred to by the reference) can be more cv-qualified than the
+ // transformed A.
+ if (ParamTypeWasReference) {
+ unsigned ExtraQualsOnParam
+ = Param.getCVRQualifiers() & ~Arg.getCVRQualifiers();
+ Param.setCVRQualifiers(Param.getCVRQualifiers() & ~ExtraQualsOnParam);
+ }
+
// If the parameter type is not dependent, just compare the types
// directly.
if (!Param->isDependentType()) {
@@ -761,7 +793,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
CheckArgs = Function->getNumParams();
}
+ // Template argument deduction for function templates in a SFINAE context.
+ // Trap any errors that might occur.
SFINAETrap Trap(*this);
+
+ // Deduce template arguments from the function parameters.
llvm::SmallVector<TemplateArgument, 4> Deduced;
Deduced.resize(FunctionTemplate->getTemplateParameters()->size());
TemplateParameterList *TemplateParams
@@ -769,11 +805,12 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
for (unsigned I = 0; I != CheckArgs; ++I) {
QualType ParamType = Function->getParamDecl(I)->getType();
QualType ArgType = Args[I]->getType();
-
+
// C++ [temp.deduct.call]p2:
// If P is not a reference type:
QualType CanonParamType = Context.getCanonicalType(ParamType);
- if (!isa<ReferenceType>(CanonParamType)) {
+ bool ParamWasReference = isa<ReferenceType>(CanonParamType);
+ if (!ParamWasReference) {
// - If A is an array type, the pointer type produced by the
// array-to-pointer standard conversion (4.2) is used in place of
// A for type deduction; otherwise,
@@ -822,7 +859,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// arguments from a type.
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(Context, TemplateParams,
- ParamType, ArgType, Info, Deduced))
+ ParamType, ArgType, Info, Deduced,
+ ParamWasReference))
return Result;
// FIXME: C++ [temp.deduct.call] paragraphs 6-9 deal with function