|
35 | 35 | #include "llvm/ADT/PointerUnion.h"
|
36 | 36 | #include "llvm/ADT/SmallVector.h"
|
37 | 37 | #include "llvm/ADT/StringExtras.h"
|
| 38 | +#include "llvm/Support/Timer.h" |
| 39 | +#include "llvm/Support/WithColor.h" |
38 | 40 | #include <cstddef>
|
39 | 41 | #include <optional>
|
40 | 42 |
|
@@ -390,16 +392,23 @@ SubstitutionInTemplateArguments(
|
390 | 392 | Constraint.mappingOccurenceList();
|
391 | 393 | SubstitutedOuterMost =
|
392 | 394 | llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
|
| 395 | + unsigned Offset = 0; |
393 | 396 | for (unsigned I = 0, MappedIndex = 0; I < Used.size(); I++) {
|
394 | 397 | TemplateArgument Arg;
|
395 | 398 | if (Used[I])
|
396 | 399 | Arg = S.Context.getCanonicalTemplateArgument(
|
397 | 400 | CTAI.SugaredConverted[MappedIndex++]);
|
398 |
| - if (I < SubstitutedOuterMost.size()) |
| 401 | + if (I < SubstitutedOuterMost.size()) { |
399 | 402 | SubstitutedOuterMost[I] = Arg;
|
400 |
| - else |
| 403 | + Offset = I + 1; |
| 404 | + } else { |
401 | 405 | SubstitutedOuterMost.push_back(Arg);
|
| 406 | + Offset = SubstitutedOuterMost.size(); |
| 407 | + } |
402 | 408 | }
|
| 409 | + if (Offset < SubstitutedOuterMost.size()) |
| 410 | + SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset); |
| 411 | + |
403 | 412 | MLTAL.replaceOutermostTemplateArguments(
|
404 | 413 | const_cast<NamedDecl *>(Constraint.getConstraintDecl()),
|
405 | 414 | SubstitutedOuterMost);
|
@@ -765,7 +774,8 @@ static bool CheckConstraintSatisfaction(
|
765 | 774 | if (TopLevelConceptId) {
|
766 | 775 | C = ConceptIdConstraint::Create(S.getASTContext(), TopLevelConceptId,
|
767 | 776 | const_cast<NormalizedConstraint *>(C),
|
768 |
| - Template, S.ArgPackSubstIndex); |
| 777 | + Template, /*CSE=*/nullptr, |
| 778 | + S.ArgPackSubstIndex); |
769 | 779 | }
|
770 | 780 |
|
771 | 781 | return !calculateConstraintSatisfaction(
|
@@ -1535,27 +1545,6 @@ void Sema::DiagnoseUnsatisfiedConstraint(
|
1535 | 1545 | ConstraintExpr->getBeginLoc(), First);
|
1536 | 1546 | }
|
1537 | 1547 |
|
1538 |
| -const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints( |
1539 |
| - ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq, |
1540 |
| - ArrayRef<AssociatedConstraint> AssociatedConstraints) { |
1541 |
| - if (!ConstrainedDeclOrNestedReq) |
1542 |
| - return NormalizedConstraint::fromAssociatedConstraints( |
1543 |
| - *this, nullptr, AssociatedConstraints); |
1544 |
| - |
1545 |
| - // FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement! |
1546 |
| - const NamedDecl *ND = |
1547 |
| - ConstrainedDeclOrNestedReq.dyn_cast<const NamedDecl *>(); |
1548 |
| - auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq); |
1549 |
| - if (CacheEntry == NormalizationCache.end()) { |
1550 |
| - auto *Normalized = NormalizedConstraint::fromAssociatedConstraints( |
1551 |
| - *this, ND, AssociatedConstraints); |
1552 |
| - CacheEntry = |
1553 |
| - NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized) |
1554 |
| - .first; |
1555 |
| - } |
1556 |
| - return CacheEntry->second; |
1557 |
| -} |
1558 |
| - |
1559 | 1548 | static bool
|
1560 | 1549 | substituteParameterMappings(Sema &S, NormalizedConstraint &N,
|
1561 | 1550 | const MultiLevelTemplateArgumentList &MLTAL,
|
@@ -1626,30 +1615,6 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1626 | 1615 | if (Inst.isInvalid())
|
1627 | 1616 | return true;
|
1628 | 1617 |
|
1629 |
| - unsigned Hash; |
1630 |
| - llvm::FoldingSetNodeID ID; |
1631 |
| - auto &Context = S.getASTContext(); |
1632 |
| - if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId) { |
1633 |
| - ID.AddPointer(static_cast<ConceptIdConstraint &>(N) |
1634 |
| - .getConceptId() |
1635 |
| - ->getNamedConcept() |
1636 |
| - ->getCanonicalDecl()); |
1637 |
| - for (auto &ArgLoc : static_cast<ConceptIdConstraint &>(N) |
1638 |
| - .getConceptId() |
1639 |
| - ->getTemplateArgsAsWritten() |
1640 |
| - ->arguments()) |
1641 |
| - ArgLoc.getArgument().Profile(ID, Context); |
1642 |
| - |
1643 |
| - Hash = ID.ComputeHash(); |
1644 |
| - if (auto Iter = S.ParameterMappingCache.find(Hash); |
1645 |
| - Iter != S.ParameterMappingCache.end()) { |
1646 |
| - N.updateParameterMapping(N.mappingOccurenceList(), Iter->second, |
1647 |
| - N.getUsedTemplateParamList()); |
1648 |
| - return false; |
1649 |
| - } |
1650 |
| - } |
1651 |
| - // FIXME: Cache for atomic constraints. |
1652 |
| - |
1653 | 1618 | // TransformTemplateArguments is unable to preserve the source location of a
|
1654 | 1619 | // pack. The SourceLocation is necessary for the instantiation location.
|
1655 | 1620 | // FIXME: The BaseLoc will be used as the location of the pack expansion,
|
@@ -1683,23 +1648,46 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1683 | 1648 | CTAI.SugaredConverted.size());
|
1684 | 1649 | N.updateParameterMapping(N.mappingOccurenceList(), Mapping,
|
1685 | 1650 | N.getUsedTemplateParamList());
|
1686 |
| - if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId) |
1687 |
| - S.ParameterMappingCache.insert({Hash, Mapping}); |
1688 | 1651 | return false;
|
1689 | 1652 | }
|
1690 | 1653 |
|
1691 | 1654 | static bool
|
1692 | 1655 | substituteParameterMappings(Sema &S, ConceptIdConstraint &N,
|
1693 | 1656 | const MultiLevelTemplateArgumentList &MLTAL,
|
1694 | 1657 | const ASTTemplateArgumentListInfo *ArgsAsWritten) {
|
1695 |
| - |
| 1658 | + assert(N.getConstraintDecl()); |
| 1659 | +#if 0 |
| 1660 | + return substituteParameterMappings( |
| 1661 | + S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL, |
| 1662 | + ArgsAsWritten); |
| 1663 | +#else |
| 1664 | + auto TemplateArgs = MLTAL; |
1696 | 1665 | if (N.getConstraintDecl()) {
|
1697 |
| - substituteParameterMappings( |
1698 |
| - S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL, |
1699 |
| - ArgsAsWritten); |
| 1666 | + if (substituteParameterMappings( |
| 1667 | + S, static_cast<NormalizedConstraintWithParamMapping &>(N), |
| 1668 | + TemplateArgs, ArgsAsWritten)) |
| 1669 | + return true; |
| 1670 | + auto *CSE = N.getConceptSpecializationExpr(); |
| 1671 | + assert(CSE); |
| 1672 | + TemplateArgumentListInfo Out; |
| 1673 | + assert(!N.getBeginLoc().isInvalid()); |
| 1674 | + if (S.SubstTemplateArgumentsInParameterMapping( |
| 1675 | + CSE->getTemplateArgsAsWritten()->arguments(), N.getBeginLoc(), |
| 1676 | + MLTAL, Out)) |
| 1677 | + return true; |
| 1678 | + Sema::CheckTemplateArgumentInfo CTAI; |
| 1679 | + if (S.CheckTemplateArgumentList(CSE->getNamedConcept(), |
| 1680 | + CSE->getConceptNameInfo().getLoc(), Out, |
| 1681 | + /*DefaultArgs=*/{}, |
| 1682 | + /*PartialTemplateArgs=*/false, CTAI, |
| 1683 | + /*UpdateArgsWithConversions=*/false)) |
| 1684 | + return true; |
| 1685 | + TemplateArgs.replaceOutermostTemplateArguments( |
| 1686 | + TemplateArgs.getAssociatedDecl(0).first, CTAI.CanonicalConverted); |
1700 | 1687 | }
|
1701 |
| - return substituteParameterMappings(S, N.getNormalizedConstraint(), MLTAL, |
1702 |
| - ArgsAsWritten); |
| 1688 | + return substituteParameterMappings(S, N.getNormalizedConstraint(), |
| 1689 | + TemplateArgs, ArgsAsWritten); |
| 1690 | +#endif |
1703 | 1691 | }
|
1704 | 1692 |
|
1705 | 1693 | static bool
|
@@ -1742,10 +1730,40 @@ static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
|
1742 | 1730 | // Don't build Subst* nodes to model lambda expressions.
|
1743 | 1731 | // The transform of Subst* is oblivious to the lambda type.
|
1744 | 1732 | MLTAL.setKind(TemplateSubstitutionKind::Rewrite);
|
| 1733 | + Sema::InstantiatingTemplate Inst( |
| 1734 | + S, N.getBeginLoc(), |
| 1735 | + Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, |
| 1736 | + CSE->getNamedConcept(), {N.getBeginLoc(), N.getEndLoc()}); |
| 1737 | + if (Inst.isInvalid()) |
| 1738 | + return true; |
| 1739 | + |
1745 | 1740 | return substituteParameterMappings(S, N, MLTAL,
|
1746 | 1741 | CSE->getTemplateArgsAsWritten());
|
1747 | 1742 | }
|
1748 | 1743 |
|
| 1744 | +static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N) { |
| 1745 | + switch (N.getKind()) { |
| 1746 | + case NormalizedConstraint::ConstraintKind::Atomic: |
| 1747 | + return false; |
| 1748 | + case NormalizedConstraint::ConstraintKind::FoldExpanded: { |
| 1749 | + Sema::ArgPackSubstIndexRAII _(S, std::nullopt); |
| 1750 | + return substituteParameterMappings( |
| 1751 | + S, static_cast<FoldExpandedConstraint &>(N).getNormalizedPattern()); |
| 1752 | + } |
| 1753 | + case NormalizedConstraint::ConstraintKind::ConceptId: { |
| 1754 | + auto &CC = static_cast<ConceptIdConstraint &>(N); |
| 1755 | + return substituteParameterMappings(S, CC.getNormalizedConstraint(), |
| 1756 | + CC.getConceptSpecializationExpr()); |
| 1757 | + } |
| 1758 | + case NormalizedConstraint::ConstraintKind::Compound: { |
| 1759 | + auto &Compound = static_cast<CompoundConstraint &>(N); |
| 1760 | + if (substituteParameterMappings(S, Compound.getLHS())) |
| 1761 | + return true; |
| 1762 | + return substituteParameterMappings(S, Compound.getRHS()); |
| 1763 | + } |
| 1764 | + } |
| 1765 | +} |
| 1766 | + |
1749 | 1767 | NormalizedConstraint *NormalizedConstraint::fromAssociatedConstraints(
|
1750 | 1768 | Sema &S, const NamedDecl *D, ArrayRef<AssociatedConstraint> ACs) {
|
1751 | 1769 | assert(ACs.size() != 0);
|
@@ -1824,11 +1842,11 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr(
|
1824 | 1842 | if (!SubNF)
|
1825 | 1843 | return nullptr;
|
1826 | 1844 | }
|
1827 |
| - if (substituteParameterMappings(S, *SubNF, CSE)) |
1828 |
| - return nullptr; |
| 1845 | + // if (substituteParameterMappings(S, *SubNF, CSE)) |
| 1846 | + // return nullptr; |
1829 | 1847 |
|
1830 | 1848 | return ConceptIdConstraint::Create(
|
1831 |
| - S.getASTContext(), CSE->getConceptReference(), SubNF, D, SubstIndex); |
| 1849 | + S.getASTContext(), CSE->getConceptReference(), SubNF, D, CSE, SubstIndex); |
1832 | 1850 |
|
1833 | 1851 | } else if (auto *FE = dyn_cast<const CXXFoldExpr>(E);
|
1834 | 1852 | FE && S.getLangOpts().CPlusPlus26 &&
|
@@ -1870,6 +1888,29 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr(
|
1870 | 1888 | return AtomicConstraint::Create(S.getASTContext(), E, D, SubstIndex);
|
1871 | 1889 | }
|
1872 | 1890 |
|
| 1891 | +const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints( |
| 1892 | + ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq, |
| 1893 | + ArrayRef<AssociatedConstraint> AssociatedConstraints) { |
| 1894 | + if (!ConstrainedDeclOrNestedReq) |
| 1895 | + return NormalizedConstraint::fromAssociatedConstraints( |
| 1896 | + *this, nullptr, AssociatedConstraints); |
| 1897 | + |
| 1898 | + // FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement! |
| 1899 | + const NamedDecl *ND = |
| 1900 | + ConstrainedDeclOrNestedReq.dyn_cast<const NamedDecl *>(); |
| 1901 | + auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq); |
| 1902 | + if (CacheEntry == NormalizationCache.end()) { |
| 1903 | + auto *Normalized = NormalizedConstraint::fromAssociatedConstraints( |
| 1904 | + *this, ND, AssociatedConstraints); |
| 1905 | + CacheEntry = |
| 1906 | + NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized) |
| 1907 | + .first; |
| 1908 | + if (!Normalized || substituteParameterMappings(*this, *Normalized)) |
| 1909 | + return nullptr; |
| 1910 | + } |
| 1911 | + return CacheEntry->second; |
| 1912 | +} |
| 1913 | + |
1873 | 1914 | bool FoldExpandedConstraint::AreCompatibleForSubsumption(
|
1874 | 1915 | const FoldExpandedConstraint &A, const FoldExpandedConstraint &B) {
|
1875 | 1916 |
|
|
0 commit comments