summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-10-15 14:46:39 +0000
committerNico Weber <nicolasweber@gmx.de>2019-10-15 14:46:39 +0000
commit04a9a9ffc7bfe4a6aa68bab502171cc63f0309d0 (patch)
tree8eec9d6b9c97096a1afe18b77f4c4cab31c63f5c
parent0e042f01abf08432152709f6f4d71ee1cf39c684 (diff)
downloadclang-04a9a9ffc7bfe4a6aa68bab502171cc63f0309d0.tar.gz
Revert 374882 "[Concepts] Concept Specialization Expressions"
This reverts commit ec87b003823d63f3342cf648f55a134c1522e612. The test fails on Windows, see e.g. http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/11533/steps/stage%201%20check/logs/stdio Also revert follow-up r374893. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374899 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ExprCXX.h121
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h6
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td11
-rw-r--r--include/clang/Basic/StmtNodes.td3
-rw-r--r--include/clang/Sema/Sema.h43
-rw-r--r--include/clang/Serialization/ASTBitCodes.h1
-rw-r--r--lib/AST/Expr.cpp1
-rw-r--r--lib/AST/ExprCXX.cpp79
-rw-r--r--lib/AST/ExprClassification.cpp1
-rw-r--r--lib/AST/ExprConstant.cpp8
-rw-r--r--lib/AST/ItaniumMangle.cpp1
-rw-r--r--lib/AST/StmtPrinter.cpp11
-rw-r--r--lib/AST/StmtProfile.cpp8
-rw-r--r--lib/CodeGen/CGExprScalar.cpp4
-rw-r--r--lib/Frontend/FrontendActions.cpp4
-rw-r--r--lib/Parse/ParseExpr.cpp12
-rw-r--r--lib/Sema/CMakeLists.txt1
-rw-r--r--lib/Sema/SemaConcept.cpp125
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp1
-rw-r--r--lib/Sema/SemaTemplate.cpp69
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp51
-rw-r--r--lib/Sema/TreeTransform.h36
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp24
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp61
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp13
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp25
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp25
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp18
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/lit.cfg.py26
-rw-r--r--test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp4
-rw-r--r--test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp (renamed from test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp)0
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.id/p3.cpp149
-rw-r--r--test/PCH/cxx2a-concept-specialization-expr.cpp32
-rw-r--r--test/Parser/cxx2a-concept-declaration.cpp61
-rw-r--r--tools/libclang/CXCursor.cpp1
37 files changed, 228 insertions, 827 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 57ccba8b81..61e7a91d9f 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -17,7 +17,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -57,7 +56,6 @@ class IdentifierInfo;
class LambdaCapture;
class NonTypeTemplateParmDecl;
class TemplateParameterList;
-class Sema;
//===--------------------------------------------------------------------===//
// C++ Expressions.
@@ -4752,125 +4750,6 @@ public:
}
};
-/// \brief Represents the specialization of a concept - evaluates to a prvalue
-/// of type bool.
-///
-/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
-/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr,
- private llvm::TrailingObjects<ConceptSpecializationExpr,
- TemplateArgument> {
- friend class ASTStmtReader;
- friend TrailingObjects;
-
- // \brief The optional nested name specifier used when naming the concept.
- NestedNameSpecifierLoc NestedNameSpec;
-
- /// \brief The location of the template keyword, if specified when naming the
- /// concept.
- SourceLocation TemplateKWLoc;
-
- /// \brief The location of the concept name in the expression.
- SourceLocation ConceptNameLoc;
-
- /// \brief The declaration found by name lookup when the expression was
- /// created.
- /// Can differ from NamedConcept when, for example, the concept was found
- /// through a UsingShadowDecl.
- NamedDecl *FoundDecl;
-
- /// \brief The concept named, and whether or not the concept with the given
- /// arguments was satisfied when the expression was created.
- /// If any of the template arguments are dependent (this expr would then be
- /// isValueDependent()), this bit is to be ignored.
- llvm::PointerIntPair<ConceptDecl *, 1, bool> NamedConcept;
-
- /// \brief The template argument list source info used to specialize the
- /// concept.
- const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
-
- /// \brief The number of template arguments in the tail-allocated list of
- /// converted template arguments.
- unsigned NumTemplateArgs;
-
- ConceptSpecializationExpr(ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- Optional<bool> IsSatisfied);
-
- ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
-
- static ConceptSpecializationExpr *
- Create(ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, SourceLocation ConceptNameLoc,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs, Optional<bool> IsSatisfied);
-
- static ConceptSpecializationExpr *
- Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
- const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
- return NestedNameSpec;
- }
-
- NamedDecl *getFoundDecl() const {
- return FoundDecl;
- }
-
- ConceptDecl *getNamedConcept() const {
- return NamedConcept.getPointer();
- }
-
- ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
- }
-
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Set new template arguments for this concept specialization.
- void setTemplateArguments(const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> Converted);
-
- /// \brief Whether or not the concept with the given arguments was satisfied
- /// when the expression was created. This method assumes that the expression
- /// is not dependent!
- bool isSatisfied() const {
- assert(!isValueDependent()
- && "isSatisfied called on a dependent ConceptSpecializationExpr");
- return NamedConcept.getInt();
- }
-
- SourceLocation getConceptNameLoc() const { return ConceptNameLoc; }
-
- SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConceptSpecializationExprClass;
- }
-
- SourceLocation getBeginLoc() const LLVM_READONLY { return ConceptNameLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return ArgsAsWritten->RAngleLoc;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-};
-
} // namespace clang
#endif // LLVM_CLANG_AST_EXPRCXX_H
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 998cf9238c..09a6f7840d 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2659,12 +2659,6 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
}
})
-DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgsAsWritten()->getTemplateArgs(),
- S->getTemplateArgsAsWritten()->NumTemplateArgs));
-})
-
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, {})
DEF_TRAVERSE_STMT(FixedPointLiteral, {})
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 968c2dbd56..47a1deef98 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2526,6 +2526,8 @@ def note_private_extern : Note<
"use __attribute__((visibility(\"hidden\"))) attribute instead">;
// C++ Concepts
+def err_concept_initialized_with_non_bool_type : Error<
+ "constraint expression must be of type 'bool' but is of type %0">;
def err_concept_decls_may_only_appear_in_global_namespace_scope : Error<
"concept declarations may only appear in global or namespace scope">;
def err_concept_no_parameters : Error<
@@ -2537,11 +2539,6 @@ def err_concept_no_associated_constraints : Error<
"concept cannot have associated constraints">;
def err_concept_not_implemented : Error<
"sorry, unimplemented concepts feature %0 used">;
-def err_non_constant_constraint_expression : Error<
- "substitution into constraint expression resulted in a non-constant "
- "expression">;
-def err_non_bool_atomic_constraint : Error<
- "atomic constraint must be of type 'bool' (found %0)">;
def err_template_different_associated_constraints : Error<
"associated constraints differ in template redeclaration">;
@@ -4499,10 +4496,6 @@ def note_prior_template_arg_substitution : Note<
" template parameter%1 %2">;
def note_template_default_arg_checking : Note<
"while checking a default template argument used here">;
-def note_concept_specialization_here : Note<
- "while checking the satisfaction of concept '%0' requested here">;
-def note_constraint_substitution_here : Note<
- "while substituting template arguments into constraint expression here">;
def note_instantiation_contexts_suppressed : Note<
"(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
"see all)">;
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 6231484e2b..1cef89f371 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -163,9 +163,6 @@ def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
def DependentCoawaitExpr : DStmt<Expr>;
def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
-// C++2a Concepts expressions
-def ConceptSpecializationExpr : DStmt<Expr>;
-
// Obj-C Expressions.
def ObjCStringLiteral : DStmt<Expr>;
def ObjCBoxedExpr : DStmt<Expr>;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 6b2d603206..0403df4ba7 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6047,16 +6047,7 @@ public:
CXXConversionDecl *Conv,
Expr *Src);
- /// Check whether the given expression is a valid constraint expression.
- /// A diagnostic is emitted if it is not, and false is returned.
- bool CheckConstraintExpression(Expr *CE);
-
- bool CalculateConstraintSatisfaction(ConceptDecl *NamedConcept,
- MultiLevelTemplateArgumentList &MLTAL,
- Expr *ConstraintExpr,
- bool &IsSatisfied);
-
- // ParseObjCStringLiteral - Parse Objective-C string literals.
+ // ParseObjCStringLiteral - Parse Objective-C string literals.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ArrayRef<Expr *> Strings);
@@ -6727,9 +6718,9 @@ public:
ExprResult
CheckConceptTemplateId(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
+ const DeclarationNameInfo &NameInfo,
+ ConceptDecl *Template,
+ SourceLocation TemplateLoc,
const TemplateArgumentListInfo *TemplateArgs);
void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc);
@@ -7648,15 +7639,6 @@ public:
/// member).
DefiningSynthesizedFunction,
- // We are checking the constraints associated with a constrained entity or
- // the constraint expression of a concept. This includes the checks that
- // atomic constraints have the type 'bool' and that they can be constant
- // evaluated.
- ConstraintsCheck,
-
- // We are substituting template arguments into a constraint expression.
- ConstraintSubstitution,
-
/// Added for Template instantiation observation.
/// Memoization means we are _not_ instantiating a template because
/// it is already instantiated (but we entered a context where we
@@ -7917,23 +7899,6 @@ public:
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange);
- struct ConstraintsCheck {};
- /// \brief Note that we are checking the constraints associated with some
- /// constrained entity (a concept declaration or a template with associated
- /// constraints).
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- ConstraintsCheck, TemplateDecl *Template,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange InstantiationRange);
-
- struct ConstraintSubstitution {};
- /// \brief Note that we are checking a constraint expression associated
- /// with a template declaration or as part of the satisfaction check of a
- /// concept.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- ConstraintSubstitution, TemplateDecl *Template,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange);
/// Note that we have finished instantiating this template.
void Clear();
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 0d3971dd27..eab1ec86db 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1915,7 +1915,6 @@ namespace serialization {
EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr
EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
EXPR_CXX_FOLD, // CXXFoldExpr
- EXPR_CONCEPT_SPECIALIZATION,// ConceptSpecializationExpr
// CUDA
EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index f2e625124c..339f471a2c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -3403,7 +3403,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CXXUuidofExprClass:
case OpaqueValueExprClass:
case SourceLocExprClass:
- case ConceptSpecializationExprClass:
// These never have a side-effect.
return false;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a9b7c00a8b..cb6b8703f5 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1680,82 +1680,3 @@ CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
alignof(CUDAKernelCallExpr));
return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
}
-
-ConceptSpecializationExpr::ConceptSpecializationExpr(ASTContext &C,
- NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
- SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs, Optional<bool> IsSatisfied)
- : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false,
- // All the flags below are set in setTemplateArguments.
- /*ValueDependent=*/!IsSatisfied.hasValue(),
- /*InstantiationDependent=*/false,
- /*ContainsUnexpandedParameterPacks=*/false),
- NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
- ConceptNameLoc(ConceptNameLoc), FoundDecl(FoundDecl),
- NamedConcept(NamedConcept, IsSatisfied ? *IsSatisfied : true),
- NumTemplateArgs(ConvertedArgs.size()) {
-
- setTemplateArguments(ArgsAsWritten, ConvertedArgs);
-}
-
-ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty,
- unsigned NumTemplateArgs)
- : Expr(ConceptSpecializationExprClass, Empty),
- NumTemplateArgs(NumTemplateArgs) { }
-
-void ConceptSpecializationExpr::setTemplateArguments(
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> Converted) {
- assert(Converted.size() == NumTemplateArgs);
- assert(!this->ArgsAsWritten && "setTemplateArguments can only be used once");
- this->ArgsAsWritten = ArgsAsWritten;
- std::uninitialized_copy(Converted.begin(), Converted.end(),
- getTrailingObjects<TemplateArgument>());
- bool IsInstantiationDependent = false;
- bool ContainsUnexpandedParameterPack = false;
- for (const TemplateArgumentLoc& LocInfo : ArgsAsWritten->arguments()) {
- if (LocInfo.getArgument().isInstantiationDependent())
- IsInstantiationDependent = true;
- if (LocInfo.getArgument().containsUnexpandedParameterPack())
- ContainsUnexpandedParameterPack = true;
- if (ContainsUnexpandedParameterPack && IsInstantiationDependent)
- break;
- }
-
- // Currently guaranteed by the fact concepts can only be at namespace-scope.
- assert(!NestedNameSpec ||
- (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() &&
- !NestedNameSpec.getNestedNameSpecifier()
- ->containsUnexpandedParameterPack()));
- setInstantiationDependent(IsInstantiationDependent);
- setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
- assert((!isValueDependent() || isInstantiationDependent()) &&
- "should not be value-dependent");
-}
-
-ConceptSpecializationExpr *
-ConceptSpecializationExpr::Create(ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- SourceLocation ConceptNameLoc,
- NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- Optional<bool> IsSatisfied) {
- void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
- ConvertedArgs.size()));
- return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
- ConceptNameLoc, FoundDecl,
- NamedConcept, ArgsAsWritten,
- ConvertedArgs, IsSatisfied);
-}
-
-ConceptSpecializationExpr *
-ConceptSpecializationExpr::Create(ASTContext &C, EmptyShell Empty,
- unsigned NumTemplateArgs) {
- void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
- NumTemplateArgs));
- return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
-}
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index d109cd3d03..c61ee703ac 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -192,7 +192,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::NoInitExprClass:
case Expr::DesignatedInitUpdateExprClass:
case Expr::SourceLocExprClass:
- case Expr::ConceptSpecializationExprClass:
return Cl::CL_PRValue;
case Expr::ConstantExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 4459335094..ceee50da30 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -9768,7 +9768,6 @@ public:
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
bool VisitSourceLocExpr(const SourceLocExpr *E);
- bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
// FIXME: Missing: array subscript of vector, member of vector
};
@@ -12251,12 +12250,6 @@ bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
return Success(E->getValue(), E);
}
-bool IntExprEvaluator::VisitConceptSpecializationExpr(
- const ConceptSpecializationExpr *E) {
- return Success(E->isSatisfied(), E);
-}
-
-
bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
switch (E->getOpcode()) {
default:
@@ -13930,7 +13923,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::CXXBoolLiteralExprClass:
case Expr::CXXScalarValueInitExprClass:
case Expr::TypeTraitExprClass:
- case Expr::ConceptSpecializationExprClass:
case Expr::ArrayTypeTraitExprClass:
case Expr::ExpressionTraitExprClass:
case Expr::CXXNoexceptExprClass:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 8e3ad4c266..c6f7143251 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -3658,7 +3658,6 @@ recurse:
case Expr::ConvertVectorExprClass:
case Expr::StmtExprClass:
case Expr::TypeTraitExprClass:
- case Expr::ConceptSpecializationExprClass:
case Expr::ArrayTypeTraitExprClass:
case Expr::ExpressionTraitExprClass:
case Expr::VAArgExprClass:
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 70fe484751..e392682af7 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -2231,17 +2231,6 @@ void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
OS << ")";
}
-void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
- NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
- if (NNS)
- NNS.getNestedNameSpecifier()->print(OS, Policy);
- if (E->getTemplateKWLoc().isValid())
- OS << "template ";
- OS << E->getFoundDecl()->getName();
- printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
- Policy);
-}
-
// C++ Coroutines TS
void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 82bb4b86d9..9c19305a7d 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -1309,14 +1309,6 @@ void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
ID.AddInteger(S->getOp());
}
-void StmtProfiler::VisitConceptSpecializationExpr(
- const ConceptSpecializationExpr *S) {
- VisitExpr(S);
- VisitDecl(S->getFoundDecl());
- VisitTemplateArguments(S->getTemplateArgsAsWritten()->getTemplateArgs(),
- S->getTemplateArgsAsWritten()->NumTemplateArgs);
-}
-
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
UnaryOperatorKind &UnaryOp,
BinaryOperatorKind &BinaryOp) {
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index f1396137d7..a10b18c5c9 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -673,10 +673,6 @@ public:
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
}
- Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
- return Builder.getInt1(E->isSatisfied());
- }
-
Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
}
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index fea5826179..dc830cbacb 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -417,10 +417,6 @@ private:
return "DefiningSynthesizedFunction";
case CodeSynthesisContext::Memoization:
return "Memoization";
- case CodeSynthesisContext::ConstraintsCheck:
- return "ConstraintsCheck";
- case CodeSynthesisContext::ConstraintSubstitution:
- return "ConstraintSubstitution";
}
return "";
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index b74a95a3cd..455d109021 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -228,16 +228,18 @@ ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
/// Parse a constraint-expression.
///
/// \verbatim
-/// constraint-expression: C++2a[temp.constr.decl]p1
+/// constraint-expression: [Concepts TS temp.constr.decl p1]
/// logical-or-expression
/// \endverbatim
ExprResult Parser::ParseConstraintExpression() {
- EnterExpressionEvaluationContext ConstantEvaluated(
- Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+ // FIXME: this may erroneously consume a function-body as the braced
+ // initializer list of a compound literal
+ //
+ // FIXME: this may erroneously consume a parenthesized rvalue reference
+ // declarator as a parenthesized address-of-label expression
ExprResult LHS(ParseCastExpression(/*isUnaryExpression=*/false));
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
- if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get()))
- return ExprError();
+
return Res;
}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 89c3f6c47b..742343583d 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/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/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;
-}
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 76fd10d2e6..0f3a27233e 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/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/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index cb756eb30f..284962f3e0 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/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/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 42411c9c33..9091bc5b80 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/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/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 8184d4c09b..59cac78787 100644
--- a/lib/Sema/TreeTransform.h
+++ b/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)
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 7eb56e16ea..0c802a6b09 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -734,24 +734,6 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
E->setRParenLoc(ReadSourceLocation());
}
-void ASTStmtReader::VisitConceptSpecializationExpr(
- ConceptSpecializationExpr *E) {
- VisitExpr(E);
- unsigned NumTemplateArgs = Record.readInt();
- E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
- E->TemplateKWLoc = Record.readSourceLocation();
- E->ConceptNameLoc = Record.readSourceLocation();
- E->FoundDecl = ReadDeclAs<NamedDecl>();
- E->NamedConcept.setPointer(ReadDeclAs<ConceptDecl>());
- const ASTTemplateArgumentListInfo *ArgsAsWritten =
- Record.readASTTemplateArgumentListInfo();
- llvm::SmallVector<TemplateArgument, 4> Args;
- for (unsigned I = 0; I < NumTemplateArgs; ++I)
- Args.push_back(Record.readTemplateArgument());
- E->setTemplateArguments(ArgsAsWritten, Args);
- E->NamedConcept.setInt(Record.readInt() == 1);
-}
-
void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
VisitExpr(E);
E->setLHS(Record.readSubExpr());
@@ -3508,12 +3490,6 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
case EXPR_DEPENDENT_COAWAIT:
S = new (Context) DependentCoawaitExpr(Empty);
break;
-
- case EXPR_CONCEPT_SPECIALIZATION:
- unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields];
- S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs);
- break;
-
}
// We hit a STMT_STOP, so we're done with this expression.
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index deba1ccb0e..387ed44f1a 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -388,24 +388,6 @@ void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
Code = serialization::EXPR_DEPENDENT_COAWAIT;
}
-void ASTStmtWriter::VisitConceptSpecializationExpr(
- ConceptSpecializationExpr *E) {
- VisitExpr(E);
- ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments();
- Record.push_back(TemplateArgs.size());
- Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
- Record.AddSourceLocation(E->getTemplateKWLoc());
- Record.AddSourceLocation(E->getConceptNameLoc());
- Record.AddDeclRef(E->getFoundDecl());
- Record.AddDeclRef(E->getNamedConcept());
- Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
- for (const TemplateArgument &Arg : TemplateArgs)
- Record.AddTemplateArgument(Arg);
- Record.push_back(E->isSatisfied());
- Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
-}
-
-
void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
VisitStmt(S);
// NumCaptures
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 8629fd98db..855ecf1a67 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1370,7 +1370,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::CUDAKernelCallExprClass:
case Stmt::OpaqueValueExprClass:
case Stmt::AsTypeExprClass:
- case Stmt::ConceptSpecializationExprClass:
// Fall through.
// Cases we intentionally don't evaluate, since they don't need
diff --git a/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp
new file mode 100644
index 0000000000..863b608b5b
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -fcxx-exceptions -x c++ -verify %s
+
+namespace A {
+ template<typename T> concept bool C1() { return true; }
+
+ template<typename T> concept bool C2 = true;
+}
+
+template<typename T> concept bool C3() { return (throw 0, true); }
+static_assert(noexcept(C3<int>()), "function concept should be treated as if noexcept(true) specified");
+
+template<typename T> concept bool D1(); // expected-error {{function concept declaration must be a definition}}
+
+struct B {
+ template<typename T> concept bool D2() { return true; } // expected-error {{concept declarations may only appear in namespace scope}}
+};
+
+struct C {
+ template<typename T> static concept bool D3 = true; // expected-error {{concept declarations may only appear in namespace scope}}
+};
+
+concept bool D4() { return true; } // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+
+concept bool D5 = true; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+
+template<typename T>
+concept bool D6; // expected-error {{variable concept declaration must be initialized}}
+
+template<typename T>
+concept bool D7() throw(int) { return true; } // expected-error {{function concept cannot have exception specification}}
+
+// Tag
+
+concept class CC1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+concept struct CS1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+concept union CU1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+concept enum CE1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+template <typename T> concept class TCC1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+template <typename T> concept struct TCS1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+template <typename T> concept union TCU1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+typedef concept int CI; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+void fpc(concept int i) {} // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+
+concept bool; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
+
+template <typename T> concept bool VCEI{ true };
+template concept bool VCEI<int>; // expected-error {{'concept' cannot be applied on an explicit instantiation}}
+extern template concept bool VCEI<int>; // expected-error {{'concept' cannot be applied on an explicit instantiation}}
+
+template <typename T> concept bool VCPS{ true };
+template <typename T> concept bool VCPS<T *>{ true }; // expected-error {{'concept' cannot be applied on an partial specialization}}
+
+template <typename T> concept bool VCES{ true };
+template <> concept bool VCES<int>{ true }; // expected-error {{'concept' cannot be applied on an explicit specialization}}
+
+template <typename T> concept bool FCEI() { return true; }
+template concept bool FCEI<int>(); // expected-error {{'concept' cannot be applied on an explicit instantiation}}
+extern template concept bool FCEI<int>(); // expected-error {{'concept' cannot be applied on an explicit instantiation}}
+
+template <typename T> concept bool FCES() { return true; }
+template <> concept bool FCES<bool>() { return true; } // expected-error {{'concept' cannot be applied on an explicit specialization}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
new file mode 100644
index 0000000000..477910986d
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template<typename T> concept thread_local bool VCTL = true; // expected-error {{variable concept cannot be declared 'thread_local'}}
+
+template<typename T> concept constexpr bool VCC = true; // expected-error {{variable concept cannot be declared 'constexpr'}}
+
+template<typename T> concept inline bool FCI() { return true; } // expected-error {{function concept cannot be declared 'inline'}}
+
+struct X {
+ template<typename T> concept friend bool FCF() { return true; } // expected-error {{function concept cannot be declared 'friend'}}
+};
+
+template<typename T> concept constexpr bool FCC() { return true; } // expected-error {{function concept cannot be declared 'constexpr'}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp
new file mode 100644
index 0000000000..69672ca830
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template<typename T>
+concept bool fcpv(void) { return true; }
+
+template<typename T>
+concept bool fcpi(int i = 0) { return true; } // expected-error {{function concept cannot have any parameters}}
+
+template<typename... Ts>
+concept bool fcpp(Ts... ts) { return true; } // expected-error {{function concept cannot have any parameters}}
+
+template<typename T>
+concept bool fcpva(...) { return true; } // expected-error {{function concept cannot have any parameters}}
+
+template<typename T>
+concept const bool fcrtc() { return true; } // expected-error {{declared return type of function concept must be 'bool'}}
+
+template<typename T>
+concept int fcrti() { return 5; } // expected-error {{declared return type of function concept must be 'bool'}}
+
+template<typename T>
+concept float fcrtf() { return 5.5; } // expected-error {{declared return type of function concept must be 'bool'}}
+
+template<typename T>
+concept decltype(auto) fcrtd(void) { return true; } // expected-error {{declared return type of function concept must be 'bool'}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp
new file mode 100644
index 0000000000..f8a1bb72e3
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template<typename T>
+concept bool vc { true };
+
+template<typename T>
+struct B { typedef bool Boolean; };
+
+template<int N>
+B<void>::Boolean concept vctb(!0);
+
+template<typename T>
+concept const bool vctc { true }; // expected-error {{declared type of variable concept must be 'bool'}}
+
+template<typename T>
+concept int vcti { 5 }; // expected-error {{declared type of variable concept must be 'bool'}}
+
+template<typename T>
+concept float vctf { 5.5 }; // expected-error {{declared type of variable concept must be 'bool'}}
+
+template<typename T>
+concept auto vcta { true }; // expected-error {{declared type of variable concept must be 'bool'}}
+
+template<typename T>
+concept decltype(auto) vctd { true }; // expected-error {{declared type of variable concept must be 'bool'}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp
new file mode 100644
index 0000000000..1bad6bb932
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template <typename T> concept bool FCEI() { return true; } // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}}
+template bool FCEI<int>(); // expected-error {{function concept cannot be explicitly instantiated}}
+extern template bool FCEI<double>(); // expected-error {{function concept cannot be explicitly instantiated}}
+
+template <typename T> concept bool FCES() { return true; } // expected-note {{previous declaration is here}}
+template <> bool FCES<int>() { return true; } // expected-error {{function concept cannot be explicitly specialized}}
+
+template <typename T> concept bool VC { true }; // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}}
+template bool VC<int>; // expected-error {{variable concept cannot be explicitly instantiated}}
+extern template bool VC<double>; // expected-error {{variable concept cannot be explicitly instantiated}}
+
+template <typename T> concept bool VCES { true }; // expected-note {{previous declaration is here}}
+template <> bool VCES<int> { true }; // expected-error {{variable concept cannot be explicitly specialized}}
+
+template <typename T> concept bool VCPS { true }; // expected-note {{previous declaration is here}}
+template <typename T> bool VCPS<T *> { true }; // expected-error {{variable concept cannot be partially specialized}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py b/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py
new file mode 100644
index 0000000000..c705e3cb93
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+import os
+import lit.formats
+
+from lit.llvm import llvm_config
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang-Concepts-TS-Unsupported'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.cppm', '.m', '.mm', '.cu',
+ '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs']
+
+config.unsupported = True
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
diff --git a/test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp b/test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
new file mode 100644
index 0000000000..16da146a96
--- /dev/null
+++ b/test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+
+template<typename T> concept C = true;
+static_assert(C<int>); // expected-error{{sorry, unimplemented concepts feature concept specialization used}}
diff --git a/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
index d1ad0404ef..d1ad0404ef 100644
--- a/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
+++ b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
diff --git a/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp b/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp
deleted file mode 100644
index dd3f0c0e3d..0000000000
--- a/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -verify -triple x86_64-linux-gnu %s
-
-template<typename T> concept C1 = true; // expected-note{{template is declared here}}
-static_assert(C1<int>);
-static_assert(C1);
-// expected-error@-1{{use of concept 'C1' requires template arguments}}
-
-template<typename T> concept C2 = sizeof(T) == 4;
-static_assert(C2<int>);
-static_assert(!C2<long long int>);
-static_assert(C2<char[4]>);
-static_assert(!C2<char[5]>);
-
-template<typename T> concept C3 = sizeof(*T{}) == 4;
-static_assert(C3<int*>);
-static_assert(!C3<long long int>);
-
-struct A {
- static constexpr int add(int a, int b) {
- return a + b;
- }
-};
-struct B {
- static int add(int a, int b) { // expected-note{{declared here}}
- return a + b;
- }
-};
-template<typename U>
-concept C4 = U::add(1, 2) == 3;
-// expected-error@-1{{substitution into constraint expression resulted in a non-constant expression}}
-// expected-note@-2{{non-constexpr function 'add' cannot be used in a constant expression}}
-static_assert(C4<A>);
-static_assert(!C4<B>); // expected-note {{while checking the satisfaction of concept 'C4<B>' requested here}}
-
-template<typename T, typename U>
-constexpr bool is_same_v = false;
-
-template<typename T>
-constexpr bool is_same_v<T, T> = true;
-
-template<typename T, typename U>
-concept Same = is_same_v<T, U>;
-
-static_assert(Same<int, int>);
-static_assert(Same<int, decltype(1)>);
-static_assert(!Same<int, unsigned int>);
-static_assert(!Same<A, B>);
-static_assert(Same<A, A>);
-
-static_assert(Same<bool, decltype(C1<int>)>);
-static_assert(Same<bool, decltype(C2<int>)>);
-static_assert(Same<bool, decltype(C3<int*>)>);
-static_assert(Same<bool, decltype(C4<A>)>);
-
-template<typename T> concept C5 = T{}; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-constexpr bool x = C5<int>; // expected-note {{while checking the satisfaction of concept 'C5<int>' requested here}}
-
-template<int x>
-concept IsEven = (x % 2) == 0;
-
-static_assert(IsEven<20>);
-static_assert(!IsEven<11>);
-
-template<template<typename T> typename P>
-concept IsTypePredicate = is_same_v<decltype(P<bool>::value), const bool>
- && is_same_v<decltype(P<int>::value), const bool>
- && is_same_v<decltype(P<long long>::value), const bool>;
-
-template<typename T> struct T1 {};
-template<typename T> struct T2 { static constexpr bool value = sizeof(T) == 2; };
-
-static_assert(IsTypePredicate<T2>);
-static_assert(!IsTypePredicate<T1>);
-
-namespace piecewise_substitution {
- template <typename T>
- concept True = true;
-
- template <typename T>
- concept A = True<T> || T::value;
-
- template <typename T>
- concept B = (True<T> || T::value);
-
- template <typename T>
- concept C = !True<T> && T::value || true;
-
- template <typename T>
- concept D = (!True<T> && T::value) || true;
-
- template <typename T>
- concept E = T::value || True<T>;
-
- template <typename T>
- concept F = (T::value || True<T>);
-
- template <typename T>
- concept G = T::value && !True<T> || true;
-
- template <typename T>
- concept H = (T::value && !True<T>) || true;
-
- template <typename T>
- concept I = T::value;
-
- static_assert(A<int>);
- static_assert(B<int>);
- static_assert(C<int>);
- static_assert(D<int>);
- static_assert(E<int>);
- static_assert(F<int>);
- static_assert(G<int>);
- static_assert(H<int>);
- static_assert(!I<int>);
-}
-
-// Short ciruiting
-
-template<typename T> struct T3 { using type = typename T::type; };
-// expected-error@-1{{type 'char' cannot be used prior to '::' because it has no members}}
-// expected-error@-2{{type 'short' cannot be used prior to '::' because it has no members}}
-
-template<typename T>
-concept C6 = sizeof(T) == 1 && sizeof(typename T3<T>::type) == 1;
-// expected-note@-1{{while substituting template arguments into constraint expression here}}
-// expected-note@-2{{in instantiation of template class 'T3<char>' requested here}}
-
-template<typename T>
-concept C7 = sizeof(T) == 1 || sizeof(
-// expected-note@-1{{while substituting template arguments into constraint expression here}}
- typename
- T3<T>
-// expected-note@-1{{in instantiation of template class 'T3<short>' requested here}}
- ::type) == 1;
-
-static_assert(!C6<short>);
-static_assert(!C6<char>); // expected-note{{while checking the satisfaction of concept 'C6<char>' requested here}}
-static_assert(C7<char>);
-static_assert(!C7<short>); // expected-note{{while checking the satisfaction of concept 'C7<short>' requested here}}
-
-// Make sure argument list is converted when instantiating a CSE.
-
-template<typename T, typename U = int>
-concept SameSize = sizeof(T) == sizeof(U);
-
-template<typename T>
-struct X { static constexpr bool a = SameSize<T>; };
-
-static_assert(X<unsigned>::a);
diff --git a/test/PCH/cxx2a-concept-specialization-expr.cpp b/test/PCH/cxx2a-concept-specialization-expr.cpp
deleted file mode 100644
index 6227d57c87..0000000000
--- a/test/PCH/cxx2a-concept-specialization-expr.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
-
-// expected-no-diagnostics
-
-#ifndef HEADER
-#define HEADER
-
-template<typename... T>
-concept C = true;
-
-namespace n {
- template<typename... T>
- concept C = true;
-}
-
-void f() {
- (void)C<int>;
- (void)C<int, void>;
- (void)n::C<void>;
-}
-
-#else /*included pch*/
-
-int main() {
- (void)C<int>;
- (void)C<int, void>;
- (void)n::C<void>;
- f();
-}
-
-#endif // HEADER
diff --git a/test/Parser/cxx2a-concept-declaration.cpp b/test/Parser/cxx2a-concept-declaration.cpp
index 4dcfa3f854..d80b3db428 100644
--- a/test/Parser/cxx2a-concept-declaration.cpp
+++ b/test/Parser/cxx2a-concept-declaration.cpp
@@ -14,6 +14,8 @@ template<template<typename> concept T> concept D2 = true;
// expected-error@-2{{template template parameter requires 'class' after the parameter list}}
// expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
+template<typename T> concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
+
struct S1 {
template<typename T> concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
};
@@ -24,15 +26,15 @@ extern "C++" {
template<typename A>
template<typename B>
-concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
-template<typename T> concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
-int C3; // expected-error {{redefinition}}
-struct C3 {}; // expected-error {{redefinition}}
+template<typename T> concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
+int C5; // expected-error {{redefinition}}
+struct C5 {}; // expected-error {{redefinition}}
-struct C4 {}; // expected-note{{previous definition is here}}
-template<typename T> concept C4 = true;
-// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
+struct C6 {}; // expected-note{{previous definition is here}}
+template<typename T> concept C6 = true;
+// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
// TODO: Add test to prevent explicit specialization, partial specialization
// and explicit instantiation of concepts.
@@ -41,60 +43,31 @@ template<typename T, T v>
struct integral_constant { static constexpr T value = v; };
namespace N {
- template<typename T> concept C5 = true;
+ template<typename T> concept C7 = true;
}
-using N::C5;
+using N::C7;
-template <bool word> concept C6 = integral_constant<bool, wor>::value;
+template <bool word> concept C8 = integral_constant<bool, wor>::value;
// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
// expected-note@-2{{'word' declared here}}
-template<typename T> concept bool C7 = true;
+template<typename T> concept bool C9 = true;
// expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
-template<> concept C8 = false;
+template<> concept C10 = false;
// expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
-template<> concept C7<int> = false;
+template<> concept C9<int> = false;
// expected-error@-1{{name defined in concept definition must be an identifier}}
-template<typename T> concept N::C9 = false;
+template<typename T> concept N::C11 = false;
// expected-error@-1{{name defined in concept definition must be an identifier}}
class A { };
// expected-note@-1{{'A' declared here}}
-template<typename T> concept A::C10 = false;
+template<typename T> concept A::C12 = false;
// expected-error@-1{{expected namespace name}}
template<typename T> concept operator int = false;
// expected-error@-1{{name defined in concept definition must be an identifier}}
-
-template<bool x> concept C11 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template<bool x> concept C12 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template<bool x> concept C13 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template<bool x> concept C14 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
-template<typename T> concept C15 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
-template<typename T> concept C16 = true && (0 && 0); // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-// expected-warning@-1{{use of logical '&&' with constant operand}}
-// expected-note@-2{{use '&' for a bitwise operation}}
-// expected-note@-3{{remove constant to silence this warning}}
-template<typename T> concept C17 = T{};
-static_assert(!C17<bool>);
-template<typename T> concept C18 = (bool&&)true;
-static_assert(C18<int>);
-template<typename T> concept C19 = (const bool&)true;
-static_assert(C19<int>);
-template<typename T> concept C20 = (const bool)true;
-static_assert(C20<int>);
-template <bool c> concept C21 = integral_constant<bool, c>::value && true;
-static_assert(C21<true>);
-static_assert(!C21<false>);
-template <bool c> concept C22 = integral_constant<bool, c>::value;
-static_assert(C22<true>);
-static_assert(!C22<false>);
-
-template <bool word> concept C23 = integral_constant<bool, wor>::value;
-// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
-// expected-note@-2{{'word' declared here}}
-
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 634b108ec3..93e588ebaa 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -256,7 +256,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::BinaryConditionalOperatorClass:
case Stmt::TypeTraitExprClass:
case Stmt::CoawaitExprClass:
- case Stmt::ConceptSpecializationExprClass:
case Stmt::DependentCoawaitExprClass:
case Stmt::CoyieldExprClass:
case Stmt::CXXBindTemporaryExprClass: