[cfe-commits] r91769 - in /cfe/trunk: lib/Parse/ParseDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp test/SemaCXX/nested-name-spec.cpp test/SemaCXX/qual-id-test.cpp

Douglas Gregor dgregor at apple.com
Sat Dec 19 10:19:57 PST 2009


On Dec 19, 2009, at 1:28 AM, John McCall wrote:

> Author: rjmccall
> Date: Sat Dec 19 03:28:58 2009
> New Revision: 91769
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=91769&view=rev
> Log:
> Just push a new scope when parsing an out-of-line variable definition.
> Magically fixes all the terrible lookup problems associated with not pushing
> a new scope.  Resolves an ancient xfail and an LLVM misparse.

Does this also make it easy to fix

	http://llvm.org/bugs/show_bug.cgi?id=5741

?

	- Doug

> 
> Modified:
>    cfe/trunk/lib/Parse/ParseDecl.cpp
>    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
>    cfe/trunk/test/SemaCXX/nested-name-spec.cpp
>    cfe/trunk/test/SemaCXX/qual-id-test.cpp
> 
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=91769&r1=91768&r2=91769&view=diff
> 
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Dec 19 03:28:58 2009
> @@ -550,13 +550,17 @@
>       SourceLocation DelLoc = ConsumeToken();
>       Actions.SetDeclDeleted(ThisDecl, DelLoc);
>     } else {
> -      if (getLang().CPlusPlus)
> +      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
> +        EnterScope(0);
>         Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
> +      }
> 
>       OwningExprResult Init(ParseInitializer());
> 
> -      if (getLang().CPlusPlus)
> +      if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
>         Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
> +        ExitScope();
> +      }
> 
>       if (Init.isInvalid()) {
>         SkipUntil(tok::semi, true, true);
> 
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=91769&r1=91768&r2=91769&view=diff
> 
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Dec 19 03:28:58 2009
> @@ -5529,51 +5529,61 @@
>   return true;
> }
> 
> -/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
> -/// initializer for the declaration 'Dcl'.
> +/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse
> +/// an initializer for the out-of-line declaration 'Dcl'.  The scope
> +/// is a fresh scope pushed for just this purpose.
> +///
> /// 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) {
> -  AdjustDeclIfTemplate(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;
> +  Decl *D = Dcl.getAs<Decl>();
> +  if (D == 0) 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.
> +  // We should only get called for declarations with scope specifiers, like:
> +  //   int foo::bar;
> +  assert(D->isOutOfLine());
> +
> +  // C++0x [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.
> +  // C++0x [basic.lookup.unqual]p14:
> +  //   If a variable member of a namespace is defined outside of the
> +  //   scope of its namespace then any name used in the definition of
> +  //   the variable member (after the declarator-id) is looked up as
> +  //   if the definition of the variable member occurred in its
> +  //   namespace.
> +  // Both of these imply that we should push a scope whose context
> +  // is the semantic context of the declaration.  We can't use
> +  // PushDeclContext here because that context is not necessarily
> +  // lexically contained in the current context.  Fortunately,
> +  // scopes should work.
> +
> +#ifndef NDEBUG
> +  Scope *Ancestor = S->getParent();
> +  while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent();
> +  assert(Ancestor->getEntity() == CurContext && "ancestor context mismatch");
> +#endif
> 
> -  // Change current context into the context of the initializing declaration.
> -  EnterDeclaratorContext(S, D->getDeclContext());
> +  CurContext = D->getDeclContext();
> +  S->setEntity(CurContext);
> }
> 
> /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
> -/// initializer for the declaration 'Dcl'.
> +/// initializer for the out-of-line declaration 'Dcl'.
> void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
> -  AdjustDeclIfTemplate(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;
> +  Decl *D = Dcl.getAs<Decl>();
> +  if (D == 0) return;
> 
> +  assert(D->isOutOfLine());
>   assert(S->getEntity() == D->getDeclContext() && "Context imbalance!");
> -  ExitDeclaratorContext(S);
> +  
> +  Scope *Ancestor = S->getParent();
> +  while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent();
> +  CurContext = (DeclContext*) Ancestor->getEntity();
> }
> 
> /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
> 
> Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp?rev=91769&r1=91768&r2=91769&view=diff
> 
> ==============================================================================
> --- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp (original)
> +++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp Sat Dec 19 03:28:58 2009
> @@ -1,5 +1,10 @@
> // RUN: %clang_cc1 -fsyntax-only -verify %s
> -// XFAIL: *
> +
> +// C++0x [basic.lookup.unqual]p14:
> +//   If a variable member of a namespace is defined outside of the
> +//   scope of its namespace then any name used in the definition of
> +//   the variable member (after the declarator-id) is looked up as if
> +//   the definition of the variable member occurred in its namespace.
> 
> namespace N { 
>   struct S {};
> 
> Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=91769&r1=91768&r2=91769&view=diff
> 
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
> +++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Sat Dec 19 03:28:58 2009
> @@ -207,3 +207,16 @@
>     }
>   };
> }
> +
> +// We still need to do lookup in the lexical scope, even if we push a
> +// non-lexical scope.
> +namespace test2 {
> +  namespace ns {
> +    int *count_ptr;
> +  }
> +  namespace {
> +    int count = 0;
> +  }
> +
> +  int *ns::count_ptr = &count;
> +}
> 
> Modified: cfe/trunk/test/SemaCXX/qual-id-test.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/qual-id-test.cpp?rev=91769&r1=91768&r2=91769&view=diff
> 
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/qual-id-test.cpp (original)
> +++ cfe/trunk/test/SemaCXX/qual-id-test.cpp Sat Dec 19 03:28:58 2009
> @@ -137,4 +137,4 @@
> 
> a a;
> 
> -int a::sa = a.a;
> +int a::sa = a.a; // expected-error {{invalid use of nonstatic data member 'a'}}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list