Coverage Report

Created: 2020-03-31 06:27

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