diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 73 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
2 files changed, 68 insertions, 36 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4268aa24e36..426b13cfaf4 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2976,22 +2976,25 @@ SubstDefaultTemplateArgument(Sema &SemaRef, // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. if (ArgType->getType()->isDependentType()) { - TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, - Converted.data(), Converted.size()); - - MultiLevelTemplateArgumentList AllTemplateArgs - = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst) return 0; + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); + + // Only substitute for the innermost template argument list. + MultiLevelTemplateArgumentList TemplateArgLists; + TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) + TemplateArgLists.addOuterTemplateArguments(None); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); - ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs, - Param->getDefaultArgumentLoc(), - Param->getDeclName()); + ArgType = + SemaRef.SubstType(ArgType, TemplateArgLists, + Param->getDefaultArgumentLoc(), Param->getDeclName()); } return ArgType; @@ -3026,21 +3029,24 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param, SmallVectorImpl<TemplateArgument> &Converted) { - TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, - Converted.data(), Converted.size()); - - MultiLevelTemplateArgumentList AllTemplateArgs - = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst) return ExprError(); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); + + // Only substitute for the innermost template argument list. + MultiLevelTemplateArgumentList TemplateArgLists; + TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) + TemplateArgLists.addOuterTemplateArguments(None); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); - return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs); + return SemaRef.SubstExpr(Param->getDefaultArgument(), TemplateArgLists); } /// \brief Substitute template arguments into the default template argument for @@ -3076,32 +3082,35 @@ SubstDefaultTemplateArgument(Sema &SemaRef, TemplateTemplateParmDecl *Param, SmallVectorImpl<TemplateArgument> &Converted, NestedNameSpecifierLoc &QualifierLoc) { - TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, - Converted.data(), Converted.size()); - - MultiLevelTemplateArgumentList AllTemplateArgs - = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); - - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted, + Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst) return TemplateName(); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); + + // Only substitute for the innermost template argument list. + MultiLevelTemplateArgumentList TemplateArgLists; + TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) + TemplateArgLists.addOuterTemplateArguments(None); + Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); - // Substitute into the nested-name-specifier first, + // Substitute into the nested-name-specifier first, QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc(); if (QualifierLoc) { - QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, - AllTemplateArgs); + QualifierLoc = + SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgLists); if (!QualifierLoc) return TemplateName(); } - - return SemaRef.SubstTemplateName(QualifierLoc, - Param->getDefaultArgument().getArgument().getAsTemplate(), - Param->getDefaultArgument().getTemplateNameLoc(), - AllTemplateArgs); + + return SemaRef.SubstTemplateName( + QualifierLoc, + Param->getDefaultArgument().getArgument().getAsTemplate(), + Param->getDefaultArgument().getTemplateNameLoc(), + TemplateArgLists); } /// \brief If the given template parameter has a default template diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a797ae66b19..5d6847fdf0e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1737,8 +1737,13 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( D->isParameterPack()); Inst->setAccess(AS_public); - if (D->hasDefaultArgument()) - Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false); + if (D->hasDefaultArgument()) { + TypeSourceInfo *InstantiatedDefaultArg = + SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs, + D->getDefaultArgumentLoc(), D->getDeclName()); + if (InstantiatedDefaultArg) + Inst->setDefaultArgument(InstantiatedDefaultArg, false); + } // Introduce this template parameter's instantiation into the instantiation // scope. @@ -1888,7 +1893,11 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( if (Invalid) Param->setInvalidDecl(); - Param->setDefaultArgument(D->getDefaultArgument(), false); + if (D->hasDefaultArgument()) { + ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs); + if (!Value.isInvalid()) + Param->setDefaultArgument(Value.get(), false); + } // Introduce this template parameter's instantiation into the instantiation // scope. @@ -2011,7 +2020,21 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams); - Param->setDefaultArgument(D->getDefaultArgument(), false); + if (D->hasDefaultArgument()) { + NestedNameSpecifierLoc QualifierLoc = + D->getDefaultArgument().getTemplateQualifierLoc(); + QualifierLoc = + SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); + TemplateName TName = SemaRef.SubstTemplateName( + QualifierLoc, D->getDefaultArgument().getArgument().getAsTemplate(), + D->getDefaultArgument().getTemplateNameLoc(), TemplateArgs); + if (!TName.isNull()) + Param->setDefaultArgument( + TemplateArgumentLoc(TemplateArgument(TName), + D->getDefaultArgument().getTemplateQualifierLoc(), + D->getDefaultArgument().getTemplateNameLoc()), + false); + } Param->setAccess(AS_public); // Introduce this template parameter's instantiation into the instantiation |