When we are instantiating a member function of a local class, be sure

to merge the local instantiation scope with the outer local
instantiation scope, so that we can instantiate declarations from the
function owning the local class. Fixes an assert while instantiating
Boost.MPL's BOOST_MPL_ASSERT_MSG.

llvm-svn: 93651
This commit is contained in:
Douglas Gregor 2010-01-16 20:21:20 +00:00
parent faf85c0dbe
commit f5974fa0d5
4 changed files with 33 additions and 9 deletions

View File

@ -1017,13 +1017,8 @@ private:
};
inline bool Decl::isTemplateParameter() const {
return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm;
}
inline bool Decl::isDefinedOutsideFunctionOrMethod() const {
if (getDeclContext())
return !getDeclContext()->getLookupContext()->isFunctionOrMethod();
return true;
return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
getKind() == TemplateTemplateParm;
}
} // end clang.

View File

@ -102,6 +102,17 @@ bool Decl::isFunctionOrFunctionTemplate() const {
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
}
bool Decl::isDefinedOutsideFunctionOrMethod() const {
for (const DeclContext *DC = getDeclContext();
DC && !DC->isTranslationUnit();
DC = DC->getParent())
if (DC->isFunctionOrMethod())
return false;
return true;
}
//===----------------------------------------------------------------------===//
// PrettyStackTraceDecl Implementation
//===----------------------------------------------------------------------===//

View File

@ -717,7 +717,10 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
return Info->Function;
}
Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0);
bool MergeWithParentScope = (TemplateParams != 0) ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
QualType T = SubstFunctionType(D, Params);
@ -844,7 +847,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
return Info->Function;
}
Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0);
bool MergeWithParentScope = (TemplateParams != 0) ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
QualType T = SubstFunctionType(D, Params);

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -verify %s
template<typename T>
void f0() {
struct X;
typedef struct Y {
T (X::* f1())(int) { return 0; }
} Y2;
Y2 y = Y();
}
template void f0<int>();