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) {
- // FIXME: Do we need to merge the results together here?
- if (checkDeducedTemplateArguments(Context,
- DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
- DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
- .isNull())
+ TemplateArgument Merged = checkDeducedTemplateArguments(
+ Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
+ DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()));
+ if (Merged.isNull())
return DeducedTemplateArgument();
+ NewPack.push_back(Merged);
}
- return X;
+ return DeducedTemplateArgument(
+ TemplateArgument::CreatePackCopy(Context, NewPack),
+ X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
}
llvm_unreachable("Invalid TemplateArgument Kind!");
// for that pack, then clear out the deduced argument.
for (auto &Pack : Packs) {
DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
- if (!DeducedArg.isNull()) {
+ if (!Pack.New.empty() || !DeducedArg.isNull()) {
+ while (Pack.New.size() < PackElements)
+ Pack.New.push_back(DeducedTemplateArgument());
Pack.New.push_back(DeducedArg);
DeducedArg = DeducedTemplateArgument();
}
}
+ ++PackElements;
}
/// \brief Finish template argument deduction for a set of argument packs,
/// producing the argument packs and checking for consistency with prior
/// deductions.
- Sema::TemplateDeductionResult finish(bool HasAnyArguments) {
+ Sema::TemplateDeductionResult finish() {
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
for (auto &Pack : Packs) {
// Build or find a new value for this pack.
DeducedTemplateArgument NewPack;
- if (HasAnyArguments && Pack.New.empty()) {
+ if (PackElements && Pack.New.empty()) {
if (Pack.DeferredDeduction.isNull()) {
// We were not able to deduce anything for this parameter pack
// (because it only appeared in non-deduced contexts), so just
TemplateParameterList *TemplateParams;
SmallVectorImpl<DeducedTemplateArgument> &Deduced;
TemplateDeductionInfo &Info;
+ unsigned PackElements = 0;
SmallVector<DeducedPack, 2> Packs;
};
QualType Pattern = Expansion->getPattern();
PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
- bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
- HasAnyArguments = true;
-
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern,
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (auto Result = PackScope.finish(HasAnyArguments))
+ if (auto Result = PackScope.finish())
return Result;
}
// Keep track of the deduced template arguments for each parameter pack
// expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
- bool HasAnyArguments = false;
for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) {
- HasAnyArguments = true;
-
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (auto Result = PackScope.finish(HasAnyArguments))
+ if (auto Result = PackScope.finish())
return Result;
}
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;
PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
ParamPattern);
- bool HasAnyArguments = false;
- for (; ArgIdx < Args.size(); ++ArgIdx) {
- HasAnyArguments = true;
-
+ for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) {
QualType OrigParamType = ParamPattern;
ParamType = OrigParamType;
Expr *Arg = Args[ArgIdx];
unsigned TDF = 0;
if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
ParamType, ArgType, Arg,
- TDF)) {
- // We can't actually perform any deduction for this argument, so stop
- // deduction at this point.
- ++ArgIdx;
- break;
- }
+ TDF))
+ continue;
+
+ // Keep track of the argument type and corresponding argument index,
+ // so we can check for compatibility between the deduced A and A.
+ if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
+ continue;
// As above, initializer lists need special handling.
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
TemplateDeductionResult Result;
if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE,
Info, Deduced, TDF, Result)) {
+ // FIXME: Bailing out here is wrong; we could still need to deduce
+ // from later pack elements.
++ArgIdx;
break;
}
if (Result)
return Result;
} else {
-
- // Keep track of the argument type and corresponding argument index,
- // so we can check for compatibility between the deduced A and A.
- if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
- OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx,
- ArgType));
+ OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx,
+ ArgType));
if (TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
Deduced, TDF))
return Result;
}
-
- PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (auto Result = PackScope.finish(HasAnyArguments))
+ if (auto Result = PackScope.finish())
return Result;
// After we've matching against a parameter pack, we're done.
g<int, float&, double&>(a, b, c, &c); // ok
}
}
+
+namespace overload_vs_pack {
+ void f(int);
+ void f(float);
+ void g(double);
+
+ template<typename ...T> struct X {};
+ template<typename ...T> void x(T...);
+
+ template<typename ...T> struct Y { typedef int type(typename T::error...); };
+ template<> struct Y<int, float, double> { typedef int type; };
+
+ template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+ template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+
+ template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
+ template<typename T> float &h1(...);
+
+ template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
+ template<typename T> float &h2(...);
+
+ int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
+ int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
+ int n3 = g1(X<int, float, double, char>(), f);
+ int n4 = g2(x<int, float, double, long>, f);
+
+ int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
+ int &a2 = h2<double>(0);
+
+ float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
+ float &b2 = h2<float>(0);
+
+ template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+ int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
+
+ template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+ int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
+}