blob: 93e796ee9668ecb6d2abdafbd30159d63a1ed68e [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/AST/TypeOrdering.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,
bool DeducedFromArrayBound = false);
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
ArrayRef<TemplateArgument> Params,
ArrayRef<TemplateArgument> Args,
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(TemplateDeductionInfo &Info, 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))
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
if (NTTP->getDepth() == Info.getDeducedDepth())
return NTTP;
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;
// If we have two non-type template argument values deduced for the same
// parameter, they must both match the type of the parameter, and thus must
// match each other's type. As we're only keeping one of them, we must check
// for that now. The exception is that if either was deduced from an array
// bound, the type is permitted to differ.
if (!X.wasDeducedFromArrayBound() && !Y.wasDeducedFromArrayBound()) {
QualType XType = X.getNonTypeTemplateArgumentType();
if (!XType.isNull()) {
QualType YType = Y.getNonTypeTemplateArgumentType();
if (YType.isNull() || !Context.hasSameType(XType, YType))
return DeducedTemplateArgument();
}
}
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;
// If one of the two arguments was deduced from an array bound, the other
// supersedes it.
if (X.wasDeducedFromArrayBound() != Y.wasDeducedFromArrayBound())
return X.wasDeducedFromArrayBound() ? Y : X;
// The arguments are not compatible.
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 X.wasDeducedFromArrayBound() ? Y : X;
// 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 (Y.getKind() != TemplateArgument::Expression)
return checkDeducedTemplateArguments(Context, Y, X);
// 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.wasDeducedFromArrayBound() ? Y : X;
// Differing dependent expressions are incompatible.
return DeducedTemplateArgument();
}
case TemplateArgument::Declaration:
assert(!X.wasDeducedFromArrayBound());
// 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 and whichever type did not come from an array
// bound.
if (Y.getKind() == TemplateArgument::Integral) {
if (Y.wasDeducedFromArrayBound())
return TemplateArgument(Context, Y.getAsIntegral(),
X.getParamTypeForDecl());
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, they are the same.
if (Y.getKind() == TemplateArgument::NullPtr)
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();
llvm::SmallVector<TemplateArgument, 8> NewPack;
for (TemplateArgument::pack_iterator XA = X.pack_begin(),
XAEnd = X.pack_end(),
YA = Y.pack_begin();
XA != XAEnd; ++XA, ++YA) {
TemplateArgument Merged = checkDeducedTemplateArguments(
Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()));
if (Merged.isNull())
return DeducedTemplateArgument();
NewPack.push_back(Merged);
}
return DeducedTemplateArgument(
TemplateArgument::CreatePackCopy(Context, NewPack),
X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// \brief Deduce the value of the given non-type template parameter
/// as the given deduced template argument. All non-type template parameter
/// deduction is funneled through here.
static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
Sema &S, TemplateParameterList *TemplateParams,
NonTypeTemplateParmDecl *NTTP, const DeducedTemplateArgument &NewDeduced,
QualType ValueType, TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == Info.getDeducedDepth() &&
"deducing non-type template argument with wrong depth");
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;
if (!S.getLangOpts().CPlusPlus1z)
return Sema::TDK_Success;
// FIXME: It's not clear how deduction of a parameter of reference
// type from an argument (of non-reference type) should be performed.
// For now, we just remove reference types from both sides and let
// the final check for matching types sort out the mess.
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, NTTP->getType().getNonReferenceType(),
ValueType.getNonReferenceType(), Info, Deduced, TDF_SkipNonDependent,
/*PartialOrdering=*/false,
/*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound());
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given integral constant.
static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
Sema &S, TemplateParameterList *TemplateParams,
NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value,
QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP,
DeducedTemplateArgument(S.Context, Value, ValueType,
DeducedFromArrayBound),
ValueType, Info, Deduced);
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given null pointer template argument type.
static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument(
Sema &S, TemplateParameterList *TemplateParams,
NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
Expr *Value =
S.ImpCastExprToType(new (S.Context) CXXNullPtrLiteralExpr(
S.Context.NullPtrTy, NTTP->getLocation()),
NullPtrType, CK_NullToPointer)
.get();
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
DeducedTemplateArgument(Value),
Value->getType(), Info, Deduced);
}
/// \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, TemplateParameterList *TemplateParams,
NonTypeTemplateParmDecl *NTTP, Expr *Value, TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
DeducedTemplateArgument(Value),
Value->getType(), Info, Deduced);
}
/// \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, TemplateParameterList *TemplateParams,
NonTypeTemplateParmDecl *NTTP, ValueDecl *D, QualType T,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
TemplateArgument New(D, T);
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced);
}
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)) {
// If we're not deducing at this depth, there's nothing to deduce.
if (TempParam->getDepth() != Info.getDeducedDepth())
return Sema::TDK_Success;
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->template_arguments(),
SpecArg->template_arguments(), 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->template_arguments(),
SpecArg->getTemplateArgs().asArray(), 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 == Info.getDeducedDepth() && !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) ==
std::make_pair(Info.getDeducedDepth(), Pack.Index))
Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs);
}
}
}
~PackDeductionScope() {
for (auto &Pack : Packs)
Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
}
/// Determine whether this pack has already been partially expanded into a
/// sequence of (prior) function parameters / template arguments.
bool isPartiallyExpanded() {
if (Packs.size() != 1 || !S.CurrentInstantiationScope)
return false;
auto *PartiallySubstitutedPack =
S.CurrentInstantiationScope->getPartiallySubstitutedPack();
return PartiallySubstitutedPack &&
getDepthAndIndex(PartiallySubstitutedPack) ==
std::make_pair(Info.getDeducedDepth(), Packs.front().Index);
}
/// 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 (!Pack.New.empty() || !DeducedArg.isNull()) {
while (Pack.New.size() < PackElements)
Pack.New.push_back(DeducedTemplateArgument());
Pack.New.push_back(DeducedArg);
DeducedArg = DeducedTemplateArgument();
}
}
++PackElements;
}
/// \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() {
// 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 (PackElements && 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;
unsigned PackElements = 0;
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);
for (; ArgIdx < NumArgs; ++ArgIdx) {
// 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())
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 and noexcept adjustment.
QualType AdjustedParam;
if (IsFunctionConversion(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,
bool DeducedFromArrayBound) {
// 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 or a parameter
// at a different depth.
if (Arg->isPlaceholderType() ||
Info.getDeducedDepth() != TemplateTypeParm->getDepth())
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() == Info.getDeducedDepth() &&
"saw template type parameter with wrong depth");
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, DeducedFromArrayBound);
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(Info, DependentArrayParm->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
// We can perform template argument deduction for the given non-type
// template parameter.
assert(NTTP->getDepth() == Info.getDeducedDepth() &&
"saw non-type template parameter with wrong depth");
if (const ConstantArrayType *ConstantArrayArg
= dyn_cast<ConstantArrayType>(ArrayArg)) {
llvm::APSInt Size(ConstantArrayArg->getSize());
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, Size,
S.Context.getSizeType(),
/*ArrayBound=*/true,
Info, Deduced);
}
if (const DependentSizedArrayType *DependentArrayArg
= dyn_cast<DependentSizedArrayType>(ArrayArg))
if (DependentArrayArg->getSizeExpr())
return DeduceNonTypeTemplateArgument(S, TemplateParams, 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(Info, VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = VectorArg->getNumElements();
// Note that we use the "array bound" rules here; just like in that
// case, we don't have any particular type for the vector size, but
// we can provide one if necessary.
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
S.Context.IntTy, true, 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(Info, VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(S, TemplateParams, 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(Info, Param.getAsExpr())) {
if (Arg.getKind() == TemplateArgument::Integral)
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
Arg.getAsIntegral(),
Arg.getIntegralType(),
/*ArrayBound=*/false,
Info, Deduced);
if (Arg.getKind() == TemplateArgument::NullPtr)
return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP,
Arg.getNullPtrType(),
Info, Deduced);
if (Arg.getKind() == TemplateArgument::Expression)
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
Arg.getAsExpr(), Info, Deduced);
if (Arg.getKind() == TemplateArgument::Declaration)
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
Arg.getAsDecl(),
Arg.getParamTypeForDecl(),
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(ArrayRef<TemplateArgument> &Args,
unsigned &ArgIdx) {
if (ArgIdx == Args.size())
return false;
const TemplateArgument &Arg = Args[ArgIdx];
if (Arg.getKind() != TemplateArgument::Pack)
return true;
assert(ArgIdx == Args.size() - 1 && "Pack not at the end of argument list?");
Args = Arg.pack_elements();
ArgIdx = 0;
return ArgIdx < Args.size();
}
/// \brief Determine whether the given set of template arguments has a pack
/// expansion that is not the last template argument.
static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) {
bool FoundPackExpansion = false;
for (const auto &A : Args) {
if (FoundPackExpansion)
return true;
if (A.getKind() == TemplateArgument::Pack)
return hasPackExpansionBeforeEnd(A.pack_elements());
if (A.isPackExpansion())
FoundPackExpansion = true;
}
return false;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
ArrayRef<TemplateArgument> Params,
ArrayRef<TemplateArgument> Args,
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))
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); ++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))
return NumberOfArgumentsMustMatch
? Sema::TDK_MiscellaneousDeductionFailure
: Sema::TDK_Success;
// C++1z [temp.deduct.type]p9:
// During partial ordering, if Ai was originally a pack expansion [and]
// Pi is not a pack expansion, template argument deduction fails.
if (Args[ArgIdx].isPackExpansion())
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).
for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) {
// 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())
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.asArray(),
ArgList.asArray(), Info, Deduced,
/*NumberOfArgumentsMustMatch*/false);
}
/// \brief Determine whether two template arguments are the same.
static bool isSameTemplateArg(ASTContext &Context,
TemplateArgument X,
const TemplateArgument &Y,
bool PackExpansionMatchesPack = false) {
// If we're checking deduced arguments (X) against original arguments (Y),
// we will have flattened packs to non-expansions in X.
if (PackExpansionMatchesPack && X.isPackExpansion() && !Y.isPackExpansion())
X = X.getPackExpansionPattern();
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 hasSameExtendedValue(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, PackExpansionMatchesPack))
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. Can be null if no type sugar is available to add to the
/// type from the 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: {
if (NTTPType.isNull())
NTTPType = Arg.getParamTypeForDecl();
Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
case TemplateArgument::NullPtr: {
if (NTTPType.isNull())
NTTPType = Arg.getNullPtrType();
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 IsDeduced,
SmallVectorImpl<TemplateArgument> &Output) {
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, QualType(), Info.getLocation());
// Check the template argument, converting it as necessary.
return S.CheckTemplateArgument(
Param, ArgLoc, Template, Template->getLocation(),
Template->getSourceRange().getEnd(), ArgumentPackIndex, Output,
IsDeduced
? (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 (P.isNull()) {
// We deduced arguments for some elements of this pack, but not for
// all of them. This happens if we get a conditionally-non-deduced
// context in a pack expansion (such as an overload set in one of the
// arguments).
S.Diag(Param->getLocation(),
diag::err_template_arg_deduced_incomplete_pack)
<< Arg << Param;
return true;
}
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.
if (PackedArgsBuilder.empty()) {
LocalInstantiationScope Scope(S);
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
MultiLevelTemplateArgumentList Args(TemplateArgs);
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
NTTP, Output,
Template->getSourceRange());
if (Inst.isInvalid() ||
S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
NTTP->getDeclName()).isNull())
return true;
} else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
TTP, Output,
Template->getSourceRange());
if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
return true;
}
// For type parameters, no substitution is ever required.
}
// Create the resulting argument pack.
Output.push_back(
TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder));
return false;
}
return ConvertArg(Arg, 0);
}
// FIXME: This should not be a template, but
// ClassTemplatePartialSpecializationDecl sadly does not derive from
// TemplateDecl.
template<typename TemplateDeclT>
static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
Sema &S, TemplateDeclT *Template, bool IsDeduced,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info, SmallVectorImpl<TemplateArgument> &Builder,
LocalInstantiationScope *CurrentInstantiationScope = nullptr,
unsigned NumAlreadyConverted = 0, bool PartialOverloading = false) {
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
NamedDecl *Param = TemplateParams->getParam(I);
if (!Deduced[I].isNull()) {
if (I < NumAlreadyConverted) {
// We may have had explicitly-specified template arguments for a
// template parameter pack (that may or may not have been extended
// via additional deduced arguments).
if (Param->isParameterPack() && CurrentInstantiationScope &&
CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
// Forget the partially-substituted pack; its substitution is now
// complete.
CurrentInstantiationScope->ResetPartiallySubstitutedPack();
// We still need to check the argument in case it was extended by
// deduction.
} else {
// We have already fully type-checked and converted this
// argument, because it was explicitly-specified. Just record the
// presence of this argument.
Builder.push_back(Deduced[I]);
continue;
}
}
// We may have deduced this argument, so it still needs to be
// checked and converted.
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info,
IsDeduced, Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
return Sema::TDK_SubstitutionFailure;
}
continue;
}
// C++0x [temp.arg.explicit]p3:
// A trailing template parameter pack (14.5.3) not otherwise deduced will
// be deduced to an empty sequence of template arguments.
// FIXME: Where did the word "trailing" come from?
if (Param->isTemplateParameterPack()) {
// We may have had explicitly-specified template arguments for this
// template parameter pack. If so, our empty deduction extends the
// explicitly-specified set (C++0x [temp.arg.explicit]p9).
const TemplateArgument *ExplicitArgs;
unsigned NumExplicitArgs;
if (CurrentInstantiationScope &&
CurrentInstantiationScope->getPartiallySubstitutedPack(
&ExplicitArgs, &NumExplicitArgs) == Param) {
Builder.push_back(TemplateArgument(
llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
// Forget the partially-substituted pack; its substitution is now
// complete.
CurrentInstantiationScope->ResetPartiallySubstitutedPack();
} else {
// Go through the motions of checking the empty argument pack against
// the parameter pack.
DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
if (ConvertDeducedTemplateArgument(S, Param, DeducedPack, Template,
Info, IsDeduced, Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
return Sema::TDK_SubstitutionFailure;
}
}
continue;
}
// Substitute into the default template argument, if available.
bool HasDefaultArg = false;
TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
if (!TD) {
assert(isa<ClassTemplatePartialSpecializationDecl>(Template));
return Sema::TDK_Incomplete;
}
TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
HasDefaultArg);
// If there was no default argument, deduction is incomplete.
if (DefArg.getArgument().isNull()) {
Info.Param = makeTemplateParameter(
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
if (PartialOverloading) break;
return HasDefaultArg ? Sema::TDK_SubstitutionFailure
: Sema::TDK_Incomplete;
}
// Check whether we can actually use the default argument.
if (S.CheckTemplateArgument(Param, DefArg, TD, TD->getLocation(),
TD->getSourceRange().getEnd(), 0, Builder,
Sema::CTAK_Specified)) {
Info.Param = makeTemplateParameter(
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
// FIXME: These template arguments are temporary. Free them!
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
return Sema::TDK_SubstitutionFailure;
}
// If we get here, we successfully used the default template argument.
}
return Sema::TDK_Success;
}
DeclContext *getAsDeclContextOrEnclosing(Decl *D) {
if (auto *DC = dyn_cast<DeclContext>(D))
return DC;
return D->getDeclContext();
}
template<typename T> struct IsPartialSpecialization {
static constexpr bool value = false;
};
template<>
struct IsPartialSpecialization<ClassTemplatePartialSpecializationDecl> {
static constexpr bool value = true;
};
template<>
struct IsPartialSpecialization<VarTemplatePartialSpecializationDecl> {
static constexpr bool value = true;
};
/// Complete template argument deduction for a partial specialization.
template <typename T>
static typename std::enable_if<IsPartialSpecialization<T>::value,
Sema::TemplateDeductionResult>::type
FinishTemplateArgumentDeduction(
Sema &S, T *Partial, bool IsPartialOrdering,
const TemplateArgumentList &TemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(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;
if (auto Result = ConvertDeducedTemplateArguments(
S, Partial, IsPartialOrdering, Deduced, Info, Builder))
return Result;
// 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);
auto *Template = 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(Template, Partial->getLocation(), InstArgs,
false, ConvertedInstArgs))
return Sema::TDK_SubstitutionFailure;
TemplateParameterList *TemplateParams = Template->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;
}
/// Complete template argument deduction for a class or variable template,
/// when partial ordering against a partial specialization.
// FIXME: Factor out duplication with partial specialization version above.
Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
Sema &S, TemplateDecl *Template, bool PartialOrdering,
const TemplateArgumentList &TemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template));
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
if (auto Result = ConvertDeducedTemplateArguments(
S, Template, /*IsDeduced*/PartialOrdering, Deduced, Info, Builder))
return Result;
// Check that we produced the correct argument list.
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
TemplateArgument InstArg = Builder[I];
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,
/*PackExpansionMatchesPack*/true)) {
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, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info);
}
/// \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].
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(