[cfe-commits] r73652 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseDecl.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Wed Jun 17 15:50:07 PDT 2009
Author: akirtzidis
Date: Wed Jun 17 17:50:06 2009
New Revision: 73652
URL: http://llvm.org/viewvc/llvm-project?rev=73652&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=73652&r1=73651&r2=73652&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Jun 17 17:50:06 2009
@@ -248,6 +248,19 @@
virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
}
+ /// 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.
+ virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ }
+
+ /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+ /// initializer for the declaration 'Dcl'.
+ virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ }
+
/// ActOnDeclarator - This callback is invoked when a declarator is parsed and
/// 'Init' specifies the initializer if any. This is for things like:
/// "int X = 4" or "typedef int foo".
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=73652&r1=73651&r2=73652&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Jun 17 17:50:06 2009
@@ -402,7 +402,14 @@
SourceLocation DelLoc = ConsumeToken();
Actions.SetDeclDeleted(ThisDecl, DelLoc);
} else {
+ if (getLang().CPlusPlus)
+ Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
+
OwningExprResult Init(ParseInitializer());
+
+ if (getLang().CPlusPlus)
+ Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+
if (Init.isInvalid()) {
SkipUntil(tok::semi, true, true);
return DeclPtrTy();
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73652&r1=73651&r2=73652&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Jun 17 17:50:06 2009
@@ -1721,6 +1721,17 @@
/// defining scope.
virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+ /// 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.
+ virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl);
+
+ /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+ /// initializer for the declaration 'Dcl'.
+ virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl);
+
// ParseObjCStringLiteral - Parse Objective-C string literals.
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=73652&r1=73651&r2=73652&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 17 17:50:06 2009
@@ -2828,3 +2828,58 @@
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?");
+}
Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp?rev=73652&r1=73651&r2=73652&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp Wed Jun 17 17:50:06 2009
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
struct S {
static const int f0 = 0;
More information about the cfe-commits
mailing list