================
@@ -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