[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-13 Thread Alexander Kornienko via cfe-commits

alexfh wrote:

Thanks! The fix resolves the crash, but the original code still doesn't 
compile. See 
https://github.com/llvm/llvm-project/pull/108491#issuecomment-2350634130

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-12 Thread Matheus Izvekov via cfe-commits

mizvekov wrote:

@alexfh Thanks, fixed in https://github.com/llvm/llvm-project/pull/108491

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-12 Thread Matheus Izvekov via cfe-commits

mizvekov wrote:

Thanks for the repro! I am taking a look.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-12 Thread Alexander Kornienko via cfe-commits

alexfh wrote:

Here's a reduced test case: https://gcc.godbolt.org/z/jxer3W39W

As usual, it's hard to say if the code got invalid during automatic reduction, 
but it at least compiles well with clang before this commit.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-12 Thread Alexander Kornienko via cfe-commits

alexfh wrote:

Hi @mizvekov, we started seeing crashes after this commit.

I'm working on a shareable test case, but here's the assertion failure and the 
stack trace:
```
assert.h assertion failed at llvm-project/clang/lib/AST/TemplateName.cpp:184 in 
TemplateDecl *clang::TemplateName::getAsTemplateDecl(bool) const: 
Name.getAsDeducedTemplateName
() == nullptr && "Unexpected canonical DeducedTemplateName; Did you mean to use 
" "getTemplateDeclAndDefaultArgs instead?"
@ 0x559dafb2e734  __assert_fail
@ 0x559dac2d2534  clang::TemplateName::getAsTemplateDecl()
@ 0x559dab8f5744  (anonymous 
namespace)::TemplateInstantiator::TransformTemplateName()
@ 0x559dab94e9a2  
clang::TreeTransform<>::TransformTemplateSpecializationType()
@ 0x559dab8e7f9f  clang::TreeTransform<>::TransformType()
@ 0x559dab94ad68  clang::TreeTransform<>::TransformElaboratedType()
@ 0x559dab8e80a5  clang::TreeTransform<>::TransformType()
@ 0x559dab8e7a0b  clang::TreeTransform<>::TransformType()
@ 0x559dab8e8790  clang::TreeTransform<>::TransformType()
@ 0x559dab8e8690  clang::Sema::SubstType()
@ 0x559dab6f4796  clang::Sema::CheckTemplateIdType()
@ 0x559dab94a6d1  
clang::TreeTransform<>::TransformDependentTemplateSpecializationType()
@ 0x559dab8e815f  clang::TreeTransform<>::TransformType()
@ 0x559dab8e8ebe  clang::Sema::SubstFunctionDeclType()
@ 0x559dab985787  clang::TemplateDeclInstantiator::SubstFunctionType()
@ 0x559dab98386d  clang::TemplateDeclInstantiator::VisitFunctionDecl()
@ 0x559dab9de2f3  llvm::function_ref<>::callback_fn<>()
@ 0x559daace13df  clang::Sema::runWithSufficientStackSpace()
@ 0x559dab98e1c8  clang::Sema::SubstDecl()
@ 0x559dab7d6bc1  clang::Sema::FinishTemplateArgumentDeduction()
@ 0x559dab866702  llvm::function_ref<>::callback_fn<>()
@ 0x559daace13df  clang::Sema::runWithSufficientStackSpace()
@ 0x559dab7da125  clang::Sema::DeduceTemplateArguments()
@ 0x559dab64655f  clang::Sema::AddTemplateOverloadCandidate()
@ 0x559dab65b2e4  AddOverloadedCallCandidate()
@ 0x559dab65b167  clang::Sema::AddOverloadedCallCandidates()
@ 0x559dab65b735  clang::Sema::buildOverloadedCallSet()
@ 0x559dab65bb92  clang::Sema::BuildOverloadedCallExpr()
@ 0x559dab13092c  clang::Sema::BuildCallExpr()
@ 0x559dab14af37  clang::Sema::ActOnCallExpr()
@ 0x559daa9f72b4  clang::Parser::ParsePostfixExpressionSuffix()
@ 0x559daa9f9078  clang::Parser::ParseCastExpression()
@ 0x559daa9f44b2  clang::Parser::ParseAssignmentExpression()
@ 0x559daaa4f9a0  
clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes()
@ 0x559daaa4cf26  clang::Parser::ParseDeclGroup()
@ 0x559daaa4b310  clang::Parser::ParseSimpleDeclaration()
@ 0x559daaa4aa30  clang::Parser::ParseDeclaration()
@ 0x559daaa96433  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9f8f3  clang::Parser::ParseCompoundStatementBody()
@ 0x559daaa94f57  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9b8c0  clang::Parser::ParseForStatement()
@ 0x559daaa94e07  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9f8f3  clang::Parser::ParseCompoundStatementBody()
@ 0x559daaa94f57  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9b8c0  clang::Parser::ParseForStatement()
@ 0x559daaa94e07  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9f8f3  clang::Parser::ParseCompoundStatementBody()
@ 0x559daaa94f57  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9b8c0  clang::Parser::ParseForStatement()
@ 0x559daaa94e07  
clang::Parser::ParseStatementOrDeclarationAfterAttributes()
@ 0x559daaa9428e  clang::Parser::ParseStatementOrDeclaration()
@ 0x559daaa9f8f3  clang::Parser::ParseCompoundStatementBody()
@ 0x559d0c70  clang::Parser::ParseFunctionStatementBody()
@ 0x559daa9d361c  clang::Parser::ParseFunctionDefinition()
@ 0x559daaa4d89b  clang::Parser::ParseDeclGroup()
@ 0x559daa9d1ea8  clang::Parser::ParseDeclOrFunctionDefInternal()
@ 0x559daa9d13d2  clang::Parser::ParseDeclarationOrFunctionDefinition()
@ 0x559daa9d0106  clang::Parser::ParseExternalDeclaration()
@ 0x559daaa1fba7  clang::Parser::Par

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov closed 
https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread Matheus Izvekov via cfe-commits


@@ -6753,16 +6758,41 @@ ASTContext::getNameForTemplate(TemplateName Name,
   case TemplateName::UsingTemplate:
 return DeclarationNameInfo(Name.getAsUsingShadowDecl()->getDeclName(),
NameLoc);
+  case TemplateName::DeducedTemplate: {
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+return getNameForTemplate(DTS->getUnderlying(), NameLoc);
+  }
   }
 
   llvm_unreachable("bad template name kind!");
 }
 
-TemplateName
-ASTContext::getCanonicalTemplateName(const TemplateName &Name) const {
+static const TemplateArgument *
+getDefaultTemplateArgumentOrNone(const NamedDecl *P) {
+  auto handleParam = [](auto *TP) -> const TemplateArgument * {
+if (!TP->hasDefaultArgument())
+  return nullptr;
+return &TP->getDefaultArgument().getArgument();
+  };
+  switch (P->getKind()) {
+  case NamedDecl::TemplateTypeParm:
+return handleParam(cast(P));
+  case NamedDecl::NonTypeTemplateParm:
+return handleParam(cast(P));
+  case NamedDecl::TemplateTemplateParm:
+return handleParam(cast(P));
+  default:
+llvm_unreachable("Unexpected template parameter kind");
+  }
+}

mizvekov wrote:

We'd have to break TypeDecl, DeclaratorDecl, TemplateDecl, etc into mixins.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits


@@ -645,6 +645,9 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  // It is sufficient to check value of getAsTemplateDecl.
  break;
 
+   case TemplateName::DeducedTemplate:
+ // FIXME: We can't reach here.
+ llvm_unreachable("unimplemented");

cor3ntin wrote:

Hum, fair enough. It's hard to me to understand how we could ever get there 
though

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits


@@ -2304,6 +2306,15 @@ class ASTContext : public RefCountedBase {
 unsigned Index,
 bool Final) const;
 
+  /// Represents a TemplateName which had some of it's default arguments

cor3ntin wrote:

```suggestion
  /// Represents a TemplateName which had some of its default arguments
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits

https://github.com/cor3ntin edited 
https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits


@@ -6753,16 +6758,41 @@ ASTContext::getNameForTemplate(TemplateName Name,
   case TemplateName::UsingTemplate:
 return DeclarationNameInfo(Name.getAsUsingShadowDecl()->getDeclName(),
NameLoc);
+  case TemplateName::DeducedTemplate: {
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+return getNameForTemplate(DTS->getUnderlying(), NameLoc);
+  }
   }
 
   llvm_unreachable("bad template name kind!");
 }
 
-TemplateName
-ASTContext::getCanonicalTemplateName(const TemplateName &Name) const {
+static const TemplateArgument *
+getDefaultTemplateArgumentOrNone(const NamedDecl *P) {
+  auto handleParam = [](auto *TP) -> const TemplateArgument * {
+if (!TP->hasDefaultArgument())
+  return nullptr;
+return &TP->getDefaultArgument().getArgument();
+  };
+  switch (P->getKind()) {
+  case NamedDecl::TemplateTypeParm:
+return handleParam(cast(P));
+  case NamedDecl::NonTypeTemplateParm:
+return handleParam(cast(P));
+  case NamedDecl::TemplateTemplateParm:
+return handleParam(cast(P));
+  default:
+llvm_unreachable("Unexpected template parameter kind");
+  }
+}

cor3ntin wrote:

Not in this PR, but i wonder if we should have a base class for all these types

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

Only nits at this point.
Sorry the review took this long, it was a pretty large PR.
Thanks for working on it!

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-07 Thread via cfe-commits


@@ -1555,6 +1499,11 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
   return TemplateDeductionResult::Success;
 }
 
+static PartialOrderingKind
+degradeCallPartialOrderingKind(PartialOrderingKind POK) {
+  return std::min(POK, PartialOrderingKind::NonCall);
+}
+

cor3ntin wrote:

Can we get a comment here?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -6803,9 +6809,6 @@ bool CXXNameMangler::mangleSubstitution(QualType T) {
 }
 
 bool CXXNameMangler::mangleSubstitution(TemplateName Template) {
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-return mangleSubstitution(TD);
-

mizvekov wrote:

This one looks like it was a rebasing mistake. Restored.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -2143,15 +2107,17 @@ static TemplateDeductionResult 
DeduceTemplateArgumentsByTypeMatch(
   unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
   if (auto Result = DeduceTemplateArgumentsByTypeMatch(
   S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
-  /*PartialOrdering=*/false, /*DeducedFromArrayBound=*/false,
-  HasDeducedAnyParam);
+  POK != PartialOrderingKind::None ? PartialOrderingKind::NonCall

mizvekov wrote:

Yes, this is slightly complicated because I tried to do an enum instead of 
adding another bool.

Basically we want to add a new flag to the deduction functions saying that we 
are in a partial ordering context, which needs to be propagated deeply.

We already had one such flag, but this one was for supporting deduction of 
function calls, and it had shallow propagation. So this is the transfer 
function for the shallow Call Partial ordering mode into the deep non-call mode.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -139,28 +165,63 @@ TemplateName::NameKind TemplateName::getKind() const {
 return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
 return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
-TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast()) {
-if (UsingShadowDecl *USD = dyn_cast(TemplateOrUsing))
-  return cast(USD->getTargetDecl());
-
-assert(isa(TemplateOrUsing));
-return cast(TemplateOrUsing);
-  }
+TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const {

mizvekov wrote:

I am not sure which part you were talking about, but a DeducedTemplateName is 
sugar when it appears in the TemplateName of a TemplateSpecializationType, so 
we need this new logic here.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -5327,9 +5332,29 @@ bool Sema::CheckTemplateArgumentList(
   SmallVector CanonicalArgumentPack;
   unsigned ArgIdx = 0, NumArgs = NewArgs.size();
   LocalInstantiationScope InstScope(*this, true);
-  for (TemplateParameterList::iterator Param = Params->begin(),
-   ParamEnd = Params->end();
-   Param != ParamEnd; /* increment in loop */) {
+  for (TemplateParameterList::iterator ParamBegin = Params->begin(),
+   ParamEnd = Params->end(),
+   Param = ParamBegin;
+   Param != ParamEnd;
+   /* increment in loop */) {
+if (size_t ParamIdx = Param - ParamBegin;
+DefaultArgs && ParamIdx >= DefaultArgs.StartPos) {
+  // All written arguments should have been consumed by this point.
+  assert(ArgIdx == NumArgs && "bad default argument deduction");
+  // FIXME: Don't ignore parameter packs.

mizvekov wrote:

This is already tested and tackled in the next patch in the series, the P0522 
complete implementation one.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -1198,6 +1198,18 @@ void TextNodeDumper::dumpBareTemplateName(TemplateName 
TN) {
 dumpTemplateName(STS->getReplacement(), "replacement");
 return;
   }
+  case TemplateName::DeducedTemplate: {
+OS << " deduced";
+const DeducedTemplateStorage *DTS = TN.getAsDeducedTemplateName();
+dumpTemplateName(DTS->getUnderlying(), "underlying");
+AddChild("defaults", [=] {
+  auto [StartPos, Args] = DTS->getDefaultArguments();
+  OS << " start " << StartPos;
+  for (const TemplateArgument &Arg : Args)
+AddChild([=] { Visit(Arg, SourceRange()); });
+});
+return;
+  }

mizvekov wrote:

Yeah, this could be tested in ast-dump tests before we restricted this to 
partial ordering. Now it only helps in debugging there.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -139,28 +165,63 @@ TemplateName::NameKind TemplateName::getKind() const {
 return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
 return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
-TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast()) {
-if (UsingShadowDecl *USD = dyn_cast(TemplateOrUsing))
-  return cast(USD->getTargetDecl());
-
-assert(isa(TemplateOrUsing));
-return cast(TemplateOrUsing);
-  }
+TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const {
+  TemplateName Name = *this;
+  while (std::optional UnderlyingOrNone =
+ Name.desugar(IgnoreDeduced))
+Name = *UnderlyingOrNone;
 
-  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
-return QTN->getUnderlyingTemplate().getAsTemplateDecl();
+  if (!IgnoreDeduced)
+assert(Name.getAsDeducedTemplateName() == nullptr &&
+   "Unexpected canonical DeducedTemplateName; Did you mean to use "
+   "getTemplateDeclAndDefaultArgs instead?");
 
-  if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
-return sub->getReplacement().getAsTemplateDecl();
+  return cast_if_present(Name.Storage.dyn_cast());
+}
 
-  if (UsingShadowDecl *USD = getAsUsingShadowDecl())
-return cast(USD->getTargetDecl());
+std::pair
+TemplateName::getTemplateDeclAndDefaultArgs() const {
+  for (TemplateName Name = *this; /**/; /**/) {
+if (Name.getKind() == TemplateName::DeducedTemplate) {
+  DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+  TemplateDecl *TD =
+  DTS->getUnderlying().getAsTemplateDecl(/*IgnoreDeduced=*/true);
+  DefaultArguments DefArgs = DTS->getDefaultArguments();
+  if (TD && DefArgs)
+assert(DefArgs.StartPos + DefArgs.Args.size() <=
+   TD->getTemplateParameters()->size());
+  return {TD, DTS->getDefaultArguments()};
+}
+if (std::optional UnderlyingOrNone =
+Name.desugar(/*IgnoreDeduced=*/false)) {
+  Name = *UnderlyingOrNone;
+  continue;
+}
+return {cast_if_present(Name.Storage.dyn_cast()), 
{}};
+  }
+}
 
-  return nullptr;
+std::optional TemplateName::desugar(bool IgnoreDeduced) const {

mizvekov wrote:

They were not fully fledged implemented like the other kinds of AST nodes. 
Their canonicalization plays by different rules, and this patch expands on that.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -326,6 +320,48 @@ namespace classes {
   // expected-error@-1 {{no matching function for call}}
 }
   } // namespace packs
+  namespace nested {

mizvekov wrote:

The test case from 100692 doesn't have anything interesting new on top of this 
one. There might be differences in the kinds of template arguments which have 
default deductions, but we already test all kinds when matching TTP to  TTP, so 
I am not sure it would be worth doing a power set where we test every 
combination of matching with every kind.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -1371,11 +1371,17 @@ class TemplateDiff {
   /// argument info into a tree.
   void DiffTemplate(const TemplateSpecializationType *FromTST,
 const TemplateSpecializationType *ToTST) {
+// FIXME: With P3310R0, A TST formed from a DeducedTemplateName might
+// differ in template arguments which were not written.

mizvekov wrote:

It's still possible these types might appear in diagnostics, even if they don't 
make it to the final program.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -645,6 +645,9 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  // It is sufficient to check value of getAsTemplateDecl.
  break;
 
+   case TemplateName::DeducedTemplate:
+ // FIXME: We can't reach here.
+ llvm_unreachable("unimplemented");

mizvekov wrote:

Well it's both, ideally we should implement this, but we don't implement other 
stuff that would even allow us to reach here.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -412,6 +445,30 @@ class SubstTemplateTemplateParmStorage
   std::optional PackIndex);
 };
 
+class DeducedTemplateStorage : public UncommonTemplateNameStorage,

mizvekov wrote:

This one is a too internal detail of how the different kinds of TemplateNames 
are implemented. Ie if we can't fit everything we need in one pointer, then we 
allocate separate storage for it.
Might be more useful to document the DeducedTemplate itself.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Matheus Izvekov via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

mizvekov wrote:

The problem with the separate Sugared / Converted lists I already have an 
incomplete patch to address that, though  I am currently working on something 
else.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread Erich Keane via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

erichkeane wrote:

There's enough repeated stuff though these interfaces here, I don't think I'd 
mind a followup that created an object to contain all the related stuff.  For 
example, the Sugared/Canonical vectors shoudl probably be a vectro of 
TempalteArgument pairs (or more likely their own structure) or something?  But 
I'm open to other ideas as well (agian in a followup).

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -139,28 +165,63 @@ TemplateName::NameKind TemplateName::getKind() const {
 return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
 return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
-TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast()) {
-if (UsingShadowDecl *USD = dyn_cast(TemplateOrUsing))
-  return cast(USD->getTargetDecl());
-
-assert(isa(TemplateOrUsing));
-return cast(TemplateOrUsing);
-  }
+TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const {

cor3ntin wrote:

That change looks sort of unrelated?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -139,28 +165,63 @@ TemplateName::NameKind TemplateName::getKind() const {
 return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
 return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
-TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast()) {
-if (UsingShadowDecl *USD = dyn_cast(TemplateOrUsing))
-  return cast(USD->getTargetDecl());
-
-assert(isa(TemplateOrUsing));
-return cast(TemplateOrUsing);
-  }
+TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const {
+  TemplateName Name = *this;
+  while (std::optional UnderlyingOrNone =
+ Name.desugar(IgnoreDeduced))
+Name = *UnderlyingOrNone;
 
-  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
-return QTN->getUnderlyingTemplate().getAsTemplateDecl();
+  if (!IgnoreDeduced)
+assert(Name.getAsDeducedTemplateName() == nullptr &&
+   "Unexpected canonical DeducedTemplateName; Did you mean to use "
+   "getTemplateDeclAndDefaultArgs instead?");
 
-  if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
-return sub->getReplacement().getAsTemplateDecl();
+  return cast_if_present(Name.Storage.dyn_cast());
+}
 
-  if (UsingShadowDecl *USD = getAsUsingShadowDecl())
-return cast(USD->getTargetDecl());
+std::pair
+TemplateName::getTemplateDeclAndDefaultArgs() const {
+  for (TemplateName Name = *this; /**/; /**/) {
+if (Name.getKind() == TemplateName::DeducedTemplate) {
+  DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+  TemplateDecl *TD =
+  DTS->getUnderlying().getAsTemplateDecl(/*IgnoreDeduced=*/true);
+  DefaultArguments DefArgs = DTS->getDefaultArguments();
+  if (TD && DefArgs)
+assert(DefArgs.StartPos + DefArgs.Args.size() <=
+   TD->getTemplateParameters()->size());
+  return {TD, DTS->getDefaultArguments()};
+}
+if (std::optional UnderlyingOrNone =
+Name.desugar(/*IgnoreDeduced=*/false)) {
+  Name = *UnderlyingOrNone;
+  continue;
+}
+return {cast_if_present(Name.Storage.dyn_cast()), 
{}};
+  }
+}
 
-  return nullptr;
+std::optional TemplateName::desugar(bool IgnoreDeduced) const {

cor3ntin wrote:

I am surprise that we don't have something to desugar template names already?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -645,6 +645,9 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  // It is sufficient to check value of getAsTemplateDecl.
  break;
 
+   case TemplateName::DeducedTemplate:
+ // FIXME: We can't reach here.
+ llvm_unreachable("unimplemented");

cor3ntin wrote:

is it unreachable or just unimplemented?
If deduced arguments are only used during partial ordering they should never 
need to be compared for structural equivalence... maybe. I am not actually 
sure, but the fix me and the strings should agree with each other!

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -134,11 +134,16 @@ static bool hasSameExtendedValue(llvm::APSInt X, 
llvm::APSInt Y) {
   return X == Y;
 }
 
+/// What kind of PartialOrdering we're performing template argument deduction

cor3ntin wrote:

```suggestion
/// The kind of PartialOrdering we're performing template argument deduction
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -1371,11 +1371,17 @@ class TemplateDiff {
   /// argument info into a tree.
   void DiffTemplate(const TemplateSpecializationType *FromTST,
 const TemplateSpecializationType *ToTST) {
+// FIXME: With P3310R0, A TST formed from a DeducedTemplateName might
+// differ in template arguments which were not written.

cor3ntin wrote:

I am not sure we need that fixme now

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -134,11 +134,16 @@ static bool hasSameExtendedValue(llvm::APSInt X, 
llvm::APSInt Y) {
   return X == Y;
 }
 
+/// What kind of PartialOrdering we're performing template argument deduction
+/// for (C++0x [temp.deduct.partial]).

cor3ntin wrote:

```suggestion
/// for (C++11 [temp.deduct.partial]).
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -6803,9 +6809,6 @@ bool CXXNameMangler::mangleSubstitution(QualType T) {
 }
 
 bool CXXNameMangler::mangleSubstitution(TemplateName Template) {
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-return mangleSubstitution(TD);
-

cor3ntin wrote:

Can you explain that change?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

cor3ntin wrote:

Can we think about ways to simplify these interface in a subsequent patch?
@AaronBallman @erichkeane for additional opinions

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -5327,9 +5332,29 @@ bool Sema::CheckTemplateArgumentList(
   SmallVector CanonicalArgumentPack;
   unsigned ArgIdx = 0, NumArgs = NewArgs.size();
   LocalInstantiationScope InstScope(*this, true);
-  for (TemplateParameterList::iterator Param = Params->begin(),
-   ParamEnd = Params->end();
-   Param != ParamEnd; /* increment in loop */) {
+  for (TemplateParameterList::iterator ParamBegin = Params->begin(),
+   ParamEnd = Params->end(),
+   Param = ParamBegin;
+   Param != ParamEnd;
+   /* increment in loop */) {
+if (size_t ParamIdx = Param - ParamBegin;
+DefaultArgs && ParamIdx >= DefaultArgs.StartPos) {
+  // All written arguments should have been consumed by this point.
+  assert(ArgIdx == NumArgs && "bad default argument deduction");
+  // FIXME: Don't ignore parameter packs.

cor3ntin wrote:

Do we need a test/issue?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -326,6 +320,48 @@ namespace classes {
   // expected-error@-1 {{no matching function for call}}
 }
   } // namespace packs
+  namespace nested {

cor3ntin wrote:

Do we need more tests?
Maybe add the example from #100692 ?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -6797,15 +6821,58 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+bool NonCanonical = CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+
+ArrayRef Params =
+
CanonUnderlying.getAsTemplateDecl()->getTemplateParameters()->asArray();
+assert(CanonArgs.size() <= Params.size());
+// A deduced template name which deduces the same default arguments already
+// declared in the underlying template, is the same template as the

cor3ntin wrote:

```suggestion
// declared in the underlying template is the same template as the
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -6797,15 +6821,58 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+bool NonCanonical = CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+
+ArrayRef Params =
+
CanonUnderlying.getAsTemplateDecl()->getTemplateParameters()->asArray();
+assert(CanonArgs.size() <= Params.size());
+// A deduced template name which deduces the same default arguments already
+// declared in the underlying template, is the same template as the
+// underlying template. We need need to note any arguments which differ 
from
+// the corresponding declaration. If they are not the same, we must build a
+// deduced template name.

cor3ntin wrote:

```suggestion
// underlying template. We need need to note any arguments which differ from
// the corresponding declaration. If any argument differ, we build a
// deduced template name.
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -2143,15 +2107,17 @@ static TemplateDeductionResult 
DeduceTemplateArgumentsByTypeMatch(
   unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
   if (auto Result = DeduceTemplateArgumentsByTypeMatch(
   S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
-  /*PartialOrdering=*/false, /*DeducedFromArrayBound=*/false,
-  HasDeducedAnyParam);
+  POK != PartialOrderingKind::None ? PartialOrderingKind::NonCall

cor3ntin wrote:

Can you explain that logic?
And you do it in a whole bunch of places, how putting it a 
getPartialOrderingKindForTypeMatch() function,
or modifying DeduceTemplateArgumentsByTypeMatch to do that transformation there?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -1198,6 +1198,18 @@ void TextNodeDumper::dumpBareTemplateName(TemplateName 
TN) {
 dumpTemplateName(STS->getReplacement(), "replacement");
 return;
   }
+  case TemplateName::DeducedTemplate: {
+OS << " deduced";
+const DeducedTemplateStorage *DTS = TN.getAsDeducedTemplateName();
+dumpTemplateName(DTS->getUnderlying(), "underlying");
+AddChild("defaults", [=] {
+  auto [StartPos, Args] = DTS->getDefaultArguments();
+  OS << " start " << StartPos;
+  for (const TemplateArgument &Arg : Args)
+AddChild([=] { Visit(Arg, SourceRange()); });
+});
+return;
+  }

cor3ntin wrote:

When would these things be printed? I guess if you call dump() while debugging 
partial ordering?
Do we need a test?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-05 Thread via cfe-commits


@@ -412,6 +445,30 @@ class SubstTemplateTemplateParmStorage
   std::optional PackIndex);
 };
 
+class DeducedTemplateStorage : public UncommonTemplateNameStorage,

cor3ntin wrote:

I think a comment describing when this is useful would be beneficial 

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-09-04 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

I've not done as in depth of a review as Corentin, but I approve of the 
direction here, I think the approach is correct, and most of the changes are 
fairly mechanical.  So once Corentin is happy with the changes, so am I.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-08-28 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov edited 
https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-19 Thread Vlad Serebrennikov via cfe-commits




Endilll wrote:

Sure.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-19 Thread Matheus Izvekov via cfe-commits




mizvekov wrote:

After we fork for clang-20, we can entirely remove 
`frelaxed-template-template-args`, and so won't need to worry about testing 
that non-conforming mode. Would it be reasonable to postpone that until then?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-19 Thread Vlad Serebrennikov via cfe-commits




Endilll wrote:

Now that you published P3310R0, this test can be moved to DR tests with a 
status `// cwg2398: 19 drafting P3310R0`.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-18 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From b238961ba3a174d7dc211caf36ff8fd6c8429a76 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |  11 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  63 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 153 +---
 clang/lib/AST/ASTDiagnostic.cpp   |  45 +++--
 clang/lib/AST/ASTImporter.cpp |  15 ++
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/Decl.cpp|   3 +-
 clang/lib/AST/ItaniumMangle.cpp   |  20 ++-
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 163 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/AST/TypePrinter.cpp |   3 +-
 clang/lib/Sema/SemaDeclCXX.cpp|   9 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 158 +
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  62 +--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 28 files changed, 629 insertions(+), 257 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index de86cb5e9d7fc..837bcacbc0bfc 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   Arr

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-13 Thread Matheus Izvekov via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

mizvekov wrote:

Yeah. One issue I have often had with these functions with large amount of both 
defaulted and non-defaulted parameters, is that you would want to extend it by 
changing the signature, then arguments would match parameters incorrectly, but 
this would not cause a hard error on all of the call sites.

I could have easily added DefaultArgs as defaulted empty here, but chose not to 
due to this reason.

Besides that, overloading functions with such huge numbers of parameters 
creates some confusion as well.
I'd slightly prefer if we avoided that, but don't have strong enough feelings 
to go on a crusade against it.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-13 Thread via cfe-commits

https://github.com/cor3ntin edited 
https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-13 Thread via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

cor3ntin wrote:

```cpp

bool CheckTemplateArgumentList(
  TemplateDecl *Template, SourceLocation TemplateLoc,
  TemplateArgumentListInfo &TemplateArgs,
  bool PartialTemplateArgs,
  SmallVectorImpl &SugaredConverted,
  SmallVectorImpl &CanonicalConverted,
  bool UpdateArgsWithConversions = true,
  bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false, 
const DefaultArguments * DefaultArgs = nullptr);


bool CheckTemplateArgumentList(
  TemplateDecl *Template, SourceLocation TemplateLoc,
  TemplateArgumentListInfo &TemplateArgs,
  const DefaultArguments & DefaultArgs, 
  SmallVectorImpl &SugaredConverted,
  SmallVectorImpl &CanonicalConverted) {

return CheckTemplateArgumentList(Template, TemplateLoc, 
/*PartialTemplateArgs=*/false,
  
SugaredConverted, CanonicalConverted, /*UpdateArgsWithConversions=*/true, 
nullptr, false, &DefaultArgs); 
 
}
```

Maybe something like that?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-13 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

`Sema.h` changes look good.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits

mizvekov wrote:

FYI https://github.com/itanium-cxx-abi/cxx-abi/issues/184 is the tracking issue 
for the mangling rules we need here.
We will probably end up with something quite different than what I coded here 
so far.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

mizvekov wrote:

I am not seeing a worthwhile tradeoff.

Just the function signature is hugely complicated, and would need to be 
duplicated.
The implementation would be mostly the same, with a small block which would be 
omitted in one of the implementations.

What did you have in mind?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits


@@ -9434,6 +9505,32 @@ ASTContext::getSubstTemplateTemplateParmPack(const 
TemplateArgument &ArgPack,
   return TemplateName(Subst);
 }
 
+/// Retrieve the template name that represents a template name
+/// deduced from a specialization.
+TemplateName
+ASTContext::getDeducedTemplateName(TemplateName Underlying,
+   DefaultArguments DefaultArgs) const {
+  if (!DefaultArgs)
+return Underlying;
+
+  auto &Self = const_cast(*this);

mizvekov wrote:

Actually in this case the relevant hash tables were already declared mutable, 
but there were a couple of profile functions not marked const. Fixed.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From f05e8590c7fae599d0658829949fa907942e83f2 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |  11 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  63 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 153 +---
 clang/lib/AST/ASTDiagnostic.cpp   |  45 +++--
 clang/lib/AST/ASTImporter.cpp |  15 ++
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/Decl.cpp|   3 +-
 clang/lib/AST/ItaniumMangle.cpp   |  20 ++-
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 163 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/AST/TypePrinter.cpp |   3 +-
 clang/lib/Sema/SemaDeclCXX.cpp|   9 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 158 +
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  62 +--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 28 files changed, 629 insertions(+), 257 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index f1f20fca477a4..c9376dc02fcfc 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   Arr

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits


@@ -9434,6 +9505,32 @@ ASTContext::getSubstTemplateTemplateParmPack(const 
TemplateArgument &ArgPack,
   return TemplateName(Subst);
 }
 
+/// Retrieve the template name that represents a template name
+/// deduced from a specialization.
+TemplateName
+ASTContext::getDeducedTemplateName(TemplateName Underlying,
+   DefaultArguments DefaultArgs) const {
+  if (!DefaultArgs)
+return Underlying;
+
+  auto &Self = const_cast(*this);

mizvekov wrote:

This is done throughout the ASTContext and is not novel here.

We wish to be able to create a new node from a const ASTContext reference.

These creation functions mostly behave const-ish, they just use hash tables in 
the ASTContext for caching / identity purposes.

The other alternative is to declare these hash tables as mutable, though this 
would necessitate a large noisy change to update everything at once.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+NonCanonical |= CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+{
+  unsigned NumArgs = CanonArgs.size() - 1;
+  auto handleParamDefArg = [&](const TemplateArgument &ParamDefArg,
+   unsigned I) {
+auto CanonParamDefArg = getCanonicalTemplateArgument(ParamDefArg);
+TemplateArgument &CanonDefArg = CanonArgs[I];
+if (CanonDefArg.structurallyEquals(CanonParamDefArg))
+  return;
+if (I == NumArgs)
+  CanonArgs.pop_back();
+NonCanonical = true;
+  };
+  auto handleParam = [&](auto *TP, int I) -> bool {
+if (!TP->hasDefaultArgument())
+  return true;
+handleParamDefArg(TP->getDefaultArgument().getArgument(), I);
+return false;
+  };
+
+  ArrayRef Params = CanonUnderlying.getAsTemplateDecl()
+ ->getTemplateParameters()
+ ->asArray();
+  assert(CanonArgs.size() <= Params.size());
+  for (int I = NumArgs; I >= 0; --I) {

mizvekov wrote:

The code is correct, but the variable name is not right. Should have been 
`LastArgIndex` or some such.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread Matheus Izvekov via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();

mizvekov wrote:

They are pointer sized, it's the same as a QualType, and we never take those by 
reference either.

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+NonCanonical |= CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+{
+  unsigned NumArgs = CanonArgs.size() - 1;
+  auto handleParamDefArg = [&](const TemplateArgument &ParamDefArg,
+   unsigned I) {
+auto CanonParamDefArg = getCanonicalTemplateArgument(ParamDefArg);
+TemplateArgument &CanonDefArg = CanonArgs[I];
+if (CanonDefArg.structurallyEquals(CanonParamDefArg))
+  return;
+if (I == NumArgs)
+  CanonArgs.pop_back();
+NonCanonical = true;

cor3ntin wrote:

I think this lambdas needs a comment, I'm not sure I understand what's 
happening here

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -9434,6 +9505,32 @@ ASTContext::getSubstTemplateTemplateParmPack(const 
TemplateArgument &ArgPack,
   return TemplateName(Subst);
 }
 
+/// Retrieve the template name that represents a template name
+/// deduced from a specialization.
+TemplateName
+ASTContext::getDeducedTemplateName(TemplateName Underlying,
+   DefaultArguments DefaultArgs) const {
+  if (!DefaultArgs)
+return Underlying;
+
+  auto &Self = const_cast(*this);

cor3ntin wrote:

Why do you need the const_cast?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -172,6 +180,13 @@ class SubstTemplateTemplateParmPackStorage : public 
UncommonTemplateNameStorage,
   unsigned Index, bool Final);
 };
 
+struct DefaultArguments {
+  unsigned StartPos;

cor3ntin wrote:

Can we add a comment here?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -139,28 +165,61 @@ TemplateName::NameKind TemplateName::getKind() const {
 return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
 return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast()) {
-if (UsingShadowDecl *USD = dyn_cast(TemplateOrUsing))
-  return cast(USD->getTargetDecl());
+  TemplateName Name = *this;
+  while (std::optional UnderlyingOrNone =
+ Name.desugar(/*IgnoreDeduced=*/false))
+Name = *UnderlyingOrNone;
 
-assert(isa(TemplateOrUsing));
+  if (Decl *TemplateOrUsing = Name.Storage.dyn_cast())
 return cast(TemplateOrUsing);
+  return nullptr;
+}
+
+std::pair
+TemplateName::getTemplateDeclAndDefaultArgs() const {
+  DefaultArguments DefArgs;
+  for (TemplateName Name = *this; /**/; /**/) {
+if (!DefArgs && Name.getKind() == TemplateName::DeducedTemplate) {
+  DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+  Name = DTS->getUnderlying();
+  DefArgs = DTS->getDefaultArguments();
+  continue;
+}
+if (std::optional UnderlyingOrNone =
+Name.desugar(/*IgnoreDeduced=*/DefArgs)) {
+  Name = *UnderlyingOrNone;
+  continue;
+}
+TemplateDecl *TD = Name.getAsTemplateDecl();
+if (TD && DefArgs != 0)
+  assert(DefArgs.StartPos + DefArgs.Args.size() <=
+ TD->getTemplateParameters()->size());
+return {TD, DefArgs};
   }
+}

cor3ntin wrote:

This is too clever.

I'd do

```cpp
static std::pair
getTemplateDeclAndDefaultArgs(const TemplateName N&,  DefaultArguments Args) {
if(...) {
return getTemplateDeclAndDefaultArgs(DTS->getUnderlying(), 
DTS->getDefaultArguments()) ;
}
   // ...
}

std::pair
TemplateName::getTemplateDeclAndDefaultArgs() const {
return getTemplateDeclAndDefaultArgs(*this, {});
}

```





https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();

cor3ntin wrote:

These could be reference. they are small-ish, but no need to copy

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+NonCanonical |= CanonUnderlying != Underlying;

cor3ntin wrote:

```suggestion
bool NonCanonical = CanonUnderlying != Underlying;
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -9219,7 +9222,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(
   TemplateDecl *Template, SourceLocation TemplateLoc,
-  TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+  TemplateArgumentListInfo &TemplateArgs,

cor3ntin wrote:

I wonder if instead we want to add an additional method.
In a lot of places through the rest of the patch, `DefaultArgs` is defaulted

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;

cor3ntin wrote:

```suggestion
```

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits

https://github.com/cor3ntin commented:

Thanks for this!
I still need time to fully understand the work this but i left a few comment in 
the meantime.
Overall it seems like a good approach

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+NonCanonical |= CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+{
+  unsigned NumArgs = CanonArgs.size() - 1;
+  auto handleParamDefArg = [&](const TemplateArgument &ParamDefArg,
+   unsigned I) {
+auto CanonParamDefArg = getCanonicalTemplateArgument(ParamDefArg);
+TemplateArgument &CanonDefArg = CanonArgs[I];
+if (CanonDefArg.structurallyEquals(CanonParamDefArg))
+  return;
+if (I == NumArgs)
+  CanonArgs.pop_back();
+NonCanonical = true;
+  };
+  auto handleParam = [&](auto *TP, int I) -> bool {
+if (!TP->hasDefaultArgument())
+  return true;
+handleParamDefArg(TP->getDefaultArgument().getArgument(), I);
+return false;
+  };
+
+  ArrayRef Params = CanonUnderlying.getAsTemplateDecl()
+ ->getTemplateParameters()
+ ->asArray();
+  assert(CanonArgs.size() <= Params.size());
+  for (int I = NumArgs; I >= 0; --I) {

cor3ntin wrote:

Should that not be `NumArgs -1` ?

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits

https://github.com/cor3ntin edited 
https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-12 Thread via cfe-commits


@@ -6371,6 +6376,70 @@ ASTContext::getCanonicalTemplateName(const TemplateName 
&Name) const {
 canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),
 subst->getFinal(), subst->getIndex());
   }
+  case TemplateName::DeducedTemplate: {
+assert(IgnoreDeduced == false);
+DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+DefaultArguments DefArgs = DTS->getDefaultArguments();
+TemplateName Underlying = DTS->getUnderlying();
+
+bool NonCanonical = false;
+TemplateName CanonUnderlying =
+getCanonicalTemplateName(Underlying, /*IgnoreDeduced=*/true);
+NonCanonical |= CanonUnderlying != Underlying;
+auto CanonArgs =
+getCanonicalTemplateArguments(*this, DefArgs.Args, NonCanonical);
+{

cor3ntin wrote:

I don't think this scope is useful (unless you would want to put the whole 
thing in a separate function which might be cleaner)

https://github.com/llvm/llvm-project/pull/94981
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-11 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From d12c7d50b67cd669f09b3701ccf34154876786c9 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |   8 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  59 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 129 --
 clang/lib/AST/ASTDiagnostic.cpp   |  24 +--
 clang/lib/AST/ASTImporter.cpp |  15 ++
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/ItaniumMangle.cpp   |  11 ++
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 157 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 128 --
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  60 +--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 25 files changed, 564 insertions(+), 208 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 8bce4812f0d48..8818314de9364 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   ArrayParameterTypes;
@@ -2247,6 +2249,9 @@ class ASTContext : public RefCountedBase {
 unsigned Index,

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-10 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From 68791782b7a1a0eafa98950f6e03aa1585be5223 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |   8 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  59 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 129 --
 clang/lib/AST/ASTDiagnostic.cpp   |  24 +--
 clang/lib/AST/ASTImporter.cpp |  92 +-
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/ItaniumMangle.cpp   |  11 ++
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 157 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 128 --
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  60 +--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 25 files changed, 594 insertions(+), 255 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 8bce4812f0d48..8818314de9364 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   ArrayParameterTypes;
@@ -2247,6 +2249,9 @@ class ASTContext : public RefCountedBase {
 unsigned Index,

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-10 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From ea98dec85a9817eb4e35ce97389433e4a5b9676d Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |   8 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  59 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 129 --
 clang/lib/AST/ASTDiagnostic.cpp   |  24 +--
 clang/lib/AST/ASTImporter.cpp |  92 +-
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/ItaniumMangle.cpp   |  11 ++
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 157 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 134 ---
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  60 +--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 25 files changed, 600 insertions(+), 255 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 8bce4812f0d48..8818314de9364 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   ArrayParameterTypes;
@@ -2247,6 +2249,9 @@ class ASTContext : public RefCountedBase {
 unsigned Index,
   

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-10 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/94981

>From 015a05707caad5d39909bc68a5371161de464d9d Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Mon, 20 May 2024 01:15:03 -0300
Subject: [PATCH] [clang] Implement CWG2398 provisional TTP matching to class
 templates

This extends default argument deduction to cover class templates as
well, and also applies outside of partial ordering, adding to the
provisional wording introduced in 
https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how
template template parameters are partially ordered, and should reduce
the negative impact of enabling `-frelaxed-template-template-args`
by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template  class TT1, class T5> struct B>;   // #1
template   struct B>; // #2

template struct B>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous.
This patch restores the pre-P0522 behavior, `#2` is picked again.

As the consequences are not restricted to partial ordering,
the following code becomes valid:
```C++
template struct A {};
A v;
template class TT> void f(TT);

// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```

Also, since 'f' deduced from `A` is different from 'f'
deduced from `A`, this implements an additional mangling
rule.

---

Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
---
 clang-tools-extra/clangd/DumpAST.cpp  |   1 +
 .../clangd/SemanticHighlighting.cpp   |   1 +
 clang/include/clang/AST/ASTContext.h  |   8 +-
 clang/include/clang/AST/ASTImporter.h |   5 +
 clang/include/clang/AST/DependenceFlags.h |   5 +
 clang/include/clang/AST/PropertiesBase.td |  17 ++
 clang/include/clang/AST/TemplateName.h|  59 ++-
 clang/include/clang/Sema/Sema.h   |  10 +-
 clang/lib/AST/ASTContext.cpp  | 129 --
 clang/lib/AST/ASTDiagnostic.cpp   |  24 +--
 clang/lib/AST/ASTImporter.cpp |  92 +-
 clang/lib/AST/ASTStructuralEquivalence.cpp|   3 +
 clang/lib/AST/ItaniumMangle.cpp   |  11 ++
 clang/lib/AST/ODRHash.cpp |   1 +
 clang/lib/AST/TemplateName.cpp| 157 ++
 clang/lib/AST/TextNodeDumper.cpp  |  12 ++
 clang/lib/AST/Type.cpp|   3 +-
 clang/lib/Sema/SemaTemplate.cpp   |  63 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 134 ---
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  24 +--
 .../CXX/temp/temp.decls/temp.alias/p2.cpp |   5 +-
 clang/test/CodeGenCXX/mangle-cwg2398.cpp  |  11 ++
 clang/test/SemaTemplate/cwg2398.cpp   |  44 +++--
 clang/tools/libclang/CIndex.cpp   |   3 +
 clang/unittests/AST/ASTImporterTest.cpp   |  17 ++
 25 files changed, 584 insertions(+), 255 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/mangle-cwg2398.cpp

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 9a525efb938e8..e605f82e91fe4 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -187,6 +187,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_KIND(SubstTemplateTemplateParm);
   TEMPLATE_KIND(SubstTemplateTemplateParmPack);
   TEMPLATE_KIND(UsingTemplate);
+  TEMPLATE_KIND(DeducedTemplate);
 #undef TEMPLATE_KIND
 }
 llvm_unreachable("Unhandled NameKind enum");
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a366f1331c2d3..e6d16af2495fe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -1120,6 +1120,7 @@ class CollectExtraHighlightings
 case TemplateName::SubstTemplateTemplateParm:
 case TemplateName::SubstTemplateTemplateParmPack:
 case TemplateName::UsingTemplate:
+case TemplateName::DeducedTemplate:
   // Names that could be resolved to a TemplateDecl are handled elsewhere.
   break;
 }
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 8bce4812f0d48..8818314de9364 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -262,6 +262,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::ContextualFoldingSet
 SubstTemplateTemplateParmPacks;
+  mutable llvm::ContextualFoldingSet
+  DeducedTemplates;
 
   mutable llvm::ContextualFoldingSet
   ArrayParameterTypes;
@@ -2247,6 +2249,9 @@ class ASTContext : public RefCountedBase {
 unsigned Index,
 

[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

2024-06-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-modules

Author: Matheus Izvekov (mizvekov)


Changes

This extends default argument deduction to cover class templates as well, and 
also applies outside of partial ordering, adding to the provisional wording 
introduced in https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how template template 
parameters are partially ordered, and should reduce the negative impact of 
enabling `-frelaxed-template-template-args` by default.

Given the following example:
```C++
template  struct A;
template  struct B;

template