================
@@ -274,6 +277,151 @@ struct AccessTarget : public AccessedEntity {
 
 }
 
+static void AddFriendTemplateDeductionCandidate(
+    Sema &S, TemplateDecl *TD, Decl *Declaration, TemplateDeductionInfo &Info,
+    TemplateDeductionResult Result, TemplateSpecCandidateSet *FailedTSC) {
+  if (!FailedTSC)
+    return;
+
+  const Decl *CanonicalDeclaration = Declaration->getCanonicalDecl();
+  for (TemplateSpecCandidate &Candidate : *FailedTSC) {
+    if (!Candidate.Specialization)
+      continue;
+
+    if (Candidate.Specialization->getCanonicalDecl() == CanonicalDeclaration)
+      return;
+  }
+
+  FailedTSC->addCandidate().set(
+      DeclAccessPair::make(TD, AS_public), Declaration,
+      MakeDeductionFailureInfo(S.Context, Result, Info));
+}
+
+static bool CanDeduceTemplateArguments(Sema &S, TemplateParameterList *TPL,
+                                       TemplateDecl *TD,
+                                       ArrayRef<TemplateArgument> PatternArgs,
+                                       ArrayRef<TemplateArgument> Args,
+                                       SourceLocation Loc,
+                                       TemplateSpecCandidateSet *FailedTSC) {
+  auto Equal =
+      llvm::equal(PatternArgs, Args,
+                  [](const TemplateArgument &LHS, const TemplateArgument &RHS) 
{
+                    return LHS.structurallyEquals(RHS);
+                  });
+  if (Equal)
+    return true;
+
+  EnterExpressionEvaluationContext Unevaluated(
+      S, Sema::ExpressionEvaluationContext::Unevaluated);
+  TemplateDeductionInfo Info(FailedTSC ? FailedTSC->getLocation() : Loc);
+  Sema::SFINAETrap Trap(S, Info);
+  LocalInstantiationScope InstantiationScope(S);
+  SmallVector<DeducedTemplateArgument, 4> Deduced(TPL->size());
+  TemplateDeductionResult DeductionResult =
+      S.DeduceTemplateArguments(TPL, PatternArgs, Args, Info, Deduced,
+                                /*NumberOfArgumentsMustMatch=*/false);
+  if (DeductionResult != TemplateDeductionResult::Success) {
+    AddFriendTemplateDeductionCandidate(S, TD, TD->getTemplatedDecl(), Info,
+                                        DeductionResult, FailedTSC);
+    return false;
+  }
+
+  SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
+  Sema::InstantiatingTemplate Inst(S, Info.getLocation(), TD, DeducedArgs);
+  if (Inst.isInvalid()) {
+    AddFriendTemplateDeductionCandidate(
+        S, TD, TD->getTemplatedDecl(), Info,
+        TemplateDeductionResult::InstantiationDepth, FailedTSC);
+    return false;
+  }
+
+  TemplateDeductionResult Result;
+  S.runWithSufficientStackSpace(Info.getLocation(), [&] {
+    Result = S.FinishTemplateArgumentDeduction(
+        TD, TPL, PatternArgs, Args, Deduced, Info, /*CopyDeducedArgs=*/false);
+  });
+
+  if (Result != TemplateDeductionResult::Success || Trap.hasErrorOccurred()) {
+    TemplateDeductionResult Failure =
+        Result != TemplateDeductionResult::Success
+            ? Result
+            : TemplateDeductionResult::SubstitutionFailure;
+    AddFriendTemplateDeductionCandidate(S, TD, TD->getTemplatedDecl(), Info,
+                                        Failure, FailedTSC);
+    return false;
+  }
+
+  return true;
+}
+
+static CanQual<FunctionProtoType>
+GetCanonicalFunctionProto(Sema &S, const FunctionDecl *FD) {
+  return S.Context.getCanonicalType(FD->getType())->getAs<FunctionProtoType>();
+}
+
+static const TemplateSpecializationType *
+GetCanonicalQualifierTemplateSpecializationType(Sema &S,
+                                                NestedNameSpecifier NNS) {
+  if (!NNS)
+    return nullptr;
+
+  QualType Ty(NNS.getAsType(), 0);
+  if (Ty.isNull())
+    return nullptr;
+
+  if (const auto *ICNT = Ty->getAs<InjectedClassNameType>())
+    Ty = ICNT->getDecl()->getCanonicalTemplateSpecializationType(S.Context);
+
+  return Ty->getAs<TemplateSpecializationType>();
----------------
mizvekov wrote:

So this could return an arbitrary TemplateSpecializatonType, even for type 
alias templates. Is that what you want?

Also, this mixes canonical and non-canonical types in an arbitrary manner.

Are the results here ever going to end up in diagnostics?

https://github.com/llvm/llvm-project/pull/191268
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to