================
@@ -7167,6 +7173,43 @@
TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
SubtitutedTypes.push_back(Pack);
continue;
}
+ // Fast path: substitute only the selected element instead of all N. A
+ // pack-indexing type inside a pack expansion (`T...[Is]...`) is
transformed
+ // once per outer element, so substituting the whole pack each time is
+ // O(N^2) in time and memory.
+ if (!RetainExpansion && Types.size() == 1 && IndexExpr.isUsable() &&
+ !IndexExpr.get()->isInstantiationDependent()) {
+ llvm::APSInt Value;
+ ExprResult CCE = SemaRef.CheckConvertedConstantExpression(
+ IndexExpr.get(), SemaRef.Context.getSizeType(), Value,
+ CCEKind::PackIndex);
+ if (!CCE.isUsable() || !Value.isRepresentableByInt64())
+ return QualType();
+ uint64_t V = Value.getZExtValue();
+ if (V < *NumExpansions) {
+ QualType Selected;
+ {
+ Sema::ArgPackSubstIndexRAII SubstIndex(getSema(),
+ static_cast<unsigned>(V));
+ Selected = getDerived().TransformType(T);
+ }
+ if (Selected.isNull())
+ return QualType();
+ if (!Selected->containsUnexpandedParameterPack() &&
+ !Selected->isInstantiationDependentType()) {
+ Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
+ QualType Result = getDerived().TransformType(TLB,
TL.getPatternLoc());
+ if (Result.isNull())
+ return QualType();
+ QualType Out = SemaRef.Context.getPackIndexingType(
+ Result, CCE.get(), /*FullySubstituted=*/true, {Selected},
+ /*Index=*/0u);
+ PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
+ Loc.setEllipsisLoc(TL.getEllipsisLoc());
+ return Out;
+ }
----------------
zyn0217 wrote:
Please don't try fixing two separate issues in one PR, if fixing that is not
necessary to address the problem this PR is focusing on.
https://github.com/llvm/llvm-project/pull/213790
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits