summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/CMakeLists.txt1
-rw-r--r--clang/lib/Sema/SemaConcept.cpp125
-rw-r--r--clang/lib/Sema/SemaExceptionSpec.cpp1
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp69
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp51
-rw-r--r--clang/lib/Sema/TreeTransform.h36
6 files changed, 26 insertions, 257 deletions
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 89c3f6c47b4..742343583d1 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -32,7 +32,6 @@ add_clang_library(clangSema
SemaCast.cpp
SemaChecking.cpp
SemaCodeComplete.cpp
- SemaConcept.cpp
SemaConsumer.cpp
SemaCoroutine.cpp
SemaCUDA.cpp
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
deleted file mode 100644
index 3131609390a..00000000000
--- a/clang/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;
-}
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 76fd10d2e63..0f3a27233ee 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1314,7 +1314,6 @@ CanThrowResult Sema::canThrow(const Expr *E) {
case Expr::SizeOfPackExprClass:
case Expr::StringLiteralClass:
case Expr::SourceLocExprClass:
- case Expr::ConceptSpecializationExprClass:
// These expressions can never throw.
return CT_Cannot;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index cb756eb30f6..284962f3e07 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4271,47 +4271,14 @@ void Sema::diagnoseMissingTemplateArguments(TemplateName Name,
ExprResult
Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- SourceLocation ConceptNameLoc,
- NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
+ const DeclarationNameInfo &NameInfo,
+ ConceptDecl *Template,
+ SourceLocation TemplateLoc,
const TemplateArgumentListInfo *TemplateArgs) {
- assert(NamedConcept && "A concept template id without a template?");
-
- llvm::SmallVector<TemplateArgument, 4> Converted;
- if (CheckTemplateArgumentList(NamedConcept, ConceptNameLoc,
- const_cast<TemplateArgumentListInfo&>(*TemplateArgs),
- /*PartialTemplateArgs=*/false, Converted,
- /*UpdateArgsWithConversion=*/false))
- return ExprError();
-
- Optional<bool> IsSatisfied;
- bool AreArgsDependent = false;
- for (TemplateArgument &Arg : Converted) {
- if (Arg.isDependent()) {
- AreArgsDependent = true;
- break;
- }
- }
- if (!AreArgsDependent) {
- InstantiatingTemplate Inst(*this, ConceptNameLoc,
- InstantiatingTemplate::ConstraintsCheck{}, NamedConcept, Converted,
- SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameLoc,
- TemplateArgs->getRAngleLoc()));
- MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(Converted);
- bool Satisfied;
- if (CalculateConstraintSatisfaction(NamedConcept, MLTAL,
- NamedConcept->getConstraintExpr(),
- Satisfied))
- return ExprError();
- IsSatisfied = Satisfied;
- }
- return ConceptSpecializationExpr::Create(Context,
- SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc{},
- TemplateKWLoc, ConceptNameLoc, FoundDecl, NamedConcept,
- ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs), Converted,
- IsSatisfied);
+ // TODO: Do concept specialization here.
+ Diag(NameInfo.getBeginLoc(), diag::err_concept_not_implemented) <<
+ "concept specialization";
+ return ExprError();
}
ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
@@ -4355,10 +4322,9 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
}
if (R.getAsSingle<ConceptDecl>() && !AnyDependentArguments()) {
- return CheckConceptTemplateId(SS, TemplateKWLoc,
- R.getLookupNameInfo().getBeginLoc(),
- R.getFoundDecl(),
- R.getAsSingle<ConceptDecl>(), TemplateArgs);
+ return CheckConceptTemplateId(SS, R.getLookupNameInfo(),
+ R.getAsSingle<ConceptDecl>(),
+ TemplateKWLoc, TemplateArgs);
}
// We don't want lookup warnings at this point.
@@ -8088,7 +8054,20 @@ Decl *Sema::ActOnConceptDefinition(Scope *S,
ConceptDecl *NewDecl = ConceptDecl::Create(Context, DC, NameLoc, Name,
TemplateParameterLists.front(),
ConstraintExpr);
-
+
+ if (!ConstraintExpr->isTypeDependent() &&
+ ConstraintExpr->getType() != Context.BoolTy) {
+ // C++2a [temp.constr.atomic]p3:
+ // E shall be a constant expression of type bool.
+ // TODO: Do this check for individual atomic constraints
+ // and not the constraint expression. Probably should do it in
+ // ParseConstraintExpression.
+ Diag(ConstraintExpr->getSourceRange().getBegin(),
+ diag::err_concept_initialized_with_non_bool_type)
+ << ConstraintExpr->getType();
+ NewDecl->setInvalidDecl();
+ }
+
if (NewDecl->getAssociatedConstraints()) {
// C++2a [temp.concept]p4:
// A concept shall not have associated constraints.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 42411c9c33f..9091bc5b80d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -198,14 +198,12 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
case ExplicitTemplateArgumentSubstitution:
case DeducedTemplateArgumentSubstitution:
case PriorTemplateArgumentSubstitution:
- case ConstraintsCheck:
return true;
case DefaultTemplateArgumentChecking:
case DeclaringSpecialMember:
case DefiningSynthesizedFunction:
case ExceptionSpecEvaluation:
- case ConstraintSubstitution:
return false;
// This function should never be called when Kind's value is Memoization.
@@ -360,24 +358,6 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
PointOfInstantiation, InstantiationRange, Param, Template,
TemplateArgs) {}
-Sema::InstantiatingTemplate::InstantiatingTemplate(
- Sema &SemaRef, SourceLocation PointOfInstantiation,
- ConstraintsCheck, TemplateDecl *Template,
- ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
- : InstantiatingTemplate(
- SemaRef, CodeSynthesisContext::ConstraintsCheck,
- PointOfInstantiation, InstantiationRange, Template, nullptr,
- TemplateArgs) {}
-
-Sema::InstantiatingTemplate::InstantiatingTemplate(
- Sema &SemaRef, SourceLocation PointOfInstantiation,
- ConstraintSubstitution, TemplateDecl *Template,
- sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
- : InstantiatingTemplate(
- SemaRef, CodeSynthesisContext::ConstraintSubstitution,
- PointOfInstantiation, InstantiationRange, Template, nullptr,
- {}, &DeductionInfo) {}
-
void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
InNonInstantiationSFINAEContext = false;
@@ -684,30 +664,6 @@ void Sema::PrintInstantiationStack() {
case CodeSynthesisContext::Memoization:
break;
-
- case CodeSynthesisContext::ConstraintsCheck:
- if (auto *CD = dyn_cast<ConceptDecl>(Active->Entity)) {
- SmallVector<char, 128> TemplateArgsStr;
- llvm::raw_svector_ostream OS(TemplateArgsStr);
- CD->printName(OS);
- printTemplateArgumentList(OS, Active->template_arguments(),
- getPrintingPolicy());
- Diags.Report(Active->PointOfInstantiation,
- diag::note_concept_specialization_here)
- << OS.str()
- << Active->InstantiationRange;
- break;
- }
- // TODO: Concepts - implement this for constrained templates and partial
- // specializations.
- llvm_unreachable("only concept constraints are supported right now");
- break;
-
- case CodeSynthesisContext::ConstraintSubstitution:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_constraint_substitution_here)
- << Active->InstantiationRange;
- break;
}
}
}
@@ -731,7 +687,6 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
LLVM_FALLTHROUGH;
case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
case CodeSynthesisContext::ExceptionSpecInstantiation:
- case CodeSynthesisContext::ConstraintsCheck:
// This is a template instantiation, so there is no SFINAE.
return None;
@@ -745,10 +700,8 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
- case CodeSynthesisContext::ConstraintSubstitution:
- // We're either substituting explicitly-specified template arguments
- // or deduced template arguments or a constraint expression, so SFINAE
- // applies.
+ // We're either substitution explicitly-specified template arguments
+ // or deduced template arguments, so SFINAE applies.
assert(Active->DeductionInfo && "Missing deduction info pointer");
return Active->DeductionInfo;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8184d4c09b4..59cac787876 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3019,25 +3019,6 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, SourceLocation ConceptNameLoc,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- TemplateArgumentListInfo *TALI) {
- CXXScopeSpec SS;
- SS.Adopt(NNS);
- ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
- ConceptNameLoc,
- FoundDecl,
- NamedConcept, TALI);
- if (Result.isInvalid())
- return ExprError();
- return Result;
- }
-
- /// \brief Build a new Objective-C boxed expression.
- ///
- /// By default, performs semantic analysis to build the new expression.
- /// Subclasses may override this routine to provide different behavior.
ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
}
@@ -11035,23 +11016,6 @@ TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
template<typename Derived>
ExprResult
-TreeTransform<Derived>::TransformConceptSpecializationExpr(
- ConceptSpecializationExpr *E) {
- const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
- TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
- if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
- Old->NumTemplateArgs, TransArgs))
- return ExprError();
-
- return getDerived().RebuildConceptSpecializationExpr(
- E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
- E->getConceptNameLoc(), E->getFoundDecl(), E->getNamedConcept(),
- &TransArgs);
-}
-
-
-template<typename Derived>
-ExprResult
TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
if (!T)
OpenPOWER on IntegriCloud