Commit 3e3f722c by Martin v. Löwis Committed by Jason Merrill

cp-tree.h (DECL_NAMESPACE_ALIAS, [...]): Declare.

	* cp-tree.h (DECL_NAMESPACE_ALIAS, ORIGINAL_NAMESPACE): Declare.
	* decl.c (lookup_name_real): Add namespaces_only parameter.
	If set, return only NAMESPACE_DECLs.
	(select_decl): Likewise.
	(identifier_type_value): Give additional parameter.
	(lookup_name_nonclass): Likewise.
	(lookup_name): Likewise.
	(find_binding): Skip namespace aliases.
	(binding_for_name): Likewise.
	(push_namespace): Check for namespace aliases.
	(lookup_name_namespace_only): New function.
	(begin_only_namespace_names, end_only_namespace_names): New functions.
	* decl2.c (set_decl_namespace): Skip namespace aliases.
	(do_using_directive): Likewise.
	(do_namespace_alias): Produce namespace aliases, fix alias
	redeclaration.
	* error.c (dump_decl): Support SCOPE_REF.
	* parse.y (extdef): Wrap lookup with namespace_only for namespace
	aliases and using declarations.

From-SVN: r20236
parent 122d34f6
1998-06-05 Martin v. Loewis <loewis@informatik.hu-berlin.de>
* cp-tree.h (DECL_NAMESPACE_ALIAS, ORIGINAL_NAMESPACE): Declare.
* decl.c (lookup_name_real): Add namespaces_only parameter.
If set, return only NAMESPACE_DECLs.
(select_decl): Likewise.
(identifier_type_value): Give additional parameter.
(lookup_name_nonclass): Likewise.
(lookup_name): Likewise.
(find_binding): Skip namespace aliases.
(binding_for_name): Likewise.
(push_namespace): Check for namespace aliases.
(lookup_name_namespace_only): New function.
(begin_only_namespace_names, end_only_namespace_names): New functions.
* decl2.c (set_decl_namespace): Skip namespace aliases.
(do_using_directive): Likewise.
(do_namespace_alias): Produce namespace aliases, fix alias
redeclaration.
* error.c (dump_decl): Support SCOPE_REF.
* parse.y (extdef): Wrap lookup with namespace_only for namespace
aliases and using declarations.
1998-06-04 Jason Merrill <jason@yorick.cygnus.com> 1998-06-04 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (really_overloaded_fn): Only see through one TREE_LIST. * tree.c (really_overloaded_fn): Only see through one TREE_LIST.
......
...@@ -1205,6 +1205,12 @@ struct lang_decl ...@@ -1205,6 +1205,12 @@ struct lang_decl
of a namespace, to record the transitive closure of using namespace. */ of a namespace, to record the transitive closure of using namespace. */
#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE) #define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE)
/* In a NAMESPACE_DECL, points to the original namespace if this is
a namespace alias. */
#define DECL_NAMESPACE_ALIAS(NODE) DECL_ABSTRACT_ORIGIN (NODE)
#define ORIGINAL_NAMESPACE(NODE) \
(DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE))
/* In a TREE_LIST concatenating using directives, indicate indirekt /* In a TREE_LIST concatenating using directives, indicate indirekt
directives */ directives */
#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0) #define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0)
...@@ -2354,6 +2360,9 @@ extern tree lookup_name_nonclass PROTO((tree)); ...@@ -2354,6 +2360,9 @@ extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree)); extern tree lookup_function_nonclass PROTO((tree, tree));
extern tree lookup_name PROTO((tree, int)); extern tree lookup_name PROTO((tree, int));
extern tree lookup_name_current_level PROTO((tree)); 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 lookup_using_namespace PROTO((tree,tree,tree,tree));
extern int qualified_lookup_using_namespace PROTO((tree,tree,tree)); extern int qualified_lookup_using_namespace PROTO((tree,tree,tree));
extern tree auto_function PROTO((tree, tree, enum built_in_function)); extern tree auto_function PROTO((tree, tree, enum built_in_function));
......
...@@ -157,7 +157,7 @@ static tree store_bindings PROTO((tree, tree)); ...@@ -157,7 +157,7 @@ static tree store_bindings PROTO((tree, tree));
static tree lookup_tag_reverse PROTO((tree, tree)); static tree lookup_tag_reverse PROTO((tree, tree));
static tree obscure_complex_init PROTO((tree, tree)); static tree obscure_complex_init PROTO((tree, tree));
static tree maybe_build_cleanup_1 PROTO((tree, tree)); static tree maybe_build_cleanup_1 PROTO((tree, tree));
static tree lookup_name_real PROTO((tree, int, int)); static tree lookup_name_real PROTO((tree, int, int, int));
static void warn_extern_redeclared_static PROTO((tree, tree)); static void warn_extern_redeclared_static PROTO((tree, tree));
static void grok_reference_init PROTO((tree, tree, tree)); static void grok_reference_init PROTO((tree, tree, tree));
static tree grokfndecl PROTO((tree, tree, tree, tree, int, static tree grokfndecl PROTO((tree, tree, tree, tree, int,
...@@ -331,6 +331,9 @@ tree vtbl_type_node; ...@@ -331,6 +331,9 @@ tree vtbl_type_node;
tree std_node; tree std_node;
int in_std = 0; int in_std = 0;
/* Expect only namespace names now. */
static int only_namespace_names;
/* In a destructor, the point at which all derived class destroying /* In a destructor, the point at which all derived class destroying
has been done, just before any base class destroying will be done. */ has been done, just before any base class destroying will be done. */
...@@ -1646,6 +1649,9 @@ find_binding (name, scope) ...@@ -1646,6 +1649,9 @@ find_binding (name, scope)
tree scope; tree scope;
{ {
tree iter, prev = NULL_TREE; tree iter, prev = NULL_TREE;
scope = ORIGINAL_NAMESPACE (scope);
for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter; for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
iter = TREE_CHAIN (iter)) iter = TREE_CHAIN (iter))
{ {
...@@ -1678,6 +1684,9 @@ binding_for_name (name, scope) ...@@ -1678,6 +1684,9 @@ binding_for_name (name, scope)
{ {
tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
tree result; tree result;
scope = ORIGINAL_NAMESPACE (scope);
if (b && TREE_CODE (b) != CPLUS_BINDING) if (b && TREE_CODE (b) != CPLUS_BINDING)
{ {
/* Get rid of optimization for global scope. */ /* Get rid of optimization for global scope. */
...@@ -1783,7 +1792,15 @@ push_namespace (name) ...@@ -1783,7 +1792,15 @@ push_namespace (name)
/* Check whether this is an extended namespace definition. */ /* Check whether this is an extended namespace definition. */
d = IDENTIFIER_NAMESPACE_VALUE (name); d = IDENTIFIER_NAMESPACE_VALUE (name);
if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
need_new = 0; {
need_new = 0;
if (DECL_NAMESPACE_ALIAS (d))
{
cp_error ("namespace alias `%D' not allowed here, assuming `%D'",
d, DECL_NAMESPACE_ALIAS (d));
d = DECL_NAMESPACE_ALIAS (d);
}
}
} }
if (need_new) if (need_new)
...@@ -2145,7 +2162,7 @@ identifier_type_value (id) ...@@ -2145,7 +2162,7 @@ identifier_type_value (id)
return REAL_IDENTIFIER_TYPE_VALUE (id); return REAL_IDENTIFIER_TYPE_VALUE (id);
/* Have to search for it. It must be on the global level, now. /* Have to search for it. It must be on the global level, now.
Ask lookup_name not to return non-types. */ Ask lookup_name not to return non-types. */
id = lookup_name_real (id, 2, 1); id = lookup_name_real (id, 2, 1, 0);
if (id) if (id)
return TREE_TYPE (id); return TREE_TYPE (id);
return NULL_TREE; return NULL_TREE;
...@@ -4680,12 +4697,20 @@ make_typename_type (context, name) ...@@ -4680,12 +4697,20 @@ make_typename_type (context, name)
/* Select the right _DECL from multiple choices. */ /* Select the right _DECL from multiple choices. */
static tree static tree
select_decl (binding, prefer_type) select_decl (binding, prefer_type, namespaces_only)
tree binding; tree binding;
int prefer_type; int prefer_type, namespaces_only;
{ {
tree val; tree val;
val = BINDING_VALUE (binding); val = BINDING_VALUE (binding);
if (namespaces_only)
{
/* We are not interested in types. */
if (val && TREE_CODE (val) == NAMESPACE_DECL)
return val;
return NULL_TREE;
}
/* If we could have a type and /* If we could have a type and
we have nothing or we need a type and have none. */ we have nothing or we need a type and have none. */
if (BINDING_TYPE (binding) if (BINDING_TYPE (binding)
...@@ -4713,15 +4738,19 @@ select_decl (binding, prefer_type) ...@@ -4713,15 +4738,19 @@ select_decl (binding, prefer_type)
using IDENTIFIER_CLASS_VALUE. */ using IDENTIFIER_CLASS_VALUE. */
static tree static tree
lookup_name_real (name, prefer_type, nonclass) lookup_name_real (name, prefer_type, nonclass, namespaces_only)
tree name; tree name;
int prefer_type, nonclass; int prefer_type, nonclass, namespaces_only;
{ {
register tree val; register tree val;
int yylex = 0; int yylex = 0;
tree from_obj = NULL_TREE; tree from_obj = NULL_TREE;
tree locval, classval; tree locval, classval;
/* Hack: copy flag set by parser, if set. */
if (only_namespace_names)
namespaces_only = 1;
if (prefer_type == -2) if (prefer_type == -2)
{ {
extern int looking_for_typename; extern int looking_for_typename;
...@@ -4756,7 +4785,7 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4756,7 +4785,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = binding_init (&b); val = binding_init (&b);
if (!qualified_lookup_using_namespace (name, type, val)) if (!qualified_lookup_using_namespace (name, type, val))
return NULL_TREE; return NULL_TREE;
val = select_decl (val, prefer_type); val = select_decl (val, prefer_type, namespaces_only);
} }
else if (! IS_AGGR_TYPE (type) else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TYPE_PARM
...@@ -4800,7 +4829,7 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4800,7 +4829,7 @@ lookup_name_real (name, prefer_type, nonclass)
locval = classval = NULL_TREE; locval = classval = NULL_TREE;
if (!current_binding_level->namespace_p if (!namespaces_only && !current_binding_level->namespace_p
&& IDENTIFIER_LOCAL_VALUE (name) && IDENTIFIER_LOCAL_VALUE (name)
/* Kludge to avoid infinite recursion with identifier_type_value. */ /* Kludge to avoid infinite recursion with identifier_type_value. */
&& (prefer_type <= 0 && (prefer_type <= 0
...@@ -4885,7 +4914,7 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4885,7 +4914,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = NULL_TREE; val = NULL_TREE;
break; break;
} }
val = select_decl (b, prefer_type); val = select_decl (b, prefer_type, namespaces_only);
if (scope == global_namespace) if (scope == global_namespace)
break; break;
scope = DECL_CONTEXT (scope); scope = DECL_CONTEXT (scope);
...@@ -4932,7 +4961,7 @@ tree ...@@ -4932,7 +4961,7 @@ tree
lookup_name_nonclass (name) lookup_name_nonclass (name)
tree name; tree name;
{ {
return lookup_name_real (name, 0, 1); return lookup_name_real (name, 0, 1, 0);
} }
tree tree
...@@ -4944,11 +4973,19 @@ lookup_function_nonclass (name, args) ...@@ -4944,11 +4973,19 @@ lookup_function_nonclass (name, args)
} }
tree tree
lookup_name_namespace_only (name)
tree name;
{
/* type-or-namespace, nonclass, namespace_only */
return lookup_name_real (name, 1, 1, 1);
}
tree
lookup_name (name, prefer_type) lookup_name (name, prefer_type)
tree name; tree name;
int prefer_type; int prefer_type;
{ {
return lookup_name_real (name, prefer_type, 0); return lookup_name_real (name, prefer_type, 0, 0);
} }
/* Similar to `lookup_name' but look only at current binding level. */ /* Similar to `lookup_name' but look only at current binding level. */
...@@ -4986,6 +5023,18 @@ lookup_name_current_level (name) ...@@ -4986,6 +5023,18 @@ lookup_name_current_level (name)
return t; return t;
} }
void
begin_only_namespace_names ()
{
only_namespace_names = 1;
}
void
end_only_namespace_names ()
{
only_namespace_names = 0;
}
/* Arrange for the user to get a source line number, even when the /* Arrange for the user to get a source line number, even when the
compiler is going down in flames, so that she at least has a compiler is going down in flames, so that she at least has a
......
...@@ -4003,6 +4003,9 @@ set_decl_namespace (decl, scope) ...@@ -4003,6 +4003,9 @@ set_decl_namespace (decl, scope)
tree old; tree old;
if (scope == std_node) if (scope == std_node)
scope = global_namespace; scope = global_namespace;
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
if (!is_namespace_ancestor (current_namespace, scope)) if (!is_namespace_ancestor (current_namespace, scope))
cp_error ("declaration of `%D' not in a namespace surrounding `%D'", cp_error ("declaration of `%D' not in a namespace surrounding `%D'",
decl, scope); decl, scope);
...@@ -4354,27 +4357,35 @@ do_namespace_alias (alias, namespace) ...@@ -4354,27 +4357,35 @@ do_namespace_alias (alias, namespace)
tree alias, namespace; tree alias, namespace;
{ {
tree binding; tree binding;
tree ns; tree old;
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
ns = lookup_name (namespace, 1); if (TREE_CODE (namespace) != NAMESPACE_DECL)
else
ns = namespace;
if (TREE_CODE (ns) != NAMESPACE_DECL)
{ {
cp_error ("`%D' is not a namespace", namespace); /* The parser did not find it, so it's not there. */
cp_error ("unknown namespace `%D'", namespace);
return; return;
} }
namespace = ORIGINAL_NAMESPACE (namespace);
binding = binding_for_name (alias, current_namespace); binding = binding_for_name (alias, current_namespace);
if (BINDING_VALUE (binding) && BINDING_VALUE (binding) != namespace) old = BINDING_VALUE (binding);
if (old)
{ {
if (TREE_CODE (old) == NAMESPACE_DECL
&& DECL_NAMESPACE_ALIAS (old) == namespace)
/* Ok: redeclaration. */
return;
cp_error ("invalid namespace alias `%D'", alias); cp_error ("invalid namespace alias `%D'", alias);
cp_error_at ("`%D' previously declared here", alias); cp_error_at ("`%D' previously declared here", old);
} }
else else
{ {
/* XXX the alias is not exactly identical to the name space, /* Build the alias. */
it must not be used in a using directive or namespace alias */ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
BINDING_VALUE (binding) = ns; DECL_NAMESPACE_ALIAS (alias) = namespace;
DECL_CONTEXT (alias) = current_namespace;
BINDING_VALUE (binding) = alias;
} }
} }
...@@ -4512,7 +4523,7 @@ do_using_directive (namespace) ...@@ -4512,7 +4523,7 @@ do_using_directive (namespace)
sorry ("using directives inside functions"); sorry ("using directives inside functions");
return; return;
} }
/* using A::B::C; */ /* using namespace A::B::C; */
if (TREE_CODE (namespace) == SCOPE_REF) if (TREE_CODE (namespace) == SCOPE_REF)
namespace = TREE_OPERAND (namespace, 1); namespace = TREE_OPERAND (namespace, 1);
if (TREE_CODE (namespace) == IDENTIFIER_NODE) if (TREE_CODE (namespace) == IDENTIFIER_NODE)
...@@ -4526,6 +4537,7 @@ do_using_directive (namespace) ...@@ -4526,6 +4537,7 @@ do_using_directive (namespace)
cp_error ("`%T' is not a namespace", namespace); cp_error ("`%T' is not a namespace", namespace);
return; return;
} }
namespace = ORIGINAL_NAMESPACE (namespace);
/* direct usage */ /* direct usage */
add_using_namespace (current_namespace, namespace, 0); add_using_namespace (current_namespace, namespace, 0);
} }
......
...@@ -39,18 +39,18 @@ typedef char* cp_printer (); ...@@ -39,18 +39,18 @@ typedef char* cp_printer ();
#define T type_as_string #define T type_as_string
#define V cv_as_string #define V cv_as_string
#define _ (cp_printer *) 0 #define o (cp_printer *) 0
cp_printer * cp_printers[256] = cp_printer * cp_printers[256] =
{ {
/*0 1 2 3 4 5 6 7 8 9 A B C D E F */ /*0 1 2 3 4 5 6 7 8 9 A B C D E F */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
_, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */ o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */
P, Q, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */ P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
}; };
#undef C #undef C
#undef D #undef D
...@@ -61,7 +61,7 @@ cp_printer * cp_printers[256] = ...@@ -61,7 +61,7 @@ cp_printer * cp_printers[256] =
#undef Q #undef Q
#undef T #undef T
#undef V #undef V
#undef _ #undef o
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
...@@ -726,6 +726,12 @@ dump_decl (t, v) ...@@ -726,6 +726,12 @@ dump_decl (t, v)
OB_PUTID (DECL_NAME (t)); OB_PUTID (DECL_NAME (t));
break; break;
case SCOPE_REF:
dump_decl (TREE_OPERAND (t, 0), 0);
OB_PUTS ("::");
dump_decl (TREE_OPERAND (t, 1), 0);
break;
case ARRAY_REF: case ARRAY_REF:
dump_decl (TREE_OPERAND (t, 0), v); dump_decl (TREE_OPERAND (t, 0), v);
OB_PUTC ('['); OB_PUTC ('[');
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -401,18 +401,28 @@ extdef: ...@@ -401,18 +401,28 @@ extdef:
{ push_namespace (NULL_TREE); } { push_namespace (NULL_TREE); }
extdefs_opt '}' extdefs_opt '}'
{ pop_namespace (); } { pop_namespace (); }
| NAMESPACE identifier '=' any_id ';' | NAMESPACE identifier '='
{ do_namespace_alias ($2, $4); } { begin_only_namespace_names (); }
any_id ';'
{
end_only_namespace_names ();
if (lastiddecl)
$5 = lastiddecl;
do_namespace_alias ($2, $5);
}
| using_decl ';' | using_decl ';'
{ do_toplevel_using_decl ($1); } { do_toplevel_using_decl ($1); }
| USING NAMESPACE any_id ';' | USING NAMESPACE
{ begin_only_namespace_names (); }
any_id ';'
{ {
end_only_namespace_names ();
/* If no declaration was found, the using-directive is /* If no declaration was found, the using-directive is
invalid. Since that was not reported, we need the invalid. Since that was not reported, we need the
identifier for the error message. */ identifier for the error message. */
if (TREE_CODE ($3) == IDENTIFIER_NODE && lastiddecl) if (TREE_CODE ($4) == IDENTIFIER_NODE && lastiddecl)
$3 = lastiddecl; $4 = lastiddecl;
do_using_directive ($3); do_using_directive ($4);
} }
| extension extdef | extension extdef
{ pedantic = $<itype>1; } { pedantic = $<itype>1; }
......
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