https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/79371
From d4ca5c2fcb87f424be23efc4513df491403c3811 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Wed, 24 Jan 2024 21:21:26 +0100 Subject: [PATCH 1/2] [Sema]Substitue template parameter packs when deduced from function parameter --- clang/lib/Sema/SemaTemplateDeduction.cpp | 63 +++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e9e7ab5bb6698a0..46fa9eece3747a2 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -730,6 +730,7 @@ class PackDeductionScope { void addPack(unsigned Index) { // Save the deduced template argument for the parameter pack expanded // by this pack expansion, then clear out the deduction. + DeducedFromEarlierParameter = !Deduced[Index].isNull(); DeducedPack Pack(Index); Pack.Saved = Deduced[Index]; Deduced[Index] = TemplateArgument(); @@ -858,6 +859,29 @@ class PackDeductionScope { Info.PendingDeducedPacks[Pack.Index] = Pack.Outer; } + std::optional<unsigned> getSavedPackSize(unsigned Index, + TemplateArgument Pattern) const { + + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + S.collectUnexpandedParameterPacks(Pattern, Unexpanded); + if (Unexpanded.size() == 0 || + Packs[0].Saved.getKind() != clang::TemplateArgument::Pack) + return {}; + unsigned PackSize = Packs[0].Saved.pack_size(); + + if (std::all_of(Packs.begin() + 1, Packs.end(), + [&PackSize](auto P) { + return P.Saved.getKind() == TemplateArgument::Pack && + P.Saved.pack_size() == PackSize; + })) + return PackSize; + return {}; + } + + /// Determine whether this pack has already been deduced from a previous + /// argument. + bool isDeducedFromEarlierParameter() const {return DeducedFromEarlierParameter;} + /// Determine whether this pack has already been partially expanded into a /// sequence of (prior) function parameters / template arguments. bool isPartiallyExpanded() { return IsPartiallyExpanded; } @@ -970,7 +994,6 @@ class PackDeductionScope { NewPack = Pack.DeferredDeduction; Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack); } - NamedDecl *Param = TemplateParams->getParam(Pack.Index); if (Result.isNull()) { Info.Param = makeTemplateParameter(Param); @@ -1003,9 +1026,12 @@ class PackDeductionScope { unsigned PackElements = 0; bool IsPartiallyExpanded = false; bool DeducePackIfNotAlreadyDeduced = false; + bool DeducedFromEarlierParameter = false; + /// The number of expansions, if we have a fully-expanded pack in this scope. std::optional<unsigned> FixedNumExpansions; + SmallVector<DeducedPack, 2> Packs; }; @@ -4371,6 +4397,41 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // corresponding argument is a list? PackScope.nextPackElement(); } + } else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() && + PackScope.isDeducedFromEarlierParameter() && + !isa<PackExpansionType>(ParamTypes[ParamIdx + 1])) { + // [temp.deduct.general#3] + // When all template arguments have been deduced + // or obtained from default template arguments, all uses of template + // parameters in the template parameter list of the template are + // replaced with the corresponding deduced or default argument values + // + // If we have a trailing parameter pack, that has been deduced perviously + // we substitute the pack here in a similar fashion as seen above with + // the trailing parameter packs. The main difference here is that, in + // this case we are not processing all of the remaining arguments. We + // are only process as many arguments as much we have in the already + // deduced parameter. + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + collectUnexpandedParameterPacks(ParamPattern, Unexpanded); + if (Unexpanded.size() == 0) + continue; + + std::optional<unsigned> ArgPosAfterSubstitution = + PackScope.getSavedPackSize(getDepthAndIndex(Unexpanded[0]).second, + ParamPattern); + if (!ArgPosAfterSubstitution) + continue; + + unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution; + for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) { + ParamTypesForArgChecking.push_back(ParamPattern); + if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, + /*ExplicitObjetArgument=*/false)) + return Result; + + PackScope.nextPackElement(); + } } } From 52de421b998481105e5522a04ad9e39a4a6cbb82 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Wed, 24 Jan 2024 22:33:02 +0100 Subject: [PATCH 2/2] Format changes --- clang/lib/Sema/SemaTemplateDeduction.cpp | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 46fa9eece3747a2..e682ca6dc0f7d45 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -869,18 +869,19 @@ class PackDeductionScope { return {}; unsigned PackSize = Packs[0].Saved.pack_size(); - if (std::all_of(Packs.begin() + 1, Packs.end(), - [&PackSize](auto P) { - return P.Saved.getKind() == TemplateArgument::Pack && - P.Saved.pack_size() == PackSize; - })) + if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](auto P) { + return P.Saved.getKind() == TemplateArgument::Pack && + P.Saved.pack_size() == PackSize; + })) return PackSize; return {}; } /// Determine whether this pack has already been deduced from a previous /// argument. - bool isDeducedFromEarlierParameter() const {return DeducedFromEarlierParameter;} + bool isDeducedFromEarlierParameter() const { + return DeducedFromEarlierParameter; + } /// Determine whether this pack has already been partially expanded into a /// sequence of (prior) function parameters / template arguments. @@ -4406,12 +4407,12 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // parameters in the template parameter list of the template are // replaced with the corresponding deduced or default argument values // - // If we have a trailing parameter pack, that has been deduced perviously - // we substitute the pack here in a similar fashion as seen above with - // the trailing parameter packs. The main difference here is that, in - // this case we are not processing all of the remaining arguments. We - // are only process as many arguments as much we have in the already - // deduced parameter. + // If we have a trailing parameter pack, that has been deduced + // perviously we substitute the pack here in a similar fashion as seen + // above with the trailing parameter packs. The main difference here is + // that, in this case we are not processing all of the remaining + // arguments. We are only process as many arguments as much we have in + // the already deduced parameter. SmallVector<UnexpandedParameterPack, 2> Unexpanded; collectUnexpandedParameterPacks(ParamPattern, Unexpanded); if (Unexpanded.size() == 0) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits