decl.c (qualify_lookup): New fn.

* decl.c (qualify_lookup): New fn.
	(lookup_name_real): Use it.
	* decl2.c (add_using_namespace): When directly using a namespace
	that was indirect before, promote it.
	* cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES,
	LOOKUP_PREFER_BOTH, LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY,
	LOOKUP_QUALIFIERS_ONLY, LOOKUP_TEMPLATES_EXPECTED): New macros.
	* decl.c (select_decl): Replace two flag parameters by one.
	(unqualified_namespace_lookup): Likewise, pass flag.
	(lookup_flags): New function.
	(lookup_name_real): Compute flags, pass them.
	(lookup_namespace_name): Call with zero-flag.
	* decl2.c (ambiguous_decl): Add flag parameter, complain only
	according to flags.
	(lookup_using_namespace, qualified_lookup_using_namespace):
	Add flag parameter, pass them through.
	* lex.c (do_scoped_id): Call with zero-flag.

From-SVN: r21218
This commit is contained in:
Jason Merrill 1998-07-16 12:38:26 -04:00
parent a942e89c9a
commit 52c11ef6a3
5 changed files with 183 additions and 68 deletions

View File

@ -1,3 +1,27 @@
1998-07-16 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (qualify_lookup): New fn.
(lookup_name_real): Use it.
1998-07-16 Martin v. Loewis <loewis@informatik.hu-berlin.de>
* decl2.c (add_using_namespace): When directly using a namespace
that was indirect before, promote it.
* cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES,
LOOKUP_PREFER_BOTH, LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY,
LOOKUP_QUALIFIERS_ONLY, LOOKUP_TEMPLATES_EXPECTED): New macros.
* decl.c (select_decl): Replace two flag parameters by one.
(unqualified_namespace_lookup): Likewise, pass flag.
(lookup_flags): New function.
(lookup_name_real): Compute flags, pass them.
(lookup_namespace_name): Call with zero-flag.
* decl2.c (ambiguous_decl): Add flag parameter, complain only
according to flags.
(lookup_using_namespace, qualified_lookup_using_namespace):
Add flag parameter, pass them through.
* lex.c (do_scoped_id): Call with zero-flag.
1998-07-16 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (convert_for_assignment): Use comptypes.

View File

@ -2174,7 +2174,16 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
LOOKUP_NO_CONVERSION means that user-defined conversions are not
permitted. Built-in conversions are permitted.
LOOKUP_DESTRUCTOR means explicit call to destructor.
LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references. */
LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
These are used in global lookup to support elaborated types and
qualifiers.
LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
LOOKUP_PREFER_BOTH means class-or-namespace-name.
LOOKUP_TEMPLATES_EXPECTED means that class templates also count
as types. */
#define LOOKUP_PROTECT (1)
#define LOOKUP_COMPLAIN (2)
@ -2189,6 +2198,17 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_NO_CONVERSION (512)
#define LOOKUP_DESTRUCTOR (512)
#define LOOKUP_NO_TEMP_BIND (1024)
#define LOOKUP_PREFER_TYPES (2048)
#define LOOKUP_PREFER_NAMESPACES (4096)
#define LOOKUP_PREFER_BOTH (6144)
#define LOOKUP_TEMPLATES_EXPECTED (8192)
#define LOOKUP_NAMESPACES_ONLY(f) \
(((f) & LOOKUP_PREFER_NAMESPACES) && !((f) & LOOKUP_PREFER_TYPES))
#define LOOKUP_TYPES_ONLY(f) \
(!((f) & LOOKUP_PREFER_NAMESPACES) && ((f) & LOOKUP_PREFER_TYPES))
#define LOOKUP_QUALIFIERS_ONLY(f) ((f) & LOOKUP_PREFER_BOTH)
/* These flags are used by the conversion code.
CONV_IMPLICIT : Perform implicit conversions (standard and user-defined).
@ -2386,8 +2406,8 @@ extern tree lookup_name_current_level PROTO((tree));
extern tree lookup_name_namespace_only PROTO((tree));
extern void begin_only_namespace_names PROTO((void));
extern void end_only_namespace_names PROTO((void));
extern int lookup_using_namespace PROTO((tree,tree,tree,tree));
extern int qualified_lookup_using_namespace PROTO((tree,tree,tree));
extern int lookup_using_namespace PROTO((tree,tree,tree,tree,int));
extern int qualified_lookup_using_namespace PROTO((tree,tree,tree,int));
extern tree auto_function PROTO((tree, tree, enum built_in_function));
extern void init_decl_processing PROTO((void));
extern int init_type_desc PROTO((void));

View File

@ -4646,7 +4646,7 @@ lookup_namespace_name (namespace, name)
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
val = binding_init (&_b);
if (!qualified_lookup_using_namespace (name, namespace, val))
if (!qualified_lookup_using_namespace (name, namespace, val, 0))
return error_mark_node;
if (BINDING_VALUE (val))
@ -4736,13 +4736,13 @@ make_typename_type (context, name)
/* Select the right _DECL from multiple choices. */
static tree
select_decl (binding, prefer_type, namespaces_only)
select_decl (binding, flags)
tree binding;
int prefer_type, namespaces_only;
int flags;
{
tree val;
val = BINDING_VALUE (binding);
if (namespaces_only)
if (LOOKUP_NAMESPACES_ONLY (flags))
{
/* We are not interested in types. */
if (val && TREE_CODE (val) == NAMESPACE_DECL)
@ -4753,10 +4753,11 @@ select_decl (binding, prefer_type, namespaces_only)
/* If we could have a type and
we have nothing or we need a type and have none. */
if (BINDING_TYPE (binding)
&& (!val || (prefer_type && TREE_CODE (val) != TYPE_DECL)))
&& (!val || ((flags & LOOKUP_PREFER_TYPES)
&& TREE_CODE (val) != TYPE_DECL)))
val = TYPE_STUB_DECL (BINDING_TYPE (binding));
/* Don't return non-types if we really prefer types. */
else if (val && prefer_type > 1 && TREE_CODE (val) != TYPE_DECL
else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL
&& (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL))
val = NULL_TREE;
return val;
@ -4766,10 +4767,9 @@ select_decl (binding, prefer_type, namespaces_only)
using namespace statements. */
static tree
unqualified_namespace_lookup (name, prefer_type, namespaces_only)
unqualified_namespace_lookup (name, flags)
tree name;
int prefer_type;
int namespaces_only;
int flags;
{
struct tree_binding _binding;
tree b = binding_init (&_binding);
@ -4791,7 +4791,8 @@ unqualified_namespace_lookup (name, prefer_type, namespaces_only)
for (level = current_binding_level;
!level->namespace_p;
level = level->level_chain)
if (!lookup_using_namespace (name, b, level->using_directives, scope))
if (!lookup_using_namespace (name, b, level->using_directives,
scope, flags))
/* Give up because of error. */
return NULL_TREE;
@ -4801,14 +4802,14 @@ unqualified_namespace_lookup (name, prefer_type, namespaces_only)
while (1)
{
if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter),
scope))
scope, flags))
/* Give up because of error. */
return NULL_TREE;
if (siter == scope) break;
siter = CP_DECL_CONTEXT (siter);
}
val = select_decl (b, prefer_type, namespaces_only);
val = select_decl (b, flags);
if (scope == global_namespace)
break;
scope = DECL_CONTEXT (scope);
@ -4818,6 +4819,38 @@ unqualified_namespace_lookup (name, prefer_type, namespaces_only)
return val;
}
/* Combine prefer_type and namespaces_only into flags. */
static int
lookup_flags (prefer_type, namespaces_only)
int prefer_type, namespaces_only;
{
if (namespaces_only)
return LOOKUP_PREFER_NAMESPACES;
if (prefer_type > 1)
return LOOKUP_PREFER_TYPES;
if (prefer_type > 0)
return LOOKUP_PREFER_BOTH;
return 0;
}
/* Given a lookup that returned VAL, use FLAGS to decide if we want to
ignore it or not. Subroutine of lookup_name_real. */
static tree
qualify_lookup (val, flags)
tree val;
int flags;
{
if (val == NULL_TREE)
return val;
if (LOOKUP_NAMESPACES_ONLY (flags) && TREE_CODE (val) != NAMESPACE_DECL)
return NULL_TREE;
if (LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL)
return NULL_TREE;
return val;
}
/* Look up NAME in the current binding level and its superiors in the
namespace of variables, functions and typedefs. Return a ..._DECL
node of some kind representing its definition if there is only one
@ -4841,11 +4874,12 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
int yylex = 0;
tree from_obj = NULL_TREE;
tree locval, classval;
int flags;
/* Hack: copy flag set by parser, if set. */
if (only_namespace_names)
namespaces_only = 1;
if (prefer_type == -2)
{
extern int looking_for_typename;
@ -4854,6 +4888,13 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
yylex = 1;
prefer_type = looking_for_typename;
flags = lookup_flags (prefer_type, namespaces_only);
/* During parsing, we need to complain. */
flags |= LOOKUP_COMPLAIN;
/* If the next thing is '<', class templates are types. */
if (looking_for_template)
flags |= LOOKUP_TEMPLATES_EXPECTED;
/* std:: becomes :: for now. */
if (got_scope == std_node)
got_scope = void_type_node;
@ -4879,9 +4920,9 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
{
struct tree_binding b;
val = binding_init (&b);
if (!qualified_lookup_using_namespace (name, type, val))
if (!qualified_lookup_using_namespace (name, type, val, flags))
return NULL_TREE;
val = select_decl (val, prefer_type, namespaces_only);
val = select_decl (val, flags);
}
else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
@ -4922,29 +4963,13 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
else if (got_object && val)
from_obj = val;
}
else
flags = lookup_flags (prefer_type, namespaces_only);
locval = classval = NULL_TREE;
if (!current_binding_level->namespace_p
&& IDENTIFIER_LOCAL_VALUE (name))
switch (TREE_CODE (IDENTIFIER_LOCAL_VALUE (name)))
{
case NAMESPACE_DECL:
/* A namespace is rejected only if we strictly require types. */
if (prefer_type <= 1)
locval = IDENTIFIER_LOCAL_VALUE (name);
break;
case TYPE_DECL:
/* A type is rejected only if we strictly require namespaces. */
if (!namespaces_only)
locval = IDENTIFIER_LOCAL_VALUE (name);
break;
default:
/* We require neither types or namespaces. */
if (!namespaces_only && prefer_type <= 0)
locval = IDENTIFIER_LOCAL_VALUE (name);
break;
}
if (! namespace_bindings_p ())
locval = qualify_lookup (IDENTIFIER_LOCAL_VALUE (name), flags);
/* In C++ class fields are between local and global scope,
just before the global scope. */
@ -4972,6 +4997,8 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
created the COMPONENT_REF or anything like that. */
if (classval == NULL_TREE)
classval = lookup_nested_field (name, ! yylex);
classval = qualify_lookup (classval, flags);
}
if (locval && classval)
@ -5003,7 +5030,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
else if (classval)
val = classval;
else
val = unqualified_namespace_lookup (name, prefer_type, namespaces_only);
val = unqualified_namespace_lookup (name, flags);
done:
if (val)

View File

@ -60,7 +60,7 @@ static void finish_sigtable_vardecl PROTO((tree, tree));
static int is_namespace_ancestor PROTO((tree, tree));
static tree namespace_ancestor PROTO((tree, tree));
static void add_using_namespace PROTO((tree, tree, int));
static tree ambiguous_decl PROTO((tree, tree, tree));
static tree ambiguous_decl PROTO((tree, tree, tree,int));
static tree build_anon_union_vars PROTO((tree, tree*, int, int));
static void check_decl_namespace PROTO((void));
@ -3857,15 +3857,21 @@ add_using_namespace (user, used, indirect)
tree used;
int indirect;
{
tree iter;
tree t;
/* Using oneself is a no-op. */
if (user == used)
return;
my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
/* Check if we already have this. */
if (purpose_member (used, DECL_NAMESPACE_USING (user)) != NULL_TREE)
return;
t = purpose_member (used, DECL_NAMESPACE_USING (user));
if (t != NULL_TREE)
{
if (!indirect)
/* Promote to direct usage. */
TREE_INDIRECT_USING (t) = 0;
return;
}
/* Add used to the user's using list. */
DECL_NAMESPACE_USING (user)
@ -3879,13 +3885,13 @@ add_using_namespace (user, used, indirect)
= perm_tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
/* Recursively add all namespaces used. */
for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
/* indirect usage */
add_using_namespace (user, TREE_PURPOSE (iter), 1);
add_using_namespace (user, TREE_PURPOSE (t), 1);
/* Tell everyone using us about the new used namespaces. */
for (iter = DECL_NAMESPACE_USERS (user); iter; iter = TREE_CHAIN (iter))
add_using_namespace (TREE_PURPOSE (iter), used, 1);
for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
add_using_namespace (TREE_PURPOSE (t), used, 1);
}
/* Combines two sets of overloaded functions into an OVERLOAD chain.
@ -3916,42 +3922,77 @@ merge_functions (s1, s2)
XXX I don't want to repeat the entire duplicate_decls here */
static tree
ambiguous_decl (name, old, new)
ambiguous_decl (name, old, new, flags)
tree name;
tree old;
tree new;
int flags;
{
tree val, type;
my_friendly_assert (old != NULL_TREE, 393);
/* Copy the value. */
val = BINDING_VALUE (new);
if (val)
switch (TREE_CODE (val))
{
case TEMPLATE_DECL:
/* If we expect types or namespaces, and not templates,
or this is not a template class. */
if (LOOKUP_QUALIFIERS_ONLY (flags)
&& (!(flags & LOOKUP_TEMPLATES_EXPECTED)
|| !DECL_CLASS_TEMPLATE_P (val)))
val = NULL_TREE;
break;
case TYPE_DECL:
if (LOOKUP_NAMESPACES_ONLY (flags))
val = NULL_TREE;
break;
case NAMESPACE_DECL:
if (LOOKUP_TYPES_ONLY (flags))
val = NULL_TREE;
break;
default:
if (LOOKUP_QUALIFIERS_ONLY (flags))
val = NULL_TREE;
}
if (!BINDING_VALUE (old))
BINDING_VALUE (old) = BINDING_VALUE (new);
else if (BINDING_VALUE (new)
&& BINDING_VALUE (new) != BINDING_VALUE (old))
BINDING_VALUE (old) = val;
else if (val && val != BINDING_VALUE (old))
{
if (is_overloaded_fn (BINDING_VALUE (old))
&& is_overloaded_fn (BINDING_VALUE (new)))
&& is_overloaded_fn (val))
{
BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old),
BINDING_VALUE (new));
val);
}
else
{
/* Some declarations are functions, some are not. */
cp_error ("use of `%D' is ambiguous", name);
cp_error_at (" first declared as `%#D' here", BINDING_VALUE (old));
cp_error_at (" also declared as `%#D' here", BINDING_VALUE (new));
if (flags & LOOKUP_COMPLAIN)
{
cp_error ("use of `%D' is ambiguous", name);
cp_error_at (" first declared as `%#D' here",
BINDING_VALUE (old));
cp_error_at (" also declared as `%#D' here", val);
}
return error_mark_node;
}
}
/* ... and copy the type. */
type = BINDING_TYPE (new);
if (LOOKUP_NAMESPACES_ONLY (flags))
type = NULL_TREE;
if (!BINDING_TYPE (old))
BINDING_TYPE (old) = BINDING_TYPE (new);
else if(BINDING_TYPE (new)
&& BINDING_TYPE (old) != BINDING_TYPE (new))
BINDING_TYPE (old) = type;
else if(type && BINDING_TYPE (old) != type)
{
cp_error ("`%D' denotes an ambiguous type",name);
cp_error_at ("first type here", BINDING_TYPE (old));
cp_error_at ("other type here", BINDING_TYPE (new));
if (flags & LOOKUP_COMPLAIN)
{
cp_error ("`%D' denotes an ambiguous type",name);
cp_error_at (" first type here", BINDING_TYPE (old));
cp_error_at (" other type here", type);
}
}
return old;
}
@ -3961,8 +4002,9 @@ ambiguous_decl (name, old, new)
Returns zero on errors. */
int
lookup_using_namespace (name, val, usings, scope)
lookup_using_namespace (name, val, usings, scope, flags)
tree name, val, usings, scope;
int flags;
{
tree iter;
tree val1;
@ -3973,7 +4015,7 @@ lookup_using_namespace (name, val, usings, scope)
{
val1 = binding_for_name (name, TREE_PURPOSE (iter));
/* Resolve ambiguities. */
val = ambiguous_decl (name, val, val1);
val = ambiguous_decl (name, val, val1, flags);
}
return val != error_mark_node;
}
@ -3984,10 +4026,11 @@ lookup_using_namespace (name, val, usings, scope)
or 0 on error. */
int
qualified_lookup_using_namespace (name, scope, result)
qualified_lookup_using_namespace (name, scope, result, flags)
tree name;
tree scope;
tree result;
int flags;
{
/* Maintain a list of namespaces visited... */
tree seen = NULL_TREE;
@ -3997,7 +4040,8 @@ qualified_lookup_using_namespace (name, scope, result)
while (scope && (result != error_mark_node))
{
seen = temp_tree_cons (scope, NULL_TREE, seen);
result = ambiguous_decl (name, result, binding_for_name (name, scope));
result = ambiguous_decl (name, result,
binding_for_name (name, scope), flags);
if (!BINDING_VALUE (result) && !BINDING_TYPE (result))
/* Consider using directives. */
for (usings = DECL_NAMESPACE_USING (scope); usings;
@ -4437,7 +4481,7 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
*newval = *newtype = NULL_TREE;
decls = binding_init (&_decls);
if (!qualified_lookup_using_namespace (name, scope, decls))
if (!qualified_lookup_using_namespace (name, scope, decls, 0))
/* Lookup error */
return;

View File

@ -3014,7 +3014,7 @@ do_scoped_id (token, parsing)
{
struct tree_binding _b;
id = binding_init (&_b);
if (!qualified_lookup_using_namespace (token, global_namespace, id))
if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
id = NULL_TREE;
else
id = BINDING_VALUE (id);