diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 579fe37feb56..cd18b969a4aa 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -539,6 +539,12 @@ public: void PushDeclContext(Scope *S, DeclContext *DC); void PopDeclContext(); + /// EnterDeclaratorContext - Used when we must lookup names in the context + /// of a declarator's nested name specifier. + void EnterDeclaratorContext(Scope *S, DeclContext *DC); + void ExitDeclaratorContext(Scope *S); + + /// getCurFunctionDecl - If inside of a function body, this returns a pointer /// to the function decl for the function being parsed. If we're currently /// in a 'block', this returns the containing context. diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 11ac0bd30056..a14bcd5287cd 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -286,11 +286,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, /// The 'SS' should be a non-empty valid CXXScopeSpec. void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); - assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?"); - PreDeclaratorDC = static_cast(S->getEntity()); - CurContext = computeDeclContext(SS); - assert(CurContext && "No context?"); - S->setEntity(CurContext); + EnterDeclaratorContext(S, computeDeclContext(SS)); } /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously @@ -301,12 +297,5 @@ void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); assert(S->getEntity() == computeDeclContext(SS) && "Context imbalance!"); - S->setEntity(PreDeclaratorDC); - PreDeclaratorDC = 0; - - // Reset CurContext to the nearest enclosing context. - while (!S->getEntity() && S->getParent()) - S = S->getParent(); - CurContext = static_cast(S->getEntity()); - assert(CurContext && "No context?"); + ExitDeclaratorContext(S); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0c5ec60e887b..90b26025414b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -219,6 +219,30 @@ void Sema::PopDeclContext() { CurContext = getContainingDC(CurContext); } +void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) { + assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?"); + PreDeclaratorDC = static_cast(S->getEntity()); + CurContext = DC; + assert(CurContext && "No context?"); + S->setEntity(CurContext); +} + +/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously +/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same +/// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. +/// Used to indicate that names should revert to being looked up in the +/// defining scope. +void Sema::ExitDeclaratorContext(Scope *S) { + S->setEntity(PreDeclaratorDC); + PreDeclaratorDC = 0; + + // Reset CurContext to the nearest enclosing context. + while (!S->getEntity() && S->getParent()) + S = S->getParent(); + CurContext = static_cast(S->getEntity()); + assert(CurContext && "No context?"); +} + /// \brief Determine whether we allow overloading of the function /// PrevDecl with another declaration. /// diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index bb1f50f104b7..a37929cb67d7 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2852,12 +2852,7 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) { // was used in a member function of X. // Change current context into the context of the initializing declaration. - - assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?"); - PreDeclaratorDC = static_cast(S->getEntity()); - CurContext = D->getDeclContext(); - assert(CurContext && "No context?"); - S->setEntity(CurContext); + EnterDeclaratorContext(S, D->getDeclContext()); } /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an @@ -2874,12 +2869,5 @@ void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) { return; assert(S->getEntity() == D->getDeclContext() && "Context imbalance!"); - S->setEntity(PreDeclaratorDC); - PreDeclaratorDC = 0; - - // Reset CurContext to the nearest enclosing context. - while (!S->getEntity() && S->getParent()) - S = S->getParent(); - CurContext = static_cast(S->getEntity()); - assert(CurContext && "No context?"); + ExitDeclaratorContext(S); }