aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 20219d205e..3d909bb26a 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -37,8 +37,7 @@ namespace clang {
TDF_IgnoreQualifiers = 0x02,
/// \brief Within template argument deduction from a function call,
/// we are matching in a case where we can perform template argument
- /// deduction from a derived class of the argument type.
- /// FIXME: this is completely unsupported right now.
+ /// deduction from a template-id of a derived class of the argument type.
TDF_DerivedClass = 0x04
};
}
@@ -299,11 +298,11 @@ DeduceTemplateArguments(ASTContext &Context,
if (!PointerArg)
return Sema::TDK_NonDeducedMismatch;
+ unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
return DeduceTemplateArguments(Context, TemplateParams,
cast<PointerType>(Param)->getPointeeType(),
PointerArg->getPointeeType(),
- Info, Deduced,
- TDF & TDF_IgnoreQualifiers);
+ Info, Deduced, SubTDF);
}
// T &
@@ -499,6 +498,11 @@ DeduceTemplateArguments(ASTContext &Context,
if (!RecordArg)
return Sema::TDK_NonDeducedMismatch;
+ // FIXME: Check TDF_DerivedClass here. When this flag is set, we need
+ // to troll through the base classes of the argument and try matching
+ // all of them. Failure to match does not mean that there is a problem,
+ // of course.
+
ClassTemplateSpecializationDecl *SpecArg
= dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
if (!SpecArg)
@@ -849,6 +853,15 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
return TDK_Success;
}
+/// \brief Determine whether the given type T is a simple-template-id type.
+static bool isSimpleTemplateIdType(QualType T) {
+ if (const TemplateSpecializationType *Spec
+ = T->getAsTemplateSpecializationType())
+ return Spec->getTemplateName().getAsTemplateDecl() != 0;
+
+ return false;
+}
+
/// \brief Perform template argument deduction from a function call
/// (C++ [temp.deduct.call]).
///
@@ -965,7 +978,17 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// conversion (4.4).
if (ArgType->isPointerType() || ArgType->isMemberPointerType())
TDF |= TDF_IgnoreQualifiers;
- // FIXME: derived -> base checks
+ // - If P is a class and P has the form simple-template-id, then the
+ // transformed A can be a derived class of the deduced A. Likewise,
+ // if P is a pointer to a class of the form simple-template-id, the
+ // transformed A can be a pointer to a derived class pointed to by
+ // the deduced A.
+ if (isSimpleTemplateIdType(ParamType) ||
+ (isa<PointerType>(ParamType) &&
+ isSimpleTemplateIdType(
+ ParamType->getAsPointerType()->getPointeeType())))
+ TDF |= TDF_DerivedClass;
+
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(Context, TemplateParams,
ParamType, ArgType, Info, Deduced,