From 6920cdce298ac9ba50dc7ebb7dea982a300b0664 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 3 May 2010 15:32:18 +0000 Subject: [PATCH] When instantiating a member function declared via a typedef, don't try to enter the instantiated parameter declarations into the local instantiation scope; they can't be referenced anyway. Fixes PR7022. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102914 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 32 +++++++++++++----------- test/SemaTemplate/instantiate-method.cpp | 23 +++++++++++++++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 48b517ef22..8974ecbdf4 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1776,28 +1776,32 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (NewTInfo != OldTInfo) { // Get parameters from the new type info. TypeLoc OldTL = OldTInfo->getTypeLoc(); - FunctionProtoTypeLoc *OldProtoLoc = cast(&OldTL); - TypeLoc NewTL = NewTInfo->getTypeLoc(); - FunctionProtoTypeLoc *NewProtoLoc = cast(&NewTL); - assert(NewProtoLoc && "Missing prototype?"); - for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i) { - // FIXME: Variadic templates will break this. - Params.push_back(NewProtoLoc->getArg(i)); - SemaRef.CurrentInstantiationScope->InstantiatedLocal( + if (FunctionProtoTypeLoc *OldProtoLoc + = dyn_cast(&OldTL)) { + TypeLoc NewTL = NewTInfo->getTypeLoc(); + FunctionProtoTypeLoc *NewProtoLoc = cast(&NewTL); + assert(NewProtoLoc && "Missing prototype?"); + for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i) { + // FIXME: Variadic templates will break this. + Params.push_back(NewProtoLoc->getArg(i)); + SemaRef.CurrentInstantiationScope->InstantiatedLocal( OldProtoLoc->getArg(i), NewProtoLoc->getArg(i)); + } } } else { // The function type itself was not dependent and therefore no // substitution occurred. However, we still need to instantiate // the function parameters themselves. TypeLoc OldTL = OldTInfo->getTypeLoc(); - FunctionProtoTypeLoc *OldProtoLoc = cast(&OldTL); - for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) { - ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i)); - if (!Parm) - return 0; - Params.push_back(Parm); + if (FunctionProtoTypeLoc *OldProtoLoc + = dyn_cast(&OldTL)) { + for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) { + ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i)); + if (!Parm) + return 0; + Params.push_back(Parm); + } } } return NewTInfo; diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index c0325cfa6c..363115d184 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -152,3 +152,26 @@ namespace PR6947 { } } + +namespace PR7022 { + template + struct X1 + { + typedef int state_t( ); + state_t g ; + }; + + template < typename U = X1 > struct X2 + { + X2( U = U()) + { + } + }; + + void m(void) + { + typedef X2<> X2_type; + X2_type c; + } + +} -- 2.40.0