36
36
#include " llvm/ADT/PointerUnion.h"
37
37
#include " llvm/ADT/SmallVector.h"
38
38
#include " llvm/ADT/StringExtras.h"
39
- #include " llvm/Support/Timer.h"
40
- #include " llvm/Support/WithColor.h"
41
39
#include < cstddef>
42
40
#include < optional>
43
41
@@ -345,7 +343,7 @@ static ExprResult EvaluateAtomicConstraint(
345
343
return SubstitutedExpression;
346
344
}
347
345
348
- static bool calculateConstraintSatisfaction (
346
+ static ExprResult calculateConstraintSatisfaction (
349
347
Sema &S, const NormalizedConstraint &Constraint, const NamedDecl *Template,
350
348
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
351
349
ConstraintSatisfaction &Satisfaction, UnsignedOrNone PackSubstitutionIndex);
@@ -417,7 +415,7 @@ SubstitutionInTemplateArguments(
417
415
return std::move (MLTAL);
418
416
}
419
417
420
- static bool calculateConstraintSatisfaction (
418
+ static ExprResult calculateConstraintSatisfaction (
421
419
Sema &S, const AtomicConstraint &Constraint, const NamedDecl *Template,
422
420
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
423
421
ConstraintSatisfaction &Satisfaction,
@@ -497,7 +495,7 @@ static bool calculateConstraintSatisfaction(
497
495
if (!Satisfaction.IsSatisfied )
498
496
Satisfaction.Details .emplace_back (SubstitutedAtomicExpr.get ());
499
497
500
- return SubstitutedAtomicExpr. isUsable () ;
498
+ return SubstitutedAtomicExpr;
501
499
}
502
500
503
501
static UnsignedOrNone EvaluateFoldExpandedConstraintSize (
@@ -533,7 +531,7 @@ static UnsignedOrNone EvaluateFoldExpandedConstraintSize(
533
531
return NumExpansions;
534
532
}
535
533
536
- static bool calculateConstraintSatisfaction (
534
+ static ExprResult calculateConstraintSatisfaction (
537
535
Sema &S, const FoldExpandedConstraint &FE, const NamedDecl *Template,
538
536
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
539
537
ConstraintSatisfaction &Satisfaction) {
@@ -568,12 +566,13 @@ static bool calculateConstraintSatisfaction(
568
566
Sema::ArgPackSubstIndexRAII SubstIndex (S, I);
569
567
Satisfaction.IsSatisfied = false ;
570
568
Satisfaction.ContainsErrors = false ;
571
- bool Success = calculateConstraintSatisfaction (
569
+ // FIXME
570
+ ExprResult Expr = calculateConstraintSatisfaction (
572
571
S, FE.getNormalizedPattern (), Template, TemplateNameLoc,
573
572
*SubstitutedArgs, Satisfaction, UnsignedOrNone (I));
574
573
// SFINAE errors shouldn't prevent disjunction from evaluating
575
574
// FIXME: Does !Success == SFINAE errors occurred?
576
- if (!Success && Conjunction)
575
+ if (!Expr. isUsable () && Conjunction)
577
576
return false ;
578
577
if (!Conjunction && Satisfaction.IsSatisfied ) {
579
578
Satisfaction.Details .erase (Satisfaction.Details .begin () +
@@ -589,25 +588,12 @@ static bool calculateConstraintSatisfaction(
589
588
return true ;
590
589
}
591
590
592
- static bool calculateConstraintSatisfaction (
591
+ static ExprResult calculateConstraintSatisfaction (
593
592
Sema &S, const ConceptIdConstraint &Constraint, const NamedDecl *Template,
594
593
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
595
594
ConstraintSatisfaction &Satisfaction,
596
595
UnsignedOrNone PackSubstitutionIndex) {
597
596
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
-
611
597
Sema::ContextRAII CurContext (
612
598
S, Constraint.getConceptId ()->getNamedConcept ()->getDeclContext (),
613
599
/* NewThisContext=*/ false );
@@ -620,11 +606,12 @@ static bool calculateConstraintSatisfaction(
620
606
621
607
auto Size = Satisfaction.Details .size ();
622
608
623
- bool Ok = calculateConstraintSatisfaction (
609
+ ExprResult E = calculateConstraintSatisfaction (
624
610
S, Constraint.getNormalizedConstraint (), Template, TemplateNameLoc, MLTAL,
625
611
Satisfaction, PackSubstitutionIndex);
626
612
627
- if (Size != Satisfaction.Details .size ()) {
613
+ if (!E.isUsable ())
614
+ return E;
628
615
629
616
llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
630
617
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
@@ -633,7 +620,7 @@ static bool calculateConstraintSatisfaction(
633
620
PackSubstitutionIndex);
634
621
635
622
if (!SubstitutedArgs)
636
- return Ok ;
623
+ return E. isUsable () ;
637
624
638
625
Sema::SFINAETrap Trap (S);
639
626
Sema::ArgPackSubstIndexRAII SubstIndex (
@@ -652,12 +639,15 @@ static bool calculateConstraintSatisfaction(
652
639
AdjustConstraintDepth Adjust (S, Depth);
653
640
if (Adjust.TransformTemplateArguments (Ori->getTemplateArgs (),
654
641
Ori->NumTemplateArgs , TransArgs))
655
- return Ok ;
642
+ return false ;
656
643
657
644
if (S.SubstTemplateArguments (TransArgs.arguments (), *SubstitutedArgs,
658
645
OutArgs) ||
659
- Trap.hasErrorOccurred ())
660
- return Ok;
646
+ Trap.hasErrorOccurred ()) {
647
+ Satisfaction.ContainsErrors = true ;
648
+ Satisfaction.IsSatisfied = false ;
649
+ return false ;
650
+ }
661
651
662
652
CXXScopeSpec SS;
663
653
SS.Adopt (Constraint.getConceptId ()->getNestedNameSpecifierLoc ());
@@ -669,18 +659,20 @@ static bool calculateConstraintSatisfaction(
669
659
/* CheckConstraintSatisfaction=*/ false );
670
660
671
661
if (SubstitutedConceptId.isInvalid () || Trap.hasErrorOccurred ())
672
- return Ok;
662
+ return false ;
663
+
664
+ if (Size != Satisfaction.Details .size ()) {
673
665
674
666
Satisfaction.Details .insert (
675
667
Satisfaction.Details .begin () + Size,
676
668
UnsatisfiedConstraintRecord (
677
669
SubstitutedConceptId.getAs <ConceptSpecializationExpr>()
678
670
->getConceptReference ()));
679
671
}
680
- return Ok ;
672
+ return SubstitutedConceptId ;
681
673
}
682
674
683
- static bool calculateConstraintSatisfaction (
675
+ static ExprResult calculateConstraintSatisfaction (
684
676
Sema &S, const CompoundConstraint &Constraint, const NamedDecl *Template,
685
677
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
686
678
ConstraintSatisfaction &Satisfaction,
@@ -691,35 +683,49 @@ static bool calculateConstraintSatisfaction(
691
683
bool Conjunction =
692
684
Constraint.getCompoundKind () == NormalizedConstraint::CCK_Conjunction;
693
685
694
- bool Ok = calculateConstraintSatisfaction (
686
+ ExprResult LHS = calculateConstraintSatisfaction (
695
687
S, Constraint.getLHS (), Template, TemplateNameLoc, MLTAL, Satisfaction,
696
688
PackSubstitutionIndex);
697
689
698
- if (Conjunction && !Ok )
690
+ if (Conjunction && !LHS. isUsable () )
699
691
return false ;
700
692
701
- if (!Conjunction && Ok && Satisfaction.IsSatisfied &&
693
+ if (!Conjunction && LHS. isUsable () && Satisfaction.IsSatisfied &&
702
694
!Satisfaction.ContainsErrors )
703
- return true ;
695
+ return LHS ;
704
696
705
- if (Conjunction && Ok &&
697
+ if (Conjunction && LHS. isUsable () &&
706
698
(!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors ))
707
- return true ;
699
+ return LHS ;
708
700
709
701
Satisfaction.ContainsErrors = false ;
710
702
Satisfaction.IsSatisfied = false ;
711
703
712
- Ok = calculateConstraintSatisfaction (S, Constraint. getRHS (), Template,
713
- TemplateNameLoc, MLTAL, Satisfaction,
704
+ ExprResult RHS = calculateConstraintSatisfaction (
705
+ S, Constraint. getRHS (), Template, TemplateNameLoc, MLTAL, Satisfaction,
714
706
PackSubstitutionIndex);
715
- if (Ok && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors )
707
+ if (RHS. isUsable () && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors )
716
708
Satisfaction.Details .erase (Satisfaction.Details .begin () +
717
709
EffectiveDetailEndIndex,
718
710
Satisfaction.Details .end ());
719
- return Ok;
711
+
712
+ if (!LHS.isUsable ())
713
+ return RHS;
714
+
715
+ if (!RHS.isUsable ())
716
+ return LHS;
717
+
718
+ return BinaryOperator::Create (
719
+ S.Context , LHS.get (), RHS.get (),
720
+ BinaryOperator::getOverloadedOpcode (
721
+ Constraint.getCompoundKind () == NormalizedConstraint::CCK_Conjunction
722
+ ? OO_AmpAmp
723
+ : OO_PipePipe),
724
+ S.Context .BoolTy , VK_PRValue, OK_Ordinary, Constraint.getBeginLoc (),
725
+ FPOptionsOverride{});
720
726
}
721
727
722
- static bool calculateConstraintSatisfaction (
728
+ static ExprResult calculateConstraintSatisfaction (
723
729
Sema &S, const NormalizedConstraint &Constraint, const NamedDecl *Template,
724
730
SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL,
725
731
ConstraintSatisfaction &Satisfaction,
@@ -753,7 +759,10 @@ static bool CheckConstraintSatisfaction(
753
759
ArrayRef<AssociatedConstraint> AssociatedConstraints,
754
760
const MultiLevelTemplateArgumentList &TemplateArgsLists,
755
761
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction,
756
- const ConceptReference *TopLevelConceptId = nullptr ) {
762
+ Expr **ConvertedExpr, const ConceptReference *TopLevelConceptId = nullptr ) {
763
+
764
+ if (ConvertedExpr)
765
+ *ConvertedExpr = nullptr ;
757
766
758
767
if (AssociatedConstraints.empty ()) {
759
768
Satisfaction.IsSatisfied = true ;
@@ -790,7 +799,6 @@ static bool CheckConstraintSatisfaction(
790
799
const_cast <NormalizedConstraint *>(C),
791
800
Template, /* CSE=*/ nullptr ,
792
801
S.ArgPackSubstIndex );
793
- }
794
802
795
803
ExprResult Res = calculateConstraintSatisfaction (
796
804
S, *C, Template, TemplateIDRange.getBegin (), TemplateArgsLists,
@@ -810,16 +818,16 @@ bool Sema::CheckConstraintSatisfaction(
810
818
ArrayRef<AssociatedConstraint> AssociatedConstraints,
811
819
const MultiLevelTemplateArgumentList &TemplateArgsLists,
812
820
SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction,
813
- const ConceptReference *TopLevelConceptId) {
821
+ const ConceptReference *TopLevelConceptId, Expr **ConvertedExpr ) {
814
822
if (AssociatedConstraints.empty ()) {
815
823
OutSatisfaction.IsSatisfied = true ;
816
824
return false ;
817
825
}
818
826
const auto *Template = Entity.dyn_cast <const NamedDecl *>();
819
827
if (!Template) {
820
- return ::CheckConstraintSatisfaction (* this , nullptr , AssociatedConstraints,
821
- TemplateArgsLists, TemplateIDRange ,
822
- OutSatisfaction, TopLevelConceptId);
828
+ return ::CheckConstraintSatisfaction (
829
+ * this , nullptr , AssociatedConstraints, TemplateArgsLists ,
830
+ TemplateIDRange, OutSatisfaction, ConvertedExpr , TopLevelConceptId);
823
831
}
824
832
// Invalid templates could make their way here. Substituting them could result
825
833
// in dependent expressions.
@@ -850,13 +858,15 @@ bool Sema::CheckConstraintSatisfaction(
850
858
851
859
auto Satisfaction =
852
860
std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
853
- if (::CheckConstraintSatisfaction (* this , Template, AssociatedConstraints,
854
- TemplateArgsLists, TemplateIDRange ,
855
- *Satisfaction, TopLevelConceptId)) {
861
+ if (::CheckConstraintSatisfaction (
862
+ * this , Template, AssociatedConstraints, TemplateArgsLists ,
863
+ TemplateIDRange, *Satisfaction, ConvertedExpr , TopLevelConceptId)) {
856
864
OutSatisfaction = *Satisfaction;
857
865
return true ;
858
866
}
859
867
868
+ // FIXME: cache ConvertedExpr for nested requirements?
869
+
860
870
if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos (ID, InsertPos)) {
861
871
// The evaluation of this constraint resulted in us trying to re-evaluate it
862
872
// recursively. This isn't really possible, except we try to form a
@@ -1612,7 +1622,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
1612
1622
SourceLocation Loc = ArgsAsWritten->NumTemplateArgs > I
1613
1623
? ArgsAsWritten->arguments ()[I].getLocation ()
1614
1624
: SourceLocation ();
1615
- // FIXME: Investigate when we couldn't preserve the SourceLoc. What shall we do??
1625
+ // FIXME: Investigate when we couldn't preserve the SourceLoc. What shall
1626
+ // we do??
1616
1627
// assert(Loc.isValid());
1617
1628
if (OccurringIndices[I]) {
1618
1629
NamedDecl *Param = TemplateParams->begin ()[I];
@@ -1945,9 +1956,14 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr(
1945
1956
const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints (
1946
1957
ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq,
1947
1958
ArrayRef<AssociatedConstraint> AssociatedConstraints) {
1948
- if (!ConstrainedDeclOrNestedReq)
1949
- return NormalizedConstraint::fromAssociatedConstraints (
1959
+ if (!ConstrainedDeclOrNestedReq) {
1960
+ auto *Normalized = NormalizedConstraint::fromAssociatedConstraints (
1950
1961
*this , nullptr , AssociatedConstraints);
1962
+ if (!Normalized || substituteParameterMappings (*this , *Normalized))
1963
+ return nullptr ;
1964
+
1965
+ return Normalized;
1966
+ }
1951
1967
1952
1968
// FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement!
1953
1969
const NamedDecl *ND =
0 commit comments