diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 25cb6c8fbf610..c1912343cf43b 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13033,11 +13033,14 @@ class Sema final : public SemaBase { /// instantiation arguments. /// /// \param DC In the event we don't HAVE a declaration yet, we instead provide - /// the decl context where it will be created. In this case, the `Innermost` - /// should likely be provided. If ND is non-null, this is ignored. + /// the decl context where it will be created. In this case, the \p + /// Innermost should likely be provided. If \p ND is non-null and \p + /// Innermost is NULL, this is ignored. /// /// \param Innermost if non-NULL, specifies a template argument list for the - /// template declaration passed as ND. + /// template declaration passed as \p ND. The next declaration context would + /// be switched to \p DC if present; otherwise, it would be the semantic + /// declaration context of \p ND. /// /// \param RelativeToPrimary true if we should get the template /// arguments relative to the primary template, even when we're @@ -13053,6 +13056,9 @@ class Sema final : public SemaBase { /// ForConstraintInstantiation indicates we should continue looking when /// encountering a lambda generic call operator, and continue looking for /// arguments on an enclosing class template. + /// + /// \param SkipForSpecialization when specified, any template specializations + /// in a traversal would be ignored. MultiLevelTemplateArgumentList getTemplateInstantiationArgs( const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false, std::optional> Innermost = std::nullopt, diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index de24bbe7eb99c..f4dd0648781b6 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1487,7 +1487,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N, static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, const ConceptSpecializationExpr *CSE) { MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( - CSE->getNamedConcept(), CSE->getNamedConcept()->getLexicalDeclContext(), + CSE->getNamedConcept(), CSE->getNamedConcept()->getDeclContext(), /*Final=*/false, CSE->getTemplateArguments(), /*RelativeToPrimary=*/true, /*Pattern=*/nullptr, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 29e7978ba5b1f..d2b1bc0e463ad 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5582,11 +5582,12 @@ bool Sema::CheckTemplateArgumentList( ContextRAII Context(*this, NewContext); CXXThisScopeRAII(*this, RD, ThisQuals, RD != nullptr); - MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs( - Template, NewContext, /*Final=*/false, CanonicalConverted, - /*RelativeToPrimary=*/true, - /*Pattern=*/nullptr, - /*ForConceptInstantiation=*/true); + MultiLevelTemplateArgumentList MLTAL = + getTemplateInstantiationArgs(Template, Template->getDeclContext(), + /*Final=*/false, CanonicalConverted, + /*RelativeToPrimary=*/true, + /*Pattern=*/nullptr, + /*ForConceptInstantiation=*/true); if (EnsureTemplateArgumentListConstraints( Template, MLTAL, SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 9a6cd2cd0ab75..efae547b21c71 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -492,7 +492,8 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( // has a depth of 0. if (const auto *TTP = dyn_cast(CurDecl)) HandleDefaultTempArgIntoTempTempParam(TTP, Result); - CurDecl = Response::UseNextDecl(CurDecl).NextDecl; + CurDecl = DC ? Decl::castFromDeclContext(DC) + : Response::UseNextDecl(CurDecl).NextDecl; } while (!CurDecl->isFileContextDecl()) { @@ -3240,15 +3241,13 @@ bool Sema::SubstDefaultArgument( /*ForDefinition*/ false); if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs)) return true; - const FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate(); - if (PrimaryTemplate && PrimaryTemplate->isOutOfLine()) { - TemplateArgumentList *CurrentTemplateArgumentList = - TemplateArgumentList::CreateCopy(getASTContext(), - TemplateArgs.getInnermost()); + // FIXME: Investigate if we shall validate every FunctionTemplateDecl + // along the getInstantiatedFromMemberTemplate() chain. + if (auto *PrimaryTemplate = FD->getPrimaryTemplate(); + PrimaryTemplate && PrimaryTemplate->isOutOfLine()) NewTemplateArgs = getTemplateInstantiationArgs( FD, FD->getDeclContext(), /*Final=*/false, - CurrentTemplateArgumentList->asArray(), /*RelativeToPrimary=*/true); - } + TemplateArgs.getInnermost(), /*RelativeToPrimary=*/true); } runWithSufficientStackSpace(Loc, [&] {