Home | History | Annotate | Line # | Download | only in Sema
      1      1.1  joerg //===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===//
      2      1.1  joerg //
      3      1.1  joerg //                     The LLVM Compiler Infrastructure
      4      1.1  joerg //
      5      1.1  joerg // This file is distributed under the University of Illinois Open Source
      6      1.1  joerg // License. See LICENSE.TXT for details.
      7      1.1  joerg //
      8      1.1  joerg //===----------------------------------------------------------------------===//
      9      1.1  joerg //
     10      1.1  joerg //  This file implements semantic analysis for C++ constraints and concepts.
     11      1.1  joerg //
     12      1.1  joerg //===----------------------------------------------------------------------===//
     13      1.1  joerg 
     14  1.1.1.2  joerg #include "clang/Sema/SemaConcept.h"
     15      1.1  joerg #include "clang/Sema/Sema.h"
     16  1.1.1.2  joerg #include "clang/Sema/SemaInternal.h"
     17      1.1  joerg #include "clang/Sema/SemaDiagnostic.h"
     18      1.1  joerg #include "clang/Sema/TemplateDeduction.h"
     19      1.1  joerg #include "clang/Sema/Template.h"
     20  1.1.1.2  joerg #include "clang/Sema/Overload.h"
     21  1.1.1.2  joerg #include "clang/Sema/Initialization.h"
     22  1.1.1.2  joerg #include "clang/Sema/SemaInternal.h"
     23  1.1.1.2  joerg #include "clang/AST/ExprConcepts.h"
     24  1.1.1.2  joerg #include "clang/AST/RecursiveASTVisitor.h"
     25  1.1.1.2  joerg #include "clang/Basic/OperatorPrecedence.h"
     26  1.1.1.2  joerg #include "llvm/ADT/DenseMap.h"
     27  1.1.1.2  joerg #include "llvm/ADT/PointerUnion.h"
     28      1.1  joerg using namespace clang;
     29      1.1  joerg using namespace sema;
     30      1.1  joerg 
     31  1.1.1.2  joerg namespace {
     32  1.1.1.2  joerg class LogicalBinOp {
     33  1.1.1.2  joerg   OverloadedOperatorKind Op = OO_None;
     34  1.1.1.2  joerg   const Expr *LHS = nullptr;
     35  1.1.1.2  joerg   const Expr *RHS = nullptr;
     36  1.1.1.2  joerg 
     37  1.1.1.2  joerg public:
     38  1.1.1.2  joerg   LogicalBinOp(const Expr *E) {
     39  1.1.1.2  joerg     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
     40  1.1.1.2  joerg       Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
     41  1.1.1.2  joerg       LHS = BO->getLHS();
     42  1.1.1.2  joerg       RHS = BO->getRHS();
     43  1.1.1.2  joerg     } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
     44  1.1.1.2  joerg       Op = OO->getOperator();
     45  1.1.1.2  joerg       LHS = OO->getArg(0);
     46  1.1.1.2  joerg       RHS = OO->getArg(1);
     47  1.1.1.2  joerg     }
     48  1.1.1.2  joerg   }
     49  1.1.1.2  joerg 
     50  1.1.1.2  joerg   bool isAnd() const { return Op == OO_AmpAmp; }
     51  1.1.1.2  joerg   bool isOr() const { return Op == OO_PipePipe; }
     52  1.1.1.2  joerg   explicit operator bool() const { return isAnd() || isOr(); }
     53  1.1.1.2  joerg 
     54  1.1.1.2  joerg   const Expr *getLHS() const { return LHS; }
     55  1.1.1.2  joerg   const Expr *getRHS() const { return RHS; }
     56  1.1.1.2  joerg };
     57  1.1.1.2  joerg }
     58  1.1.1.2  joerg 
     59  1.1.1.2  joerg bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
     60  1.1.1.2  joerg                                      Token NextToken, bool *PossibleNonPrimary,
     61  1.1.1.2  joerg                                      bool IsTrailingRequiresClause) {
     62      1.1  joerg   // C++2a [temp.constr.atomic]p1
     63      1.1  joerg   // ..E shall be a constant expression of type bool.
     64      1.1  joerg 
     65      1.1  joerg   ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
     66      1.1  joerg 
     67  1.1.1.2  joerg   if (LogicalBinOp BO = ConstraintExpression) {
     68  1.1.1.2  joerg     return CheckConstraintExpression(BO.getLHS(), NextToken,
     69  1.1.1.2  joerg                                      PossibleNonPrimary) &&
     70  1.1.1.2  joerg            CheckConstraintExpression(BO.getRHS(), NextToken,
     71  1.1.1.2  joerg                                      PossibleNonPrimary);
     72      1.1  joerg   } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
     73  1.1.1.2  joerg     return CheckConstraintExpression(C->getSubExpr(), NextToken,
     74  1.1.1.2  joerg                                      PossibleNonPrimary);
     75  1.1.1.2  joerg 
     76  1.1.1.2  joerg   QualType Type = ConstraintExpression->getType();
     77  1.1.1.2  joerg 
     78  1.1.1.2  joerg   auto CheckForNonPrimary = [&] {
     79  1.1.1.2  joerg     if (PossibleNonPrimary)
     80  1.1.1.2  joerg       *PossibleNonPrimary =
     81  1.1.1.2  joerg           // We have the following case:
     82  1.1.1.2  joerg           // template<typename> requires func(0) struct S { };
     83  1.1.1.2  joerg           // The user probably isn't aware of the parentheses required around
     84  1.1.1.2  joerg           // the function call, and we're only going to parse 'func' as the
     85  1.1.1.2  joerg           // primary-expression, and complain that it is of non-bool type.
     86  1.1.1.2  joerg           (NextToken.is(tok::l_paren) &&
     87  1.1.1.2  joerg            (IsTrailingRequiresClause ||
     88  1.1.1.2  joerg             (Type->isDependentType() &&
     89  1.1.1.2  joerg              isa<UnresolvedLookupExpr>(ConstraintExpression)) ||
     90  1.1.1.2  joerg             Type->isFunctionType() ||
     91  1.1.1.2  joerg             Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
     92  1.1.1.2  joerg           // We have the following case:
     93  1.1.1.2  joerg           // template<typename T> requires size_<T> == 0 struct S { };
     94  1.1.1.2  joerg           // The user probably isn't aware of the parentheses required around
     95  1.1.1.2  joerg           // the binary operator, and we're only going to parse 'func' as the
     96  1.1.1.2  joerg           // first operand, and complain that it is of non-bool type.
     97  1.1.1.2  joerg           getBinOpPrecedence(NextToken.getKind(),
     98  1.1.1.2  joerg                              /*GreaterThanIsOperator=*/true,
     99  1.1.1.2  joerg                              getLangOpts().CPlusPlus11) > prec::LogicalAnd;
    100  1.1.1.2  joerg   };
    101      1.1  joerg 
    102      1.1  joerg   // An atomic constraint!
    103  1.1.1.2  joerg   if (ConstraintExpression->isTypeDependent()) {
    104  1.1.1.2  joerg     CheckForNonPrimary();
    105      1.1  joerg     return true;
    106  1.1.1.2  joerg   }
    107      1.1  joerg 
    108      1.1  joerg   if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) {
    109      1.1  joerg     Diag(ConstraintExpression->getExprLoc(),
    110      1.1  joerg          diag::err_non_bool_atomic_constraint) << Type
    111      1.1  joerg         << ConstraintExpression->getSourceRange();
    112  1.1.1.2  joerg     CheckForNonPrimary();
    113      1.1  joerg     return false;
    114      1.1  joerg   }
    115  1.1.1.2  joerg 
    116  1.1.1.2  joerg   if (PossibleNonPrimary)
    117  1.1.1.2  joerg       *PossibleNonPrimary = false;
    118      1.1  joerg   return true;
    119      1.1  joerg }
    120      1.1  joerg 
    121  1.1.1.2  joerg template <typename AtomicEvaluator>
    122  1.1.1.2  joerg static bool
    123  1.1.1.2  joerg calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
    124  1.1.1.2  joerg                                 ConstraintSatisfaction &Satisfaction,
    125  1.1.1.2  joerg                                 AtomicEvaluator &&Evaluator) {
    126      1.1  joerg   ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
    127      1.1  joerg 
    128  1.1.1.2  joerg   if (LogicalBinOp BO = ConstraintExpr) {
    129  1.1.1.2  joerg     if (calculateConstraintSatisfaction(S, BO.getLHS(), Satisfaction,
    130  1.1.1.2  joerg                                         Evaluator))
    131  1.1.1.2  joerg       return true;
    132      1.1  joerg 
    133  1.1.1.2  joerg     bool IsLHSSatisfied = Satisfaction.IsSatisfied;
    134      1.1  joerg 
    135  1.1.1.2  joerg     if (BO.isOr() && IsLHSSatisfied)
    136  1.1.1.2  joerg       // [temp.constr.op] p3
    137  1.1.1.2  joerg       //    A disjunction is a constraint taking two operands. To determine if
    138  1.1.1.2  joerg       //    a disjunction is satisfied, the satisfaction of the first operand
    139  1.1.1.2  joerg       //    is checked. If that is satisfied, the disjunction is satisfied.
    140  1.1.1.2  joerg       //    Otherwise, the disjunction is satisfied if and only if the second
    141  1.1.1.2  joerg       //    operand is satisfied.
    142  1.1.1.2  joerg       return false;
    143      1.1  joerg 
    144  1.1.1.2  joerg     if (BO.isAnd() && !IsLHSSatisfied)
    145  1.1.1.2  joerg       // [temp.constr.op] p2
    146  1.1.1.2  joerg       //    A conjunction is a constraint taking two operands. To determine if
    147  1.1.1.2  joerg       //    a conjunction is satisfied, the satisfaction of the first operand
    148  1.1.1.2  joerg       //    is checked. If that is not satisfied, the conjunction is not
    149  1.1.1.2  joerg       //    satisfied. Otherwise, the conjunction is satisfied if and only if
    150  1.1.1.2  joerg       //    the second operand is satisfied.
    151      1.1  joerg       return false;
    152  1.1.1.2  joerg 
    153  1.1.1.2  joerg     return calculateConstraintSatisfaction(
    154  1.1.1.2  joerg         S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
    155  1.1.1.2  joerg   } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
    156  1.1.1.2  joerg     return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction,
    157  1.1.1.2  joerg         std::forward<AtomicEvaluator>(Evaluator));
    158      1.1  joerg   }
    159      1.1  joerg 
    160  1.1.1.2  joerg   // An atomic constraint expression
    161  1.1.1.2  joerg   ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
    162  1.1.1.2  joerg 
    163  1.1.1.2  joerg   if (SubstitutedAtomicExpr.isInvalid())
    164      1.1  joerg     return true;
    165      1.1  joerg 
    166  1.1.1.2  joerg   if (!SubstitutedAtomicExpr.isUsable())
    167  1.1.1.2  joerg     // Evaluator has decided satisfaction without yielding an expression.
    168  1.1.1.2  joerg     return false;
    169  1.1.1.2  joerg 
    170  1.1.1.2  joerg   EnterExpressionEvaluationContext ConstantEvaluated(
    171  1.1.1.2  joerg       S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
    172      1.1  joerg   SmallVector<PartialDiagnosticAt, 2> EvaluationDiags;
    173      1.1  joerg   Expr::EvalResult EvalResult;
    174      1.1  joerg   EvalResult.Diag = &EvaluationDiags;
    175  1.1.1.2  joerg   if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
    176  1.1.1.2  joerg                                                            S.Context) ||
    177  1.1.1.2  joerg       !EvaluationDiags.empty()) {
    178      1.1  joerg     // C++2a [temp.constr.atomic]p1
    179      1.1  joerg     //   ...E shall be a constant expression of type bool.
    180  1.1.1.2  joerg     S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
    181  1.1.1.2  joerg            diag::err_non_constant_constraint_expression)
    182  1.1.1.2  joerg         << SubstitutedAtomicExpr.get()->getSourceRange();
    183      1.1  joerg     for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
    184  1.1.1.2  joerg       S.Diag(PDiag.first, PDiag.second);
    185  1.1.1.2  joerg     return true;
    186  1.1.1.2  joerg   }
    187  1.1.1.2  joerg 
    188  1.1.1.2  joerg   assert(EvalResult.Val.isInt() &&
    189  1.1.1.2  joerg          "evaluating bool expression didn't produce int");
    190  1.1.1.2  joerg   Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
    191  1.1.1.2  joerg   if (!Satisfaction.IsSatisfied)
    192  1.1.1.2  joerg     Satisfaction.Details.emplace_back(ConstraintExpr,
    193  1.1.1.2  joerg                                       SubstitutedAtomicExpr.get());
    194  1.1.1.2  joerg 
    195  1.1.1.2  joerg   return false;
    196  1.1.1.2  joerg }
    197  1.1.1.2  joerg 
    198  1.1.1.2  joerg static bool calculateConstraintSatisfaction(
    199  1.1.1.2  joerg     Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
    200  1.1.1.2  joerg     SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
    201  1.1.1.2  joerg     const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
    202  1.1.1.2  joerg   return calculateConstraintSatisfaction(
    203  1.1.1.2  joerg       S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
    204  1.1.1.2  joerg         EnterExpressionEvaluationContext ConstantEvaluated(
    205  1.1.1.2  joerg             S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
    206  1.1.1.2  joerg 
    207  1.1.1.2  joerg         // Atomic constraint - substitute arguments and check satisfaction.
    208  1.1.1.2  joerg         ExprResult SubstitutedExpression;
    209  1.1.1.2  joerg         {
    210  1.1.1.2  joerg           TemplateDeductionInfo Info(TemplateNameLoc);
    211  1.1.1.2  joerg           Sema::InstantiatingTemplate Inst(S, AtomicExpr->getBeginLoc(),
    212  1.1.1.2  joerg               Sema::InstantiatingTemplate::ConstraintSubstitution{},
    213  1.1.1.2  joerg               const_cast<NamedDecl *>(Template), Info,
    214  1.1.1.2  joerg               AtomicExpr->getSourceRange());
    215  1.1.1.2  joerg           if (Inst.isInvalid())
    216  1.1.1.2  joerg             return ExprError();
    217  1.1.1.2  joerg           // We do not want error diagnostics escaping here.
    218  1.1.1.2  joerg           Sema::SFINAETrap Trap(S);
    219  1.1.1.2  joerg           SubstitutedExpression = S.SubstExpr(const_cast<Expr *>(AtomicExpr),
    220  1.1.1.2  joerg                                               MLTAL);
    221  1.1.1.2  joerg           // Substitution might have stripped off a contextual conversion to
    222  1.1.1.2  joerg           // bool if this is the operand of an '&&' or '||'. For example, we
    223  1.1.1.2  joerg           // might lose an lvalue-to-rvalue conversion here. If so, put it back
    224  1.1.1.2  joerg           // before we try to evaluate.
    225  1.1.1.2  joerg           if (!SubstitutedExpression.isInvalid())
    226  1.1.1.2  joerg             SubstitutedExpression =
    227  1.1.1.2  joerg                 S.PerformContextuallyConvertToBool(SubstitutedExpression.get());
    228  1.1.1.2  joerg           if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
    229  1.1.1.2  joerg             // C++2a [temp.constr.atomic]p1
    230  1.1.1.2  joerg             //   ...If substitution results in an invalid type or expression, the
    231  1.1.1.2  joerg             //   constraint is not satisfied.
    232  1.1.1.2  joerg             if (!Trap.hasErrorOccurred())
    233  1.1.1.2  joerg               // A non-SFINAE error has occured as a result of this
    234  1.1.1.2  joerg               // substitution.
    235  1.1.1.2  joerg               return ExprError();
    236  1.1.1.2  joerg 
    237  1.1.1.2  joerg             PartialDiagnosticAt SubstDiag{SourceLocation(),
    238  1.1.1.2  joerg                                           PartialDiagnostic::NullDiagnostic()};
    239  1.1.1.2  joerg             Info.takeSFINAEDiagnostic(SubstDiag);
    240  1.1.1.2  joerg             // FIXME: Concepts: This is an unfortunate consequence of there
    241  1.1.1.2  joerg             //  being no serialization code for PartialDiagnostics and the fact
    242  1.1.1.2  joerg             //  that serializing them would likely take a lot more storage than
    243  1.1.1.2  joerg             //  just storing them as strings. We would still like, in the
    244  1.1.1.2  joerg             //  future, to serialize the proper PartialDiagnostic as serializing
    245  1.1.1.2  joerg             //  it as a string defeats the purpose of the diagnostic mechanism.
    246  1.1.1.2  joerg             SmallString<128> DiagString;
    247  1.1.1.2  joerg             DiagString = ": ";
    248  1.1.1.2  joerg             SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
    249  1.1.1.2  joerg             unsigned MessageSize = DiagString.size();
    250  1.1.1.2  joerg             char *Mem = new (S.Context) char[MessageSize];
    251  1.1.1.2  joerg             memcpy(Mem, DiagString.c_str(), MessageSize);
    252  1.1.1.2  joerg             Satisfaction.Details.emplace_back(
    253  1.1.1.2  joerg                 AtomicExpr,
    254  1.1.1.2  joerg                 new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
    255  1.1.1.2  joerg                         SubstDiag.first, StringRef(Mem, MessageSize)});
    256  1.1.1.2  joerg             Satisfaction.IsSatisfied = false;
    257  1.1.1.2  joerg             return ExprEmpty();
    258  1.1.1.2  joerg           }
    259  1.1.1.2  joerg         }
    260  1.1.1.2  joerg 
    261  1.1.1.2  joerg         if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
    262  1.1.1.2  joerg           return ExprError();
    263  1.1.1.2  joerg 
    264  1.1.1.2  joerg         return SubstitutedExpression;
    265  1.1.1.2  joerg       });
    266  1.1.1.2  joerg }
    267  1.1.1.2  joerg 
    268  1.1.1.2  joerg static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
    269  1.1.1.2  joerg                                         ArrayRef<const Expr *> ConstraintExprs,
    270  1.1.1.2  joerg                                         ArrayRef<TemplateArgument> TemplateArgs,
    271  1.1.1.2  joerg                                         SourceRange TemplateIDRange,
    272  1.1.1.2  joerg                                         ConstraintSatisfaction &Satisfaction) {
    273  1.1.1.2  joerg   if (ConstraintExprs.empty()) {
    274  1.1.1.2  joerg     Satisfaction.IsSatisfied = true;
    275  1.1.1.2  joerg     return false;
    276  1.1.1.2  joerg   }
    277  1.1.1.2  joerg 
    278  1.1.1.2  joerg   for (auto& Arg : TemplateArgs)
    279  1.1.1.2  joerg     if (Arg.isInstantiationDependent()) {
    280  1.1.1.2  joerg       // No need to check satisfaction for dependent constraint expressions.
    281  1.1.1.2  joerg       Satisfaction.IsSatisfied = true;
    282  1.1.1.2  joerg       return false;
    283  1.1.1.2  joerg     }
    284  1.1.1.2  joerg 
    285  1.1.1.2  joerg   Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
    286  1.1.1.2  joerg       Sema::InstantiatingTemplate::ConstraintsCheck{},
    287  1.1.1.2  joerg       const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
    288  1.1.1.2  joerg   if (Inst.isInvalid())
    289  1.1.1.2  joerg     return true;
    290  1.1.1.2  joerg 
    291  1.1.1.2  joerg   MultiLevelTemplateArgumentList MLTAL;
    292  1.1.1.2  joerg   MLTAL.addOuterTemplateArguments(TemplateArgs);
    293  1.1.1.2  joerg 
    294  1.1.1.2  joerg   for (const Expr *ConstraintExpr : ConstraintExprs) {
    295  1.1.1.2  joerg     if (calculateConstraintSatisfaction(S, Template, TemplateArgs,
    296  1.1.1.2  joerg                                         TemplateIDRange.getBegin(), MLTAL,
    297  1.1.1.2  joerg                                         ConstraintExpr, Satisfaction))
    298  1.1.1.2  joerg       return true;
    299  1.1.1.2  joerg     if (!Satisfaction.IsSatisfied)
    300  1.1.1.2  joerg       // [temp.constr.op] p2
    301  1.1.1.2  joerg       //   [...] To determine if a conjunction is satisfied, the satisfaction
    302  1.1.1.2  joerg       //   of the first operand is checked. If that is not satisfied, the
    303  1.1.1.2  joerg       //   conjunction is not satisfied. [...]
    304  1.1.1.2  joerg       return false;
    305  1.1.1.2  joerg   }
    306  1.1.1.2  joerg   return false;
    307  1.1.1.2  joerg }
    308  1.1.1.2  joerg 
    309  1.1.1.2  joerg bool Sema::CheckConstraintSatisfaction(
    310  1.1.1.2  joerg     const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
    311  1.1.1.2  joerg     ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
    312  1.1.1.2  joerg     ConstraintSatisfaction &OutSatisfaction) {
    313  1.1.1.2  joerg   if (ConstraintExprs.empty()) {
    314  1.1.1.2  joerg     OutSatisfaction.IsSatisfied = true;
    315  1.1.1.2  joerg     return false;
    316  1.1.1.2  joerg   }
    317  1.1.1.2  joerg 
    318  1.1.1.2  joerg   llvm::FoldingSetNodeID ID;
    319  1.1.1.2  joerg   void *InsertPos;
    320  1.1.1.2  joerg   ConstraintSatisfaction *Satisfaction = nullptr;
    321  1.1.1.2  joerg   bool ShouldCache = LangOpts.ConceptSatisfactionCaching && Template;
    322  1.1.1.2  joerg   if (ShouldCache) {
    323  1.1.1.2  joerg     ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
    324  1.1.1.2  joerg     Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
    325  1.1.1.2  joerg     if (Satisfaction) {
    326  1.1.1.2  joerg       OutSatisfaction = *Satisfaction;
    327  1.1.1.2  joerg       return false;
    328  1.1.1.2  joerg     }
    329  1.1.1.2  joerg     Satisfaction = new ConstraintSatisfaction(Template, TemplateArgs);
    330  1.1.1.2  joerg   } else {
    331  1.1.1.2  joerg     Satisfaction = &OutSatisfaction;
    332  1.1.1.2  joerg   }
    333  1.1.1.2  joerg   if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
    334  1.1.1.2  joerg                                     TemplateArgs, TemplateIDRange,
    335  1.1.1.2  joerg                                     *Satisfaction)) {
    336  1.1.1.2  joerg     if (ShouldCache)
    337  1.1.1.2  joerg       delete Satisfaction;
    338      1.1  joerg     return true;
    339      1.1  joerg   }
    340      1.1  joerg 
    341  1.1.1.2  joerg   if (ShouldCache) {
    342  1.1.1.2  joerg     // We cannot use InsertNode here because CheckConstraintSatisfaction might
    343  1.1.1.2  joerg     // have invalidated it.
    344  1.1.1.2  joerg     SatisfactionCache.InsertNode(Satisfaction);
    345  1.1.1.2  joerg     OutSatisfaction = *Satisfaction;
    346  1.1.1.2  joerg   }
    347  1.1.1.2  joerg   return false;
    348  1.1.1.2  joerg }
    349  1.1.1.2  joerg 
    350  1.1.1.2  joerg bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
    351  1.1.1.2  joerg                                        ConstraintSatisfaction &Satisfaction) {
    352  1.1.1.2  joerg   return calculateConstraintSatisfaction(
    353  1.1.1.2  joerg       *this, ConstraintExpr, Satisfaction,
    354  1.1.1.2  joerg       [](const Expr *AtomicExpr) -> ExprResult {
    355  1.1.1.2  joerg         return ExprResult(const_cast<Expr *>(AtomicExpr));
    356  1.1.1.2  joerg       });
    357  1.1.1.2  joerg }
    358  1.1.1.2  joerg 
    359  1.1.1.2  joerg bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
    360  1.1.1.2  joerg                                     ConstraintSatisfaction &Satisfaction,
    361  1.1.1.2  joerg                                     SourceLocation UsageLoc) {
    362  1.1.1.2  joerg   const Expr *RC = FD->getTrailingRequiresClause();
    363  1.1.1.2  joerg   if (RC->isInstantiationDependent()) {
    364  1.1.1.2  joerg     Satisfaction.IsSatisfied = true;
    365  1.1.1.2  joerg     return false;
    366  1.1.1.2  joerg   }
    367  1.1.1.2  joerg   Qualifiers ThisQuals;
    368  1.1.1.2  joerg   CXXRecordDecl *Record = nullptr;
    369  1.1.1.2  joerg   if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
    370  1.1.1.2  joerg     ThisQuals = Method->getMethodQualifiers();
    371  1.1.1.2  joerg     Record = const_cast<CXXRecordDecl *>(Method->getParent());
    372  1.1.1.2  joerg   }
    373  1.1.1.2  joerg   CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
    374  1.1.1.2  joerg   // We substitute with empty arguments in order to rebuild the atomic
    375  1.1.1.2  joerg   // constraint in a constant-evaluated context.
    376  1.1.1.2  joerg   // FIXME: Should this be a dedicated TreeTransform?
    377  1.1.1.2  joerg   return CheckConstraintSatisfaction(
    378  1.1.1.2  joerg       FD, {RC}, /*TemplateArgs=*/{},
    379  1.1.1.2  joerg       SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
    380  1.1.1.2  joerg       Satisfaction);
    381  1.1.1.2  joerg }
    382  1.1.1.2  joerg 
    383  1.1.1.2  joerg bool Sema::EnsureTemplateArgumentListConstraints(
    384  1.1.1.2  joerg     TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
    385  1.1.1.2  joerg     SourceRange TemplateIDRange) {
    386  1.1.1.2  joerg   ConstraintSatisfaction Satisfaction;
    387  1.1.1.2  joerg   llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
    388  1.1.1.2  joerg   TD->getAssociatedConstraints(AssociatedConstraints);
    389  1.1.1.2  joerg   if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs,
    390  1.1.1.2  joerg                                   TemplateIDRange, Satisfaction))
    391  1.1.1.2  joerg     return true;
    392  1.1.1.2  joerg 
    393  1.1.1.2  joerg   if (!Satisfaction.IsSatisfied) {
    394  1.1.1.2  joerg     SmallString<128> TemplateArgString;
    395  1.1.1.2  joerg     TemplateArgString = " ";
    396  1.1.1.2  joerg     TemplateArgString += getTemplateArgumentBindingsText(
    397  1.1.1.2  joerg         TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size());
    398      1.1  joerg 
    399  1.1.1.2  joerg     Diag(TemplateIDRange.getBegin(),
    400  1.1.1.2  joerg          diag::err_template_arg_list_constraints_not_satisfied)
    401  1.1.1.2  joerg         << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD
    402  1.1.1.2  joerg         << TemplateArgString << TemplateIDRange;
    403  1.1.1.2  joerg     DiagnoseUnsatisfiedConstraint(Satisfaction);
    404  1.1.1.2  joerg     return true;
    405  1.1.1.2  joerg   }
    406      1.1  joerg   return false;
    407  1.1.1.2  joerg }
    408  1.1.1.2  joerg 
    409  1.1.1.2  joerg static void diagnoseUnsatisfiedRequirement(Sema &S,
    410  1.1.1.2  joerg                                            concepts::ExprRequirement *Req,
    411  1.1.1.2  joerg                                            bool First) {
    412  1.1.1.2  joerg   assert(!Req->isSatisfied()
    413  1.1.1.2  joerg          && "Diagnose() can only be used on an unsatisfied requirement");
    414  1.1.1.2  joerg   switch (Req->getSatisfactionStatus()) {
    415  1.1.1.2  joerg     case concepts::ExprRequirement::SS_Dependent:
    416  1.1.1.2  joerg       llvm_unreachable("Diagnosing a dependent requirement");
    417  1.1.1.2  joerg       break;
    418  1.1.1.2  joerg     case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
    419  1.1.1.2  joerg       auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
    420  1.1.1.2  joerg       if (!SubstDiag->DiagMessage.empty())
    421  1.1.1.2  joerg         S.Diag(SubstDiag->DiagLoc,
    422  1.1.1.2  joerg                diag::note_expr_requirement_expr_substitution_error)
    423  1.1.1.2  joerg                << (int)First << SubstDiag->SubstitutedEntity
    424  1.1.1.2  joerg                << SubstDiag->DiagMessage;
    425  1.1.1.2  joerg       else
    426  1.1.1.2  joerg         S.Diag(SubstDiag->DiagLoc,
    427  1.1.1.2  joerg                diag::note_expr_requirement_expr_unknown_substitution_error)
    428  1.1.1.2  joerg             << (int)First << SubstDiag->SubstitutedEntity;
    429  1.1.1.2  joerg       break;
    430  1.1.1.2  joerg     }
    431  1.1.1.2  joerg     case concepts::ExprRequirement::SS_NoexceptNotMet:
    432  1.1.1.2  joerg       S.Diag(Req->getNoexceptLoc(),
    433  1.1.1.2  joerg              diag::note_expr_requirement_noexcept_not_met)
    434  1.1.1.2  joerg           << (int)First << Req->getExpr();
    435  1.1.1.2  joerg       break;
    436  1.1.1.2  joerg     case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
    437  1.1.1.2  joerg       auto *SubstDiag =
    438  1.1.1.2  joerg           Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
    439  1.1.1.2  joerg       if (!SubstDiag->DiagMessage.empty())
    440  1.1.1.2  joerg         S.Diag(SubstDiag->DiagLoc,
    441  1.1.1.2  joerg                diag::note_expr_requirement_type_requirement_substitution_error)
    442  1.1.1.2  joerg             << (int)First << SubstDiag->SubstitutedEntity
    443  1.1.1.2  joerg             << SubstDiag->DiagMessage;
    444  1.1.1.2  joerg       else
    445  1.1.1.2  joerg         S.Diag(SubstDiag->DiagLoc,
    446  1.1.1.2  joerg                diag::note_expr_requirement_type_requirement_unknown_substitution_error)
    447  1.1.1.2  joerg             << (int)First << SubstDiag->SubstitutedEntity;
    448  1.1.1.2  joerg       break;
    449  1.1.1.2  joerg     }
    450  1.1.1.2  joerg     case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
    451  1.1.1.2  joerg       ConceptSpecializationExpr *ConstraintExpr =
    452  1.1.1.2  joerg           Req->getReturnTypeRequirementSubstitutedConstraintExpr();
    453  1.1.1.2  joerg       if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
    454  1.1.1.2  joerg         // A simple case - expr type is the type being constrained and the concept
    455  1.1.1.2  joerg         // was not provided arguments.
    456  1.1.1.2  joerg         Expr *e = Req->getExpr();
    457  1.1.1.2  joerg         S.Diag(e->getBeginLoc(),
    458  1.1.1.2  joerg                diag::note_expr_requirement_constraints_not_satisfied_simple)
    459  1.1.1.2  joerg             << (int)First << S.getDecltypeForParenthesizedExpr(e)
    460  1.1.1.2  joerg             << ConstraintExpr->getNamedConcept();
    461  1.1.1.2  joerg       } else {
    462  1.1.1.2  joerg         S.Diag(ConstraintExpr->getBeginLoc(),
    463  1.1.1.2  joerg                diag::note_expr_requirement_constraints_not_satisfied)
    464  1.1.1.2  joerg             << (int)First << ConstraintExpr;
    465  1.1.1.2  joerg       }
    466  1.1.1.2  joerg       S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
    467  1.1.1.2  joerg       break;
    468  1.1.1.2  joerg     }
    469  1.1.1.2  joerg     case concepts::ExprRequirement::SS_Satisfied:
    470  1.1.1.2  joerg       llvm_unreachable("We checked this above");
    471  1.1.1.2  joerg   }
    472  1.1.1.2  joerg }
    473  1.1.1.2  joerg 
    474  1.1.1.2  joerg static void diagnoseUnsatisfiedRequirement(Sema &S,
    475  1.1.1.2  joerg                                            concepts::TypeRequirement *Req,
    476  1.1.1.2  joerg                                            bool First) {
    477  1.1.1.2  joerg   assert(!Req->isSatisfied()
    478  1.1.1.2  joerg          && "Diagnose() can only be used on an unsatisfied requirement");
    479  1.1.1.2  joerg   switch (Req->getSatisfactionStatus()) {
    480  1.1.1.2  joerg   case concepts::TypeRequirement::SS_Dependent:
    481  1.1.1.2  joerg     llvm_unreachable("Diagnosing a dependent requirement");
    482  1.1.1.2  joerg     return;
    483  1.1.1.2  joerg   case concepts::TypeRequirement::SS_SubstitutionFailure: {
    484  1.1.1.2  joerg     auto *SubstDiag = Req->getSubstitutionDiagnostic();
    485  1.1.1.2  joerg     if (!SubstDiag->DiagMessage.empty())
    486  1.1.1.2  joerg       S.Diag(SubstDiag->DiagLoc,
    487  1.1.1.2  joerg              diag::note_type_requirement_substitution_error) << (int)First
    488  1.1.1.2  joerg           << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
    489  1.1.1.2  joerg     else
    490  1.1.1.2  joerg       S.Diag(SubstDiag->DiagLoc,
    491  1.1.1.2  joerg              diag::note_type_requirement_unknown_substitution_error)
    492  1.1.1.2  joerg           << (int)First << SubstDiag->SubstitutedEntity;
    493  1.1.1.2  joerg     return;
    494  1.1.1.2  joerg   }
    495  1.1.1.2  joerg   default:
    496  1.1.1.2  joerg     llvm_unreachable("Unknown satisfaction status");
    497  1.1.1.2  joerg     return;
    498  1.1.1.2  joerg   }
    499  1.1.1.2  joerg }
    500  1.1.1.2  joerg 
    501  1.1.1.2  joerg static void diagnoseUnsatisfiedRequirement(Sema &S,
    502  1.1.1.2  joerg                                            concepts::NestedRequirement *Req,
    503  1.1.1.2  joerg                                            bool First) {
    504  1.1.1.2  joerg   if (Req->isSubstitutionFailure()) {
    505  1.1.1.2  joerg     concepts::Requirement::SubstitutionDiagnostic *SubstDiag =
    506  1.1.1.2  joerg         Req->getSubstitutionDiagnostic();
    507  1.1.1.2  joerg     if (!SubstDiag->DiagMessage.empty())
    508  1.1.1.2  joerg       S.Diag(SubstDiag->DiagLoc,
    509  1.1.1.2  joerg              diag::note_nested_requirement_substitution_error)
    510  1.1.1.2  joerg              << (int)First << SubstDiag->SubstitutedEntity
    511  1.1.1.2  joerg              << SubstDiag->DiagMessage;
    512  1.1.1.2  joerg     else
    513  1.1.1.2  joerg       S.Diag(SubstDiag->DiagLoc,
    514  1.1.1.2  joerg              diag::note_nested_requirement_unknown_substitution_error)
    515  1.1.1.2  joerg           << (int)First << SubstDiag->SubstitutedEntity;
    516  1.1.1.2  joerg     return;
    517  1.1.1.2  joerg   }
    518  1.1.1.2  joerg   S.DiagnoseUnsatisfiedConstraint(Req->getConstraintSatisfaction(), First);
    519  1.1.1.2  joerg }
    520  1.1.1.2  joerg 
    521  1.1.1.2  joerg 
    522  1.1.1.2  joerg static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
    523  1.1.1.2  joerg                                                         Expr *SubstExpr,
    524  1.1.1.2  joerg                                                         bool First = true) {
    525  1.1.1.2  joerg   SubstExpr = SubstExpr->IgnoreParenImpCasts();
    526  1.1.1.2  joerg   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
    527  1.1.1.2  joerg     switch (BO->getOpcode()) {
    528  1.1.1.2  joerg     // These two cases will in practice only be reached when using fold
    529  1.1.1.2  joerg     // expressions with || and &&, since otherwise the || and && will have been
    530  1.1.1.2  joerg     // broken down into atomic constraints during satisfaction checking.
    531  1.1.1.2  joerg     case BO_LOr:
    532  1.1.1.2  joerg       // Or evaluated to false - meaning both RHS and LHS evaluated to false.
    533  1.1.1.2  joerg       diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
    534  1.1.1.2  joerg       diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
    535  1.1.1.2  joerg                                                   /*First=*/false);
    536  1.1.1.2  joerg       return;
    537  1.1.1.2  joerg     case BO_LAnd: {
    538  1.1.1.2  joerg       bool LHSSatisfied =
    539  1.1.1.2  joerg           BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
    540  1.1.1.2  joerg       if (LHSSatisfied) {
    541  1.1.1.2  joerg         // LHS is true, so RHS must be false.
    542  1.1.1.2  joerg         diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First);
    543  1.1.1.2  joerg         return;
    544  1.1.1.2  joerg       }
    545  1.1.1.2  joerg       // LHS is false
    546  1.1.1.2  joerg       diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
    547  1.1.1.2  joerg 
    548  1.1.1.2  joerg       // RHS might also be false
    549  1.1.1.2  joerg       bool RHSSatisfied =
    550  1.1.1.2  joerg           BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
    551  1.1.1.2  joerg       if (!RHSSatisfied)
    552  1.1.1.2  joerg         diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
    553  1.1.1.2  joerg                                                     /*First=*/false);
    554  1.1.1.2  joerg       return;
    555  1.1.1.2  joerg     }
    556  1.1.1.2  joerg     case BO_GE:
    557  1.1.1.2  joerg     case BO_LE:
    558  1.1.1.2  joerg     case BO_GT:
    559  1.1.1.2  joerg     case BO_LT:
    560  1.1.1.2  joerg     case BO_EQ:
    561  1.1.1.2  joerg     case BO_NE:
    562  1.1.1.2  joerg       if (BO->getLHS()->getType()->isIntegerType() &&
    563  1.1.1.2  joerg           BO->getRHS()->getType()->isIntegerType()) {
    564  1.1.1.2  joerg         Expr::EvalResult SimplifiedLHS;
    565  1.1.1.2  joerg         Expr::EvalResult SimplifiedRHS;
    566  1.1.1.2  joerg         BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
    567  1.1.1.2  joerg                                     Expr::SE_NoSideEffects,
    568  1.1.1.2  joerg                                     /*InConstantContext=*/true);
    569  1.1.1.2  joerg         BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
    570  1.1.1.2  joerg                                     Expr::SE_NoSideEffects,
    571  1.1.1.2  joerg                                     /*InConstantContext=*/true);
    572  1.1.1.2  joerg         if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
    573  1.1.1.2  joerg           S.Diag(SubstExpr->getBeginLoc(),
    574  1.1.1.2  joerg                  diag::note_atomic_constraint_evaluated_to_false_elaborated)
    575  1.1.1.2  joerg               << (int)First << SubstExpr
    576  1.1.1.2  joerg               << SimplifiedLHS.Val.getInt().toString(10)
    577  1.1.1.2  joerg               << BinaryOperator::getOpcodeStr(BO->getOpcode())
    578  1.1.1.2  joerg               << SimplifiedRHS.Val.getInt().toString(10);
    579  1.1.1.2  joerg           return;
    580  1.1.1.2  joerg         }
    581  1.1.1.2  joerg       }
    582  1.1.1.2  joerg       break;
    583  1.1.1.2  joerg 
    584  1.1.1.2  joerg     default:
    585  1.1.1.2  joerg       break;
    586  1.1.1.2  joerg     }
    587  1.1.1.2  joerg   } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
    588  1.1.1.2  joerg     if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
    589  1.1.1.2  joerg       S.Diag(
    590  1.1.1.2  joerg           CSE->getSourceRange().getBegin(),
    591  1.1.1.2  joerg           diag::
    592  1.1.1.2  joerg           note_single_arg_concept_specialization_constraint_evaluated_to_false)
    593  1.1.1.2  joerg           << (int)First
    594  1.1.1.2  joerg           << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
    595  1.1.1.2  joerg           << CSE->getNamedConcept();
    596  1.1.1.2  joerg     } else {
    597  1.1.1.2  joerg       S.Diag(SubstExpr->getSourceRange().getBegin(),
    598  1.1.1.2  joerg              diag::note_concept_specialization_constraint_evaluated_to_false)
    599  1.1.1.2  joerg           << (int)First << CSE;
    600  1.1.1.2  joerg     }
    601  1.1.1.2  joerg     S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
    602  1.1.1.2  joerg     return;
    603  1.1.1.2  joerg   } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
    604  1.1.1.2  joerg     for (concepts::Requirement *Req : RE->getRequirements())
    605  1.1.1.2  joerg       if (!Req->isDependent() && !Req->isSatisfied()) {
    606  1.1.1.2  joerg         if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
    607  1.1.1.2  joerg           diagnoseUnsatisfiedRequirement(S, E, First);
    608  1.1.1.2  joerg         else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
    609  1.1.1.2  joerg           diagnoseUnsatisfiedRequirement(S, T, First);
    610  1.1.1.2  joerg         else
    611  1.1.1.2  joerg           diagnoseUnsatisfiedRequirement(
    612  1.1.1.2  joerg               S, cast<concepts::NestedRequirement>(Req), First);
    613  1.1.1.2  joerg         break;
    614  1.1.1.2  joerg       }
    615  1.1.1.2  joerg     return;
    616  1.1.1.2  joerg   }
    617  1.1.1.2  joerg 
    618  1.1.1.2  joerg   S.Diag(SubstExpr->getSourceRange().getBegin(),
    619  1.1.1.2  joerg          diag::note_atomic_constraint_evaluated_to_false)
    620  1.1.1.2  joerg       << (int)First << SubstExpr;
    621  1.1.1.2  joerg }
    622  1.1.1.2  joerg 
    623  1.1.1.2  joerg template<typename SubstitutionDiagnostic>
    624  1.1.1.2  joerg static void diagnoseUnsatisfiedConstraintExpr(
    625  1.1.1.2  joerg     Sema &S, const Expr *E,
    626  1.1.1.2  joerg     const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
    627  1.1.1.2  joerg     bool First = true) {
    628  1.1.1.2  joerg   if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
    629  1.1.1.2  joerg     S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
    630  1.1.1.2  joerg         << Diag->second;
    631  1.1.1.2  joerg     return;
    632  1.1.1.2  joerg   }
    633  1.1.1.2  joerg 
    634  1.1.1.2  joerg   diagnoseWellFormedUnsatisfiedConstraintExpr(S,
    635  1.1.1.2  joerg       Record.template get<Expr *>(), First);
    636  1.1.1.2  joerg }
    637  1.1.1.2  joerg 
    638  1.1.1.2  joerg void
    639  1.1.1.2  joerg Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
    640  1.1.1.2  joerg                                     bool First) {
    641  1.1.1.2  joerg   assert(!Satisfaction.IsSatisfied &&
    642  1.1.1.2  joerg          "Attempted to diagnose a satisfied constraint");
    643  1.1.1.2  joerg   for (auto &Pair : Satisfaction.Details) {
    644  1.1.1.2  joerg     diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
    645  1.1.1.2  joerg     First = false;
    646  1.1.1.2  joerg   }
    647  1.1.1.2  joerg }
    648  1.1.1.2  joerg 
    649  1.1.1.2  joerg void Sema::DiagnoseUnsatisfiedConstraint(
    650  1.1.1.2  joerg     const ASTConstraintSatisfaction &Satisfaction,
    651  1.1.1.2  joerg     bool First) {
    652  1.1.1.2  joerg   assert(!Satisfaction.IsSatisfied &&
    653  1.1.1.2  joerg          "Attempted to diagnose a satisfied constraint");
    654  1.1.1.2  joerg   for (auto &Pair : Satisfaction) {
    655  1.1.1.2  joerg     diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
    656  1.1.1.2  joerg     First = false;
    657  1.1.1.2  joerg   }
    658  1.1.1.2  joerg }
    659  1.1.1.2  joerg 
    660  1.1.1.2  joerg const NormalizedConstraint *
    661  1.1.1.2  joerg Sema::getNormalizedAssociatedConstraints(
    662  1.1.1.2  joerg     NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
    663  1.1.1.2  joerg   auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
    664  1.1.1.2  joerg   if (CacheEntry == NormalizationCache.end()) {
    665  1.1.1.2  joerg     auto Normalized =
    666  1.1.1.2  joerg         NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
    667  1.1.1.2  joerg                                                   AssociatedConstraints);
    668  1.1.1.2  joerg     CacheEntry =
    669  1.1.1.2  joerg         NormalizationCache
    670  1.1.1.2  joerg             .try_emplace(ConstrainedDecl,
    671  1.1.1.2  joerg                          Normalized
    672  1.1.1.2  joerg                              ? new (Context) NormalizedConstraint(
    673  1.1.1.2  joerg                                  std::move(*Normalized))
    674  1.1.1.2  joerg                              : nullptr)
    675  1.1.1.2  joerg             .first;
    676  1.1.1.2  joerg   }
    677  1.1.1.2  joerg   return CacheEntry->second;
    678  1.1.1.2  joerg }
    679  1.1.1.2  joerg 
    680  1.1.1.2  joerg static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
    681  1.1.1.2  joerg     ConceptDecl *Concept, ArrayRef<TemplateArgument> TemplateArgs,
    682  1.1.1.2  joerg     const ASTTemplateArgumentListInfo *ArgsAsWritten) {
    683  1.1.1.2  joerg   if (!N.isAtomic()) {
    684  1.1.1.2  joerg     if (substituteParameterMappings(S, N.getLHS(), Concept, TemplateArgs,
    685  1.1.1.2  joerg                                     ArgsAsWritten))
    686  1.1.1.2  joerg       return true;
    687  1.1.1.2  joerg     return substituteParameterMappings(S, N.getRHS(), Concept, TemplateArgs,
    688  1.1.1.2  joerg                                        ArgsAsWritten);
    689  1.1.1.2  joerg   }
    690  1.1.1.2  joerg   TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
    691  1.1.1.2  joerg 
    692  1.1.1.2  joerg   AtomicConstraint &Atomic = *N.getAtomicConstraint();
    693  1.1.1.2  joerg   TemplateArgumentListInfo SubstArgs;
    694  1.1.1.2  joerg   MultiLevelTemplateArgumentList MLTAL;
    695  1.1.1.2  joerg   MLTAL.addOuterTemplateArguments(TemplateArgs);
    696  1.1.1.2  joerg   if (!Atomic.ParameterMapping) {
    697  1.1.1.2  joerg     llvm::SmallBitVector OccurringIndices(TemplateParams->size());
    698  1.1.1.2  joerg     S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
    699  1.1.1.2  joerg                                  /*Depth=*/0, OccurringIndices);
    700  1.1.1.2  joerg     Atomic.ParameterMapping.emplace(
    701  1.1.1.2  joerg         MutableArrayRef<TemplateArgumentLoc>(
    702  1.1.1.2  joerg             new (S.Context) TemplateArgumentLoc[OccurringIndices.count()],
    703  1.1.1.2  joerg             OccurringIndices.count()));
    704  1.1.1.2  joerg     for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
    705  1.1.1.2  joerg       if (OccurringIndices[I])
    706  1.1.1.2  joerg         new (&(*Atomic.ParameterMapping)[J++]) TemplateArgumentLoc(
    707  1.1.1.2  joerg             S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I],
    708  1.1.1.2  joerg                 // Here we assume we do not support things like
    709  1.1.1.2  joerg                 // template<typename A, typename B>
    710  1.1.1.2  joerg                 // concept C = ...;
    711  1.1.1.2  joerg                 //
    712  1.1.1.2  joerg                 // template<typename... Ts> requires C<Ts...>
    713  1.1.1.2  joerg                 // struct S { };
    714  1.1.1.2  joerg                 // The above currently yields a diagnostic.
    715  1.1.1.2  joerg                 // We still might have default arguments for concept parameters.
    716  1.1.1.2  joerg                 ArgsAsWritten->NumTemplateArgs > I ?
    717  1.1.1.2  joerg                 ArgsAsWritten->arguments()[I].getLocation() :
    718  1.1.1.2  joerg                 SourceLocation()));
    719  1.1.1.2  joerg   }
    720  1.1.1.2  joerg   Sema::InstantiatingTemplate Inst(
    721  1.1.1.2  joerg       S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
    722  1.1.1.2  joerg       Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
    723  1.1.1.2  joerg       SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(),
    724  1.1.1.2  joerg                   ArgsAsWritten->arguments().back().getSourceRange().getEnd()));
    725  1.1.1.2  joerg   if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
    726  1.1.1.2  joerg     return true;
    727  1.1.1.2  joerg   Atomic.ParameterMapping.emplace(
    728  1.1.1.2  joerg         MutableArrayRef<TemplateArgumentLoc>(
    729  1.1.1.2  joerg             new (S.Context) TemplateArgumentLoc[SubstArgs.size()],
    730  1.1.1.2  joerg             SubstArgs.size()));
    731  1.1.1.2  joerg   std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
    732  1.1.1.2  joerg             N.getAtomicConstraint()->ParameterMapping->begin());
    733  1.1.1.2  joerg   return false;
    734  1.1.1.2  joerg }
    735  1.1.1.2  joerg 
    736  1.1.1.2  joerg Optional<NormalizedConstraint>
    737  1.1.1.2  joerg NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
    738  1.1.1.2  joerg                                           ArrayRef<const Expr *> E) {
    739  1.1.1.2  joerg   assert(E.size() != 0);
    740  1.1.1.2  joerg   auto First = fromConstraintExpr(S, D, E[0]);
    741  1.1.1.2  joerg   if (E.size() == 1)
    742  1.1.1.2  joerg     return First;
    743  1.1.1.2  joerg   auto Second = fromConstraintExpr(S, D, E[1]);
    744  1.1.1.2  joerg   if (!Second)
    745  1.1.1.2  joerg     return None;
    746  1.1.1.2  joerg   llvm::Optional<NormalizedConstraint> Conjunction;
    747  1.1.1.2  joerg   Conjunction.emplace(S.Context, std::move(*First), std::move(*Second),
    748  1.1.1.2  joerg                       CCK_Conjunction);
    749  1.1.1.2  joerg   for (unsigned I = 2; I < E.size(); ++I) {
    750  1.1.1.2  joerg     auto Next = fromConstraintExpr(S, D, E[I]);
    751  1.1.1.2  joerg     if (!Next)
    752  1.1.1.2  joerg       return llvm::Optional<NormalizedConstraint>{};
    753  1.1.1.2  joerg     NormalizedConstraint NewConjunction(S.Context, std::move(*Conjunction),
    754  1.1.1.2  joerg                                         std::move(*Next), CCK_Conjunction);
    755  1.1.1.2  joerg     *Conjunction = std::move(NewConjunction);
    756  1.1.1.2  joerg   }
    757  1.1.1.2  joerg   return Conjunction;
    758  1.1.1.2  joerg }
    759  1.1.1.2  joerg 
    760  1.1.1.2  joerg llvm::Optional<NormalizedConstraint>
    761  1.1.1.2  joerg NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
    762  1.1.1.2  joerg   assert(E != nullptr);
    763  1.1.1.2  joerg 
    764  1.1.1.2  joerg   // C++ [temp.constr.normal]p1.1
    765  1.1.1.2  joerg   // [...]
    766  1.1.1.2  joerg   // - The normal form of an expression (E) is the normal form of E.
    767  1.1.1.2  joerg   // [...]
    768  1.1.1.2  joerg   E = E->IgnoreParenImpCasts();
    769  1.1.1.2  joerg   if (LogicalBinOp BO = E) {
    770  1.1.1.2  joerg     auto LHS = fromConstraintExpr(S, D, BO.getLHS());
    771  1.1.1.2  joerg     if (!LHS)
    772  1.1.1.2  joerg       return None;
    773  1.1.1.2  joerg     auto RHS = fromConstraintExpr(S, D, BO.getRHS());
    774  1.1.1.2  joerg     if (!RHS)
    775  1.1.1.2  joerg       return None;
    776  1.1.1.2  joerg 
    777  1.1.1.2  joerg     return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
    778  1.1.1.2  joerg                                 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
    779  1.1.1.2  joerg   } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
    780  1.1.1.2  joerg     const NormalizedConstraint *SubNF;
    781  1.1.1.2  joerg     {
    782  1.1.1.2  joerg       Sema::InstantiatingTemplate Inst(
    783  1.1.1.2  joerg           S, CSE->getExprLoc(),
    784  1.1.1.2  joerg           Sema::InstantiatingTemplate::ConstraintNormalization{}, D,
    785  1.1.1.2  joerg           CSE->getSourceRange());
    786  1.1.1.2  joerg       // C++ [temp.constr.normal]p1.1
    787  1.1.1.2  joerg       // [...]
    788  1.1.1.2  joerg       // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
    789  1.1.1.2  joerg       // where C names a concept, is the normal form of the
    790  1.1.1.2  joerg       // constraint-expression of C, after substituting A1, A2, ..., AN for Cs
    791  1.1.1.2  joerg       // respective template parameters in the parameter mappings in each atomic
    792  1.1.1.2  joerg       // constraint. If any such substitution results in an invalid type or
    793  1.1.1.2  joerg       // expression, the program is ill-formed; no diagnostic is required.
    794  1.1.1.2  joerg       // [...]
    795  1.1.1.2  joerg       ConceptDecl *CD = CSE->getNamedConcept();
    796  1.1.1.2  joerg       SubNF = S.getNormalizedAssociatedConstraints(CD,
    797  1.1.1.2  joerg                                                    {CD->getConstraintExpr()});
    798  1.1.1.2  joerg       if (!SubNF)
    799  1.1.1.2  joerg         return None;
    800  1.1.1.2  joerg     }
    801  1.1.1.2  joerg 
    802  1.1.1.2  joerg     Optional<NormalizedConstraint> New;
    803  1.1.1.2  joerg     New.emplace(S.Context, *SubNF);
    804  1.1.1.2  joerg 
    805  1.1.1.2  joerg     if (substituteParameterMappings(
    806  1.1.1.2  joerg             S, *New, CSE->getNamedConcept(),
    807  1.1.1.2  joerg             CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten()))
    808  1.1.1.2  joerg       return None;
    809  1.1.1.2  joerg 
    810  1.1.1.2  joerg     return New;
    811  1.1.1.2  joerg   }
    812  1.1.1.2  joerg   return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
    813  1.1.1.2  joerg }
    814  1.1.1.2  joerg 
    815  1.1.1.2  joerg using NormalForm =
    816  1.1.1.2  joerg     llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>;
    817  1.1.1.2  joerg 
    818  1.1.1.2  joerg static NormalForm makeCNF(const NormalizedConstraint &Normalized) {
    819  1.1.1.2  joerg   if (Normalized.isAtomic())
    820  1.1.1.2  joerg     return {{Normalized.getAtomicConstraint()}};
    821  1.1.1.2  joerg 
    822  1.1.1.2  joerg   NormalForm LCNF = makeCNF(Normalized.getLHS());
    823  1.1.1.2  joerg   NormalForm RCNF = makeCNF(Normalized.getRHS());
    824  1.1.1.2  joerg   if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) {
    825  1.1.1.2  joerg     LCNF.reserve(LCNF.size() + RCNF.size());
    826  1.1.1.2  joerg     while (!RCNF.empty())
    827  1.1.1.2  joerg       LCNF.push_back(RCNF.pop_back_val());
    828  1.1.1.2  joerg     return LCNF;
    829  1.1.1.2  joerg   }
    830  1.1.1.2  joerg 
    831  1.1.1.2  joerg   // Disjunction
    832  1.1.1.2  joerg   NormalForm Res;
    833  1.1.1.2  joerg   Res.reserve(LCNF.size() * RCNF.size());
    834  1.1.1.2  joerg   for (auto &LDisjunction : LCNF)
    835  1.1.1.2  joerg     for (auto &RDisjunction : RCNF) {
    836  1.1.1.2  joerg       NormalForm::value_type Combined;
    837  1.1.1.2  joerg       Combined.reserve(LDisjunction.size() + RDisjunction.size());
    838  1.1.1.2  joerg       std::copy(LDisjunction.begin(), LDisjunction.end(),
    839  1.1.1.2  joerg                 std::back_inserter(Combined));
    840  1.1.1.2  joerg       std::copy(RDisjunction.begin(), RDisjunction.end(),
    841  1.1.1.2  joerg                 std::back_inserter(Combined));
    842  1.1.1.2  joerg       Res.emplace_back(Combined);
    843  1.1.1.2  joerg     }
    844  1.1.1.2  joerg   return Res;
    845  1.1.1.2  joerg }
    846  1.1.1.2  joerg 
    847  1.1.1.2  joerg static NormalForm makeDNF(const NormalizedConstraint &Normalized) {
    848  1.1.1.2  joerg   if (Normalized.isAtomic())
    849  1.1.1.2  joerg     return {{Normalized.getAtomicConstraint()}};
    850  1.1.1.2  joerg 
    851  1.1.1.2  joerg   NormalForm LDNF = makeDNF(Normalized.getLHS());
    852  1.1.1.2  joerg   NormalForm RDNF = makeDNF(Normalized.getRHS());
    853  1.1.1.2  joerg   if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) {
    854  1.1.1.2  joerg     LDNF.reserve(LDNF.size() + RDNF.size());
    855  1.1.1.2  joerg     while (!RDNF.empty())
    856  1.1.1.2  joerg       LDNF.push_back(RDNF.pop_back_val());
    857  1.1.1.2  joerg     return LDNF;
    858  1.1.1.2  joerg   }
    859  1.1.1.2  joerg 
    860  1.1.1.2  joerg   // Conjunction
    861  1.1.1.2  joerg   NormalForm Res;
    862  1.1.1.2  joerg   Res.reserve(LDNF.size() * RDNF.size());
    863  1.1.1.2  joerg   for (auto &LConjunction : LDNF) {
    864  1.1.1.2  joerg     for (auto &RConjunction : RDNF) {
    865  1.1.1.2  joerg       NormalForm::value_type Combined;
    866  1.1.1.2  joerg       Combined.reserve(LConjunction.size() + RConjunction.size());
    867  1.1.1.2  joerg       std::copy(LConjunction.begin(), LConjunction.end(),
    868  1.1.1.2  joerg                 std::back_inserter(Combined));
    869  1.1.1.2  joerg       std::copy(RConjunction.begin(), RConjunction.end(),
    870  1.1.1.2  joerg                 std::back_inserter(Combined));
    871  1.1.1.2  joerg       Res.emplace_back(Combined);
    872  1.1.1.2  joerg     }
    873  1.1.1.2  joerg   }
    874  1.1.1.2  joerg   return Res;
    875  1.1.1.2  joerg }
    876  1.1.1.2  joerg 
    877  1.1.1.2  joerg template<typename AtomicSubsumptionEvaluator>
    878  1.1.1.2  joerg static bool subsumes(NormalForm PDNF, NormalForm QCNF,
    879  1.1.1.2  joerg                      AtomicSubsumptionEvaluator E) {
    880  1.1.1.2  joerg   // C++ [temp.constr.order] p2
    881  1.1.1.2  joerg   //   Then, P subsumes Q if and only if, for every disjunctive clause Pi in the
    882  1.1.1.2  joerg   //   disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in
    883  1.1.1.2  joerg   //   the conjuctive normal form of Q, where [...]
    884  1.1.1.2  joerg   for (const auto &Pi : PDNF) {
    885  1.1.1.2  joerg     for (const auto &Qj : QCNF) {
    886  1.1.1.2  joerg       // C++ [temp.constr.order] p2
    887  1.1.1.2  joerg       //   - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if
    888  1.1.1.2  joerg       //     and only if there exists an atomic constraint Pia in Pi for which
    889  1.1.1.2  joerg       //     there exists an atomic constraint, Qjb, in Qj such that Pia
    890  1.1.1.2  joerg       //     subsumes Qjb.
    891  1.1.1.2  joerg       bool Found = false;
    892  1.1.1.2  joerg       for (const AtomicConstraint *Pia : Pi) {
    893  1.1.1.2  joerg         for (const AtomicConstraint *Qjb : Qj) {
    894  1.1.1.2  joerg           if (E(*Pia, *Qjb)) {
    895  1.1.1.2  joerg             Found = true;
    896  1.1.1.2  joerg             break;
    897  1.1.1.2  joerg           }
    898  1.1.1.2  joerg         }
    899  1.1.1.2  joerg         if (Found)
    900  1.1.1.2  joerg           break;
    901  1.1.1.2  joerg       }
    902  1.1.1.2  joerg       if (!Found)
    903  1.1.1.2  joerg         return false;
    904  1.1.1.2  joerg     }
    905  1.1.1.2  joerg   }
    906  1.1.1.2  joerg   return true;
    907  1.1.1.2  joerg }
    908  1.1.1.2  joerg 
    909  1.1.1.2  joerg template<typename AtomicSubsumptionEvaluator>
    910  1.1.1.2  joerg static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P,
    911  1.1.1.2  joerg                      NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes,
    912  1.1.1.2  joerg                      AtomicSubsumptionEvaluator E) {
    913  1.1.1.2  joerg   // C++ [temp.constr.order] p2
    914  1.1.1.2  joerg   //   In order to determine if a constraint P subsumes a constraint Q, P is
    915  1.1.1.2  joerg   //   transformed into disjunctive normal form, and Q is transformed into
    916  1.1.1.2  joerg   //   conjunctive normal form. [...]
    917  1.1.1.2  joerg   auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P);
    918  1.1.1.2  joerg   if (!PNormalized)
    919  1.1.1.2  joerg     return true;
    920  1.1.1.2  joerg   const NormalForm PDNF = makeDNF(*PNormalized);
    921  1.1.1.2  joerg 
    922  1.1.1.2  joerg   auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q);
    923  1.1.1.2  joerg   if (!QNormalized)
    924  1.1.1.2  joerg     return true;
    925  1.1.1.2  joerg   const NormalForm QCNF = makeCNF(*QNormalized);
    926  1.1.1.2  joerg 
    927  1.1.1.2  joerg   Subsumes = subsumes(PDNF, QCNF, E);
    928  1.1.1.2  joerg   return false;
    929  1.1.1.2  joerg }
    930  1.1.1.2  joerg 
    931  1.1.1.2  joerg bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1,
    932  1.1.1.2  joerg                                   NamedDecl *D2, ArrayRef<const Expr *> AC2,
    933  1.1.1.2  joerg                                   bool &Result) {
    934  1.1.1.2  joerg   if (AC1.empty()) {
    935  1.1.1.2  joerg     Result = AC2.empty();
    936  1.1.1.2  joerg     return false;
    937  1.1.1.2  joerg   }
    938  1.1.1.2  joerg   if (AC2.empty()) {
    939  1.1.1.2  joerg     // TD1 has associated constraints and TD2 does not.
    940  1.1.1.2  joerg     Result = true;
    941  1.1.1.2  joerg     return false;
    942  1.1.1.2  joerg   }
    943  1.1.1.2  joerg 
    944  1.1.1.2  joerg   std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
    945  1.1.1.2  joerg   auto CacheEntry = SubsumptionCache.find(Key);
    946  1.1.1.2  joerg   if (CacheEntry != SubsumptionCache.end()) {
    947  1.1.1.2  joerg     Result = CacheEntry->second;
    948  1.1.1.2  joerg     return false;
    949  1.1.1.2  joerg   }
    950  1.1.1.2  joerg 
    951  1.1.1.2  joerg   if (subsumes(*this, D1, AC1, D2, AC2, Result,
    952  1.1.1.2  joerg         [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
    953  1.1.1.2  joerg           return A.subsumes(Context, B);
    954  1.1.1.2  joerg         }))
    955  1.1.1.2  joerg     return true;
    956  1.1.1.2  joerg   SubsumptionCache.try_emplace(Key, Result);
    957  1.1.1.2  joerg   return false;
    958  1.1.1.2  joerg }
    959  1.1.1.2  joerg 
    960  1.1.1.2  joerg bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1,
    961  1.1.1.2  joerg     ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) {
    962  1.1.1.2  joerg   if (isSFINAEContext())
    963  1.1.1.2  joerg     // No need to work here because our notes would be discarded.
    964  1.1.1.2  joerg     return false;
    965  1.1.1.2  joerg 
    966  1.1.1.2  joerg   if (AC1.empty() || AC2.empty())
    967  1.1.1.2  joerg     return false;
    968  1.1.1.2  joerg 
    969  1.1.1.2  joerg   auto NormalExprEvaluator =
    970  1.1.1.2  joerg       [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
    971  1.1.1.2  joerg         return A.subsumes(Context, B);
    972  1.1.1.2  joerg       };
    973  1.1.1.2  joerg 
    974  1.1.1.2  joerg   const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
    975  1.1.1.2  joerg   auto IdenticalExprEvaluator =
    976  1.1.1.2  joerg       [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
    977  1.1.1.2  joerg         if (!A.hasMatchingParameterMapping(Context, B))
    978  1.1.1.2  joerg           return false;
    979  1.1.1.2  joerg         const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
    980  1.1.1.2  joerg         if (EA == EB)
    981  1.1.1.2  joerg           return true;
    982  1.1.1.2  joerg 
    983  1.1.1.2  joerg         // Not the same source level expression - are the expressions
    984  1.1.1.2  joerg         // identical?
    985  1.1.1.2  joerg         llvm::FoldingSetNodeID IDA, IDB;
    986  1.1.1.2  joerg         EA->Profile(IDA, Context, /*Cannonical=*/true);
    987  1.1.1.2  joerg         EB->Profile(IDB, Context, /*Cannonical=*/true);
    988  1.1.1.2  joerg         if (IDA != IDB)
    989  1.1.1.2  joerg           return false;
    990  1.1.1.2  joerg 
    991  1.1.1.2  joerg         AmbiguousAtomic1 = EA;
    992  1.1.1.2  joerg         AmbiguousAtomic2 = EB;
    993  1.1.1.2  joerg         return true;
    994  1.1.1.2  joerg       };
    995  1.1.1.2  joerg 
    996  1.1.1.2  joerg   {
    997  1.1.1.2  joerg     // The subsumption checks might cause diagnostics
    998  1.1.1.2  joerg     SFINAETrap Trap(*this);
    999  1.1.1.2  joerg     auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
   1000  1.1.1.2  joerg     if (!Normalized1)
   1001  1.1.1.2  joerg       return false;
   1002  1.1.1.2  joerg     const NormalForm DNF1 = makeDNF(*Normalized1);
   1003  1.1.1.2  joerg     const NormalForm CNF1 = makeCNF(*Normalized1);
   1004  1.1.1.2  joerg 
   1005  1.1.1.2  joerg     auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
   1006  1.1.1.2  joerg     if (!Normalized2)
   1007  1.1.1.2  joerg       return false;
   1008  1.1.1.2  joerg     const NormalForm DNF2 = makeDNF(*Normalized2);
   1009  1.1.1.2  joerg     const NormalForm CNF2 = makeCNF(*Normalized2);
   1010  1.1.1.2  joerg 
   1011  1.1.1.2  joerg     bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator);
   1012  1.1.1.2  joerg     bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator);
   1013  1.1.1.2  joerg     bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator);
   1014  1.1.1.2  joerg     bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator);
   1015  1.1.1.2  joerg     if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
   1016  1.1.1.2  joerg         Is2AtLeastAs1 == Is2AtLeastAs1Normally)
   1017  1.1.1.2  joerg       // Same result - no ambiguity was caused by identical atomic expressions.
   1018  1.1.1.2  joerg       return false;
   1019  1.1.1.2  joerg   }
   1020  1.1.1.2  joerg 
   1021  1.1.1.2  joerg   // A different result! Some ambiguous atomic constraint(s) caused a difference
   1022  1.1.1.2  joerg   assert(AmbiguousAtomic1 && AmbiguousAtomic2);
   1023  1.1.1.2  joerg 
   1024  1.1.1.2  joerg   Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
   1025  1.1.1.2  joerg       << AmbiguousAtomic1->getSourceRange();
   1026  1.1.1.2  joerg   Diag(AmbiguousAtomic2->getBeginLoc(),
   1027  1.1.1.2  joerg        diag::note_ambiguous_atomic_constraints_similar_expression)
   1028  1.1.1.2  joerg       << AmbiguousAtomic2->getSourceRange();
   1029  1.1.1.2  joerg   return true;
   1030  1.1.1.2  joerg }
   1031  1.1.1.2  joerg 
   1032  1.1.1.2  joerg concepts::ExprRequirement::ExprRequirement(
   1033  1.1.1.2  joerg     Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
   1034  1.1.1.2  joerg     ReturnTypeRequirement Req, SatisfactionStatus Status,
   1035  1.1.1.2  joerg     ConceptSpecializationExpr *SubstitutedConstraintExpr) :
   1036  1.1.1.2  joerg     Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
   1037  1.1.1.2  joerg                 Status == SS_Dependent &&
   1038  1.1.1.2  joerg                 (E->containsUnexpandedParameterPack() ||
   1039  1.1.1.2  joerg                  Req.containsUnexpandedParameterPack()),
   1040  1.1.1.2  joerg                 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
   1041  1.1.1.2  joerg     TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
   1042  1.1.1.2  joerg     Status(Status) {
   1043  1.1.1.2  joerg   assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
   1044  1.1.1.2  joerg          "Simple requirement must not have a return type requirement or a "
   1045  1.1.1.2  joerg          "noexcept specification");
   1046  1.1.1.2  joerg   assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
   1047  1.1.1.2  joerg          (SubstitutedConstraintExpr != nullptr));
   1048  1.1.1.2  joerg }
   1049  1.1.1.2  joerg 
   1050  1.1.1.2  joerg concepts::ExprRequirement::ExprRequirement(
   1051  1.1.1.2  joerg     SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
   1052  1.1.1.2  joerg     SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
   1053  1.1.1.2  joerg     Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
   1054  1.1.1.2  joerg                 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
   1055  1.1.1.2  joerg     Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
   1056  1.1.1.2  joerg     Status(SS_ExprSubstitutionFailure) {
   1057  1.1.1.2  joerg   assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
   1058  1.1.1.2  joerg          "Simple requirement must not have a return type requirement or a "
   1059  1.1.1.2  joerg          "noexcept specification");
   1060  1.1.1.2  joerg }
   1061  1.1.1.2  joerg 
   1062  1.1.1.2  joerg concepts::ExprRequirement::ReturnTypeRequirement::
   1063  1.1.1.2  joerg ReturnTypeRequirement(TemplateParameterList *TPL) :
   1064  1.1.1.2  joerg     TypeConstraintInfo(TPL, 0) {
   1065  1.1.1.2  joerg   assert(TPL->size() == 1);
   1066  1.1.1.2  joerg   const TypeConstraint *TC =
   1067  1.1.1.2  joerg       cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
   1068  1.1.1.2  joerg   assert(TC &&
   1069  1.1.1.2  joerg          "TPL must have a template type parameter with a type constraint");
   1070  1.1.1.2  joerg   auto *Constraint =
   1071  1.1.1.2  joerg       cast_or_null<ConceptSpecializationExpr>(
   1072  1.1.1.2  joerg           TC->getImmediatelyDeclaredConstraint());
   1073  1.1.1.2  joerg   bool Dependent =
   1074  1.1.1.2  joerg       Constraint->getTemplateArgsAsWritten() &&
   1075  1.1.1.2  joerg       TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
   1076  1.1.1.2  joerg           Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
   1077  1.1.1.2  joerg   TypeConstraintInfo.setInt(Dependent ? 1 : 0);
   1078  1.1.1.2  joerg }
   1079  1.1.1.2  joerg 
   1080  1.1.1.2  joerg concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) :
   1081  1.1.1.2  joerg     Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
   1082  1.1.1.2  joerg                 T->getType()->containsUnexpandedParameterPack(),
   1083  1.1.1.2  joerg                 // We reach this ctor with either dependent types (in which
   1084  1.1.1.2  joerg                 // IsSatisfied doesn't matter) or with non-dependent type in
   1085  1.1.1.2  joerg                 // which the existence of the type indicates satisfaction.
   1086  1.1.1.2  joerg                 /*IsSatisfied=*/true),
   1087  1.1.1.2  joerg     Value(T),
   1088  1.1.1.2  joerg     Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
   1089  1.1.1.2  joerg                                                         : SS_Satisfied) {}
   1090