================ @@ -3553,6 +3553,56 @@ static unsigned getPackIndexForParam(Sema &S, llvm_unreachable("parameter index would not be produced from template"); } +// if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl` +// we try to instantiate and update its explicit specifier after constraint +// checking. +static Sema::TemplateDeductionResult +tryInstantiateExplicitSpecifier(Sema &S, FunctionDecl *Specialization, + const MultiLevelTemplateArgumentList &SubstArgs, + TemplateDeductionInfo &Info, + FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> DeducedArgs) { + + const auto TryInstantiateExplicitSpecifierForSingleDecl = + [&](auto *ExplicitDecl) { + ExplicitSpecifier ExplicitSpecifier = + ExplicitDecl->getExplicitSpecifier(); + Expr *const Expr = ExplicitSpecifier.getExpr(); + if (!Expr) { + return Sema::TDK_Success; + } + if (!Expr->isValueDependent()) { + return Sema::TDK_Success; + } + // TemplateDeclInstantiator::InitFunctionInstantiation set the + // ActiveInstType to TemplateInstantiation, but we need + // to enable SFINAE when instantiating explicit specifier. + Sema::InstantiatingTemplate Inst( + S, Info.getLocation(), FunctionTemplate, DeducedArgs, + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, + Info); + const auto Instantiated = + S.instantiateExplicitSpecifier(SubstArgs, ExplicitSpecifier); + if (Instantiated.isInvalid()) { + ExplicitDecl->setInvalidDecl(true); + return clang::Sema::TDK_SubstitutionFailure; + } + ExplicitDecl->setExplicitSpecifier(Instantiated); + return clang::Sema::TDK_Success; + }; + Sema::TemplateDeductionResult DeductionResult = clang::Sema::TDK_Success; + if (CXXConstructorDecl *ConstructorDecl = + dyn_cast_or_null<CXXConstructorDecl>(Specialization)) { ---------------- erichkeane wrote:
Ah, I missed that. Hmm... Perhaps keep it inline and just extract the calls to the two functions (get and set ExplicitSpecifier) into their own little functions that 'do the right thing'. So: ``` auto getExplicitSpecifier(FunctionDecl *FD) { return isa<CXXConstructorDecl>(FD) ? cast<CXXConstructorDecl>(FD)->getExplicitSpecifier() : cast<CXXConversionDecl>(FD)->getExplicitSpecifier; } ``` https://github.com/llvm/llvm-project/pull/70548 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits