summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-06-17 22:50:06 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-06-17 22:50:06 +0000
commit3df1978270c98b653879fcad35b6848f565e820c (patch)
tree1bd964b7e90f5104d1cb8c8d5a6c4bf5657c5439 /clang/lib/Sema/SemaDeclCXX.cpp
parentc4b766bc65927dd1b09c1014287aa5e0325dcb1c (diff)
downloadbcm5719-llvm-3df1978270c98b653879fcad35b6848f565e820c.tar.gz
bcm5719-llvm-3df1978270c98b653879fcad35b6848f565e820c.zip
Implement correct name lookup inside an initializer of a C++ class static data member.
Fixes "test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp" test case. llvm-svn: 73652
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index dcf11c54acf..bb1f50f104b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2828,3 +2828,58 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
return false;
}
+
+/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
+/// initializer for the declaration 'Dcl'.
+/// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
+/// static data member of class X, names should be looked up in the scope of
+/// class X.
+void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ Decl *D = Dcl.getAs<Decl>();
+ // If there is no declaration, there was an error parsing it.
+ if (D == 0)
+ return;
+
+ // Check whether it is a declaration with a nested name specifier like
+ // int foo::bar;
+ if (!D->isOutOfLine())
+ return;
+
+ // C++ [basic.lookup.unqual]p13
+ //
+ // A name used in the definition of a static data member of class X
+ // (after the qualified-id of the static member) is looked up as if the name
+ // 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<DeclContext*>(S->getEntity());
+ CurContext = D->getDeclContext();
+ assert(CurContext && "No context?");
+ S->setEntity(CurContext);
+}
+
+/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+/// initializer for the declaration 'Dcl'.
+void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ Decl *D = Dcl.getAs<Decl>();
+ // If there is no declaration, there was an error parsing it.
+ if (D == 0)
+ return;
+
+ // Check whether it is a declaration with a nested name specifier like
+ // int foo::bar;
+ if (!D->isOutOfLine())
+ 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<DeclContext*>(S->getEntity());
+ assert(CurContext && "No context?");
+}
OpenPOWER on IntegriCloud