================
@@ -1611,13 +1618,28 @@ namespace {
}
return Type;
}
+
// Override the default version to handle a rewrite-template-arg-pack case
// for building a deduction guide.
bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
TemplateArgumentLoc &Output,
bool Uneval = false) {
const TemplateArgument &Arg = Input.getArgument();
std::vector<TemplateArgument> TArgs;
+ if (auto *Cache = SemaRef.CurrentCachedTemplateArgs;
+ TemplateArgsHashValue && Cache) {
+ llvm::FoldingSetNodeID ID = *TemplateArgsHashValue;
+ ID.AddInteger(SemaRef.ArgPackSubstIndex.toInternalRepresentation());
+ Input.getArgument().Profile(ID, SemaRef.Context);
----------------
zyn0217 wrote:
To demonstrate how badly performance was impacted, consider this example (which
is a very common pattern extracted from libc++):
```cpp
template <class Tp, class Up>
concept common_with = same_as<common_type<Tp, Up>, common_type<Up, Tp>> &&
requires { /*expressions that use Tp and Up many times*/} &&
common_reference_with<const Tp, const Up> && ...;
```
After normalization, Tp and Up are substituted with their corresponding
template arguments within the resulting atomic expressions. So we end up
substituting into the same Tp and Up parameters multiple times, whereas they
technically only need to be substituted once. (The one-shot-substitution
behavior was a natural result of the previous
substitution-first-normalization-second approach)
Clang always struggles with avoiding template transforms, and I think this
approach is our best effort so far to alleviate the issue without an overhaul
of the template instantiation stuffs.
https://github.com/llvm/llvm-project/pull/188421
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits