[clang] baa84d8 - Revert "[Concepts] Requires Expressions"

Saar Raz via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 18 05:00:49 PST 2020


Author: Saar Raz
Date: 2020-01-18T14:58:01+02:00
New Revision: baa84d8cde940278d6fb37917ac0d64c127b528f

URL: https://github.com/llvm/llvm-project/commit/baa84d8cde940278d6fb37917ac0d64c127b528f
DIFF: https://github.com/llvm/llvm-project/commit/baa84d8cde940278d6fb37917ac0d64c127b528f.diff

LOG: Revert "[Concepts] Requires Expressions"

This reverts commit 027931899763409e2c61a84bdee6057b5e838ffa.

There have been some failing tests on some platforms, reverting while investigating.

Added: 
    

Modified: 
    clang/include/clang/AST/ASTConcept.h
    clang/include/clang/AST/DeclCXX.h
    clang/include/clang/AST/ExprCXX.h
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/include/clang/AST/Stmt.h
    clang/include/clang/AST/StmtVisitor.h
    clang/include/clang/Basic/DeclNodes.td
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Basic/StmtNodes.td
    clang/include/clang/Parse/Parser.h
    clang/include/clang/Sema/DeclSpec.h
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Sema/SemaConcept.h
    clang/include/clang/Serialization/ASTBitCodes.h
    clang/lib/AST/CMakeLists.txt
    clang/lib/AST/DeclBase.cpp
    clang/lib/AST/DeclCXX.cpp
    clang/lib/AST/Expr.cpp
    clang/lib/AST/ExprCXX.cpp
    clang/lib/AST/ExprClassification.cpp
    clang/lib/AST/ExprConstant.cpp
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/AST/Stmt.cpp
    clang/lib/AST/StmtPrinter.cpp
    clang/lib/AST/StmtProfile.cpp
    clang/lib/CodeGen/CGDecl.cpp
    clang/lib/CodeGen/CGExprScalar.cpp
    clang/lib/Frontend/FrontendActions.cpp
    clang/lib/Frontend/InitPreprocessor.cpp
    clang/lib/Parse/ParseDecl.cpp
    clang/lib/Parse/ParseExpr.cpp
    clang/lib/Parse/ParseExprCXX.cpp
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaExceptionSpec.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaLookup.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Sema/SemaType.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTCommon.cpp
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/lib/Serialization/ASTReaderStmt.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/lib/Serialization/ASTWriterDecl.cpp
    clang/lib/Serialization/ASTWriterStmt.cpp
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
    clang/tools/libclang/CIndex.cpp
    clang/tools/libclang/CXCursor.cpp

Removed: 
    clang/include/clang/AST/ExprConcepts.h
    clang/lib/AST/ExprConcepts.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
    clang/test/PCH/cxx2a-requires-expr.cpp
    clang/test/Parser/cxx2a-concepts-requires-expr.cpp
    clang/test/SemaTemplate/instantiate-requires-expr.cpp


################################################################################
diff  --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h
index 84a611c14e0b..896d857d8c96 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -22,7 +22,6 @@
 #include <utility>
 namespace clang {
 class ConceptDecl;
-class ConceptSpecializationExpr;
 
 /// \brief The result of a constraint satisfaction check, containing the
 /// necessary information to diagnose an unsatisfied constraint.

diff  --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 2e8e31dbf4c7..b716ea453a5a 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1893,37 +1893,6 @@ class CXXDeductionGuideDecl : public FunctionDecl {
   static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
 };
 
-/// \brief Represents the body of a requires-expression.
-///
-/// This decl exists merely to serve as the DeclContext for the local
-/// parameters of the requires expression as well as other declarations inside
-/// it.
-///
-/// \code
-/// template<typename T> requires requires (T t) { {t++} -> regular; }
-/// \endcode
-///
-/// In this example, a RequiresExpr object will be generated for the expression,
-/// and a RequiresExprBodyDecl will be created to hold the parameter t and the
-/// template argument list imposed by the compound requirement.
-class RequiresExprBodyDecl : public Decl, public DeclContext {
-  RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
-      : Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {}
-
-public:
-  friend class ASTDeclReader;
-  friend class ASTDeclWriter;
-
-  static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC,
-                                      SourceLocation StartLoc);
-
-  static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
-  static bool classofKind(Kind K) { return K == RequiresExprBody; }
-};
-
 /// Represents a static or instance method of a struct/union/class.
 ///
 /// In the terminology of the C++ Standard, these are the (static and

diff  --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index cea360d12e91..2c29409e0ca5 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_EXPRCXX_H
 #define LLVM_CLANG_AST_EXPRCXX_H
 
+#include "clang/AST/ASTConcept.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -4835,6 +4836,99 @@ class BuiltinBitCastExpr final
   }
 };
 
+/// \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, public ConceptReference,
+      private llvm::TrailingObjects<ConceptSpecializationExpr,
+                                    TemplateArgument> {
+  friend class ASTStmtReader;
+  friend TrailingObjects;
+public:
+  using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
+
+protected:
+  /// \brief The number of template arguments in the tail-allocated list of
+  /// converted template arguments.
+  unsigned NumTemplateArgs;
+
+  /// \brief Information about the satisfaction of the named concept with the
+  /// given arguments. If this expression is value dependent, this is to be
+  /// ignored.
+  ASTConstraintSatisfaction *Satisfaction;
+
+  ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
+                            SourceLocation TemplateKWLoc,
+                            DeclarationNameInfo ConceptNameInfo,
+                            NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+                            const ASTTemplateArgumentListInfo *ArgsAsWritten,
+                            ArrayRef<TemplateArgument> ConvertedArgs,
+                            const ConstraintSatisfaction *Satisfaction);
+
+  ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+
+  static ConceptSpecializationExpr *
+  Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
+         SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+         NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+         const ASTTemplateArgumentListInfo *ArgsAsWritten,
+         ArrayRef<TemplateArgument> ConvertedArgs,
+         const ConstraintSatisfaction *Satisfaction);
+
+  static ConceptSpecializationExpr *
+  Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
+
+  ArrayRef<TemplateArgument> getTemplateArguments() const {
+    return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+                                      NumTemplateArgs);
+  }
+
+  /// \brief Set new template arguments for this concept specialization.
+  void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+
+  /// \brief Whether or not the concept with the given arguments was satisfied
+  /// when the expression was created.
+  /// The expression must not be dependent.
+  bool isSatisfied() const {
+    assert(!isValueDependent()
+           && "isSatisfied called on a dependent ConceptSpecializationExpr");
+    return Satisfaction->IsSatisfied;
+  }
+
+  /// \brief Get elaborated satisfaction info about the template arguments'
+  /// satisfaction of the named concept.
+  /// The expression must not be dependent.
+  const ASTConstraintSatisfaction &getSatisfaction() const {
+    assert(!isValueDependent()
+           && "getSatisfaction called on dependent ConceptSpecializationExpr");
+    return *Satisfaction;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConceptSpecializationExprClass;
+  }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+    return ConceptName.getBeginLoc();
+  }
+
+  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/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
deleted file mode 100644
index 8d0de0b6e99c..000000000000
--- a/clang/include/clang/AST/ExprConcepts.h
+++ /dev/null
@@ -1,537 +0,0 @@
-//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// Defines Expressions and AST nodes for C++2a concepts.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
-#define LLVM_CLANG_AST_EXPRCONCEPTS_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConcept.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <utility>
-#include <string>
-
-namespace clang {
-class ASTStmtReader;
-class ASTStmtWriter;
-
-/// \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, public ConceptReference,
-      private llvm::TrailingObjects<ConceptSpecializationExpr,
-                                    TemplateArgument> {
-  friend class ASTStmtReader;
-  friend TrailingObjects;
-public:
-  using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-
-protected:
-  /// \brief The number of template arguments in the tail-allocated list of
-  /// converted template arguments.
-  unsigned NumTemplateArgs;
-
-  /// \brief Information about the satisfaction of the named concept with the
-  /// given arguments. If this expression is value dependent, this is to be
-  /// ignored.
-  ASTConstraintSatisfaction *Satisfaction;
-
-  ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
-                            SourceLocation TemplateKWLoc,
-                            DeclarationNameInfo ConceptNameInfo,
-                            NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
-                            const ASTTemplateArgumentListInfo *ArgsAsWritten,
-                            ArrayRef<TemplateArgument> ConvertedArgs,
-                            const ConstraintSatisfaction *Satisfaction);
-
-  ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
-
-  static ConceptSpecializationExpr *
-  Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
-         SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
-         NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
-         const ASTTemplateArgumentListInfo *ArgsAsWritten,
-         ArrayRef<TemplateArgument> ConvertedArgs,
-         const ConstraintSatisfaction *Satisfaction);
-
-  static ConceptSpecializationExpr *
-  Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
-  ArrayRef<TemplateArgument> getTemplateArguments() const {
-    return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
-                                      NumTemplateArgs);
-  }
-
-  /// \brief Set new template arguments for this concept specialization.
-  void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
-
-  /// \brief Whether or not the concept with the given arguments was satisfied
-  /// when the expression was created.
-  /// The expression must not be dependent.
-  bool isSatisfied() const {
-    assert(!isValueDependent()
-           && "isSatisfied called on a dependent ConceptSpecializationExpr");
-    return Satisfaction->IsSatisfied;
-  }
-
-  /// \brief Get elaborated satisfaction info about the template arguments'
-  /// satisfaction of the named concept.
-  /// The expression must not be dependent.
-  const ASTConstraintSatisfaction &getSatisfaction() const {
-    assert(!isValueDependent()
-           && "getSatisfaction called on dependent ConceptSpecializationExpr");
-    return *Satisfaction;
-  }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == ConceptSpecializationExprClass;
-  }
-
-  SourceLocation getBeginLoc() const LLVM_READONLY {
-    return ConceptName.getBeginLoc();
-  }
-
-  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 concepts {
-
-/// \brief A static requirement that can be used in a requires-expression to
-/// check properties of types and expression.
-class Requirement {
-public:
-  // Note - simple and compound requirements are both represented by the same
-  // class (ExprRequirement).
-  enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested };
-private:
-  const RequirementKind Kind;
-  bool Dependent : 1;
-  bool ContainsUnexpandedParameterPack : 1;
-  bool Satisfied : 1;
-public:
-  struct SubstitutionDiagnostic {
-    StringRef SubstitutedEntity;
-    // FIXME: Store diagnostics semantically and not as prerendered strings.
-    //  Fixing this probably requires serialization of PartialDiagnostic
-    //  objects.
-    SourceLocation DiagLoc;
-    StringRef DiagMessage;
-  };
-
-  Requirement(RequirementKind Kind, bool IsDependent,
-              bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) :
-      Kind(Kind), Dependent(IsDependent),
-      ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack),
-      Satisfied(IsSatisfied) {}
-
-  RequirementKind getKind() const { return Kind; }
-
-  bool isSatisfied() const {
-    assert(!Dependent &&
-           "isSatisfied can only be called on non-dependent requirements.");
-    return Satisfied;
-  }
-
-  void setSatisfied(bool IsSatisfied) {
-    assert(!Dependent &&
-           "setSatisfied can only be called on non-dependent requirements.");
-    Satisfied = IsSatisfied;
-  }
-
-  void setDependent(bool IsDependent) { Dependent = IsDependent; }
-  bool isDependent() const { return Dependent; }
-
-  void setContainsUnexpandedParameterPack(bool Contains) {
-    ContainsUnexpandedParameterPack = Contains;
-  }
-  bool containsUnexpandedParameterPack() const {
-    return ContainsUnexpandedParameterPack;
-  }
-};
-
-/// \brief A requires-expression requirement which queries the existence of a
-/// type name or type template specialization ('type' requirements).
-class TypeRequirement : public Requirement {
-public:
-  enum SatisfactionStatus {
-      SS_Dependent,
-      SS_SubstitutionFailure,
-      SS_Satisfied
-  };
-private:
-  llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value;
-  SatisfactionStatus Status;
-public:
-  friend ASTStmtReader;
-  friend ASTStmtWriter;
-
-  /// \brief Construct a type requirement from a type. If the given type is not
-  /// dependent, this indicates that the type exists and the requirement will be
-  /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be
-  /// used.
-  TypeRequirement(TypeSourceInfo *T);
-
-  /// \brief Construct a type requirement when the nested name specifier is
-  /// invalid due to a bad substitution. The requirement is unsatisfied.
-  TypeRequirement(SubstitutionDiagnostic *Diagnostic) :
-      Requirement(RK_Type, false, false, false), Value(Diagnostic),
-      Status(SS_SubstitutionFailure) {}
-
-  SatisfactionStatus getSatisfactionStatus() const { return Status; }
-  void setSatisfactionStatus(SatisfactionStatus Status) {
-    this->Status = Status;
-  }
-
-  bool isSubstitutionFailure() const {
-    return Status == SS_SubstitutionFailure;
-  }
-
-  SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
-    assert(Status == SS_SubstitutionFailure &&
-           "Attempted to get substitution diagnostic when there has been no "
-           "substitution failure.");
-    return Value.get<SubstitutionDiagnostic *>();
-  }
-
-  TypeSourceInfo *getType() const {
-    assert(!isSubstitutionFailure() &&
-           "Attempted to get type when there has been a substitution failure.");
-    return Value.get<TypeSourceInfo *>();
-  }
-
-  static bool classof(const Requirement *R) {
-    return R->getKind() == RK_Type;
-  }
-};
-
-/// \brief A requires-expression requirement which queries the validity and
-/// properties of an expression ('simple' and 'compound' requirements).
-class ExprRequirement : public Requirement {
-public:
-  enum SatisfactionStatus {
-      SS_Dependent,
-      SS_ExprSubstitutionFailure,
-      SS_NoexceptNotMet,
-      SS_TypeRequirementSubstitutionFailure,
-      SS_ConstraintsNotSatisfied,
-      SS_Satisfied
-  };
-  class ReturnTypeRequirement {
-      llvm::PointerIntPair<
-          llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>,
-          2, int>
-          TypeConstraintInfo;
-  public:
-      friend ASTStmtReader;
-      friend ASTStmtWriter;
-
-      /// \brief No return type requirement was specified.
-      ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {}
-
-      /// \brief A return type requirement was specified but it was a
-      /// substitution failure.
-      ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
-          TypeConstraintInfo(SubstDiag, 0) {}
-
-      /// \brief A 'type constraint' style return type requirement.
-      /// \param TPL an invented template parameter list containing a single
-      /// type parameter with a type-constraint.
-      // TODO: Can we maybe not save the whole template parameter list and just
-      //  the type constraint? Saving the whole TPL makes it easier to handle in
-      //  serialization but is less elegant.
-      ReturnTypeRequirement(TemplateParameterList *TPL);
-
-      bool isDependent() const {
-        return TypeConstraintInfo.getInt() & 1;
-      }
-
-      bool containsUnexpandedParameterPack() const {
-        return TypeConstraintInfo.getInt() & 2;
-      }
-
-      bool isEmpty() const {
-        return TypeConstraintInfo.getPointer().isNull();
-      }
-
-      bool isSubstitutionFailure() const {
-        return !isEmpty() &&
-            TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>();
-      }
-
-      bool isTypeConstraint() const {
-        return !isEmpty() &&
-            TypeConstraintInfo.getPointer().is<TemplateParameterList *>();
-      }
-
-      SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
-        assert(isSubstitutionFailure());
-        return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>();
-      }
-
-      const TypeConstraint *getTypeConstraint() const;
-
-      TemplateParameterList *getTypeConstraintTemplateParameterList() const {
-        assert(isTypeConstraint());
-        return TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
-      }
-  };
-private:
-  llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
-  SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified.
-  ReturnTypeRequirement TypeReq;
-  ConceptSpecializationExpr *SubstitutedConstraintExpr;
-  SatisfactionStatus Status;
-public:
-  friend ASTStmtReader;
-  friend ASTStmtWriter;
-
-  /// \brief Construct a compound requirement.
-  /// \param E the expression which is checked by this requirement.
-  /// \param IsSimple whether this was a simple requirement in source.
-  /// \param NoexceptLoc the location of the noexcept keyword, if it was
-  /// specified, otherwise an empty location.
-  /// \param Req the requirement for the type of the checked expression.
-  /// \param Status the satisfaction status of this requirement.
-  ExprRequirement(
-      Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
-      ReturnTypeRequirement Req, SatisfactionStatus Status,
-      ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr);
-
-  /// \brief Construct a compound requirement whose expression was a
-  /// substitution failure. The requirement is not satisfied.
-  /// \param E the diagnostic emitted while instantiating the original
-  /// expression.
-  /// \param IsSimple whether this was a simple requirement in source.
-  /// \param NoexceptLoc the location of the noexcept keyword, if it was
-  /// specified, otherwise an empty location.
-  /// \param Req the requirement for the type of the checked expression (omit
-  /// if no requirement was specified).
-  ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple,
-                  SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {});
-
-  bool isSimple() const { return getKind() == RK_Simple; }
-  bool isCompound() const { return getKind() == RK_Compound; }
-
-  bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); }
-  SourceLocation getNoexceptLoc() const { return NoexceptLoc; }
-
-  SatisfactionStatus getSatisfactionStatus() const { return Status; }
-
-  bool isExprSubstitutionFailure() const {
-    return Status == SS_ExprSubstitutionFailure;
-  }
-
-  const ReturnTypeRequirement &getReturnTypeRequirement() const {
-    return TypeReq;
-  }
-
-  ConceptSpecializationExpr *
-  getReturnTypeRequirementSubstitutedConstraintExpr() const {
-    assert(Status >= SS_TypeRequirementSubstitutionFailure);
-    return SubstitutedConstraintExpr;
-  }
-
-  SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const {
-    assert(isExprSubstitutionFailure() &&
-           "Attempted to get expression substitution diagnostic when there has "
-           "been no expression substitution failure");
-    return Value.get<SubstitutionDiagnostic *>();
-  }
-
-  Expr *getExpr() const {
-    assert(!isExprSubstitutionFailure() &&
-           "ExprRequirement has no expression because there has been a "
-           "substitution failure.");
-    return Value.get<Expr *>();
-  }
-
-  static bool classof(const Requirement *R) {
-    return R->getKind() == RK_Compound || R->getKind() == RK_Simple;
-  }
-};
-
-/// \brief A requires-expression requirement which is satisfied when a general
-/// constraint expression is satisfied ('nested' requirements).
-class NestedRequirement : public Requirement {
-  llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
-  const ASTConstraintSatisfaction *Satisfaction = nullptr;
-
-public:
-  friend ASTStmtReader;
-  friend ASTStmtWriter;
-
-  NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
-      Requirement(RK_Nested, /*Dependent=*/false,
-                  /*ContainsUnexpandedParameterPack*/false,
-                  /*Satisfied=*/false), Value(SubstDiag) {}
-
-  NestedRequirement(Expr *Constraint) :
-      Requirement(RK_Nested, /*Dependent=*/true,
-                  Constraint->containsUnexpandedParameterPack()),
-      Value(Constraint) {
-    assert(Constraint->isInstantiationDependent() &&
-           "Nested requirement with non-dependent constraint must be "
-           "constructed with a ConstraintSatisfaction object");
-  }
-
-  NestedRequirement(ASTContext &C, Expr *Constraint,
-                    const ConstraintSatisfaction &Satisfaction) :
-      Requirement(RK_Nested, Constraint->isInstantiationDependent(),
-                  Constraint->containsUnexpandedParameterPack(),
-                  Satisfaction.IsSatisfied),
-      Value(Constraint),
-      Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
-
-  bool isSubstitutionFailure() const {
-    return Value.is<SubstitutionDiagnostic *>();
-  }
-
-  SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
-    assert(isSubstitutionFailure() &&
-           "getSubstitutionDiagnostic() may not be called when there was no "
-           "substitution failure.");
-    return Value.get<SubstitutionDiagnostic *>();
-  }
-
-  Expr *getConstraintExpr() const {
-    assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called "
-                                       "on nested requirements with "
-                                       "substitution failures.");
-    return Value.get<Expr *>();
-  }
-
-  const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
-    assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be "
-                                       "called on nested requirements with "
-                                       "substitution failures.");
-    return *Satisfaction;
-  }
-
-  static bool classof(const Requirement *R) {
-    return R->getKind() == RK_Nested;
-  }
-};
-
-} // namespace concepts
-
-/// C++2a [expr.prim.req]:
-///     A requires-expression provides a concise way to express requirements on
-///     template arguments. A requirement is one that can be checked by name
-///     lookup (6.4) or by checking properties of types and expressions.
-///     [...]
-///     A requires-expression is a prvalue of type bool [...]
-class RequiresExpr final : public Expr,
-    llvm::TrailingObjects<RequiresExpr, ParmVarDecl *,
-                          concepts::Requirement *> {
-  friend TrailingObjects;
-  friend class ASTStmtReader;
-
-  unsigned NumLocalParameters;
-  unsigned NumRequirements;
-  RequiresExprBodyDecl *Body;
-  SourceLocation RBraceLoc;
-
-  unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
-    return NumLocalParameters;
-  }
-
-  unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const {
-    return NumRequirements;
-  }
-
-  RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
-               RequiresExprBodyDecl *Body,
-               ArrayRef<ParmVarDecl *> LocalParameters,
-               ArrayRef<concepts::Requirement *> Requirements,
-               SourceLocation RBraceLoc);
-  RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
-               unsigned NumRequirements);
-
-public:
-  static RequiresExpr *
-  Create(ASTContext &C, SourceLocation RequiresKWLoc,
-         RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
-         ArrayRef<concepts::Requirement *> Requirements,
-         SourceLocation RBraceLoc);
-  static RequiresExpr *
-  Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
-         unsigned NumRequirements);
-
-  ArrayRef<ParmVarDecl *> getLocalParameters() const {
-    return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters};
-  }
-
-  RequiresExprBodyDecl *getBody() const { return Body; }
-
-  ArrayRef<concepts::Requirement *> getRequirements() const {
-    return {getTrailingObjects<concepts::Requirement *>(), NumRequirements};
-  }
-
-  /// \brief Whether or not the requires clause is satisfied.
-  /// The expression must not be dependent.
-  bool isSatisfied() const {
-    assert(!isValueDependent()
-           && "isSatisfied called on a dependent RequiresExpr");
-    return RequiresExprBits.IsSatisfied;
-  }
-
-  SourceLocation getRequiresKWLoc() const {
-    return RequiresExprBits.RequiresKWLoc;
-  }
-
-  SourceLocation getRBraceLoc() const { return RBraceLoc; }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == RequiresExprClass;
-  }
-
-  SourceLocation getBeginLoc() const LLVM_READONLY {
-    return RequiresExprBits.RequiresKWLoc;
-  }
-  SourceLocation getEndLoc() const LLVM_READONLY {
-    return RBraceLoc;
-  }
-
-  // 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_EXPRCONCEPTS_H
\ No newline at end of file

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 4633122aba48..f8ab8e451d8c 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -23,7 +23,6 @@
 #include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
@@ -2139,8 +2138,6 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
     TRY_TO(TraverseStmt(D->getDefaultArg()));
 })
 
-DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
-
 #undef DEF_TRAVERSE_DECL
 
 // ----------------- Stmt traversal -----------------
@@ -2712,28 +2709,6 @@ DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
   TRY_TO(TraverseConceptReference(*S));
 })
 
-DEF_TRAVERSE_STMT(RequiresExpr, {
-  TRY_TO(TraverseDecl(S->getBody()));
-  for (ParmVarDecl *Parm : S->getLocalParameters())
-    TRY_TO(TraverseDecl(Parm));
-  for (concepts::Requirement *Req : S->getRequirements())
-    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
-      if (!TypeReq->isSubstitutionFailure())
-        TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc()));
-    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
-      if (!ExprReq->isExprSubstitutionFailure())
-        TRY_TO(TraverseStmt(ExprReq->getExpr()));
-      auto &RetReq = ExprReq->getReturnTypeRequirement();
-      if (RetReq.isTypeConstraint())
-        TRY_TO(TraverseTemplateParameterListHelper(
-                   RetReq.getTypeConstraintTemplateParameterList()));
-    } else {
-      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
-      if (!NestedReq->isSubstitutionFailure())
-        TRY_TO(TraverseStmt(NestedReq->getConstraintExpr()));
-    }
-})
-
 // These literals (all of them) do not need any action.
 DEF_TRAVERSE_STMT(IntegerLiteral, {})
 DEF_TRAVERSE_STMT(FixedPointLiteral, {})

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 253b76941991..eaacb1a5b252 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -910,17 +910,6 @@ class alignas(void *) Stmt {
     SourceLocation NameLoc;
   };
 
-  class RequiresExprBitfields {
-    friend class ASTStmtReader;
-    friend class ASTStmtWriter;
-    friend class RequiresExpr;
-
-    unsigned : NumExprBits;
-
-    unsigned IsSatisfied : 1;
-    SourceLocation RequiresKWLoc;
-  };
-
   //===--- C++ Coroutines TS bitfields classes ---===//
 
   class CoawaitExprBitfields {
@@ -1019,7 +1008,6 @@ class alignas(void *) Stmt {
     UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
     CXXNoexceptExprBitfields CXXNoexceptExprBits;
     SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
-    RequiresExprBitfields RequiresExprBits;
 
     // C++ Coroutines TS expressions
     CoawaitExprBitfields CoawaitBits;

diff  --git a/clang/include/clang/AST/StmtVisitor.h b/clang/include/clang/AST/StmtVisitor.h
index 3e5155199eac..d3be93d228cc 100644
--- a/clang/include/clang/AST/StmtVisitor.h
+++ b/clang/include/clang/AST/StmtVisitor.h
@@ -13,7 +13,6 @@
 #ifndef LLVM_CLANG_AST_STMTVISITOR_H
 #define LLVM_CLANG_AST_STMTVISITOR_H
 
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"

diff  --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td
index d5bbc604819f..c2c23237285b 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -100,6 +100,5 @@ def OMPThreadPrivate : DeclNode<Decl>;
 def OMPAllocate : DeclNode<Decl>;
 def OMPRequires : DeclNode<Decl>;
 def Empty : DeclNode<Decl>;
-def RequiresExprBody : DeclNode<Decl>, DeclContext;
 def LifetimeExtendedTemporary : DeclNode<Decl>;
 

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 105ed7bf6c84..41f788e7d9bd 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -744,33 +744,6 @@ def err_friend_explicit_instantiation : Error<
 def err_explicit_instantiation_enum : Error<
   "enumerations cannot be explicitly instantiated">;
 def err_expected_template_parameter : Error<"expected template parameter">;
-def note_ill_formed_requires_expression_outside_template : Note<
-  "requires expression outside a template declaration may not contain invalid "
-  "types or expressions">;
-def err_empty_requires_expr : Error<
-  "a requires expression must contain at least one requirement">;
-def err_requires_expr_parameter_list_ellipsis : Error<
-  "varargs not allowed in requires expression">;
-def err_requires_expr_type_req_illegal_identifier : Error<
-  "expected identifier or template-id in type requirement">;
-def err_requires_expr_type_req_template_args_on_non_template : Error<
-  "template arguments provided for non-template '%0'">;
-def err_expected_semi_requirement : Error<
-  "expected ';' at end of requirement">;
-def err_requires_expr_missing_arrow : Error<
-  "expected '->' before expression type requirement">;
-def err_requires_expr_expected_type_constraint : Error<
-  "expected concept name with optional arguments">;
-def err_requires_expr_simple_requirement_noexcept : Error<
-  "'noexcept' can only be used in a compound requirement (with '{' '}' around "
-  "the expression)">;
-def err_requires_expr_simple_requirement_unexpected_tok : Error<
-  "unexpected %0 after expression; did you intend to use a compound "
-  "requirement (with '{' '}' around the expression)?">;
-def warn_requires_expr_in_simple_requirement : Warning<
-  "this requires expression will only be checked for syntactic validity; did "
-  "you intend to place it in a nested requirement? (add another 'requires' "
-  "before the expression)">, InGroup<DiagGroup<"requires-expression">>;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a4d042710858..ffa326932a1c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2102,21 +2102,12 @@ def err_auto_not_allowed : Error<
   "|in template argument|in typedef|in type alias|in function return type"
   "|in conversion function type|here|in lambda parameter"
   "|in type allocated by 'new'|in K&R-style function parameter"
-  "|in template parameter|in friend declaration"
-  "|in requires expression parameter}1">;
-def err_auto_not_allowed_in_return_type_requirement : Error<
-  "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed in expression "
-  "type requirement">;
+  "|in template parameter|in friend declaration}1">;
 def err_dependent_deduced_tst : Error<
   "typename specifier refers to "
   "%select{class template|function template|variable template|alias template|"
   "template template parameter|template}0 member in %1; "
   "argument deduction not allowed here">;
-def err_deduced_tst : Error<
-  "typename specifier refers to "
-  "%select{class template|function template|variable template|alias template|"
-  "template template parameter|template}0; argument deduction not allowed "
-  "here">;
 def err_auto_not_allowed_var_inst : Error<
   "'auto' variable template instantiation is not allowed">;
 def err_auto_var_requires_init : Error<
@@ -2599,56 +2590,19 @@ def note_constraints_not_satisfied : Note<
 def note_substituted_constraint_expr_is_ill_formed : Note<
   "because substituted constraint expression is ill-formed%0">;
 def note_atomic_constraint_evaluated_to_false : Note<
-  "%select{and|because}0 '%1' evaluated to false">;
+  "%select{and |because }0'%1' evaluated to false">;
 def note_concept_specialization_constraint_evaluated_to_false : Note<
-  "%select{and|because}0 '%1' evaluated to false">;
+  "%select{and |because }0'%1' evaluated to false">;
 def note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
-  "%select{and|because}0 %1 does not satisfy %2">;
+  "%select{and |because }0%1 does not satisfy %2">;
 def note_atomic_constraint_evaluated_to_false_elaborated : Note<
-  "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">;
+  "%select{and |because }0'%1' (%2 %3 %4) evaluated to false">;
 def err_constrained_virtual_method : Error<
   "virtual function cannot have a requires clause">;
 def err_trailing_requires_clause_on_deduction_guide : Error<
   "deduction guide cannot have a requires clause">;
 def err_reference_to_function_with_unsatisfied_constraints : Error<
   "invalid reference to function %0: constraints not satisfied">;
-def note_requires_expr_ill_formed_expr : Note<
-  "expression is invalid: %0">;
-def note_requires_expr_no_implicit_conversion : Note<
-  "no implicit conversion exists between expression type %0 and expected type "
-  "%1">;
-def err_requires_expr_local_parameter_default_argument : Error<
-  "default arguments not allowed for parameters of a requires expression">;
-def err_requires_expr_parameter_referenced_in_evaluated_context : Error<
-  "constraint variable %0 cannot be used in an evaluated context">;
-def note_expr_requirement_expr_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid: %2">;
-def note_expr_requirement_expr_unknown_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid">;
-def note_expr_requirement_noexcept_not_met : Note<
-  "%select{and|because}0 '%1' may throw an exception">;
-def note_expr_requirement_type_requirement_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid: %2">;
-def note_expr_requirement_type_requirement_unknown_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid">;
-def note_expr_requirement_constraints_not_satisfied : Note<
-  "%select{and|because}0 type constraint '%1' was not satisfied:">;
-def note_expr_requirement_constraints_not_satisfied_simple : Note<
-  "%select{and|because}0 %1 does not satisfy %2:">;
-def note_type_requirement_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid: %2">;
-def note_type_requirement_unknown_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid">;
-def err_type_requirement_non_type_template : Error<
-  "'%0' refers to a %select{class template|function template|"
-  "variable template|alias template|template template parameter|template}1, "
-  "not a type template">;
-def err_type_requirement_no_such_type : Error<
-  "'%0' does not name a type">;
-def note_nested_requirement_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid: %2">;
-def note_nested_requirement_unknown_substitution_error : Note<
-  "%select{and|because}0 '%1' would be invalid">;
 def note_ambiguous_atomic_constraints : Note<
   "similar constraint expressions not considered equivalent; constraint "
   "expressions cannot be considered equivalent unless they originate from the "
@@ -4634,8 +4588,6 @@ def note_template_type_alias_instantiation_here : Note<
   "in instantiation of template type alias %0 requested here">;
 def note_template_exception_spec_instantiation_here : Note<
   "in instantiation of exception specification for %0 requested here">;
-def note_template_requirement_instantiation_here : Note<
-  "in instantiation of requirement here">;
 def warn_var_template_missing : Warning<"instantiation of variable %q0 "
   "required here, but no definition is available">,
   InGroup<UndefinedVarTemplate>;
@@ -4671,8 +4623,6 @@ 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_nested_requirement_here : Note<
-  "while checking the satisfaction of nested requirement requested here">;
 def note_checking_constraints_for_template_id_here : Note<
   "while checking constraint satisfaction for template '%0' required here">;
 def note_checking_constraints_for_var_spec_id_here : Note<
@@ -4806,12 +4756,8 @@ def err_typename_nested_not_found_requirement : Error<
   "declaration">;
 def err_typename_nested_not_type : Error<
     "typename specifier refers to non-type member %0 in %1">;
-def err_typename_not_type : Error<
-    "typename specifier refers to non-type %0">;
-def note_typename_member_refers_here : Note<
-    "referenced member %0 is declared here">;
 def note_typename_refers_here : Note<
-    "referenced %0 is declared here">;
+    "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
 def err_typename_missing_template : Error<

diff  --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 41923cddc493..294993298a18 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -164,7 +164,6 @@ def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
 
 // C++2a Concepts expressions
 def ConceptSpecializationExpr : StmtNode<Expr>;
-def RequiresExpr : StmtNode<Expr>;
 
 // Obj-C Expressions.
 def ObjCStringLiteral : StmtNode<Expr>;

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 41f46861d089..182024ea5108 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1933,7 +1933,6 @@ class Parser : public CodeCompletionHandler {
   //===--------------------------------------------------------------------===//
   // C++ Concepts
 
-  ExprResult ParseRequiresExpression();
   void ParseTrailingRequiresClause(Declarator &D);
 
   //===--------------------------------------------------------------------===//
@@ -2772,7 +2771,7 @@ class Parser : public CodeCompletionHandler {
          Declarator &D,
          SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
   void ParseParameterDeclarationClause(
-         DeclaratorContext DeclaratorContext,
+         Declarator &D,
          ParsedAttributes &attrs,
          SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
          SourceLocation &EllipsisLoc);

diff  --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 1222549161e4..aceec9cbe1c9 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1757,8 +1757,7 @@ enum class DeclaratorContext {
     TemplateArgContext,  // Any template argument (in template argument list).
     TemplateTypeArgContext, // Template type argument (in default argument).
     AliasDeclContext,    // C++11 alias-declaration.
-    AliasTemplateContext, // C++11 alias-declaration template.
-    RequiresExprContext   // C++2a requires-expression.
+    AliasTemplateContext // C++11 alias-declaration template.
 };
 
 
@@ -1982,7 +1981,6 @@ class Declarator {
     case DeclaratorContext::TemplateTypeArgContext:
     case DeclaratorContext::TrailingReturnContext:
     case DeclaratorContext::TrailingReturnVarContext:
-    case DeclaratorContext::RequiresExprContext:
       return true;
     }
     llvm_unreachable("unknown context kind!");
@@ -2005,7 +2003,6 @@ class Declarator {
     case DeclaratorContext::TemplateParamContext:
     case DeclaratorContext::CXXCatchContext:
     case DeclaratorContext::ObjCCatchContext:
-    case DeclaratorContext::RequiresExprContext:
       return true;
 
     case DeclaratorContext::TypeNameContext:
@@ -2042,7 +2039,6 @@ class Declarator {
     case DeclaratorContext::MemberContext:
     case DeclaratorContext::PrototypeContext:
     case DeclaratorContext::TemplateParamContext:
-    case DeclaratorContext::RequiresExprContext:
       // Maybe one day...
       return false;
 
@@ -2120,7 +2116,6 @@ class Declarator {
     case DeclaratorContext::TemplateArgContext:
     case DeclaratorContext::TemplateTypeArgContext:
     case DeclaratorContext::TrailingReturnContext:
-    case DeclaratorContext::RequiresExprContext:
       return false;
     }
     llvm_unreachable("unknown context kind!");
@@ -2342,7 +2337,6 @@ class Declarator {
     case DeclaratorContext::TemplateTypeArgContext:
     case DeclaratorContext::TrailingReturnContext:
     case DeclaratorContext::TrailingReturnVarContext:
-    case DeclaratorContext::RequiresExprContext:
       return false;
     }
     llvm_unreachable("unknown context kind!");
@@ -2376,7 +2370,6 @@ class Declarator {
     case DeclaratorContext::TrailingReturnContext:
     case DeclaratorContext::TrailingReturnVarContext:
     case DeclaratorContext::TemplateTypeArgContext:
-    case DeclaratorContext::RequiresExprContext:
       return false;
 
     case DeclaratorContext::BlockContext:

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2fb758bc75d6..4d76c877d31b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -21,7 +21,6 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExternalASTSource.h"
@@ -6283,17 +6282,13 @@ class Sema final {
 
   /// \brief Emit diagnostics explaining why a constraint expression was deemed
   /// unsatisfied.
-  /// \param First whether this is the first time an unsatisfied constraint is
-  /// diagnosed for this error.
   void
-  DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction,
-                                bool First = true);
+  DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction);
 
   /// \brief Emit diagnostics explaining why a constraint expression was deemed
   /// unsatisfied.
   void
-  DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction,
-                                bool First = true);
+  DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction& Satisfaction);
 
   /// \brief Emit diagnostics explaining why a constraint expression was deemed
   /// unsatisfied because it was ill-formed.
@@ -7267,17 +7262,7 @@ class Sema final {
                              SourceLocation KeywordLoc,
                              NestedNameSpecifierLoc QualifierLoc,
                              const IdentifierInfo &II,
-                             SourceLocation IILoc,
-                             TypeSourceInfo **TSI,
-                             bool DeducedTSTContext);
-
-  QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
-                             SourceLocation KeywordLoc,
-                             NestedNameSpecifierLoc QualifierLoc,
-                             const IdentifierInfo &II,
-                             SourceLocation IILoc,
-                             bool DeducedTSTContext = true);
-
+                             SourceLocation IILoc);
 
   TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
                                                     SourceLocation Loc,
@@ -7297,52 +7282,11 @@ class Sema final {
                                   const TemplateArgument *Args,
                                   unsigned NumArgs);
 
-  //===--------------------------------------------------------------------===//
-  // C++ Concepts
-  //===--------------------------------------------------------------------===//
+  // Concepts
   Decl *ActOnConceptDefinition(
       Scope *S, MultiTemplateParamsArg TemplateParameterLists,
       IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr);
 
-  RequiresExprBodyDecl *
-  ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
-                         ArrayRef<ParmVarDecl *> LocalParameters,
-                         Scope *BodyScope);
-  void ActOnFinishRequiresExpr();
-  concepts::Requirement *ActOnSimpleRequirement(Expr *E);
-  concepts::Requirement *ActOnTypeRequirement(
-      SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc,
-      IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId);
-  concepts::Requirement *ActOnCompoundRequirement(Expr *E,
-                                                  SourceLocation NoexceptLoc);
-  concepts::Requirement *
-  ActOnCompoundRequirement(
-      Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
-      TemplateIdAnnotation *TypeConstraint, unsigned Depth);
-  concepts::Requirement *ActOnNestedRequirement(Expr *Constraint);
-  concepts::ExprRequirement *
-  BuildExprRequirement(
-      Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc,
-      concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement);
-  concepts::ExprRequirement *
-  BuildExprRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag,
-      bool IsSatisfied, SourceLocation NoexceptLoc,
-      concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement);
-  concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type);
-  concepts::TypeRequirement *
-  BuildTypeRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
-  concepts::NestedRequirement *BuildNestedRequirement(Expr *E);
-  concepts::NestedRequirement *
-  BuildNestedRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
-  ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc,
-                               RequiresExprBodyDecl *Body,
-                               ArrayRef<ParmVarDecl *> LocalParameters,
-                               ArrayRef<concepts::Requirement *> Requirements,
-                               SourceLocation ClosingBraceLoc);
-
   //===--------------------------------------------------------------------===//
   // C++ Variadic Templates (C++0x [temp.variadic])
   //===--------------------------------------------------------------------===//
@@ -7989,13 +7933,6 @@ class Sema final {
       /// template which was deferred until it was needed.
       ExceptionSpecInstantiation,
 
-      /// We are instantiating a requirement of a requires expression.
-      RequirementInstantiation,
-
-      /// We are checking the satisfaction of a nested requirement of a requires
-      /// expression.
-      NestedRequirementConstraintsCheck,
-
       /// We are declaring an implicit special member function.
       DeclaringSpecialMember,
 
@@ -8317,19 +8254,6 @@ class Sema final {
                           ParameterMappingSubstitution, NamedDecl *Template,
                           SourceRange InstantiationRange);
 
-    /// \brief Note that we are substituting template arguments into a part of
-    /// a requirement of a requires expression.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          concepts::Requirement *Req,
-                          sema::TemplateDeductionInfo &DeductionInfo,
-                          SourceRange InstantiationRange = SourceRange());
-
-    /// \brief Note that we are checking the satisfaction of the constraint
-    /// expression inside of a nested requirement.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          concepts::NestedRequirement *Req, ConstraintsCheck,
-                          SourceRange InstantiationRange = SourceRange());
-
     /// Note that we have finished instantiating this template.
     void Clear();
 

diff  --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h
index 7fc42a4816ec..acd1e604211a 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -13,17 +13,10 @@
 
 #ifndef LLVM_CLANG_SEMA_SEMACONCEPT_H
 #define LLVM_CLANG_SEMA_SEMACONCEPT_H
-#include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
-#include <string>
-#include <utility>
-
 namespace clang {
 class Sema;
 

diff  --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 44a12c875da7..1bfcbda8c9f1 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1403,9 +1403,6 @@ namespace serialization {
       /// An LifetimeExtendedTemporaryDecl record.
       DECL_LIFETIME_EXTENDED_TEMPORARY,
 
-      /// A RequiresExprBodyDecl record.
-      DECL_REQUIRES_EXPR_BODY,
-
       /// An ObjCTypeParamDecl record.
       DECL_OBJC_TYPE_PARAM,
 
@@ -1788,7 +1785,6 @@ namespace serialization {
       EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
       EXPR_CXX_FOLD,              // CXXFoldExpr
       EXPR_CONCEPT_SPECIALIZATION,// ConceptSpecializationExpr
-      EXPR_REQUIRES,              // RequiresExpr
 
       // CUDA
       EXPR_CUDA_KERNEL_CALL,       // CUDAKernelCallExpr

diff  --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index e79c245d2f8c..bd9b0934591c 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -46,7 +46,6 @@ add_clang_library(clangAST
   DeclTemplate.cpp
   Expr.cpp
   ExprClassification.cpp
-  ExprConcepts.cpp
   ExprConstant.cpp
   ExprCXX.cpp
   ExprObjC.cpp

diff  --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index cb4d61cac2c7..6ee767ccecf7 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -804,7 +804,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
     case OMPCapturedExpr:
     case Empty:
     case LifetimeExtendedTemporary:
-    case RequiresExprBody:
       // Never looked up by name.
       return 0;
   }
@@ -1178,7 +1177,6 @@ DeclContext *DeclContext::getPrimaryContext() {
   case Decl::Captured:
   case Decl::OMPDeclareReduction:
   case Decl::OMPDeclareMapper:
-  case Decl::RequiresExprBody:
     // There is only one DeclContext for these entities.
     return this;
 

diff  --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 48e310e858b2..2ead1e70ea0d 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1968,16 +1968,6 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C,
       QualType(), nullptr, SourceLocation());
 }
 
-RequiresExprBodyDecl *RequiresExprBodyDecl::Create(
-    ASTContext &C, DeclContext *DC, SourceLocation StartLoc) {
-  return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc);
-}
-
-RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C,
-                                                               unsigned ID) {
-  return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation());
-}
-
 void CXXMethodDecl::anchor() {}
 
 bool CXXMethodDecl::isStatic() const {

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 835198958766..73ddbc62482d 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3457,7 +3457,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
   case OpaqueValueExprClass:
   case SourceLocExprClass:
   case ConceptSpecializationExprClass:
-  case RequiresExprClass:
     // These never have a side-effect.
     return false;
 

diff  --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e4bd218ae2d3..422227d787b1 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -17,7 +17,6 @@
 #include "clang/AST/DeclAccessPair.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/LambdaCapture.h"
@@ -1765,3 +1764,81 @@ CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
                            alignof(CUDAKernelCallExpr));
   return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
 }
+
+ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext &C,
+    NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
+    DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
+    ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten,
+    ArrayRef<TemplateArgument> ConvertedArgs,
+    const ConstraintSatisfaction *Satisfaction)
+    : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
+           /*TypeDependent=*/false,
+           // All the flags below are set in setTemplateArguments.
+           /*ValueDependent=*/!Satisfaction, /*InstantiationDependent=*/false,
+           /*ContainsUnexpandedParameterPacks=*/false),
+      ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl,
+                       NamedConcept, ArgsAsWritten),
+      NumTemplateArgs(ConvertedArgs.size()),
+      Satisfaction(Satisfaction ?
+                   ASTConstraintSatisfaction::Create(C, *Satisfaction) :
+                   nullptr) {
+  setTemplateArguments(ConvertedArgs);
+}
+
+ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty,
+    unsigned NumTemplateArgs)
+    : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(),
+      NumTemplateArgs(NumTemplateArgs) { }
+
+void ConceptSpecializationExpr::setTemplateArguments(
+    ArrayRef<TemplateArgument> Converted) {
+  assert(Converted.size() == NumTemplateArgs);
+  std::uninitialized_copy(Converted.begin(), Converted.end(),
+                          getTrailingObjects<TemplateArgument>());
+  bool IsInstantiationDependent = false;
+  bool ContainsUnexpandedParameterPack = false;
+  for (const TemplateArgument& Arg : Converted) {
+    if (Arg.isInstantiationDependent())
+      IsInstantiationDependent = true;
+    if (Arg.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(const ASTContext &C,
+                                  NestedNameSpecifierLoc NNS,
+                                  SourceLocation TemplateKWLoc,
+                                  DeclarationNameInfo ConceptNameInfo,
+                                  NamedDecl *FoundDecl,
+                                  ConceptDecl *NamedConcept,
+                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
+                                  ArrayRef<TemplateArgument> ConvertedArgs,
+                                  const ConstraintSatisfaction *Satisfaction) {
+  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
+                                ConvertedArgs.size()));
+  return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
+                                                ConceptNameInfo, FoundDecl,
+                                                NamedConcept, ArgsAsWritten,
+                                                ConvertedArgs, Satisfaction);
+}
+
+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/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index d201af31f521..9dbf6fe9e0f0 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -193,7 +193,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
   case Expr::DesignatedInitUpdateExprClass:
   case Expr::SourceLocExprClass:
   case Expr::ConceptSpecializationExprClass:
-  case Expr::RequiresExprClass:
     return Cl::CL_PRValue;
 
   case Expr::ConstantExprClass:

diff  --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
deleted file mode 100644
index 76d57ed5d5b1..000000000000
--- a/clang/lib/AST/ExprConcepts.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-//===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the subclesses of Expr class declared in ExprCXX.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ExprConcepts.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConcept.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <algorithm>
-#include <utility>
-#include <string>
-
-using namespace clang;
-
-ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext &C,
-    NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
-    DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
-    ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten,
-    ArrayRef<TemplateArgument> ConvertedArgs,
-    const ConstraintSatisfaction *Satisfaction)
-    : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
-           /*TypeDependent=*/false,
-           // All the flags below are set in setTemplateArguments.
-           /*ValueDependent=*/!Satisfaction, /*InstantiationDependent=*/false,
-           /*ContainsUnexpandedParameterPacks=*/false),
-      ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl,
-                       NamedConcept, ArgsAsWritten),
-      NumTemplateArgs(ConvertedArgs.size()),
-      Satisfaction(Satisfaction ?
-                   ASTConstraintSatisfaction::Create(C, *Satisfaction) :
-                   nullptr) {
-  setTemplateArguments(ConvertedArgs);
-}
-
-ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty,
-    unsigned NumTemplateArgs)
-    : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(),
-      NumTemplateArgs(NumTemplateArgs) { }
-
-void ConceptSpecializationExpr::setTemplateArguments(
-    ArrayRef<TemplateArgument> Converted) {
-  assert(Converted.size() == NumTemplateArgs);
-  std::uninitialized_copy(Converted.begin(), Converted.end(),
-                          getTrailingObjects<TemplateArgument>());
-  bool IsInstantiationDependent = false;
-  bool ContainsUnexpandedParameterPack = false;
-  for (const TemplateArgument& Arg : Converted) {
-    if (Arg.isInstantiationDependent())
-      IsInstantiationDependent = true;
-    if (Arg.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(const ASTContext &C,
-                                  NestedNameSpecifierLoc NNS,
-                                  SourceLocation TemplateKWLoc,
-                                  DeclarationNameInfo ConceptNameInfo,
-                                  NamedDecl *FoundDecl,
-                                  ConceptDecl *NamedConcept,
-                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
-                                  ArrayRef<TemplateArgument> ConvertedArgs,
-                                  const ConstraintSatisfaction *Satisfaction) {
-  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
-                                ConvertedArgs.size()));
-  return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
-                                                ConceptNameInfo, FoundDecl,
-                                                NamedConcept, ArgsAsWritten,
-                                                ConvertedArgs, Satisfaction);
-}
-
-ConceptSpecializationExpr *
-ConceptSpecializationExpr::Create(ASTContext &C, EmptyShell Empty,
-                                  unsigned NumTemplateArgs) {
-  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
-                                NumTemplateArgs));
-  return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
-}
-
-const TypeConstraint *
-concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
-  assert(isTypeConstraint());
-  auto TPL =
-      TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
-  return cast<TemplateTypeParmDecl>(TPL->getParam(0))
-      ->getTypeConstraint();
-}
-
-RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
-                           RequiresExprBodyDecl *Body,
-                           ArrayRef<ParmVarDecl *> LocalParameters,
-                           ArrayRef<concepts::Requirement *> Requirements,
-                           SourceLocation RBraceLoc)
-  : Expr(RequiresExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
-         /*TD=*/false, /*VD=*/false, /*ID=*/false,
-         /*ContainsUnexpandedParameterPack=*/false),
-    NumLocalParameters(LocalParameters.size()),
-    NumRequirements(Requirements.size()), Body(Body), RBraceLoc(RBraceLoc) {
-  RequiresExprBits.IsSatisfied = false;
-  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
-  bool Dependent = false;
-  bool ContainsUnexpandedParameterPack = false;
-  for (ParmVarDecl *P : LocalParameters) {
-    Dependent |= P->getType()->isInstantiationDependentType();
-    ContainsUnexpandedParameterPack |=
-        P->getType()->containsUnexpandedParameterPack();
-  }
-  RequiresExprBits.IsSatisfied = true;
-  for (concepts::Requirement *R : Requirements) {
-    Dependent |= R->isDependent();
-    ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();
-    if (!Dependent) {
-      RequiresExprBits.IsSatisfied = R->isSatisfied();
-      if (!RequiresExprBits.IsSatisfied)
-        break;
-    }
-  }
-  std::copy(LocalParameters.begin(), LocalParameters.end(),
-            getTrailingObjects<ParmVarDecl *>());
-  std::copy(Requirements.begin(), Requirements.end(),
-            getTrailingObjects<concepts::Requirement *>());
-  RequiresExprBits.IsSatisfied |= Dependent;
-  setValueDependent(Dependent);
-  setInstantiationDependent(Dependent);
-  setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
-}
-
-RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
-                           unsigned NumLocalParameters,
-                           unsigned NumRequirements)
-  : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),
-    NumRequirements(NumRequirements) { }
-
-RequiresExpr *
-RequiresExpr::Create(ASTContext &C, SourceLocation RequiresKWLoc,
-                     RequiresExprBodyDecl *Body,
-                     ArrayRef<ParmVarDecl *> LocalParameters,
-                     ArrayRef<concepts::Requirement *> Requirements,
-                     SourceLocation RBraceLoc) {
-  void *Mem =
-      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
-                     LocalParameters.size(), Requirements.size()),
-                 alignof(RequiresExpr));
-  return new (Mem) RequiresExpr(C, RequiresKWLoc, Body, LocalParameters,
-                                Requirements, RBraceLoc);
-}
-
-RequiresExpr *
-RequiresExpr::Create(ASTContext &C, EmptyShell Empty,
-                     unsigned NumLocalParameters, unsigned NumRequirements) {
-  void *Mem =
-      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
-                     NumLocalParameters, NumRequirements),
-                 alignof(RequiresExpr));
-  return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
-}

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c79973507323..c4b27b5d1daa 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -9912,7 +9912,6 @@ class IntExprEvaluator
   bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
-  bool VisitRequiresExpr(const RequiresExpr *E);
   // FIXME: Missing: array subscript of vector, member of vector
 };
 
@@ -12525,9 +12524,6 @@ bool IntExprEvaluator::VisitConceptSpecializationExpr(
   return Success(E->isSatisfied(), E);
 }
 
-bool IntExprEvaluator::VisitRequiresExpr(const RequiresExpr *E) {
-  return Success(E->isSatisfied(), E);
-}
 
 bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
   switch (E->getOpcode()) {
@@ -14186,7 +14182,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::CXXScalarValueInitExprClass:
   case Expr::TypeTraitExprClass:
   case Expr::ConceptSpecializationExprClass:
-  case Expr::RequiresExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::CXXNoexceptExprClass:

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 5d485e000750..0d567edac521 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -22,7 +22,6 @@
 #include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
@@ -3669,7 +3668,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
   case Expr::ConvertVectorExprClass:
   case Expr::StmtExprClass:
   case Expr::TypeTraitExprClass:
-  case Expr::RequiresExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::VAArgExprClass:

diff  --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 7409ae7ddc9e..b6e4d8aff21e 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -16,7 +16,6 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"

diff  --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 45fd8ceae8d3..c14bb886bb11 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2269,60 +2269,6 @@ void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
                             Policy);
 }
 
-void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
-  OS << "requires ";
-  auto LocalParameters = E->getLocalParameters();
-  if (!LocalParameters.empty()) {
-    OS << "(";
-    for (ParmVarDecl *LocalParam : LocalParameters) {
-      PrintRawDecl(LocalParam);
-      if (LocalParam != LocalParameters.back())
-        OS << ", ";
-    }
-
-    OS << ") ";
-  }
-  OS << "{ ";
-  auto Requirements = E->getRequirements();
-  for (concepts::Requirement *Req : Requirements) {
-    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
-      if (TypeReq->isSubstitutionFailure())
-        OS << "<<error-type>>";
-      else
-        TypeReq->getType()->getType().print(OS, Policy);
-    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
-      if (ExprReq->isCompound())
-        OS << "{ ";
-      if (ExprReq->isExprSubstitutionFailure())
-        OS << "<<error-expression>>";
-      else
-        PrintExpr(ExprReq->getExpr());
-      if (ExprReq->isCompound()) {
-        OS << " }";
-        if (ExprReq->getNoexceptLoc().isValid())
-          OS << " noexcept";
-        const auto &RetReq = ExprReq->getReturnTypeRequirement();
-        if (!RetReq.isEmpty()) {
-          OS << " -> ";
-          if (RetReq.isSubstitutionFailure())
-            OS << "<<error-type>>";
-          else if (RetReq.isTypeConstraint())
-            RetReq.getTypeConstraint()->print(OS, Policy);
-        }
-      }
-    } else {
-      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
-      OS << "requires ";
-      if (NestedReq->isSubstitutionFailure())
-        OS << "<<error-expression>>";
-      else
-        PrintExpr(NestedReq->getConstraintExpr());
-    }
-    OS << "; ";
-  }
-  OS << "}";
-}
-
 // C++ Coroutines TS
 
 void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {

diff  --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 382ea5c8d7ef..c0b0f3b0b064 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1340,49 +1340,6 @@ void StmtProfiler::VisitConceptSpecializationExpr(
     VisitTemplateArgument(Arg);
 }
 
-void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
-  VisitExpr(S);
-  ID.AddInteger(S->getLocalParameters().size());
-  for (ParmVarDecl *LocalParam : S->getLocalParameters())
-    VisitDecl(LocalParam);
-  ID.AddInteger(S->getRequirements().size());
-  for (concepts::Requirement *Req : S->getRequirements()) {
-    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
-      ID.AddInteger(concepts::Requirement::RK_Type);
-      ID.AddBoolean(TypeReq->isSubstitutionFailure());
-      if (!TypeReq->isSubstitutionFailure())
-        VisitType(TypeReq->getType()->getType());
-    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
-      ID.AddInteger(concepts::Requirement::RK_Compound);
-      ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
-      if (!ExprReq->isExprSubstitutionFailure())
-        Visit(ExprReq->getExpr());
-      // C++2a [expr.prim.req.compound]p1 Example:
-      //    [...] The compound-requirement in C1 requires that x++ is a valid
-      //    expression. It is equivalent to the simple-requirement x++; [...]
-      // We therefore do not profile isSimple() here.
-      ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
-      const concepts::ExprRequirement::ReturnTypeRequirement &RetReq =
-          ExprReq->getReturnTypeRequirement();
-      if (RetReq.isEmpty()) {
-        ID.AddInteger(0);
-      } else if (RetReq.isTypeConstraint()) {
-        ID.AddInteger(1);
-        Visit(RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint());
-      } else {
-        assert(RetReq.isSubstitutionFailure());
-        ID.AddInteger(2);
-      }
-    } else {
-      ID.AddInteger(concepts::Requirement::RK_Nested);
-      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
-      ID.AddBoolean(NestedReq->isSubstitutionFailure());
-      if (!NestedReq->isSubstitutionFailure())  
-        Visit(NestedReq->getConstraintExpr());
-    }
-  }
-}
-
 static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
                                           UnaryOperatorKind &UnaryOp,
                                           BinaryOperatorKind &BinaryOp) {

diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 60f1dba7c768..5aac7a8d54c7 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -111,7 +111,6 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
   case Decl::Empty:
   case Decl::Concept:
   case Decl::LifetimeExtendedTemporary:
-  case Decl::RequiresExprBody:
     // None of these decls require codegen support.
     return;
 

diff  --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index de5c3a03fb68..3f23fe11e4f5 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -680,10 +680,6 @@ class ScalarExprEmitter
     return Builder.getInt1(E->isSatisfied());
   }
 
-  Value *VisitRequiresExpr(const RequiresExpr *E) {
-    return Builder.getInt1(E->isSatisfied());
-  }
-
   Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
     return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
   }

diff  --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 935c64a0fa13..8574d0a7e813 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -429,10 +429,6 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
       return "ConstraintNormalization";
     case CodeSynthesisContext::ParameterMappingSubstitution:
       return "ParameterMappingSubstitution";
-    case CodeSynthesisContext::RequirementInstantiation:
-      return "RequirementInstantiation";
-    case CodeSynthesisContext::NestedRequirementConstraintsCheck:
-      return "NestedRequirementConstraintsCheck";
     }
     return "";
   }

diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 42e6fd88515a..2c7e3a56c043 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -385,9 +385,6 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
     else
       Builder.defineMacro("__cplusplus", "199711L");
 
-    if (LangOpts.ConceptsTS)
-      Builder.defineMacro("__cpp_concepts", "201707L");
-
     // C++1z [cpp.predefined]p1:
     //   An integer literal of type std::size_t whose value is the alignment
     //   guaranteed by a call to operator new(std::size_t)

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 178cb1b661c7..192c0e99e5a5 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6366,7 +6366,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
     ProhibitAttributes(FnAttrs);
   } else {
     if (Tok.isNot(tok::r_paren))
-      ParseParameterDeclarationClause(D.getContext(), FirstArgAttrs, ParamInfo,
+      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
                                       EllipsisLoc);
     else if (RequiresArg)
       Diag(Tok, diag::err_argument_required_after_attribute);
@@ -6584,9 +6584,9 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
 /// after the opening parenthesis. This function will not parse a K&R-style
 /// identifier list.
 ///
-/// DeclContext is the context of the declarator being parsed.  If FirstArgAttrs
-/// is non-null, then the caller parsed those attributes immediately after the
-/// open paren - they should be considered to be part of the first parameter.
+/// D is the declarator being parsed.  If FirstArgAttrs is non-null, then the
+/// caller parsed those arguments immediately after the open paren - they should
+/// be considered to be part of the first parameter.
 ///
 /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
 /// be the location of the ellipsis, if any was parsed.
@@ -6612,7 +6612,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
 /// [C++11] attribute-specifier-seq parameter-declaration
 ///
 void Parser::ParseParameterDeclarationClause(
-       DeclaratorContext DeclaratorContext,
+       Declarator &D,
        ParsedAttributes &FirstArgAttrs,
        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
        SourceLocation &EllipsisLoc) {
@@ -6661,11 +6661,9 @@ void Parser::ParseParameterDeclarationClause(
     // "LambdaExprParameterContext", because we must accept either
     // 'declarator' or 'abstract-declarator' here.
     Declarator ParmDeclarator(
-        DS, DeclaratorContext == DeclaratorContext::RequiresExprContext
-                ? DeclaratorContext::RequiresExprContext
-                : DeclaratorContext == DeclaratorContext::LambdaExprContext
-                      ? DeclaratorContext::LambdaExprParameterContext
-                      : DeclaratorContext::PrototypeContext);
+        DS, D.getContext() == DeclaratorContext::LambdaExprContext
+                ? DeclaratorContext::LambdaExprParameterContext
+                : DeclaratorContext::PrototypeContext);
     ParseDeclarator(ParmDeclarator);
 
     // Parse GNU attributes, if present.
@@ -6719,7 +6717,7 @@ void Parser::ParseParameterDeclarationClause(
         SourceLocation EqualLoc = Tok.getLocation();
 
         // Parse the default argument
-        if (DeclaratorContext == DeclaratorContext::MemberContext) {
+        if (D.getContext() == DeclaratorContext::MemberContext) {
           // If we're inside a class definition, cache the tokens
           // corresponding to the default argument. We'll actually parse
           // them when we see the end of the class definition.

diff  --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index df8388926db1..32dacbcc9646 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -756,7 +756,6 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback {
 /// [C++11] user-defined-literal
 ///         '(' expression ')'
 /// [C11]   generic-selection
-/// [C++2a] requires-expression
 ///         '__func__'        [C99 6.4.2.2]
 /// [GNU]   '__FUNCTION__'
 /// [MS]    '__FUNCDNAME__'
@@ -1602,9 +1601,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
       *NotPrimaryExpression = true;
     return ParseCXXDeleteExpression(false, Tok.getLocation());
 
-  case tok::kw_requires: // [C++2a] requires-expression
-    return ParseRequiresExpression();
-
   case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')'
     if (NotPrimaryExpression)
       *NotPrimaryExpression = true;

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 036eabb94dd7..7d477d271dc2 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -11,9 +11,7 @@
 //===----------------------------------------------------------------------===//
 #include "clang/Parse/Parser.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -1301,9 +1299,9 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
       Actions.RecordParsingTemplateParameterDepth(
           CurTemplateDepthTracker.getOriginalDepth());
 
-      ParseParameterDeclarationClause(D.getContext(), Attr, ParamInfo,
-                                      EllipsisLoc);
-      // For a generic lambda, each 'auto' within the parameter declaration 
+      ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
+
+      // For a generic lambda, each 'auto' within the parameter declaration
       // clause creates a template type parameter, so increment the depth.
       // If we've parsed any explicit template parameters, then the depth will
       // have already been incremented. So we make sure that at most a single
@@ -3257,324 +3255,6 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
   return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());
 }
 
-/// ParseRequiresExpression - Parse a C++2a requires-expression.
-/// C++2a [expr.prim.req]p1
-///     A requires-expression provides a concise way to express requirements on
-///     template arguments. A requirement is one that can be checked by name
-///     lookup (6.4) or by checking properties of types and expressions.
-///
-///     requires-expression:
-///         'requires' requirement-parameter-list[opt] requirement-body
-///
-///     requirement-parameter-list:
-///         '(' parameter-declaration-clause[opt] ')'
-///
-///     requirement-body:
-///         '{' requirement-seq '}'
-///
-///     requirement-seq:
-///         requirement
-///         requirement-seq requirement
-///
-///     requirement:
-///         simple-requirement
-///         type-requirement
-///         compound-requirement
-///         nested-requirement
-ExprResult Parser::ParseRequiresExpression() {
-  assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");
-  SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires'
-
-  llvm::SmallVector<ParmVarDecl *, 2> LocalParameterDecls;
-  if (Tok.is(tok::l_paren)) {
-    // requirement parameter list is present.
-    ParseScope LocalParametersScope(this, Scope::FunctionPrototypeScope |
-                                    Scope::DeclScope);
-    BalancedDelimiterTracker Parens(*this, tok::l_paren);
-    Parens.consumeOpen();
-    if (!Tok.is(tok::r_paren)) {
-      ParsedAttributes FirstArgAttrs(getAttrFactory());
-      SourceLocation EllipsisLoc;
-      llvm::SmallVector<DeclaratorChunk::ParamInfo, 2> LocalParameters;
-      DiagnosticErrorTrap Trap(Diags);
-      ParseParameterDeclarationClause(DeclaratorContext::RequiresExprContext,
-                                      FirstArgAttrs, LocalParameters,
-                                      EllipsisLoc);
-      if (EllipsisLoc.isValid())
-        Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis);
-      for (auto &ParamInfo : LocalParameters)
-        LocalParameterDecls.push_back(cast<ParmVarDecl>(ParamInfo.Param));
-      if (Trap.hasErrorOccurred())
-        SkipUntil(tok::r_paren, StopBeforeMatch);
-    }
-    Parens.consumeClose();
-  }
-
-  BalancedDelimiterTracker Braces(*this, tok::l_brace);
-  if (Braces.expectAndConsume())
-    return ExprError();
-
-  // Start of requirement list
-  llvm::SmallVector<concepts::Requirement *, 2> Requirements;
-
-  // C++2a [expr.prim.req]p2
-  //   Expressions appearing within a requirement-body are unevaluated operands.
-  EnterExpressionEvaluationContext Ctx(
-      Actions, Sema::ExpressionEvaluationContext::Unevaluated);
-
-  ParseScope BodyScope(this, Scope::DeclScope);
-  RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(
-      RequiresKWLoc, LocalParameterDecls, getCurScope());
-
-  if (Tok.is(tok::r_brace)) {
-    // Grammar does not allow an empty body.
-    // requirement-body:
-    //   { requirement-seq }
-    // requirement-seq:
-    //   requirement
-    //   requirement-seq requirement
-    Diag(Tok, diag::err_empty_requires_expr);
-    // Continue anyway and produce a requires expr with no requirements.
-  } else {
-    while (!Tok.is(tok::r_brace)) {
-      switch (Tok.getKind()) {
-      case tok::l_brace: {
-        // Compound requirement
-        // C++ [expr.prim.req.compound]
-        //     compound-requirement:
-        //         '{' expression '}' 'noexcept'[opt]
-        //             return-type-requirement[opt] ';'
-        //     return-type-requirement:
-        //         trailing-return-type
-        //         '->' cv-qualifier-seq[opt] constrained-parameter
-        //             cv-qualifier-seq[opt] abstract-declarator[opt]
-        BalancedDelimiterTracker ExprBraces(*this, tok::l_brace);
-        ExprBraces.consumeOpen();
-        ExprResult Expression =
-            Actions.CorrectDelayedTyposInExpr(ParseExpression());
-        if (!Expression.isUsable()) {
-          ExprBraces.skipToEnd();
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        if (ExprBraces.consumeClose())
-          ExprBraces.skipToEnd();
-
-        concepts::Requirement *Req = nullptr;
-        SourceLocation NoexceptLoc;
-        TryConsumeToken(tok::kw_noexcept, NoexceptLoc);
-        if (Tok.is(tok::semi)) {
-          Req = Actions.ActOnCompoundRequirement(Expression.get(), NoexceptLoc);
-          if (Req)
-            Requirements.push_back(Req);
-          break;
-        }
-        if (!TryConsumeToken(tok::arrow))
-          // User probably forgot the arrow, remind them and try to continue.
-          Diag(Tok, diag::err_requires_expr_missing_arrow)
-              << FixItHint::CreateInsertion(Tok.getLocation(), "->");
-        // Try to parse a 'type-constraint'
-        CXXScopeSpec SS;
-        if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
-                                           /*EnteringContext=*/false,
-                                           /*MayBePseudoDestructor=*/nullptr,
-                                           // If this is not a type-constraint,
-                                           // then this scope-spec is part of
-                                           // the typename of a non-type
-                                           // template parameter
-                                           /*IsTypename=*/true,
-                                           /*LastII=*/nullptr,
-                                           // We won't find concepts in
-                                           // non-namespaces anyway, so might as
-                                           // well parse this correctly for
-                                           // possible type names.
-                                           /*OnlyNamespace=*/false,
-                                           /*SuppressDiagnostic=*/true)) {
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        if (TryAnnotateTypeConstraint()) {
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        if (!isTypeConstraintAnnotation()) {
-          Diag(Tok, diag::err_requires_expr_expected_type_constraint);
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        if (Tok.is(tok::annot_cxxscope))
-          ConsumeAnnotationToken();
-
-        Req = Actions.ActOnCompoundRequirement(
-            Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok),
-            TemplateParameterDepth);
-        ConsumeAnnotationToken();
-        if (Req)
-          Requirements.push_back(Req);
-        break;
-      }
-      default: {
-        bool PossibleRequiresExprInSimpleRequirement = false;
-        if (Tok.is(tok::kw_requires)) {
-          auto IsNestedRequirement = [&] {
-            RevertingTentativeParsingAction TPA(*this);
-            ConsumeToken(); // 'requires'
-            if (Tok.is(tok::l_brace))
-              // This is a requires expression
-              // requires (T t) {
-              //   requires { t++; };
-              //   ...      ^
-              // }
-              return false;
-            if (Tok.is(tok::l_paren)) {
-              // This might be the parameter list of a requires expression
-              ConsumeParen();
-              auto Res = TryParseParameterDeclarationClause();
-              if (Res != TPResult::False) {
-                // Skip to the closing parenthesis
-                // FIXME: Don't traverse these tokens twice (here and in
-                //  TryParseParameterDeclarationClause).
-                unsigned Depth = 1;
-                while (Depth != 0) {
-                  if (Tok.is(tok::l_paren))
-                    Depth++;
-                  else if (Tok.is(tok::r_paren))
-                    Depth--;
-                  ConsumeAnyToken();
-                }
-                // requires (T t) {
-                //   requires () ?
-                //   ...         ^
-                //   - OR -
-                //   requires (int x) ?
-                //   ...              ^
-                // }
-                if (Tok.is(tok::l_brace))
-                  // requires (...) {
-                  //                ^ - a requires expression as a
-                  //                    simple-requirement.
-                  return false;
-              }
-            }
-            return true;
-          };
-          if (IsNestedRequirement()) {
-            ConsumeToken();
-            // Nested requirement
-            // C++ [expr.prim.req.nested]
-            //     nested-requirement:
-            //         'requires' constraint-expression ';'
-            ExprResult ConstraintExpr =
-                Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());
-            if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) {
-              SkipUntil(tok::semi, tok::r_brace,
-                        SkipUntilFlags::StopBeforeMatch);
-              break;
-            }
-            if (auto *Req =
-                    Actions.ActOnNestedRequirement(ConstraintExpr.get()))
-              Requirements.push_back(Req);
-            else {
-              SkipUntil(tok::semi, tok::r_brace,
-                        SkipUntilFlags::StopBeforeMatch);
-              break;
-            }
-            break;
-          } else
-            PossibleRequiresExprInSimpleRequirement = true;
-        } else if (Tok.is(tok::kw_typename)) {
-          // This might be 'typename T::value_type;' (a type requirement) or
-          // 'typename T::value_type{};' (a simple requirement).
-          TentativeParsingAction TPA(*this);
-
-          // We need to consume the typename to allow 'requires { typename a; }'
-          SourceLocation TypenameKWLoc = ConsumeToken();
-          if (TryAnnotateCXXScopeToken()) {
-            SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-            break;
-          }
-          CXXScopeSpec SS;
-          if (Tok.is(tok::annot_cxxscope)) {
-            Actions.RestoreNestedNameSpecifierAnnotation(
-                Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
-            ConsumeAnnotationToken();
-          }
-
-          if (Tok.isOneOf(tok::identifier, tok::annot_template_id) &&
-              !NextToken().isOneOf(tok::l_brace, tok::l_paren)) {
-            TPA.Commit();
-            SourceLocation NameLoc = Tok.getLocation();
-            IdentifierInfo *II = nullptr;
-            TemplateIdAnnotation *TemplateId = nullptr;
-            if (Tok.is(tok::identifier)) {
-              II = Tok.getIdentifierInfo();
-              ConsumeToken();
-            } else {
-              TemplateId = takeTemplateIdAnnotation(Tok);
-              ConsumeAnnotationToken();
-            }
-
-            if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS,
-                                                         NameLoc, II,
-                                                         TemplateId)) {
-              Requirements.push_back(Req);
-            }
-            break;
-          }
-          TPA.Revert();
-        }
-        // Simple requirement
-        // C++ [expr.prim.req.simple]
-        //     simple-requirement:
-        //         expression ';'
-        SourceLocation StartLoc = Tok.getLocation();
-        ExprResult Expression =
-            Actions.CorrectDelayedTyposInExpr(ParseExpression());
-        if (!Expression.isUsable()) {
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)
-          Diag(StartLoc, diag::warn_requires_expr_in_simple_requirement)
-              << FixItHint::CreateInsertion(StartLoc, "requires");
-        if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get()))
-          Requirements.push_back(Req);
-        else {
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        // User may have tried to put some compound requirement stuff here
-        if (Tok.is(tok::kw_noexcept)) {
-          Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept)
-              << FixItHint::CreateInsertion(StartLoc, "{")
-              << FixItHint::CreateInsertion(Tok.getLocation(), "}");
-          SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-          break;
-        }
-        break;
-      }
-      }
-      if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) {
-        SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
-        TryConsumeToken(tok::semi);
-        break;
-      }
-    }
-    if (Requirements.empty()) {
-      // Don't emit an empty requires expr here to avoid confusing the user with
-      // other diagnostics quoting an empty requires expression they never
-      // wrote.
-      Braces.consumeClose();
-      Actions.ActOnFinishRequiresExpr();
-      return ExprError();
-    }
-  }
-  Braces.consumeClose();
-  Actions.ActOnFinishRequiresExpr();
-  return Actions.ActOnRequiresExpr(RequiresKWLoc, Body, LocalParameterDecls,
-                                   Requirements, Braces.getCloseLocation());
-}
-
 static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
   switch (kind) {
   default: llvm_unreachable("Not a known type trait");

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f8da1cb89b9d..2cd158a8b43c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1261,8 +1261,7 @@ DeclContext *Sema::getFunctionLevelDeclContext() {
   DeclContext *DC = CurContext;
 
   while (true) {
-    if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC) ||
-        isa<RequiresExprBodyDecl>(DC)) {
+    if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC)) {
       DC = DC->getParent();
     } else if (isa<CXXMethodDecl>(DC) &&
                cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index a5f505784fc5..018ac2d7dc9d 100755
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -17,10 +17,7 @@
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/Sema/TemplateDeduction.h"
 #include "clang/Sema/Template.h"
-#include "clang/Sema/Overload.h"
-#include "clang/Sema/Initialization.h"
-#include "clang/Sema/SemaInternal.h"
-#include "clang/AST/ExprConcepts.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/OperatorPrecedence.h"
 #include "llvm/ADT/DenseMap.h"
@@ -339,118 +336,6 @@ bool Sema::EnsureTemplateArgumentListConstraints(
   return false;
 }
 
-static void diagnoseUnsatisfiedRequirement(Sema &S,
-                                           concepts::ExprRequirement *Req,
-                                           bool First) {
-  assert(!Req->isSatisfied()
-         && "Diagnose() can only be used on an unsatisfied requirement");
-  switch (Req->getSatisfactionStatus()) {
-    case concepts::ExprRequirement::SS_Dependent:
-      llvm_unreachable("Diagnosing a dependent requirement");
-      break;
-    case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
-      auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
-      if (!SubstDiag->DiagMessage.empty())
-        S.Diag(SubstDiag->DiagLoc,
-               diag::note_expr_requirement_expr_substitution_error)
-               << (int)First << SubstDiag->SubstitutedEntity
-               << SubstDiag->DiagMessage;
-      else
-        S.Diag(SubstDiag->DiagLoc,
-               diag::note_expr_requirement_expr_unknown_substitution_error)
-            << (int)First << SubstDiag->SubstitutedEntity;
-      break;
-    }
-    case concepts::ExprRequirement::SS_NoexceptNotMet:
-      S.Diag(Req->getNoexceptLoc(),
-             diag::note_expr_requirement_noexcept_not_met)
-          << (int)First << Req->getExpr();
-      break;
-    case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
-      auto *SubstDiag =
-          Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
-      if (!SubstDiag->DiagMessage.empty())
-        S.Diag(SubstDiag->DiagLoc,
-               diag::note_expr_requirement_type_requirement_substitution_error)
-            << (int)First << SubstDiag->SubstitutedEntity
-            << SubstDiag->DiagMessage;
-      else
-        S.Diag(SubstDiag->DiagLoc,
-               diag::note_expr_requirement_type_requirement_unknown_substitution_error)
-            << (int)First << SubstDiag->SubstitutedEntity;
-      break;
-    }
-    case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
-      ConceptSpecializationExpr *ConstraintExpr =
-          Req->getReturnTypeRequirementSubstitutedConstraintExpr();
-      if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1)
-        // A simple case - expr type is the type being constrained and the concept
-        // was not provided arguments.
-        S.Diag(ConstraintExpr->getBeginLoc(),
-               diag::note_expr_requirement_constraints_not_satisfied_simple)
-            << (int)First << S.BuildDecltypeType(Req->getExpr(),
-                                                 Req->getExpr()->getBeginLoc())
-            << ConstraintExpr->getNamedConcept();
-      else
-        S.Diag(ConstraintExpr->getBeginLoc(),
-               diag::note_expr_requirement_constraints_not_satisfied)
-            << (int)First << ConstraintExpr;
-      S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
-      break;
-    }
-    case concepts::ExprRequirement::SS_Satisfied:
-      llvm_unreachable("We checked this above");
-  }
-}
-
-static void diagnoseUnsatisfiedRequirement(Sema &S,
-                                           concepts::TypeRequirement *Req,
-                                           bool First) {
-  assert(!Req->isSatisfied()
-         && "Diagnose() can only be used on an unsatisfied requirement");
-  switch (Req->getSatisfactionStatus()) {
-  case concepts::TypeRequirement::SS_Dependent:
-    llvm_unreachable("Diagnosing a dependent requirement");
-    return;
-  case concepts::TypeRequirement::SS_SubstitutionFailure: {
-    auto *SubstDiag = Req->getSubstitutionDiagnostic();
-    if (!SubstDiag->DiagMessage.empty())
-      S.Diag(SubstDiag->DiagLoc,
-             diag::note_type_requirement_substitution_error) << (int)First
-          << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
-    else
-      S.Diag(SubstDiag->DiagLoc,
-             diag::note_type_requirement_unknown_substitution_error)
-          << (int)First << SubstDiag->SubstitutedEntity;
-    return;
-  }
-  default:
-    llvm_unreachable("Unknown satisfaction status");
-    return;
-  }
-}
-
-static void diagnoseUnsatisfiedRequirement(Sema &S,
-                                           concepts::NestedRequirement *Req,
-                                           bool First) {
-  if (Req->isSubstitutionFailure()) {
-    concepts::Requirement::SubstitutionDiagnostic *SubstDiag =
-        Req->getSubstitutionDiagnostic();
-    if (!SubstDiag->DiagMessage.empty())
-      S.Diag(SubstDiag->DiagLoc,
-             diag::note_nested_requirement_substitution_error)
-             << (int)First << SubstDiag->SubstitutedEntity
-             << SubstDiag->DiagMessage;
-    else
-      S.Diag(SubstDiag->DiagLoc,
-             diag::note_nested_requirement_unknown_substitution_error)
-          << (int)First << SubstDiag->SubstitutedEntity;
-    return;
-  }
-  S.DiagnoseUnsatisfiedConstraint(Req->getConstraintSatisfaction(), First);
-}
-
-
 static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
                                                         Expr *SubstExpr,
                                                         bool First = true) {
@@ -527,19 +412,6 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
     }
     S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
     return;
-  } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
-    for (concepts::Requirement *Req : RE->getRequirements())
-      if (!Req->isDependent() && !Req->isSatisfied()) {
-        if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
-          diagnoseUnsatisfiedRequirement(S, E, First);
-        else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
-          diagnoseUnsatisfiedRequirement(S, T, First);
-        else
-          diagnoseUnsatisfiedRequirement(
-              S, cast<concepts::NestedRequirement>(Req), First);
-        break;
-      }
-    return;
   }
 
   S.Diag(SubstExpr->getSourceRange().getBegin(),
@@ -562,11 +434,11 @@ static void diagnoseUnsatisfiedConstraintExpr(
       Record.template get<Expr *>(), First);
 }
 
-void
-Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
-                                    bool First) {
+void Sema::DiagnoseUnsatisfiedConstraint(
+    const ConstraintSatisfaction& Satisfaction) {
   assert(!Satisfaction.IsSatisfied &&
          "Attempted to diagnose a satisfied constraint");
+  bool First = true;
   for (auto &Pair : Satisfaction.Details) {
     diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
     First = false;
@@ -574,10 +446,10 @@ Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
 }
 
 void Sema::DiagnoseUnsatisfiedConstraint(
-    const ASTConstraintSatisfaction &Satisfaction,
-    bool First) {
+    const ASTConstraintSatisfaction &Satisfaction) {
   assert(!Satisfaction.IsSatisfied &&
          "Attempted to diagnose a satisfied constraint");
+  bool First = true;
   for (auto &Pair : Satisfaction) {
     diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
     First = false;
@@ -954,70 +826,3 @@ bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1,
       << AmbiguousAtomic2->getSourceRange();
   return true;
 }
-
-concepts::ExprRequirement::ExprRequirement(
-    Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
-    ReturnTypeRequirement Req, SatisfactionStatus Status,
-    ConceptSpecializationExpr *SubstitutedConstraintExpr) :
-    Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
-                Status == SS_Dependent &&
-                (E->containsUnexpandedParameterPack() ||
-                 Req.containsUnexpandedParameterPack()),
-                Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
-    TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
-    Status(Status) {
-  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
-         "Simple requirement must not have a return type requirement or a "
-         "noexcept specification");
-  assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
-         (SubstitutedConstraintExpr != nullptr));
-}
-
-concepts::ExprRequirement::ExprRequirement(
-    SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
-    SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
-    Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
-                Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
-    Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
-    Status(SS_ExprSubstitutionFailure) {
-  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
-         "Simple requirement must not have a return type requirement or a "
-         "noexcept specification");
-}
-
-concepts::ExprRequirement::ReturnTypeRequirement::
-ReturnTypeRequirement(TemplateParameterList *TPL) :
-    TypeConstraintInfo(TPL, 0) {
-  assert(TPL->size() == 1);
-  const TypeConstraint *TC =
-      cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
-  assert(TC &&
-         "TPL must have a template type parameter with a type constraint");
-  auto *Constraint =
-      cast_or_null<ConceptSpecializationExpr>(
-          TC->getImmediatelyDeclaredConstraint());
-  bool ContainsUnexpandedParameterPack =
-      Constraint->containsUnexpandedParameterPack();
-  bool Dependent = false;
-  if (Constraint->getTemplateArgsAsWritten()) {
-    for (auto &ArgLoc :
-         Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)) {
-      if (ArgLoc.getArgument().isDependent()) {
-        Dependent = true;
-        break;
-      }
-    }
-  }
-  TypeConstraintInfo.setInt((Dependent ? 1 : 0) |
-                            (ContainsUnexpandedParameterPack ? 2 : 0));
-}
-
-concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) :
-    Requirement(RK_Type, T->getType()->isDependentType(),
-                T->getType()->containsUnexpandedParameterPack(),
-                // We reach this ctor with either dependent types (in which
-                // IsSatisfied doesn't matter) or with non-dependent type in
-                // which the existence of the type indicates satisfaction.
-                /*IsSatisfied=*/true
-                ), Value(T),
-    Status(T->getType()->isDependentType() ? SS_Dependent : SS_Satisfied) {}

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 372f3d158597..507e4a6cd436 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6468,8 +6468,6 @@ static bool shouldConsiderLinkage(const VarDecl *VD) {
     return true;
   if (DC->isRecord())
     return false;
-  if (isa<RequiresExprBodyDecl>(DC))
-    return false;
   llvm_unreachable("Unexpected context");
 }
 

diff  --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 193eaa3e01f9..5aedbe7644e4 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1386,7 +1386,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
   case Expr::StringLiteralClass:
   case Expr::SourceLocExprClass:
   case Expr::ConceptSpecializationExprClass:
-  case Expr::RequiresExprClass:
     // These expressions can never throw.
     return CT_Cannot;
 

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ea4b93ee6a5a..5f4071924d3f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -350,17 +350,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
     }
   }
 
-  if (isa<ParmVarDecl>(D) && isa<RequiresExprBodyDecl>(D->getDeclContext()) &&
-      !isUnevaluatedContext()) {
-    // C++ [expr.prim.req.nested] p3
-    //   A local parameter shall only appear as an unevaluated operand
-    //   (Clause 8) within the constraint-expression.
-    Diag(Loc, diag::err_requires_expr_parameter_referenced_in_evaluated_context)
-        << D;
-    Diag(D->getLocation(), diag::note_entity_declared_at) << D;
-    return true;
-  }
-
   return false;
 }
 
@@ -1915,7 +1904,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
   bool RefersToCapturedVariable =
       isa<VarDecl>(D) &&
       NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());
-  
+
   DeclRefExpr *E = DeclRefExpr::Create(
       Context, NNS, TemplateKWLoc, D, RefersToCapturedVariable, NameInfo, Ty,
       VK, FoundD, TemplateArgs, getNonOdrUseReasonInCurrentContext(D));

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 192c237b6c1c..938420d85c65 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -11,7 +11,6 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/Sema/Template.h"
 #include "clang/Sema/SemaInternal.h"
 #include "TreeTransform.h"
 #include "TypeLocBuilder.h"
@@ -8332,215 +8331,3 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
 
   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
 }
-
-concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) {
-  return BuildExprRequirement(E, /*IsSimple=*/true,
-                              /*NoexceptLoc=*/SourceLocation(),
-                              /*ReturnTypeRequirement=*/{});
-}
-
-concepts::Requirement *
-Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS,
-                           SourceLocation NameLoc, IdentifierInfo *TypeName,
-                           TemplateIdAnnotation *TemplateId) {
-  assert(((!TypeName && TemplateId) || (TypeName && !TemplateId)) &&
-         "Exactly one of TypeName and TemplateId must be specified.");
-  TypeSourceInfo *TSI = nullptr;
-  if (TypeName) {
-    QualType T = CheckTypenameType(ETK_Typename, TypenameKWLoc,
-                                   SS.getWithLocInContext(Context), *TypeName,
-                                   NameLoc, &TSI, /*DeducedTypeContext=*/false);
-    if (T.isNull())
-      return nullptr;
-  } else {
-    ASTTemplateArgsPtr ArgsPtr(TemplateId->getTemplateArgs(),
-                               TemplateId->NumArgs);
-    TypeResult T = ActOnTypenameType(CurScope, TypenameKWLoc, SS,
-                                     TemplateId->TemplateKWLoc,
-                                     TemplateId->Template, TemplateId->Name,
-                                     TemplateId->TemplateNameLoc,
-                                     TemplateId->LAngleLoc, ArgsPtr,
-                                     TemplateId->RAngleLoc);
-    if (T.isInvalid())
-      return nullptr;
-    if (GetTypeFromParser(T.get(), &TSI).isNull())
-      return nullptr;
-  }
-  return BuildTypeRequirement(TSI);
-}
-
-concepts::Requirement *
-Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) {
-  return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc,
-                              /*ReturnTypeRequirement=*/{});
-}
-
-concepts::Requirement *
-Sema::ActOnCompoundRequirement(
-    Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
-    TemplateIdAnnotation *TypeConstraint, unsigned Depth) {
-  // C++2a [expr.prim.req.compound] p1.3.3
-  //   [..] the expression is deduced against an invented function template
-  //   F [...] F is a void function template with a single type template
-  //   parameter T declared with the constrained-parameter. Form a new
-  //   cv-qualifier-seq cv by taking the union of const and volatile specifiers
-  //   around the constrained-parameter. F has a single parameter whose
-  //   type-specifier is cv T followed by the abstract-declarator. [...]
-  //
-  // The cv part is done in the calling function - we get the concept with
-  // arguments and the abstract declarator with the correct CV qualification and
-  // have to synthesize T and the single parameter of F.
-  auto &II = Context.Idents.get("expr-type");
-  auto *TParam = TemplateTypeParmDecl::Create(Context, CurContext,
-                                              SourceLocation(),
-                                              SourceLocation(), Depth,
-                                              /*Index=*/0, &II,
-                                              /*Typename=*/true,
-                                              /*ParameterPack=*/false,
-                                              /*HasTypeConstraint=*/true);
-
-  if (ActOnTypeConstraint(SS, TypeConstraint, TParam,
-                          /*EllpsisLoc=*/SourceLocation()))
-    // Just produce a requirement with no type requirements.
-    return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {});
-
-  auto *TPL = TemplateParameterList::Create(Context, SourceLocation(),
-                                            SourceLocation(),
-                                            ArrayRef<NamedDecl *>(TParam),
-                                            SourceLocation(),
-                                            /*RequiresClause=*/nullptr);
-  return BuildExprRequirement(
-      E, /*IsSimple=*/false, NoexceptLoc,
-      concepts::ExprRequirement::ReturnTypeRequirement(TPL));
-}
-
-concepts::ExprRequirement *
-Sema::BuildExprRequirement(
-    Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
-    concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
-  auto Status = concepts::ExprRequirement::SS_Satisfied;
-  ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
-  if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent())
-    Status = concepts::ExprRequirement::SS_Dependent;
-  else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can)
-    Status = concepts::ExprRequirement::SS_NoexceptNotMet;
-  else if (ReturnTypeRequirement.isSubstitutionFailure())
-    Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure;
-  else if (ReturnTypeRequirement.isTypeConstraint()) {
-    // C++2a [expr.prim.req]p1.3.3
-    //     The immediately-declared constraint ([temp]) of decltype((E)) shall
-    //     be satisfied.
-    TemplateParameterList *TPL =
-        ReturnTypeRequirement.getTypeConstraintTemplateParameterList();
-    QualType MatchedType =
-        BuildDecltypeType(E, E->getBeginLoc()).getCanonicalType();
-    llvm::SmallVector<TemplateArgument, 1> Args;
-    Args.push_back(TemplateArgument(MatchedType));
-    TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args);
-    MultiLevelTemplateArgumentList MLTAL(TAL);
-    for (unsigned I = 0; I < TPL->getDepth(); ++I)
-      MLTAL.addOuterRetainedLevel();
-    Expr *IDC =
-        cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint()
-            ->getImmediatelyDeclaredConstraint();
-    ExprResult Constraint = SubstExpr(IDC, MLTAL);
-    assert(!Constraint.isInvalid() &&
-           "Substitution cannot fail as it is simply putting a type template "
-           "argument into a concept specialization expression's parameter.");
-
-    SubstitutedConstraintExpr =
-        cast<ConceptSpecializationExpr>(Constraint.get());
-    if (!SubstitutedConstraintExpr->isSatisfied())
-      Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
-  }
-  return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc,
-                                                 ReturnTypeRequirement, Status,
-                                                 SubstitutedConstraintExpr);
-}
-
-concepts::ExprRequirement *
-Sema::BuildExprRequirement(
-    concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic,
-    bool IsSimple, SourceLocation NoexceptLoc,
-    concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
-  return new (Context) concepts::ExprRequirement(ExprSubstitutionDiagnostic,
-                                                 IsSimple, NoexceptLoc,
-                                                 ReturnTypeRequirement);
-}
-
-concepts::TypeRequirement *
-Sema::BuildTypeRequirement(TypeSourceInfo *Type) {
-  return new (Context) concepts::TypeRequirement(Type);
-}
-
-concepts::TypeRequirement *
-Sema::BuildTypeRequirement(
-    concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
-  return new (Context) concepts::TypeRequirement(SubstDiag);
-}
-
-concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {
-  return BuildNestedRequirement(Constraint);
-}
-
-concepts::NestedRequirement *
-Sema::BuildNestedRequirement(Expr *Constraint) {
-  ConstraintSatisfaction Satisfaction;
-  if (!Constraint->isInstantiationDependent() &&
-      CheckConstraintSatisfaction(Constraint, Satisfaction))
-    return nullptr;
-  return new (Context) concepts::NestedRequirement(Context, Constraint,
-                                                   Satisfaction);
-}
-
-concepts::NestedRequirement *
-Sema::BuildNestedRequirement(
-    concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
-  return new (Context) concepts::NestedRequirement(SubstDiag);
-}
-
-RequiresExprBodyDecl *
-Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
-                             ArrayRef<ParmVarDecl *> LocalParameters,
-                             Scope *BodyScope) {
-  assert(BodyScope);
-
-  RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(Context, CurContext,
-                                                            RequiresKWLoc);
-
-  PushDeclContext(BodyScope, Body);
-
-  for (ParmVarDecl *Param : LocalParameters) {
-    if (Param->hasDefaultArg())
-      // C++2a [expr.prim.req] p4
-      //     [...] A local parameter of a requires-expression shall not have a
-      //     default argument. [...]
-      Diag(Param->getDefaultArgRange().getBegin(),
-           diag::err_requires_expr_local_parameter_default_argument);
-    // Ignore default argument and move on
-
-    Param->setDeclContext(Body);
-    // If this has an identifier, add it to the scope stack.
-    if (Param->getIdentifier()) {
-      CheckShadow(BodyScope, Param);
-      PushOnScopeChains(Param, BodyScope);
-    }
-  }
-  return Body;
-}
-
-void Sema::ActOnFinishRequiresExpr() {
-  assert(CurContext && "DeclContext imbalance!");
-  CurContext = CurContext->getLexicalParent();
-  assert(CurContext && "Popped translation unit!");
-}
-
-ExprResult
-Sema::ActOnRequiresExpr(SourceLocation RequiresKWLoc,
-                        RequiresExprBodyDecl *Body,
-                        ArrayRef<ParmVarDecl *> LocalParameters,
-                        ArrayRef<concepts::Requirement *> Requirements,
-                        SourceLocation ClosingBraceLoc) {
-  return RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters,
-                              Requirements, ClosingBraceLoc);
-}

diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 8d96404a5c27..0ed51de0cc13 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1575,9 +1575,7 @@ llvm::DenseSet<Module*> &Sema::getLookupModules() {
   unsigned N = CodeSynthesisContexts.size();
   for (unsigned I = CodeSynthesisContextLookupModules.size();
        I != N; ++I) {
-    Module *M = CodeSynthesisContexts[I].Entity ?
-                getDefiningModule(*this, CodeSynthesisContexts[I].Entity) :
-                nullptr;
+    Module *M = getDefiningModule(*this, CodeSynthesisContexts[I].Entity);
     if (M && !LookupModulesCache.insert(M).second)
       M = nullptr;
     CodeSynthesisContextLookupModules.push_back(M);

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 661a66246a53..8a50a9e1538f 100755
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10010,12 +10010,24 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
       << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
-  TypeSourceInfo *TSI = nullptr;
   QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None,
-                                 TypenameLoc, QualifierLoc, II, IdLoc, &TSI,
-                                 /*DeducedTSTContext=*/true);
+                                 TypenameLoc, QualifierLoc, II, IdLoc);
   if (T.isNull())
     return true;
+
+  TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
+  if (isa<DependentNameType>(T)) {
+    DependentNameTypeLoc TL = TSI->getTypeLoc().castAs<DependentNameTypeLoc>();
+    TL.setElaboratedKeywordLoc(TypenameLoc);
+    TL.setQualifierLoc(QualifierLoc);
+    TL.setNameLoc(IdLoc);
+  } else {
+    ElaboratedTypeLoc TL = TSI->getTypeLoc().castAs<ElaboratedTypeLoc>();
+    TL.setElaboratedKeywordLoc(TypenameLoc);
+    TL.setQualifierLoc(QualifierLoc);
+    TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(IdLoc);
+  }
+
   return CreateParsedType(T, TSI);
 }
 
@@ -10152,35 +10164,6 @@ static bool isEnableIf(NestedNameSpecifierLoc NNS, const IdentifierInfo &II,
   return true;
 }
 
-QualType
-Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
-                        SourceLocation KeywordLoc,
-                        NestedNameSpecifierLoc QualifierLoc,
-                        const IdentifierInfo &II,
-                        SourceLocation IILoc,
-                        TypeSourceInfo **TSI,
-                        bool DeducedTSTContext) {
-  QualType T = CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, II, IILoc,
-                                 DeducedTSTContext);
-  if (T.isNull())
-    return QualType();
-
-  *TSI = Context.CreateTypeSourceInfo(T);
-  if (isa<DependentNameType>(T)) {
-    DependentNameTypeLoc TL =
-        (*TSI)->getTypeLoc().castAs<DependentNameTypeLoc>();
-    TL.setElaboratedKeywordLoc(KeywordLoc);
-    TL.setQualifierLoc(QualifierLoc);
-    TL.setNameLoc(IILoc);
-  } else {
-    ElaboratedTypeLoc TL = (*TSI)->getTypeLoc().castAs<ElaboratedTypeLoc>();
-    TL.setElaboratedKeywordLoc(KeywordLoc);
-    TL.setQualifierLoc(QualifierLoc);
-    TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(IILoc);
-  }
-  return T;
-}
-
 /// Build the type that describes a C++ typename specifier,
 /// e.g., "typename T::type".
 QualType
@@ -10188,38 +10171,32 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
                         SourceLocation KeywordLoc,
                         NestedNameSpecifierLoc QualifierLoc,
                         const IdentifierInfo &II,
-                        SourceLocation IILoc, bool DeducedTSTContext) {
+                        SourceLocation IILoc) {
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
 
-  DeclContext *Ctx = nullptr;
-  if (QualifierLoc) {
-    Ctx = computeDeclContext(SS);
-    if (!Ctx) {
-      // If the nested-name-specifier is dependent and couldn't be
-      // resolved to a type, build a typename type.
-      assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
-      return Context.getDependentNameType(Keyword,
-                                          QualifierLoc.getNestedNameSpecifier(),
-                                          &II);
-    }
-
-    // If the nested-name-specifier refers to the current instantiation,
-    // the "typename" keyword itself is superfluous. In C++03, the
-    // program is actually ill-formed. However, DR 382 (in C++0x CD1)
-    // allows such extraneous "typename" keywords, and we retroactively
-    // apply this DR to C++03 code with only a warning. In any case we continue.
-
-    if (RequireCompleteDeclContext(SS, Ctx))
-      return QualType();
+  DeclContext *Ctx = computeDeclContext(SS);
+  if (!Ctx) {
+    // If the nested-name-specifier is dependent and couldn't be
+    // resolved to a type, build a typename type.
+    assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
+    return Context.getDependentNameType(Keyword,
+                                        QualifierLoc.getNestedNameSpecifier(),
+                                        &II);
   }
 
+  // If the nested-name-specifier refers to the current instantiation,
+  // the "typename" keyword itself is superfluous. In C++03, the
+  // program is actually ill-formed. However, DR 382 (in C++0x CD1)
+  // allows such extraneous "typename" keywords, and we retroactively
+  // apply this DR to C++03 code with only a warning. In any case we continue.
+
+  if (RequireCompleteDeclContext(SS, Ctx))
+    return QualType();
+
   DeclarationName Name(&II);
   LookupResult Result(*this, Name, IILoc, LookupOrdinaryName);
-  if (Ctx)
-    LookupQualifiedName(Result, Ctx, SS);
-  else
-    LookupName(Result, CurScope);
+  LookupQualifiedName(Result, Ctx, SS);
   unsigned DiagID = 0;
   Decl *Referenced = nullptr;
   switch (Result.getResultKind()) {
@@ -10228,7 +10205,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
     // a more specific diagnostic.
     SourceRange CondRange;
     Expr *Cond = nullptr;
-    if (Ctx && isEnableIf(QualifierLoc, II, CondRange, Cond)) {
+    if (isEnableIf(QualifierLoc, II, CondRange, Cond)) {
       // If we have a condition, narrow it down to the specific failed
       // condition.
       if (Cond) {
@@ -10244,14 +10221,12 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
         return QualType();
       }
 
-      Diag(CondRange.getBegin(),
-           diag::err_typename_nested_not_found_enable_if)
+      Diag(CondRange.getBegin(), diag::err_typename_nested_not_found_enable_if)
           << Ctx << CondRange;
       return QualType();
     }
 
-    DiagID = Ctx ? diag::err_typename_nested_not_found
-                 : diag::err_unknown_typename;
+    DiagID = diag::err_typename_nested_not_found;
     break;
   }
 
@@ -10317,19 +10292,6 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
     //   is a placeholder for a deduced class type [...].
     if (getLangOpts().CPlusPlus17) {
       if (auto *TD = getAsTypeTemplateDecl(Result.getFoundDecl())) {
-        if (!DeducedTSTContext) {
-          QualType T(QualifierLoc
-                         ? QualifierLoc.getNestedNameSpecifier()->getAsType()
-                         : nullptr, 0);
-          if (!T.isNull())
-            Diag(IILoc, diag::err_dependent_deduced_tst)
-              << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << T;
-          else
-            Diag(IILoc, diag::err_deduced_tst)
-              << (int)getTemplateNameKindForDiagnostics(TemplateName(TD));
-          Diag(TD->getLocation(), diag::note_template_decl_here);
-          return QualType();
-        }
         return Context.getElaboratedType(
             Keyword, QualifierLoc.getNestedNameSpecifier(),
             Context.getDeducedTemplateSpecializationType(TemplateName(TD),
@@ -10337,14 +10299,12 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
       }
     }
 
-    DiagID = Ctx ? diag::err_typename_nested_not_type
-                 : diag::err_typename_not_type;
+    DiagID = diag::err_typename_nested_not_type;
     Referenced = Result.getFoundDecl();
     break;
 
   case LookupResult::FoundOverloaded:
-    DiagID = Ctx ? diag::err_typename_nested_not_type
-                 : diag::err_typename_not_type;
+    DiagID = diag::err_typename_nested_not_type;
     Referenced = *Result.begin();
     break;
 
@@ -10356,14 +10316,9 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
   // type. Emit an appropriate diagnostic and return an error.
   SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(),
                         IILoc);
-  if (Ctx)
-    Diag(IILoc, DiagID) << FullRange << Name << Ctx;
-  else
-    Diag(IILoc, DiagID) << FullRange << Name;
+  Diag(IILoc, DiagID) << FullRange << Name << Ctx;
   if (Referenced)
-    Diag(Referenced->getLocation(),
-         Ctx ? diag::note_typename_member_refers_here
-             : diag::note_typename_refers_here)
+    Diag(Referenced->getLocation(), diag::note_typename_refers_here)
       << Name;
   return QualType();
 }

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 39bc28d62305..af41e231134d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -26,7 +26,6 @@
 #include "clang/Sema/Template.h"
 #include "clang/Sema/TemplateDeduction.h"
 #include "clang/Sema/TemplateInstCallback.h"
-#include "clang/Sema/SemaConcept.h"
 #include "llvm/Support/TimeProfiler.h"
 
 using namespace clang;
@@ -200,10 +199,8 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
   case DeducedTemplateArgumentSubstitution:
   case PriorTemplateArgumentSubstitution:
   case ConstraintsCheck:
-  case NestedRequirementConstraintsCheck:
     return true;
 
-  case RequirementInstantiation:
   case DefaultTemplateArgumentChecking:
   case DeclaringSpecialMember:
   case DeclaringImplicitEqualityComparison:
@@ -250,7 +247,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
     Inst.InstantiationRange = InstantiationRange;
     SemaRef.pushCodeSynthesisContext(Inst);
 
-    AlreadyInstantiating = !Inst.Entity ? false :
+    AlreadyInstantiating =
         !SemaRef.InstantiatingSpecializations
              .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
              .second;
@@ -367,26 +364,6 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
           PointOfInstantiation, InstantiationRange, Param, Template,
           TemplateArgs) {}
 
-Sema::InstantiatingTemplate::InstantiatingTemplate(
-    Sema &SemaRef, SourceLocation PointOfInstantiation,
-    concepts::Requirement *Req, sema::TemplateDeductionInfo &DeductionInfo,
-    SourceRange InstantiationRange)
-    : InstantiatingTemplate(
-          SemaRef, CodeSynthesisContext::RequirementInstantiation,
-          PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
-          /*Template=*/nullptr, /*TemplateArgs=*/None, &DeductionInfo) {}
-
-
-Sema::InstantiatingTemplate::InstantiatingTemplate(
-    Sema &SemaRef, SourceLocation PointOfInstantiation,
-    concepts::NestedRequirement *Req, ConstraintsCheck,
-    SourceRange InstantiationRange)
-    : InstantiatingTemplate(
-          SemaRef, CodeSynthesisContext::NestedRequirementConstraintsCheck,
-          PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
-          /*Template=*/nullptr, /*TemplateArgs=*/None) {}
-
-
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     ConstraintsCheck, NamedDecl *Template,
@@ -469,9 +446,8 @@ void Sema::InstantiatingTemplate::Clear() {
   if (!Invalid) {
     if (!AlreadyInstantiating) {
       auto &Active = SemaRef.CodeSynthesisContexts.back();
-      if (Active.Entity)
-        SemaRef.InstantiatingSpecializations.erase(
-            std::make_pair(Active.Entity, Active.Kind));
+      SemaRef.InstantiatingSpecializations.erase(
+          std::make_pair(Active.Entity, Active.Kind));
     }
 
     atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
@@ -708,18 +684,6 @@ void Sema::PrintInstantiationStack() {
         << Active->InstantiationRange;
       break;
 
-    case CodeSynthesisContext::RequirementInstantiation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_requirement_instantiation_here)
-        << Active->InstantiationRange;
-      break;
-
-    case CodeSynthesisContext::NestedRequirementConstraintsCheck:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_nested_requirement_here)
-        << Active->InstantiationRange;
-      break;
-
     case CodeSynthesisContext::DeclaringSpecialMember:
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_in_declaration_of_implicit_special_member)
@@ -824,7 +788,6 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
     case CodeSynthesisContext::ConstraintsCheck:
     case CodeSynthesisContext::ParameterMappingSubstitution:
     case CodeSynthesisContext::ConstraintNormalization:
-    case CodeSynthesisContext::NestedRequirementConstraintsCheck:
       // This is a template instantiation, so there is no SFINAE.
       return None;
 
@@ -839,10 +802,9 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
     case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
     case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
     case CodeSynthesisContext::ConstraintSubstitution:
-    case CodeSynthesisContext::RequirementInstantiation:
-      // We're either substituting explicitly-specified template arguments,
-      // deduced template arguments, a constraint expression or a requirement
-      // in a requires expression, so SFINAE applies.
+      // We're either substituting explicitly-specified template arguments
+      // or deduced template arguments or a constraint expression, so SFINAE
+      // applies.
       assert(Active->DeductionInfo && "Missing deduction info pointer");
       return Active->DeductionInfo;
 
@@ -1094,41 +1056,6 @@ namespace {
       return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E);
     }
 
-    ExprResult TransformRequiresExpr(RequiresExpr *E) {
-      LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
-      return TreeTransform<TemplateInstantiator>::TransformRequiresExpr(E);
-    }
-
-    bool TransformRequiresExprRequirements(
-        ArrayRef<concepts::Requirement *> Reqs,
-        SmallVectorImpl<concepts::Requirement *> &Transformed) {
-      bool SatisfactionDetermined = false;
-      for (concepts::Requirement *Req : Reqs) {
-        concepts::Requirement *TransReq = nullptr;
-        if (!SatisfactionDetermined) {
-          if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
-            TransReq = TransformTypeRequirement(TypeReq);
-          else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
-            TransReq = TransformExprRequirement(ExprReq);
-          else
-            TransReq = TransformNestedRequirement(
-                cast<concepts::NestedRequirement>(Req));
-          if (!TransReq)
-            return true;
-          if (!TransReq->isDependent() && !TransReq->isSatisfied())
-            // [expr.prim.req]p6
-            //   [...]  The substitution and semantic constraint checking
-            //   proceeds in lexical order and stops when a condition that
-            //   determines the result of the requires-expression is
-            //   encountered. [..]
-            SatisfactionDetermined = true;
-        } else
-          TransReq = Req;
-        Transformed.push_back(TransReq);
-      }
-      return false;
-    }
-
     TemplateParameterList *TransformTemplateParameterList(
                               TemplateParameterList *OrigTPL)  {
       if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
@@ -1138,14 +1065,6 @@ namespace {
                         /* DeclContext *Owner */ Owner, TemplateArgs);
       return DeclInstantiator.SubstTemplateParams(OrigTPL);
     }
-
-    concepts::TypeRequirement *
-    TransformTypeRequirement(concepts::TypeRequirement *Req);
-    concepts::ExprRequirement *
-    TransformExprRequirement(concepts::ExprRequirement *Req);
-    concepts::NestedRequirement *
-    TransformNestedRequirement(concepts::NestedRequirement *Req);
-
   private:
     ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
                                                SourceLocation loc,
@@ -1750,163 +1669,6 @@ TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
   return Result;
 }
 
-template<typename EntityPrinter>
-static concepts::Requirement::SubstitutionDiagnostic *
-createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
-  SmallString<128> Message;
-  SourceLocation ErrorLoc;
-  if (Info.hasSFINAEDiagnostic()) {
-    PartialDiagnosticAt PDA(SourceLocation(),
-                            PartialDiagnostic::NullDiagnostic{});
-    Info.takeSFINAEDiagnostic(PDA);
-    PDA.second.EmitToString(S.getDiagnostics(), Message);
-    ErrorLoc = PDA.first;
-  } else {
-    ErrorLoc = Info.getLocation();
-  }
-  char *MessageBuf = new (S.Context) char[Message.size()];
-  std::copy(Message.begin(), Message.end(), MessageBuf);
-  SmallString<128> Entity;
-  llvm::raw_svector_ostream OS(Entity);
-  Printer(OS);
-  char *EntityBuf = new (S.Context) char[Entity.size()];
-  std::copy(Entity.begin(), Entity.end(), EntityBuf);
-  return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
-      StringRef(EntityBuf, Entity.size()), ErrorLoc,
-      StringRef(MessageBuf, Message.size())};
-}
-
-concepts::TypeRequirement *
-TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {
-  if (!Req->isDependent() && !AlwaysRebuild())
-    return Req;
-  if (Req->isSubstitutionFailure()) {
-    if (AlwaysRebuild())
-      return RebuildTypeRequirement(
-              Req->getSubstitutionDiagnostic());
-    return Req;
-  }
-
-  Sema::SFINAETrap Trap(SemaRef);
-  TemplateDeductionInfo Info(Req->getType()->getTypeLoc().getBeginLoc());
-  Sema::InstantiatingTemplate TypeInst(SemaRef,
-      Req->getType()->getTypeLoc().getBeginLoc(), Req, Info,
-      Req->getType()->getTypeLoc().getSourceRange());
-  if (TypeInst.isInvalid())
-    return nullptr;
-  TypeSourceInfo *TransType = TransformType(Req->getType());
-  if (!TransType || Trap.hasErrorOccurred())
-    return RebuildTypeRequirement(createSubstDiag(SemaRef, Info,
-        [&] (llvm::raw_ostream& OS) {
-            Req->getType()->getType().print(OS, SemaRef.getPrintingPolicy());
-        }));
-  return RebuildTypeRequirement(TransType);
-}
-
-concepts::ExprRequirement *
-TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
-  if (!Req->isDependent() && !AlwaysRebuild())
-    return Req;
-
-  Sema::SFINAETrap Trap(SemaRef);
-  TemplateDeductionInfo Info(Req->getExpr()->getBeginLoc());
-
-  llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
-      TransExpr;
-  if (Req->isExprSubstitutionFailure())
-    TransExpr = Req->getExprSubstitutionDiagnostic();
-  else {
-    Sema::InstantiatingTemplate ExprInst(SemaRef, Req->getExpr()->getBeginLoc(),
-                                         Req, Info,
-                                         Req->getExpr()->getSourceRange());
-    if (ExprInst.isInvalid())
-      return nullptr;
-    ExprResult TransExprRes = TransformExpr(Req->getExpr());
-    if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
-      TransExpr = createSubstDiag(SemaRef, Info,
-          [&] (llvm::raw_ostream& OS) {
-              Req->getExpr()->printPretty(OS, nullptr,
-                                          SemaRef.getPrintingPolicy());
-          });
-    else
-      TransExpr = TransExprRes.get();
-  }
-
-  llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
-  const auto &RetReq = Req->getReturnTypeRequirement();
-  if (RetReq.isEmpty())
-    TransRetReq.emplace();
-  else if (RetReq.isSubstitutionFailure())
-    TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
-  else if (RetReq.isTypeConstraint()) {
-    TemplateParameterList *OrigTPL =
-        RetReq.getTypeConstraintTemplateParameterList();
-    Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
-                                        Req, Info, OrigTPL->getSourceRange());
-    if (TPLInst.isInvalid())
-      return nullptr;
-    TemplateParameterList *TPL =
-        TransformTemplateParameterList(OrigTPL);
-    if (!TPL)
-      TransRetReq.emplace(createSubstDiag(SemaRef, Info,
-          [&] (llvm::raw_ostream& OS) {
-              RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
-                  ->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
-          }));
-    else {
-      TPLInst.Clear();
-      TransRetReq.emplace(TPL);
-    }
-  }
-  assert(TransRetReq.hasValue() &&
-         "All code paths leading here must set TransRetReq");
-  if (Expr *E = TransExpr.dyn_cast<Expr *>())
-    return RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(),
-                                  std::move(*TransRetReq));
-  return RebuildExprRequirement(
-      TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
-      Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
-}
-
-concepts::NestedRequirement *
-TemplateInstantiator::TransformNestedRequirement(
-    concepts::NestedRequirement *Req) {
-  if (!Req->isDependent() && !AlwaysRebuild())
-    return Req;
-  if (Req->isSubstitutionFailure()) {
-    if (AlwaysRebuild())
-      return RebuildNestedRequirement(
-          Req->getSubstitutionDiagnostic());
-    return Req;
-  }
-  Sema::InstantiatingTemplate ReqInst(SemaRef,
-      Req->getConstraintExpr()->getBeginLoc(), Req,
-      Sema::InstantiatingTemplate::ConstraintsCheck{},
-      Req->getConstraintExpr()->getSourceRange());
-
-  ExprResult TransConstraint;
-  TemplateDeductionInfo Info(Req->getConstraintExpr()->getBeginLoc());
-  {
-    EnterExpressionEvaluationContext ContextRAII(
-        SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-    Sema::SFINAETrap Trap(SemaRef);
-    Sema::InstantiatingTemplate ConstrInst(SemaRef,
-        Req->getConstraintExpr()->getBeginLoc(), Req, Info,
-        Req->getConstraintExpr()->getSourceRange());
-    if (ConstrInst.isInvalid())
-      return nullptr;
-    TransConstraint = TransformExpr(Req->getConstraintExpr());
-    if (TransConstraint.isInvalid() || Trap.hasErrorOccurred())
-      return RebuildNestedRequirement(createSubstDiag(SemaRef, Info,
-          [&] (llvm::raw_ostream& OS) {
-              Req->getConstraintExpr()->printPretty(OS, nullptr,
-                                                    SemaRef.getPrintingPolicy());
-          }));
-  }
-  return RebuildNestedRequirement(TransConstraint.get());
-}
-
-
 /// Perform substitution on the type T with a given set of template
 /// arguments.
 ///

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a470cfc87440..64500d0a26d5 100755
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3600,12 +3600,6 @@ Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) {
   llvm_unreachable("Concept definitions cannot reside inside a template");
 }
 
-Decl *
-TemplateDeclInstantiator::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
-  return RequiresExprBodyDecl::Create(SemaRef.Context, D->getDeclContext(),
-                                      D->getBeginLoc());
-}
-
 Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) {
   llvm_unreachable("Unexpected decl");
 }

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index efb4437b3e60..a860640444e3 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2994,9 +2994,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case DeclaratorContext::PrototypeContext:
       Error = 0;
       break;
-    case DeclaratorContext::RequiresExprContext:
-      Error = 21;
-      break;
     case DeclaratorContext::LambdaExprParameterContext:
       // In C++14, generic lambdas allow 'auto' in their parameters.
       if (!SemaRef.getLangOpts().CPlusPlus14 ||
@@ -3224,7 +3221,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case DeclaratorContext::ObjCParameterContext:
     case DeclaratorContext::ObjCResultContext:
     case DeclaratorContext::KNRTypeListContext:
-    case DeclaratorContext::RequiresExprContext:
       // C++ [dcl.fct]p6:
       //   Types shall not be defined in return or parameter types.
       DiagID = diag::err_type_defined_in_param_type;
@@ -4283,7 +4279,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
     case DeclaratorContext::TemplateTypeArgContext:
     case DeclaratorContext::TypeNameContext:
     case DeclaratorContext::FunctionalCastContext:
-    case DeclaratorContext::RequiresExprContext:
       // Don't infer in these contexts.
       break;
     }
@@ -5232,7 +5227,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
     switch (D.getContext()) {
     case DeclaratorContext::PrototypeContext:
     case DeclaratorContext::LambdaExprParameterContext:
-    case DeclaratorContext::RequiresExprContext:
       // C++0x [dcl.fct]p13:
       //   [...] When it is part of a parameter-declaration-clause, the
       //   parameter pack is a function parameter pack (14.5.3). The type T

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 1f7251173838..3b827fbc950b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -19,7 +19,6 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
@@ -510,15 +509,6 @@ class TreeTransform {
   DeclarationNameInfo
   TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
 
-  bool TransformRequiresExprRequirements(ArrayRef<concepts::Requirement *> Reqs,
-      llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
-  concepts::TypeRequirement *
-  TransformTypeRequirement(concepts::TypeRequirement *Req);
-  concepts::ExprRequirement *
-  TransformExprRequirement(concepts::ExprRequirement *Req);
-  concepts::NestedRequirement *
-  TransformNestedRequirement(concepts::NestedRequirement *Req);
-
   /// Transform the given template name.
   ///
   /// \param SS The nested-name-specifier that qualifies the template
@@ -1066,8 +1056,23 @@ class TreeTransform {
     }
 
     if (Keyword == ETK_None || Keyword == ETK_Typename) {
-      return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
-                                       *Id, IdLoc, DeducedTSTContext);
+      QualType T = SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
+                                             *Id, IdLoc);
+      // If a dependent name resolves to a deduced template specialization type,
+      // check that we're in one of the syntactic contexts permitting it.
+      if (!DeducedTSTContext) {
+        if (auto *Deduced = dyn_cast_or_null<DeducedTemplateSpecializationType>(
+                T.isNull() ? nullptr : T->getContainedDeducedType())) {
+          SemaRef.Diag(IdLoc, diag::err_dependent_deduced_tst)
+            << (int)SemaRef.getTemplateNameKindForDiagnostics(
+                   Deduced->getTemplateName())
+            << QualType(QualifierLoc.getNestedNameSpecifier()->getAsType(), 0);
+          if (auto *TD = Deduced->getTemplateName().getAsTemplateDecl())
+            SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here);
+          return QualType();
+        }
+      }
+      return T;
     }
 
     TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
@@ -3073,56 +3078,7 @@ class TreeTransform {
     return Result;
   }
 
-  /// \brief Build a new requires expression.
-  ///
-  /// By default, performs semantic analysis to build the new expression.
-  /// Subclasses may override this routine to provide 
diff erent behavior.
-  ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
-                                 RequiresExprBodyDecl *Body,
-                                 ArrayRef<ParmVarDecl *> LocalParameters,
-                                 ArrayRef<concepts::Requirement *> Requirements,
-                                 SourceLocation ClosingBraceLoc) {
-    return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body,
-                                LocalParameters, Requirements, ClosingBraceLoc);
-  }
-
-  concepts::TypeRequirement *
-  RebuildTypeRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
-    return SemaRef.BuildTypeRequirement(SubstDiag);
-  }
-
-  concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
-    return SemaRef.BuildTypeRequirement(T);
-  }
-
-  concepts::ExprRequirement *
-  RebuildExprRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
-      SourceLocation NoexceptLoc,
-      concepts::ExprRequirement::ReturnTypeRequirement Ret) {
-    return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
-                                        std::move(Ret));
-  }
-
-  concepts::ExprRequirement *
-  RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
-                         concepts::ExprRequirement::ReturnTypeRequirement Ret) {
-    return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
-                                        std::move(Ret));
-  }
-
-  concepts::NestedRequirement *
-  RebuildNestedRequirement(
-      concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
-    return SemaRef.BuildNestedRequirement(SubstDiag);
-  }
-
-  concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
-    return SemaRef.BuildNestedRequirement(Constraint);
-  }
-
-  /// \brief Build a new Objective-C boxed expression.
+    /// \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 
diff erent behavior.
@@ -11223,146 +11179,6 @@ TreeTransform<Derived>::TransformConceptSpecializationExpr(
       &TransArgs);
 }
 
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
-  SmallVector<ParmVarDecl*, 4> TransParams;
-  SmallVector<QualType, 4> TransParamTypes;
-  Sema::ExtParameterInfoBuilder ExtParamInfos;
-
-  // C++2a [expr.prim.req]p2
-  // Expressions appearing within a requirement-body are unevaluated operands.
-  EnterExpressionEvaluationContext Ctx(
-      SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
-
-  RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
-      getSema().Context, E->getBody()->getDeclContext(),
-      E->getBody()->getBeginLoc());
-
-  Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
-
-  if (getDerived().TransformFunctionTypeParams(E->getRequiresKWLoc(),
-                                               E->getLocalParameters(),
-                                               /*ParamTypes=*/nullptr,
-                                               /*ParamInfos=*/nullptr,
-                                               TransParamTypes, &TransParams,
-                                               ExtParamInfos))
-    return ExprError();
-
-  for (ParmVarDecl *Param : TransParams)
-    Param->setDeclContext(Body);
-
-  SmallVector<concepts::Requirement *, 4> TransReqs;
-  if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
-                                                     TransReqs))
-    return ExprError();
-
-  for (concepts::Requirement *Req : TransReqs) {
-    if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
-      if (ER->getReturnTypeRequirement().isTypeConstraint()) {
-        ER->getReturnTypeRequirement()
-                .getTypeConstraintTemplateParameterList()->getParam(0)
-                ->setDeclContext(Body);
-      }
-    }
-  }
-
-  return getDerived().RebuildRequiresExpr(E->getRequiresKWLoc(), Body,
-                                          TransParams, TransReqs,
-                                          E->getRBraceLoc());
-}
-
-template<typename Derived>
-bool TreeTransform<Derived>::TransformRequiresExprRequirements(
-    ArrayRef<concepts::Requirement *> Reqs,
-    SmallVectorImpl<concepts::Requirement *> &Transformed) {
-  for (concepts::Requirement *Req : Reqs) {
-    concepts::Requirement *TransReq = nullptr;
-    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
-      TransReq = getDerived().TransformTypeRequirement(TypeReq);
-    else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
-      TransReq = getDerived().TransformExprRequirement(ExprReq);
-    else
-      TransReq = getDerived().TransformNestedRequirement(
-                     cast<concepts::NestedRequirement>(Req));
-    if (!TransReq)
-      return true;
-    Transformed.push_back(TransReq);
-  }
-  return false;
-}
-
-template<typename Derived>
-concepts::TypeRequirement *
-TreeTransform<Derived>::TransformTypeRequirement(
-    concepts::TypeRequirement *Req) {
-  if (Req->isSubstitutionFailure()) {
-    if (getDerived().AlwaysRebuild())
-      return getDerived().RebuildTypeRequirement(
-              Req->getSubstitutionDiagnostic());
-    return Req;
-  }
-  TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
-  if (!TransType)
-    return nullptr;
-  return getDerived().RebuildTypeRequirement(TransType);
-}
-
-template<typename Derived>
-concepts::ExprRequirement *
-TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
-  llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
-  if (Req->isExprSubstitutionFailure())
-    TransExpr = Req->getExprSubstitutionDiagnostic();
-  else {
-    ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
-    if (TransExprRes.isInvalid())
-      return nullptr;
-    TransExpr = TransExprRes.get();
-  }
-
-  llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
-  const auto &RetReq = Req->getReturnTypeRequirement();
-  if (RetReq.isEmpty())
-    TransRetReq.emplace();
-  else if (RetReq.isSubstitutionFailure())
-    TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
-  else if (RetReq.isTypeConstraint()) {
-    TemplateParameterList *OrigTPL =
-        RetReq.getTypeConstraintTemplateParameterList();
-    TemplateParameterList *TPL =
-        getDerived().TransformTemplateParameterList(OrigTPL);
-    if (!TPL)
-      return nullptr;
-    TransRetReq.emplace(TPL);
-  }
-  assert(TransRetReq.hasValue() &&
-         "All code paths leading here must set TransRetReq");
-  if (Expr *E = TransExpr.dyn_cast<Expr *>())
-    return getDerived().RebuildExprRequirement(E, Req->isSimple(),
-                                               Req->getNoexceptLoc(),
-                                               std::move(*TransRetReq));
-  return getDerived().RebuildExprRequirement(
-      TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
-      Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
-}
-
-template<typename Derived>
-concepts::NestedRequirement *
-TreeTransform<Derived>::TransformNestedRequirement(
-    concepts::NestedRequirement *Req) {
-  if (Req->isSubstitutionFailure()) {
-    if (getDerived().AlwaysRebuild())
-      return getDerived().RebuildNestedRequirement(
-          Req->getSubstitutionDiagnostic());
-    return Req;
-  }
-  ExprResult TransConstraint =
-      getDerived().TransformExpr(Req->getConstraintExpr());
-  if (TransConstraint.isInvalid())
-    return nullptr;
-  return getDerived().RebuildNestedRequirement(TransConstraint.get());
-}
 
 template<typename Derived>
 ExprResult

diff  --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index f93f1f77405d..cdb5b17022c2 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -402,7 +402,6 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
   case Decl::Binding:
   case Decl::Concept:
   case Decl::LifetimeExtendedTemporary:
-  case Decl::RequiresExprBody:
     return false;
 
   // These indirectly derive from Redeclarable<T> but are not actually

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 4fd079e9d8e1..96a7d5ae0a31 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -375,7 +375,6 @@ namespace clang {
     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
     DeclID VisitTemplateDecl(TemplateDecl *D);
     void VisitConceptDecl(ConceptDecl *D);
-    void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
     RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
     void VisitClassTemplateDecl(ClassTemplateDecl *D);
     void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
@@ -2038,9 +2037,6 @@ void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {
   mergeMergeable(D);
 }
 
-void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
-}
-
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
@@ -3843,9 +3839,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
   case DECL_CONCEPT:
     D = ConceptDecl::CreateDeserialized(Context, ID);
     break;
-  case DECL_REQUIRES_EXPR_BODY:
-    D = RequiresExprBodyDecl::CreateDeserialized(Context, ID);
-    break;
   case DECL_STATIC_ASSERT:
     D = StaticAssertDecl::CreateDeserialized(Context, ID);
     break;

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 5dd0ef9d43c3..f558c26b5f1e 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -724,15 +724,27 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
   E->setRParenLoc(readSourceLocation());
 }
 
-static ConstraintSatisfaction
-readConstraintSatisfaction(ASTRecordReader &Record) {
+void ASTStmtReader::VisitConceptSpecializationExpr(
+        ConceptSpecializationExpr *E) {
+  VisitExpr(E);
+  unsigned NumTemplateArgs = Record.readInt();
+  E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
+  E->TemplateKWLoc = Record.readSourceLocation();
+  E->ConceptName = Record.readDeclarationNameInfo();
+  E->NamedConcept = readDeclAs<ConceptDecl>();
+  E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
+  llvm::SmallVector<TemplateArgument, 4> Args;
+  for (unsigned I = 0; I < NumTemplateArgs; ++I)
+    Args.push_back(Record.readTemplateArgument());
+  E->setTemplateArguments(Args);
   ConstraintSatisfaction Satisfaction;
   Satisfaction.IsSatisfied = Record.readInt();
   if (!Satisfaction.IsSatisfied) {
     unsigned NumDetailRecords = Record.readInt();
     for (unsigned i = 0; i != NumDetailRecords; ++i) {
       Expr *ConstraintExpr = Record.readExpr();
-      if (bool IsDiagnostic = Record.readInt()) {
+      bool IsDiagnostic = Record.readInt();
+      if (IsDiagnostic) {
         SourceLocation DiagLocation = Record.readSourceLocation();
         std::string DiagMessage = Record.readString();
         Satisfaction.Details.emplace_back(
@@ -743,137 +755,8 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
         Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr());
     }
   }
-  return Satisfaction;
-}
-
-void ASTStmtReader::VisitConceptSpecializationExpr(
-        ConceptSpecializationExpr *E) {
-  VisitExpr(E);
-  unsigned NumTemplateArgs = Record.readInt();
-  E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
-  E->TemplateKWLoc = Record.readSourceLocation();
-  E->ConceptName = Record.readDeclarationNameInfo();
-  E->NamedConcept = readDeclAs<ConceptDecl>();
-  E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
-  llvm::SmallVector<TemplateArgument, 4> Args;
-  for (unsigned I = 0; I < NumTemplateArgs; ++I)
-    Args.push_back(Record.readTemplateArgument());
-  E->setTemplateArguments(Args);
-  E->Satisfaction = E->isValueDependent() ? nullptr :
-      ASTConstraintSatisfaction::Create(Record.getContext(),
-                                        readConstraintSatisfaction(Record));
-}
-
-static concepts::Requirement::SubstitutionDiagnostic *
-readSubstitutionDiagnostic(ASTRecordReader &Record) {
-  std::string SubstitutedEntity = Record.readString();
-  SourceLocation DiagLoc = Record.readSourceLocation();
-  std::string DiagMessage = Record.readString();
-  return new (Record.getContext())
-      concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
-                                                    DiagMessage};
-}
-
-void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
-  VisitExpr(E);
-  unsigned NumLocalParameters = Record.readInt();
-  unsigned NumRequirements = Record.readInt();
-  E->RequiresExprBits.RequiresKWLoc = Record.readSourceLocation();
-  E->RequiresExprBits.IsSatisfied = Record.readInt();
-  E->Body = Record.readDeclAs<RequiresExprBodyDecl>();
-  llvm::SmallVector<ParmVarDecl *, 4> LocalParameters;
-  for (unsigned i = 0; i < NumLocalParameters; ++i)
-    LocalParameters.push_back(cast<ParmVarDecl>(Record.readDecl()));
-  std::copy(LocalParameters.begin(), LocalParameters.end(),
-            E->getTrailingObjects<ParmVarDecl *>());
-  llvm::SmallVector<concepts::Requirement *, 4> Requirements;
-  for (unsigned i = 0; i < NumRequirements; ++i) {
-    auto RK =
-        static_cast<concepts::Requirement::RequirementKind>(Record.readInt());
-    concepts::Requirement *R = nullptr;
-    switch (RK) {
-      case concepts::Requirement::RK_Type: {
-        auto Status =
-            static_cast<concepts::TypeRequirement::SatisfactionStatus>(
-                Record.readInt());
-        if (Status == concepts::TypeRequirement::SS_SubstitutionFailure)
-          R = new (Record.getContext())
-              concepts::TypeRequirement(readSubstitutionDiagnostic(Record));
-        else
-          R = new (Record.getContext())
-              concepts::TypeRequirement(Record.readTypeSourceInfo());
-      } break;
-      case concepts::Requirement::RK_Simple:
-      case concepts::Requirement::RK_Compound: {
-        auto Status =
-            static_cast<concepts::ExprRequirement::SatisfactionStatus>(
-                Record.readInt());
-        llvm::PointerUnion<concepts::Requirement::SubstitutionDiagnostic *,
-                           Expr *> E;
-        if (Status == concepts::ExprRequirement::SS_ExprSubstitutionFailure) {
-          E = readSubstitutionDiagnostic(Record);
-        } else
-          E = Record.readExpr();
-
-        llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
-        ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
-        SourceLocation NoexceptLoc;
-        if (RK == concepts::Requirement::RK_Simple) {
-          Req.emplace();
-        } else {
-          NoexceptLoc = Record.readSourceLocation();
-          switch (auto returnTypeRequirementKind = Record.readInt()) {
-            case 0:
-              // No return type requirement.
-              Req.emplace();
-              break;
-            case 1: {
-              // type-constraint
-              TemplateParameterList *TPL = Record.readTemplateParameterList();
-              if (Status >=
-                  concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
-                SubstitutedConstraintExpr =
-                    cast<ConceptSpecializationExpr>(Record.readExpr());
-              Req.emplace(TPL);
-            } break;
-            case 2:
-              // Substitution failure
-              Req.emplace(readSubstitutionDiagnostic(Record));
-              break;
-          }
-        }
-        if (Expr *Ex = E.dyn_cast<Expr *>())
-          R = new (Record.getContext()) concepts::ExprRequirement(
-                  Ex, RK == concepts::Requirement::RK_Simple, NoexceptLoc,
-                  std::move(*Req), Status, SubstitutedConstraintExpr);
-        else
-          R = new (Record.getContext()) concepts::ExprRequirement(
-                  E.get<concepts::Requirement::SubstitutionDiagnostic *>(),
-                  RK == concepts::Requirement::RK_Simple, NoexceptLoc,
-                  std::move(*Req));
-      } break;
-      case concepts::Requirement::RK_Nested: {
-        if (bool IsSubstitutionDiagnostic = Record.readInt()) {
-          R = new (Record.getContext()) concepts::NestedRequirement(
-              readSubstitutionDiagnostic(Record));
-          break;
-        }
-        Expr *E = Record.readExpr();
-        if (E->isInstantiationDependent())
-          R = new (Record.getContext()) concepts::NestedRequirement(E);
-        else
-          R = new (Record.getContext())
-              concepts::NestedRequirement(Record.getContext(), E,
-                                          readConstraintSatisfaction(Record));
-      } break;
-    }
-    if (!R)
-      continue;
-    Requirements.push_back(R);
-  }
-  std::copy(Requirements.begin(), Requirements.end(),
-            E->getTrailingObjects<concepts::Requirement *>());
-  E->RBraceLoc = Record.readSourceLocation();
+  E->Satisfaction = ASTConstraintSatisfaction::Create(Record.getContext(),
+                                                      Satisfaction);
 }
 
 void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
@@ -3683,18 +3566,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       S = new (Context) DependentCoawaitExpr(Empty);
       break;
 
-    case EXPR_CONCEPT_SPECIALIZATION: {
+    case EXPR_CONCEPT_SPECIALIZATION:
       unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields];
       S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs);
       break;
-    }
-
-    case EXPR_REQUIRES:
-      unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields];
-      unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1];
-      S = RequiresExpr::Create(Context, Empty, numLocalParameters,
-                               numRequirement);
-      break;
+      
     }
 
     // We hit a STMT_STOP, so we're done with this expression.

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index c216b14661d4..8247f5a84eca 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -885,7 +885,6 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
   RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
   RECORD(DECL_CONCEPT);
-  RECORD(DECL_REQUIRES_EXPR_BODY);
   RECORD(DECL_TYPE_ALIAS_TEMPLATE);
   RECORD(DECL_STATIC_ASSERT);
   RECORD(DECL_CXX_BASE_SPECIFIERS);

diff  --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 459e61713ed1..b2a8c118d401 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -104,7 +104,6 @@ namespace clang {
     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
     void VisitTemplateDecl(TemplateDecl *D);
     void VisitConceptDecl(ConceptDecl *D);
-    void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
     void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
     void VisitClassTemplateDecl(ClassTemplateDecl *D);
     void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -1482,10 +1481,6 @@ void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
   Code = serialization::DECL_CONCEPT;
 }
 
-void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
-  Code = serialization::DECL_REQUIRES_EXPR_BODY;
-}
-
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   VisitRedeclarable(D);
 

diff  --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 1b118c257a4c..9231f3b2b9ba 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Serialization/ASTRecordWriter.h"
-#include "clang/Sema/DeclSpec.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -389,9 +388,19 @@ void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
   Code = serialization::EXPR_DEPENDENT_COAWAIT;
 }
 
-static void
-addConstraintSatisfaction(ASTRecordWriter &Record,
-                          const ASTConstraintSatisfaction &Satisfaction) {
+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.AddDeclarationNameInfo(E->getConceptNameInfo());
+  Record.AddDeclRef(E->getNamedConcept());
+  Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
+  for (const TemplateArgument &Arg : TemplateArgs)
+    Record.AddTemplateArgument(Arg);
+  const ASTConstraintSatisfaction &Satisfaction = E->getSatisfaction();
   Record.push_back(Satisfaction.IsSatisfied);
   if (!Satisfaction.IsSatisfied) {
     Record.push_back(Satisfaction.NumRecords);
@@ -409,98 +418,10 @@ addConstraintSatisfaction(ASTRecordWriter &Record,
       }
     }
   }
-}
-
-static void
-addSubstitutionDiagnostic(
-    ASTRecordWriter &Record,
-    const concepts::Requirement::SubstitutionDiagnostic *D) {
-  Record.AddString(D->SubstitutedEntity);
-  Record.AddSourceLocation(D->DiagLoc);
-  Record.AddString(D->DiagMessage);
-}
-
-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.AddDeclarationNameInfo(E->getConceptNameInfo());
-  Record.AddDeclRef(E->getNamedConcept());
-  Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
-  for (const TemplateArgument &Arg : TemplateArgs)
-    Record.AddTemplateArgument(Arg);
-  if (!E->isValueDependent())
-    addConstraintSatisfaction(Record, E->getSatisfaction());
 
   Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
 }
 
-void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
-  VisitExpr(E);
-  Record.push_back(E->getLocalParameters().size());
-  Record.push_back(E->getRequirements().size());
-  Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
-  Record.push_back(E->RequiresExprBits.IsSatisfied);
-  Record.AddDeclRef(E->getBody());
-  for (ParmVarDecl *P : E->getLocalParameters())
-    Record.AddDeclRef(P);
-  for (concepts::Requirement *R : E->getRequirements()) {
-    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
-      Record.push_back(concepts::Requirement::RK_Type);
-      Record.push_back(TypeReq->Status);
-      if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
-        addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
-      else
-        Record.AddTypeSourceInfo(TypeReq->getType());
-    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
-      Record.push_back(ExprReq->getKind());
-      Record.push_back(ExprReq->Status);
-      if (ExprReq->isExprSubstitutionFailure()) {
-        addSubstitutionDiagnostic(Record,
-         ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>());
-      } else
-        Record.AddStmt(ExprReq->Value.get<Expr *>());
-      if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
-        Record.AddSourceLocation(ExprReq->NoexceptLoc);
-        const auto &RetReq = ExprReq->getReturnTypeRequirement();
-        if (RetReq.isSubstitutionFailure()) {
-          Record.push_back(2);
-          addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
-        } else if (RetReq.isTypeConstraint()) {
-          Record.push_back(1);
-          Record.AddTemplateParameterList(
-              RetReq.getTypeConstraintTemplateParameterList());
-          if (ExprReq->Status >=
-              concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
-            Record.AddStmt(
-                ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
-        } else {
-          assert(RetReq.isEmpty());
-          Record.push_back(0);
-        }
-      }
-    } else {
-      auto *NestedReq = cast<concepts::NestedRequirement>(R);
-      Record.push_back(concepts::Requirement::RK_Nested);
-      Record.push_back(NestedReq->isSubstitutionFailure());
-      if (NestedReq->isSubstitutionFailure()){
-        addSubstitutionDiagnostic(Record,
-                                  NestedReq->getSubstitutionDiagnostic());
-      } else {
-        Record.AddStmt(NestedReq->Value.get<Expr *>());
-        if (!NestedReq->isDependent())
-          addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
-      }
-    }
-  }
-  Record.AddSourceLocation(E->getEndLoc());
-
-  Code = serialization::EXPR_REQUIRES;
-}
-
 
 void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
   VisitStmt(S);

diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index b542cf2c0303..f917a4c8637b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1386,7 +1386,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
     case Stmt::AsTypeExprClass:
     case Stmt::ConceptSpecializationExprClass:
     case Stmt::CXXRewrittenBinaryOperatorClass:
-    case Stmt::RequiresExprClass:
       // Fall through.
 
     // Cases we intentionally don't evaluate, since they don't need

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
deleted file mode 100644
index 578efb5b24ea..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-static_assert(requires { { 0 }; });
-static_assert(requires { { "aaaa" }; });
-static_assert(requires { { (0).da }; }); // expected-error{{member reference base type 'int' is not a structure or union}}
-
-void foo() {}
-static_assert(requires { { foo() }; });
-
-// Substitution failure in expression
-
-struct A {};
-struct B {
-    B operator+(const B &other) const { return other; }
-};
-struct C {
-    C operator+(C &other) const { return other; }
-};
-
-template<typename T> requires requires (T a, const T& b) { { a + b }; } // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}} expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}}
-struct r1 {};
-
-using r1i1 = r1<int>;
-using r1i2 = r1<A>; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}}
-using r1i3 = r1<B>;
-using r1i4 = r1<C>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}
-
-struct D { void foo() {} };
-
-template<typename T> requires requires (T a) { { a.foo() }; } // expected-note{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}} expected-note{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}} expected-note{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}}
-struct r2 {};
-
-using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
-using r2i2 = r2<A>; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}}
-using r2i3 = r2<D>;
-using r2i4 = r2<const D>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}
-
-template<typename T> requires requires { { sizeof(T) }; } // expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}}
-struct r3 {};
-
-using r3i1 = r3<int>;
-using r3i2 = r3<A>;
-using r3i3 = r3<A &>;
-using r3i4 = r3<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
-using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
-
-// Non-dependent expressions
-
-template<typename T> requires requires (T t) { { 0 }; { "a" }; { (void)'a' }; }
-struct r4 {};
-
-using r4i1 = r4<int>;
-using r4i2 = r4<int[10]>;
-using r4i3 = r4<int(int)>;
-
-// Noexcept requirement
-void maythrow() { }
-static_assert(!requires { { maythrow() } noexcept; });
-static_assert(requires { { 1 } noexcept; });
-
-struct E { void operator++(int) noexcept; };
-struct F { void operator++(int); };
-
-template<typename T> requires requires (T t) { { t++ } noexcept; } // expected-note{{because 't ++' may throw an exception}}
-struct r5 {};
-
-using r5i1 = r5<int>;
-using r5i2 = r5<E>;
-using r5i2 = r5<F>; // expected-error{{constraints not satisfied for class template 'r5' [with T = F]}}
-
-template<typename T> requires requires (T t) { { t.foo() } noexcept; } // expected-note{{because 't.foo()' would be invalid: no member named 'foo' in 'E'}}
-struct r6 {};
-
-using r6i = r6<E>; // expected-error{{constraints not satisfied for class template 'r6' [with T = E]}}
-
-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>;
-
-template<typename T>
-concept Large = sizeof(T) >= 4; // expected-note{{because 'sizeof(short) >= 4' (2 >= 4) evaluated to false}}
-
-template<typename T> requires requires (T t) { { t } -> Large; } // expected-note{{because 'decltype(t)' (aka 'short') does not satisfy 'Large':}}
-struct r7 {};
-
-using r7i1 = r7<int>;
-using r7i2 = r7<short>; // expected-error{{constraints not satisfied for class template 'r7' [with T = short]}}
-
-template<typename T> requires requires (T t) { { t } -> Same<T>; }
-struct r8 {};
-
-using r8i1 = r8<int>;
-using r8i2 = r8<short*>;
-
-// Substitution failure in type constraint
-
-template<typename T> requires requires (T t) { { t } -> Same<typename T::type>; } // expected-note{{because 'Same<expr-type, typename T::type>' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
-struct r9 {};
-
-struct M { using type = M; };
-
-using r9i1 = r9<M>;
-using r9i2 = r9<int>; // expected-error{{constraints not satisfied for class template 'r9' [with T = int]}}
-
-// Substitution failure in both expression and return type requirement
-
-template<typename T> requires requires (T t) { { t.foo() } -> Same<typename T::type>; } // expected-note{{because 't.foo()' would be invalid: member reference base type 'int' is not a structure or union}}
-struct r10 {};
-
-using r10i = r10<int>; // expected-error{{constraints not satisfied for class template 'r10' [with T = int]}}
-
-// Non-type concept in type constraint
-
-template<int T>
-concept IsEven = (T % 2) == 0;
-
-template<typename T> requires requires (T t) { { t } -> IsEven; } // expected-error{{concept named in type constraint is not a type concept}}
-struct r11 {};
-
-// C++ [expr.prim.req.compound] Example
-namespace std_example {
-  template<typename T> concept C1 =
-    requires(T x) {
-      {x++};
-    };
-
-  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_as = is_same_v<T, U>;
-  // expected-note at -1 {{because 'is_same_v<int, int *>' evaluated to false}}
-
-  static_assert(C1<int>);
-  static_assert(C1<int*>);
-  template<C1 T> struct C1_check {};
-  using c1c1 = C1_check<int>;
-  using c1c2 = C1_check<int[10]>;
-
-  template<typename T> concept C2 =
-    requires(T x) {
-      {*x} -> same_as<typename T::inner>;
-      // expected-note at -1{{because type constraint 'same_as<int, typename T2::inner>' was not satisfied:}}
-      // expected-note at -2{{because '*x' would be invalid: indirection requires pointer operand ('int' invalid)}}
-    };
-
-  struct T1 {
-    using inner = int;
-    inner operator *() { return 0; }
-  };
-  struct T2 {
-    using inner = int *;
-    int operator *() { return 0; }
-  };
-  static_assert(C2<T1>);
-  template<C2 T> struct C2_check {}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'std_example::T2' does not satisfy 'C2'}}
-  using c2c1 = C2_check<int>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = int]}}
-  using c2c2 = C2_check<T2>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::T2]}}
-
-  template<typename T>
-  void g(T t) noexcept(sizeof(T) == 1) {}
-
-  template<typename T> concept C5 =
-    requires(T x) {
-      {g(x)} noexcept; // expected-note{{because 'g(x)' may throw an exception}}
-    };
-
-  static_assert(C5<char>);
-  template<C5 T> struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}}
-  using c5 = C5_check<short>; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}}
-}
\ No newline at end of file

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp
deleted file mode 100644
index ea3453201902..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-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> struct identity { using type = T; };
-template<typename T> using identity_t = T;
-
-// Type requirements
-template<typename T> requires requires { typename identity_t<T>; }
-struct r1;
-template<typename U> requires requires { typename identity_t<U>; } // expected-note{{previous template declaration is here}}
-struct r1;
-template<typename T> requires requires { typename identity_t<T*>; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r1;
-template<typename T> requires requires { typename ::identity_t<T>; }
-struct r1;
-
-template<typename Y> requires requires { typename identity<Y>::type; }
-struct r2;
-template<typename U> requires requires { typename identity<U>::type; }
-struct r2;
-template<typename T> requires requires { typename ::identity<T>::type; } // expected-note 2{{previous template declaration is here}}
-struct r2;
-template<typename T> requires requires { typename identity<T>::typr; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r2;
-namespace ns {
-  template<typename T> struct identity { using type = T; };
-}
-template<typename T> requires requires { typename ns::identity<T>::type; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r2;
-
-template<typename T> requires requires { typename T::template identity<T>::type; }
-struct r3;
-template<typename U> requires requires { typename U::template identity<U>::type; } // expected-note{{previous template declaration is here}}
-struct r3;
-template<typename T> requires requires { typename T::template identitr<T>::type; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r3;
-
-template<typename T> requires requires { typename T::template temp<>; }
-struct r4;
-template<typename U> requires requires { typename U::template temp<>; }
-struct r4;
-
-// Expr requirements
-template<typename T> requires requires { 0; } // expected-note{{previous template declaration is here}}
-struct r5;
-template<typename T> requires requires { 1; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r5;
-
-template<typename T>
-concept C1 = true;
-
-template<typename T> requires requires { sizeof(T); }
-struct r6;
-template<typename U> requires requires { sizeof(U); } // expected-note{{previous template declaration is here}}
-struct r6;
-template<typename U> requires requires { sizeof(U) - 1; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r6;
-template<typename T> requires requires { { sizeof(T) }; } // expected-note 2{{previous template declaration is here}}
-struct r6;
-template<typename T> requires requires { { sizeof(T) } noexcept; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r6;
-template<typename T> requires requires { { sizeof(T) } -> C1; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r6;
-
-template<typename T> requires requires { { sizeof(T) } -> C1; }
-struct r7;
-template<typename U> requires requires { { sizeof(U) } -> C1; }
-struct r7;
-template<typename T> requires requires { { sizeof(T) } -> C1<>; } // expected-note {{previous template declaration is here}}
-struct r7;
-template<typename U> requires requires { { sizeof(U) }; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r7;
-
-template<typename T, typename U>
-concept C2 = true;
-
-template<typename T> requires requires { { sizeof(T) } -> C2<T>; }
-struct r8;
-template<typename U> requires requires { { sizeof(U) } -> C2<U>; } // expected-note{{previous template declaration is here}}
-struct r8;
-template<typename T> requires requires { { sizeof(T) } -> C2<T*>; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r8;
-
-// Nested requirements
-template<typename T> requires requires { requires sizeof(T) == 0; }
-struct r9;
-template<typename U> requires requires { requires sizeof(U) == 0; } // expected-note{{previous template declaration is here}}
-struct r9;
-template<typename T> requires requires { requires sizeof(T) == 1; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r9;
-
-// Parameter list
-template<typename T> requires requires { requires true; }
-struct r10;
-template<typename T> requires requires() { requires true; } // expected-note{{previous template declaration is here}}
-struct r10;
-template<typename T> requires requires(T i) { requires true; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r10;
-
-template<typename T> requires requires(T i, T *j) { requires true; } // expected-note 2{{previous template declaration is here}}
-struct r11;
-template<typename T> requires requires(T i) { requires true; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r11;
-template<typename T> requires requires(T i, T *j, T &k) { requires true; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r11;
-
-// Parameter names
-template<typename T> requires requires(int i) { requires sizeof(i) == 1; }
-struct r12;
-template<typename T> requires requires(int j) { requires sizeof(j) == 1; } // expected-note 2{{previous template declaration is here}}
-struct r12;
-template<typename T> requires requires(int k) { requires sizeof(k) == 2; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r12;
-template<typename T> requires requires(const int k) { requires sizeof(k) == 1; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r12;
-
-// Order of requirements
-template<typename T> requires requires { requires true; 0; }
-struct r13;
-template<typename T> requires requires { requires true; 0; } // expected-note{{previous template declaration is here}}
-struct r13;
-template<typename T> requires requires { 0; requires true; } // expected-error{{requires clause 
diff ers in template redeclaration}}
-struct r13;

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
deleted file mode 100644
index f8776832d33f..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-static_assert(requires { requires true; });
-
-template<typename T> requires requires { requires false; } // expected-note{{because 'false' evaluated to false}}
-struct r1 {};
-
-using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
-
-template<typename T> requires requires { requires sizeof(T) == 0; } // expected-note{{because 'sizeof(int) == 0' (4 == 0) evaluated to false}}
-struct r2 {};
-
-using r2i = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
-
-template<typename T> requires requires (T t) { requires sizeof(t) == 0; } // expected-note{{because 'sizeof (t) == 0' (4 == 0) evaluated to false}}
-struct r3 {};
-
-using r3i = r3<int>; // expected-error{{constraints not satisfied for class template 'r3' [with T = int]}}
-
-template<typename T>
-struct X {
-    template<typename U> requires requires (U u) { requires sizeof(u) == sizeof(T); } // expected-note{{because 'sizeof (u) == sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}
-    struct r4 {};
-};
-
-using r4i = X<void>::r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with U = int]}}
-
-// C++ [expr.prim.req.nested] Examples
-namespace std_example {
-  template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}}
-  template<typename T> concept D =
-    requires (T t) {
-      requires C1<decltype (+t)>; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}}
-  };
-
-  struct T1 { char operator+() { return 'a'; } };
-  static_assert(D<T1>);
-  template<D T> struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}}
-  using dc1 = D_check<short>; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}}
-
-  template<typename T>
-  concept C2 = requires (T a) { // expected-note{{'a' declared here}}
-      requires sizeof(a) == 4; // OK
-      requires a == 0; // expected-error{{constraint variable 'a' cannot be used in an evaluated context}}
-    };
-}
\ No newline at end of file

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp
deleted file mode 100644
index a1a745253dd4..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-// Examples from standard
-
-template<typename T, typename U>
-concept convertible_to = requires(T t) { U(t); };
-
-template<typename T>
-concept R = requires (T i) {
-  typename T::type;
-  {*i} -> convertible_to<const typename T::type&>;
-};
-
-template<typename T> requires R<T> struct S {};
-
-struct T {
-  using type = int;
-  type i;
-  const type &operator*() { return i; }
-};
-
-using si = S<T>;
-
-template<typename T>
-requires requires (T x) { x + x; } // expected-note{{because 'x + x' would be invalid: invalid operands to binary expression ('T' and 'T')}}
-T add(T a, T b) { return a + b; } // expected-note{{candidate template ignored: constraints not satisfied [with T = T]}}
-
-int x = add(1, 2);
-int y = add(T{}, T{}); // expected-error{{no matching function for call to 'add'}}
-
-template<typename T>
-concept C = requires (T x) { x + x; }; // expected-note{{because 'x + x' would be invalid: invalid operands to binary expression ('T' and 'T')}}
-template<typename T> requires C<T> // expected-note{{because 'T' does not satisfy 'C'}}
-T add2(T a, T b) { return a + b; } // expected-note{{candidate template ignored: constraints not satisfied [with T = T]}}
-
-int z = add2(1, 2);
-int w = add2(T{}, T{}); // expected-error{{no matching function for call to 'add2'}}
\ No newline at end of file

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
deleted file mode 100644
index f9d8c3eed111..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-using A = int;
-
-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_as = is_same_v<T, U>;
-
-static_assert(requires { requires true; 0; typename A;
-                         { 0 } -> same_as<int>; });
-static_assert(is_same_v<bool, decltype(requires { requires false; })>);
-
-// Check that requires expr is an unevaluated context.
-struct Y {
-  int i;
-  static constexpr bool r = requires { i; };
-};
-
-template<typename T> requires requires (T t) {
-  requires false; // expected-note{{because 'false' evaluated to false}}
-  requires false;
-  requires requires {
-    requires false;
-  };
-}
-struct r1 { };
-
-using r1i = r1<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r1' [with T = int]}}
-
-template<typename T> requires requires (T t) {
-  requires requires {
-    requires false; // expected-note{{because 'false' evaluated to false}}
-  };
-}
-struct r2 { };
-
-using r2i = r2<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r2' [with T = int]}}
-
-template<typename T> requires requires (T t) {
-  requires requires {
-    requires true;
-  };
-  requires true;
-  requires requires {
-    requires false; // expected-note{{because 'false' evaluated to false}}
-  };
-}
-struct r3 { };
-
-using r3i = r3<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r3' [with T = int]}}
-
-template<typename T>
-struct S { static const int s = T::value; };
-
-template<typename T> requires requires { T::value; S<T>::s; }
-// expected-note at -1 {{because 'T::value' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
-struct r4 { };
-
-using r4i = r4<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r4' [with T = int]}}
\ No newline at end of file

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
deleted file mode 100644
index a5e6c3057fe6..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// RUN: %clang_cc1 %s -I%S -std=c++2a -fconcepts-ts -verify
-
-namespace std { struct type_info; }
-
-static_assert(requires { 0; });
-static_assert(requires { "aaaa"; });
-static_assert(requires { (0).da; }); // expected-error{{member reference base type 'int' is not a structure or union}}
-
-struct A {};
-struct B {
-    B operator+(const B &other) const { return other; }
-};
-struct C {
-    C operator+(C &other) const { return other; }
-};
-
-template<typename T> requires requires (T a, const T& b) { a + b; }
-// expected-note at -1{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}}
-// expected-note at -2{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}}
-struct r1 {};
-
-using r1i1 = r1<int>;
-using r1i2 = r1<A>; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}}
-using r1i3 = r1<B>;
-using r1i4 = r1<C>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}
-
-struct D { void foo() {} };
-
-template<typename T> requires requires (T a) { a.foo(); }
-// expected-note at -1{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}}
-// expected-note at -2{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}}
-// expected-note at -3{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}}
-struct r2 {};
-
-using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
-using r2i2 = r2<A>; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}}
-using r2i3 = r2<D>;
-using r2i4 = r2<const D>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}
-
-template<typename T> requires requires { sizeof(T); }
-// expected-note at -1{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}
-// expected-note at -2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}}
-struct r3 {};
-
-using r3i1 = r3<int>;
-using r3i2 = r3<A>;
-using r3i3 = r3<A &>;
-using r3i4 = r3<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
-using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
-
-template<typename T> requires requires (T t) { 0; "a"; (void)'a'; }
-struct r4 {};
-
-using r4i1 = r4<int>;
-using r4i2 = r4<int[10]>;
-using r4i3 = r4<int(int)>;
-
-template<class T> void f(T) = delete;
-template<class T> requires (sizeof(T) == 1) void f(T) { }
-
-template<typename T> requires requires(T t) { f(t); }
-// expected-note at -1{{because 'f(t)' would be invalid: call to deleted function 'f'}}
-struct r5 {};
-
-using r5i1 = r5<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r5' [with T = int]}}
-using r5i2 = r5<char>;
-
-template<typename T>
-struct E {
-  struct non_default_constructible { non_default_constructible(T t) { } };
-};
-
-template<typename T> requires requires(T t) { typename E<T>::non_default_constructible{}; }
-// expected-note at -1 {{because 'typename E<T>::non_default_constructible({})' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}
-struct r6 {};
-
-using r6i1 = r6<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r6' [with T = int]}}
-
-template<typename T> requires requires(T t) { typename E<T>::non_default_constructible(); }
-// expected-note at -1 {{because 'typename E<T>::non_default_constructible()' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}
-struct r7 {};
-
-using r7i1 = r7<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r7' [with T = int]}}
-
-// C++ [expr.prim.req.simple] Example
-namespace std_example {
-  template<typename T> concept C =
-    requires (T a, T b) { // expected-note{{because substituted constraint expression is ill-formed: argument may not have 'void' type}}
-      a + b; // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('int *' and 'int *')}}
-    };
-
-  static_assert(C<int>);
-  template<C T> struct C_check {}; // expected-note{{because 'void' does not satisfy 'C'}} expected-note{{because 'int *' does not satisfy 'C'}}
-  using c1c1 = C_check<void>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = void]}}
-  using c1c2 = C_check<int *>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = int *]}}
-}
-
-// typeid() of an expression becomes potentially evaluated if the expression is
-// of a polymorphic type.
-class X { virtual ~X(); };
-constexpr bool b = requires (X &x) { static_cast<int(*)[(typeid(x), 0)]>(nullptr); };
-// expected-error at -1{{constraint variable 'x' cannot be used in an evaluated context}}
-// expected-note at -2{{'x' declared here}}

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
deleted file mode 100644
index 8e402a88c403..000000000000
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-using A = int;
-
-template<typename T> using identity_t = T; // expected-note 4{{template is declared here}}}
-
-template<typename T> struct identity { using type = T; };
-// expected-note at -1 2{{template is declared here}}
-
-struct C {};
-
-struct D { static int type; }; // expected-note{{referenced member 'type' is declared here}}
-
-// Basic unqualified and global-qualified lookups
-
-static_assert(requires { typename A; typename ::A; });
-static_assert(requires { typename identity_t<A>; typename ::identity_t<A>; });
-static_assert(!requires { typename identity_t<A, A>; }); // expected-error{{too many template arguments for alias template 'identity_t'}}
-static_assert(!requires { typename ::identity_t<A, A>; }); // expected-error{{too many template arguments for alias template 'identity_t'}}
-static_assert(requires { typename identity<A>; });
-static_assert(!requires { typename identity; });
-// expected-error at -1 {{typename specifier refers to class template; argument deduction not allowed here}}
-static_assert(!requires { typename ::identity; });
-// expected-error at -1 {{typename specifier refers to class template; argument deduction not allowed here}}
-static_assert(!requires { typename identity_t; });
-// expected-error at -1 {{typename specifier refers to alias template; argument deduction not allowed here}}
-static_assert(!requires { typename ::identity_t; });
-// expected-error at -1 {{typename specifier refers to alias template; argument deduction not allowed here}}
-
-namespace ns {
-  using B = int;
-  int C = 0;
-  // expected-note at -1 {{referenced 'C' is declared here}}
-  static_assert(requires { typename A; typename B; typename ::A; });
-  static_assert(!requires { typename ns::A; }); // expected-error{{no type named 'A' in namespace 'ns'}}
-  static_assert(!requires { typename ::B; }); // expected-error{{no type named 'B' in the global namespace}}
-  static_assert(requires { typename C; });
-  // expected-error at -1 {{typename specifier refers to non-type 'C'}}
-}
-
-// member type lookups
-
-static_assert(requires { typename identity<int>::type; typename ::identity<int>::type; });
-static_assert(!requires { typename identity<int>::typr; }); // expected-error{{no type named 'typr' in 'identity<int>'}}
-static_assert(!requires { typename ::identity<int>::typr; }); // expected-error{{no type named 'typr' in 'identity<int>'}}
-
-template<typename T> requires requires { typename T::type; }
-// expected-note at -1 {{because 'typename T::type' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
-// expected-note at -2 {{because 'typename T::type' would be invalid: no type named 'type' in 'C'}}
-// expected-note at -3 {{because 'typename T::type' would be invalid: typename specifier refers to non-type member 'type' in 'D'}}
-// expected-note at -4 {{in instantiation of template class 'invalid<D>' requested here}}
-// expected-note at -5 {{in instantiation of requirement here}}
-// expected-note at -6 {{while substituting template arguments into constraint expression here}}
-// expected-note at -7 {{because 'typename T::type' would be invalid}}
-struct r1 {};
-
-using r1i1 = r1<identity<int>>;
-using r1i2 = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
-using r1i3 = r1<C>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}
-using r1i4 = r1<D>; // expected-error{{constraints not satisfied for class template 'r1' [with T = D]}}
-
-template<typename T> struct invalid { typename T::type x; };
-// expected-error at -1 {{typename specifier refers to non-type member 'type' in 'D'}}
-using r1i5 = r1<invalid<D>>;
-// expected-error at -1 {{constraints not satisfied for class template 'r1' [with T = invalid<D>]}}
-// expected-note at -2 {{while checking constraint satisfaction for template 'r1<invalid<D> >' required here}}
-
-// mismatching template arguments
-
-template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note{{because 'typename identity<Ts...>' would be invalid: too many template arguments for class template 'identity'}}
-struct r2 {};
-
-using r2i1 = r2<int>;
-using r2i2 = r2<void>;
-using r2i3 = r2<int, int>; // expected-error{{constraints not satisfied for class template 'r2' [with Ts = <int, int>]}}
-
-namespace ns2 {
-  template<typename T, typename U> struct identity {};
-
-  template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: too few template arguments for class template 'identity'}}
-  struct r4 {};
-
-  using r4i1 = r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int>]}}
-}
-
-using r4i2 = ns2::r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int>]}}
-
-using E = int;
-template<typename T> requires requires { typename E<T>; } // expected-error{{expected ';' at end of requirement}}
-struct r5v1 {};
-template<typename T> requires requires { typename ::E<T>; } // expected-error{{expected ';' at end of requirement}}
-struct r5v2 {};
-
-template<typename T> requires (sizeof(T) == 1)
-struct chars_only {};
-
-template<typename T> requires requires { typename chars_only<T>; } // expected-note{{because 'typename chars_only<T>' would be invalid: constraints not satisfied for class template 'chars_only' [with T = int]}}
-struct r6 {};
-
-using r6i = r6<int>; // expected-error{{constraints not satisfied for class template 'r6' [with T = int]}}
-
-template<typename T> int F = 0; // expected-note 2{{variable template 'F' declared here}}
-
-static_assert(!requires { typename F<int>; });
-// expected-error at -1{{template name refers to non-type template 'F'}}
-static_assert(!requires { typename ::F<int>; });
-// expected-error at -1{{template name refers to non-type template '::F'}}
-
-struct G { template<typename T> static T temp; };
-
-template<typename T> requires requires { typename T::template temp<int>; }
-// expected-note at -1{{because 'typename T::temp<int>' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
-// expected-note at -2{{because 'typename T::temp<int>' would be invalid: no member named 'temp' in 'D'}}
-// expected-note at -3{{because 'typename T::temp<int>' would be invalid: template name refers to non-type template 'G::template temp'}}
-struct r7 {};
-
-using r7i1 = r7<int>; // expected-error{{constraints not satisfied for class template 'r7' [with T = int]}}
-using r7i2 = r7<D>; // expected-error{{constraints not satisfied for class template 'r7' [with T = D]}}
-using r7i3 = r7<G>; // expected-error{{constraints not satisfied for class template 'r7' [with T = G]}}
-
-template<typename T> struct H;
-
-template<typename T> requires requires { typename H<T>; }
-struct r8 {};
-
-using r8i = r8<int>;
-
-template<typename T> struct I { struct incomplete; }; // expected-note{{member is declared here}}
-
-static_assert(!requires { I<int>::incomplete::inner; }); // expected-error{{implicit instantiation of undefined member 'I<int>::incomplete'}}
-
-template<typename T> requires requires { typename I<T>::incomplete::inner; } // expected-note{{because 'typename I<T>::incomplete::inner' would be invalid: implicit instantiation of undefined member 'I<int>::incomplete'}}
-struct r9 {};
-
-using r9i = r9<int>; // expected-error{{constraints not satisfied for class template 'r9' [with T = int]}}
-
-namespace ns3 {
-  struct X { }; // expected-note 2{{candidate found by name lookup is 'ns3::X'}}
-}
-
-struct X { using inner = int; }; // expected-note 2{{candidate found by name lookup is 'X'}}
-
-using namespace ns3;
-static_assert(requires { typename X; }); // expected-error{{reference to 'X' is ambiguous}}
-static_assert(requires { typename X::inner; }); // expected-error{{reference to 'X' is ambiguous}}
-// expected-error at -1{{unknown type name 'inner'}}
-
-// naming a type template specialization in a type requirement does not require
-// it to be complete and should not care about partial specializations.
-
-template<typename T>
-struct Z;
-
-template<typename T> requires (sizeof(T) >= 1)
-struct Z<T> {}; // expected-note{{partial specialization matches [with T = int]}}
-
-template<typename T> requires (sizeof(T) <= 4)
-struct Z<T> {}; // expected-note{{partial specialization matches [with T = int]}}
-
-Z<int> x; // expected-error{{ambiguous partial specializations of 'Z<int>'}}
-
-static_assert(requires { typename Z<int>; });
-
-// C++ [expr.prim.req.type] Example
-namespace std_example {
-  template<typename T, typename T::type = 0> struct S;
-  // expected-note at -1 {{because 'typename S<T>' would be invalid: no type named 'type' in 'std_example::has_inner}}
-  template<typename T> using Ref = T&; // expected-note{{because 'typename Ref<T>' would be invalid: cannot form a reference to 'void'}}
-  template<typename T> concept C1 =
-    requires {
-      typename T::inner;
-      // expected-note at -1 {{because 'typename T::inner' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
-      // expected-note at -2 {{because 'typename T::inner' would be invalid: no type named 'inner' in 'std_example::has_type'}}
-    };
-  template<typename T> concept C2 = requires { typename S<T>; };
-  template<typename T> concept C3 = requires { typename Ref<T>; };
-
-  struct has_inner { using inner = int;};
-  struct has_type { using type = int; };
-  struct has_inner_and_type { using inner = int; using type = int; };
-
-  static_assert(C1<has_inner_and_type> && C2<has_inner_and_type> && C3<has_inner_and_type>);
-  template<C1 T> struct C1_check {};
-  // expected-note at -1 {{because 'int' does not satisfy 'C1'}}
-  // expected-note at -2 {{because 'std_example::has_type' does not satisfy 'C1'}}
-  template<C2 T> struct C2_check {};
-  // expected-note at -1 {{because 'std_example::has_inner' does not satisfy 'C2'}}
-  template<C3 T> struct C3_check {};
-  // expected-note at -1 {{because 'void' does not satisfy 'C3'}}
-  using c1 = C1_check<int>; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = int]}}
-  using c2 = C1_check<has_type>; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = std_example::has_type]}}
-  using c3 = C2_check<has_inner>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::has_inner]}}
-  using c4 = C3_check<void>; // expected-error{{constraints not satisfied for class template 'C3_check' [with T = void]}}
-}
\ No newline at end of file

diff  --git a/clang/test/PCH/cxx2a-requires-expr.cpp b/clang/test/PCH/cxx2a-requires-expr.cpp
deleted file mode 100644
index d52d451c2d68..000000000000
--- a/clang/test/PCH/cxx2a-requires-expr.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -std=c++2a -fconcepts-ts -o %t %s
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x ast -ast-print %t | FileCheck %s
-
-template<typename T>
-concept C = true;
-
-template<typename T, typename U>
-concept C2 = true;
-
-template<typename T>
-bool f() {
-  // CHECK: requires (T t) { t++; { t++ } noexcept -> C; { t++ } -> C2<int>; typename T::a; requires T::val; };
-  return requires (T t) {
-    t++;
-    { t++ } noexcept -> C;
-    { t++ } -> C2<int>;
-    typename T::a;
-    requires T::val;
-  };
-}

diff  --git a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
deleted file mode 100644
index a53189caa5f7..000000000000
--- a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-bool r1 = requires () {};
-// expected-error at -1 {{a requires expression must contain at least one requirement}}
-
-bool r2 = requires { requires true; };
-
-bool r3 = requires (int a, ...) { requires true; };
-// expected-error at -1 {{varargs not allowed in requires expression}}
-
-template<typename... T>
-bool r4 = requires (T... ts) { requires true; };
-
-bool r5 = requires (bool c, int d) { c; d; };
-
-bool r6 = requires (bool c, int d) { c; d; } && decltype(d){};
-// expected-error at -1 {{use of undeclared identifier 'd'}}
-
-bool r7 = requires (bool c) { c; (requires (int d) { c; d; }); d; } && decltype(c){} && decltype(d){};
-// expected-error at -1 2{{use of undeclared identifier 'd'}}
-// expected-error at -2 {{use of undeclared identifier 'c'}}
-
-bool r8 = requires (bool, int) { requires true; };
-
-bool r9 = requires (bool a, int a) { requires true; };
-// expected-error at -1 {{redefinition of parameter 'a'}}
-// expected-note at -2 {{previous declaration is here}}
-
-bool r10 = requires (struct new_struct { int x; } s) { requires true; };
-// expected-error at -1 {{'new_struct' cannot be defined in a parameter type}}
-
-bool r11 = requires (int x(1)) { requires true; };
-// expected-error at -1 {{expected parameter declarator}}
-// expected-error at -2 {{expected ')'}}
-// expected-note at -3 {{to match this '('}}
-
-bool r12 = requires (int x = 10) { requires true; };
-// expected-error at -1 {{default arguments not allowed for parameters of a requires expression}}
-
-bool r13 = requires (int f(int)) { requires true; };
-
-bool r14 = requires (int (*f)(int)) { requires true; };
-
-bool r15 = requires (10) { requires true; };
-// expected-error at -1 {{expected parameter declarator}}
-
-bool r16 = requires (auto x) { requires true; };
-// expected-error at -1 {{'auto' not allowed in requires expression parameter}}
-
-bool r17 = requires (auto [x, y]) { requires true; };
-// expected-error at -1 {{'auto' not allowed in requires expression parameter}}
-// expected-error at -2 {{use of undeclared identifier 'x'}}
-
-using a = int;
-
-bool r18 = requires { typename a; };
-
-bool r19 = requires { typename ::a; };
-
-template<typename T> struct identity { using type = T; };
-
-template<typename T> using identity_t = T;
-
-bool r20 = requires {
-    typename identity<int>::type;
-    typename identity<int>;
-    typename ::identity_t<int>;
-};
-
-struct s { bool operator==(const s&); ~s(); };
-
-bool r21 = requires { typename s::operator==; };
-// expected-error at -1 {{expected an identifier or template-id after '::'}}
-
-bool r22 = requires { typename s::~s; };
-// expected-error at -1 {{expected an identifier or template-id after '::'}}
-
-template<typename T>
-bool r23 = requires { typename identity<T>::temp<T>; };
-// expected-error at -1 {{use 'template' keyword to treat 'temp' as a dependent template name}}
-
-template<typename T>
-bool r24 = requires {
-    typename identity<T>::template temp<T>;
-    typename identity<T>::template temp; // expected-error{{expected an identifier or template-id after '::'}}
-};
-
-bool r25 = requires { ; };
-// expected-error at -1 {{expected expression}}
-
-bool r26 = requires { {}; };
-// expected-error at -1 {{expected expression}}
-
-bool r27 = requires { { 0 } noexcept; };
-
-bool r28 = requires { { 0 } noexcept noexcept; };
-// expected-error at -1 {{expected '->' before expression type requirement}}
-// expected-error at -2 {{expected concept name with optional arguments}}
-
-template<typename T>
-concept C1 = true;
-
-template<typename T, typename U>
-concept C2 = true;
-
-bool r29 = requires { { 0 } noexcept C1; };
-// expected-error at -1 {{expected '->' before expression type requirement}}
-
-bool r30 = requires { { 0 } noexcept -> C2<int>; };
-
-template<typename T>
-T i1 = 0;
-
-bool r31 = requires { requires false, 1; };
-// expected-error at -1 {{expected ';' at end of requirement}}
-
-bool r32 = requires { 0 noexcept; };
-// expected-error at -1 {{'noexcept' can only be used in a compound requirement (with '{' '}' around the expression)}}
-
-bool r33 = requires { 0 int; };
-// expected-error at -1 {{expected ';' at end of requirement}}
-
-bool r34 = requires { requires true };
-// expected-error at -1 {{expected ';' at end of requirement}}
-
-bool r35 = requires (bool b) { requires sizeof(b) == 1; };
-
-void r36(bool b) requires requires { 1 } {}
-// expected-error at -1 {{expected ';' at end of requirement}}
-
-bool r37 = requires { requires { 1; }; };
-// expected-warning at -1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
-
-bool r38 = requires { requires () { 1; }; };
-// expected-warning at -1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
-
-bool r39 = requires { requires (int i) { i; }; };
-// expected-warning at -1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
-
-bool r40 = requires { requires (); };
-// expected-error at -1 {{expected expression}}

diff  --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
deleted file mode 100644
index 3304fd25cdc9..000000000000
--- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify -Wno-unused-value
-
-template<typename T, typename U>
-constexpr bool is_same_v = false;
-
-template<typename T>
-constexpr bool is_same_v<T, T> = true;
-
-// We use a hack in this file to make the compiler print out the requires
-// expression after it has been instantiated - we put false_v<requires {...}> as
-// the requires clause of a class template, then instantiate the template.
-// The requirement will not be satisfied, and the explaining diagnostic will
-// print out false_v<requires {...}> in its raw form (the false_v serves to
-// prevent the diagnostic from elaborating on why the requires expr wasn't
-// satisfied).
-
-template<bool v>
-constexpr bool false_v = false;
-
-template<typename... Ts>
-using void_t = void;
-
-// Check that requires parameters are instantiated correctly.
-
-template<typename T> requires
-false_v<requires (T t) { requires is_same_v<decltype(t), int>; }>
-// expected-note at -1 {{because 'false_v<requires (int t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
-// expected-note at -2 {{because 'false_v<requires (char t) { requires is_same_v<decltype(t), int>; }>' evaluated to false}}
-struct r1 {};
-
-using r1i1 = r1<int>; // expected-error {{constraints not satisfied for class template 'r1' [with T = int]}}
-using r1i2 = r1<char>; // expected-error {{constraints not satisfied for class template 'r1' [with T = char]}}
-
-// Check that parameter packs work.
-
-template<typename... Ts> requires
-false_v<requires (Ts... ts) {requires ((sizeof(ts) == 2) && ...);}>
-// expected-note at -1 {{because 'false_v<requires (short ts, unsigned short ts) { requires (sizeof (ts) == 2) && (sizeof (ts) == 2); }>'}}
-// expected-note at -2 {{because 'false_v<requires (short ts) { requires (sizeof (ts) == 2); }>' evaluated to false}}
-struct r2 {};
-
-using r2i1 = r2<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short, unsigned short>]}}
-using r2i2 = r2<short>; // expected-error {{constraints not satisfied for class template 'r2' [with Ts = <short>]}}
-
-template<typename... Ts> requires
-false_v<(requires (Ts ts) {requires sizeof(ts) != 0;} && ...)>
-// expected-note at -1 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; } && requires (unsigned short ts) { requires sizeof (ts) != 0; }>' evaluated to false}}
-// expected-note at -2 {{because 'false_v<requires (short ts) { requires sizeof (ts) != 0; }>' evaluated to false}}
-struct r3 {};
-
-using r3i1 = r3<short, unsigned short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short, unsigned short>]}}
-using r3i2 = r3<short>; // expected-error {{constraints not satisfied for class template 'r3' [with Ts = <short>]}}
-
-template<typename T>
-struct identity { using type = T; };
-
-namespace type_requirement {
-  struct A {};
-
-  // check that nested name specifier is instantiated correctly.
-  template<typename T> requires false_v<requires { typename T::type; }> // expected-note{{because 'false_v<requires { typename identity<int>::type; }>' evaluated to false}}
-  struct r1 {};
-
-  using r1i = r1<identity<int>>; // expected-error{{constraints not satisfied for class template 'r1' [with T = identity<int>]}}
-
-  // check that template argument list is instantiated correctly.
-  template<typename T>
-  struct contains_template {
-      template<typename U> requires is_same_v<contains_template<T>, U>
-      using temp = int;
-  };
-
-  template<typename T> requires
-  false_v<requires { typename T::template temp<T>; }>
-  // expected-note at -1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}}
-  // expected-note at -2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
-  struct r2 {};
-
-  using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
-  using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}}
-
-  // substitution error occurs, then requires expr is instantiated again
-
-  template<typename T>
-  struct a {
-      template<typename U> requires (requires { typename T::a::a; }, false)
-      // expected-note at -1{{because 'requires { <<error-type>>; } , false' evaluated to false}}
-      struct r {};
-  };
-
-  using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
-
-  // Parameter pack inside expr
-  template<typename... Ts> requires
-  false_v<(requires { typename Ts::type; } && ...)>
-  // expected-note at -1 {{because 'false_v<requires { typename identity<short>::type; } && requires { typename identity<int>::type; } && requires { <<error-type>>; }>' evaluated to false}}
-  struct r5 {};
-
-  using r5i = r5<identity<short>, identity<int>, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <identity<short>, identity<int>, short>]}}
-  template<typename... Ts> requires
-  false_v<(requires { typename void_t<Ts>; } && ...)> // expected-note{{because 'false_v<requires { typename void_t<int>; } && requires { typename void_t<short>; }>' evaluated to false}}
-  struct r6 {};
-
-  using r6i = r6<int, short>; // expected-error{{constraints not satisfied for class template 'r6' [with Ts = <int, short>]}}
-
-  template<typename... Ts> requires
-  false_v<(requires { typename Ts::template aaa<Ts>; } && ...)>
-  // expected-note at -1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}}
-  struct r7 {};
-
-  using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}}
-}
-
-namespace expr_requirement {
-  // check that compound/simple requirements are instantiated correctly.
-
-  template<typename T> requires false_v<requires { sizeof(T); { sizeof(T) }; }>
-  // expected-note at -1 {{because 'false_v<requires { sizeof(int); { sizeof(int) }; }>' evaluated to false}}
-  // expected-note at -2 {{because 'false_v<requires { <<error-expression>>; { sizeof(T) }; }>' evaluated to false}}
-  struct r1 {};
-
-  using r1i1 = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
-  using r1i2 = r1<void>; // expected-error{{constraints not satisfied for class template 'r1' [with T = void]}}
-
-  // substitution error occurs in expr, then expr is instantiated again.
-
-  template<typename T>
-  struct a {
-      template<typename U> requires (requires { sizeof(T::a); }, false) // expected-note{{because 'requires { <<error-expression>>; } , false' evaluated to false}}
-      struct r {};
-  };
-
-  using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
-
-  // check that the return-type-requirement is instantiated correctly.
-
-  template<typename T, typename U = int>
-  concept C1 = is_same_v<T, U>;
-
-  template<typename T> requires false_v<requires(T t) { { t } -> C1<T>; }>
-  // expected-note at -1 {{because 'false_v<requires (int t) { { t } -> C1<int>; }>' evaluated to false}}
-  // expected-note at -2 {{because 'false_v<requires (double t) { { t } -> C1<double>; }>' evaluated to false}}
-  struct r2 {};
-
-  using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
-  using r2i2 = r2<double>; // expected-error{{constraints not satisfied for class template 'r2' [with T = double]}}
-
-
-  // substitution error occurs in return type requirement, then requires expr is
-  // instantiated again.
-
-  template<typename T>
-  struct b {
-      template<typename U> requires (requires { { 0 } -> C1<typename T::a>; }, false) // expected-note{{because 'requires { { 0 } -> <<error-type>>; } , false' evaluated to false}}
-      struct r {};
-  };
-
-  using bri = b<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
-
-
-  template<typename... Ts> requires
-  false_v<(requires { { 0 } noexcept -> C1<Ts>; } && ...)>
-  // expected-note at -1 {{because 'false_v<requires { { 0 } noexcept -> C1<int>; } && requires { { 0 } noexcept -> C1<unsigned int>; }>' evaluated to false}}
-  struct r3 {};
-
-  using r3i = r3<int, unsigned int>; // expected-error{{constraints not satisfied for class template 'r3' [with Ts = <int, unsigned int>]}}
-}
-
-namespace nested_requirement {
-  // check that constraint expression is instantiated correctly
-  template<typename T> requires false_v<requires { requires sizeof(T) == 2; }> // expected-note{{because 'false_v<requires { requires sizeof(int) == 2; }>' evaluated to false}}
-  struct r1 {};
-
-  using r1i = r1<int>; // expected-error{{constraints not satisfied for class template 'r1' [with T = int]}}
-
-  // substitution error occurs in expr, then expr is instantiated again.
-  template<typename T>
-  struct a {
-      template<typename U> requires
-      (requires { requires sizeof(T::a) == 0; }, false) // expected-note{{because 'requires { requires <<error-expression>>; } , false' evaluated to false}}
-      struct r {};
-  };
-
-  using ari = a<int>::r<short>; // expected-error{{constraints not satisfied for class template 'r' [with U = short]}}
-
-  // Parameter pack inside expr
-  template<typename... Ts> requires
-  false_v<(requires { requires sizeof(Ts) == 0; } && ...)>
-  // expected-note at -1 {{because 'false_v<requires { requires sizeof(int) == 0; } && requires { requires sizeof(short) == 0; }>' evaluated to false}}
-  struct r2 {};
-
-  using r2i = r2<int, short>; // expected-error{{constraints not satisfied for class template 'r2' [with Ts = <int, short>]}}
-}
-
-// Parameter pack inside multiple requirements
-template<typename... Ts> requires
-false_v<(requires { requires sizeof(Ts) == 0; sizeof(Ts); } && ...)>
-// expected-note at -1 {{because 'false_v<requires { requires sizeof(int) == 0; sizeof(Ts); } && requires { requires sizeof(short) == 0; sizeof(Ts); }>' evaluated to false}}
-struct r4 {};
-
-using r4i = r4<int, short>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int, short>]}}
-
-template<typename... Ts> requires
-false_v<(requires(Ts t) { requires sizeof(t) == 0; t++; } && ...)>
-// expected-note at -1 {{because 'false_v<requires (int t) { requires sizeof (t) == 0; t++; } && requires (short t) { requires sizeof (t) == 0; t++; }>' evaluated to false}}
-struct r5 {};
-
-using r5i = r5<int, short>; // expected-error{{constraints not satisfied for class template 'r5' [with Ts = <int, short>]}}
-
-template<typename T> requires
-false_v<(requires(T t) { T{t}; })> // T{t} creates an "UnevaluatedList" context.
-// expected-note at -1 {{because 'false_v<(requires (int t) { int{t}; })>' evaluated to false}}
-struct r6 {};
-
-using r6i = r6<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r6' [with T = int]}}

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9a09fca5e269..6f3490471de5 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -6340,7 +6340,6 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
   case Decl::UsingPack:
   case Decl::Concept:
   case Decl::LifetimeExtendedTemporary:
-  case Decl::RequiresExprBody:
     return C;
 
   // Declaration kinds that don't make any sense here, but are

diff  --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 04b713c68b80..3632e0f85d10 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -257,7 +257,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
   case Stmt::ConceptSpecializationExprClass:
-  case Stmt::RequiresExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:


        


More information about the cfe-commits mailing list