|
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);
|
@@ -1598,6 +1612,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1598 | 1612 | SourceLocation Loc = ArgsAsWritten->NumTemplateArgs > I
|
1599 | 1613 | ? ArgsAsWritten->arguments()[I].getLocation()
|
1600 | 1614 | : SourceLocation();
|
| 1615 | + // FIXME: Investigate when we couldn't preserve the SourceLoc. What shall we do?? |
| 1616 | + // assert(Loc.isValid()); |
1601 | 1617 | if (OccurringIndices[I]) {
|
1602 | 1618 | NamedDecl *Param = TemplateParams->begin()[I];
|
1603 | 1619 | new (&(TempArgs)[J])
|
@@ -1654,6 +1670,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
|
1654 | 1670 | // If this is an empty pack, we have no corresponding SubstArgs.
|
1655 | 1671 | if (I < SubstArgs.size())
|
1656 | 1672 | Loc = SubstArgs.arguments()[I].getLocation();
|
| 1673 | + // assert(Loc.isValid()); |
1657 | 1674 | TempArgs[I] = S.getTrivialTemplateArgumentLoc(CTAI.SugaredConverted[I],
|
1658 | 1675 | QualType(), Loc);
|
1659 | 1676 | }
|
@@ -1688,9 +1705,29 @@ substituteParameterMappings(Sema &S, ConceptIdConstraint &N,
|
1688 | 1705 | assert(CSE);
|
1689 | 1706 | TemplateArgumentListInfo Out;
|
1690 | 1707 | assert(!N.getBeginLoc().isInvalid());
|
1691 |
| - if (S.SubstTemplateArgumentsInParameterMapping( |
1692 |
| - CSE->getTemplateArgsAsWritten()->arguments(), N.getBeginLoc(), |
1693 |
| - MLTAL, Out)) |
| 1708 | + // TransformTemplateArguments is unable to preserve the source location of a |
| 1709 | + // pack. The SourceLocation is necessary for the instantiation location. |
| 1710 | + // FIXME: The BaseLoc will be used as the location of the pack expansion, |
| 1711 | + // which is wrong. |
| 1712 | + ArgsAsWritten = CSE->getTemplateArgsAsWritten(); |
| 1713 | + SourceLocation InstLocBegin = |
| 1714 | + ArgsAsWritten->arguments().empty() |
| 1715 | + ? ArgsAsWritten->getLAngleLoc() |
| 1716 | + : ArgsAsWritten->arguments().front().getSourceRange().getBegin(); |
| 1717 | + SourceLocation InstLocEnd = |
| 1718 | + ArgsAsWritten->arguments().empty() |
| 1719 | + ? ArgsAsWritten->getRAngleLoc() |
| 1720 | + : ArgsAsWritten->arguments().front().getSourceRange().getEnd(); |
| 1721 | + Sema::InstantiatingTemplate Inst( |
| 1722 | + S, InstLocBegin, |
| 1723 | + Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, |
| 1724 | + const_cast<NamedDecl *>(N.getConstraintDecl()), |
| 1725 | + {InstLocBegin, InstLocEnd}); |
| 1726 | + if (Inst.isInvalid()) |
| 1727 | + return true; |
| 1728 | + |
| 1729 | + if (S.SubstTemplateArgumentsInParameterMapping(ArgsAsWritten->arguments(), |
| 1730 | + N.getBeginLoc(), MLTAL, Out)) |
1694 | 1731 | return true;
|
1695 | 1732 | Sema::CheckTemplateArgumentInfo CTAI;
|
1696 | 1733 | if (S.CheckTemplateArgumentList(CSE->getNamedConcept(),
|
|
0 commit comments