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>
* tree.c (really_overloaded_fn): Only see through one TREE_LIST.
......
......@@ -1205,6 +1205,12 @@ struct lang_decl
of a namespace, to record the transitive closure of using namespace. */
#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
directives */
#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0)
......@@ -2354,6 +2360,9 @@ extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree));
extern tree lookup_name PROTO((tree, int));
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 tree auto_function PROTO((tree, tree, enum built_in_function));
......
......@@ -157,7 +157,7 @@ static tree store_bindings PROTO((tree, tree));
static tree lookup_tag_reverse PROTO((tree, tree));
static tree obscure_complex_init 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 grok_reference_init PROTO((tree, tree, tree));
static tree grokfndecl PROTO((tree, tree, tree, tree, int,
......@@ -331,6 +331,9 @@ tree vtbl_type_node;
tree std_node;
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
has been done, just before any base class destroying will be done. */
......@@ -1646,6 +1649,9 @@ find_binding (name, scope)
tree scope;
{
tree iter, prev = NULL_TREE;
scope = ORIGINAL_NAMESPACE (scope);
for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
iter = TREE_CHAIN (iter))
{
......@@ -1678,6 +1684,9 @@ binding_for_name (name, scope)
{
tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
tree result;
scope = ORIGINAL_NAMESPACE (scope);
if (b && TREE_CODE (b) != CPLUS_BINDING)
{
/* Get rid of optimization for global scope. */
......@@ -1783,7 +1792,15 @@ push_namespace (name)
/* Check whether this is an extended namespace definition. */
d = IDENTIFIER_NAMESPACE_VALUE (name);
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)
......@@ -2145,7 +2162,7 @@ identifier_type_value (id)
return REAL_IDENTIFIER_TYPE_VALUE (id);
/* Have to search for it. It must be on the global level, now.
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)
return TREE_TYPE (id);
return NULL_TREE;
......@@ -4680,12 +4697,20 @@ make_typename_type (context, name)
/* Select the right _DECL from multiple choices. */
static tree
select_decl (binding, prefer_type)
select_decl (binding, prefer_type, namespaces_only)
tree binding;
int prefer_type;
int prefer_type, namespaces_only;
{
tree val;
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
we have nothing or we need a type and have none. */
if (BINDING_TYPE (binding)
......@@ -4713,15 +4738,19 @@ select_decl (binding, prefer_type)
using IDENTIFIER_CLASS_VALUE. */
static tree
lookup_name_real (name, prefer_type, nonclass)
lookup_name_real (name, prefer_type, nonclass, namespaces_only)
tree name;
int prefer_type, nonclass;
int prefer_type, nonclass, namespaces_only;
{
register tree val;
int yylex = 0;
tree from_obj = NULL_TREE;
tree locval, classval;
/* Hack: copy flag set by parser, if set. */
if (only_namespace_names)
namespaces_only = 1;
if (prefer_type == -2)
{
extern int looking_for_typename;
......@@ -4756,7 +4785,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = binding_init (&b);
if (!qualified_lookup_using_namespace (name, type, val))
return NULL_TREE;
val = select_decl (val, prefer_type);
val = select_decl (val, prefer_type, namespaces_only);
}
else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
......@@ -4800,7 +4829,7 @@ lookup_name_real (name, prefer_type, nonclass)
locval = classval = NULL_TREE;
if (!current_binding_level->namespace_p
if (!namespaces_only && !current_binding_level->namespace_p
&& IDENTIFIER_LOCAL_VALUE (name)
/* Kludge to avoid infinite recursion with identifier_type_value. */
&& (prefer_type <= 0
......@@ -4885,7 +4914,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = NULL_TREE;
break;
}
val = select_decl (b, prefer_type);
val = select_decl (b, prefer_type, namespaces_only);
if (scope == global_namespace)
break;
scope = DECL_CONTEXT (scope);
......@@ -4932,7 +4961,7 @@ tree
lookup_name_nonclass (name)
tree name;
{
return lookup_name_real (name, 0, 1);
return lookup_name_real (name, 0, 1, 0);
}
tree
......@@ -4944,11 +4973,19 @@ lookup_function_nonclass (name, args)
}
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)
tree name;
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. */
......@@ -4986,6 +5023,18 @@ lookup_name_current_level (name)
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
compiler is going down in flames, so that she at least has a
......
......@@ -4003,6 +4003,9 @@ set_decl_namespace (decl, scope)
tree old;
if (scope == std_node)
scope = global_namespace;
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
if (!is_namespace_ancestor (current_namespace, scope))
cp_error ("declaration of `%D' not in a namespace surrounding `%D'",
decl, scope);
......@@ -4354,27 +4357,35 @@ do_namespace_alias (alias, namespace)
tree alias, namespace;
{
tree binding;
tree ns;
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
ns = lookup_name (namespace, 1);
else
ns = namespace;
if (TREE_CODE (ns) != NAMESPACE_DECL)
tree old;
if (TREE_CODE (namespace) != 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;
}
namespace = ORIGINAL_NAMESPACE (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_at ("`%D' previously declared here", alias);
cp_error_at ("`%D' previously declared here", old);
}
else
{
/* XXX the alias is not exactly identical to the name space,
it must not be used in a using directive or namespace alias */
BINDING_VALUE (binding) = ns;
/* Build the alias. */
alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
DECL_NAMESPACE_ALIAS (alias) = namespace;
DECL_CONTEXT (alias) = current_namespace;
BINDING_VALUE (binding) = alias;
}
}
......@@ -4512,7 +4523,7 @@ do_using_directive (namespace)
sorry ("using directives inside functions");
return;
}
/* using A::B::C; */
/* using namespace A::B::C; */
if (TREE_CODE (namespace) == SCOPE_REF)
namespace = TREE_OPERAND (namespace, 1);
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
......@@ -4526,6 +4537,7 @@ do_using_directive (namespace)
cp_error ("`%T' is not a namespace", namespace);
return;
}
namespace = ORIGINAL_NAMESPACE (namespace);
/* direct usage */
add_using_namespace (current_namespace, namespace, 0);
}
......
......@@ -39,18 +39,18 @@ typedef char* cp_printer ();
#define T type_as_string
#define V cv_as_string
#define _ (cp_printer *) 0
#define o (cp_printer *) 0
cp_printer * cp_printers[256] =
{
{
/*0 1 2 3 4 5 6 7 8 9 A B C D E F */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
_, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
P, Q, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */
P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
};
#undef C
#undef D
......@@ -61,7 +61,7 @@ cp_printer * cp_printers[256] =
#undef Q
#undef T
#undef V
#undef _
#undef o
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
......@@ -726,6 +726,12 @@ dump_decl (t, v)
OB_PUTID (DECL_NAME (t));
break;
case SCOPE_REF:
dump_decl (TREE_OPERAND (t, 0), 0);
OB_PUTS ("::");
dump_decl (TREE_OPERAND (t, 1), 0);
break;
case ARRAY_REF:
dump_decl (TREE_OPERAND (t, 0), v);
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:
{ push_namespace (NULL_TREE); }
extdefs_opt '}'
{ pop_namespace (); }
| NAMESPACE identifier '=' any_id ';'
{ do_namespace_alias ($2, $4); }
| NAMESPACE identifier '='
{ begin_only_namespace_names (); }
any_id ';'
{
end_only_namespace_names ();
if (lastiddecl)
$5 = lastiddecl;
do_namespace_alias ($2, $5);
}
| using_decl ';'
{ 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
invalid. Since that was not reported, we need the
identifier for the error message. */
if (TREE_CODE ($3) == IDENTIFIER_NODE && lastiddecl)
$3 = lastiddecl;
do_using_directive ($3);
if (TREE_CODE ($4) == IDENTIFIER_NODE && lastiddecl)
$4 = lastiddecl;
do_using_directive ($4);
}
| extension extdef
{ 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