From: Mark Mitchell Date: Fri, 16 Apr 1999 13:16:50 +0000 (+0000) Subject: cp-tree.h (TREE_NONLOCAL_FLAG): Remove. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=280f9385eef072ea1445a6444d292465654ea018;p=gcc.git cp-tree.h (TREE_NONLOCAL_FLAG): Remove. * cp-tree.h (TREE_NONLOCAL_FLAG): Remove. (storetags): Declare. * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG. (pushclass): Likewise. Use storetags to install tag declarations, not pushtag. (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG. * decl.c (storetags): Make it global. (push_class_binding): Set INHERITED_VALUE_BINDING_P for an implicit typename declaration. (pushtag): Tidy. Don't use TREE_NONLOCAL_FLAG. * method.c (hack_identifier): Likewise. * search.c (lookup_member): Likewise. From-SVN: r26491 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8f6159813ee..b7b3a85d980 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 1999-04-16 Mark Mitchell + * cp-tree.h (TREE_NONLOCAL_FLAG): Remove. + (storetags): Declare. + * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG. + (pushclass): Likewise. Use storetags to install tag declarations, + not pushtag. + (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG. + * decl.c (storetags): Make it global. + (push_class_binding): Set INHERITED_VALUE_BINDING_P for an + implicit typename declaration. + (pushtag): Tidy. Don't use TREE_NONLOCAL_FLAG. + * method.c (hack_identifier): Likewise. + * search.c (lookup_member): Likewise. + * decl.c (warn_about_implicit_typename_lookup): New function. (lookup_name_real): Use it. Rework handling of implicit typename extension. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4d970f5d6f2..cc23b29cc13 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4185,10 +4185,6 @@ finish_struct (t, attributes, warn_anon) as necessary. */ unreverse_member_declarations (t); - /* Mark all the tags in the class as class-local. */ - for (x = CLASSTYPE_TAGS (t); x; x = TREE_CHAIN (x)) - TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0; - cplus_decl_attributes (t, attributes, NULL_TREE); if (processing_template_decl) @@ -4511,17 +4507,7 @@ pushclass (type, modify) unuse_fields (type); } - for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) - { - tree tag_type = TREE_VALUE (tags); - - TREE_NONLOCAL_FLAG (tag_type) = 1; - if (! TREE_PURPOSE (tags)) - continue; - if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type)) - && CLASSTYPE_IS_TEMPLATE (tag_type))) - pushtag (TREE_PURPOSE (tags), tag_type, 0); - } + storetags (CLASSTYPE_TAGS (type)); } } @@ -4541,11 +4527,6 @@ invalidate_class_lookup_cache () them. This is it! */ for (t = previous_class_values; t; t = TREE_CHAIN (t)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } previous_class_type = NULL_TREE; } @@ -4556,16 +4537,6 @@ invalidate_class_lookup_cache () void popclass () { - /* Just remove from this class what didn't make - it into IDENTIFIER_CLASS_VALUE. */ - tree tags = CLASSTYPE_TAGS (current_class_type); - - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } - poplevel (1, 0, 0); /* Since poplevel_class does the popping of class decls nowadays, this really only frees the obstack used for these decls. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dcfdeb38021..282d1fa5324 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -23,8 +23,7 @@ Boston, MA 02111-1307, USA. */ #define _CP_TREE_H /* Usage of TREE_LANG_FLAG_?: - 0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE). - BINFO_MARKED (BINFO nodes). + 0: BINFO_MARKED (BINFO nodes). COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). NEW_EXPR_USE_GLOBAL (in NEW_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). @@ -803,9 +802,6 @@ struct lang_type (TYPE_NEEDS_DESTRUCTOR (NODE) \ || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE))) -/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */ -#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE)) - /* Nonzero means that this _CLASSTYPE node defines ways of converting itself to other types. */ #define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion) @@ -2885,6 +2881,7 @@ extern int push_class_binding PROTO((tree, tree)); extern tree check_default_argument PROTO((tree, tree)); extern tree push_overloaded_decl PROTO((tree, int)); extern void clear_identifier_class_values PROTO((void)); +extern void storetags PROTO((tree)); /* in decl2.c */ extern int check_java_method PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index fe30586454d..d1f722cdb19 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -148,7 +148,6 @@ static struct binding_level *make_binding_level PROTO((void)); static void declare_namespace_level PROTO((void)); static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN; static void storedecls PROTO((tree)); -static void storetags PROTO((tree)); static void require_complete_types_for_parms PROTO((tree)); static void push_overloaded_decl_1 PROTO((tree)); static int ambi_op_p PROTO((tree)); @@ -1231,19 +1230,29 @@ push_class_binding (id, decl) binding = IDENTIFIER_BINDING (id); if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST) { - if (TREE_CODE (decl) == OVERLOAD) - context = DECL_REAL_CONTEXT (OVL_CURRENT (decl)); + /* Any implicit typename must be from a base-class. The + context for an implicit typename declaration is always + the derived class in which the lookup was done, so the checks + based on the context of DECL below will not trigger. */ + if (TREE_CODE (decl) == TYPE_DECL + && IMPLICIT_TYPENAME_P (TREE_TYPE (decl))) + INHERITED_VALUE_BINDING_P (binding) = 1; else { - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', - 0); - context = DECL_REAL_CONTEXT (decl); - } + if (TREE_CODE (decl) == OVERLOAD) + context = DECL_REAL_CONTEXT (OVL_CURRENT (decl)); + else + { + my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', + 0); + context = DECL_REAL_CONTEXT (decl); + } - if (is_properly_derived_from (current_class_type, context)) - INHERITED_VALUE_BINDING_P (binding) = 1; - else - INHERITED_VALUE_BINDING_P (binding) = 0; + if (is_properly_derived_from (current_class_type, context)) + INHERITED_VALUE_BINDING_P (binding) = 1; + else + INHERITED_VALUE_BINDING_P (binding) = 0; + } } else if (BINDING_VALUE (binding) == decl) /* We only encounter a TREE_LIST when push_class_decls detects an @@ -2616,7 +2625,6 @@ maybe_process_template_type_declaration (type, globalize, b) binding level, but is instead the pseudo-global level. */ b->level_chain->tags = saveable_tree_cons (name, type, b->level_chain->tags); - TREE_NONLOCAL_FLAG (type) = 1; if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; } @@ -2637,8 +2645,6 @@ pushtag (name, type, globalize) int globalize; { register struct binding_level *b; - tree context = 0; - tree c_decl = 0; b = current_binding_level; while (b->tag_transparent @@ -2652,32 +2658,34 @@ pushtag (name, type, globalize) if (name) { - context = type ? TYPE_CONTEXT (type) : NULL_TREE; - if (! context) - { - tree cs = current_scope (); - - if (! globalize) - context = cs; - else if (cs != NULL_TREE - && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') - /* When declaring a friend class of a local class, we want - to inject the newly named class into the scope - containing the local class, not the namespace scope. */ - context = hack_decl_function_context (get_type_decl (cs)); - } - if (context) - c_decl = TREE_CODE (context) == FUNCTION_DECL - ? context : TYPE_MAIN_DECL (context); - - if (!context) - context = current_namespace; - /* Do C++ gratuitous typedefing. */ if (IDENTIFIER_TYPE_VALUE (name) != type) { register tree d = NULL_TREE; int newdecl = 0, in_class = 0; + tree context; + tree c_decl = NULL_TREE; + + context = type ? TYPE_CONTEXT (type) : NULL_TREE; + if (! context) + { + tree cs = current_scope (); + + if (! globalize) + context = cs; + else if (cs != NULL_TREE + && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') + /* When declaring a friend class of a local class, we want + to inject the newly named class into the scope + containing the local class, not the namespace scope. */ + context = hack_decl_function_context (get_type_decl (cs)); + } + if (context) + c_decl = TREE_CODE (context) == FUNCTION_DECL + ? context : TYPE_MAIN_DECL (context); + + if (!context) + context = current_namespace; if ((b->pseudo_global && b->level_chain->parm_flag == 2) || b->parm_flag == 2) @@ -2732,7 +2740,6 @@ pushtag (name, type, globalize) } if (b->parm_flag == 2) { - TREE_NONLOCAL_FLAG (type) = 1; if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->tags; } @@ -4931,7 +4938,7 @@ storedecls (decls) /* Similarly, store the list of tags of the current level. */ -static void +void storetags (tags) tree tags; { diff --git a/gcc/cp/method.c b/gcc/cp/method.c index edb690f16b9..39f7f041937 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -2007,7 +2007,8 @@ hack_identifier (value, name) return error_mark_node; } } - else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) + else if (TREE_CODE (value) == TREE_LIST + && TREE_TYPE (value) == error_mark_node) { error ("request for member `%s' is ambiguous in multiple inheritance lattice", IDENTIFIER_POINTER (name)); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c061d72dca6..74b9c2de0ae 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1406,9 +1406,9 @@ lookup_member (xbasetype, name, protect, want_type) { if (lfi.ambiguous) { - /* This flag tells hack_identifier that the lookup is - ambiguous. */ - TREE_NONLOCAL_FLAG (lfi.ambiguous) = 1; + /* An ERROR_MARK for the TREE_TYPE tells hack_identifier + that the lookup is ambiguous. */ + TREE_TYPE (lfi.ambiguous) = error_mark_node; return scratch_tree_cons (error_mark_node, lfi.ambiguous, NULL_TREE); diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename20.C b/gcc/testsuite/g++.old-deja/g++.pt/typename20.C new file mode 100644 index 00000000000..0f6c4fc1ef4 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/typename20.C @@ -0,0 +1,16 @@ +// Build don't link: +// Origin: Mark Mitchell +// Special g++ Options: + +template +struct B { + typedef int I; +}; + +template +struct S : public B { + struct I { + }; + + void f(int i = true) {} +}; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename21.C b/gcc/testsuite/g++.old-deja/g++.pt/typename21.C new file mode 100644 index 00000000000..2dc52aa429a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/typename21.C @@ -0,0 +1,25 @@ +// Build don't link: +// Origin: Mark Mitchell +// Special g++ Options: + +template +struct S1 { + typedef T X; +}; + +template +struct B { + typedef T I; +}; + +template +struct S2 : public B { + struct I {}; + + typedef typename S1::X IX; + + void f(IX); +}; + +template +void S2::f(IX) {}