[clang] 5c02fe1 - Revert "[Concepts] Placeholder constraints and abbreviated templates"

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 23 01:54:46 PST 2020


Author: Sam McCall
Date: 2020-01-23T10:38:59+01:00
New Revision: 5c02fe1faabd5519c48ded170fe849f9b2c8d10f

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

LOG: Revert "[Concepts] Placeholder constraints and abbreviated templates"

This reverts commit e57a9abc4b01fa69fe81ace8df70517983b6cbac.

Parser/cxx2a-placeholder-type-constraint.cpp has MSan failures.

Present at 7b81c3f8793d30a4285095a9b67dcfca2117916c:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/17133/steps/check-clang%20msan/logs/stdio
not present at eaa594f4ec54eba52b03fd9f1c789b214c66a753:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/17132/steps/check-clang%20msan/logs/stdio

Stack trace:
```
==57032==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0xccfe016 in clang::AutoTypeLoc::getLocalSourceRange() const /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/include/clang/AST/TypeLoc.h:2036:19
    #1 0xcc56758 in CheckDeducedPlaceholderConstraints(clang::Sema&, clang::AutoType const&, clang::AutoTypeLoc, clang::QualType) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4505:56
    #2 0xcc550ce in clang::Sema::DeduceAutoType(clang::TypeLoc, clang::Expr*&, clang::QualType&, llvm::Optional<unsigned int>, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4707:11
    #3 0xcc52407 in clang::Sema::DeduceAutoType(clang::TypeSourceInfo*, clang::Expr*&, clang::QualType&, llvm::Optional<unsigned int>, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4457:10
    #4 0xba38332 in clang::Sema::deduceVarTypeFromInitializer(clang::VarDecl*, clang::DeclarationName, clang::QualType, clang::TypeSourceInfo*, clang::SourceRange, bool, clang::Expr*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11351:7
    #5 0xba3a8a9 in clang::Sema::DeduceVariableDeclarationType(clang::VarDecl*, bool, clang::Expr*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11385:26
    #6 0xba3c520 in clang::Sema::AddInitializerToDecl(clang::Decl*, clang::Expr*, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11725:9
    #7 0xb39c498 in clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2399:17
    #8 0xb394d80 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2128:21
    #9 0xb383bbf in clang::Parser::ParseSimpleDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&, bool, clang::Parser::ForRangeInit*, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:1848:10
    #10 0xb383129 in clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/include/llvm/ADT/PointerUnion.h
    #11 0xb53a388 in clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::Parser::ParsedAttributesWithRange&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:221:13
    #12 0xb539309 in clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:106:20
    #13 0xb55610e in clang::Parser::ParseCompoundStatementBody(bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:1079:11
    #14 0xb559529 in clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:2204:21
    #15 0xb33c13e in clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1339:10
    #16 0xb394703 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2068:11
    #17 0xb338e52 in clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1099:10
    #18 0xb337674 in clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1115:12
    #19 0xb334a96 in clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:935:12
    #20 0xb32f12a in clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:686:12
    #21 0xb31e193 in clang::ParseAST(clang::Sema&, bool, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseAST.cpp:158:20
    #22 0x80263f0 in clang::FrontendAction::Execute() /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Frontend/FrontendAction.cpp:936:8
    #23 0x7f2a257 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:965:33
    #24 0x8288bef in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:290:25
    #25 0xad44c2 in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/cc1_main.cpp:239:15
    #26 0xacd76a in ExecuteCC1Tool(llvm::ArrayRef<char const*>) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/driver.cpp:325:12
    #27 0xacc9fd in main /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/driver.cpp:398:12
    #28 0x7f7d82cdb2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
    #29 0xa4dde9 in _start (/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/clang-11+0xa4dde9)
```

Added: 
    

Modified: 
    clang/include/clang/AST/ASTContext.h
    clang/include/clang/AST/ASTNodeTraverser.h
    clang/include/clang/AST/DeclTemplate.h
    clang/include/clang/AST/PropertiesBase.td
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/include/clang/AST/TemplateBase.h
    clang/include/clang/AST/Type.h
    clang/include/clang/AST/TypeLoc.h
    clang/include/clang/AST/TypeProperties.td
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/DeclSpec.h
    clang/include/clang/Sema/Scope.h
    clang/include/clang/Sema/ScopeInfo.h
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/ASTContext.cpp
    clang/lib/AST/ASTImporter.cpp
    clang/lib/AST/ASTStructuralEquivalence.cpp
    clang/lib/AST/DeclTemplate.cpp
    clang/lib/AST/ODRHash.cpp
    clang/lib/AST/TemplateBase.cpp
    clang/lib/AST/TextNodeDumper.cpp
    clang/lib/AST/Type.cpp
    clang/lib/AST/TypeLoc.cpp
    clang/lib/AST/TypePrinter.cpp
    clang/lib/Parse/ParseCXXInlineMethods.cpp
    clang/lib/Parse/ParseDecl.cpp
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/lib/Parse/ParseTemplate.cpp
    clang/lib/Parse/ParseTentative.cpp
    clang/lib/Parse/Parser.cpp
    clang/lib/Sema/DeclSpec.cpp
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Sema/SemaType.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/lib/Serialization/ASTWriterDecl.cpp
    clang/test/AST/ast-dump-record-definition-data-json.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
    clang/test/CXX/temp/temp.param/p10-2a.cpp
    clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
    clang/test/SemaTemplate/ms-delayed-default-template-args.cpp

Removed: 
    clang/test/CXX/dcl/dcl.fct/p17.cpp
    clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
    clang/test/Parser/cxx2a-placeholder-type-constraint.cpp


################################################################################
diff  --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index f8403cf13c4a..fb269cef1ce8 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -88,7 +88,6 @@ class AtomicExpr;
 class BlockExpr;
 class BuiltinTemplateDecl;
 class CharUnits;
-class ConceptDecl;
 class CXXABI;
 class CXXConstructorDecl;
 class CXXMethodDecl;
@@ -212,7 +211,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
   mutable llvm::FoldingSet<DependentUnaryTransformType>
     DependentUnaryTransformTypes;
-  mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
+  mutable llvm::FoldingSet<AutoType> AutoTypes;
   mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
     DeducedTemplateSpecializationTypes;
   mutable llvm::FoldingSet<AtomicType> AtomicTypes;
@@ -1543,9 +1542,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
 
   /// C++11 deduced auto type.
   QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
-                       bool IsDependent, bool IsPack = false,
-                       ConceptDecl *TypeConstraintConcept = nullptr,
-                       ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
+                       bool IsDependent, bool IsPack = false) const;
 
   /// C++11 deduction pattern for 'auto' type.
   QualType getAutoDeductType() const;

diff  --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index 9ebf64a12af5..e0ebb020e697 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -548,8 +548,8 @@ class ASTNodeTraverser
   }
 
   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
-    if (const auto *E = D->getPlaceholderTypeConstraint())
-      Visit(E);
+    if (const auto *TC = D->getPlaceholderTypeConstraint())
+      Visit(TC->getImmediatelyDeclaredConstraint());
     if (D->hasDefaultArgument())
       Visit(D->getDefaultArgument(), SourceRange(),
             D->getDefaultArgStorage().getInheritedFrom(),

diff  --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 7a9f623d8152..7a55d04a0f35 100755
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1102,17 +1102,6 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
   /// template.
   ArrayRef<TemplateArgument> getInjectedTemplateArgs();
 
-  /// Return whether this function template is an abbreviated function template,
-  /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
-  bool isAbbreviated() const {
-    // Since the invented template parameters generated from 'auto' parameters
-    // are either appended to the end of the explicit template parameter list or
-    // form a new template paramter list, we can simply observe the last
-    // parameter to determine if such a thing happened.
-    const TemplateParameterList *TPL = getTemplateParameters();
-    return TPL->getParam(TPL->size() - 1)->isImplicit();
-  }
-
   /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
   void mergePrevDecl(FunctionTemplateDecl *Prev);
 
@@ -1226,6 +1215,7 @@ class TemplateTypeParmDecl final : public TypeDecl,
                                       bool ParameterPack,
                                       bool HasTypeConstraint = false,
                                       Optional<unsigned> NumExpanded = None);
+
   static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
                                                   unsigned ID);
   static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1384,8 +1374,7 @@ class NonTypeTemplateParmDecl final
     : public DeclaratorDecl,
       protected TemplateParmPosition,
       private llvm::TrailingObjects<NonTypeTemplateParmDecl,
-                                    std::pair<QualType, TypeSourceInfo *>,
-                                    Expr *> {
+                                    std::pair<QualType, TypeSourceInfo *>> {
   friend class ASTDeclReader;
   friend TrailingObjects;
 
@@ -1440,12 +1429,10 @@ class NonTypeTemplateParmDecl final
          ArrayRef<TypeSourceInfo *> ExpandedTInfos);
 
   static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
-                                                     unsigned ID,
-                                                     bool HasTypeConstraint);
+                                                     unsigned ID);
   static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
                                                      unsigned ID,
-                                                     unsigned NumExpandedTypes,
-                                                     bool HasTypeConstraint);
+                                                     unsigned NumExpandedTypes);
 
   using TemplateParmPosition::getDepth;
   using TemplateParmPosition::setDepth;
@@ -1556,22 +1543,20 @@ class NonTypeTemplateParmDecl final
     return TypesAndInfos[I].second;
   }
 
-  /// Return the constraint introduced by the placeholder type of this non-type
+  /// Return the type-constraint in the placeholder type of this non-type
   /// template parameter (if any).
-  Expr *getPlaceholderTypeConstraint() const {
-    return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
-        nullptr;
-  }
-
-  void setPlaceholderTypeConstraint(Expr *E) {
-    *getTrailingObjects<Expr *>() = E;
+  TypeConstraint *getPlaceholderTypeConstraint() const {
+    // TODO: Concepts: Implement once we have actual placeholders with type
+    //                 constraints.
+    return nullptr;
   }
 
   /// Determine whether this non-type template parameter's type has a
   /// placeholder with a type-constraint.
   bool hasPlaceholderTypeConstraint() const {
-    auto *AT = getType()->getContainedAutoType();
-    return AT && AT->isConstrained();
+    // TODO: Concepts: Implement once we have actual placeholders with type
+    //                 constraints.
+    return false;
   }
 
   /// \brief Get the associated-constraints of this template parameter.
@@ -1581,8 +1566,8 @@ class NonTypeTemplateParmDecl final
   /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
   /// concepts APIs that accept an ArrayRef of constraint expressions.
   void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
-    if (Expr *E = getPlaceholderTypeConstraint())
-      AC.push_back(E);
+    if (TypeConstraint *TC = getPlaceholderTypeConstraint())
+      AC.push_back(TC->getImmediatelyDeclaredConstraint());
   }
 
   // Implement isa/cast/dyncast/etc.

diff  --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index ba0f237a3bc3..9aacdb9fee36 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -99,8 +99,6 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
     SubclassPropertyType<"TagDecl", DeclRef>;
   def TemplateDeclRef :
     SubclassPropertyType<"TemplateDecl", DeclRef>;
-  def ConceptDeclRef :
-    SubclassPropertyType<"ConceptDecl", DeclRef>;
   def TemplateTypeParmDeclRef :
     SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
   def TemplateTemplateParmDeclRef :

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 86521d82c6ff..4633122aba48 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1040,13 +1040,7 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
   TRY_TO(TraverseType(T->getUnderlyingType()));
 })
 
-DEF_TRAVERSE_TYPE(AutoType, {
-  TRY_TO(TraverseType(T->getDeducedType()));
-  if (T->isConstrained()) {
-    TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
-    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-  }
-})
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
 DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
   TRY_TO(TraverseTemplateName(T->getTemplateName()));
   TRY_TO(TraverseType(T->getDeducedType()));
@@ -1293,12 +1287,6 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
 
 DEF_TRAVERSE_TYPELOC(AutoType, {
   TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-  if (TL.isConstrained()) {
-    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
-      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
-  }
 })
 
 DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {

diff  --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index 93f7b62b8aea..058a5bc0a067 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -637,7 +637,7 @@ struct ASTTemplateArgumentListInfo final
   }
 
   static const ASTTemplateArgumentListInfo *
-  Create(const ASTContext &C, const TemplateArgumentListInfo &List);
+  Create(ASTContext &C, const TemplateArgumentListInfo &List);
 };
 
 /// Represents an explicit template argument list in C++, e.g.,
@@ -702,11 +702,6 @@ inline const TemplateArgument &
   return getArgs()[Idx];
 }
 
-inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
-  assert(Idx < getNumArgs() && "Template argument out of range");
-  return getArgs()[Idx];
-}
-
 } // namespace clang
 
 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H

diff  --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index e8248147f9ad..2291d776db3e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -58,7 +58,6 @@ namespace clang {
 
 class ExtQuals;
 class QualType;
-class ConceptDecl;
 class TagDecl;
 class Type;
 
@@ -1684,15 +1683,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
     /// Was this placeholder type spelled as 'auto', 'decltype(auto)',
     /// or '__auto_type'?  AutoTypeKeyword value.
     unsigned Keyword : 2;
-
-    /// The number of template arguments in the type-constraints, which is
-    /// expected to be able to hold at least 1024 according to [implimits].
-    /// However as this limit is somewhat easy to hit with template
-    /// metaprogramming we'd prefer to keep it as large as possible.
-    /// At the moment it has been left as a non-bitfield since this type
-    /// safely fits in 64 bits as an unsigned, so there is no reason to
-    /// introduce the performance impact of a bitfield.
-    unsigned NumArgs;
   };
 
   class SubstTemplateTypeParmPackTypeBitfields {
@@ -4824,7 +4814,8 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
 
 /// Common base class for placeholders for types that get replaced by
 /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
-/// class template types, and constrained type names.
+/// class template types, and (eventually) constrained type names from the C++
+/// Concepts TS.
 ///
 /// These types are usually a placeholder for a deduced type. However, before
 /// the initializer is attached, or (usually) if the initializer is
@@ -4869,50 +4860,18 @@ class DeducedType : public Type {
   }
 };
 
-/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
-/// by a type-constraint.
-class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
+/// Represents a C++11 auto or C++14 decltype(auto) type.
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
-  ConceptDecl *TypeConstraintConcept;
-
   AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
-           bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD,
-           ArrayRef<TemplateArgument> TypeConstraintArgs);
-
-  const TemplateArgument *getArgBuffer() const {
-    return reinterpret_cast<const TemplateArgument*>(this+1);
-  }
-
-  TemplateArgument *getArgBuffer() {
-    return reinterpret_cast<TemplateArgument*>(this+1);
+           bool IsDeducedAsDependent, bool IsDeducedAsPack)
+      : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
+                    IsDeducedAsDependent, IsDeducedAsPack) {
+    AutoTypeBits.Keyword = (unsigned)Keyword;
   }
 
 public:
-  /// Retrieve the template arguments.
-  const TemplateArgument *getArgs() const {
-    return getArgBuffer();
-  }
-
-  /// Retrieve the number of template arguments.
-  unsigned getNumArgs() const {
-    return AutoTypeBits.NumArgs;
-  }
-
-  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
-  ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
-    return {getArgs(), getNumArgs()};
-  }
-
-  ConceptDecl *getTypeConstraintConcept() const {
-    return TypeConstraintConcept;
-  }
-
-  bool isConstrained() const {
-    return TypeConstraintConcept != nullptr;
-  }
-
   bool isDecltypeAuto() const {
     return getKeyword() == AutoTypeKeyword::DecltypeAuto;
   }
@@ -4921,15 +4880,18 @@ class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
     return (AutoTypeKeyword)AutoTypeBits.Keyword;
   }
 
-  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
-    Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
-            getTypeConstraintConcept(), getTypeConstraintArguments());
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getDeducedType(), getKeyword(), isDependentType(),
+            containsUnexpandedParameterPack());
   }
 
-  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
-                      QualType Deduced, AutoTypeKeyword Keyword,
-                      bool IsDependent, ConceptDecl *CD,
-                      ArrayRef<TemplateArgument> Arguments);
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
+                      AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) {
+    ID.AddPointer(Deduced.getAsOpaquePtr());
+    ID.AddInteger((unsigned)Keyword);
+    ID.AddBoolean(IsDependent);
+    ID.AddBoolean(IsPack);
+  }
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == Auto;

diff  --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 3fc53d823c37..c3baaa3e4174 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -14,7 +14,6 @@
 #ifndef LLVM_CLANG_AST_TYPELOC_H
 #define LLVM_CLANG_AST_TYPELOC_H
 
-#include "clang/AST/DeclarationName.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/Type.h"
@@ -35,7 +34,6 @@ namespace clang {
 class Attr;
 class ASTContext;
 class CXXRecordDecl;
-class ConceptDecl;
 class Expr;
 class ObjCInterfaceDecl;
 class ObjCProtocolDecl;
@@ -183,11 +181,6 @@ class TypeLoc {
   ///   AttributedTypeLoc, for those type attributes that behave as qualifiers
   TypeLoc findExplicitQualifierLoc() const;
 
-  /// Get the typeloc of an AutoType whose type will be deduced for a variable
-  /// with an initializer of this type. This looks through declarators like
-  /// pointer types, but not through decltype or typedefs.
-  AutoTypeLoc getContainedAutoTypeLoc() const;
-
   /// Initializes this to state that every location in this
   /// type is the given location.
   ///
@@ -1930,137 +1923,8 @@ class DeducedTypeLoc
     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
                                        DeducedType> {};
 
-struct AutoTypeLocInfo : TypeSpecLocInfo {
-  NestedNameSpecifierLoc NestedNameSpec;
-  SourceLocation TemplateKWLoc;
-  SourceLocation ConceptNameLoc;
-  NamedDecl *FoundDecl;
-  SourceLocation LAngleLoc;
-  SourceLocation RAngleLoc;
-};
-
 class AutoTypeLoc
-    : public ConcreteTypeLoc<DeducedTypeLoc,
-                             AutoTypeLoc,
-                             AutoType,
-                             AutoTypeLocInfo> {
-public:
-  AutoTypeKeyword getAutoKeyword() const {
-    return getTypePtr()->getKeyword();
-  }
-
-  bool isConstrained() const {
-    return getTypePtr()->isConstrained();
-  }
-
-  const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
-    return getLocalData()->NestedNameSpec;
-  }
-
-  void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
-    getLocalData()->NestedNameSpec = NNS;
-  }
-
-  SourceLocation getTemplateKWLoc() const {
-    return getLocalData()->TemplateKWLoc;
-  }
-
-  void setTemplateKWLoc(SourceLocation Loc) {
-    getLocalData()->TemplateKWLoc = Loc;
-  }
-
-  SourceLocation getConceptNameLoc() const {
-    return getLocalData()->ConceptNameLoc;
-  }
-
-  void setConceptNameLoc(SourceLocation Loc) {
-    getLocalData()->ConceptNameLoc = Loc;
-  }
-
-  NamedDecl *getFoundDecl() const {
-    return getLocalData()->FoundDecl;
-  }
-
-  void setFoundDecl(NamedDecl *D) {
-    getLocalData()->FoundDecl = D;
-  }
-
-  ConceptDecl *getNamedConcept() const {
-    return getTypePtr()->getTypeConstraintConcept();
-  }
-
-  DeclarationNameInfo getConceptNameInfo() const;
-
-  bool hasExplicitTemplateArgs() const {
-    return getLocalData()->LAngleLoc.isValid();
-  }
-
-  SourceLocation getLAngleLoc() const {
-    return this->getLocalData()->LAngleLoc;
-  }
-
-  void setLAngleLoc(SourceLocation Loc) {
-    this->getLocalData()->LAngleLoc = Loc;
-  }
-
-  SourceLocation getRAngleLoc() const {
-    return this->getLocalData()->RAngleLoc;
-  }
-
-  void setRAngleLoc(SourceLocation Loc) {
-    this->getLocalData()->RAngleLoc = Loc;
-  }
-
-  unsigned getNumArgs() const {
-    return getTypePtr()->getNumArgs();
-  }
-
-  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
-    getArgInfos()[i] = AI;
-  }
-
-  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
-    return getArgInfos()[i];
-  }
-
-  TemplateArgumentLoc getArgLoc(unsigned i) const {
-    return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
-                               getArgLocInfo(i));
-  }
-
-  SourceRange getLocalSourceRange() const {
-    return{
-        isConstrained()
-          ? (getNestedNameSpecifierLoc()
-               ? getNestedNameSpecifierLoc().getBeginLoc()
-               : (getTemplateKWLoc().isValid()
-                  ? getTemplateKWLoc()
-                  : getConceptNameLoc()))
-          : getNameLoc(),
-        getNameLoc()
-    };
-  }
-
-  void copy(AutoTypeLoc Loc) {
-    unsigned size = getFullDataSize();
-    assert(size == Loc.getFullDataSize());
-    memcpy(Data, Loc.Data, size);
-  }
-
-  void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
-  unsigned getExtraLocalDataSize() const {
-    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
-  }
-
-  unsigned getExtraLocalDataAlignment() const {
-    return alignof(TemplateArgumentLocInfo);
-  }
-
-private:
-  TemplateArgumentLocInfo *getArgInfos() const {
-    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
-  }
+    : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
 };
 
 class DeducedTemplateSpecializationTypeLoc

diff  --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 3cf56e5a5629..4df2e2f77e2b 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -395,13 +395,6 @@ let Class = AutoType in {
   def : Property<"keyword", AutoTypeKeyword> {
     let Read = [{ node->getKeyword() }];
   }
-  def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
-    let Read = [{ makeOptionalFromPointer(
-        const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
-  }
-  def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
-    let Read = [{ node->getTypeConstraintArguments() }];
-  }
   // FIXME: better enumerated value
   // Only really required when the deduced type is null
   def : Property<"dependence", UInt32> {
@@ -413,9 +406,7 @@ let Class = AutoType in {
   def : Creator<[{
     return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
                            /*isDependentWithoutDeducedType*/ dependence > 0,
-                           /*isPackWithoutDeducedType*/ dependence > 1,
-                           makePointerFromOptional(typeConstraintConcept),
-                           typeConstraintArguments);
+                           /*isPackWithoutDeducedType*/ dependence > 1);
   }]>;
 }
 

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 04b103e3087a..105ed7bf6c84 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1371,8 +1371,6 @@ def err_concept_definition_not_identifier : Error<
 def ext_concept_legacy_bool_keyword : ExtWarn<
   "ISO C++2a does not permit the 'bool' keyword after 'concept'">,
   InGroup<DiagGroup<"concepts-ts-compat">>;
-def err_placeholder_expected_auto_or_decltype_auto : Error<
-  "expected 'auto' or 'decltype(auto)' after concept name">;
 }
 
 } // end of Parser diagnostics

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 488f7477d248..b87419d393e2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2102,8 +2102,11 @@ 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 function prototype that is "
-  "not a function declaration|in requires expression parameter}1">;
+  "|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">;
 def err_dependent_deduced_tst : Error<
   "typename specifier refers to "
   "%select{class template|function template|variable template|alias template|"
@@ -2652,9 +2655,6 @@ def note_ambiguous_atomic_constraints : Note<
   "same concept">;
 def note_ambiguous_atomic_constraints_similar_expression : Note<
   "similar constraint expression here">;
-def err_unsupported_placeholder_constraint : Error<
-  "constrained placeholder types other than simple 'auto' on non-type template "
-  "parameters not supported yet">;
 
 def err_template_
diff erent_requires_clause : Error<
   "requires clause 
diff ers in template redeclaration">;
@@ -2669,8 +2669,6 @@ def err_type_constraint_non_type_concept : Error<
 def err_type_constraint_missing_arguments : Error<
   "%0 requires more than 1 template argument; provide the remaining arguments "
   "explicitly to use it here">;
-def err_placeholder_constraints_not_satisfied : Error<
-  "deduced type %0 does not satisfy %1">;
 
 // C++11 char16_t/char32_t
 def warn_cxx98_compat_unicode_type : Warning<

diff  --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 1559b51ea77f..1222549161e4 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -349,7 +349,6 @@ class DeclSpec {
   unsigned TypeSpecOwned : 1;
   unsigned TypeSpecPipe : 1;
   unsigned TypeSpecSat : 1;
-  unsigned ConstrainedAuto : 1;
 
   // type-qualifiers
   unsigned TypeQualifiers : 5;  // Bitwise OR of TQ.
@@ -370,7 +369,6 @@ class DeclSpec {
     UnionParsedType TypeRep;
     Decl *DeclRep;
     Expr *ExprRep;
-    TemplateIdAnnotation *TemplateIdRep;
   };
 
   /// ExplicitSpecifier - Store information about explicit spicifer.
@@ -415,9 +413,6 @@ class DeclSpec {
   static bool isExprRep(TST T) {
     return (T == TST_typeofExpr || T == TST_decltype);
   }
-  static bool isTemplateIdRep(TST T) {
-    return (T == TST_auto || T == TST_decltype_auto);
-  }
 
   DeclSpec(const DeclSpec &) = delete;
   void operator=(const DeclSpec &) = delete;
@@ -435,8 +430,7 @@ class DeclSpec {
         TypeSpecComplex(TSC_unspecified), TypeSpecSign(TSS_unspecified),
         TypeSpecType(TST_unspecified), TypeAltiVecVector(false),
         TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false),
-        TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
-        TypeQualifiers(TQ_unspecified),
+        TypeSpecPipe(false), TypeSpecSat(false), TypeQualifiers(TQ_unspecified),
         FS_inline_specified(false), FS_forceinline_specified(false),
         FS_virtual_specified(false), FS_noreturn_specified(false),
         Friend_specified(false), ConstexprSpecifier(CSK_unspecified),
@@ -484,7 +478,6 @@ class DeclSpec {
   bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); }
   bool isTypeSpecPipe() const { return TypeSpecPipe; }
   bool isTypeSpecSat() const { return TypeSpecSat; }
-  bool isConstrainedAuto() const { return ConstrainedAuto; }
 
   ParsedType getRepAsType() const {
     assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
@@ -498,11 +491,6 @@ class DeclSpec {
     assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr");
     return ExprRep;
   }
-  TemplateIdAnnotation *getRepAsTemplateId() const {
-    assert(isTemplateIdRep((TST) TypeSpecType) &&
-           "DeclSpec does not store a template id");
-    return TemplateIdRep;
-  }
   CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
   const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
 
@@ -678,9 +666,6 @@ class DeclSpec {
                        SourceLocation TagNameLoc, const char *&PrevSpec,
                        unsigned &DiagID, Decl *Rep, bool Owned,
                        const PrintingPolicy &Policy);
-  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                       unsigned &DiagID, TemplateIdAnnotation *Rep,
-                       const PrintingPolicy &Policy);
 
   bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
                        unsigned &DiagID, Expr *Rep,
@@ -1846,14 +1831,6 @@ class Declarator {
   /// requires-clause, or null if no such clause was specified.
   Expr *TrailingRequiresClause;
 
-  /// If this declarator declares a template, its template parameter lists.
-  ArrayRef<TemplateParameterList *> TemplateParameterLists;
-
-  /// If the declarator declares an abbreviated function template, the innermost
-  /// template parameter list containing the invented and explicit template
-  /// parameters (if any).
-  TemplateParameterList *InventedTemplateParameterList;
-
 #ifndef _MSC_VER
   union {
 #endif
@@ -1884,8 +1861,7 @@ class Declarator {
         Redeclaration(false), Extension(false), ObjCIvar(false),
         ObjCWeakProperty(false), InlineStorageUsed(false),
         Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
-        TrailingRequiresClause(nullptr),
-        InventedTemplateParameterList(nullptr) {}
+        TrailingRequiresClause(nullptr) {}
 
   ~Declarator() {
     clear();
@@ -2453,30 +2429,6 @@ class Declarator {
     return TrailingRequiresClause != nullptr;
   }
 
-  /// Sets the template parameter lists that preceded the declarator.
-  void setTemplateParameterLists(ArrayRef<TemplateParameterList *> TPLs) {
-    TemplateParameterLists = TPLs;
-  }
-
-  /// The template parameter lists that preceded the declarator.
-  ArrayRef<TemplateParameterList *> getTemplateParameterLists() const {
-    return TemplateParameterLists;
-  }
-
-  /// Sets the template parameter list generated from the explicit template
-  /// parameters along with any invented template parameters from
-  /// placeholder-typed parameters.
-  void setInventedTemplateParameterList(TemplateParameterList *Invented) {
-    InventedTemplateParameterList = Invented;
-  }
-
-  /// The template parameter list generated from the explicit template
-  /// parameters along with any invented template parameters from
-  /// placeholder-typed parameters, if there were any such parameters.
-  TemplateParameterList * getInventedTemplateParameterList() const {
-    return InventedTemplateParameterList;
-  }
-
   /// takeAttributes - Takes attributes from the given parsed-attributes
   /// set and add them to this declarator.
   ///
@@ -2677,26 +2629,6 @@ struct LambdaIntroducer {
   }
 };
 
-struct InventedTemplateParameterInfo {
-  /// The number of parameters in the template parameter list that were
-  /// explicitly specified by the user, as opposed to being invented by use
-  /// of an auto parameter.
-  unsigned NumExplicitTemplateParams = 0;
-
-  /// If this is a generic lambda or abbreviated function template, use this
-  /// as the depth of each 'auto' parameter, during initial AST construction.
-  unsigned AutoTemplateParameterDepth = 0;
-
-  /// Store the list of the template parameters for a generic lambda or an
-  /// abbreviated function template.
-  /// If this is a generic lambda or abbreviated function template, this holds
-  /// the explicit template parameters followed by the auto parameters
-  /// converted into TemplateTypeParmDecls.
-  /// It can be used to construct the generic lambda or abbreviated template's
-  /// template parameter list during initial AST construction.
-  SmallVector<NamedDecl*, 4> TemplateParams;
-};
-
 } // end namespace clang
 
 #endif // LLVM_CLANG_SEMA_DECLSPEC_H

diff  --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 6133425a42a6..7848df8f70d9 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -385,12 +385,6 @@ class Scope {
     return getFlags() & Scope::FunctionPrototypeScope;
   }
 
-  /// isFunctionDeclarationScope - Return true if this scope is a
-  /// function prototype scope.
-  bool isFunctionDeclarationScope() const {
-    return getFlags() & Scope::FunctionDeclarationScope;
-  }
-
   /// isAtCatchScope - Return true if this scope is \@catch.
   bool isAtCatchScope() const {
     return getFlags() & Scope::AtCatchScope;

diff  --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h
index 3c4847a2932c..4f7534f9ef1a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -22,7 +22,6 @@
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Sema/CleanupInfo.h"
-#include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/MapVector.h"
@@ -790,8 +789,7 @@ class CapturedRegionScopeInfo final : public CapturingScopeInfo {
   }
 };
 
-class LambdaScopeInfo final :
-    public CapturingScopeInfo, public InventedTemplateParameterInfo {
+class LambdaScopeInfo final : public CapturingScopeInfo {
 public:
   /// The class that describes the lambda.
   CXXRecordDecl *Lambda = nullptr;
@@ -825,9 +823,25 @@ class LambdaScopeInfo final :
   /// Packs introduced by this lambda, if any.
   SmallVector<NamedDecl*, 4> LocalPacks;
 
+  /// If this is a generic lambda, use this as the depth of
+  /// each 'auto' parameter, during initial AST construction.
+  unsigned AutoTemplateParameterDepth = 0;
+
+  /// The number of parameters in the template parameter list that were
+  /// explicitly specified by the user, as opposed to being invented by use
+  /// of an auto parameter.
+  unsigned NumExplicitTemplateParams = 0;
+
   /// Source range covering the explicit template parameter list (if it exists).
   SourceRange ExplicitTemplateParamsRange;
 
+  /// Store the list of the template parameters for a generic lambda.
+  /// If this is a generic lambda, this holds the explicit template parameters
+  /// followed by the auto parameters converted into TemplateTypeParmDecls.
+  /// It can be used to construct the generic lambda's template parameter list
+  /// during initial AST construction.
+  SmallVector<NamedDecl*, 4> TemplateParams;
+
   /// If this is a generic lambda, and the template parameter
   /// list has been created (from the TemplateParams) then store
   /// a reference to it (cache it to avoid reconstructing it).

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ebd24b0d71da..08f657374bcf 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -620,13 +620,6 @@ class Sema final {
   /// function, block, and method scopes that are currently active.
   SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
 
-  /// Stack containing information needed when in C++2a an 'auto' is encountered
-  /// in a function declaration parameter type specifier in order to invent a
-  /// corresponding template parameter in the enclosing abbreviated function
-  /// template. This information is also present in LambdaScopeInfo, stored in
-  /// the FunctionScopes stack.
-  SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos;
-
   typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
                      &ExternalSemaSource::ReadExtVectorDecls, 2, 2>
     ExtVectorDeclsType;
@@ -1432,11 +1425,6 @@ class Sema final {
   /// Retrieve the module loader associated with the preprocessor.
   ModuleLoader &getModuleLoader() const;
 
-  /// Invent a new identifier for parameters of abbreviated templates.
-  IdentifierInfo *
-  InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName,
-                                             unsigned Index);
-
   void emitAndClearUnusedLocalTypedefWarnings();
 
   enum TUFragmentKind {
@@ -1531,15 +1519,6 @@ class Sema final {
   /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls
   SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
 
-  /// Called before parsing a function declarator belonging to a function
-  /// declaration.
-  void ActOnStartFunctionDeclarationDeclarator(Declarator &D,
-                                               unsigned TemplateParameterDepth);
-
-  /// Called after parsing a function declarator belonging to a function
-  /// declaration.
-  void ActOnFinishFunctionDeclarationDeclarator(Declarator &D);
-
   void ActOnComment(SourceRange Comment);
 
   //===--------------------------------------------------------------------===//
@@ -1943,8 +1922,6 @@ class Sema final {
     NC_FunctionTemplate,
     /// The name was classified as an ADL-only function template name.
     NC_UndeclaredTemplate,
-    /// The name was classified as a concept name.
-    NC_Concept,
   };
 
   class NameClassification {
@@ -2009,12 +1986,6 @@ class Sema final {
       return Result;
     }
 
-    static NameClassification Concept(TemplateName Name) {
-      NameClassification Result(NC_Concept);
-      Result.Template = Name;
-      return Result;
-    }
-
     static NameClassification UndeclaredTemplate(TemplateName Name) {
       NameClassification Result(NC_UndeclaredTemplate);
       Result.Template = Name;
@@ -2040,8 +2011,7 @@ class Sema final {
 
     TemplateName getTemplateName() const {
       assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate ||
-             Kind == NC_VarTemplate || Kind == NC_Concept ||
-             Kind == NC_UndeclaredTemplate);
+             Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate);
       return Template;
     }
 
@@ -2053,8 +2023,6 @@ class Sema final {
         return TNK_Function_template;
       case NC_VarTemplate:
         return TNK_Var_template;
-      case NC_Concept:
-        return TNK_Concept_template;
       case NC_UndeclaredTemplate:
         return TNK_Undeclared_template;
       default:
@@ -6914,10 +6882,6 @@ class Sema final {
                             TemplateTypeParmDecl *ConstrainedParameter,
                             SourceLocation EllipsisLoc);
 
-  bool AttachTypeConstraint(AutoTypeLoc TL,
-                            NonTypeTemplateParmDecl *ConstrainedParameter,
-                            SourceLocation EllipsisLoc);
-
   QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
                                              SourceLocation Loc);
   QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
@@ -6967,8 +6931,7 @@ class Sema final {
       SourceLocation DeclStartLoc, SourceLocation DeclLoc,
       const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
       ArrayRef<TemplateParameterList *> ParamLists,
-      bool IsFriend, bool &IsMemberSpecialization, bool &Invalid,
-      bool SuppressDiagnostic = false);
+      bool IsFriend, bool &IsMemberSpecialization, bool &Invalid);
 
   DeclResult CheckClassTemplate(
       Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
@@ -7880,12 +7843,10 @@ class Sema final {
 
   DeduceAutoResult
   DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
-                 Optional<unsigned> DependentDeductionDepth = None,
-                 bool IgnoreConstraints = false);
+                 Optional<unsigned> DependentDeductionDepth = None);
   DeduceAutoResult
   DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
-                 Optional<unsigned> DependentDeductionDepth = None,
-                 bool IgnoreConstraints = false);
+                 Optional<unsigned> DependentDeductionDepth = None);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
   bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
                         bool Diagnose = true);

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 6d1db38e36cc..a51429264dbe 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -716,61 +716,6 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
     RequiresClause->Profile(ID, C, /*Canonical=*/true);
 }
 
-static Expr *
-canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC,
-                                          QualType ConstrainedType) {
-  // This is a bit ugly - we need to form a new immediately-declared
-  // constraint that references the new parameter; this would ideally
-  // require semantic analysis (e.g. template<C T> struct S {}; - the
-  // converted arguments of C<T> could be an argument pack if C is
-  // declared as template<typename... T> concept C = ...).
-  // We don't have semantic analysis here so we dig deep into the
-  // ready-made constraint expr and change the thing manually.
-  ConceptSpecializationExpr *CSE;
-  if (const auto *Fold = dyn_cast<CXXFoldExpr>(IDC))
-    CSE = cast<ConceptSpecializationExpr>(Fold->getLHS());
-  else
-    CSE = cast<ConceptSpecializationExpr>(IDC);
-  ArrayRef<TemplateArgument> OldConverted = CSE->getTemplateArguments();
-  SmallVector<TemplateArgument, 3> NewConverted;
-  NewConverted.reserve(OldConverted.size());
-  if (OldConverted.front().getKind() == TemplateArgument::Pack) {
-    // The case:
-    // template<typename... T> concept C = true;
-    // template<C<int> T> struct S; -> constraint is C<{T, int}>
-    NewConverted.push_back(ConstrainedType);
-    for (auto &Arg : OldConverted.front().pack_elements().drop_front(1))
-      NewConverted.push_back(Arg);
-    TemplateArgument NewPack(NewConverted);
-
-    NewConverted.clear();
-    NewConverted.push_back(NewPack);
-    assert(OldConverted.size() == 1 &&
-           "Template parameter pack should be the last parameter");
-  } else {
-    assert(OldConverted.front().getKind() == TemplateArgument::Type &&
-           "Unexpected first argument kind for immediately-declared "
-           "constraint");
-    NewConverted.push_back(ConstrainedType);
-    for (auto &Arg : OldConverted.drop_front(1))
-      NewConverted.push_back(Arg);
-  }
-  Expr *NewIDC = ConceptSpecializationExpr::Create(
-      C, NestedNameSpecifierLoc(), /*TemplateKWLoc=*/SourceLocation(),
-      CSE->getConceptNameInfo(), /*FoundDecl=*/CSE->getNamedConcept(),
-      CSE->getNamedConcept(),
-      // Actually canonicalizing a TemplateArgumentLoc is 
diff icult so we
-      // simply omit the ArgsAsWritten
-      /*ArgsAsWritten=*/nullptr, NewConverted, nullptr);
-
-  if (auto *OrigFold = dyn_cast<CXXFoldExpr>(IDC))
-    NewIDC = new (C) CXXFoldExpr(OrigFold->getType(), SourceLocation(), NewIDC,
-                                 BinaryOperatorKind::BO_LAnd,
-                                 SourceLocation(), /*RHS=*/nullptr,
-                                 SourceLocation(), /*NumExpansions=*/None);
-  return NewIDC;
-}
-
 TemplateTemplateParmDecl *
 ASTContext::getCanonicalTemplateTemplateParmDecl(
                                           TemplateTemplateParmDecl *TTP) const {
@@ -798,23 +743,68 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
           TTP->isExpandedParameterPack() ?
           llvm::Optional<unsigned>(TTP->getNumExpansionParameters()) : None);
       if (const auto *TC = TTP->getTypeConstraint()) {
+        // This is a bit ugly - we need to form a new immediately-declared
+        // constraint that references the new parameter; this would ideally
+        // require semantic analysis (e.g. template<C T> struct S {}; - the
+        // converted arguments of C<T> could be an argument pack if C is
+        // declared as template<typename... T> concept C = ...).
+        // We don't have semantic analysis here so we dig deep into the
+        // ready-made constraint expr and change the thing manually.
+        Expr *IDC = TC->getImmediatelyDeclaredConstraint();
+        ConceptSpecializationExpr *CSE;
+        if (const auto *Fold = dyn_cast<CXXFoldExpr>(IDC))
+          CSE = cast<ConceptSpecializationExpr>(Fold->getLHS());
+        else
+          CSE = cast<ConceptSpecializationExpr>(IDC);
+        ArrayRef<TemplateArgument> OldConverted = CSE->getTemplateArguments();
+        SmallVector<TemplateArgument, 3> NewConverted;
+        NewConverted.reserve(OldConverted.size());
+
         QualType ParamAsArgument(NewTTP->getTypeForDecl(), 0);
-        Expr *NewIDC = canonicalizeImmediatelyDeclaredConstraint(
-                *this, TC->getImmediatelyDeclaredConstraint(),
-                ParamAsArgument);
-        TemplateArgumentListInfo CanonArgsAsWritten;
-        if (auto *Args = TC->getTemplateArgsAsWritten())
-          for (const auto &ArgLoc : Args->arguments())
-            CanonArgsAsWritten.addArgument(
-                TemplateArgumentLoc(ArgLoc.getArgument(),
-                                    TemplateArgumentLocInfo()));
+        if (OldConverted.front().getKind() == TemplateArgument::Pack) {
+          // The case:
+          // template<typename... T> concept C = true;
+          // template<C<int> T> struct S; -> constraint is C<{T, int}>
+          NewConverted.push_back(ParamAsArgument);
+          for (auto &Arg : OldConverted.front().pack_elements().drop_front(1))
+            NewConverted.push_back(Arg);
+          TemplateArgument NewPack(NewConverted);
+
+          NewConverted.clear();
+          NewConverted.push_back(NewPack);
+          assert(OldConverted.size() == 1 &&
+                 "Template parameter pack should be the last parameter");
+        } else {
+          assert(OldConverted.front().getKind() == TemplateArgument::Type &&
+                 "Unexpected first argument kind for immediately-declared "
+                 "constraint");
+          NewConverted.push_back(ParamAsArgument);
+          for (auto &Arg : OldConverted.drop_front(1))
+            NewConverted.push_back(Arg);
+        }
+        Expr *NewIDC = ConceptSpecializationExpr::Create(*this,
+            NestedNameSpecifierLoc(), /*TemplateKWLoc=*/SourceLocation(),
+            CSE->getConceptNameInfo(), /*FoundDecl=*/CSE->getNamedConcept(),
+            CSE->getNamedConcept(),
+            // Actually canonicalizing a TemplateArgumentLoc is 
diff icult so we
+            // simply omit the ArgsAsWritten
+            /*ArgsAsWritten=*/nullptr, NewConverted, nullptr);
+
+        if (auto *OrigFold = dyn_cast<CXXFoldExpr>(IDC))
+          NewIDC = new (*this) CXXFoldExpr(OrigFold->getType(),
+                                           SourceLocation(), NewIDC,
+                                           BinaryOperatorKind::BO_LAnd,
+                                           SourceLocation(), /*RHS=*/nullptr,
+                                           SourceLocation(),
+                                           /*NumExpansions=*/None);
+
         NewTTP->setTypeConstraint(
             NestedNameSpecifierLoc(),
             DeclarationNameInfo(TC->getNamedConcept()->getDeclName(),
                                 SourceLocation()), /*FoundDecl=*/nullptr,
             // Actually canonicalizing a TemplateArgumentLoc is 
diff icult so we
             // simply omit the ArgsAsWritten
-            TC->getNamedConcept(), /*ArgsAsWritten=*/nullptr, NewIDC);
+            CSE->getNamedConcept(), /*ArgsAsWritten=*/nullptr, NewIDC);
       }
       CanonParams.push_back(NewTTP);
     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
@@ -849,13 +839,6 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
                                                 NTTP->isParameterPack(),
                                                 TInfo);
       }
-      if (AutoType *AT = T->getContainedAutoType()) {
-        if (AT->isConstrained()) {
-          Param->setPlaceholderTypeConstraint(
-              canonicalizeImmediatelyDeclaredConstraint(
-                  *this, NTTP->getPlaceholderTypeConstraint(), T));
-        }
-      }
       CanonParams.push_back(Param);
 
     } else
@@ -960,7 +943,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
                        Builtin::Context &builtins)
     : ConstantArrayTypes(this_()), FunctionProtoTypes(this_()),
       TemplateSpecializationTypes(this_()),
-      DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()),
+      DependentTemplateSpecializationTypes(this_()),
       SubstTemplateTemplateParmPacks(this_()),
       CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts),
       SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
@@ -5141,29 +5124,21 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
 /// getAutoType - Return the uniqued reference to the 'auto' type which has been
 /// deduced to the given type, or to the canonical undeduced 'auto' type, or the
 /// canonical deduced-but-dependent 'auto' type.
-QualType
-ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
-                        bool IsDependent, bool IsPack,
-                        ConceptDecl *TypeConstraintConcept,
-                        ArrayRef<TemplateArgument> TypeConstraintArgs) const {
+QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
+                                 bool IsDependent, bool IsPack) const {
   assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack");
-  if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto &&
-      !TypeConstraintConcept && !IsDependent)
+  if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent)
     return getAutoDeductType();
 
   // Look in the folding set for an existing type.
   void *InsertPos = nullptr;
   llvm::FoldingSetNodeID ID;
-  AutoType::Profile(ID, *this, DeducedType, Keyword, IsDependent,
-                    TypeConstraintConcept, TypeConstraintArgs);
+  AutoType::Profile(ID, DeducedType, Keyword, IsDependent, IsPack);
   if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(AT, 0);
 
-  void *Mem = Allocate(sizeof(AutoType) +
-                       sizeof(TemplateArgument) * TypeConstraintArgs.size(),
-                       TypeAlignment);
-  auto *AT = new (Mem) AutoType(DeducedType, Keyword, IsDependent, IsPack,
-                                TypeConstraintConcept, TypeConstraintArgs);
+  auto *AT = new (*this, TypeAlignment)
+      AutoType(DeducedType, Keyword, IsDependent, IsPack);
   Types.push_back(AT);
   if (InsertPos)
     AutoTypes.InsertNode(AT, InsertPos);
@@ -5225,8 +5200,7 @@ QualType ASTContext::getAutoDeductType() const {
   if (AutoDeductTy.isNull())
     AutoDeductTy = QualType(
       new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto,
-                                          /*dependent*/false, /*pack*/false,
-                                          /*concept*/nullptr, /*args*/{}),
+                                          /*dependent*/false, /*pack*/false),
       0);
   return AutoDeductTy;
 }

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 9dd20e2d5921..b67d101eefb4 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1366,21 +1366,9 @@ ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) {
   if (!ToDeducedTypeOrErr)
     return ToDeducedTypeOrErr.takeError();
 
-  ExpectedDecl ToTypeConstraintConcept = import(T->getTypeConstraintConcept());
-  if (!ToTypeConstraintConcept)
-    return ToTypeConstraintConcept.takeError();
-
-  SmallVector<TemplateArgument, 2> ToTemplateArgs;
-  ArrayRef<TemplateArgument> FromTemplateArgs = T->getTypeConstraintArguments();
-  if (Error Err = ImportTemplateArguments(FromTemplateArgs.data(),
-                                          FromTemplateArgs.size(),
-                                          ToTemplateArgs))
-    return std::move(Err);
-
-  return Importer.getToContext().getAutoType(
-      *ToDeducedTypeOrErr, T->getKeyword(), /*IsDependent*/false,
-      /*IsPack=*/false, cast_or_null<ConceptDecl>(*ToTypeConstraintConcept),
-      ToTemplateArgs);
+  return Importer.getToContext().getAutoType(*ToDeducedTypeOrErr,
+                                             T->getKeyword(),
+                                             /*IsDependent*/false);
 }
 
 ExpectedType ASTNodeImporter::VisitInjectedClassNameType(

diff  --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 91a2f3a8391b..db48405055cd 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -729,31 +729,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       return false;
     break;
 
-  case Type::Auto: {
-    auto *Auto1 = cast<AutoType>(T1);
-    auto *Auto2 = cast<AutoType>(T2);
-    if (!IsStructurallyEquivalent(Context, Auto1->getDeducedType(),
-                                  Auto2->getDeducedType()))
+  case Type::Auto:
+    if (!IsStructurallyEquivalent(Context, cast<AutoType>(T1)->getDeducedType(),
+                                  cast<AutoType>(T2)->getDeducedType()))
       return false;
-    if (Auto1->isConstrained() != Auto2->isConstrained())
-      return false;
-    if (Auto1->isConstrained()) {
-      if (Auto1->getTypeConstraintConcept() !=
-          Auto2->getTypeConstraintConcept())
-        return false;
-      ArrayRef<TemplateArgument> Auto1Args =
-          Auto1->getTypeConstraintArguments();
-      ArrayRef<TemplateArgument> Auto2Args =
-          Auto2->getTypeConstraintArguments();
-      if (Auto1Args.size() != Auto2Args.size())
-        return false;
-      for (unsigned I = 0, N = Auto1Args.size(); I != N; ++I) {
-        if (!IsStructurallyEquivalent(Context, Auto1Args[I], Auto2Args[I]))
-          return false;
-      }
-    }
     break;
-  }
 
   case Type::DeducedTemplateSpecialization: {
     const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);

diff  --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 9bd3b64feb4e..58ce49aab400 100755
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -164,15 +164,10 @@ static void AdoptTemplateParameterList(TemplateParameterList *Params,
 void TemplateParameterList::
 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
   if (HasConstrainedParameters)
-    for (const NamedDecl *Param : *this) {
-      if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+    for (const NamedDecl *Param : *this)
+      if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
         if (const auto *TC = TTP->getTypeConstraint())
           AC.push_back(TC->getImmediatelyDeclaredConstraint());
-      } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-        if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
-          AC.push_back(E);
-      }
-    }
   if (HasRequiresClause)
     AC.push_back(getRequiresClause());
 }
@@ -692,14 +687,8 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
                                 unsigned D, unsigned P, IdentifierInfo *Id,
                                 QualType T, bool ParameterPack,
                                 TypeSourceInfo *TInfo) {
-  AutoType *AT =
-      C.getLangOpts().ConceptsTS ? T->getContainedAutoType() : nullptr;
-  return new (C, DC,
-              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
-                                    Expr *>(0,
-                                            AT && AT->isConstrained() ? 1 : 0))
-      NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
-                              TInfo);
+  return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
+                                             T, ParameterPack, TInfo);
 }
 
 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
@@ -707,34 +696,26 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
-  AutoType *AT = TInfo->getType()->getContainedAutoType();
   return new (C, DC,
-              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
-                                    Expr *>(
-                  ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
+              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
+                  ExpandedTypes.size()))
       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
                               ExpandedTypes, ExpandedTInfos);
 }
 
 NonTypeTemplateParmDecl *
-NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
-                                            bool HasTypeConstraint) {
-  return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
-                                                     TypeSourceInfo *>,
-                                           Expr *>(0,
-                                                   HasTypeConstraint ? 1 : 0))
-          NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
-                                  0, 0, nullptr, QualType(), false, nullptr);
+NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
+  return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
+                                             SourceLocation(), 0, 0, nullptr,
+                                             QualType(), false, nullptr);
 }
 
 NonTypeTemplateParmDecl *
 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
-                                            unsigned NumExpandedTypes,
-                                            bool HasTypeConstraint) {
+                                            unsigned NumExpandedTypes) {
   auto *NTTP =
-      new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
-                                        Expr *>(
-                      NumExpandedTypes, HasTypeConstraint ? 1 : 0))
+      new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
+                      NumExpandedTypes))
           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
                                   0, 0, nullptr, QualType(), nullptr, None,
                                   None);

diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 1f9ff9e407dc..27fdca1c4b9c 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -857,13 +857,6 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
 
   void VisitAutoType(const AutoType *T) {
     ID.AddInteger((unsigned)T->getKeyword());
-    ID.AddInteger(T->isConstrained());
-    if (T->isConstrained()) {
-      AddDecl(T->getTypeConstraintConcept());
-      ID.AddInteger(T->getNumArgs());
-      for (const auto &TA : T->getTypeConstraintArguments())
-        Hash.AddTemplateArgument(TA);
-    }
     VisitDeducedType(T);
   }
 

diff  --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index 6f0ebf232e77..db16c2a06b64 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -561,7 +561,7 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
 }
 
 const ASTTemplateArgumentListInfo *
-ASTTemplateArgumentListInfo::Create(const ASTContext &C,
+ASTTemplateArgumentListInfo::Create(ASTContext &C,
                                     const TemplateArgumentListInfo &List) {
   std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));

diff  --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index c9b571862c19..965ad17fcfa5 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1201,11 +1201,6 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) {
     OS << " decltype(auto)";
   if (!T->isDeduced())
     OS << " undeduced";
-  if (T->isConstrained()) {
-    dumpDeclRef(T->getTypeConstraintConcept());
-    for (const auto &Arg : T->getTypeConstraintArguments())
-      VisitTemplateArgument(Arg);
-  }
 }
 
 void TextNodeDumper::VisitTemplateSpecializationType(

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 5099494da5fd..c5ad711d872e 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1114,9 +1114,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
       return QualType(T, 0);
 
     return Ctx.getAutoType(deducedType, T->getKeyword(),
-                           T->isDependentType(), /*IsPack=*/false,
-                           T->getTypeConstraintConcept(),
-                           T->getTypeConstraintArguments());
+                           T->isDependentType());
   }
 
   // FIXME: Non-trivial to implement, but important for C++
@@ -4160,35 +4158,3 @@ void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
                              /*HasUnsignedPadding=*/false);
   APFixedPoint(Val, FXSema).toString(Str);
 }
-
-AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
-                   bool IsDeducedAsDependent, bool IsDeducedAsPack,
-                   ConceptDecl *TypeConstraintConcept,
-                   ArrayRef<TemplateArgument> TypeConstraintArgs)
-    : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
-                  IsDeducedAsDependent, IsDeducedAsPack) {
-  AutoTypeBits.Keyword = (unsigned)Keyword;
-  AutoTypeBits.NumArgs = TypeConstraintArgs.size();
-  this->TypeConstraintConcept = TypeConstraintConcept;
-  if (TypeConstraintConcept) {
-    TemplateArgument *ArgBuffer = getArgBuffer();
-    for (const TemplateArgument &Arg : TypeConstraintArgs) {
-      if (Arg.containsUnexpandedParameterPack())
-        setContainsUnexpandedParameterPack();
-
-      new (ArgBuffer++) TemplateArgument(Arg);
-    }
-  }
-}
-
-void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
-                      QualType Deduced, AutoTypeKeyword Keyword,
-                      bool IsDependent, ConceptDecl *CD,
-                      ArrayRef<TemplateArgument> Arguments) {
-  ID.AddPointer(Deduced.getAsOpaquePtr());
-  ID.AddInteger((unsigned)Keyword);
-  ID.AddBoolean(IsDependent);
-  ID.AddPointer(CD);
-  for (const TemplateArgument &Arg : Arguments)
-    Arg.Profile(ID, Context);
-}

diff  --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 665a86f2c143..6e67ca8e0af7 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -11,7 +11,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/TypeLoc.h"
-#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
@@ -590,97 +589,3 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
     }
   }
 }
-
-DeclarationNameInfo AutoTypeLoc::getConceptNameInfo() const {
-  return DeclarationNameInfo(getNamedConcept()->getDeclName(),
-                             getLocalData()->ConceptNameLoc);
-}
-
-void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
-  setNestedNameSpecifierLoc(NestedNameSpecifierLoc());
-  setTemplateKWLoc(Loc);
-  setConceptNameLoc(Loc);
-  setFoundDecl(nullptr);
-  setRAngleLoc(Loc);
-  setLAngleLoc(Loc);
-  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
-                                                   getTypePtr()->getArgs(),
-                                                   getArgInfos(), Loc);
-  setNameLoc(Loc);
-}
-
-
-namespace {
-
-  class GetContainedAutoTypeLocVisitor :
-    public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {
-  public:
-    using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;
-
-    TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {
-      return TL;
-    }
-
-    // Only these types can contain the desired 'auto' type.
-
-    TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
-      return Visit(T.getNamedTypeLoc());
-    }
-
-    TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
-      return Visit(T.getUnqualifiedLoc());
-    }
-
-    TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {
-      return Visit(T.getPointeeLoc());
-    }
-
-    TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
-      return Visit(T.getPointeeLoc());
-    }
-
-    TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {
-      return Visit(T.getPointeeLoc());
-    }
-
-    TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
-      return Visit(T.getPointeeLoc());
-    }
-
-    TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {
-      return Visit(T.getElementLoc());
-    }
-
-    TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {
-      return Visit(T.getReturnLoc());
-    }
-
-    TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {
-      return Visit(T.getInnerLoc());
-    }
-
-    TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {
-      return Visit(T.getModifiedLoc());
-    }
-
-    TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
-      return Visit(T.getInnerLoc());
-    }
-
-    TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {
-      return Visit(T.getOriginalLoc());
-    }
-
-    TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {
-      return Visit(T.getPatternLoc());
-    }
-  };
-
-} // namespace
-
-AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
-  TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);
-  if (Res.isNull())
-    return AutoTypeLoc();
-  return Res.getAs<AutoTypeLoc>();
-}

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 1495162ac081..3a00a6c11ddb 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1046,13 +1046,6 @@ void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
   if (!T->getDeducedType().isNull()) {
     printBefore(T->getDeducedType(), OS);
   } else {
-    if (T->isConstrained()) {
-      OS << T->getTypeConstraintConcept()->getName();
-      auto Args = T->getTypeConstraintArguments();
-      if (!Args.empty())
-        printTemplateArgumentList(OS, Args, Policy);
-      OS << ' ';
-    }
     switch (T->getKeyword()) {
     case AutoTypeKeyword::Auto: OS << "auto"; break;
     case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
@@ -1241,18 +1234,20 @@ void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
 
 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
                                               raw_ostream &OS) {
-  TemplateTypeParmDecl *D = T->getDecl();
-  if (D && D->isImplicit()) {
-    if (auto *TC = D->getTypeConstraint()) {
-      TC->print(OS, Policy);
-      OS << ' ';
-    }
-    OS << "auto";
-  } else if (IdentifierInfo *Id = T->getIdentifier())
+  if (IdentifierInfo *Id = T->getIdentifier())
     OS << Id->getName();
-  else
-    OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
+  else {
+    bool IsLambdaAutoParam = false;
+    if (auto D = T->getDecl()) {
+      if (auto M = dyn_cast_or_null<CXXMethodDecl>(D->getDeclContext()))
+        IsLambdaAutoParam = D->isImplicit() && M->getParent()->isLambda();
+    }
 
+    if (IsLambdaAutoParam)
+      OS << "auto";
+    else
+      OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
+  }
   spaceBeforePlaceHolder(OS);
 }
 

diff  --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index a75965784168..f8b5fec43800 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -133,9 +133,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
 
   LexedMethod* LM = new LexedMethod(this, FnD);
   getCurrentClass().LateParsedDeclarations.push_back(LM);
-  LM->TemplateScope = getCurScope()->isTemplateParamScope() ||
-      (FnD && isa<FunctionTemplateDecl>(FnD) &&
-       cast<FunctionTemplateDecl>(FnD)->isAbbreviated());
+  LM->TemplateScope = getCurScope()->isTemplateParamScope();
   CachedTokens &Toks = LM->Toks;
 
   tok::TokenKind kind = Tok.getKind();

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4af993c4527f..065a82b9298a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2962,7 +2962,6 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
       case Sema::NC_ContextIndependentExpr:
       case Sema::NC_VarTemplate:
       case Sema::NC_FunctionTemplate:
-      case Sema::NC_Concept:
         // Might be a redeclaration of a prior entity.
         break;
       }
@@ -3194,18 +3193,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
         continue;
       }
 
-      if (Next.is(tok::annot_template_id) &&
-          static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
-            ->Kind == TNK_Concept_template &&
-          GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype)) {
-        DS.getTypeSpecScope() = SS;
-        // This is a qualified placeholder-specifier, e.g., ::C<int> auto ...
-        // Consume the scope annotation and continue to consume the template-id
-        // as a placeholder-specifier.
-        ConsumeAnnotationToken();
-        continue;
-      }
-
       if (Next.is(tok::annot_typename)) {
         DS.getTypeSpecScope() = SS;
         ConsumeAnnotationToken(); // The C++ scope.
@@ -3248,10 +3235,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
       // typename.
       if (!TypeRep) {
-        if (TryAnnotateTypeConstraint())
-          goto DoneWithDeclSpec;
-        if (isTypeConstraintAnnotation())
-          continue;
         // Eat the scope spec so the identifier is current.
         ConsumeAnnotationToken();
         ParsedAttributesWithRange Attrs(AttrFactory);
@@ -3401,10 +3384,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       // If this is not a typedef name, don't parse it as part of the declspec,
       // it must be an implicit int or an error.
       if (!TypeRep) {
-        if (TryAnnotateTypeConstraint())
-          goto DoneWithDeclSpec;
-        if (isTypeConstraintAnnotation())
-          continue;
         ParsedAttributesWithRange Attrs(AttrFactory);
         if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {
           if (!Attrs.empty()) {
@@ -3454,51 +3433,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       continue;
     }
 
-      // type-name or placeholder-specifier
+      // type-name
     case tok::annot_template_id: {
       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
-      if (TemplateId->Kind == TNK_Concept_template) {
-        if (NextToken().is(tok::identifier)) {
-          Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
-              << FixItHint::CreateInsertion(NextToken().getLocation(), "auto");
-          // Attempt to continue as if 'auto' was placed here.
-          isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID,
-                                         TemplateId, Policy);
-          break;
-        }
-        if (!NextToken().isOneOf(tok::kw_auto, tok::kw_decltype))
-            goto DoneWithDeclSpec;
-        ConsumeAnnotationToken();
-        SourceLocation AutoLoc = Tok.getLocation();
-        if (TryConsumeToken(tok::kw_decltype)) {
-          BalancedDelimiterTracker Tracker(*this, tok::l_paren);
-          if (Tracker.consumeOpen()) {
-            // Something like `void foo(Iterator decltype i)`
-            Diag(Tok, diag::err_expected) << tok::l_paren;
-          } else {
-            if (!TryConsumeToken(tok::kw_auto)) {
-              // Something like `void foo(Iterator decltype(int) i)`
-              Tracker.skipToEnd();
-              Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
-                << FixItHint::CreateReplacement(SourceRange(AutoLoc,
-                                                            Tok.getLocation()),
-                                                "auto");
-            } else {
-              Tracker.consumeClose();
-            }
-          }
-          ConsumedEnd = Tok.getLocation();
-          // Even if something went wrong above, continue as if we've seen
-          // `decltype(auto)`.
-          isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,
-                                         DiagID, TemplateId, Policy);
-        } else {
-          isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID,
-                                         TemplateId, Policy);
-        }
-        break;
-      }
-
       if (TemplateId->Kind != TNK_Type_template &&
           TemplateId->Kind != TNK_Undeclared_template) {
         // This template-id does not refer to a type name, so we're
@@ -6090,12 +6027,11 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
 
   while (1) {
     if (Tok.is(tok::l_paren)) {
-      bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration();
       // Enter function-declaration scope, limiting any declarators to the
       // function prototype scope, including parameter declarators.
       ParseScope PrototypeScope(this,
                                 Scope::FunctionPrototypeScope|Scope::DeclScope|
-                                (IsFunctionDeclaration
+                                (D.isFunctionDeclaratorAFunctionDeclaration()
                                    ? Scope::FunctionDeclarationScope : 0));
 
       // The paren may be part of a C++ direct initializer, eg. "int x(1);".
@@ -6114,12 +6050,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
       ParsedAttributes attrs(AttrFactory);
       BalancedDelimiterTracker T(*this, tok::l_paren);
       T.consumeOpen();
-      if (IsFunctionDeclaration)
-        Actions.ActOnStartFunctionDeclarationDeclarator(D,
-                                                        TemplateParameterDepth);
       ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
-      if (IsFunctionDeclaration)
-        Actions.ActOnFinishFunctionDeclarationDeclarator(D);
       PrototypeScope.Exit();
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index f872aa3a950c..9c7d3c566554 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2642,8 +2642,6 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
   }
 
   ParsingDeclarator DeclaratorInfo(*this, DS, DeclaratorContext::MemberContext);
-  if (TemplateInfo.TemplateParams)
-    DeclaratorInfo.setTemplateParameterLists(TemplateParams);
   VirtSpecifiers VS;
 
   // Hold late-parsed attributes so we can attach a Decl to them later.

diff  --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index e96baec0780a..2ac8be430c31 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -240,8 +240,6 @@ Decl *Parser::ParseSingleDeclarationAfterTemplate(
 
   // Parse the declarator.
   ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
-  if (TemplateInfo.TemplateParams)
-    DeclaratorInfo.setTemplateParameterLists(*TemplateInfo.TemplateParams);
   ParseDeclarator(DeclaratorInfo);
   // Error parsing the declarator?
   if (!DeclaratorInfo.hasName()) {
@@ -603,7 +601,6 @@ Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
 ///         typename
 ///
 NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
-
   switch (isStartOfTemplateTypeParameter()) {
   case TPResult::True:
     // Is there just a typo in the input code? ('typedef' instead of
@@ -621,6 +618,7 @@ NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
     }
 
     return ParseTypeParameter(Depth, Position);
+
   case TPResult::False:
     break;
 
@@ -680,6 +678,7 @@ bool Parser::isTypeConstraintAnnotation() {
 bool Parser::TryAnnotateTypeConstraint() {
   if (!getLangOpts().ConceptsTS)
     return false;
+
   CXXScopeSpec SS;
   bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
   if (ParseOptionalCXXScopeSpecifier(

diff  --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index ad0a15b0c8a6..79e96816f864 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1313,18 +1313,6 @@ class TentativeParseCCC final : public CorrectionCandidateCallback {
 Parser::TPResult
 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
                                   bool *InvalidAsDeclSpec) {
-  auto IsPlaceholderSpecifier = [&] (TemplateIdAnnotation *TemplateId,
-                                     int Lookahead) {
-    // We have a placeholder-constraint (we check for 'auto' or 'decltype' to
-    // distinguish 'C<int>;' from 'C<int> auto c = 1;')
-    return TemplateId->Kind == TNK_Concept_template &&
-        GetLookAheadToken(Lookahead + 1).isOneOf(tok::kw_auto, tok::kw_decltype,
-            // If we have an identifier here, the user probably forgot the
-            // 'auto' in the placeholder constraint, e.g. 'C<int> x = 2;'
-            // This will be diagnosed nicely later, so disambiguate as a
-            // declaration.
-            tok::identifier);
-  };
   switch (Tok.getKind()) {
   case tok::identifier: {
     // Check for need to substitute AltiVec __vector keyword
@@ -1528,8 +1516,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
       *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
       return TPResult::Ambiguous;
     }
-    if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0))
-      return TPResult::True;
     if (TemplateId->Kind != TNK_Type_template)
       return TPResult::False;
     CXXScopeSpec SS;
@@ -1543,13 +1529,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
     if (TryAnnotateTypeOrScopeToken())
       return TPResult::Error;
     if (!Tok.is(tok::annot_typename)) {
-      if (Tok.is(tok::annot_cxxscope) &&
-          NextToken().is(tok::annot_template_id)) {
-        TemplateIdAnnotation *TemplateId =
-            takeTemplateIdAnnotation(NextToken());
-        if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1))
-          return TPResult::True;
-      }
       // If the next token is an identifier or a type qualifier, then this
       // can't possibly be a valid expression either.
       if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {

diff  --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0b778bd24277..0194c243f93d 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1136,7 +1136,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
   // Poison SEH identifiers so they are flagged as illegal in function bodies.
   PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
   const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
-  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
 
   // If this is C90 and the declspecs were completely missing, fudge in an
   // implicit int.  We do this here because this is the only place where
@@ -1263,15 +1262,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
   // safe because we're always the sole owner.
   D.getMutableDeclSpec().abort();
 
-  // With abbreviated function templates - we need to explicitly add depth to
-  // account for the implicit template parameter list induced by the template.
-  if (auto *Template = dyn_cast_or_null<FunctionTemplateDecl>(Res))
-    if (Template->isAbbreviated() &&
-        Template->getTemplateParameters()->getParam(0)->isImplicit())
-      // First template parameter is implicit - meaning no explicit template
-      // parameter list was specified.
-      CurTemplateDepthTracker.addDepth(1);
-
   if (TryConsumeToken(tok::equal)) {
     assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
 
@@ -1742,20 +1732,6 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) {
       return ANK_Error;
     return ANK_Success;
   }
-  case Sema::NC_Concept: {
-    UnqualifiedId Id;
-    Id.setIdentifier(Name, NameLoc);
-    if (Next.is(tok::less))
-      // We have a concept name followed by '<'. Consume the identifier token so
-      // we reach the '<' and annotate it.
-      ConsumeToken();
-    if (AnnotateTemplateIdToken(
-            TemplateTy::make(Classification.getTemplateName()),
-            Classification.getTemplateNameKind(), SS, SourceLocation(), Id,
-            /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true))
-      return ANK_Error;
-    return ANK_Success;
-  }
   }
 
   // Unable to classify the name, but maybe we can annotate a scope specifier.

diff  --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 94d87974624e..639231c87232 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -784,15 +784,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
   return false;
 }
 
-bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                               unsigned &DiagID, TemplateIdAnnotation *Rep,
-                               const PrintingPolicy &Policy) {
-  assert(T == TST_auto || T == TST_decltype_auto);
-  ConstrainedAuto = true;
-  TemplateIdRep = Rep;
-  return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy);
-}
-
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
                                unsigned &DiagID,

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 9cfce5a63b1d..7eb8c8d2f760 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -52,21 +52,6 @@ SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) {
 
 ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
 
-IdentifierInfo *
-Sema::InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName,
-                                                 unsigned int Index) {
-  std::string InventedName;
-  llvm::raw_string_ostream OS(InventedName);
-
-  if (!ParamName)
-    OS << "auto:" << Index + 1;
-  else
-    OS << ParamName->getName() << ":auto";
-
-  OS.flush();
-  return &Context.Idents.get(OS.str());
-}
-
 PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
                                        const Preprocessor &PP) {
   PrintingPolicy Policy = Context.getPrintingPolicy();

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0bf490336537..372f3d158597 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10,7 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TreeTransform.h"
 #include "TypeLocBuilder.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -1154,10 +1153,6 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
     return ParsedType::make(T);
   }
 
-  if (isa<ConceptDecl>(FirstDecl))
-    return NameClassification::Concept(
-        TemplateName(cast<TemplateDecl>(FirstDecl)));
-
   // We can have a type template here if we're classifying a template argument.
   if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl) &&
       !isa<VarTemplateDecl>(FirstDecl))
@@ -8661,21 +8656,11 @@ static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) {
 NamedDecl*
 Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
-                              MultiTemplateParamsArg TemplateParamListsRef,
+                              MultiTemplateParamsArg TemplateParamLists,
                               bool &AddToScope) {
   QualType R = TInfo->getType();
 
   assert(R->isFunctionType());
-  SmallVector<TemplateParameterList *, 4> TemplateParamLists;
-  for (TemplateParameterList *TPL : TemplateParamListsRef)
-    TemplateParamLists.push_back(TPL);
-  if (TemplateParameterList *Invented = D.getInventedTemplateParameterList()) {
-    if (!TemplateParamLists.empty() &&
-        Invented->getDepth() == TemplateParamLists.back()->getDepth())
-      TemplateParamLists.back() = Invented;
-    else
-      TemplateParamLists.push_back(Invented);
-  }
 
   // TODO: consider using NameInfo for diagnostic.
   DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
@@ -8755,16 +8740,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     // Match up the template parameter lists with the scope specifier, then
     // determine whether we have a template or a template specialization.
     bool Invalid = false;
-    TemplateParameterList *TemplateParams =
-        MatchTemplateParametersToScopeSpecifier(
-            D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(),
-            D.getCXXScopeSpec(),
-            D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId
-                ? D.getName().TemplateId
-                : nullptr,
-            TemplateParamLists, isFriend, isMemberSpecialization,
-            Invalid);
-    if (TemplateParams) {
+    if (TemplateParameterList *TemplateParams =
+            MatchTemplateParametersToScopeSpecifier(
+                D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(),
+                D.getCXXScopeSpec(),
+                D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId
+                    ? D.getName().TemplateId
+                    : nullptr,
+                TemplateParamLists, isFriend, isMemberSpecialization,
+                Invalid)) {
       if (TemplateParams->size() > 0) {
         // This is a function template
 
@@ -8797,8 +8781,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         // For source fidelity, store the other template param lists.
         if (TemplateParamLists.size() > 1) {
           NewFD->setTemplateParameterListsInfo(Context,
-              ArrayRef<TemplateParameterList *>(TemplateParamLists)
-                  .drop_back(1));
+                                               TemplateParamLists.drop_back(1));
         }
       } else {
         // This is a function template specialization.

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 523daf370fc7..d1e720ebcc2a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -17386,50 +17386,3 @@ MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
 
   return NewPD;
 }
-
-void Sema::ActOnStartFunctionDeclarationDeclarator(
-    Declarator &Declarator, unsigned TemplateParameterDepth) {
-  auto &Info = InventedParameterInfos.emplace_back();
-  TemplateParameterList *ExplicitParams = nullptr;
-  ArrayRef<TemplateParameterList *> ExplicitLists =
-      Declarator.getTemplateParameterLists();
-  if (!ExplicitLists.empty()) {
-    bool IsMemberSpecialization, IsInvalid;
-    ExplicitParams = MatchTemplateParametersToScopeSpecifier(
-        Declarator.getBeginLoc(), Declarator.getIdentifierLoc(),
-        Declarator.getCXXScopeSpec(), /*TemplateId=*/nullptr,
-        ExplicitLists, /*IsFriend=*/false, IsMemberSpecialization, IsInvalid,
-        /*SuppressDiagnostic=*/true);
-  }
-  if (ExplicitParams) {
-    Info.AutoTemplateParameterDepth = ExplicitParams->getDepth();
-    for (NamedDecl *Param : *ExplicitParams)
-      Info.TemplateParams.push_back(Param);
-    Info.NumExplicitTemplateParams = ExplicitParams->size();
-  } else {
-    Info.AutoTemplateParameterDepth = TemplateParameterDepth;
-    Info.NumExplicitTemplateParams = 0;
-  }
-}
-
-void Sema::ActOnFinishFunctionDeclarationDeclarator(Declarator &Declarator) {
-  auto &FSI = InventedParameterInfos.back();
-  if (FSI.TemplateParams.size() > FSI.NumExplicitTemplateParams) {
-    if (FSI.NumExplicitTemplateParams != 0) {
-      TemplateParameterList *ExplicitParams =
-          Declarator.getTemplateParameterLists().back();
-      Declarator.setInventedTemplateParameterList(
-          TemplateParameterList::Create(
-              Context, ExplicitParams->getTemplateLoc(),
-              ExplicitParams->getLAngleLoc(), FSI.TemplateParams,
-              ExplicitParams->getRAngleLoc(),
-              ExplicitParams->getRequiresClause()));
-    } else {
-      Declarator.setInventedTemplateParameterList(
-          TemplateParameterList::Create(
-              Context, SourceLocation(), SourceLocation(), FSI.TemplateParams,
-              SourceLocation(), /*RequiresClause=*/nullptr));
-    }
-  }
-  InventedParameterInfos.pop_back();
-}

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index ae89b146c409..c2d14a44f53d 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -791,8 +791,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(
   // deduce against.
   QualType DeductType = Context.getAutoDeductType();
   TypeLocBuilder TLB;
-  AutoTypeLoc TL = TLB.push<AutoTypeLoc>(DeductType);
-  TL.setNameLoc(Loc);
+  TLB.pushTypeSpec(DeductType).setNameLoc(Loc);
   if (ByRef) {
     DeductType = BuildReferenceType(DeductType, true, Loc, Id);
     assert(!DeductType.isNull() && "can't build reference to auto");

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 2f44f8f08d08..2d87e7b367f3 100755
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1088,50 +1088,6 @@ bool Sema::ActOnTypeConstraint(const CXXScopeSpec &SS,
       ConstrainedParameter, EllipsisLoc);
 }
 
-template<typename ArgumentLocAppender>
-static ExprResult formImmediatelyDeclaredConstraint(
-    Sema &S, NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo,
-    ConceptDecl *NamedConcept, SourceLocation LAngleLoc,
-    SourceLocation RAngleLoc, QualType ConstrainedType,
-    SourceLocation ParamNameLoc, ArgumentLocAppender Appender,
-    SourceLocation EllipsisLoc) {
-
-  TemplateArgumentListInfo ConstraintArgs;
-  ConstraintArgs.addArgument(
-    S.getTrivialTemplateArgumentLoc(TemplateArgument(ConstrainedType),
-                                    /*NTTPType=*/QualType(), ParamNameLoc));
-
-  ConstraintArgs.setRAngleLoc(RAngleLoc);
-  ConstraintArgs.setLAngleLoc(LAngleLoc);
-  Appender(ConstraintArgs);
-
-  // C++2a [temp.param]p4:
-  //     [...] This constraint-expression E is called the immediately-declared
-  //     constraint of T. [...]
-  CXXScopeSpec SS;
-  SS.Adopt(NS);
-  ExprResult ImmediatelyDeclaredConstraint = S.CheckConceptTemplateId(
-      SS, /*TemplateKWLoc=*/SourceLocation(), NameInfo,
-      /*FoundDecl=*/NamedConcept, NamedConcept, &ConstraintArgs);
-  if (ImmediatelyDeclaredConstraint.isInvalid() || !EllipsisLoc.isValid())
-    return ImmediatelyDeclaredConstraint;
-
-  // C++2a [temp.param]p4:
-  //     [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
-  //
-  // We have the following case:
-  //
-  // template<typename T> concept C1 = true;
-  // template<C1... T> struct s1;
-  //
-  // The constraint: (C1<T> && ...)
-  return S.BuildCXXFoldExpr(/*LParenLoc=*/SourceLocation(),
-                            ImmediatelyDeclaredConstraint.get(), BO_LAnd,
-                            EllipsisLoc, /*RHS=*/nullptr,
-                            /*RParenLoc=*/SourceLocation(),
-                            /*NumExpansions=*/None);
-}
-
 /// Attach a type-constraint to a template parameter.
 /// \returns true if an error occured. This can happen if the
 /// immediately-declared constraint could not be formed (e.g. incorrect number
@@ -1150,21 +1106,51 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS,
                                                        *TemplateArgs) : nullptr;
 
   QualType ParamAsArgument(ConstrainedParameter->getTypeForDecl(), 0);
+  TemplateArgumentListInfo ConstraintArgs;
+  ConstraintArgs.addArgument(
+    TemplateArgumentLoc(
+        TemplateArgument(ParamAsArgument),
+        TemplateArgumentLocInfo(
+            Context.getTrivialTypeSourceInfo(ParamAsArgument,
+                ConstrainedParameter->getLocation()))));
+  if (TemplateArgs) {
+    ConstraintArgs.setRAngleLoc(TemplateArgs->getRAngleLoc());
+    ConstraintArgs.setLAngleLoc(TemplateArgs->getLAngleLoc());
+    for (const TemplateArgumentLoc &ArgLoc : TemplateArgs->arguments())
+      ConstraintArgs.addArgument(ArgLoc);
+  }
 
-  ExprResult ImmediatelyDeclaredConstraint =
-      formImmediatelyDeclaredConstraint(
-          *this, NS, NameInfo, NamedConcept,
-          TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(),
-          TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(),
-          ParamAsArgument, ConstrainedParameter->getLocation(),
-          [&] (TemplateArgumentListInfo &ConstraintArgs) {
-            if (TemplateArgs)
-              for (const auto &ArgLoc : TemplateArgs->arguments())
-                ConstraintArgs.addArgument(ArgLoc);
-          }, EllipsisLoc);
+  // C++2a [temp.param]p4:
+  //     [...] This constraint-expression E is called the immediately-declared
+  //     constraint of T. [...]
+  CXXScopeSpec SS;
+  SS.Adopt(NS);
+  ExprResult ImmediatelyDeclaredConstraint = CheckConceptTemplateId(SS,
+      /*TemplateKWLoc=*/SourceLocation(), NameInfo, /*FoundDecl=*/NamedConcept,
+      NamedConcept, &ConstraintArgs);
   if (ImmediatelyDeclaredConstraint.isInvalid())
     return true;
 
+  if (ConstrainedParameter->isParameterPack()) {
+    // C++2a [temp.param]p4:
+    //     [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
+    //
+    // We have the following case:
+    //
+    // template<typename T> concept C1 = true;
+    // template<C1... T> struct s1;
+    //
+    // The constraint: (C1<T> && ...)
+    ImmediatelyDeclaredConstraint =
+        BuildCXXFoldExpr(/*LParenLoc=*/SourceLocation(),
+                         ImmediatelyDeclaredConstraint.get(), BO_LAnd,
+                         EllipsisLoc, /*RHS=*/nullptr,
+                         /*RParenLoc=*/SourceLocation(),
+                         /*NumExpansions=*/None).get();
+    if (ImmediatelyDeclaredConstraint.isInvalid())
+      return true;
+  }
+
   ConstrainedParameter->setTypeConstraint(NS, NameInfo,
                                           /*FoundDecl=*/NamedConcept,
                                           NamedConcept, ArgsAsWritten,
@@ -1172,38 +1158,6 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS,
   return false;
 }
 
-bool Sema::AttachTypeConstraint(AutoTypeLoc TL, NonTypeTemplateParmDecl *NTTP,
-                                SourceLocation EllipsisLoc) {
-  if (NTTP->getType() != TL.getType() ||
-      TL.getAutoKeyword() != AutoTypeKeyword::Auto) {
-    Diag(NTTP->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
-         diag::err_unsupported_placeholder_constraint)
-       << NTTP->getTypeSourceInfo()->getTypeLoc().getSourceRange();
-    return true;
-  }
-  // FIXME: Concepts: This should be the type of the placeholder, but this is
-  // unclear in the wording right now.
-  DeclRefExpr *Ref = BuildDeclRefExpr(NTTP, NTTP->getType(), VK_RValue,
-                                      NTTP->getLocation());
-  if (!Ref)
-    return true;
-  ExprResult ImmediatelyDeclaredConstraint =
-      formImmediatelyDeclaredConstraint(
-          *this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(),
-          TL.getNamedConcept(), TL.getLAngleLoc(), TL.getRAngleLoc(),
-          BuildDecltypeType(Ref, NTTP->getLocation()), NTTP->getLocation(),
-          [&] (TemplateArgumentListInfo &ConstraintArgs) {
-            for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I)
-              ConstraintArgs.addArgument(TL.getArgLoc(I));
-          }, EllipsisLoc);
-  if (ImmediatelyDeclaredConstraint.isInvalid() ||
-     !ImmediatelyDeclaredConstraint.isUsable())
-    return true;
-
-  NTTP->setPlaceholderTypeConstraint(ImmediatelyDeclaredConstraint.get());
-  return false;
-}
-
 /// Check that the type of a non-type template parameter is
 /// well-formed.
 ///
@@ -1365,11 +1319,6 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
       TInfo);
   Param->setAccess(AS_public);
 
-  if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc())
-    if (TL.isConstrained())
-      if (AttachTypeConstraint(TL, Param, D.getEllipsisLoc()))
-        Invalid = true;
-
   if (Invalid)
     Param->setInvalidDecl();
 
@@ -2813,7 +2762,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
     SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS,
     TemplateIdAnnotation *TemplateId,
     ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend,
-    bool &IsMemberSpecialization, bool &Invalid, bool SuppressDiagnostic) {
+    bool &IsMemberSpecialization, bool &Invalid) {
   IsMemberSpecialization = false;
   Invalid = false;
 
@@ -2921,9 +2870,8 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
 
   auto CheckExplicitSpecialization = [&](SourceRange Range, bool Recovery) {
     if (SawNonEmptyTemplateParameterList) {
-      if (!SuppressDiagnostic)
-        Diag(DeclLoc, diag::err_specialize_member_of_template)
-          << !Recovery << Range;
+      Diag(DeclLoc, diag::err_specialize_member_of_template)
+        << !Recovery << Range;
       Invalid = true;
       IsMemberSpecialization = false;
       return true;
@@ -2944,10 +2892,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
     else
       ExpectedTemplateLoc = DeclStartLoc;
 
-    if (!SuppressDiagnostic)
-      Diag(DeclLoc, diag::err_template_spec_needs_header)
-        << Range
-        << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
+    Diag(DeclLoc, diag::err_template_spec_needs_header)
+      << Range
+      << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
     return false;
   };
 
@@ -3037,13 +2984,12 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
       if (ParamIdx < ParamLists.size()) {
         if (ParamLists[ParamIdx]->size() > 0) {
           // The header has template parameters when it shouldn't. Complain.
-          if (!SuppressDiagnostic)
-            Diag(ParamLists[ParamIdx]->getTemplateLoc(),
-                 diag::err_template_param_list_matches_nontemplate)
-              << T
-              << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(),
-                             ParamLists[ParamIdx]->getRAngleLoc())
-              << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
+          Diag(ParamLists[ParamIdx]->getTemplateLoc(),
+               diag::err_template_param_list_matches_nontemplate)
+            << T
+            << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(),
+                           ParamLists[ParamIdx]->getRAngleLoc())
+            << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
           Invalid = true;
           return nullptr;
         }
@@ -3079,7 +3025,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
         if (ExpectedTemplateParams &&
             !TemplateParameterListsAreEqual(ParamLists[ParamIdx],
                                             ExpectedTemplateParams,
-                                            !SuppressDiagnostic, TPL_TemplateMatch))
+                                            true, TPL_TemplateMatch))
           Invalid = true;
 
         if (!Invalid &&
@@ -3091,10 +3037,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
         continue;
       }
 
-      if (!SuppressDiagnostic)
-        Diag(DeclLoc, diag::err_template_spec_needs_template_parameters)
-          << T
-          << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
+      Diag(DeclLoc, diag::err_template_spec_needs_template_parameters)
+        << T
+        << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
       Invalid = true;
       continue;
     }
@@ -3130,18 +3075,16 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
         AllExplicitSpecHeaders = false;
     }
 
-    if (!SuppressDiagnostic)
-      Diag(ParamLists[ParamIdx]->getTemplateLoc(),
-           AllExplicitSpecHeaders ? diag::warn_template_spec_extra_headers
-                                  : diag::err_template_spec_extra_headers)
-          << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(),
-                         ParamLists[ParamLists.size() - 2]->getRAngleLoc());
+    Diag(ParamLists[ParamIdx]->getTemplateLoc(),
+         AllExplicitSpecHeaders ? diag::warn_template_spec_extra_headers
+                                : diag::err_template_spec_extra_headers)
+        << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(),
+                       ParamLists[ParamLists.size() - 2]->getRAngleLoc());
 
     // If there was a specialization somewhere, such that 'template<>' is
     // not required, and there were any 'template<>' headers, note where the
     // specialization occurred.
-    if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader &&
-        !SuppressDiagnostic)
+    if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader)
       Diag(ExplicitSpecLoc,
            diag::note_explicit_template_spec_does_not_need_header)
         << NestedTypes.back();
@@ -6587,12 +6530,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
       DeductionArg = PE->getPattern();
     if (DeduceAutoType(
             Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()),
-            DeductionArg, ParamType, Depth,
-            // We do not check constraints right now because the
-            // immediately-declared constraint of the auto type is also an
-            // associated constraint, and will be checked along with the other
-            // associated constraints after checking the template argument list.
-            /*IgnoreConstraints=*/true) == DAR_Failed) {
+            DeductionArg, ParamType, Depth) == DAR_Failed) {
       Diag(Arg->getExprLoc(),
            diag::err_non_type_template_parm_type_deduction_failure)
         << Param->getDeclName() << Param->getType() << Arg->getType()

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 394c81c82794..048a50a741e4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4414,10 +4414,9 @@ namespace {
 
       QualType Result = SemaRef.Context.getAutoType(
           Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(),
-          ReplacementIsPack, TL.getTypePtr()->getTypeConstraintConcept(),
-          TL.getTypePtr()->getTypeConstraintArguments());
+          ReplacementIsPack);
       auto NewTL = TLB.push<AutoTypeLoc>(Result);
-      NewTL.copy(TL);
+      NewTL.setNameLoc(TL.getNameLoc());
       return Result;
     }
 
@@ -4452,10 +4451,9 @@ namespace {
 
 Sema::DeduceAutoResult
 Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result,
-                     Optional<unsigned> DependentDeductionDepth,
-                     bool IgnoreConstraints) {
+                     Optional<unsigned> DependentDeductionDepth) {
   return DeduceAutoType(Type->getTypeLoc(), Init, Result,
-                        DependentDeductionDepth, IgnoreConstraints);
+                        DependentDeductionDepth);
 }
 
 /// Attempt to produce an informative diagostic explaining why auto deduction
@@ -4483,49 +4481,6 @@ static bool diagnoseAutoDeductionFailure(Sema &S,
   }
 }
 
-static Sema::DeduceAutoResult
-CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
-                                   AutoTypeLoc TypeLoc, QualType Deduced) {
-  ConstraintSatisfaction Satisfaction;
-  ConceptDecl *Concept = Type.getTypeConstraintConcept();
-  TemplateArgumentListInfo TemplateArgs(TypeLoc.getLAngleLoc(),
-                                        TypeLoc.getRAngleLoc());
-  TemplateArgs.addArgument(
-      TemplateArgumentLoc(TemplateArgument(Deduced),
-                          S.Context.getTrivialTypeSourceInfo(
-                              Deduced, TypeLoc.getNameLoc())));
-  for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I)
-    TemplateArgs.addArgument(TypeLoc.getArgLoc(I));
-
-  llvm::SmallVector<TemplateArgument, 4> Converted;
-  if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
-                                  /*PartialTemplateArgs=*/false, Converted))
-    return Sema::DAR_FailedAlreadyDiagnosed;
-  if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
-                                    Converted, TypeLoc.getLocalSourceRange(),
-                                    Satisfaction))
-    return Sema::DAR_FailedAlreadyDiagnosed;
-  if (!Satisfaction.IsSatisfied) {
-    std::string Buf;
-    llvm::raw_string_ostream OS(Buf);
-    OS << "'" << Concept->getName();
-    if (TypeLoc.hasExplicitTemplateArgs()) {
-      OS << "<";
-      for (const auto &Arg : Type.getTypeConstraintArguments())
-        Arg.print(S.getPrintingPolicy(), OS);
-      OS << ">";
-    }
-    OS << "'";
-    OS.flush();
-    S.Diag(TypeLoc.getConceptNameLoc(),
-           diag::err_placeholder_constraints_not_satisfied)
-         << Deduced << Buf << TypeLoc.getLocalSourceRange();
-    S.DiagnoseUnsatisfiedConstraint(Satisfaction);
-    return Sema::DAR_FailedAlreadyDiagnosed;
-  }
-  return Sema::DAR_Succeeded;
-}
-
 /// Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
 ///
 /// Note that this is done even if the initializer is dependent. (This is
@@ -4540,12 +4495,9 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
 ///        dependent cases. This is necessary for template partial ordering with
 ///        'auto' template parameters. The value specified is the template
 ///        parameter depth at which we should perform 'auto' deduction.
-/// \param IgnoreConstraints Set if we should not fail if the deduced type does
-///                          not satisfy the type-constraint in the auto type.
 Sema::DeduceAutoResult
 Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
-                     Optional<unsigned> DependentDeductionDepth,
-                     bool IgnoreConstraints) {
+                     Optional<unsigned> DependentDeductionDepth) {
   if (Init->getType()->isNonOverloadPlaceholderType()) {
     ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
     if (NonPlaceholder.isInvalid())
@@ -4586,14 +4538,6 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
         return DAR_FailedAlreadyDiagnosed;
       // FIXME: Support a non-canonical deduced type for 'auto'.
       Deduced = Context.getCanonicalType(Deduced);
-      if (AT->isConstrained() && !IgnoreConstraints) {
-        auto ConstraintsResult =
-            CheckDeducedPlaceholderConstraints(*this, *AT,
-                                               Type.getContainedAutoTypeLoc(),
-                                               Deduced);
-        if (ConstraintsResult != DAR_Succeeded)
-          return ConstraintsResult;
-      }
       Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type);
       if (Result.isNull())
         return DAR_FailedAlreadyDiagnosed;
@@ -4701,17 +4645,6 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
       return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs<AutoType>()) {
-    if (AT->isConstrained() && !IgnoreConstraints) {
-      auto ConstraintsResult =
-          CheckDeducedPlaceholderConstraints(*this, *AT,
-                                             Type.getContainedAutoTypeLoc(),
-                                             DeducedType);
-      if (ConstraintsResult != DAR_Succeeded)
-        return ConstraintsResult;
-    }
-  }
-
   Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
   if (Result.isNull())
     return DAR_FailedAlreadyDiagnosed;

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8fd7491c45e3..7d60298be2be 100755
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2685,16 +2685,6 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
         D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
         D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);
 
-  if (AutoTypeLoc AutoLoc = DI->getTypeLoc().getContainedAutoTypeLoc())
-    if (AutoLoc.isConstrained())
-      if (SemaRef.AttachTypeConstraint(
-              AutoLoc, Param,
-              IsExpandedParameterPack
-                ? DI->getTypeLoc().getAs<PackExpansionTypeLoc>()
-                    .getEllipsisLoc()
-                : SourceLocation()))
-        Invalid = true;
-
   Param->setAccess(AS_public);
   Param->setImplicit(D->isImplicit());
   if (Invalid)

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 02ca73e9fc59..efb4437b3e60 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -11,7 +11,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "TypeLocBuilder.h"
-#include "TreeTransform.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
@@ -28,7 +27,6 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Lookup.h"
-#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
@@ -1253,26 +1251,6 @@ getImageAccess(const ParsedAttributesView &Attrs) {
   return OpenCLAccessAttr::Keyword_read_only;
 }
 
-static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS,
-                                                     AutoTypeKeyword AutoKW) {
-  assert(DS.isConstrainedAuto());
-  TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
-  TemplateArgumentListInfo TemplateArgsInfo;
-  TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc);
-  TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc);
-  ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                     TemplateId->NumArgs);
-  S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
-  llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
-  for (auto &ArgLoc : TemplateArgsInfo.arguments())
-    TemplateArgs.push_back(ArgLoc.getArgument());
-  return S.Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false,
-                               /*IsPack=*/false,
-                               cast<ConceptDecl>(TemplateId->Template.get()
-                                                 .getAsTemplateDecl()),
-                               TemplateArgs);
-}
-
 /// Convert the specified declspec to the appropriate type
 /// object.
 /// \param state Specifies the declarator containing the declaration specifier
@@ -1617,11 +1595,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     break;
 
   case DeclSpec::TST_auto:
-    if (DS.isConstrainedAuto()) {
-      Result = ConvertConstrainedAutoDeclSpecToType(S, DS,
-                                                    AutoTypeKeyword::Auto);
-      break;
-    }
     Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false);
     break;
 
@@ -1630,12 +1603,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     break;
 
   case DeclSpec::TST_decltype_auto:
-    if (DS.isConstrainedAuto()) {
-      Result =
-          ConvertConstrainedAutoDeclSpecToType(S, DS,
-                                               AutoTypeKeyword::DecltypeAuto);
-      break;
-    }
     Result = Context.getAutoType(QualType(), AutoTypeKeyword::DecltypeAuto,
                                  /*IsDependent*/ false);
     break;
@@ -2954,87 +2921,6 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
                               D.getDeclSpec().getUnalignedSpecLoc());
 }
 
-static void CopyTypeConstraintFromAutoType(Sema &SemaRef, const AutoType *Auto,
-                                           AutoTypeLoc AutoLoc,
-                                           TemplateTypeParmDecl *TP,
-                                           SourceLocation EllipsisLoc) {
-
-  TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc());
-  for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx)
-    TAL.addArgument(AutoLoc.getArgLoc(Idx));
-
-  SemaRef.AttachTypeConstraint(
-      AutoLoc.getNestedNameSpecifierLoc(), AutoLoc.getConceptNameInfo(),
-      AutoLoc.getNamedConcept(),
-      AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr, TP, EllipsisLoc);
-}
-
-static QualType InventTemplateParameter(
-    TypeProcessingState &state, QualType T, TypeSourceInfo *TSI, AutoType *Auto,
-    InventedTemplateParameterInfo &Info) {
-  Sema &S = state.getSema();
-  Declarator &D = state.getDeclarator();
-
-  const unsigned TemplateParameterDepth = Info.AutoTemplateParameterDepth;
-  const unsigned AutoParameterPosition = Info.TemplateParams.size();
-  const bool IsParameterPack = D.hasEllipsis();
-
-  // If auto is mentioned in a lambda parameter or abbreviated function
-  // template context, convert it to a template parameter type.
-
-  // Create the TemplateTypeParmDecl here to retrieve the corresponding
-  // template parameter type. Template parameters are temporarily added
-  // to the TU until the associated TemplateDecl is created.
-  TemplateTypeParmDecl *InventedTemplateParam =
-      TemplateTypeParmDecl::Create(
-          S.Context, S.Context.getTranslationUnitDecl(),
-          /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(),
-          /*NameLoc=*/D.getIdentifierLoc(),
-          TemplateParameterDepth, AutoParameterPosition,
-          S.InventAbbreviatedTemplateParameterTypeName(
-              D.getIdentifier(), AutoParameterPosition), false,
-          IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained());
-  InventedTemplateParam->setImplicit();
-  Info.TemplateParams.push_back(InventedTemplateParam);
-  // Attach type constraints
-  if (Auto->isConstrained()) {
-    if (TSI) {
-      CopyTypeConstraintFromAutoType(
-          S, Auto, TSI->getTypeLoc().getContainedAutoTypeLoc(),
-          InventedTemplateParam, D.getEllipsisLoc());
-    } else {
-      TemplateIdAnnotation *TemplateId = D.getDeclSpec().getRepAsTemplateId();
-      TemplateArgumentListInfo TemplateArgsInfo;
-      if (TemplateId->LAngleLoc.isValid()) {
-        ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                           TemplateId->NumArgs);
-        S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
-      }
-      S.AttachTypeConstraint(
-          D.getDeclSpec().getTypeSpecScope().getWithLocInContext(S.Context),
-          DeclarationNameInfo(DeclarationName(TemplateId->Name),
-                              TemplateId->TemplateNameLoc),
-          cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl()),
-          TemplateId->LAngleLoc.isValid() ? &TemplateArgsInfo : nullptr,
-          InventedTemplateParam, D.getEllipsisLoc());
-    }
-  }
-
-  // If TSI is nullptr, this is a constrained declspec auto and the type
-  // constraint will be attached later in TypeSpecLocFiller
-
-  // Replace the 'auto' in the function parameter with this invented
-  // template type parameter.
-  // FIXME: Retain some type sugar to indicate that this was written
-  //  as 'auto'?
-  return state.ReplaceAutoType(
-      T, QualType(InventedTemplateParam->getTypeForDecl(), 0));
-}
-
-static TypeSourceInfo *
-GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
-                               QualType T, TypeSourceInfo *ReturnTypeInfo);
-
 static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
                                              TypeSourceInfo *&ReturnTypeInfo) {
   Sema &SemaRef = state.getSema();
@@ -3105,43 +2991,46 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
       break;
     case DeclaratorContext::ObjCParameterContext:
     case DeclaratorContext::ObjCResultContext:
+    case DeclaratorContext::PrototypeContext:
       Error = 0;
       break;
     case DeclaratorContext::RequiresExprContext:
-      Error = 22;
+      Error = 21;
       break;
-    case DeclaratorContext::PrototypeContext:
-    case DeclaratorContext::LambdaExprParameterContext: {
-      InventedTemplateParameterInfo *Info = nullptr;
-      if (D.getContext() == DeclaratorContext::PrototypeContext) {
-        // With concepts we allow 'auto' in function parameters.
-        if (!SemaRef.getLangOpts().ConceptsTS || !Auto ||
-            Auto->getKeyword() != AutoTypeKeyword::Auto) {
-          Error = 0;
-          break;
-        } else if (!SemaRef.getCurScope()->isFunctionDeclarationScope()) {
-          Error = 21;
-          break;
-        } else if (D.hasTrailingReturnType()) {
-          // This might be OK, but we'll need to convert the trailing return
-          // type later.
-          break;
-        }
-
-        Info = &SemaRef.InventedParameterInfos.back();
-      } else {
-        // In C++14, generic lambdas allow 'auto' in their parameters.
-        if (!SemaRef.getLangOpts().CPlusPlus14 || !Auto ||
-            Auto->getKeyword() != AutoTypeKeyword::Auto) {
-          Error = 16;
-          break;
-        }
-        Info = SemaRef.getCurLambda();
-        assert(Info && "No LambdaScopeInfo on the stack!");
+    case DeclaratorContext::LambdaExprParameterContext:
+      // In C++14, generic lambdas allow 'auto' in their parameters.
+      if (!SemaRef.getLangOpts().CPlusPlus14 ||
+          !Auto || Auto->getKeyword() != AutoTypeKeyword::Auto)
+        Error = 16;
+      else {
+        // If auto is mentioned in a lambda parameter context, convert it to a
+        // template parameter type.
+        sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda();
+        assert(LSI && "No LambdaScopeInfo on the stack!");
+        const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;
+        const unsigned AutoParameterPosition = LSI->TemplateParams.size();
+        const bool IsParameterPack = D.hasEllipsis();
+
+        // Create the TemplateTypeParmDecl here to retrieve the corresponding
+        // template parameter type. Template parameters are temporarily added
+        // to the TU until the associated TemplateDecl is created.
+        TemplateTypeParmDecl *CorrespondingTemplateParam =
+            TemplateTypeParmDecl::Create(
+                SemaRef.Context, SemaRef.Context.getTranslationUnitDecl(),
+                /*KeyLoc*/ SourceLocation(), /*NameLoc*/ D.getBeginLoc(),
+                TemplateParameterDepth, AutoParameterPosition,
+                /*Identifier*/ nullptr, false, IsParameterPack,
+                /*HasTypeConstraint=*/false);
+        CorrespondingTemplateParam->setImplicit();
+        LSI->TemplateParams.push_back(CorrespondingTemplateParam);
+        // Replace the 'auto' in the function parameter with this invented
+        // template type parameter.
+        // FIXME: Retain some type sugar to indicate that this was written
+        // as 'auto'.
+        T = state.ReplaceAutoType(
+            T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0));
       }
-      T = InventTemplateParameter(state, T, nullptr, Auto, *Info);
       break;
-    }
     case DeclaratorContext::MemberContext: {
       if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
           D.isFunctionDeclarator())
@@ -4143,6 +4032,10 @@ static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld,
   return false;
 }
 
+static TypeSourceInfo *
+GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
+                               QualType T, TypeSourceInfo *ReturnTypeInfo);
+
 static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
                                                 QualType declSpecType,
                                                 TypeSourceInfo *TInfo) {
@@ -4718,8 +4611,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
           } else if (D.getContext() != DeclaratorContext::LambdaExprContext &&
                      (T.hasQualifiers() || !isa<AutoType>(T) ||
                       cast<AutoType>(T)->getKeyword() !=
-                          AutoTypeKeyword::Auto ||
-                      cast<AutoType>(T)->isConstrained())) {
+                          AutoTypeKeyword::Auto)) {
             S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
                    diag::err_trailing_return_without_auto)
                 << T << D.getDeclSpec().getSourceRange();
@@ -4730,12 +4622,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
             // An error occurred parsing the trailing return type.
             T = Context.IntTy;
             D.setInvalidType(true);
-          } else if (S.getLangOpts().ConceptsTS)
-            // Handle cases like: `auto f() -> auto` or `auto f() -> C auto`.
-            if (AutoType *Auto = T->getContainedAutoType())
-              if (S.getCurScope()->isFunctionDeclarationScope())
-                T = InventTemplateParameter(state, T, TInfo, Auto,
-                                            S.InventedParameterInfos.back());
+          }
         } else {
           // This function type is not the type of the entity being declared,
           // so checking the 'auto' is not the responsibility of this chunk.
@@ -5355,8 +5242,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
       //
       // We represent function parameter packs as function parameters whose
       // type is a pack expansion.
-      if (!T->containsUnexpandedParameterPack() &&
-          (!LangOpts.ConceptsTS || !T->getContainedAutoType())) {
+      if (!T->containsUnexpandedParameterPack()) {
         S.Diag(D.getEllipsisLoc(),
              diag::err_function_parameter_pack_without_parameter_packs)
           << T <<  D.getSourceRange();
@@ -5564,15 +5450,14 @@ static void fillAttributedTypeLoc(AttributedTypeLoc TL,
 
 namespace {
   class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
-    Sema &SemaRef;
     ASTContext &Context;
     TypeProcessingState &State;
     const DeclSpec &DS;
 
   public:
-    TypeSpecLocFiller(Sema &S, ASTContext &Context, TypeProcessingState &State,
+    TypeSpecLocFiller(ASTContext &Context, TypeProcessingState &State,
                       const DeclSpec &DS)
-        : SemaRef(S), Context(Context), State(State), DS(DS) {}
+        : Context(Context), State(State), DS(DS) {}
 
     void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
       Visit(TL.getModifiedLoc());
@@ -5700,32 +5585,6 @@ namespace {
       TL.copy(
           TInfo->getTypeLoc().castAs<DependentTemplateSpecializationTypeLoc>());
     }
-    void VisitAutoTypeLoc(AutoTypeLoc TL) {
-      assert(DS.getTypeSpecType() == TST_auto ||
-             DS.getTypeSpecType() == TST_decltype_auto ||
-             DS.getTypeSpecType() == TST_auto_type ||
-             DS.getTypeSpecType() == TST_unspecified);
-      TL.setNameLoc(DS.getTypeSpecTypeLoc());
-      if (!DS.isConstrainedAuto())
-        return;
-      TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
-      if (DS.getTypeSpecScope().isNotEmpty())
-        TL.setNestedNameSpecifierLoc(
-            DS.getTypeSpecScope().getWithLocInContext(Context));
-      else
-        TL.setNestedNameSpecifierLoc(NestedNameSpecifierLoc());
-      TL.setConceptNameLoc(TemplateId->TemplateNameLoc);
-      TL.setLAngleLoc(TemplateId->LAngleLoc);
-      TL.setRAngleLoc(TemplateId->RAngleLoc);
-      if (TemplateId->NumArgs == 0)
-        return;
-      TemplateArgumentListInfo TemplateArgsInfo;
-      ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                         TemplateId->NumArgs);
-      SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
-      for (unsigned I = 0; I < TemplateId->NumArgs; ++I)
-        TL.setArgLocInfo(I, TemplateArgsInfo.arguments()[I].getLocInfo());
-    }
     void VisitTagTypeLoc(TagTypeLoc TL) {
       TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
     }
@@ -5995,7 +5854,7 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
     assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
     memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
   } else {
-    TypeSpecLocFiller(S, S.Context, State, D.getDeclSpec()).Visit(CurrTL);
+    TypeSpecLocFiller(S.Context, State, D.getDeclSpec()).Visit(CurrTL);
   }
 
   return TInfo;

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index d6105353bbdf..1f7251173838 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -951,16 +951,12 @@ class TreeTransform {
   /// Build a new C++11 auto type.
   ///
   /// By default, builds a new AutoType with the given deduced type.
-  QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
-                           ConceptDecl *TypeConstraintConcept,
-                           ArrayRef<TemplateArgument> TypeConstraintArgs) {
+  QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword) {
     // Note, IsDependent is always false here: we implicitly convert an 'auto'
     // which has been deduced to a dependent type into an undeduced 'auto', so
     // that we'll retry deduction after the transformation.
     return SemaRef.Context.getAutoType(Deduced, Keyword,
-                                       /*IsDependent*/ false, /*IsPack=*/false,
-                                       TypeConstraintConcept,
-                                       TypeConstraintArgs);
+                                       /*IsDependent*/ false);
   }
 
   /// By default, builds a new DeducedTemplateSpecializationType with the given
@@ -4504,10 +4500,7 @@ QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
         Deduced =
             SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
         T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
-                                        AutoTy->isDependentType(),
-                                        /*isPack=*/false,
-                                        AutoTy->getTypeConstraintConcept(),
-                                        AutoTy->getTypeConstraintArguments());
+                                        AutoTy->isDependentType());
       } else {
         // Otherwise, complain about the addition of a qualifier to an
         // already-qualified type.
@@ -5240,29 +5233,21 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
         PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
         TypeLoc Pattern = ExpansionTL.getPatternLoc();
         SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
+        assert(Unexpanded.size() > 0 && "Could not find parameter packs!");
 
         // Determine whether we should expand the parameter packs.
         bool ShouldExpand = false;
         bool RetainExpansion = false;
-        Optional<unsigned> OrigNumExpansions;
-        if (Unexpanded.size() > 0) {
-          OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
-          NumExpansions = OrigNumExpansions;
-          if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
-                                                   Pattern.getSourceRange(),
-                                                   Unexpanded,
-                                                   ShouldExpand,
-                                                   RetainExpansion,
-                                                   NumExpansions)) {
-            return true;
-          }
-        } else {
-#ifndef NDEBUG
-          const AutoType *AT =
-              Pattern.getType().getTypePtr()->getContainedAutoType();
-          assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
-                 "Could not find parameter packs or undeduced auto type!");
-#endif
+        Optional<unsigned> OrigNumExpansions =
+            ExpansionTL.getTypePtr()->getNumExpansions();
+        NumExpansions = OrigNumExpansions;
+        if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
+                                                 Pattern.getSourceRange(),
+                                                 Unexpanded,
+                                                 ShouldExpand,
+                                                 RetainExpansion,
+                                                 NumExpansions)) {
+          return true;
         }
 
         if (ShouldExpand) {
@@ -5322,9 +5307,6 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
                                                           indexAdjustment,
                                                           NumExpansions,
                                                   /*ExpectParameterPack=*/true);
-        assert(NewParm->isParameterPack() &&
-               "Parameter pack no longer a parameter pack after "
-               "transformation.");
       } else {
         NewParm = getDerived().TransformFunctionTypeParam(
             OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false);
@@ -5829,6 +5811,32 @@ QualType TreeTransform<Derived>::TransformUnaryTransformType(
   return Result;
 }
 
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
+                                                   AutoTypeLoc TL) {
+  const AutoType *T = TL.getTypePtr();
+  QualType OldDeduced = T->getDeducedType();
+  QualType NewDeduced;
+  if (!OldDeduced.isNull()) {
+    NewDeduced = getDerived().TransformType(OldDeduced);
+    if (NewDeduced.isNull())
+      return QualType();
+  }
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
+      T->isDependentType()) {
+    Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword());
+    if (Result.isNull())
+      return QualType();
+  }
+
+  AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+
+  return Result;
+}
+
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
     TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
@@ -6090,71 +6098,6 @@ QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
     }
   };
 
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
-                                                   AutoTypeLoc TL) {
-  const AutoType *T = TL.getTypePtr();
-  QualType OldDeduced = T->getDeducedType();
-  QualType NewDeduced;
-  if (!OldDeduced.isNull()) {
-    NewDeduced = getDerived().TransformType(OldDeduced);
-    if (NewDeduced.isNull())
-      return QualType();
-  }
-
-  ConceptDecl *NewCD = nullptr;
-  TemplateArgumentListInfo NewTemplateArgs;
-  NestedNameSpecifierLoc NewNestedNameSpec;
-  if (TL.getTypePtr()->isConstrained()) {
-    NewCD = cast_or_null<ConceptDecl>(
-        getDerived().TransformDecl(
-            TL.getConceptNameLoc(),
-            TL.getTypePtr()->getTypeConstraintConcept()));
-
-    NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
-    NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
-    typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
-    if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
-                                                ArgIterator(TL,
-                                                            TL.getNumArgs()),
-                                                NewTemplateArgs))
-      return QualType();
-
-    if (TL.getNestedNameSpecifierLoc()) {
-      NewNestedNameSpec
-        = getDerived().TransformNestedNameSpecifierLoc(
-            TL.getNestedNameSpecifierLoc());
-      if (!NewNestedNameSpec)
-        return QualType();
-    }
-  }
-
-  QualType Result = TL.getType();
-  if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
-      T->isDependentType()) {
-    llvm::SmallVector<TemplateArgument, 4> NewArgList;
-    NewArgList.reserve(NewArgList.size());
-    for (const auto &ArgLoc : NewTemplateArgs.arguments())
-      NewArgList.push_back(ArgLoc.getArgument());
-    Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
-                                          NewArgList);
-    if (Result.isNull())
-      return QualType();
-  }
-
-  AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
-  NewTL.setNestedNameSpecifierLoc(NewNestedNameSpec);
-  NewTL.setTemplateKWLoc(TL.getTemplateKWLoc());
-  NewTL.setConceptNameLoc(TL.getConceptNameLoc());
-  NewTL.setFoundDecl(TL.getFoundDecl());
-  NewTL.setLAngleLoc(TL.getLAngleLoc());
-  NewTL.setRAngleLoc(TL.getRAngleLoc());
-  for (unsigned I = 0; I < TL.getNumArgs(); ++I)
-    NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo());
-
-  return Result;
-}
 
 template <typename Derived>
 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(

diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 5351ac31c179..342ac20a1aee 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -6576,17 +6576,6 @@ void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
 
 void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
   TL.setNameLoc(readSourceLocation());
-  if (Reader.readBool()) {
-    TL.setNestedNameSpecifierLoc(ReadNestedNameSpecifierLoc());
-    TL.setTemplateKWLoc(readSourceLocation());
-    TL.setConceptNameLoc(readSourceLocation());
-    TL.setFoundDecl(Reader.readDeclAs<NamedDecl>());
-    TL.setLAngleLoc(readSourceLocation());
-    TL.setRAngleLoc(readSourceLocation());
-    for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
-      TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo(
-                              TL.getTypePtr()->getArg(i).getKind()));
-  }
 }
 
 void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 093b69ab19d0..4fd079e9d8e1 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2317,12 +2317,12 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (Record.readBool()) {
+  if (Record.readInt()) {
     NestedNameSpecifierLoc NNS = Record.readNestedNameSpecifierLoc();
     DeclarationNameInfo DN = Record.readDeclarationNameInfo();
-    ConceptDecl *NamedConcept = Record.readDeclAs<ConceptDecl>();
+    ConceptDecl *NamedConcept = cast<ConceptDecl>(Record.readDecl());
     const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
-    if (Record.readBool())
+    if (Record.readInt())
         ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
     Expr *ImmediatelyDeclaredConstraint = Record.readExpr();
     D->setTypeConstraint(NNS, DN, /*FoundDecl=*/nullptr, NamedConcept,
@@ -2340,8 +2340,6 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   // TemplateParmPosition.
   D->setDepth(Record.readInt());
   D->setPosition(Record.readInt());
-  if (D->hasPlaceholderTypeConstraint())
-    D->setPlaceholderTypeConstraint(Record.readExpr());
   if (D->isExpandedParameterPack()) {
     auto TypesAndInfos =
         D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
@@ -3825,19 +3823,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
                                                  HasTypeConstraint);
     break;
   }
-  case DECL_NON_TYPE_TEMPLATE_PARM: {
-    bool HasTypeConstraint = Record.readInt();
-    D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
-                                                    HasTypeConstraint);
+  case DECL_NON_TYPE_TEMPLATE_PARM:
+    D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID);
     break;
-  }
-  case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: {
-    bool HasTypeConstraint = Record.readInt();
+  case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
     D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
-                                                    Record.readInt(),
-                                                    HasTypeConstraint);
+                                                    Record.readInt());
     break;
-  }
   case DECL_TEMPLATE_TEMPLATE_PARM:
     D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID);
     break;

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 79f7d577c672..c216b14661d4 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -349,18 +349,6 @@ void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
 
 void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
   Record.AddSourceLocation(TL.getNameLoc());
-  Record.push_back(TL.isConstrained());
-  if (TL.isConstrained()) {
-    Record.AddNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc());
-    Record.AddSourceLocation(TL.getTemplateKWLoc());
-    Record.AddSourceLocation(TL.getConceptNameLoc());
-    Record.AddDeclRef(TL.getFoundDecl());
-    Record.AddSourceLocation(TL.getLAngleLoc());
-    Record.AddSourceLocation(TL.getRAngleLoc());
-    for (unsigned I = 0; I < TL.getNumArgs(); ++I)
-      Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
-                                        TL.getArgLocInfo(I));
-  }
 }
 
 void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(

diff  --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 472136d99a13..459e61713ed1 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1675,8 +1675,6 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   // For an expanded parameter pack, record the number of expansion types here
   // so that it's easier for deserialization to allocate the right amount of
   // memory.
-  Expr *TypeConstraint = D->getPlaceholderTypeConstraint();
-  Record.push_back(!!TypeConstraint);
   if (D->isExpandedParameterPack())
     Record.push_back(D->getNumExpansionTypes());
 
@@ -1684,8 +1682,6 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   // TemplateParmPosition.
   Record.push_back(D->getDepth());
   Record.push_back(D->getPosition());
-  if (TypeConstraint)
-    Record.AddStmt(TypeConstraint);
 
   if (D->isExpandedParameterPack()) {
     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {

diff  --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp
index 44ec2a2f7bc6..2603eedcd817 100644
--- a/clang/test/AST/ast-dump-record-definition-data-json.cpp
+++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp
@@ -417,24 +417,15 @@ struct DoesNotAllowConstDefaultInit {
 // CHECK-NEXT:      "id": "0x{{.*}}",
 // CHECK-NEXT:      "kind": "TemplateTypeParmDecl",
 // CHECK-NEXT:      "loc": {
-// CHECK-NEXT:        "offset": 197,
-// CHECK-NEXT:        "col": 33,
-// CHECK-NEXT:        "tokLen": 1
+// CHECK-NEXT:       "offset": 193,
+// CHECK-NEXT:       "col": 29,
+// CHECK-NEXT:       "tokLen": 4
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "range": {
-// CHECK-NEXT:        "begin": {
-// CHECK-NEXT:          "offset": 193,
-// CHECK-NEXT:          "col": 29,
-// CHECK-NEXT:          "tokLen": 4
-// CHECK-NEXT:        },
-// CHECK-NEXT:        "end": {
-// CHECK-NEXT:          "offset": 197,
-// CHECK-NEXT:          "col": 33,
-// CHECK-NEXT:          "tokLen": 1
-// CHECK-NEXT:        }
+// CHECK-NEXT:       "begin": {},
+// CHECK-NEXT:       "end": {}
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "isImplicit": true,
-// CHECK-NEXT:      "name": "auto:1",
 // CHECK-NEXT:      "tagUsed": "class",
 // CHECK-NEXT:      "depth": 0,
 // CHECK-NEXT:      "index": 0
@@ -533,24 +524,15 @@ struct DoesNotAllowConstDefaultInit {
 // CHECK-NEXT:      "id": "0x{{.*}}",
 // CHECK-NEXT:      "kind": "TemplateTypeParmDecl",
 // CHECK-NEXT:      "loc": {
-// CHECK-NEXT:        "offset": 197,
-// CHECK-NEXT:        "col": 33,
-// CHECK-NEXT:        "tokLen": 1
+// CHECK-NEXT:       "offset": 193,
+// CHECK-NEXT:       "col": 29,
+// CHECK-NEXT:       "tokLen": 4
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "range": {
-// CHECK-NEXT:        "begin": {
-// CHECK-NEXT:          "offset": 193,
-// CHECK-NEXT:          "col": 29,
-// CHECK-NEXT:          "tokLen": 4
-// CHECK-NEXT:        },
-// CHECK-NEXT:        "end": {
-// CHECK-NEXT:          "offset": 197,
-// CHECK-NEXT:          "col": 33,
-// CHECK-NEXT:          "tokLen": 1
-// CHECK-NEXT:        }
+// CHECK-NEXT:       "begin": {},
+// CHECK-NEXT:       "end": {}
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "isImplicit": true,
-// CHECK-NEXT:      "name": "auto:1",
 // CHECK-NEXT:      "tagUsed": "class",
 // CHECK-NEXT:      "depth": 0,
 // CHECK-NEXT:      "index": 0
@@ -608,24 +590,15 @@ struct DoesNotAllowConstDefaultInit {
 // CHECK-NEXT:      "id": "0x{{.*}}",
 // CHECK-NEXT:      "kind": "TemplateTypeParmDecl",
 // CHECK-NEXT:      "loc": {
-// CHECK-NEXT:        "offset": 197,
-// CHECK-NEXT:        "col": 33,
-// CHECK-NEXT:        "tokLen": 1
+// CHECK-NEXT:       "offset": 193,
+// CHECK-NEXT:       "col": 29,
+// CHECK-NEXT:       "tokLen": 4
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "range": {
-// CHECK-NEXT:        "begin": {
-// CHECK-NEXT:          "offset": 193,
-// CHECK-NEXT:          "col": 29,
-// CHECK-NEXT:          "tokLen": 4
-// CHECK-NEXT:        },
-// CHECK-NEXT:        "end": {
-// CHECK-NEXT:          "offset": 197,
-// CHECK-NEXT:          "col": 33,
-// CHECK-NEXT:          "tokLen": 1
-// CHECK-NEXT:        }
+// CHECK-NEXT:       "begin": {},
+// CHECK-NEXT:       "end": {}
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "isImplicit": true,
-// CHECK-NEXT:      "name": "auto:1",
 // CHECK-NEXT:      "tagUsed": "class",
 // CHECK-NEXT:      "depth": 0,
 // CHECK-NEXT:      "index": 0

diff  --git a/clang/test/CXX/dcl/dcl.fct/p17.cpp b/clang/test/CXX/dcl/dcl.fct/p17.cpp
deleted file mode 100644
index bf19e57e7964..000000000000
--- a/clang/test/CXX/dcl/dcl.fct/p17.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-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 type_list;
-
-namespace unconstrained {
-  decltype(auto) f1(auto x) { return x; }
-  static_assert(is_same_v<decltype(f1(1)), int>);
-  static_assert(is_same_v<decltype(f1('c')), char>);
-
-  decltype(auto) f2(auto &x) { return x; }
-  // expected-note at -1{{candidate function [with x:auto = int] not viable: expects an l-value for 1st argument}}
-  // expected-note at -2{{candidate function [with x:auto = char] not viable: expects an l-value for 1st argument}}
-  static_assert(is_same_v<decltype(f2(1)), int &>); // expected-error{{no matching}}
-  static_assert(is_same_v<decltype(f2('c')), char &>); // expected-error{{no matching}}
-
-  decltype(auto) f3(const auto &x) { return x; }
-  static_assert(is_same_v<decltype(f3(1)), const int &>);
-  static_assert(is_same_v<decltype(f3('c')), const char &>);
-
-  decltype(auto) f4(auto (*x)(auto y)) { return x; } // expected-error{{'auto' not allowed in function prototype}}
-
-  decltype(auto) f5(void (*x)(decltype(auto) y)) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}}
-
-  int return_int(); void return_void(); int foo(int);
-
-  decltype(auto) f6(auto (*x)()) { return x; }
-  // expected-note at -1{{candidate template ignored: failed template argument deduction}}
-  static_assert(is_same_v<decltype(f6(return_int)), int (*)()>);
-  static_assert(is_same_v<decltype(f6(return_void)), void (*)()>);
-  using f6c1 = decltype(f6(foo)); // expected-error{{no matching}}
-
-  decltype(auto) f7(auto (*x)() -> int) { return x; }
-  // expected-note at -1{{candidate function not viable: no known conversion from 'void ()' to 'auto (*)() -> int' for 1st argument}}
-  // expected-note at -2{{candidate function not viable: no known conversion from 'int (int)' to 'auto (*)() -> int' for 1st argument}}
-  static_assert(is_same_v<decltype(f7(return_int)), int (*)()>);
-  using f7c1 = decltype(f7(return_void)); // expected-error{{no matching}}
-  using f7c2 = decltype(f7(foo)); // expected-error{{no matching}}
-  static_assert(is_same_v<decltype(&f7), int (*(*)(int (*x)()))()>);
-
-  decltype(auto) f8(auto... x) { return (x + ...); }
-  static_assert(is_same_v<decltype(f8(1, 2, 3)), int>);
-  static_assert(is_same_v<decltype(f8('c', 'd')), int>);
-  static_assert(is_same_v<decltype(f8('c', 1)), int>);
-
-  decltype(auto) f9(auto &... x) { return (x, ...); }
-  // expected-note at -1{{candidate function [with x:auto = <int (), int>] not viable: expects an l-value for 2nd argument}}
-  using f9c1 = decltype(f9(return_int, 1)); // expected-error{{no matching}}
-
-  decltype(auto) f11(decltype(auto) x) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}}
-
-  template<typename T>
-  auto f12(auto x, T y) -> type_list<T, decltype(x)>;
-  static_assert(is_same_v<decltype(f12(1, 'c')), type_list<char, int>>);
-  static_assert(is_same_v<decltype(f12<char>(1, 'c')), type_list<char, int>>);
-
-  template<typename T>
-  auto f13(T x, auto y) -> type_list<T, decltype(y)>;
-  static_assert(is_same_v<decltype(f13(1, 'c')), type_list<int, char>>);
-  static_assert(is_same_v<decltype(f13<char>(1, 'c')), type_list<char, char>>);
-
-  template<typename T>
-  auto f14(auto y) -> type_list<T, decltype(y)>;
-  static_assert(is_same_v<decltype(f14<int>('c')), type_list<int, char>>);
-  static_assert(is_same_v<decltype(f14<int, char>('c')), type_list<int, char>>);
-
-  template<typename T, typename U>
-  auto f15(auto y, U u) -> type_list<T, U, decltype(y)>;
-  static_assert(is_same_v<decltype(f15<int>('c', nullptr)), type_list<int, decltype(nullptr), char>>);
-  static_assert(is_same_v<decltype(f15<int, decltype(nullptr)>('c', nullptr)), type_list<int, decltype(nullptr), char>>);
-
-  auto f16(auto x, auto y) -> type_list<decltype(x), decltype(y)>;
-  static_assert(is_same_v<decltype(f16('c', 1)), type_list<char, int>>);
-  static_assert(is_same_v<decltype(f16<int>('c', 1)), type_list<int, int>>);
-  static_assert(is_same_v<decltype(f16<int, char>('c', 1)), type_list<int, char>>);
-
-  void f17(auto x, auto y) requires (sizeof(x) > 1);
-  // expected-note at -1{{candidate template ignored: constraints not satisfied [with x:auto = char, y:auto = int]}}
-  // expected-note at -2{{because 'sizeof (x) > 1' (1 > 1) evaluated to false}}
-  static_assert(is_same_v<decltype(f17('c', 1)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f17<int>('c', 1)), void>);
-  static_assert(is_same_v<decltype(f17<int, char>('c', 1)), void>);
-
-  void f18(auto... x) requires (sizeof...(x) == 2);
-  // expected-note at -1{{candidate template ignored: constraints not satisfied [with x:auto = <char, int, int>]}}
-  // expected-note at -2{{candidate template ignored: constraints not satisfied [with x:auto = <char>]}}
-  // expected-note at -3{{because 'sizeof...(x) == 2' (1 == 2) evaluated to false}}
-  // expected-note at -4{{because 'sizeof...(x) == 2' (3 == 2) evaluated to false}}
-  static_assert(is_same_v<decltype(f18('c')), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f18('c', 1)), void>);
-  static_assert(is_same_v<decltype(f18('c', 1, 2)), void>);
-  // expected-error at -1{{no matching}}
-
-  template<typename T>
-  struct S {
-    constexpr auto f1(auto x, T t) -> decltype(x + t);
-
-    template<typename U>
-    constexpr auto f2(U u, auto x, T t) -> decltype(x + u + t);
-  };
-
-  template<typename T>
-  constexpr auto S<T>::f1(auto x, T t) -> decltype(x + t) { return x + t; }
-
-  template<typename T>
-  template<typename U>
-  constexpr auto S<T>::f2(auto x, U u, T t) -> decltype(x + u + t) { return x + u + t; }
-  // expected-error at -1 {{out-of-line definition of 'f2' does not match any declaration in 'S<T>'}}
-
-  template<typename T>
-  template<typename U>
-  constexpr auto S<T>::f2(U u, auto x, T t) -> decltype(x + u + t) { return x + u + t; }
-
-  template<>
-  template<>
-  constexpr auto S<int>::f2<double>(double u, char x, int t) -> double { return 42; }
-
-  static_assert(S<char>{}.f1(1, 2) == 3);
-  static_assert(S<char>{}.f2(1, 2, '\x00') == 3);
-  static_assert(S<char>{}.f2<double>(1, 2, '\x00') == 3.);
-  static_assert(S<int>{}.f2<double>(1, '2', '\x00') == 42);
-}
-
-namespace constrained {
-  template<typename T>
-  concept C = is_same_v<T, int>;
-  // expected-note at -1 12{{because}}
-  template<typename T, typename U>
-  concept C2 = is_same_v<T, U>;
-  // expected-note at -1 12{{because}}
-
-  int i;
-  const int ci = 1;
-  char c;
-  const char cc = 'a';
-  int g(int);
-  char h(int);
-
-  void f1(C auto x);
-  // expected-note at -1 {{candidate template ignored: constraints not satisfied [with x:auto = }}
-  // expected-note at -2{{because}}
-  static_assert(is_same_v<decltype(f1(1)), void>);
-  static_assert(is_same_v<decltype(f1('a')), void>);
-  // expected-error at -1{{no matching}}
-  void f2(C auto &x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f2(i)), void>);
-  static_assert(is_same_v<decltype(f2(ci)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f2(c)), void>);
-  // expected-error at -1{{no matching}}
-  void f3(const C auto &x);
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f3(i)), void>);
-  static_assert(is_same_v<decltype(f3(ci)), void>);
-  static_assert(is_same_v<decltype(f3(c)), void>);
-  // expected-error at -1{{no matching}}
-  void f4(C auto (*x)(C auto y)); // expected-error{{'auto' not allowed}}
-  void f5(C auto (*x)(int y));
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f5(g)), void>);
-  static_assert(is_same_v<decltype(f5(h)), void>);
-  // expected-error at -1{{no matching}}
-  void f6(C auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C auto'}}
-  void f7(C auto... x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f7(1, 2)), void>);
-  static_assert(is_same_v<decltype(f7(1, 'a')), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f7('a', 2)), void>);
-  // expected-error at -1{{no matching}}
-  void f8(C auto &... x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f8(i, i)), void>);
-  static_assert(is_same_v<decltype(f8(i, c)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f8(i, i, ci)), void>);
-  // expected-error at -1{{no matching}}
-  void f9(const C auto &... x);
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f9(i, i)), void>);
-  static_assert(is_same_v<decltype(f9(i, c)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f9(i, i, ci)), void>);
-  void f10(C decltype(auto) x);
-  auto f11 = [] (C auto x) { };
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f11(1)), void>);
-  static_assert(is_same_v<decltype(f11('a')), void>);
-  // expected-error at -1{{no matching}}
-
-  void f12(C2<char> auto x);
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f12(1)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f12('a')), void>);
-  void f13(C2<char> auto &x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f13(i)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f13(cc)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f13(c)), void>);
-  void f14(const C2<char> auto &x);
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f14(i)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f14(cc)), void>);
-  static_assert(is_same_v<decltype(f14(c)), void>);
-  void f15(C2<char> auto (*x)(C2<int> auto y)); // expected-error{{'auto' not allowed}}
-  void f16(C2<char> auto (*x)(int y));
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f16(g)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f16(h)), void>);
-  void f17(C2<char> auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C2<char> auto'}}
-  void f18(C2<char> auto... x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f18('a', 'b')), void>);
-  static_assert(is_same_v<decltype(f18('a', 1)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f18(2, 'a')), void>);
-  // expected-error at -1{{no matching}}
-  void f19(C2<char> auto &... x);
-  // expected-note at -1 2{{candidate template ignored}} expected-note at -1 2{{because}}
-  static_assert(is_same_v<decltype(f19(c, c)), void>);
-  static_assert(is_same_v<decltype(f19(i, c)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f19(c, c, cc)), void>);
-  // expected-error at -1{{no matching}}
-  void f20(const C2<char> auto &... x);
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f20(c, c)), void>);
-  static_assert(is_same_v<decltype(f20(i, c)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f20(c, c, cc)), void>);
-  void f21(C2<char> decltype(auto) x);
-  auto f22 = [] (C2<char> auto x) { };
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  static_assert(is_same_v<decltype(f22(1)), void>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(f22('a')), void>);
-
-  struct S1 { S1(C auto); };
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  // expected-note at -2 2{{candidate constructor}}
-  static_assert(is_same_v<decltype(S1(1)), S1>);
-  static_assert(is_same_v<decltype(S1('a')), S1>);
-  // expected-error at -1{{no matching}}
-  struct S2 { S2(C2<char> auto); };
-  // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
-  // expected-note at -2 2{{candidate constructor}}
-  static_assert(is_same_v<decltype(S2(1)), S2>);
-  // expected-error at -1{{no matching}}
-  static_assert(is_same_v<decltype(S2('a')), S2>);
-}

diff  --git a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
deleted file mode 100644
index a4e71d341cd7..000000000000
--- a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-
-template<typename T, unsigned size>
-concept LargerThan = sizeof(T) > size;
-// expected-note at -1 2{{because 'sizeof(char) > 1U' (1 > 1) evaluated to false}}
-// expected-note at -2 {{because 'sizeof(int) > 10U' (4 > 10) evaluated to false}}
-// expected-note at -3 {{because 'sizeof(int) > 4U' (4 > 4) evaluated to false}}
-
-template<typename T>
-concept Large = LargerThan<T, 1>;
-// expected-note at -1 2{{because 'LargerThan<char, 1>' evaluated to false}}
-
-namespace X {
-  template<typename T, unsigned size>
-  concept SmallerThan = sizeof(T) < size;
-  template<typename T>
-  concept Small = SmallerThan<T, 2>;
-}
-
-Large auto test1() { // expected-error{{deduced type 'char' does not satisfy 'Large'}}
-  Large auto i = 'a';
-  // expected-error at -1{{deduced type 'char' does not satisfy 'Large'}}
-  Large auto j = 10;
-  ::Large auto k = 10;
-  LargerThan<1> auto l = 10;
-  ::LargerThan<1> auto m = 10;
-  LargerThan<10> auto n = 10;
-  // expected-error at -1{{deduced type 'int' does not satisfy 'LargerThan<10>'}}
-  X::Small auto o = 'x';
-  X::SmallerThan<5> auto p = 1;
-  return 'a';
-}
-
-::Large auto test2() { return 10; }
-LargerThan<4> auto test3() { return 10; }
-// expected-error at -1{{deduced type 'int' does not satisfy 'LargerThan<4>'}}
-::LargerThan<2> auto test4() { return 10; }
-
-Large auto test5() -> void;
-// expected-error at -1{{function with trailing return type must specify return type 'auto', not 'Large auto'}}
-auto test6() -> Large auto { return 1; }
-
-X::Small auto test7() { return 'a'; }
-X::SmallerThan<5> auto test8() { return 10; }
\ No newline at end of file

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
index 0c0f820d1689..942280e1059f 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
@@ -1,7 +1,7 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
 
 auto l1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { return x; };
-// expected-note at -1{{candidate template ignored: constraints not satisfied [with x:auto = int]}}
+// expected-note at -1{{candidate template ignored: constraints not satisfied [with $0 = int]}}
 // expected-note at -2{{because 'sizeof(decltype(x)) == 1' (4 == 1) evaluated to false}}
 
 auto l1t1 = l1('a');
@@ -9,8 +9,8 @@ auto l1t2 = l1(1);
 // expected-error at -1{{no matching function for call to object of type '(lambda at}}
 
 auto l2 = [] (auto... x) requires ((sizeof(decltype(x)) >= 2) && ...) { return (x + ...); };
-// expected-note at -1{{candidate template ignored: constraints not satisfied [with x:auto = <char>]}}
-// expected-note at -2{{candidate template ignored: constraints not satisfied [with x:auto = <int, char>]}}
+// expected-note at -1{{candidate template ignored: constraints not satisfied [with $0 = <char>]}}
+// expected-note at -2{{candidate template ignored: constraints not satisfied [with $0 = <int, char>]}}
 // expected-note at -3 2{{because 'sizeof(decltype(x)) >= 2' (1 >= 2) evaluated to false}}
 
 auto l2t1 = l2('a');

diff  --git a/clang/test/CXX/temp/temp.param/p10-2a.cpp b/clang/test/CXX/temp/temp.param/p10-2a.cpp
index 3d2be1a92be1..de40f8cca5d5 100644
--- a/clang/test/CXX/temp/temp.param/p10-2a.cpp
+++ b/clang/test/CXX/temp/temp.param/p10-2a.cpp
@@ -94,8 +94,6 @@ concept OneOf = (is_same_v<T, Ts> || ...);
 // expected-note at -5 {{and 'is_same_v<short, char>' evaluated to false}}
 // expected-note at -6 3{{because 'is_same_v<int, char [1]>' evaluated to false}}
 // expected-note at -7 3{{and 'is_same_v<int, char [2]>' evaluated to false}}
-// expected-note at -8 2{{because 'is_same_v<nullptr_t, char>' evaluated to false}}
-// expected-note at -9 2{{and 'is_same_v<nullptr_t, int>' evaluated to false}}
 
 template<OneOf<char[1], char[2]> T, OneOf<int, long, char> U>
 // expected-note at -1 2{{because 'OneOf<char, char [1], char [2]>' evaluated to false}}
@@ -116,25 +114,4 @@ using h1 = H<char[1], int>;
 // expected-error at -1 {{constraints not satisfied for alias template 'H' [with Ts = <char [1], int>]}}
 using h2 = H<int, int>;
 // expected-error at -1 {{constraints not satisfied for alias template 'H' [with Ts = <int, int>]}}
-using h3 = H<char[1], char[2]>;
-
-template<OneOf<char, int> auto x>
-// expected-note at -1 {{because 'OneOf<decltype(nullptr), char, int>' evaluated to false}}
-using I = int;
-
-using i1 = I<1>;
-using i2 = I<'a'>;
-using i3 = I<nullptr>;
-// expected-error at -1 {{constraints not satisfied for alias template 'I' [with x = nullptr]}}
-
-template<OneOf<char, int> auto... x>
-// expected-note at -1 {{because 'OneOf<decltype(nullptr), char, int>' evaluated to false}}
-using J = int;
-
-using j1 = J<1, 'b'>;
-using j2 = J<'a', nullptr>;
-// expected-error at -1 {{constraints not satisfied for alias template 'J' [with x = <'a', nullptr>]}}
-
-template<OneOf<char, int> auto &x>
-// expected-error at -1 {{constrained placeholder types other than simple 'auto' on non-type template parameters not supported yet}}
-using K = int;
+using h3 = H<char[1], char[2]>;
\ No newline at end of file

diff  --git a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp b/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
deleted file mode 100644
index a1bd08827b93..000000000000
--- a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
-
-template<typename T, typename U=void>
-concept C = true;
-
-int foo() {
-  C auto a4 = 1;
-  C<> auto a5 = 1;
-  C<int> auto a6 = 1;
-  const C auto &a7 = 1;
-  const C<> auto &a8 = 1;
-  const C<int> auto &a9 = 1;
-  C decltype(auto) a10 = 1;
-  C<> decltype(auto) a11 = 1;
-  C<int> decltype(auto) a12 = 1;
-  const C<> decltype(auto) &a13 = 1; // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
-  // expected-error at -1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  const C<int> decltype(auto) &a14 = 1; // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
-  // expected-error at -1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  C a15 = 1;
-  // expected-error at -1{{expected 'auto' or 'decltype(auto)' after concept name}}
-  C decltype a19 = 1;
-  // expected-error at -1{{expected '('}}
-  C decltype(1) a20 = 1;
-  // expected-error at -1{{expected 'auto' or 'decltype(auto)' after concept name}}
-}
\ No newline at end of file

diff  --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 13ab7aae6c32..087982327c72 100644
--- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -181,7 +181,7 @@ int test() {
     int (*fp2)(int) = [](auto b) -> int {  return b; };
     int (*fp3)(char) = [](auto c) -> int { return c; };
     char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\
-                                                 //expected-note{{candidate function [with d:auto = int]}}
+                                                 //expected-note{{candidate function [with $0 = int]}}
     char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\
                                                  //expected-note{{candidate template ignored}}
 

diff  --git a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
index b2350c900e63..276464875342 100644
--- a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
+++ b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -93,8 +93,7 @@ namespace test_undeclared_nontype_parm_arg {
 // template parameter.
 template <typename T> struct Bar { T x; };
 
-template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
-// expected-note at -1{{template parameter is declared here}}
+template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}} expected-note {{declared here}}
 struct Foo { };
 
 typedef int Xylophone;


        


More information about the cfe-commits mailing list