]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/47 (nested classes broken)
authorJeffrey D. Oldham <oldham@codesourcery.com>
Tue, 21 Jan 2003 19:00:29 +0000 (19:00 +0000)
committerJeffrey D. Oldham <oldham@gcc.gnu.org>
Tue, 21 Jan 2003 19:00:29 +0000 (19:00 +0000)
2003-01-21  Jeffrey D. Oldham  <oldham@codesourcery.com>

PR c++/47
* cp-tree.h (lookup_nested_field): Add declaration.
* decl.c (lookup_name_real): Call lookup_nested_field.
* search.c (lookup_nested_field): Add function.

From-SVN: r61562

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/search.c

index 21abdcb7f467fc4f3399ac7d7064d70d535b797e..54ede46c071e35bc8b1110aae87c293495311573 100644 (file)
@@ -1,3 +1,10 @@
+2003-01-21  Jeffrey D. Oldham  <oldham@codesourcery.com>
+
+       PR c++/47
+       * cp-tree.h (lookup_nested_field): Add declaration.
+       * decl.c (lookup_name_real): Call lookup_nested_field.
+       * search.c (lookup_nested_field): Add function.
+
 2002-12-26  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/8503
index 3a43eaa06e79aefbe9d8444123917eec8d61f174..a2c0db11574ac7b06801dea62c5e4aa8f5aa9ebd 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for C++ parsing and type checking.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -4062,6 +4062,7 @@ extern tree get_dynamic_cast_base_type          PARAMS ((tree, tree));
 extern void type_access_control                        PARAMS ((tree, tree));
 extern int accessible_p                         PARAMS ((tree, tree));
 extern tree lookup_field                       PARAMS ((tree, tree, int, int));
+extern tree lookup_nested_field                        PARAMS ((tree, int));
 extern int lookup_fnfields_1                    PARAMS ((tree, tree));
 extern tree lookup_fnfields                    PARAMS ((tree, tree, int));
 extern tree lookup_member                      PARAMS ((tree, tree, int, int));
index 9ec1170bc7e0c7142ae3ec976f52bbacd6886d2b..5c891a552c639c9906799f26b45ce0d3f4cae077 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002  Free Software Foundation, Inc.
+   2001, 2002, 2003  Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -6173,6 +6173,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
        }
     }
 
+  /* The name might be from an enclosing class of the current scope.  */
+  if (!val && !nonclass && current_class_type)
+    val = qualify_lookup (lookup_nested_field (name, !yylex), flags);
+
   /* Now lookup in namespace scopes.  */
   if (!val || val_is_implicit_typename)
     {
index 9821907377f77fab7c46c88a0737da93834af4b2..38f46341aef89160ebb7282ef6132a72b3e7f713 100644 (file)
@@ -1,7 +1,7 @@
 /* Breadth-first and depth-first routines for
    searching multiple-inheritance lattice for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -1513,6 +1513,70 @@ lookup_fnfields (xbasetype, name, protect)
   return rval;
 }
 
+/* Try to find NAME inside a nested class.  */
+
+tree
+lookup_nested_field (name, complain)
+     tree name;
+     int complain;
+{
+  register tree t;
+
+  tree id = NULL_TREE;
+  if (TYPE_MAIN_DECL (current_class_type))
+    {
+      /* Climb our way up the nested ladder, seeing if we're trying to
+        modify a field in an enclosing class.  If so, we should only
+        be able to modify if it's static.  */
+      for (t = TYPE_MAIN_DECL (current_class_type);
+          t && DECL_CONTEXT (t);
+          t = TYPE_MAIN_DECL (DECL_CONTEXT (t)))
+       {
+         if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)
+           break;
+
+         /* N.B.: lookup_field will do the access checking for us */
+         id = lookup_field (DECL_CONTEXT (t), name, complain, 0);
+         if (id == error_mark_node)
+           {
+             id = NULL_TREE;
+             continue;
+           }
+
+         if (id != NULL_TREE)
+           {
+             if (TREE_CODE (id) == FIELD_DECL
+                 && ! TREE_STATIC (id)
+                 && TREE_TYPE (id) != error_mark_node)
+               {
+                 if (complain)
+                   {
+                     /* At parse time, we don't want to give this error, since
+                        we won't have enough state to make this kind of
+                        decision properly.  But there are times (e.g., with
+                        enums in nested classes) when we do need to call
+                        this fn at parse time.  So, in those cases, we pass
+                        complain as a 0 and just return a NULL_TREE.  */
+                     error ("assignment to non-static member `%D' of enclosing class `%T'",
+                               id, DECL_CONTEXT (t));
+                     /* Mark this for do_identifier().  It would otherwise
+                        claim that the variable was undeclared.  */
+                     TREE_TYPE (id) = error_mark_node;
+                   }
+                 else
+                   {
+                     id = NULL_TREE;
+                     continue;
+                   }
+               }
+             break;
+           }
+       }
+    }
+
+  return id;
+}
+
 /* TYPE is a class type. Return the index of the fields within
    the method vector with name NAME, or -1 is no such field exists.  */