blob: f8e825ff941ad8517f7b4396524468c95736b2b4 [file] [log] [blame]
//===------- SemaTemplateDeduction.cpp - Template Argument Deduction ------===/
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===/
//
// This file implements C++ template argument deduction.
//
//===----------------------------------------------------------------------===/
#include "clang/Sema/TemplateDeduction.h"
#include "TreeTransform.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/SmallBitVector.h"
#include <algorithm>
namespace clang {
using namespace sema;
/// \brief Various flags that control template argument deduction.
///
/// These flags can be bitwise-OR'd together.
enum TemplateDeductionFlags {
/// \brief No template argument deduction flags, which indicates the
/// strictest results for template argument deduction (as used for, e.g.,
/// matching class template partial specializations).
TDF_None = 0,
/// \brief Within template argument deduction from a function call, we are
/// matching with a parameter type for which the original parameter was
/// a reference.
TDF_ParamWithReferenceType = 0x1,
/// \brief Within template argument deduction from a function call, we
/// are matching in a case where we ignore cv-qualifiers.
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 template-id of a derived class of the argument type.
TDF_DerivedClass = 0x04,
/// \brief Allow non-dependent types to differ, e.g., when performing
/// template argument deduction from a function call where conversions
/// may apply.
TDF_SkipNonDependent = 0x08,
/// \brief Whether we are performing template argument deduction for
/// parameters and arguments in a top-level template argument
TDF_TopLevelParameterTypeList = 0x10,
/// \brief Within template argument deduction from overload resolution per
/// C++ [over.over] allow matching function types that are compatible in
/// terms of noreturn and default calling convention adjustments.
TDF_InOverloadResolution = 0x20
};
}
using namespace clang;
/// \brief Compare two APSInts, extending and switching the sign as
/// necessary to compare their values regardless of underlying type.
static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) {
if (Y.getBitWidth() > X.getBitWidth())
X = X.extend(Y.getBitWidth());
else if (Y.getBitWidth() < X.getBitWidth())
Y = Y.extend(X.getBitWidth());
// If there is a signedness mismatch, correct it.
if (X.isSigned() != Y.isSigned()) {
// If the signed value is negative, then the values cannot be the same.
if ((Y.isSigned() && Y.isNegative()) || (X.isSigned() && X.isNegative()))
return false;
Y.setIsSigned(true);
X.setIsSigned(true);
}
return X == Y;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgument &Param,
TemplateArgument Arg,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced);
static Sema::TemplateDeductionResult
DeduceTemplateArgumentsByTypeMatch(Sema &S,
TemplateParameterList *TemplateParams,
QualType Param,
QualType Arg,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &
Deduced,
unsigned TDF,
bool PartialOrdering = false);
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
const TemplateArgument *Params, unsigned NumParams,
const TemplateArgument *Args, unsigned NumArgs,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch);
/// \brief If the given expression is of a form that permits the deduction
/// of a non-type template parameter, return the declaration of that
/// non-type template parameter.
static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) {
// If we are within an alias template, the expression may have undergone
// any number of parameter substitutions already.
while (1) {
if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
E = IC->getSubExpr();
else if (SubstNonTypeTemplateParmExpr *Subst =
dyn_cast<SubstNonTypeTemplateParmExpr>(E))
E = Subst->getReplacement();
else
break;
}
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
return nullptr;
}
/// \brief Determine whether two declaration pointers refer to the same
/// declaration.
static bool isSameDeclaration(Decl *X, Decl *Y) {
if (NamedDecl *NX = dyn_cast<NamedDecl>(X))
X = NX->getUnderlyingDecl();
if (NamedDecl *NY = dyn_cast<NamedDecl>(Y))
Y = NY->getUnderlyingDecl();
return X->getCanonicalDecl() == Y->getCanonicalDecl();
}
/// \brief Verify that the given, deduced template arguments are compatible.
///
/// \returns The deduced template argument, or a NULL template argument if
/// the deduced template arguments were incompatible.
static DeducedTemplateArgument
checkDeducedTemplateArguments(ASTContext &Context,
const DeducedTemplateArgument &X,
const DeducedTemplateArgument &Y) {
// We have no deduction for one or both of the arguments; they're compatible.
if (X.isNull())
return Y;
if (Y.isNull())
return X;
switch (X.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Non-deduced template arguments handled above");
case TemplateArgument::Type:
// If two template type arguments have the same type, they're compatible.
if (Y.getKind() == TemplateArgument::Type &&
Context.hasSameType(X.getAsType(), Y.getAsType()))
return X;
return DeducedTemplateArgument();
case TemplateArgument::Integral:
// If we deduced a constant in one case and either a dependent expression or
// declaration in another case, keep the integral constant.
// If both are integral constants with the same value, keep that value.
if (Y.getKind() == TemplateArgument::Expression ||
Y.getKind() == TemplateArgument::Declaration ||
(Y.getKind() == TemplateArgument::Integral &&
hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral())))
return DeducedTemplateArgument(X,
X.wasDeducedFromArrayBound() &&
Y.wasDeducedFromArrayBound());
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::Template:
if (Y.getKind() == TemplateArgument::Template &&
Context.hasSameTemplateName(X.getAsTemplate(), Y.getAsTemplate()))
return X;
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::TemplateExpansion:
if (Y.getKind() == TemplateArgument::TemplateExpansion &&
Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(),
Y.getAsTemplateOrTemplatePattern()))
return X;
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::Expression:
// If we deduced a dependent expression in one case and either an integral
// constant or a declaration in another case, keep the integral constant
// or declaration.
if (Y.getKind() == TemplateArgument::Integral ||
Y.getKind() == TemplateArgument::Declaration)
return DeducedTemplateArgument(Y, X.wasDeducedFromArrayBound() &&
Y.wasDeducedFromArrayBound());
if (Y.getKind() == TemplateArgument::Expression) {
// Compare the expressions for equality
llvm::FoldingSetNodeID ID1, ID2;
X.getAsExpr()->Profile(ID1, Context, true);
Y.getAsExpr()->Profile(ID2, Context, true);
if (ID1 == ID2)
return X;
}
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::Declaration:
// If we deduced a declaration and a dependent expression, keep the
// declaration.
if (Y.getKind() == TemplateArgument::Expression)
return X;
// If we deduced a declaration and an integral constant, keep the
// integral constant.
if (Y.getKind() == TemplateArgument::Integral)
return Y;
// If we deduced two declarations, make sure they they refer to the
// same declaration.
if (Y.getKind() == TemplateArgument::Declaration &&
isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))
return X;
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::NullPtr:
// If we deduced a null pointer and a dependent expression, keep the
// null pointer.
if (Y.getKind() == TemplateArgument::Expression)
return X;
// If we deduced a null pointer and an integral constant, keep the
// integral constant.
if (Y.getKind() == TemplateArgument::Integral)
return Y;
// If we deduced two null pointers, make sure they have the same type.
if (Y.getKind() == TemplateArgument::NullPtr &&
Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType()))
return X;
// All other combinations are incompatible.
return DeducedTemplateArgument();
case TemplateArgument::Pack:
if (Y.getKind() != TemplateArgument::Pack ||
X.pack_size() != Y.pack_size())
return DeducedTemplateArgument();
for (TemplateArgument::pack_iterator XA = X.pack_begin(),
XAEnd = X.pack_end(),
YA = Y.pack_begin();
XA != XAEnd; ++XA, ++YA) {
// FIXME: Do we need to merge the results together here?
if (checkDeducedTemplateArguments(Context,
DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
.isNull())
return DeducedTemplateArgument();
}
return X;
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given constant.
static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
Sema &S, NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value,
QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
DeducedTemplateArgument NewDeduced(S.Context, Value, ValueType,
DeducedFromArrayBound);
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given type- or value-dependent expression.
///
/// \returns true if deduction succeeded, false otherwise.
static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
Expr *Value,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
assert((Value->isTypeDependent() || Value->isValueDependent()) &&
"Expression template argument must be type- or value-dependent.");
DeducedTemplateArgument NewDeduced(Value);
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given declaration.
///
/// \returns true if deduction succeeded, false otherwise.
static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
ValueDecl *D,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
TemplateArgument New(D, NTTP->getType());
DeducedTemplateArgument NewDeduced(New);
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
TemplateName Param,
TemplateName Arg,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
if (!ParamDecl) {
// The parameter type is dependent and is not a template template parameter,
// so there is nothing that we can deduce.
return Sema::TDK_Success;
}
if (TemplateTemplateParmDecl *TempParam
= dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
DeducedTemplateArgument NewDeduced(S.Context.getCanonicalTemplateName(Arg));
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[TempParam->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = TempParam;
Info.FirstArg = Deduced[TempParam->getIndex()];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[TempParam->getIndex()] = Result;
return Sema::TDK_Success;
}
// Verify that the two template names are equivalent.
if (S.Context.hasSameTemplateName(Param, Arg))
return Sema::TDK_Success;
// Mismatch of non-dependent template parameter to argument.
Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_NonDeducedMismatch;
}
/// \brief Deduce the template arguments by comparing the template parameter
/// type (which is a template-id) with the template argument type.
///
/// \param S the Sema
///
/// \param TemplateParams the template parameters that we are deducing
///
/// \param Param the parameter type
///
/// \param Arg the argument type
///
/// \param Info information about the template argument deduction itself
///
/// \param Deduced the deduced template arguments
///
/// \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(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateSpecializationType *Param,
QualType Arg,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(Arg.isCanonical() && "Argument type must be canonical");
// Check whether the template argument is a dependent template-id.
if (const TemplateSpecializationType *SpecArg
= dyn_cast<TemplateSpecializationType>(Arg)) {
// Perform template argument deduction for the template name.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams,
Param->getTemplateName(),
SpecArg->getTemplateName(),
Info, Deduced))
return Result;
// Perform template argument deduction on each template
// argument. Ignore any missing/extra arguments, since they could be
// filled in by default arguments.
return DeduceTemplateArguments(S, TemplateParams, Param->getArgs(),
Param->getNumArgs(), SpecArg->getArgs(),
SpecArg->getNumArgs(), Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
}
// If the argument type is a class template specialization, we
// perform template argument deduction using its template
// arguments.
const RecordType *RecordArg = dyn_cast<RecordType>(Arg);
if (!RecordArg) {
Info.FirstArg = TemplateArgument(QualType(Param, 0));
Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_NonDeducedMismatch;
}
ClassTemplateSpecializationDecl *SpecArg
= dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
if (!SpecArg) {
Info.FirstArg = TemplateArgument(QualType(Param, 0));
Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_NonDeducedMismatch;
}
// Perform template argument deduction for the template name.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S,
TemplateParams,
Param->getTemplateName(),
TemplateName(SpecArg->getSpecializedTemplate()),
Info, Deduced))
return Result;
// Perform template argument deduction for the template arguments.
return DeduceTemplateArguments(
S, TemplateParams, Param->getArgs(), Param->getNumArgs(),
SpecArg->getTemplateArgs().data(), SpecArg->getTemplateArgs().size(),
Info, Deduced, /*NumberOfArgumentsMustMatch=*/true);
}
/// \brief Determines whether the given type is an opaque type that
/// might be more qualified when instantiated.
static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
switch (T->getTypeClass()) {
case Type::TypeOfExpr:
case Type::TypeOf:
case Type::DependentName:
case Type::Decltype:
case Type::UnresolvedUsing:
case Type::TemplateTypeParm:
return true;
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::DependentSizedArray:
return IsPossiblyOpaquelyQualifiedType(
cast<ArrayType>(T)->getElementType());
default:
return false;
}
}
/// \brief Retrieve the depth and index of a template parameter.
static std::pair<unsigned, unsigned>
getDepthAndIndex(NamedDecl *ND) {
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
return std::make_pair(TTP->getDepth(), TTP->getIndex());
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
return std::make_pair(TTP->getDepth(), TTP->getIndex());
}
/// \brief Retrieve the depth and index of an unexpanded parameter pack.
static std::pair<unsigned, unsigned>
getDepthAndIndex(UnexpandedParameterPack UPP) {
if (const TemplateTypeParmType *TTP
= UPP.first.dyn_cast<const TemplateTypeParmType *>())
return std::make_pair(TTP->getDepth(), TTP->getIndex());
return getDepthAndIndex(UPP.first.get<NamedDecl *>());
}
/// \brief Helper function to build a TemplateParameter when we don't
/// know its type statically.
static TemplateParameter makeTemplateParameter(Decl *D) {
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D))
return TemplateParameter(TTP);
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
return TemplateParameter(NTTP);
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
/// A pack that we're currently deducing.
struct clang::DeducedPack {
DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {}
// The index of the pack.
unsigned Index;
// The old value of the pack before we started deducing it.
DeducedTemplateArgument Saved;
// A deferred value of this pack from an inner deduction, that couldn't be
// deduced because this deduction hadn't happened yet.
DeducedTemplateArgument DeferredDeduction;
// The new value of the pack.
SmallVector<DeducedTemplateArgument, 4> New;
// The outer deduction for this pack, if any.
DeducedPack *Outer;
};
namespace {
/// A scope in which we're performing pack deduction.
class PackDeductionScope {
public:
PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info, TemplateArgument Pattern)
: S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
// Compute the set of template parameter indices that correspond to
// parameter packs expanded by the pack expansion.
{
llvm::SmallBitVector SawIndices(TemplateParams->size());
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
unsigned Depth, Index;
std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
if (Depth == 0 && !SawIndices[Index]) {
SawIndices[Index] = true;
// Save the deduced template argument for the parameter pack expanded
// by this pack expansion, then clear out the deduction.
DeducedPack Pack(Index);
Pack.Saved = Deduced[Index];
Deduced[Index] = TemplateArgument();
Packs.push_back(Pack);
}
}
}
assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
for (auto &Pack : Packs) {
if (Info.PendingDeducedPacks.size() > Pack.Index)
Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
else
Info.PendingDeducedPacks.resize(Pack.Index + 1);
Info.PendingDeducedPacks[Pack.Index] = &Pack;
if (S.CurrentInstantiationScope) {
// If the template argument pack was explicitly specified, add that to
// the set of deduced arguments.
const TemplateArgument *ExplicitArgs;
unsigned NumExplicitArgs;
NamedDecl *PartiallySubstitutedPack =
S.CurrentInstantiationScope->getPartiallySubstitutedPack(
&ExplicitArgs, &NumExplicitArgs);
if (PartiallySubstitutedPack &&
getDepthAndIndex(PartiallySubstitutedPack).second == Pack.Index)
Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs);
}
}
}
~PackDeductionScope() {
for (auto &Pack : Packs)
Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
}
/// Move to deducing the next element in each pack that is being deduced.
void nextPackElement() {
// Capture the deduced template arguments for each parameter pack expanded
// by this pack expansion, add them to the list of arguments we've deduced
// for that pack, then clear out the deduced argument.
for (auto &Pack : Packs) {
DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
if (!DeducedArg.isNull()) {
Pack.New.push_back(DeducedArg);
DeducedArg = DeducedTemplateArgument();
}
}
}
/// \brief Finish template argument deduction for a set of argument packs,
/// producing the argument packs and checking for consistency with prior
/// deductions.
Sema::TemplateDeductionResult finish(bool HasAnyArguments) {
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
for (auto &Pack : Packs) {
// Put back the old value for this pack.
Deduced[Pack.Index] = Pack.Saved;
// Build or find a new value for this pack.
DeducedTemplateArgument NewPack;
if (HasAnyArguments && Pack.New.empty()) {
if (Pack.DeferredDeduction.isNull()) {
// We were not able to deduce anything for this parameter pack
// (because it only appeared in non-deduced contexts), so just
// restore the saved argument pack.
continue;
}
NewPack = Pack.DeferredDeduction;
Pack.DeferredDeduction = TemplateArgument();
} else if (Pack.New.empty()) {
// If we deduced an empty argument pack, create it now.
NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
} else {
TemplateArgument *ArgumentPack =
new (S.Context) TemplateArgument[Pack.New.size()];
std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
NewPack = DeducedTemplateArgument(
TemplateArgument(llvm::makeArrayRef(ArgumentPack, Pack.New.size())),
Pack.New[0].wasDeducedFromArrayBound());
}
// Pick where we're going to put the merged pack.
DeducedTemplateArgument *Loc;
if (Pack.Outer) {
if (Pack.Outer->DeferredDeduction.isNull()) {
// Defer checking this pack until we have a complete pack to compare
// it against.
Pack.Outer->DeferredDeduction = NewPack;
continue;
}
Loc = &Pack.Outer->DeferredDeduction;
} else {
Loc = &Deduced[Pack.Index];
}
// Check the new pack matches any previous value.
DeducedTemplateArgument OldPack = *Loc;
DeducedTemplateArgument Result =
checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
// If we deferred a deduction of this pack, check that one now too.
if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
OldPack = Result;
NewPack = Pack.DeferredDeduction;
Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
}
if (Result.isNull()) {
Info.Param =
makeTemplateParameter(TemplateParams->getParam(Pack.Index));
Info.FirstArg = OldPack;
Info.SecondArg = NewPack;
return Sema::TDK_Inconsistent;
}
*Loc = Result;
}
return Sema::TDK_Success;
}
private:
Sema &S;
TemplateParameterList *TemplateParams;
SmallVectorImpl<DeducedTemplateArgument> &Deduced;
TemplateDeductionInfo &Info;
SmallVector<DeducedPack, 2> Packs;
};
} // namespace
/// \brief Deduce the template arguments by comparing the list of parameter
/// types to the list of argument types, as in the parameter-type-lists of
/// function types (C++ [temp.deduct.type]p10).
///
/// \param S The semantic analysis object within which we are deducing
///
/// \param TemplateParams The template parameters that we are deducing
///
/// \param Params The list of parameter types
///
/// \param NumParams The number of types in \c Params
///
/// \param Args The list of argument types
///
/// \param NumArgs The number of types in \c Args
///
/// \param Info information about the template argument deduction itself
///
/// \param Deduced the deduced template arguments
///
/// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
/// how template argument deduction is performed.
///
/// \param PartialOrdering If true, we are performing template argument
/// deduction for during partial ordering for a call
/// (C++0x [temp.deduct.partial]).
///
/// \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(Sema &S,
TemplateParameterList *TemplateParams,
const QualType *Params, unsigned NumParams,
const QualType *Args, unsigned NumArgs,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
unsigned TDF,
bool PartialOrdering = false) {
// Fast-path check to see if we have too many/too few arguments.
if (NumParams != NumArgs &&
!(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) &&
!(NumArgs && isa<PackExpansionType>(Args[NumArgs - 1])))
return Sema::TDK_MiscellaneousDeductionFailure;
// C++0x [temp.deduct.type]p10:
// Similarly, if P has a form that contains (T), then each parameter type
// Pi of the respective parameter-type- list of P is compared with the
// corresponding parameter type Ai of the corresponding parameter-type-list
// of A. [...]
unsigned ArgIdx = 0, ParamIdx = 0;
for (; ParamIdx != NumParams; ++ParamIdx) {
// Check argument types.
const PackExpansionType *Expansion
= dyn_cast<PackExpansionType>(Params[ParamIdx]);
if (!Expansion) {
// Simple case: compare the parameter and argument types at this point.
// Make sure we have an argument.
if (ArgIdx >= NumArgs)
return Sema::TDK_MiscellaneousDeductionFailure;
if (isa<PackExpansionType>(Args[ArgIdx])) {
// C++0x [temp.deduct.type]p22:
// If the original function parameter associated with A is a function
// parameter pack and the function parameter associated with P is not
// a function parameter pack, then template argument deduction fails.
return Sema::TDK_MiscellaneousDeductionFailure;
}
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
Params[ParamIdx], Args[ArgIdx],
Info, Deduced, TDF,
PartialOrdering))
return Result;
++ArgIdx;
continue;
}
// C++0x [temp.deduct.type]p5:
// The non-deduced contexts are:
// - A function parameter pack that does not occur at the end of the
// parameter-declaration-clause.
if (ParamIdx + 1 < NumParams)
return Sema::TDK_Success;
// C++0x [temp.deduct.type]p10:
// If the parameter-declaration corresponding to Pi is a function
// parameter pack, then the type of its declarator- id is compared with
// each remaining parameter type in the parameter-type-list of A. Each
// comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by the function parameter pack.
QualType Pattern = Expansion->getPattern();
PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
HasAnyArguments = true;
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern,
Args[ArgIdx], Info, Deduced,
TDF, PartialOrdering))
return Result;
PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
if (auto Result = PackScope.finish(HasAnyArguments))
return Result;
}
// Make sure we don't have any extra arguments.
if (ArgIdx < NumArgs)
return Sema::TDK_MiscellaneousDeductionFailure;
return Sema::TDK_Success;
}
/// \brief Determine whether the parameter has qualifiers that are either
/// inconsistent with or a superset of the argument's qualifiers.
static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType,
QualType ArgType) {
Qualifiers ParamQs = ParamType.getQualifiers();
Qualifiers ArgQs = ArgType.getQualifiers();
if (ParamQs == ArgQs)
return false;
// Mismatched (but not missing) Objective-C GC attributes.
if (ParamQs.getObjCGCAttr() != ArgQs.getObjCGCAttr() &&
ParamQs.hasObjCGCAttr())
return true;
// Mismatched (but not missing) address spaces.
if (ParamQs.getAddressSpace() != ArgQs.getAddressSpace() &&
ParamQs.hasAddressSpace())
return true;
// Mismatched (but not missing) Objective-C lifetime qualifiers.
if (ParamQs.getObjCLifetime() != ArgQs.getObjCLifetime() &&
ParamQs.hasObjCLifetime())
return true;
// CVR qualifier superset.
return (ParamQs.getCVRQualifiers() != ArgQs.getCVRQualifiers()) &&
((ParamQs.getCVRQualifiers() | ArgQs.getCVRQualifiers())
== ParamQs.getCVRQualifiers());
}
/// \brief Compare types for equality with respect to possibly compatible
/// function types (noreturn adjustment, implicit calling conventions). If any
/// of parameter and argument is not a function, just perform type comparison.
///
/// \param Param the template parameter type.
///
/// \param Arg the argument type.
bool Sema::isSameOrCompatibleFunctionType(CanQualType Param,
CanQualType Arg) {
const FunctionType *ParamFunction = Param->getAs<FunctionType>(),
*ArgFunction = Arg->getAs<FunctionType>();
// Just compare if not functions.
if (!ParamFunction || !ArgFunction)
return Param == Arg;
// Noreturn adjustment.
QualType AdjustedParam;
if (IsNoReturnConversion(Param, Arg, AdjustedParam))
return Arg == Context.getCanonicalType(AdjustedParam);
// FIXME: Compatible calling conventions.
return Param == Arg;
}
/// \brief Deduce the template arguments by comparing the parameter type and
/// the argument type (C++ [temp.deduct.type]).
///
/// \param S the semantic analysis object within which we are deducing
///
/// \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 TDF bitwise OR of the TemplateDeductionFlags bits that describe
/// how template argument deduction is performed.
///
/// \param PartialOrdering Whether we're performing template argument deduction
/// in the context of partial ordering (C++0x [temp.deduct.partial]).
///
/// \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
DeduceTemplateArgumentsByTypeMatch(Sema &S,
TemplateParameterList *TemplateParams,
QualType ParamIn, QualType ArgIn,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
unsigned TDF,
bool PartialOrdering) {
// We only want to look at the canonical types, since typedefs and
// sugar are not part of template argument deduction.
QualType Param = S.Context.getCanonicalType(ParamIn);
QualType Arg = S.Context.getCanonicalType(ArgIn);
// If the argument type is a pack expansion, look at its pattern.
// This isn't explicitly called out
if (const PackExpansionType *ArgExpansion
= dyn_cast<PackExpansionType>(Arg))
Arg = ArgExpansion->getPattern();
if (PartialOrdering) {
// C++11 [temp.deduct.partial]p5:
// Before the partial ordering is done, certain transformations are
// performed on the types used for partial ordering:
// - If P is a reference type, P is replaced by the type referred to.
const ReferenceType *ParamRef = Param->getAs<ReferenceType>();
if (ParamRef)
Param = ParamRef->getPointeeType();
// - If A is a reference type, A is replaced by the type referred to.
const ReferenceType *ArgRef = Arg->getAs<ReferenceType>();
if (ArgRef)
Arg = ArgRef->getPointeeType();
if (ParamRef && ArgRef && S.Context.hasSameUnqualifiedType(Param, Arg)) {
// C++11 [temp.deduct.partial]p9:
// If, for a given type, deduction succeeds in both directions (i.e.,
// the types are identical after the transformations above) and both
// P and A were reference types [...]:
// - if [one type] was an lvalue reference and [the other type] was
// not, [the other type] is not considered to be at least as
// specialized as [the first type]
// - if [one type] is more cv-qualified than [the other type],
// [the other type] is not considered to be at least as specialized
// as [the first type]
// Objective-C ARC adds:
// - [one type] has non-trivial lifetime, [the other type] has
// __unsafe_unretained lifetime, and the types are otherwise
// identical
//
// A is "considered to be at least as specialized" as P iff deduction
// succeeds, so we model this as a deduction failure. Note that
// [the first type] is P and [the other type] is A here; the standard
// gets this backwards.
Qualifiers ParamQuals = Param.getQualifiers();
Qualifiers ArgQuals = Arg.getQualifiers();
if ((ParamRef->isLValueReferenceType() &&
!ArgRef->isLValueReferenceType()) ||
ParamQuals.isStrictSupersetOf(ArgQuals) ||
(ParamQuals.hasNonTrivialObjCLifetime() &&
ArgQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
ParamQuals.withoutObjCLifetime() ==
ArgQuals.withoutObjCLifetime())) {
Info.FirstArg = TemplateArgument(ParamIn);
Info.SecondArg = TemplateArgument(ArgIn);
return Sema::TDK_NonDeducedMismatch;
}
}
// C++11 [temp.deduct.partial]p7:
// Remove any top-level cv-qualifiers:
// - If P is a cv-qualified type, P is replaced by the cv-unqualified
// version of P.
Param = Param.getUnqualifiedType();
// - If A is a cv-qualified type, A is replaced by the cv-unqualified
// version of A.
Arg = Arg.getUnqualifiedType();
} else {
// 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 (TDF & TDF_ParamWithReferenceType) {
Qualifiers Quals;
QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
Arg.getCVRQualifiers());
Param = S.Context.getQualifiedType(UnqualParam, Quals);
}
if ((TDF & TDF_TopLevelParameterTypeList) && !Param->isFunctionType()) {
// C++0x [temp.deduct.type]p10:
// If P and A are function types that originated from deduction when
// taking the address of a function template (14.8.2.2) or when deducing
// template arguments from a function declaration (14.8.2.6) and Pi and
// Ai are parameters of the top-level parameter-type-list of P and A,
// respectively, Pi is adjusted if it is an rvalue reference to a
// cv-unqualified template parameter and Ai is an lvalue reference, in
// which case the type of Pi is changed to be the template parameter
// type (i.e., T&& is changed to simply T). [ Note: As a result, when
// Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
// deduced as X&. - end note ]
TDF &= ~TDF_TopLevelParameterTypeList;
if (const RValueReferenceType *ParamRef
= Param->getAs<RValueReferenceType>()) {
if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) &&
!ParamRef->getPointeeType().getQualifiers())
if (Arg->isLValueReferenceType())
Param = ParamRef->getPointeeType();
}
}
}
// C++ [temp.deduct.type]p9:
// A template type argument T, a template template argument TT or a
// template non-type argument i can be deduced if P and A have one of
// the following forms:
//
// T
// cv-list T
if (const TemplateTypeParmType *TemplateTypeParm
= Param->getAs<TemplateTypeParmType>()) {
// Just skip any attempts to deduce from a placeholder type.
if (Arg->isPlaceholderType())
return Sema::TDK_Success;
unsigned Index = TemplateTypeParm->getIndex();
bool RecanonicalizeArg = false;
// If the argument type is an array type, move the qualifiers up to the
// top level, so they can be matched with the qualifiers on the parameter.
if (isa<ArrayType>(Arg)) {
Qualifiers Quals;
Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
if (Quals) {
Arg = S.Context.getQualifiedType(Arg, Quals);
RecanonicalizeArg = true;
}
}
// The argument type can not be less qualified than the parameter
// type.
if (!(TDF & TDF_IgnoreQualifiers) &&
hasInconsistentOrSupersetQualifiersOf(Param, Arg)) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_Underqualified;
}
assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function");
QualType DeducedType = Arg;
// Remove any qualifiers on the parameter from the deduced type.
// We checked the qualifiers for consistency above.
Qualifiers DeducedQs = DeducedType.getQualifiers();
Qualifiers ParamQs = Param.getQualifiers();
DeducedQs.removeCVRQualifiers(ParamQs.getCVRQualifiers());
if (ParamQs.hasObjCGCAttr())
DeducedQs.removeObjCGCAttr();
if (ParamQs.hasAddressSpace())
DeducedQs.removeAddressSpace();
if (ParamQs.hasObjCLifetime())
DeducedQs.removeObjCLifetime();
// Objective-C ARC:
// If template deduction would produce a lifetime qualifier on a type
// that is not a lifetime type, template argument deduction fails.
if (ParamQs.hasObjCLifetime() && !DeducedType->isObjCLifetimeType() &&
!DeducedType->isDependentType()) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_Underqualified;
}
// Objective-C ARC:
// If template deduction would produce an argument type with lifetime type
// but no lifetime qualifier, the __strong lifetime qualifier is inferred.
if (S.getLangOpts().ObjCAutoRefCount &&
DeducedType->isObjCLifetimeType() &&
!DeducedQs.hasObjCLifetime())
DeducedQs.setObjCLifetime(Qualifiers::OCL_Strong);
DeducedType = S.Context.getQualifiedType(DeducedType.getUnqualifiedType(),
DeducedQs);
if (RecanonicalizeArg)
DeducedType = S.Context.getCanonicalType(DeducedType);
DeducedTemplateArgument NewDeduced(DeducedType);
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[Index],
NewDeduced);
if (Result.isNull()) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = Deduced[Index];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[Index] = Result;
return Sema::TDK_Success;
}
// Set up the template argument deduction information for a failure.
Info.FirstArg = TemplateArgument(ParamIn);
Info.SecondArg = TemplateArgument(ArgIn);
// If the parameter is an already-substituted template parameter
// pack, do nothing: we don't know which of its arguments to look
// at, so we have to wait until all of the parameter packs in this
// expansion have arguments.
if (isa<SubstTemplateTypeParmPackType>(Param))
return Sema::TDK_Success;
// Check the cv-qualifiers on the parameter and argument types.
CanQualType CanParam = S.Context.getCanonicalType(Param);
CanQualType CanArg = S.Context.getCanonicalType(Arg);
if (!(TDF & TDF_IgnoreQualifiers)) {
if (TDF & TDF_ParamWithReferenceType) {
if (hasInconsistentOrSupersetQualifiersOf(Param, Arg))
return Sema::TDK_NonDeducedMismatch;
} else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
return Sema::TDK_NonDeducedMismatch;
}
// If the parameter type is not dependent, there is nothing to deduce.
if (!Param->isDependentType()) {
if (!(TDF & TDF_SkipNonDependent)) {
bool NonDeduced = (TDF & TDF_InOverloadResolution)?
!S.isSameOrCompatibleFunctionType(CanParam, CanArg) :
Param != Arg;
if (NonDeduced) {
return Sema::TDK_NonDeducedMismatch;
}
}
return Sema::TDK_Success;
}
} else if (!Param->isDependentType()) {
CanQualType ParamUnqualType = CanParam.getUnqualifiedType(),
ArgUnqualType = CanArg.getUnqualifiedType();
bool Success = (TDF & TDF_InOverloadResolution)?
S.isSameOrCompatibleFunctionType(ParamUnqualType,
ArgUnqualType) :
ParamUnqualType == ArgUnqualType;
if (Success)
return Sema::TDK_Success;
}
switch (Param->getTypeClass()) {
// Non-canonical types cannot appear here.
#define NON_CANONICAL_TYPE(Class, Base) \
case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
#define TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
llvm_unreachable("Type nodes handled above");
// These types cannot be dependent, so simply check whether the types are
// the same.
case Type::Builtin:
case Type::VariableArray:
case Type::Vector:
case Type::FunctionNoProto:
case Type::Record:
case Type::Enum:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer: {
if (TDF & TDF_SkipNonDependent)
return Sema::TDK_Success;
if (TDF & TDF_IgnoreQualifiers) {
Param = Param.getUnqualifiedType();
Arg = Arg.getUnqualifiedType();
}
return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch;
}
// _Complex T [placeholder extension]
case Type::Complex:
if (const ComplexType *ComplexArg = Arg->getAs<ComplexType>())
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
cast<ComplexType>(Param)->getElementType(),
ComplexArg->getElementType(),
Info, Deduced, TDF);
return Sema::TDK_NonDeducedMismatch;
// _Atomic T [extension]
case Type::Atomic:
if (const AtomicType *AtomicArg = Arg->getAs<AtomicType>())
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
cast<AtomicType>(Param)->getValueType(),
AtomicArg->getValueType(),
Info, Deduced, TDF);
return Sema::TDK_NonDeducedMismatch;
// T *
case Type::Pointer: {
QualType PointeeType;
if (const PointerType *PointerArg = Arg->getAs<PointerType>()) {
PointeeType = PointerArg->getPointeeType();
} else if (const ObjCObjectPointerType *PointerArg
= Arg->getAs<ObjCObjectPointerType>()) {
PointeeType = PointerArg->getPointeeType();
} else {
return Sema::TDK_NonDeducedMismatch;
}
unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
cast<PointerType>(Param)->getPointeeType(),
PointeeType,
Info, Deduced, SubTDF);
}
// T &
case Type::LValueReference: {
const LValueReferenceType *ReferenceArg =
Arg->getAs<LValueReferenceType>();
if (!ReferenceArg)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
cast<LValueReferenceType>(Param)->getPointeeType(),
ReferenceArg->getPointeeType(), Info, Deduced, 0);
}
// T && [C++0x]
case Type::RValueReference: {
const RValueReferenceType *ReferenceArg =
Arg->getAs<RValueReferenceType>();
if (!ReferenceArg)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
cast<RValueReferenceType>(Param)->getPointeeType(),
ReferenceArg->getPointeeType(),
Info, Deduced, 0);
}
// T [] (implied, but not stated explicitly)
case Type::IncompleteArray: {
const IncompleteArrayType *IncompleteArrayArg =
S.Context.getAsIncompleteArrayType(Arg);
if (!IncompleteArrayArg)
return Sema::TDK_NonDeducedMismatch;
unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
S.Context.getAsIncompleteArrayType(Param)->getElementType(),
IncompleteArrayArg->getElementType(),
Info, Deduced, SubTDF);
}
// T [integer-constant]
case Type::ConstantArray: {
const ConstantArrayType *ConstantArrayArg =
S.Context.getAsConstantArrayType(Arg);
if (!ConstantArrayArg)
return Sema::TDK_NonDeducedMismatch;
const ConstantArrayType *ConstantArrayParm =
S.Context.getAsConstantArrayType(Param);
if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
return Sema::TDK_NonDeducedMismatch;
unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
ConstantArrayParm->getElementType(),
ConstantArrayArg->getElementType(),
Info, Deduced, SubTDF);
}
// type [i]
case Type::DependentSizedArray: {
const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg);
if (!ArrayArg)
return Sema::TDK_NonDeducedMismatch;
unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
// Check the element type of the arrays
const DependentSizedArrayType *DependentArrayParm
= S.Context.getAsDependentSizedArrayType(Param);
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
DependentArrayParm->getElementType(),
ArrayArg->getElementType(),
Info, Deduced, SubTDF))
return Result;
// Determine the array bound is something we can deduce.
NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(DependentArrayParm->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
// We can perform template argument deduction for the given non-type
// template parameter.
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument at depth > 0");
if (const ConstantArrayType *ConstantArrayArg
= dyn_cast<ConstantArrayType>(ArrayArg)) {
llvm::APSInt Size(ConstantArrayArg->getSize());
return DeduceNonTypeTemplateArgument(S, NTTP, Size,
S.Context.getSizeType(),
/*ArrayBound=*/true,
Info, Deduced);
}
if (const DependentSizedArrayType *DependentArrayArg
= dyn_cast<DependentSizedArrayType>(ArrayArg))
if (DependentArrayArg->getSizeExpr())
return DeduceNonTypeTemplateArgument(S, NTTP,
DependentArrayArg->getSizeExpr(),
Info, Deduced);
// Incomplete type does not match a dependently-sized array type
return Sema::TDK_NonDeducedMismatch;
}
// type(*)(T)
// T(*)()
// T(*)(T)
case Type::FunctionProto: {
unsigned SubTDF = TDF & TDF_TopLevelParameterTypeList;
const FunctionProtoType *FunctionProtoArg =
dyn_cast<FunctionProtoType>(Arg);
if (!FunctionProtoArg)
return Sema::TDK_NonDeducedMismatch;
const FunctionProtoType *FunctionProtoParam =
cast<FunctionProtoType>(Param);
if (FunctionProtoParam->getTypeQuals()
!= FunctionProtoArg->getTypeQuals() ||
FunctionProtoParam->getRefQualifier()
!= FunctionProtoArg->getRefQualifier() ||
FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
return Sema::TDK_NonDeducedMismatch;
// Check return types.
if (Sema::TemplateDeductionResult Result =
DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, FunctionProtoParam->getReturnType(),
FunctionProtoArg->getReturnType(), Info, Deduced, 0))
return Result;
return DeduceTemplateArguments(
S, TemplateParams, FunctionProtoParam->param_type_begin(),
FunctionProtoParam->getNumParams(),
FunctionProtoArg->param_type_begin(),
FunctionProtoArg->getNumParams(), Info, Deduced, SubTDF);
}
case Type::InjectedClassName: {
// Treat a template's injected-class-name as if the template
// specialization type had been used.
Param = cast<InjectedClassNameType>(Param)
->getInjectedSpecializationType();
assert(isa<TemplateSpecializationType>(Param) &&
"injected class name is not a template specialization type");
// fall through
}
// template-name<T> (where template-name refers to a class template)
// template-name<i>
// TT<T>
// TT<i>
// TT<>
case Type::TemplateSpecialization: {
const TemplateSpecializationType *SpecParam =
cast<TemplateSpecializationType>(Param);
// When Arg cannot be a derived class, we can just try to deduce template
// arguments from the template-id.
const RecordType *RecordT = Arg->getAs<RecordType>();
if (!(TDF & TDF_DerivedClass) || !RecordT)
return DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg, Info,
Deduced);
SmallVector<DeducedTemplateArgument, 8> DeducedOrig(Deduced.begin(),
Deduced.end());
Sema::TemplateDeductionResult Result = DeduceTemplateArguments(
S, TemplateParams, SpecParam, Arg, Info, Deduced);
if (Result == Sema::TDK_Success)
return Result;
// We cannot inspect base classes as part of deduction when the type
// is incomplete, so either instantiate any templates necessary to
// complete the type, or skip over it if it cannot be completed.
if (!S.isCompleteType(Info.getLocation(), Arg))
return Result;
// C++14 [temp.deduct.call] p4b3:
// 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.
//
// These alternatives are considered only if type deduction would
// otherwise fail. If they yield more than one possible deduced A, the
// type deduction fails.
// Reset the incorrectly deduced argument from above.
Deduced = DeducedOrig;
// Use data recursion to crawl through the list of base classes.
// Visited contains the set of nodes we have already visited, while
// ToVisit is our stack of records that we still need to visit.
llvm::SmallPtrSet<const RecordType *, 8> Visited;
SmallVector<const RecordType *, 8> ToVisit;
ToVisit.push_back(RecordT);
bool Successful = false;
SmallVector<DeducedTemplateArgument, 8> SuccessfulDeduced;
while (!ToVisit.empty()) {
// Retrieve the next class in the inheritance hierarchy.
const RecordType *NextT = ToVisit.pop_back_val();
// If we have already seen this type, skip it.
if (!Visited.insert(NextT).second)
continue;
// If this is a base class, try to perform template argument
// deduction from it.
if (NextT != RecordT) {
TemplateDeductionInfo BaseInfo(Info.getLocation());
Sema::TemplateDeductionResult BaseResult =
DeduceTemplateArguments(S, TemplateParams, SpecParam,
QualType(NextT, 0), BaseInfo, Deduced);
// If template argument deduction for this base was successful,
// note that we had some success. Otherwise, ignore any deductions
// from this base class.
if (BaseResult == Sema::TDK_Success) {
// If we've already seen some success, then deduction fails due to
// an ambiguity (temp.deduct.call p5).
if (Successful)
return Sema::TDK_MiscellaneousDeductionFailure;
Successful = true;
std::swap(SuccessfulDeduced, Deduced);
Info.Param = BaseInfo.Param;
Info.FirstArg = BaseInfo.FirstArg;
Info.SecondArg = BaseInfo.SecondArg;
}
Deduced = DeducedOrig;
}
// Visit base classes
CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
for (const auto &Base : Next->bases()) {
assert(Base.getType()->isRecordType() &&
"Base class that isn't a record?");
ToVisit.push_back(Base.getType()->getAs<RecordType>());
}
}
if (Successful) {
std::swap(SuccessfulDeduced, Deduced);
return Sema::TDK_Success;
}
return Result;
}
// T type::*
// T T::*
// T (type::*)()
// type (T::*)()
// type (type::*)(T)
// type (T::*)(T)
// T (type::*)(T)
// T (T::*)()
// T (T::*)(T)
case Type::MemberPointer: {
const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
if (!MemPtrArg)
return Sema::TDK_NonDeducedMismatch;
QualType ParamPointeeType = MemPtrParam->getPointeeType();
if (ParamPointeeType->isFunctionType())
S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());
QualType ArgPointeeType = MemPtrArg->getPointeeType();
if (ArgPointeeType->isFunctionType())
S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
ParamPointeeType,
ArgPointeeType,
Info, Deduced,
TDF & TDF_IgnoreQualifiers))
return Result;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
QualType(MemPtrParam->getClass(), 0),
QualType(MemPtrArg->getClass(), 0),
Info, Deduced,
TDF & TDF_IgnoreQualifiers);
}
// (clang extension)
//
// type(^)(T)
// T(^)()
// T(^)(T)
case Type::BlockPointer: {
const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param);
const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
if (!BlockPtrArg)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
BlockPtrParam->getPointeeType(),
BlockPtrArg->getPointeeType(),
Info, Deduced, 0);
}
// (clang extension)
//
// T __attribute__(((ext_vector_type(<integral constant>))))
case Type::ExtVector: {
const ExtVectorType *VectorParam = cast<ExtVectorType>(Param);
if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
// Make sure that the vectors have the same number of elements.
if (VectorParam->getNumElements() != VectorArg->getNumElements())
return Sema::TDK_NonDeducedMismatch;
// Perform deduction on the element types.
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
VectorParam->getElementType(),
VectorArg->getElementType(),
Info, Deduced, TDF);
}
if (const DependentSizedExtVectorType *VectorArg
= dyn_cast<DependentSizedExtVectorType>(Arg)) {
// We can't check the number of elements, since the argument has a
// dependent number of elements. This can only occur during partial
// ordering.
// Perform deduction on the element types.
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
VectorParam->getElementType(),
VectorArg->getElementType(),
Info, Deduced, TDF);
}
return Sema::TDK_NonDeducedMismatch;
}
// (clang extension)
//
// T __attribute__(((ext_vector_type(N))))
case Type::DependentSizedExtVector: {
const DependentSizedExtVectorType *VectorParam
= cast<DependentSizedExtVectorType>(Param);
if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
// Perform deduction on the element types.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
VectorParam->getElementType(),
VectorArg->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = VectorArg->getNumElements();
return DeduceNonTypeTemplateArgument(S, NTTP, ArgSize, S.Context.IntTy,
false, Info, Deduced);
}
if (const DependentSizedExtVectorType *VectorArg
= dyn_cast<DependentSizedExtVectorType>(Arg)) {
// Perform deduction on the element types.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
VectorParam->getElementType(),
VectorArg->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(S, NTTP, VectorArg->getSizeExpr(),
Info, Deduced);
}
return Sema::TDK_NonDeducedMismatch;
}
case Type::TypeOfExpr:
case Type::TypeOf:
case Type::DependentName:
case Type::UnresolvedUsing:
case Type::Decltype:
case Type::UnaryTransform:
case Type::Auto:
case Type::DependentTemplateSpecialization:
case Type::PackExpansion:
case Type::Pipe:
// No template argument deduction for these types
return Sema::TDK_Success;
}
llvm_unreachable("Invalid Type Class!");
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgument &Param,
TemplateArgument Arg,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
// If the template argument is a pack expansion, perform template argument
// deduction against the pattern of that expansion. This only occurs during
// partial ordering.
if (Arg.isPackExpansion())
Arg = Arg.getPackExpansionPattern();
switch (Param.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Null template argument in parameter list");
case TemplateArgument::Type:
if (Arg.getKind() == TemplateArgument::Type)
return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
Param.getAsType(),
Arg.getAsType(),
Info, Deduced, 0);
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Template:
if (Arg.getKind() == TemplateArgument::Template)
return DeduceTemplateArguments(S, TemplateParams,
Param.getAsTemplate(),
Arg.getAsTemplate(), Info, Deduced);
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::TemplateExpansion:
llvm_unreachable("caller should handle pack expansions");
case TemplateArgument::Declaration:
if (Arg.getKind() == TemplateArgument::Declaration &&
isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()))
return Sema::TDK_Success;
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::NullPtr:
if (Arg.getKind() == TemplateArgument::NullPtr &&
S.Context.hasSameType(Param.getNullPtrType(), Arg.getNullPtrType()))
return Sema::TDK_Success;
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Integral:
if (Arg.getKind() == TemplateArgument::Integral) {
if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral()))
return Sema::TDK_Success;
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
}
if (Arg.getKind() == TemplateArgument::Expression) {
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
}
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Expression: {
if (NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(Param.getAsExpr())) {
if (Arg.getKind() == TemplateArgument::Integral)
return DeduceNonTypeTemplateArgument(S, NTTP,
Arg.getAsIntegral(),
Arg.getIntegralType(),
/*ArrayBound=*/false,
Info, Deduced);
if (Arg.getKind() == TemplateArgument::Expression)
return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsExpr(),
Info, Deduced);
if (Arg.getKind() == TemplateArgument::Declaration)
return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
Info, Deduced);
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
}
// Can't deduce anything, but that's okay.
return Sema::TDK_Success;
}
case TemplateArgument::Pack:
llvm_unreachable("Argument packs should be expanded by the caller!");
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// \brief Determine whether there is a template argument to be used for
/// deduction.
///
/// This routine "expands" argument packs in-place, overriding its input
/// parameters so that \c Args[ArgIdx] will be the available template argument.
///
/// \returns true if there is another template argument (which will be at
/// \c Args[ArgIdx]), false otherwise.
static bool hasTemplateArgumentForDeduction(const TemplateArgument *&Args,
unsigned &ArgIdx,
unsigned &NumArgs) {
if (ArgIdx == NumArgs)
return false;
const TemplateArgument &Arg = Args[ArgIdx];
if (Arg.getKind() != TemplateArgument::Pack)
return true;
assert(ArgIdx == NumArgs - 1 && "Pack not at the end of argument list?");
Args = Arg.pack_begin();
NumArgs = Arg.pack_size();
ArgIdx = 0;
return ArgIdx < NumArgs;
}
/// \brief Determine whether the given set of template arguments has a pack
/// expansion that is not the last template argument.
static bool hasPackExpansionBeforeEnd(const TemplateArgument *Args,
unsigned NumArgs) {
unsigned ArgIdx = 0;
while (ArgIdx < NumArgs) {
const TemplateArgument &Arg = Args[ArgIdx];
// Unwrap argument packs.
if (Args[ArgIdx].getKind() == TemplateArgument::Pack) {
Args = Arg.pack_begin();
NumArgs = Arg.pack_size();
ArgIdx = 0;
continue;
}
++ArgIdx;
if (ArgIdx == NumArgs)
return false;
if (Arg.isPackExpansion())
return true;
}
return false;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
const TemplateArgument *Params, unsigned NumParams,
const TemplateArgument *Args, unsigned NumArgs,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch) {
// C++0x [temp.deduct.type]p9:
// If the template argument list of P contains a pack expansion that is not
// the last template argument, the entire template argument list is a
// non-deduced context.
if (hasPackExpansionBeforeEnd(Params, NumParams))
return Sema::TDK_Success;
// C++0x [temp.deduct.type]p9:
// If P has a form that contains <T> or <i>, then each argument Pi of the
// respective template argument list P is compared with the corresponding
// argument Ai of the corresponding template argument list of A.
unsigned ArgIdx = 0, ParamIdx = 0;
for (; hasTemplateArgumentForDeduction(Params, ParamIdx, NumParams);
++ParamIdx) {
if (!Params[ParamIdx].isPackExpansion()) {
// The simple case: deduce template arguments by matching Pi and Ai.
// Check whether we have enough arguments.
if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
return NumberOfArgumentsMustMatch ? Sema::TDK_TooFewArguments
: Sema::TDK_Success;
if (Args[ArgIdx].isPackExpansion()) {
// FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here,
// but applied to pack expansions that are template arguments.
return Sema::TDK_MiscellaneousDeductionFailure;
}
// Perform deduction for this Pi/Ai pair.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams,
Params[ParamIdx], Args[ArgIdx],
Info, Deduced))
return Result;
// Move to the next argument.
++ArgIdx;
continue;
}
// The parameter is a pack expansion.
// C++0x [temp.deduct.type]p9:
// If Pi is a pack expansion, then the pattern of Pi is compared with
// each remaining argument in the template argument list of A. Each
// comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by Pi.
TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern();
// FIXME: If there are no remaining arguments, we can bail out early
// and set any deduced parameter packs to an empty argument pack.
// The latter part of this is a (minor) correctness issue.
// Prepare to deduce the packs within the pattern.
PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
// Keep track of the deduced template arguments for each parameter pack
// expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
bool HasAnyArguments = false;
for (; hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs); ++ArgIdx) {
HasAnyArguments = true;
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
Info, Deduced))
return Result;
PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
if (auto Result = PackScope.finish(HasAnyArguments))
return Result;
}
return Sema::TDK_Success;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgumentList &ParamList,
const TemplateArgumentList &ArgList,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
return DeduceTemplateArguments(S, TemplateParams,
ParamList.data(), ParamList.size(),
ArgList.data(), ArgList.size(),
Info, Deduced, false);
}
/// \brief Determine whether two template arguments are the same.
static bool isSameTemplateArg(ASTContext &Context,
const TemplateArgument &X,
const TemplateArgument &Y) {
if (X.getKind() != Y.getKind())
return false;
switch (X.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Comparing NULL template argument");
case TemplateArgument::Type:
return Context.getCanonicalType(X.getAsType()) ==
Context.getCanonicalType(Y.getAsType());
case TemplateArgument::Declaration:
return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
case TemplateArgument::NullPtr:
return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
return Context.getCanonicalTemplateName(
X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
Context.getCanonicalTemplateName(
Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
case TemplateArgument::Integral:
return X.getAsIntegral() == Y.getAsIntegral();
case TemplateArgument::Expression: {
llvm::FoldingSetNodeID XID, YID;
X.getAsExpr()->Profile(XID, Context, true);
Y.getAsExpr()->Profile(YID, Context, true);
return XID == YID;
}
case TemplateArgument::Pack:
if (X.pack_size() != Y.pack_size())
return false;
for (TemplateArgument::pack_iterator XP = X.pack_begin(),
XPEnd = X.pack_end(),
YP = Y.pack_begin();
XP != XPEnd; ++XP, ++YP)
if (!isSameTemplateArg(Context, *XP, *YP))
return false;
return true;
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// \brief Allocate a TemplateArgumentLoc where all locations have
/// been initialized to the given location.
///
/// \param Arg The template argument we are producing template argument
/// location information for.
///
/// \param NTTPType For a declaration template argument, the type of
/// the non-type template parameter that corresponds to this template
/// argument.
///
/// \param Loc The source location to use for the resulting template
/// argument.
TemplateArgumentLoc
Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType, SourceLocation Loc) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Can't get a NULL template argument here");
case TemplateArgument::Type:
return TemplateArgumentLoc(
Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
case TemplateArgument::Declaration: {
Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
case TemplateArgument::NullPtr: {
Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
E);
}
case TemplateArgument::Integral: {
Expr *E =
BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion: {
NestedNameSpecifierLocBuilder Builder;
TemplateName Template = Arg.getAsTemplate();
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
else if (QualifiedTemplateName *QTN =
Template.getAsQualifiedTemplateName())
Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
if (Arg.getKind() == TemplateArgument::Template)
return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context),
Loc);
return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context),
Loc, Loc);
}
case TemplateArgument::Expression:
return TemplateArgumentLoc(Arg, Arg.getAsExpr());
case TemplateArgument::Pack:
return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// \brief Convert the given deduced template argument and add it to the set of
/// fully-converted template arguments.
static bool
ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
DeducedTemplateArgument Arg,
NamedDecl *Template,
TemplateDeductionInfo &Info,
bool InFunctionTemplate,
SmallVectorImpl<TemplateArgument> &Output) {
// First, for a non-type template parameter type that is
// initialized by a declaration, we need the type of the
// corresponding non-type template parameter.
QualType NTTPType;
if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(Param)) {
NTTPType = NTTP->getType();
if (NTTPType->isDependentType()) {
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
NTTPType = S.SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
NTTP->getLocation(),
NTTP->getDeclName());
if (NTTPType.isNull())
return true;
}
}
auto ConvertArg = [&](DeducedTemplateArgument Arg,
unsigned ArgumentPackIndex) {
// Convert the deduced template argument into a template
// argument that we can check, almost as if the user had written
// the template argument explicitly.
TemplateArgumentLoc ArgLoc =
S.getTrivialTemplateArgumentLoc(Arg, NTTPType, Info.getLocation());
// Check the template argument, converting it as necessary.
return S.CheckTemplateArgument(
Param, ArgLoc, Template, Template->getLocation(),
Template->getSourceRange().getEnd(), ArgumentPackIndex, Output,
InFunctionTemplate
? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
: Sema::CTAK_Deduced)
: Sema::CTAK_Specified);
};
if (Arg.getKind() == TemplateArgument::Pack) {
// This is a template argument pack, so check each of its arguments against
// the template parameter.
SmallVector<TemplateArgument, 2> PackedArgsBuilder;
for (const auto &P : Arg.pack_elements()) {
// When converting the deduced template argument, append it to the
// general output list. We need to do this so that the template argument
// checking logic has all of the prior template arguments available.
DeducedTemplateArgument InnerArg(P);
InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
assert(InnerArg.getKind() != TemplateArgument::Pack &&
"deduced nested pack");
if (ConvertArg(InnerArg, PackedArgsBuilder.size()))
return true;
// Move the converted template argument into our argument pack.
PackedArgsBuilder.push_back(Output.pop_back_val());
}
// If the pack is empty, we still need to substitute into the parameter
// itself, in case that substitution fails. For non-type parameters, we did
// this above. For type parameters, no substitution is ever required.
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param);
if (TTP && PackedArgsBuilder.empty()) {
// Set up a template instantiation context.
LocalInstantiationScope Scope(S);
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
TTP, Output,
Template->getSourceRange());
if (Inst.isInvalid())
return true;
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
if (!S.SubstDecl(TTP, S.CurContext,
MultiLevelTemplateArgumentList(TemplateArgs)))
return true;
}
// Create the resulting argument pack.
Output.push_back(
TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder));
return false;
}
return ConvertArg(Arg, 0);
}
/// Complete template argument deduction for a class template partial
/// specialization.
static Sema::TemplateDeductionResult
FinishTemplateArgumentDeduction(Sema &S,
ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, Partial);
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
TemplateParameterList *PartialParams = Partial->getTemplateParameters();
for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
NamedDecl *Param = PartialParams->getParam(I);
if (Deduced[I].isNull()) {
Info.Param = makeTemplateParameter(Param);
return Sema::TDK_Incomplete;
}
// We have deduced this argument, so it still needs to be
// checked and converted.
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
Partial, Info, false,
Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
return Sema::TDK_SubstitutionFailure;
}
}
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
= TemplateArgumentList::CreateCopy(S.Context, Builder);
Info.reset(DeducedArgumentList);
// Substitute the deduced template arguments into the template
// arguments of the class template partial specialization, and
// verify that the instantiated template arguments are both valid
// and are equivalent to the template arguments originally provided
// to the class template.
LocalInstantiationScope InstScope(S);
ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
const ASTTemplateArgumentListInfo *PartialTemplArgInfo
= Partial->getTemplateArgsAsWritten();
const TemplateArgumentLoc *PartialTemplateArgs
= PartialTemplArgInfo->getTemplateArgs();
TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
PartialTemplArgInfo->RAngleLoc);
if (S.Subst(PartialTemplateArgs, PartialTemplArgInfo->NumTemplateArgs,
InstArgs, MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
if (ParamIdx >= Partial->getTemplateParameters()->size())
ParamIdx = Partial->getTemplateParameters()->size() - 1;
Decl *Param
= const_cast<NamedDecl *>(
Partial->getTemplateParameters()->getParam(ParamIdx));
Info.Param = makeTemplateParameter(Param);
Info.FirstArg = PartialTemplateArgs[ArgIdx].getArgument();
return Sema::TDK_SubstitutionFailure;
}
SmallVector<TemplateArgument, 4> ConvertedInstArgs;
if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
InstArgs, false, ConvertedInstArgs))
return Sema::TDK_SubstitutionFailure;
TemplateParameterList *TemplateParams
= ClassTemplate->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
TemplateArgument InstArg = ConvertedInstArgs.data()[I];
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
Info.FirstArg = TemplateArgs[I];
Info.SecondArg = InstArg;
return Sema::TDK_NonDeducedMismatch;
}
}
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
return Sema::TDK_Success;
}
/// \brief Perform template argument deduction to determine whether
/// the given template arguments match the given class template
/// partial specialization per C++ [temp.class.spec.match].
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
TemplateDeductionInfo &Info) {
if (Partial->isInvalidDecl())
return TDK_Invalid;
// C++ [temp.class.spec.match]p2:
// A partial specialization matches a given actual template
// argument list if the template arguments of the partial
// specialization can be deduced from the actual template argument
// list (14.8.2).
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(Partial->getTemplateParameters()->size());
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(*this,
Partial->getTemplateParameters(),
Partial->getTemplateArgs(),
TemplateArgs, Info, Deduced))
return Result;
SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
Info);
if (Inst.isInvalid())
return TDK_InstantiationDepth;
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
Deduced, Info);
}
/// Complete template argument deduction for a variable template partial
/// specialization.
/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
/// May require unifying ClassTemplate(Partial)SpecializationDecl and
/// VarTemplate(Partial)SpecializationDecl with a new data
/// structure Template(Partial)SpecializationDecl, and
/// using Template(Partial)SpecializationDecl as input type.
static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
Sema &S, VarTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
Sema::SFINAETrap Trap(S);
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
TemplateParameterList *PartialParams = Partial->getTemplateParameters();
for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
NamedDecl *Param = PartialParams->getParam(I);
if (Deduced[I].isNull()) {
Info.Param = makeTemplateParameter(Param);
return Sema::TDK_Incomplete;
}
// We have deduced this argument, so it still needs to be
// checked and converted.
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial,
Info, false, Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
return Sema::TDK_SubstitutionFailure;
}
}
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList = TemplateArgumentList::CreateCopy(
S.Context, Builder);
Info.reset(DeducedArgumentList);
// Substitute the deduced template arguments into the template
// arguments of the class template partial specialization, and
// verify that the instantiated template arguments are both valid
// and are equivalent to the template arguments originally provided
// to the class template.
LocalInstantiationScope InstScope(S);
VarTemplateDecl *VarTemplate = Partial->getSpecializedTemplate();
const ASTTemplateArgumentListInfo *PartialTemplArgInfo
= Partial->getTemplateArgsAsWritten();
const TemplateArgumentLoc *PartialTemplateArgs
= PartialTemplArgInfo->getTemplateArgs();
TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
PartialTemplArgInfo->RAngleLoc);
if (S.Subst(PartialTemplateArgs, PartialTemplArgInfo->NumTemplateArgs,
InstArgs, MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
if (ParamIdx >= Partial->getTemplateParameters()->size())
ParamIdx = Partial->getTemplateParameters()->size() - 1;
Decl *Param = const_cast<NamedDecl *>(
Partial->getTemplateParameters()->getParam(ParamIdx));
Info.Param = makeTemplateParameter(Param);
Info.FirstArg = PartialTemplateArgs[ArgIdx].getArgument();
return Sema::TDK_SubstitutionFailure;
}
SmallVector<TemplateArgument, 4> ConvertedInstArgs;
if (S.CheckTemplateArgumentList(VarTemplate, Partial->getLocation(), InstArgs,
false, ConvertedInstArgs))
return Sema::TDK_SubstitutionFailure;
TemplateParameterList *TemplateParams = VarTemplate->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
TemplateArgument InstArg = ConvertedInstArgs.data()[I];
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
Info.FirstArg = TemplateArgs[I];
Info.SecondArg = InstArg;
return Sema::TDK_NonDeducedMismatch;
}
}
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
return Sema::TDK_Success;
}
/// \brief Perform template argument deduction to determine whether
/// the given template arguments match the given variable template
/// partial specialization per C++ [temp.class.spec.match].
/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
/// May require unifying ClassTemplate(Partial)SpecializationDecl and
/// VarTemplate(Partial)SpecializationDecl with a new data
/// structure Template(Partial)SpecializationDecl, and
/// using Template(Partial)SpecializationDecl as input type.
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
TemplateDeductionInfo &Info) {
if (Partial->isInvalidDecl())
return TDK_Invalid;
// C++ [temp.class.spec.match]p2:
// A partial specialization matches a given actual template
// argument list if the template arguments of the partial
// specialization can be deduced from the actual template argument
// list (14.8.2).
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(Partial->getTemplateParameters()->size());
if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
*this, Partial->getTemplateParameters(), Partial->getTemplateArgs(),
TemplateArgs, Info, Deduced))
return Result;
SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
Info);
if (Inst.isInvalid())
return TDK_InstantiationDepth;
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
Deduced, Info);
}
/// \brief Determine whether the given type T is a simple-template-id type.
static bool isSimpleTemplateIdType(QualType T) {
if (const TemplateSpecializationType *Spec
= T->getAs<TemplateSpecializationType>())
return Spec->getTemplateName().getAsTemplateDecl() != nullptr;
return false;
}
/// \brief Substitute the explicitly-provided template arguments into the
/// given function template according to C++ [temp.arg.explicit].
///
/// \param FunctionTemplate the function template into which the explicit
/// template arguments will be substituted.
///
/// \param ExplicitTemplateArgs the explicitly-specified template
/// arguments.
///
/// \param Deduced the deduced template arguments, which will be populated
/// with the converted and checked explicit template arguments.
///
/// \param ParamTypes will be populated with the instantiated function
/// parameters.
///
/// \param FunctionType if non-NULL, the result type of the function template
/// will also be instantiated and the pointed-to value will be updated with
/// the instantiated function type.
///
/// \param Info if substitution fails for any reason, this object will be
/// populated with more information about the failure.
///
/// \returns TDK_Success if substitution was successful, or some failure
/// condition.
Sema::TemplateDeductionResult
Sema::SubstituteExplicitTemplateArguments(
FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo &ExplicitTemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
SmallVectorImpl<QualType> &ParamTypes,
QualType *FunctionType,
TemplateDeductionInfo &Info) {
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
if (ExplicitTemplateArgs.size() == 0) {
// No arguments to substitute; just copy over the parameter types and
// fill in the function type.
for (auto P : Function->parameters())
ParamTypes.push_back(P->getType());
if (FunctionType)
*FunctionType = Function->getType();
return TDK_Success;
}
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
// C++ [temp.arg.explicit]p3:
// Template arguments that are present shall be specified in the
// declaration order of their corresponding template-parameters. The
// template argument list shall not specify more template-arguments than
// there are corresponding template-parameters.
SmallVector<TemplateArgument, 4> Builder;
// Enter a new template instantiation context where we check the
// explicitly-specified template arguments against this function template,
// and then substitute them into the function parameter types.
SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
DeducedArgs,
ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution,
Info);
if (Inst.isInvalid())
return TDK_InstantiationDepth;
if (CheckTemplateArgumentList(FunctionTemplate,
SourceLocation(),
ExplicitTemplateArgs,
true,
Builder) || Trap.hasErrorOccurred()) {
unsigned Index = Builder.size();
if (Index >= TemplateParams->size())
Index = TemplateParams->size() - 1;
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
return TDK_InvalidExplicitArguments;
}
// Form the template argument list from the explicitly-specified
// template arguments.
TemplateArgumentList *ExplicitArgumentList
= TemplateArgumentList::CreateCopy(Context, Builder);
Info.reset(ExplicitArgumentList);
// Template argument deduction and the final substitution should be
// done in the context of the templated declaration. Explicit
// argument substitution, on the other hand, needs to happen in the
// calling context.
ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
// If we deduced template arguments for a template parameter pack,
// note that the template argument pack is partially substituted and record
// the explicit template arguments. They'll be used as part of deduction
// for this template parameter pack.
for (unsigned I = 0, N = Builder.size(); I != N; ++I) {
const TemplateArgument &Arg = Builder[I];
if (Arg.getKind() == TemplateArgument::Pack) {
CurrentInstantiationScope->SetPartiallySubstitutedPack(
TemplateParams->getParam(I),
Arg.pack_begin(),
Arg.pack_size());
break;
}
}
const FunctionProtoType *Proto
= Function->getType()->getAs<FunctionProtoType>();
assert(Proto && "Function template does not have a prototype?");
// Isolate our substituted parameters from our caller.
LocalInstantiationScope InstScope(*this, /*MergeWithOuterScope*/true);
ExtParameterInfoBuilder ExtParamInfos;
// Instantiate the types of each of the function parameters given the
// explicitly-specified template arguments. If the function has a trailing
// return type, substitute it after the arguments to ensure we substitute
// in lexical order.