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.

llvm-svn: 102914
This commit is contained in:
Douglas Gregor 2010-05-03 15:32:18 +00:00
parent 456ad1a817
commit 95c70ec678
2 changed files with 41 additions and 14 deletions

View File

@ -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<FunctionProtoTypeLoc>(&OldTL);
TypeLoc NewTL = NewTInfo->getTypeLoc();
FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&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<FunctionProtoTypeLoc>(&OldTL)) {
TypeLoc NewTL = NewTInfo->getTypeLoc();
FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&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<FunctionProtoTypeLoc>(&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<FunctionProtoTypeLoc>(&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;

View File

@ -152,3 +152,26 @@ namespace PR6947 {
}
}
namespace PR7022 {
template <typename >
struct X1
{
typedef int state_t( );
state_t g ;
};
template < typename U = X1<int> > struct X2
{
X2( U = U())
{
}
};
void m(void)
{
typedef X2<> X2_type;
X2_type c;
}
}