blob: 81edae10335d2e32bab10a9d279f36764ad545b1 [file] [log] [blame]
//===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements C++ template argument deduction.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/TemplateDeduction.h"
#include "TreeTransform.h"
#include "TypeLocBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <tuple>
#include <utility>
namespace clang {
/// Various flags that control template argument deduction.
///
/// These flags can be bitwise-OR'd together.
enum TemplateDeductionFlags {
/// 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,
/// 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,
/// Within template argument deduction from a function call, we
/// are matching in a case where we ignore cv-qualifiers.
TDF_IgnoreQualifiers = 0x02,
/// 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,
/// Allow non-dependent types to differ, e.g., when performing
/// template argument deduction from a function call where conversions
/// may apply.
TDF_SkipNonDependent = 0x08,
/// Whether we are performing template argument deduction for
/// parameters and arguments in a top-level template argument
TDF_TopLevelParameterTypeList = 0x10,
/// 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, or
/// similarly matching a declared template specialization against a
/// possible template, per C++ [temp.deduct.decl]. In either case, permit
/// deduction where the parameter is a function type that can be converted
/// to the argument type.
TDF_AllowCompatibleFunctionType = 0x20,
/// Within template argument deduction for a conversion function, we are
/// matching with an argument type for which the original argument was
/// a reference.
TDF_ArgWithReferenceType = 0x40,
};
}
using namespace clang;
using namespace sema;
/// 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 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> Ps,
ArrayRef<TemplateArgument> As,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch);
static void MarkUsedTemplateParameters(ASTContext &Ctx,
const TemplateArgument &TemplateArg,
bool OnlyDeduced, unsigned Depth,
llvm::SmallBitVector &Used);
static void MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
bool OnlyDeduced, unsigned Level,
llvm::SmallBitVector &Deduced);
/// 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 const NonTypeTemplateParmDecl *
getDeducedParameterFromExpr(const Expr *E, unsigned Depth) {
// If we are within an alias template, the expression may have undergone
// any number of parameter substitutions already.
while (true) {
if (const auto *IC = dyn_cast<ImplicitCastExpr>(E))
E = IC->getSubExpr();
else if (const auto *CE = dyn_cast<ConstantExpr>(E))
E = CE->getSubExpr();
else if (const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
E = Subst->getReplacement();
else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
// Look through implicit copy construction from an lvalue of the same type.
if (CCE->getParenOrBraceRange().isValid())
break;
// Note, there could be default arguments.
assert(CCE->getNumArgs() >= 1 && "implicit construct expr should have 1 arg");
E = CCE->getArg(0);
} else
break;
}
if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
if (NTTP->getDepth() == Depth)
return NTTP;
return nullptr;
}
static const NonTypeTemplateParmDecl *
getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) {
return getDeducedParameterFromExpr(E, Info.getDeducedDepth());
}
/// 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();
}
/// 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 that 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() && !(XA->isNull() && YA->isNull()))
return DeducedTemplateArgument();
NewPack.push_back(Merged);
}
return DeducedTemplateArgument(
TemplateArgument::CreatePackCopy(Context, NewPack),
X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
}
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// 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,
const 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 = const_cast<NonTypeTemplateParmDecl*>(NTTP);
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
return Sema::TDK_Inconsistent;
}
Deduced[NTTP->getIndex()] = Result;
if (!S.getLangOpts().CPlusPlus17)
return Sema::TDK_Success;
if (NTTP->isExpandedParameterPack())
// FIXME: We may still need to deduce parts of the type here! But we
// don't have any way to find which slice of the type to use, and the
// type stored on the NTTP itself is nonsense. Perhaps the type of an
// expanded NTTP should be a pack expansion type?
return Sema::TDK_Success;
// Get the type of the parameter for deduction. If it's a (dependent) array
// or function type, we will not have decayed it yet, so do that now.
QualType ParamType = S.Context.getAdjustedParameterType(NTTP->getType());
if (auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
ParamType = Expansion->getPattern();
// 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.
ValueType = ValueType.getNonReferenceType();
if (ParamType->isReferenceType())
ParamType = ParamType.getNonReferenceType();
else
// Top-level cv-qualifiers are irrelevant for a non-reference type.
ValueType = ValueType.getUnqualifiedType();
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, ParamType, ValueType, Info, Deduced,
TDF_SkipNonDependent, /*PartialOrdering=*/false,
/*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound());
}
/// Deduce the value of the given non-type template parameter
/// from the given integral constant.
static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
Sema &S, TemplateParameterList *TemplateParams,
const 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);
}
/// 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,
const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
Expr *Value = S.ImpCastExprToType(
new (S.Context) CXXNullPtrLiteralExpr(S.Context.NullPtrTy,
NTTP->getLocation()),
NullPtrType,
NullPtrType->isMemberPointerType() ? CK_NullToMemberPointer
: CK_NullToPointer)
.get();
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
DeducedTemplateArgument(Value),
Value->getType(), Info, Deduced);
}
/// 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,
const NonTypeTemplateParmDecl *NTTP, Expr *Value, TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
DeducedTemplateArgument(Value),
Value->getType(), Info, Deduced);
}
/// 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,
const 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;
}
/// 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
DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
const QualType P, QualType A,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
QualType UP = P;
if (const auto *IP = P->getAs<InjectedClassNameType>())
UP = IP->getInjectedSpecializationType();
// FIXME: Try to preserve type sugar here, which is hard
// because of the unresolved template arguments.
const auto *TP = UP.getCanonicalType()->castAs<TemplateSpecializationType>();
ArrayRef<TemplateArgument> PResolved = TP->template_arguments();
QualType UA = A;
// Treat an injected-class-name as its underlying template-id.
if (const auto *Injected = A->getAs<InjectedClassNameType>())
UA = Injected->getInjectedSpecializationType();
// Check whether the template argument is a dependent template-id.
// FIXME: Should not lose sugar here.
if (const auto *SA =
dyn_cast<TemplateSpecializationType>(UA.getCanonicalType())) {
// Perform template argument deduction for the template name.
if (auto Result =
DeduceTemplateArguments(S, TemplateParams, TP->getTemplateName(),
SA->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, PResolved,
SA->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 auto *RA = UA->getAs<RecordType>();
const auto *SA =
RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) : nullptr;
if (!SA) {
Info.FirstArg = TemplateArgument(P);
Info.SecondArg = TemplateArgument(A);
return Sema::TDK_NonDeducedMismatch;
}
// Perform template argument deduction for the template name.
if (auto Result = DeduceTemplateArguments(
S, TemplateParams, TP->getTemplateName(),
TemplateName(SA->getSpecializedTemplate()), Info, Deduced))
return Result;
// Perform template argument deduction for the template arguments.
return DeduceTemplateArguments(S, TemplateParams, PResolved,
SA->getTemplateArgs().asArray(), Info, Deduced,
/*NumberOfArgumentsMustMatch=*/true);
}
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T) {
assert(T->isCanonicalUnqualified());
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 IsPossiblyOpaquelyQualifiedTypeInternal(
cast<ArrayType>(T)->getElementType().getTypePtr());
default:
return false;
}
}
/// Determines whether the given type is an opaque type that
/// might be more qualified when instantiated.
static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
return IsPossiblyOpaquelyQualifiedTypeInternal(
T->getCanonicalTypeInternal().getTypePtr());
}
/// 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 {
// 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 = nullptr;
DeducedPack(unsigned Index) : Index(Index) {}
};
namespace {
/// A scope in which we're performing pack deduction.
class PackDeductionScope {
public:
/// Prepare to deduce the packs named within Pattern.
PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info, TemplateArgument Pattern)
: S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
unsigned NumNamedPacks = addPacks(Pattern);
finishConstruction(NumNamedPacks);
}
/// Prepare to directly deduce arguments of the parameter with index \p Index.
PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info, unsigned Index)
: S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
addPack(Index);
finishConstruction(1);
}
private:
void addPack(unsigned Index) {
// 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();
// FIXME: What if we encounter multiple packs with different numbers of
// pre-expanded expansions? (This should already have been diagnosed
// during substitution.)
if (Optional<unsigned> ExpandedPackExpansions =
getExpandedPackSize(TemplateParams->getParam(Index)))
FixedNumExpansions = ExpandedPackExpansions;
Packs.push_back(Pack);
}
unsigned addPacks(TemplateArgument Pattern) {
// Compute the set of template parameter indices that correspond to
// parameter packs expanded by the pack expansion.
llvm::SmallBitVector SawIndices(TemplateParams->size());
llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
auto AddPack = [&](unsigned Index) {
if (SawIndices[Index])
return;
SawIndices[Index] = true;
addPack(Index);
// Deducing a parameter pack that is a pack expansion also constrains the
// packs appearing in that parameter to have the same deduced arity. Also,
// in C++17 onwards, deducing a non-type template parameter deduces its
// type, so we need to collect the pending deduced values for those packs.
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
TemplateParams->getParam(Index))) {
if (!NTTP->isExpandedParameterPack())
if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType()))
ExtraDeductions.push_back(Expansion->getPattern());
}
// FIXME: Also collect the unexpanded packs in any type and template
// parameter packs that are pack expansions.
};
auto Collect = [&](TemplateArgument Pattern) {
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())
AddPack(Index);
}
};
// Look for unexpanded packs in the pattern.
Collect(Pattern);
assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
unsigned NumNamedPacks = Packs.size();
// Also look for unexpanded packs that are indirectly deduced by deducing
// the sizes of the packs in this pattern.
while (!ExtraDeductions.empty())
Collect(ExtraDeductions.pop_back_val());
return NumNamedPacks;
}
void finishConstruction(unsigned NumNamedPacks) {
// Dig out the partially-substituted pack, if there is one.
const TemplateArgument *PartialPackArgs = nullptr;
unsigned NumPartialPackArgs = 0;
std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
if (auto *Scope = S.CurrentInstantiationScope)
if (auto *Partial = Scope->getPartiallySubstitutedPack(
&PartialPackArgs, &NumPartialPackArgs))
PartialPackDepthIndex = getDepthAndIndex(Partial);
// This pack expansion will have been partially or fully expanded if
// it only names explicitly-specified parameter packs (including the
// partially-substituted one, if any).
bool IsExpanded = true;
for (unsigned I = 0; I != NumNamedPacks; ++I) {
if (Packs[I].Index >= Info.getNumExplicitArgs()) {
IsExpanded = false;
IsPartiallyExpanded = false;
break;
}
if (PartialPackDepthIndex ==
std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
IsPartiallyExpanded = true;
}
}
// Skip over the pack elements that were expanded into separate arguments.
// If we partially expanded, this is the number of partial arguments.
if (IsPartiallyExpanded)
PackElements += NumPartialPackArgs;
else if (IsExpanded)
PackElements += *FixedNumExpansions;
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 (PartialPackDepthIndex ==
std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
// We pre-populate the deduced value of the partially-substituted
// pack with the specified value. This is not entirely correct: the
// value is supposed to have been substituted, not deduced, but the
// cases where this is observable require an exact type match anyway.
//
// FIXME: If we could represent a "depth i, index j, pack elem k"
// parameter, we could substitute the partially-substituted pack
// everywhere and avoid this.
if (!IsPartiallyExpanded)
Deduced[Pack.Index] = Pack.New[PackElements];
}
}
}
public:
~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() { return IsPartiallyExpanded; }
/// Determine whether this pack expansion scope has a known, fixed arity.
/// This happens if it involves a pack from an outer template that has
/// (notionally) already been expanded.
bool hasFixedArity() { return FixedNumExpansions.hasValue(); }
/// Determine whether the next element of the argument is still part of this
/// pack. This is the case unless the pack is already expanded to a fixed
/// length.
bool hasNextElement() {
return !FixedNumExpansions || *FixedNumExpansions > PackElements;
}
/// 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());
if (Pack.New.size() == PackElements)
Pack.New.push_back(DeducedArg);
else
Pack.New[PackElements] = DeducedArg;
DeducedArg = Pack.New.size() > PackElements + 1
? Pack.New[PackElements + 1]
: DeducedTemplateArgument();
}
}
++PackElements;
}
/// 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;
// Always make sure the size of this pack is correct, even if we didn't
// deduce any values for it.
//
// FIXME: This isn't required by the normative wording, but substitution
// and post-substitution checking will always fail if the arity of any
// pack is not equal to the number of elements we processed. (Either that
// or something else has gone *very* wrong.) We're permitted to skip any
// hard errors from those follow-on steps by the intent (but not the
// wording) of C++ [temp.inst]p8:
//
// If the function selected by overload resolution can be determined
// without instantiating a class template definition, it is unspecified
// whether that instantiation actually takes place
Pack.New.resize(PackElements);
// Build or find a new value for this pack.
DeducedTemplateArgument NewPack;
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())),
// FIXME: This is wrong, it's possible that some pack elements are
// deduced from an array bound and others are not:
// template<typename ...T, T ...V> void g(const T (&...p)[V]);
// g({1, 2, 3}, {{}, {}});
// ... should deduce T = {int, size_t (from array bound)}.
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);
}
NamedDecl *Param = TemplateParams->getParam(Pack.Index);
if (Result.isNull()) {
Info.Param = makeTemplateParameter(Param);
Info.FirstArg = OldPack;
Info.SecondArg = NewPack;
return Sema::TDK_Inconsistent;
}
// If we have a pre-expanded pack and we didn't deduce enough elements
// for it, fail deduction.
if (Optional<unsigned> Expansions = getExpandedPackSize(Param)) {
if (*Expansions != PackElements) {
Info.Param = makeTemplateParameter(Param);
Info.FirstArg = Result;
return Sema::TDK_IncompletePack;
}
}
*Loc = Result;
}
return Sema::TDK_Success;
}
private:
Sema &S;
TemplateParameterList *TemplateParams;
SmallVectorImpl<DeducedTemplateArgument> &Deduced;
TemplateDeductionInfo &Info;
unsigned PackElements = 0;
bool IsPartiallyExpanded = false;
/// The number of expansions, if we have a fully-expanded pack in this scope.
Optional<unsigned> FixedNumExpansions;
SmallVector<DeducedPack, 2> Packs;
};
} // namespace
/// 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) {
// 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].getUnqualifiedType(),
Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
PartialOrdering,
/*DeducedFromArrayBound=*/false))
return Result;
++ArgIdx;
continue;
}
// 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);
// A pack scope with fixed arity is not really a pack any more, so is not
// a non-deduced context.
if (ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) {
for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) {
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result =
DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, Pattern.getUnqualifiedType(),
Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
PartialOrdering, /*DeducedFromArrayBound=*/false))
return Result;
PackScope.nextPackElement();
}
} else {
// 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.
//
// FIXME: There is no wording to say what we should do in this case. We
// choose to resolve this by applying the same rule that is applied for a
// function call: that is, deduce all contained packs to their
// explicitly-specified values (or to <> if there is no such value).
//
// This is seemingly-arbitrarily different from the case of a template-id
// with a non-trailing pack-expansion in its arguments, which renders the
// entire template-argument-list a non-deduced context.
// If the parameter type contains an explicitly-specified pack that we
// could not expand, skip the number of parameters notionally created
// by the expansion.
Optional<unsigned> NumExpansions = Expansion->getNumExpansions();
if (NumExpansions && !PackScope.isPartiallyExpanded()) {
for (unsigned I = 0; I != *NumExpansions && ArgIdx < NumArgs;
++I, ++ArgIdx)
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;
}
/// Determine whether the parameter has qualifiers that the argument
/// lacks. Put another way, determine whether there is no way to add
/// a deduced set of qualifiers to the ParamType that would result in
/// its qualifiers matching those of the ArgType.
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 qualifiers inconsistent or a superset.
return (ParamQs.getCVRQualifiers() & ~ArgQs.getCVRQualifiers()) != 0;
}
/// 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 P the template parameter type.
///
/// \param A the argument type.
bool Sema::isSameOrCompatibleFunctionType(QualType P, QualType A) {
const FunctionType *PF = P->getAs<FunctionType>(),
*AF = A->getAs<FunctionType>();
// Just compare if not functions.
if (!PF || !AF)
return Context.hasSameType(P, A);
// Noreturn and noexcept adjustment.
QualType AdjustedParam;
if (IsFunctionConversion(P, A, AdjustedParam))
return Context.hasSameType(AdjustedParam, A);
// FIXME: Compatible calling conventions.
return Context.hasSameType(P, A);
}
/// Get the index of the first template parameter that was originally from the
/// innermost template-parameter-list. This is 0 except when we concatenate
/// the template parameter lists of a class template and a constructor template
/// when forming an implicit deduction guide.
static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD) {
auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
if (!Guide || !Guide->isImplicit())
return 0;
return Guide->getDeducedTemplate()->getTemplateParameters()->size();
}
/// Determine whether a type denotes a forwarding reference.
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) {
// C++1z [temp.deduct.call]p3:
// A forwarding reference is an rvalue reference to a cv-unqualified
// template parameter that does not represent a template parameter of a
// class template.
if (auto *ParamRef = Param->getAs<RValueReferenceType>()) {
if (ParamRef->getPointeeType().getQualifiers())
return false;
auto *TypeParm = ParamRef->getPointeeType()->getAs<TemplateTypeParmType>();
return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
}
return false;
}
static CXXRecordDecl *getCanonicalRD(QualType T) {
return cast<CXXRecordDecl>(
T->castAs<RecordType>()->getDecl()->getCanonicalDecl());
}
/// Attempt to deduce the template arguments by checking the base types
/// according to (C++20 [temp.deduct.call] p4b3.
///
/// \param S the semantic analysis object within which we are deducing.
///
/// \param RecordT the top level record object we are deducing against.
///
/// \param TemplateParams the template parameters that we are deducing.
///
/// \param SpecParam the template specialization parameter type.
///
/// \param Info information about the template argument deduction itself.
///
/// \param Deduced the deduced template arguments.
///
/// \returns the result of template argument deduction with the bases. "invalid"
/// means no matches, "success" found a single item, and the
/// "MiscellaneousDeductionFailure" result happens when the match is ambiguous.
static Sema::TemplateDeductionResult
DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
TemplateParameterList *TemplateParams, QualType P,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
// 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. However, if there is a class C that is a (direct or
// indirect) base class of D and derived (directly or indirectly) from a
// class B and that would be a valid deduced A, the deduced A cannot be
// B or pointer to B, respectively.
//
// These alternatives are considered only if type deduction would
// otherwise fail. If they yield more than one possible deduced A, the
// type deduction fails.
// Use a breadth-first search through the bases to collect the set of
// successful matches. Visited contains the set of nodes we have already
// visited, while ToVisit is our stack of records that we still need to
// visit. Matches contains a list of matches that have yet to be
// disqualified.
llvm::SmallPtrSet<const CXXRecordDecl *, 8> Visited;
SmallVector<QualType, 8> ToVisit;
// We iterate over this later, so we have to use MapVector to ensure
// determinism.
llvm::MapVector<const CXXRecordDecl *,
SmallVector<DeducedTemplateArgument, 8>>
Matches;
auto AddBases = [&Visited, &ToVisit](const CXXRecordDecl *RD) {
for (const auto &Base : RD->bases()) {
QualType T = Base.getType();
assert(T->isRecordType() && "Base class that isn't a record?");
if (Visited.insert(::getCanonicalRD(T)).second)
ToVisit.push_back(T);
}
};
// Set up the loop by adding all the bases.
AddBases(RD);
// Search each path of bases until we either run into a successful match
// (where all bases of it are invalid), or we run out of bases.
while (!ToVisit.empty()) {
QualType NextT = ToVisit.pop_back_val();
SmallVector<DeducedTemplateArgument, 8> DeducedCopy(Deduced.begin(),
Deduced.end());
TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info);
Sema::TemplateDeductionResult BaseResult = DeduceTemplateSpecArguments(
S, TemplateParams, P, NextT, BaseInfo, DeducedCopy);
// If this was a successful deduction, add it to the list of matches,
// otherwise we need to continue searching its bases.
const CXXRecordDecl *RD = ::getCanonicalRD(NextT);
if (BaseResult == Sema::TDK_Success)
Matches.insert({RD, DeducedCopy});
else
AddBases(RD);
}
// At this point, 'Matches' contains a list of seemingly valid bases, however
// in the event that we have more than 1 match, it is possible that the base
// of one of the matches might be disqualified for being a base of another
// valid match. We can count on cyclical instantiations being invalid to
// simplify the disqualifications. That is, if A & B are both matches, and B
// inherits from A (disqualifying A), we know that A cannot inherit from B.
if (Matches.size() > 1) {
Visited.clear();
for (const auto &Match : Matches)
AddBases(Match.first);
// We can give up once we have a single item (or have run out of things to
// search) since cyclical inheritance isn't valid.
while (Matches.size() > 1 && !ToVisit.empty()) {
const CXXRecordDecl *RD = ::getCanonicalRD(ToVisit.pop_back_val());
Matches.erase(RD);
// Always add all bases, since the inheritance tree can contain
// disqualifications for multiple matches.
AddBases(RD);
}
}
if (Matches.empty())
return Sema::TDK_Invalid;
if (Matches.size() > 1)
return Sema::TDK_MiscellaneousDeductionFailure;
std::swap(Matches.front().second, Deduced);
return Sema::TDK_Success;
}
/// 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 P, QualType A,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF,
bool PartialOrdering, bool DeducedFromArrayBound) {
// If the argument type is a pack expansion, look at its pattern.
// This isn't explicitly called out
if (const auto *AExp = dyn_cast<PackExpansionType>(A))
A = AExp->getPattern();
assert(!isa<PackExpansionType>(A.getCanonicalType()));
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 *PRef = P->getAs<ReferenceType>();
if (PRef)
P = PRef->getPointeeType();
// - If A is a reference type, A is replaced by the type referred to.
const ReferenceType *ARef = A->getAs<ReferenceType>();
if (ARef)
A = A->getPointeeType();
if (PRef && ARef && S.Context.hasSameUnqualifiedType(P, A)) {
// 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 PQuals = P.getQualifiers(), AQuals = A.getQualifiers();
if ((PRef->isLValueReferenceType() && !ARef->isLValueReferenceType()) ||
PQuals.isStrictSupersetOf(AQuals) ||
(PQuals.hasNonTrivialObjCLifetime() &&
AQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
PQuals.withoutObjCLifetime() == AQuals.withoutObjCLifetime())) {
Info.FirstArg = TemplateArgument(P);
Info.SecondArg = TemplateArgument(A);
return Sema::TDK_NonDeducedMismatch;
}
}
Qualifiers DiscardedQuals;
// 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.
P = S.Context.getUnqualifiedArrayType(P, DiscardedQuals);
// - If A is a cv-qualified type, A is replaced by the cv-unqualified
// version of A.
A = S.Context.getUnqualifiedArrayType(A, DiscardedQuals);
} 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 UnqualP = S.Context.getUnqualifiedArrayType(P, Quals);
Quals.setCVRQualifiers(Quals.getCVRQualifiers() & A.getCVRQualifiers());
P = S.Context.getQualifiedType(UnqualP, Quals);
}
if ((TDF & TDF_TopLevelParameterTypeList) && !P->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 a forwarding reference 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 (isForwardingReference(P, /*FirstInnerIndex=*/0) &&
A->isLValueReferenceType())
P = P->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 auto *TTP = P->getAs<TemplateTypeParmType>()) {
// Just skip any attempts to deduce from a placeholder type or a parameter
// at a different depth.
if (A->isPlaceholderType() || Info.getDeducedDepth() != TTP->getDepth())
return Sema::TDK_Success;
unsigned Index = TTP->getIndex();
// 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 (A->isArrayType()) {
Qualifiers Quals;
A = S.Context.getUnqualifiedArrayType(A, Quals);
if (Quals)
A = S.Context.getQualifiedType(A, Quals);
}
// The argument type can not be less qualified than the parameter
// type.
if (!(TDF & TDF_IgnoreQualifiers) &&
hasInconsistentOrSupersetQualifiersOf(P, A)) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = TemplateArgument(P);
Info.SecondArg = TemplateArgument(A);
return Sema::TDK_Underqualified;
}
// Do not match a function type with a cv-qualified type.
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584
if (A->isFunctionType() && P.hasQualifiers())
return Sema::TDK_NonDeducedMismatch;
assert(TTP->getDepth() == Info.getDeducedDepth() &&
"saw template type parameter with wrong depth");
assert(A->getCanonicalTypeInternal() != S.Context.OverloadTy &&
"Unresolved overloaded function");
QualType DeducedType = A;
// Remove any qualifiers on the parameter from the deduced type.
// We checked the qualifiers for consistency above.
Qualifiers DeducedQs = DeducedType.getQualifiers();
Qualifiers ParamQs = P.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(P);
Info.SecondArg = TemplateArgument(A);
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);
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(P);
Info.SecondArg = TemplateArgument(A);
// 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 (P->getAs<SubstTemplateTypeParmPackType>())
return Sema::TDK_Success;
// Check the cv-qualifiers on the parameter and argument types.
if (!(TDF & TDF_IgnoreQualifiers)) {
if (TDF & TDF_ParamWithReferenceType) {
if (hasInconsistentOrSupersetQualifiersOf(P, A))
return Sema::TDK_NonDeducedMismatch;
} else if (TDF & TDF_ArgWithReferenceType) {
// C++ [temp.deduct.conv]p4:
// If the original A is a reference type, A can be more cv-qualified
// than the deduced A
if (!A.getQualifiers().compatiblyIncludes(P.getQualifiers()))
return Sema::TDK_NonDeducedMismatch;
// Strip out all extra qualifiers from the argument to figure out the
// type we're converting to, prior to the qualification conversion.
Qualifiers Quals;
A = S.Context.getUnqualifiedArrayType(A, Quals);
A = S.Context.getQualifiedType(A, P.getQualifiers());
} else if (!IsPossiblyOpaquelyQualifiedType(P)) {
if (P.getCVRQualifiers() != A.getCVRQualifiers())
return Sema::TDK_NonDeducedMismatch;
}
}
// If the parameter type is not dependent, there is nothing to deduce.
if (!P->isDependentType()) {
if (TDF & TDF_SkipNonDependent)
return Sema::TDK_Success;
if ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A)
: S.Context.hasSameType(P, A))
return Sema::TDK_Success;
if (TDF & TDF_AllowCompatibleFunctionType &&
S.isSameOrCompatibleFunctionType(P, A))
return Sema::TDK_Success;
if (!(TDF & TDF_IgnoreQualifiers))
return Sema::TDK_NonDeducedMismatch;
// Otherwise, when ignoring qualifiers, the types not having the same
// unqualified type does not mean they do not match, so in this case we
// must keep going and analyze with a non-dependent parameter type.
}
switch (P.getCanonicalType()->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.inc"
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
llvm_unreachable("Type nodes handled above");
case Type::Auto:
// FIXME: Implement deduction in dependent case.
if (P->isDependentType())
return Sema::TDK_Success;
LLVM_FALLTHROUGH;
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:
case Type::ExtInt:
return (TDF & TDF_SkipNonDependent) ||
((TDF & TDF_IgnoreQualifiers)
? S.Context.hasSameUnqualifiedType(P, A)
: S.Context.hasSameType(P, A))
? Sema::TDK_Success
: Sema::TDK_NonDeducedMismatch;
// _Complex T [placeholder extension]
case Type::Complex: {
const auto *CP = P->castAs<ComplexType>(), *CA = A->getAs<ComplexType>();
if (!CA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
Deduced, TDF);
}
// _Atomic T [extension]
case Type::Atomic: {
const auto *PA = P->castAs<AtomicType>(), *AA = A->getAs<AtomicType>();
if (!AA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
Deduced, TDF);
}
// T *
case Type::Pointer: {
QualType PointeeType;
if (const auto *PA = A->getAs<PointerType>()) {
PointeeType = PA->getPointeeType();
} else if (const auto *PA = A->getAs<ObjCObjectPointerType>()) {
PointeeType = PA->getPointeeType();
} else {
return Sema::TDK_NonDeducedMismatch;
}
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, P->castAs<PointerType>()->getPointeeType(),
PointeeType, Info, Deduced,
TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass));
}
// T &
case Type::LValueReference: {
const auto *RP = P->castAs<LValueReferenceType>(),
*RA = A->getAs<LValueReferenceType>();
if (!RA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
Deduced, 0);
}
// T && [C++0x]
case Type::RValueReference: {
const auto *RP = P->castAs<RValueReferenceType>(),
*RA = A->getAs<RValueReferenceType>();
if (!RA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
Deduced, 0);
}
// T [] (implied, but not stated explicitly)
case Type::IncompleteArray: {
const auto *IAA = S.Context.getAsIncompleteArrayType(A);
if (!IAA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams,
S.Context.getAsIncompleteArrayType(P)->getElementType(),
IAA->getElementType(), Info, Deduced, TDF & TDF_IgnoreQualifiers);
}
// T [integer-constant]
case Type::ConstantArray: {
const auto *CAA = S.Context.getAsConstantArrayType(A),
*CAP = S.Context.getAsConstantArrayType(P);
assert(CAP);
if (!CAA || CAA->getSize() != CAP->getSize())
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
Deduced, TDF & TDF_IgnoreQualifiers);
}
// type [i]
case Type::DependentSizedArray: {
const auto *AA = S.Context.getAsArrayType(A);
if (!AA)
return Sema::TDK_NonDeducedMismatch;
// Check the element type of the arrays
const auto *DAP = S.Context.getAsDependentSizedArrayType(P);
assert(DAP);
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, DAP->getElementType(), AA->getElementType(),
Info, Deduced, TDF & TDF_IgnoreQualifiers))
return Result;
// Determine the array bound is something we can deduce.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, DAP->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 auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
llvm::APSInt Size(CAA->getSize());
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, Size, S.Context.getSizeType(),
/*ArrayBound=*/true, Info, Deduced);
}
if (const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
if (DAA->getSizeExpr())
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, DAA->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: {
const auto *FPP = P->castAs<FunctionProtoType>(),
*FPA = A->getAs<FunctionProtoType>();
if (!FPA)
return Sema::TDK_NonDeducedMismatch;
if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
FPP->getRefQualifier() != FPA->getRefQualifier() ||
FPP->isVariadic() != FPA->isVariadic())
return Sema::TDK_NonDeducedMismatch;
// Check return types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
Info, Deduced, 0,
/*PartialOrdering=*/false,
/*DeducedFromArrayBound=*/false))
return Result;
// Check parameter types.
if (auto Result = DeduceTemplateArguments(
S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(),
FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced,
TDF & TDF_TopLevelParameterTypeList))
return Result;
if (TDF & TDF_AllowCompatibleFunctionType)
return Sema::TDK_Success;
// FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit
// deducing through the noexcept-specifier if it's part of the canonical
// type. libstdc++ relies on this.
Expr *NoexceptExpr = FPP->getNoexceptExpr();
if (const NonTypeTemplateParmDecl *NTTP =
NoexceptExpr ? getDeducedParameterFromExpr(Info, NoexceptExpr)
: nullptr) {
assert(NTTP->getDepth() == Info.getDeducedDepth() &&
"saw non-type template parameter with wrong depth");
llvm::APSInt Noexcept(1);
switch (FPA->canThrow()) {
case CT_Cannot:
Noexcept = 1;
LLVM_FALLTHROUGH;
case CT_Can:
// We give E in noexcept(E) the "deduced from array bound" treatment.
// FIXME: Should we?
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, Noexcept, S.Context.BoolTy,
/*DeducedFromArrayBound=*/true, Info, Deduced);
case CT_Dependent:
if (Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced);
// Can't deduce anything from throw(T...).
break;
}
}
// FIXME: Detect non-deduced exception specification mismatches?
//
// Careful about [temp.deduct.call] and [temp.deduct.conv], which allow
// top-level differences in noexcept-specifications.
return Sema::TDK_Success;
}
case Type::InjectedClassName:
// Treat a template's injected-class-name as if the template
// specialization type had been used.
// template-name<T> (where template-name refers to a class template)
// template-name<i>
// TT<T>
// TT<i>
// TT<>
case Type::TemplateSpecialization: {
// When Arg cannot be a derived class, we can just try to deduce template
// arguments from the template-id.
if (!(TDF & TDF_DerivedClass) || !A->isRecordType())
return DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info,
Deduced);
SmallVector<DeducedTemplateArgument, 8> DeducedOrig(Deduced.begin(),
Deduced.end());
auto Result =
DeduceTemplateSpecArguments(S, TemplateParams, P, A, 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(), A))
return Result;
// Reset the incorrectly deduced argument from above.
Deduced = DeducedOrig;
// Check bases according to C++14 [temp.deduct.call] p4b3:
auto BaseResult = DeduceTemplateBases(S, getCanonicalRD(A),
TemplateParams, P, Info, Deduced);
return BaseResult != Sema::TDK_Invalid ? BaseResult : 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 auto *MPP = P->castAs<MemberPointerType>(),
*MPA = A->getAs<MemberPointerType>();
if (!MPA)
return Sema::TDK_NonDeducedMismatch;
QualType PPT = MPP->getPointeeType();
if (PPT->isFunctionType())
S.adjustMemberFunctionCC(PPT, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());
QualType APT = MPA->getPointeeType();
if (APT->isFunctionType())
S.adjustMemberFunctionCC(APT, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());
unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, PPT, APT, Info, Deduced, SubTDF))
return Result;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, QualType(MPP->getClass(), 0),
QualType(MPA->getClass(), 0), Info, Deduced, SubTDF);
}
// (clang extension)
//
// type(^)(T)
// T(^)()
// T(^)(T)
case Type::BlockPointer: {
const auto *BPP = P->castAs<BlockPointerType>(),
*BPA = A->getAs<BlockPointerType>();
if (!BPA)
return Sema::TDK_NonDeducedMismatch;
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
Deduced, 0);
}
// (clang extension)
//
// T __attribute__(((ext_vector_type(<integral constant>))))
case Type::ExtVector: {
const auto *VP = P->castAs<ExtVectorType>();
QualType ElementType;
if (const auto *VA = A->getAs<ExtVectorType>()) {
// Make sure that the vectors have the same number of elements.
if (VP->getNumElements() != VA->getNumElements())
return Sema::TDK_NonDeducedMismatch;
ElementType = VA->getElementType();
} else if (const auto *VA = A->getAs<DependentSizedExtVectorType>()) {
// We can't check the number of elements, since the argument has a
// dependent number of elements. This can only occur during partial
// ordering.
ElementType = VA->getElementType();
} else {
return Sema::TDK_NonDeducedMismatch;
}
// Perform deduction on the element types.
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
TDF);
}
case Type::DependentVector: {
const auto *VP = P->castAs<DependentVectorType>();
if (const auto *VA = A->getAs<VectorType>()) {
// Perform deduction on the element types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VP->getElementType(), VA->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VP->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = VA->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.UnsignedIntTy, true,
Info, Deduced);
}
if (const auto *VA = A->getAs<DependentVectorType>()) {
// Perform deduction on the element types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VP->getElementType(), VA->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VP->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
VA->getSizeExpr(), Info, Deduced);
}
return Sema::TDK_NonDeducedMismatch;
}
// (clang extension)
//
// T __attribute__(((ext_vector_type(N))))
case Type::DependentSizedExtVector: {
const auto *VP = P->castAs<DependentSizedExtVectorType>();
if (const auto *VA = A->getAs<ExtVectorType>()) {
// Perform deduction on the element types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VP->getElementType(), VA->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VP->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = VA->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 auto *VA = A->getAs<DependentSizedExtVectorType>()) {
// Perform deduction on the element types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VP->getElementType(), VA->getElementType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VP->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
VA->getSizeExpr(), Info, Deduced);
}
return Sema::TDK_NonDeducedMismatch;
}
// (clang extension)
//
// T __attribute__((matrix_type(<integral constant>,
// <integral constant>)))
case Type::ConstantMatrix: {
const auto *MP = P->castAs<ConstantMatrixType>(),
*MA = A->getAs<ConstantMatrixType>();
if (!MA)
return Sema::TDK_NonDeducedMismatch;
// Check that the dimensions are the same
if (MP->getNumRows() != MA->getNumRows() ||
MP->getNumColumns() != MA->getNumColumns()) {
return Sema::TDK_NonDeducedMismatch;
}
// Perform deduction on element types.
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
Deduced, TDF);
}
case Type::DependentSizedMatrix: {
const auto *MP = P->castAs<DependentSizedMatrixType>();
const auto *MA = A->getAs<MatrixType>();
if (!MA)
return Sema::TDK_NonDeducedMismatch;
// Check the element type of the matrixes.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, MP->getElementType(), MA->getElementType(),
Info, Deduced, TDF))
return Result;
// Try to deduce a matrix dimension.
auto DeduceMatrixArg =
[&S, &Info, &Deduced, &TemplateParams](
Expr *ParamExpr, const MatrixType *A,
unsigned (ConstantMatrixType::*GetArgDimension)() const,
Expr *(DependentSizedMatrixType::*GetArgDimensionExpr)() const) {
const auto *ACM = dyn_cast<ConstantMatrixType>(A);
const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
if (!ParamExpr->isValueDependent()) {
Optional<llvm::APSInt> ParamConst =
ParamExpr->getIntegerConstantExpr(S.Context);
if (!ParamConst)
return Sema::TDK_NonDeducedMismatch;
if (ACM) {
if ((ACM->*GetArgDimension)() == *ParamConst)
return Sema::TDK_Success;
return Sema::TDK_NonDeducedMismatch;
}
Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
if (Optional<llvm::APSInt> ArgConst =
ArgExpr->getIntegerConstantExpr(S.Context))
if (*ArgConst == *ParamConst)
return Sema::TDK_Success;
return Sema::TDK_NonDeducedMismatch;
}
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, ParamExpr);
if (!NTTP)
return Sema::TDK_Success;
if (ACM) {
llvm::APSInt ArgConst(
S.Context.getTypeSize(S.Context.getSizeType()));
ArgConst = (ACM->*GetArgDimension)();
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, ArgConst, S.Context.getSizeType(),
/*ArrayBound=*/true, Info, Deduced);
}
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
(ADM->*GetArgDimensionExpr)(),
Info, Deduced);
};
if (auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
&ConstantMatrixType::getNumRows,
&DependentSizedMatrixType::getRowExpr))
return Result;
return DeduceMatrixArg(MP->getColumnExpr(), MA,
&ConstantMatrixType::getNumColumns,
&DependentSizedMatrixType::getColumnExpr);
}
// (clang extension)
//
// T __attribute__(((address_space(N))))
case Type::DependentAddressSpace: {
const auto *ASP = P->castAs<DependentAddressSpaceType>();
if (const auto *ASA = A->getAs<DependentAddressSpaceType>()) {
// Perform deduction on the pointer type.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
Info, Deduced, TDF))
return Result;
// Perform deduction on the address space, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced);
}
if (isTargetAddressSpace(A.getAddressSpace())) {
llvm::APSInt ArgAddressSpace(S.Context.getTypeSize(S.Context.IntTy),
false);
ArgAddressSpace = toTargetAddressSpace(A.getAddressSpace());
// Perform deduction on the pointer types.
if (auto Result = DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, ASP->getPointeeType(),
S.Context.removeAddrSpaceQualType(A), Info, Deduced, TDF))
return Result;
// Perform deduction on the address space, if we can.
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
ArgAddressSpace, S.Context.IntTy,
true, Info, Deduced);
}
return Sema::TDK_NonDeducedMismatch;
}
case Type::DependentExtInt: {
const auto *IP = P->castAs<DependentExtIntType>();
if (const auto *IA = A->getAs<ExtIntType>()) {
if (IP->isUnsigned() != IA->isUnsigned())
return Sema::TDK_NonDeducedMismatch;
const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, IP->getNumBitsExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = IA->getNumBits();
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
S.Context.IntTy, true, Info,
Deduced);
}
if (const auto *IA = A->getAs<DependentExtIntType>()) {
if (IP->isUnsigned() != IA->isUnsigned())
return Sema::TDK_NonDeducedMismatch;
return Sema::TDK_Success;
}
return Sema::TDK_NonDeducedMismatch;
}
case Type::TypeOfExpr:
case Type::TypeOf:
case Type::DependentName:
case Type::UnresolvedUsing:
case Type::Decltype:
case Type::UnaryTransform:
case Type::DeducedTemplateSpecialization:
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 &P, TemplateArgument A,
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 (A.isPackExpansion())
A = A.getPackExpansionPattern();
switch (P.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Null template argument in parameter list");
case TemplateArgument::Type:
if (A.getKind() == TemplateArgument::Type)
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, P.getAsType(), A.getAsType(), Info, Deduced, 0);
Info.FirstArg = P;
Info.SecondArg = A;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Template:
if (A.getKind() == TemplateArgument::Template)
return DeduceTemplateArguments(S, TemplateParams, P.getAsTemplate(),
A.getAsTemplate(), Info, Deduced);
Info.FirstArg = P;
Info.SecondArg = A;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::TemplateExpansion:
llvm_unreachable("caller should handle pack expansions");
case TemplateArgument::Declaration:
if (A.getKind() == TemplateArgument::Declaration &&
isSameDeclaration(P.getAsDecl(), A.getAsDecl()))
return Sema::TDK_Success;
Info.FirstArg = P;
Info.SecondArg = A;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::NullPtr:
if (A.getKind() == TemplateArgument::NullPtr &&
S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType()))
return Sema::TDK_Success;
Info.FirstArg = P;
Info.SecondArg = A;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Integral:
if (A.getKind() == TemplateArgument::Integral) {
if (hasSameExtendedValue(P.getAsIntegral(), A.getAsIntegral()))
return Sema::TDK_Success;
}
Info.FirstArg = P;
Info.SecondArg = A;
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Expression:
if (const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, P.getAsExpr())) {
if (A.getKind() == TemplateArgument::Integral)
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, A.getAsIntegral(), A.getIntegralType(),
/*ArrayBound=*/false, Info, Deduced);
if (A.getKind() == TemplateArgument::NullPtr)
return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP,
A.getNullPtrType(), Info, Deduced);
if (A.getKind() == TemplateArgument::Expression)
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
A.getAsExpr(), Info, Deduced);
if (A.getKind() == TemplateArgument::Declaration)
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, A.getAsDecl(), A.getParamTypeForDecl(),
Info, Deduced);
Info.FirstArg = P;
Info.SecondArg = A;
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!");
}
/// 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();
}
/// 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());
// FIXME: If this is a fixed-arity pack expansion from an outer level of
// templates, it should not be treated as a pack expansion.
if (A.isPackExpansion())
FoundPackExpansion = true;
}
return false;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
ArrayRef<TemplateArgument> Ps,
ArrayRef<TemplateArgument> As,
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(Ps))
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(Ps, ParamIdx); ++ParamIdx) {
const TemplateArgument &P = Ps[ParamIdx];
if (!P.isPackExpansion()) {
// The simple case: deduce template arguments by matching Pi and Ai.
// Check whether we have enough arguments.
if (!hasTemplateArgumentForDeduction(As, 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 (As[ArgIdx].isPackExpansion())
return Sema::TDK_MiscellaneousDeductionFailure;
// Perform deduction for this Pi/Ai pair.
if (auto Result = DeduceTemplateArguments(S, TemplateParams, P,
As[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 = P.getPackExpansionPattern();
// 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(As, ArgIdx) &&
PackScope.hasNextElement();
++ArgIdx) {
// Deduce template arguments from the pattern.
if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pattern,
As[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);
}
/// 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!");
}
/// 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.getAsTemplateOrTemplatePattern();
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(Context, Arg,
Builder.getWithLocInContext(Context), Loc);
return TemplateArgumentLoc(
Context, 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!");
}
TemplateArgumentLoc
Sema::getIdentityTemplateArgumentLoc(NamedDecl *TemplateParm,
SourceLocation Location) {
return getTrivialTemplateArgumentLoc(
Context.getInjectedTemplateArg(TemplateParm), QualType(), Location);
}
/// 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);
// 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 (Deduced[I].isNull() && Param->isTemplateParameterPack()) {
if (auto Result =
PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish())
return Result;
}
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;
}
// Substitute into the default template argument, if available.
bool HasDefaultArg = false;
TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
if (!TD) {
assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
isa<VarTemplatePartialSpecializationDecl>(Template));
return Sema::TDK_Incomplete;
}
TemplateArgumentLoc DefArg;
{
Qualifiers ThisTypeQuals;
CXXRecordDecl *ThisContext = nullptr;
if (auto *Rec = dyn_cast<CXXRecordDecl>(TD->getDeclContext()))
if (Rec->isLambda())
if (auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
ThisContext = Method->getParent();
ThisTypeQuals = Method->getMethodQualifiers();
}
Sema::CXXThisScopeRAII ThisScope(S, ThisContext, ThisTypeQuals,
S.getLangOpts().CPlusPlus17);
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;
}
static 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;
};
template<typename TemplateDeclT>
static Sema::TemplateDeductionResult
CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template,
ArrayRef<TemplateArgument> DeducedArgs,
TemplateDeductionInfo& Info) {
llvm::SmallVector<const