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>
* 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.
......
......@@ -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. */
......
......@@ -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));
......
......@@ -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,6 +1230,15 @@ push_class_binding (id, decl)
binding = IDENTIFIER_BINDING (id);
if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)
{
/* 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
{
if (TREE_CODE (decl) == OVERLOAD)
context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
else
......@@ -1245,6 +1253,7 @@ push_class_binding (id, decl)
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
ambiguity. Such an ambiguity can be overridden by a definition
......@@ -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,6 +2658,14 @@ pushtag (name, type, globalize)
if (name)
{
/* 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)
{
......@@ -2673,12 +2687,6 @@ pushtag (name, type, globalize)
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;
if ((b->pseudo_global && b->level_chain->parm_flag == 2)
|| b->parm_flag == 2)
in_class = 1;
......@@ -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;
{
......
......@@ -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));
......
......@@ -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);
......
// 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