Commit 280f9385 by Mark Mitchell Committed by Mark Mitchell

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
parent 5e651bf2
1999-04-16 Mark Mitchell <mark@codesourcery.com> 1999-04-16 Mark Mitchell <mark@codesourcery.com>
* 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. * decl.c (warn_about_implicit_typename_lookup): New function.
(lookup_name_real): Use it. Rework handling of implicit typename (lookup_name_real): Use it. Rework handling of implicit typename
extension. extension.
......
...@@ -4185,10 +4185,6 @@ finish_struct (t, attributes, warn_anon) ...@@ -4185,10 +4185,6 @@ finish_struct (t, attributes, warn_anon)
as necessary. */ as necessary. */
unreverse_member_declarations (t); 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); cplus_decl_attributes (t, attributes, NULL_TREE);
if (processing_template_decl) if (processing_template_decl)
...@@ -4511,17 +4507,7 @@ pushclass (type, modify) ...@@ -4511,17 +4507,7 @@ pushclass (type, modify)
unuse_fields (type); unuse_fields (type);
} }
for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) storetags (CLASSTYPE_TAGS (type));
{
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);
}
} }
} }
...@@ -4541,11 +4527,6 @@ invalidate_class_lookup_cache () ...@@ -4541,11 +4527,6 @@ invalidate_class_lookup_cache ()
them. This is it! */ them. This is it! */
for (t = previous_class_values; t; t = TREE_CHAIN (t)) for (t = previous_class_values; t; t = TREE_CHAIN (t))
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; 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; previous_class_type = NULL_TREE;
} }
...@@ -4556,16 +4537,6 @@ invalidate_class_lookup_cache () ...@@ -4556,16 +4537,6 @@ invalidate_class_lookup_cache ()
void void
popclass () 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); poplevel (1, 0, 0);
/* Since poplevel_class does the popping of class decls nowadays, /* Since poplevel_class does the popping of class decls nowadays,
this really only frees the obstack used for these decls. */ this really only frees the obstack used for these decls. */
......
...@@ -23,8 +23,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -23,8 +23,7 @@ Boston, MA 02111-1307, USA. */
#define _CP_TREE_H #define _CP_TREE_H
/* Usage of TREE_LANG_FLAG_?: /* Usage of TREE_LANG_FLAG_?:
0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE). 0: BINFO_MARKED (BINFO nodes).
BINFO_MARKED (BINFO nodes).
COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT).
NEW_EXPR_USE_GLOBAL (in NEW_EXPR). NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
...@@ -803,9 +802,6 @@ struct lang_type ...@@ -803,9 +802,6 @@ struct lang_type
(TYPE_NEEDS_DESTRUCTOR (NODE) \ (TYPE_NEEDS_DESTRUCTOR (NODE) \
|| (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (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 /* Nonzero means that this _CLASSTYPE node defines ways of converting
itself to other types. */ itself to other types. */
#define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion) #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)); ...@@ -2885,6 +2881,7 @@ extern int push_class_binding PROTO((tree, tree));
extern tree check_default_argument PROTO((tree, tree)); extern tree check_default_argument PROTO((tree, tree));
extern tree push_overloaded_decl PROTO((tree, int)); extern tree push_overloaded_decl PROTO((tree, int));
extern void clear_identifier_class_values PROTO((void)); extern void clear_identifier_class_values PROTO((void));
extern void storetags PROTO((tree));
/* in decl2.c */ /* in decl2.c */
extern int check_java_method PROTO((tree)); extern int check_java_method PROTO((tree));
......
...@@ -148,7 +148,6 @@ static struct binding_level *make_binding_level PROTO((void)); ...@@ -148,7 +148,6 @@ static struct binding_level *make_binding_level PROTO((void));
static void declare_namespace_level PROTO((void)); static void declare_namespace_level PROTO((void));
static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN; static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN;
static void storedecls PROTO((tree)); static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static void require_complete_types_for_parms PROTO((tree)); static void require_complete_types_for_parms PROTO((tree));
static void push_overloaded_decl_1 PROTO((tree)); static void push_overloaded_decl_1 PROTO((tree));
static int ambi_op_p PROTO((tree)); static int ambi_op_p PROTO((tree));
...@@ -1231,19 +1230,29 @@ push_class_binding (id, decl) ...@@ -1231,19 +1230,29 @@ push_class_binding (id, decl)
binding = IDENTIFIER_BINDING (id); binding = IDENTIFIER_BINDING (id);
if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST) if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)
{ {
if (TREE_CODE (decl) == OVERLOAD) /* Any implicit typename must be from a base-class. The
context = DECL_REAL_CONTEXT (OVL_CURRENT (decl)); 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 else
{ {
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', if (TREE_CODE (decl) == OVERLOAD)
0); context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
context = DECL_REAL_CONTEXT (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)) if (is_properly_derived_from (current_class_type, context))
INHERITED_VALUE_BINDING_P (binding) = 1; INHERITED_VALUE_BINDING_P (binding) = 1;
else else
INHERITED_VALUE_BINDING_P (binding) = 0; INHERITED_VALUE_BINDING_P (binding) = 0;
}
} }
else if (BINDING_VALUE (binding) == decl) else if (BINDING_VALUE (binding) == decl)
/* We only encounter a TREE_LIST when push_class_decls detects an /* We only encounter a TREE_LIST when push_class_decls detects an
...@@ -2616,7 +2625,6 @@ maybe_process_template_type_declaration (type, globalize, b) ...@@ -2616,7 +2625,6 @@ maybe_process_template_type_declaration (type, globalize, b)
binding level, but is instead the pseudo-global level. */ binding level, but is instead the pseudo-global level. */
b->level_chain->tags = b->level_chain->tags =
saveable_tree_cons (name, type, 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) if (TYPE_SIZE (current_class_type) == NULL_TREE)
CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
} }
...@@ -2637,8 +2645,6 @@ pushtag (name, type, globalize) ...@@ -2637,8 +2645,6 @@ pushtag (name, type, globalize)
int globalize; int globalize;
{ {
register struct binding_level *b; register struct binding_level *b;
tree context = 0;
tree c_decl = 0;
b = current_binding_level; b = current_binding_level;
while (b->tag_transparent while (b->tag_transparent
...@@ -2652,32 +2658,34 @@ pushtag (name, type, globalize) ...@@ -2652,32 +2658,34 @@ pushtag (name, type, globalize)
if (name) 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. */ /* Do C++ gratuitous typedefing. */
if (IDENTIFIER_TYPE_VALUE (name) != type) if (IDENTIFIER_TYPE_VALUE (name) != type)
{ {
register tree d = NULL_TREE; register tree d = NULL_TREE;
int newdecl = 0, in_class = 0; 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) if ((b->pseudo_global && b->level_chain->parm_flag == 2)
|| b->parm_flag == 2) || b->parm_flag == 2)
...@@ -2732,7 +2740,6 @@ pushtag (name, type, globalize) ...@@ -2732,7 +2740,6 @@ pushtag (name, type, globalize)
} }
if (b->parm_flag == 2) if (b->parm_flag == 2)
{ {
TREE_NONLOCAL_FLAG (type) = 1;
if (TYPE_SIZE (current_class_type) == NULL_TREE) if (TYPE_SIZE (current_class_type) == NULL_TREE)
CLASSTYPE_TAGS (current_class_type) = b->tags; CLASSTYPE_TAGS (current_class_type) = b->tags;
} }
...@@ -4931,7 +4938,7 @@ storedecls (decls) ...@@ -4931,7 +4938,7 @@ storedecls (decls)
/* Similarly, store the list of tags of the current level. */ /* Similarly, store the list of tags of the current level. */
static void void
storetags (tags) storetags (tags)
tree tags; tree tags;
{ {
......
...@@ -2007,7 +2007,8 @@ hack_identifier (value, name) ...@@ -2007,7 +2007,8 @@ hack_identifier (value, name)
return error_mark_node; 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", error ("request for member `%s' is ambiguous in multiple inheritance lattice",
IDENTIFIER_POINTER (name)); IDENTIFIER_POINTER (name));
......
...@@ -1406,9 +1406,9 @@ lookup_member (xbasetype, name, protect, want_type) ...@@ -1406,9 +1406,9 @@ lookup_member (xbasetype, name, protect, want_type)
{ {
if (lfi.ambiguous) if (lfi.ambiguous)
{ {
/* This flag tells hack_identifier that the lookup is /* An ERROR_MARK for the TREE_TYPE tells hack_identifier
ambiguous. */ that the lookup is ambiguous. */
TREE_NONLOCAL_FLAG (lfi.ambiguous) = 1; TREE_TYPE (lfi.ambiguous) = error_mark_node;
return scratch_tree_cons (error_mark_node, return scratch_tree_cons (error_mark_node,
lfi.ambiguous, lfi.ambiguous,
NULL_TREE); NULL_TREE);
......
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
// Special g++ Options:
template <class T>
struct B {
typedef int I;
};
template <class T, class X = int>
struct S : public B <T> {
struct I {
};
void f(int i = true) {}
};
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
// Special g++ Options:
template <class T>
struct S1 {
typedef T X;
};
template <class T>
struct B {
typedef T I;
};
template <class T>
struct S2 : public B<T> {
struct I {};
typedef typename S1<I>::X IX;
void f(IX);
};
template <class T>
void S2<T>::f(IX) {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment