From 4112877d1043d0b937f5abcf043bc7fa48138f05 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 26 Jun 2009 23:27:24 +0000 Subject: [PATCH] Set the rest of the flags we need to perform template argument deduction using a base class of the argument type. No actual functionality change; this is just a hook. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74356 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateDeduction.cpp | 33 +++++++++++++++++++++++++----- 1 file 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(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(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(ParamType) && + isSimpleTemplateIdType( + ParamType->getAsPointerType()->getPointeeType()))) + TDF |= TDF_DerivedClass; + if (TemplateDeductionResult Result = ::DeduceTemplateArguments(Context, TemplateParams, ParamType, ArgType, Info, Deduced, -- 2.40.0