From: Jeffrey D. Oldham Date: Tue, 21 Jan 2003 19:00:29 +0000 (+0000) Subject: re PR c++/47 (nested classes broken) X-Git-Tag: releases/gcc-3.2.2~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38f61711464f7af9eae082c13c8c1c16ff3755a4;p=thirdparty%2Fgcc.git re PR c++/47 (nested classes broken) 2003-01-21 Jeffrey D. Oldham 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 21abdcb7f467..54ede46c071e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2003-01-21 Jeffrey D. Oldham + + 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 PR c++/8503 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3a43eaa06e79..a2c0db11574a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9ec1170bc7e0..5c891a552c63 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) { diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 9821907377f7..38f46341aef8 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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. */