diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index e750bb8b6af7..02296d8aea16 100755 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -488,7 +488,15 @@ static void ProfileTemplateParameterList(ASTContext &C, if (const auto *TTP = dyn_cast(D)) { ID.AddInteger(1); ID.AddBoolean(TTP->isParameterPack()); - // TODO: Concepts: profile type-constraints. + ID.AddBoolean(TTP->hasTypeConstraint()); + if (const TypeConstraint *TC = TTP->getTypeConstraint()) { + ID.AddPointer(TC->getNamedConcept()->getCanonicalDecl()); + ID.AddBoolean(TC->hasExplicitTemplateArgs()); + if (TC->hasExplicitTemplateArgs()) { + for (const auto &Arg : TC->getTemplateArgsAsWritten()->arguments()) + Arg.getArgument().Profile(ID, C); + } + } continue; } const auto *TTP = cast(D); diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp index 1ea4da29ee9f..9f3c21f99174 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp @@ -31,6 +31,23 @@ namespace class_templates // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}} // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}} // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}} + + template + concept same_as = is_same::value; + + template T> requires A::type + struct B {}; + // expected-note@-1{{previous}} + + template T> requires A::type + struct B {}; + // expected-error@-1{{redefinition}} + + template requires A::type + struct B {}; + + template T> requires A::type + struct B {}; } namespace variable_templates