diff options
Diffstat (limited to 'clang/lib/Sema/SemaConcept.cpp')
-rw-r--r-- | clang/lib/Sema/SemaConcept.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index c6a54dc..a4f660c3 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -792,7 +792,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, bool ForOverloadResolution) { // Don't check constraints if the function is dependent. Also don't check if // this is a function template specialization, as the call to - // CheckinstantiatedFunctionTemplateConstraints after this will check it + // CheckFunctionTemplateConstraints after this will check it // better. if (FD->isDependentContext() || FD->getTemplatedKind() == @@ -1060,12 +1060,55 @@ bool Sema::EnsureTemplateArgumentListConstraints( return false; } -bool Sema::CheckInstantiatedFunctionTemplateConstraints( +static bool CheckFunctionConstraintsWithoutInstantiation( + Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionTemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, + ConstraintSatisfaction &Satisfaction) { + SmallVector<AssociatedConstraint, 3> TemplateAC; + Template->getAssociatedConstraints(TemplateAC); + if (TemplateAC.empty()) { + Satisfaction.IsSatisfied = true; + return false; + } + + LocalInstantiationScope Scope(SemaRef); + + FunctionDecl *FD = Template->getTemplatedDecl(); + // Collect the list of template arguments relative to the 'primary' + // template. We need the entire list, since the constraint is completely + // uninstantiated at this point. + + // FIXME: Add TemplateArgs through the 'Innermost' parameter once + // the refactoring of getTemplateInstantiationArgs() relands. + MultiLevelTemplateArgumentList MLTAL; + MLTAL.addOuterTemplateArguments(Template, std::nullopt, /*Final=*/false); + SemaRef.getTemplateInstantiationArgs( + MLTAL, /*D=*/FD, FD, + /*Final=*/false, /*Innermost=*/std::nullopt, /*RelativeToPrimary=*/true, + /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true); + MLTAL.replaceInnermostTemplateArguments(Template, TemplateArgs); + + Sema::ContextRAII SavedContext(SemaRef, FD); + std::optional<Sema::CXXThisScopeRAII> ThisScope; + if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) + ThisScope.emplace(SemaRef, /*Record=*/Method->getParent(), + /*ThisQuals=*/Method->getMethodQualifiers()); + return SemaRef.CheckConstraintSatisfaction( + Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction); +} + +bool Sema::CheckFunctionTemplateConstraints( SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef<TemplateArgument> TemplateArgs, ConstraintSatisfaction &Satisfaction) { // In most cases we're not going to have constraints, so check for that first. FunctionTemplateDecl *Template = Decl->getPrimaryTemplate(); + + if (!Template) + return ::CheckFunctionConstraintsWithoutInstantiation( + *this, PointOfInstantiation, Decl->getDescribedFunctionTemplate(), + TemplateArgs, Satisfaction); + // Note - code synthesis context for the constraints check is created // inside CheckConstraintsSatisfaction. SmallVector<AssociatedConstraint, 3> TemplateAC; |