When entering the scope of a declarator, make sure that the scope is

complete (or, possibly causing template instantiation).

Test this via some explicit specializations of member functions.

llvm-svn: 82732
This commit is contained in:
Douglas Gregor 2009-09-24 23:39:01 +00:00
parent c594890a82
commit 5013a7e42d
5 changed files with 28 additions and 5 deletions

View File

@ -300,7 +300,9 @@ public:
/// looked up in the declarator-id's scope, until the declarator is parsed and
/// ActOnCXXExitDeclaratorScope is called.
/// The 'SS' should be a non-empty valid CXXScopeSpec.
virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
/// \returns true if an error occurred, false otherwise.
virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
return false;
}
/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously

View File

@ -1123,7 +1123,9 @@ private:
void EnterDeclaratorScope() {
assert(!EnteredScope && "Already entered the scope!");
assert(SS.isSet() && "C++ scope was not set!");
P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS);
if (P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
SS.setScopeRep(0);
if (!SS.isInvalid())
EnteredScope = true;
}

View File

@ -2151,7 +2151,7 @@ public:
/// looked up in the declarator-id's scope, until the declarator is parsed and
/// ActOnCXXExitDeclaratorScope is called.
/// The 'SS' should be a non-empty valid CXXScopeSpec.
virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same

View File

@ -519,10 +519,18 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
/// looked up in the declarator-id's scope, until the declarator is parsed and
/// ActOnCXXExitDeclaratorScope is called.
/// The 'SS' should be a non-empty valid CXXScopeSpec.
void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
if (DeclContext *DC = computeDeclContext(SS, true))
if (DeclContext *DC = computeDeclContext(SS, true)) {
// Before we enter a declarator's context, we need to make sure that
// it is a complete declaration context.
if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
return true;
EnterDeclaratorContext(S, DC);
}
return false;
}
/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously

View File

@ -0,0 +1,11 @@
// RUN: clang-cc -fsyntax-only -verify %s
template<typename T>
struct X0 {
typedef T* type;
void f0(T);
void f1(type);
};
template<> void X0<char>::f0(char);
template<> void X0<char>::f1(type);