зеркало из https://github.com/microsoft/clang-1.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82732 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6b304a0254
Коммит
7dfd0fb083
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
Загрузка…
Ссылка в новой задаче