|
17 | 17 | #include "clang/AST/Decl.h"
|
18 | 18 | #include "clang/AST/DeclCXX.h"
|
19 | 19 | #include "clang/AST/DeclTemplate.h"
|
| 20 | +#include "clang/AST/DependenceFlags.h" |
20 | 21 | #include "clang/AST/Expr.h"
|
21 | 22 | #include "clang/AST/ExprConcepts.h"
|
22 | 23 | #include "clang/AST/TemplateBase.h"
|
@@ -594,6 +595,19 @@ static bool calculateConstraintSatisfaction(
|
594 | 595 | ConstraintSatisfaction &Satisfaction,
|
595 | 596 | UnsignedOrNone PackSubstitutionIndex) {
|
596 | 597 |
|
| 598 | + // If the expression has been calculated, e.g. when we are in a nested |
| 599 | + // requirement, do not compute it repeatedly. |
| 600 | + if (auto *Expr = Constraint.getConceptSpecializationExpr(); |
| 601 | + Expr && Expr->getDependence() == ExprDependence::None) { |
| 602 | + auto &Calculated = Expr->getSatisfaction(); |
| 603 | + Satisfaction.ContainsErrors = Calculated.ContainsErrors; |
| 604 | + Satisfaction.IsSatisfied = Calculated.IsSatisfied; |
| 605 | + Satisfaction.Details.insert(Satisfaction.Details.end(), |
| 606 | + Calculated.records().begin(), |
| 607 | + Calculated.records().end()); |
| 608 | + return !Satisfaction.ContainsErrors; |
| 609 | + } |
| 610 | + |
597 | 611 | Sema::ContextRAII CurContext(
|
598 | 612 | S, Constraint.getConceptId()->getNamedConcept()->getDeclContext(),
|
599 | 613 | /*NewThisContext=*/false);
|
@@ -1581,6 +1595,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1581 | 1595 | SourceLocation Loc = ArgsAsWritten->NumTemplateArgs > I
|
1582 | 1596 | ? ArgsAsWritten->arguments()[I].getLocation()
|
1583 | 1597 | : SourceLocation();
|
| 1598 | + // FIXME: Investigate when we couldn't preserve the SourceLoc. What shall we do?? |
| 1599 | + // assert(Loc.isValid()); |
1584 | 1600 | if (OccurringIndices[I]) {
|
1585 | 1601 | NamedDecl *Param = TemplateParams->begin()[I];
|
1586 | 1602 | new (&(TempArgs)[J])
|
@@ -1637,6 +1653,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1637 | 1653 | // If this is an empty pack, we have no corresponding SubstArgs.
|
1638 | 1654 | if (I < SubstArgs.size())
|
1639 | 1655 | Loc = SubstArgs.arguments()[I].getLocation();
|
| 1656 | + // assert(Loc.isValid()); |
1640 | 1657 | TempArgs[I] = S.getTrivialTemplateArgumentLoc(CTAI.SugaredConverted[I],
|
1641 | 1658 | QualType(), Loc);
|
1642 | 1659 | }
|
@@ -1671,9 +1688,29 @@ substituteParameterMappings(Sema &S, ConceptIdConstraint &N,
|
1671 | 1688 | assert(CSE);
|
1672 | 1689 | TemplateArgumentListInfo Out;
|
1673 | 1690 | assert(!N.getBeginLoc().isInvalid());
|
1674 |
| - if (S.SubstTemplateArgumentsInParameterMapping( |
1675 |
| - CSE->getTemplateArgsAsWritten()->arguments(), N.getBeginLoc(), |
1676 |
| - MLTAL, Out)) |
| 1691 | + // TransformTemplateArguments is unable to preserve the source location of a |
| 1692 | + // pack. The SourceLocation is necessary for the instantiation location. |
| 1693 | + // FIXME: The BaseLoc will be used as the location of the pack expansion, |
| 1694 | + // which is wrong. |
| 1695 | + ArgsAsWritten = CSE->getTemplateArgsAsWritten(); |
| 1696 | + SourceLocation InstLocBegin = |
| 1697 | + ArgsAsWritten->arguments().empty() |
| 1698 | + ? ArgsAsWritten->getLAngleLoc() |
| 1699 | + : ArgsAsWritten->arguments().front().getSourceRange().getBegin(); |
| 1700 | + SourceLocation InstLocEnd = |
| 1701 | + ArgsAsWritten->arguments().empty() |
| 1702 | + ? ArgsAsWritten->getRAngleLoc() |
| 1703 | + : ArgsAsWritten->arguments().front().getSourceRange().getEnd(); |
| 1704 | + Sema::InstantiatingTemplate Inst( |
| 1705 | + S, InstLocBegin, |
| 1706 | + Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, |
| 1707 | + const_cast<NamedDecl *>(N.getConstraintDecl()), |
| 1708 | + {InstLocBegin, InstLocEnd}); |
| 1709 | + if (Inst.isInvalid()) |
| 1710 | + return true; |
| 1711 | + |
| 1712 | + if (S.SubstTemplateArgumentsInParameterMapping(ArgsAsWritten->arguments(), |
| 1713 | + N.getBeginLoc(), MLTAL, Out)) |
1677 | 1714 | return true;
|
1678 | 1715 | Sema::CheckTemplateArgumentInfo CTAI;
|
1679 | 1716 | if (S.CheckTemplateArgumentList(CSE->getNamedConcept(),
|
|
0 commit comments