diff options
Diffstat (limited to 'lib/Sema/SemaConcept.cpp')
-rw-r--r-- | lib/Sema/SemaConcept.cpp | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/lib/Sema/SemaConcept.cpp b/lib/Sema/SemaConcept.cpp deleted file mode 100644 index 3131609390..0000000000 --- a/lib/Sema/SemaConcept.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements semantic analysis for C++ constraints and concepts. -// -//===----------------------------------------------------------------------===// - -#include "clang/Sema/Sema.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "clang/Sema/TemplateDeduction.h" -#include "clang/Sema/Template.h" -#include "clang/AST/ExprCXX.h" -using namespace clang; -using namespace sema; - -bool Sema::CheckConstraintExpression(Expr *ConstraintExpression) { - // C++2a [temp.constr.atomic]p1 - // ..E shall be a constant expression of type bool. - - ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts(); - - if (auto *BinOp = dyn_cast<BinaryOperator>(ConstraintExpression)) { - if (BinOp->getOpcode() == BO_LAnd || BinOp->getOpcode() == BO_LOr) - return CheckConstraintExpression(BinOp->getLHS()) && - CheckConstraintExpression(BinOp->getRHS()); - } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression)) - return CheckConstraintExpression(C->getSubExpr()); - - // An atomic constraint! - if (ConstraintExpression->isTypeDependent()) - return true; - - QualType Type = ConstraintExpression->getType(); - if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) { - Diag(ConstraintExpression->getExprLoc(), - diag::err_non_bool_atomic_constraint) << Type - << ConstraintExpression->getSourceRange(); - return false; - } - return true; -} - -bool -Sema::CalculateConstraintSatisfaction(ConceptDecl *NamedConcept, - MultiLevelTemplateArgumentList &MLTAL, - Expr *ConstraintExpr, - bool &IsSatisfied) { - ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts(); - - if (auto *BO = dyn_cast<BinaryOperator>(ConstraintExpr)) { - if (BO->getOpcode() == BO_LAnd) { - if (CalculateConstraintSatisfaction(NamedConcept, MLTAL, BO->getLHS(), - IsSatisfied)) - return true; - if (!IsSatisfied) - return false; - return CalculateConstraintSatisfaction(NamedConcept, MLTAL, BO->getRHS(), - IsSatisfied); - } else if (BO->getOpcode() == BO_LOr) { - if (CalculateConstraintSatisfaction(NamedConcept, MLTAL, BO->getLHS(), - IsSatisfied)) - return true; - if (IsSatisfied) - return false; - return CalculateConstraintSatisfaction(NamedConcept, MLTAL, BO->getRHS(), - IsSatisfied); - } - } - else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) - return CalculateConstraintSatisfaction(NamedConcept, MLTAL, C->getSubExpr(), - IsSatisfied); - - EnterExpressionEvaluationContext ConstantEvaluated( - *this, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - // Atomic constraint - substitute arguments and check satisfaction. - ExprResult E; - { - TemplateDeductionInfo Info(ConstraintExpr->getBeginLoc()); - InstantiatingTemplate Inst(*this, ConstraintExpr->getBeginLoc(), - InstantiatingTemplate::ConstraintSubstitution{}, - NamedConcept, Info, - ConstraintExpr->getSourceRange()); - if (Inst.isInvalid()) - return true; - // We do not want error diagnostics escaping here. - Sema::SFINAETrap Trap(*this); - - E = SubstExpr(ConstraintExpr, MLTAL); - if (E.isInvalid() || Trap.hasErrorOccurred()) { - // C++2a [temp.constr.atomic]p1 - // ...If substitution results in an invalid type or expression, the - // constraint is not satisfied. - IsSatisfied = false; - return false; - } - } - - if (!CheckConstraintExpression(E.get())) - return true; - - SmallVector<PartialDiagnosticAt, 2> EvaluationDiags; - Expr::EvalResult EvalResult; - EvalResult.Diag = &EvaluationDiags; - if (!E.get()->EvaluateAsRValue(EvalResult, Context)) { - // C++2a [temp.constr.atomic]p1 - // ...E shall be a constant expression of type bool. - Diag(E.get()->getBeginLoc(), - diag::err_non_constant_constraint_expression) - << E.get()->getSourceRange(); - for (const PartialDiagnosticAt &PDiag : EvaluationDiags) - Diag(PDiag.first, PDiag.second); - return true; - } - - IsSatisfied = EvalResult.Val.getInt().getBoolValue(); - - return false; -} |