diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-31 17:21:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-31 17:21:17 +0000 |
commit | 550d9b28fd586db541eb6dd36f3c10d114e483d8 (patch) | |
tree | b01023c9c5330b297f5388de6ac1a22dadc028b1 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | df7c3b955e31a6951822f2adf36e98543ef14c7e (diff) |
Implement "incremental" template instantiation for non-type template
parameters and template type parameters, which occurs when
substituting into the declarations of member templates inside class
templates. This eliminates errors about our inability to "reduce
non-type template parameter depth", fixing PR5311.
Also fixes a bug when instantiating a template type parameter
declaration in a member template, where we weren't properly reducing
the template parameter's depth.
LLVM's StringSwitch header now parses.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85669 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f8f2217464..27275230f7 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -409,6 +409,9 @@ namespace { } Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { + // Create a local instantiation scope for this class template, which + // will contain the instantiations of the template parameters. + Sema::LocalInstantiationScope Scope(SemaRef); TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) @@ -491,8 +494,12 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( Decl * TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - // FIXME: Dig out the out-of-line definition of this function template? - + // Create a local instantiation scope for this function template, which + // will contain the instantiations of the template parameters and then get + // merged with the local instantiation scope for the function template + // itself. + Sema::LocalInstantiationScope Scope(SemaRef); + TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) @@ -582,7 +589,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { return Info->Function; } - Sema::LocalInstantiationScope Scope(SemaRef); + Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0); llvm::SmallVector<ParmVarDecl *, 4> Params; QualType T = SubstFunctionType(D, Params); @@ -711,7 +718,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, return Info->Function; } - Sema::LocalInstantiationScope Scope(SemaRef); + Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0); llvm::SmallVector<ParmVarDecl *, 4> Params; QualType T = SubstFunctionType(D, Params); @@ -886,7 +893,7 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(), - TTPT->getDepth(), TTPT->getIndex(), + TTPT->getDepth() - 1, TTPT->getIndex(), TTPT->getName(), D->wasDeclaredWithTypename(), D->isParameterPack()); @@ -904,6 +911,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( D->defaultArgumentWasInherited() /* preserve? */); } + // Introduce this template parameter's instantiation into the instantiation + // scope. + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst); + return Inst; } @@ -940,6 +951,10 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( Param->setInvalidDecl(); Param->setDefaultArgument(D->getDefaultArgument()); + + // Introduce this template parameter's instantiation into the instantiation + // scope. + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); return Param; } @@ -1024,6 +1039,11 @@ bool TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec) { + // Create a local instantiation scope for this class template partial + // specialization, which will contain the instantiations of the template + // parameters. + Sema::LocalInstantiationScope Scope(SemaRef); + // Substitute into the template parameters of the class template partial // specialization. TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); @@ -1773,7 +1793,9 @@ NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D, } DeclContext *ParentDC = D->getDeclContext(); - if (isa<ParmVarDecl>(D) || ParentDC->isFunctionOrMethod()) { + if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || + isa<TemplateTypeParmDecl>(D) || isa<TemplateTypeParmDecl>(D) || + ParentDC->isFunctionOrMethod()) { // D is a local of some kind. Look into the map of local // declarations to their instantiations. return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D)); |