Commit 30394414 by Jason Merrill

Partial implementation of namespaces.

	* decl.c (push_namespace): Handle redeclaration error.
	* cp-tree.h (IDENTIFIER_NAMESPACE_VALUE): New macro.
	(IDENTIFIER_NAMESPACE_BINDINGS): New macro.
	(NAMESPACE_BINDING): New macro.
	(IDENTIFIER_GLOBAL_VALUE): Use NAMESPACE_BINDING.
	* *.c: Use them.
	* pt.c (push_template_decl): Use innermost_args.
	* decl.c (get_unique_name): Tweak from earlier in the name.
	* cp-tree.def: Add CPLUS_BINDING node.
	* cp-tree.h (tree_binding): new struct
	(BINDING_SCOPE, BINDING_VALUE): new macros
	(current_namespace, global_namespace): declare extern
	(struct lang_decl_flags): new field in_namespace
	(DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): new macros
	(DECL_NAMESPACE, SET_DECL_NAMESPACE): new macros
	(TREE_INDIRECT_USING): new macro
	* decl2.c (current_namespace, global_namespace): Declare.  The
	value is a NAMESPACE_DECL now, not a TREE_LIST.
	(is_namespace_ancestor, namespace_ancestor):new static functions.
	(add_using_namespace, ambiguous_decl): likewise.
	(lookup_using_namespace): new support function for lookup_name.
	(qualified_lookup_using_namespace): new support function for
	do_scoped_id and lookup_namespace_name
	(get_namespace_id): mark as obsolete.
	(current_namespace_id): Likewise.
	(do_namespace_alias): Implement.
	(do_using_directive): Implement as call to add_using_namespace.
	* decl.c (binding_for_name): new function.
	(push_namespace, pop_namespace): implement.
	(push_decl): don't install a FUNCTION_DECL in the global branch.
	(lookup_namespace_name): implement using qualified lookup.
	(lookup_name_real): For global scoping, lookup in
	global_namespace. For namespace scoping, lookup in given
	namespace. For unscoped lookup, iterate over namespace,
	considering using directives.
	(init_decl_processing): initialize global_namespace.
	(grokvardecl): Build assembler name as static name for globals.
	(grokdeclarator): Remove old namespace mangling.
	(xref_tag): When installing a global binding for the
	tag, make sure we have an identifier.
	* method.c (build_overload_nested_name): mangle namespaces.
	(build_qualified_name): Likewise.
	(build_decl_overload_real): Likewise.
	* lex.c (build_lang_decl): set namespace for new declaration to
	current_namespace.
	(do_scoped_id): find global names in global or current
	namespace, or using qualified namespace lookup, depending on
	context.
	* init.c (build_member_call): When scope is namespace, use
	build_x_function_call instead.
	(build_offset_ref): When scope is namespace, collapse processing
	to lookup_namespace_name instead.
	* error.c (dump_decl): Support NAMESPACE_DECL.
	* decl.c (pushdecl): Bind globals to current namespace.
	(push_overloaded_decl): Likewise.
	(lookup_tag): Likewise.
	(lookup_name_current_level): Likewise.
	(xref_tag): Likewise.
	(start_function): Likewise.
	* lex.c (do_identifier): Likewise.
	(identifier_typedecl_value): Likewise.
	(real_yylex): Likewise.
	* method.c (do_inline_function_hair): Likewise.
	* parse.y (unscoped): Likewise.
	* pt.c (check_explicit_specialization): Likewise.
	(lookup_template_class): Likewise.
	* rtti.c (call_void_fn): Likewise.
	* sig.c (build_sigtable): Likewise.
	* ptree.c (lang_print_xnode): New function.

From-SVN: r18227
parent 8dfafd99
Wed Feb 25 00:35:33 1998 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (push_namespace): Handle redeclaration error.
* cp-tree.h (IDENTIFIER_NAMESPACE_VALUE): New macro.
(IDENTIFIER_NAMESPACE_BINDINGS): New macro.
(NAMESPACE_BINDING): New macro.
(IDENTIFIER_GLOBAL_VALUE): Use NAMESPACE_BINDING.
* *.c: Use them.
* pt.c (push_template_decl): Use innermost_args.
* decl.c (get_unique_name): Tweak from earlier in the name.
Tue Feb 24 22:15:04 1998 Martin von Loewis <loewis@informatik.hu-berlin.de>
* cp-tree.def: Add CPLUS_BINDING node.
* cp-tree.h (tree_binding): new struct
(BINDING_SCOPE, BINDING_VALUE): new macros
(current_namespace, global_namespace): declare extern
(struct lang_decl_flags): new field in_namespace
(DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): new macros
(DECL_NAMESPACE, SET_DECL_NAMESPACE): new macros
(TREE_INDIRECT_USING): new macro
* decl2.c (current_namespace, global_namespace): Declare. The
value is a NAMESPACE_DECL now, not a TREE_LIST.
(is_namespace_ancestor, namespace_ancestor):new static functions.
(add_using_namespace, ambiguous_decl): likewise.
(lookup_using_namespace): new support function for lookup_name.
(qualified_lookup_using_namespace): new support function for
do_scoped_id and lookup_namespace_name
(get_namespace_id): mark as obsolete.
(current_namespace_id): Likewise.
(do_namespace_alias): Implement.
(do_using_directive): Implement as call to add_using_namespace.
* decl.c (binding_for_name): new function.
(push_namespace, pop_namespace): implement.
(push_decl): don't install a FUNCTION_DECL in the global branch.
(lookup_namespace_name): implement using qualified lookup.
(lookup_name_real): For global scoping, lookup in
global_namespace. For namespace scoping, lookup in given
namespace. For unscoped lookup, iterate over namespace,
considering using directives.
(init_decl_processing): initialize global_namespace.
(grokvardecl): Build assembler name as static name for globals.
(grokdeclarator): Remove old namespace mangling.
(xref_tag): When installing a global binding for the
tag, make sure we have an identifier.
* method.c (build_overload_nested_name): mangle namespaces.
(build_qualified_name): Likewise.
(build_decl_overload_real): Likewise.
* lex.c (build_lang_decl): set namespace for new declaration to
current_namespace.
(do_scoped_id): find global names in global or current
namespace, or using qualified namespace lookup, depending on
context.
* init.c (build_member_call): When scope is namespace, use
build_x_function_call instead.
(build_offset_ref): When scope is namespace, collapse processing
to lookup_namespace_name instead.
* error.c (dump_decl): Support NAMESPACE_DECL.
* decl.c (pushdecl): Bind globals to current namespace.
(push_overloaded_decl): Likewise.
(lookup_tag): Likewise.
(lookup_name_current_level): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
* lex.c (do_identifier): Likewise.
(identifier_typedecl_value): Likewise.
(real_yylex): Likewise.
* method.c (do_inline_function_hair): Likewise.
* parse.y (unscoped): Likewise.
* pt.c (check_explicit_specialization): Likewise.
(lookup_template_class): Likewise.
* rtti.c (call_void_fn): Likewise.
* sig.c (build_sigtable): Likewise.
* ptree.c (lang_print_xnode): New function.
Tue Feb 24 01:40:24 1998 Jason Merrill <jason@yorick.cygnus.com> Tue Feb 24 01:40:24 1998 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): Don't instantiate if pedantic * pt.c (instantiate_class_template): Don't instantiate if pedantic
......
...@@ -169,6 +169,10 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2) ...@@ -169,6 +169,10 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
the template will will be an IDENTIFIER_NODE. */ the template will will be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* has two fields: scope and value */
/* XXX: could recycle some of the common fields */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
/* A whole bunch of tree codes for the initial, superficial parsing of /* A whole bunch of tree codes for the initial, superficial parsing of
templates. */ templates. */
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2) DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
......
...@@ -58,13 +58,28 @@ typedef struct ...@@ -58,13 +58,28 @@ typedef struct
tree decl; tree decl;
} template_parm_index; } template_parm_index;
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
#define NAMESPACE_BINDING(ID,NS) BINDING_VALUE (binding_for_name (ID, NS))
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
NAMESPACE_BINDING (NODE, global_namespace)
#define IDENTIFIER_NAMESPACE_VALUE(NODE) \
NAMESPACE_BINDING (NODE, current_namespace)
struct tree_binding
{
char common[sizeof (struct tree_common)];
tree scope;
tree value;
};
/* To identify to the debug emitters if it should pay attention to the /* To identify to the debug emitters if it should pay attention to the
flag `-Wtemplate-debugging'. */ flag `-Wtemplate-debugging'. */
#define HAVE_TEMPLATES 1 #define HAVE_TEMPLATES 1
/* Macros for access to language-specific slots in an identifier. */ /* Macros for access to language-specific slots in an identifier. */
#define IDENTIFIER_GLOBAL_VALUE(NODE) \ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
(((struct lang_identifier *)(NODE))->global_value) (((struct lang_identifier *)(NODE))->global_value)
#define IDENTIFIER_CLASS_VALUE(NODE) \ #define IDENTIFIER_CLASS_VALUE(NODE) \
(((struct lang_identifier *)(NODE))->class_value) (((struct lang_identifier *)(NODE))->class_value)
...@@ -161,6 +176,9 @@ extern int current_function_returns_value; ...@@ -161,6 +176,9 @@ extern int current_function_returns_value;
extern int current_function_returns_null; extern int current_function_returns_null;
extern tree current_function_return_value; extern tree current_function_return_value;
extern tree current_namespace;
extern tree global_namespace;
extern tree ridpointers[]; extern tree ridpointers[];
extern tree ansi_opname[]; extern tree ansi_opname[];
extern tree ansi_assopname[]; extern tree ansi_assopname[];
...@@ -967,6 +985,7 @@ struct lang_decl_flags ...@@ -967,6 +985,7 @@ struct lang_decl_flags
tree memfunc_pointer_to; tree memfunc_pointer_to;
tree template_info; tree template_info;
struct binding_level *level; struct binding_level *level;
tree in_namespace;
}; };
struct lang_decl struct lang_decl
...@@ -1071,7 +1090,7 @@ struct lang_decl ...@@ -1071,7 +1090,7 @@ struct lang_decl
/* The _TYPE context in which this _DECL appears. This field holds the /* The _TYPE context in which this _DECL appears. This field holds the
class where a virtual function instance is actually defined, and the class where a virtual function instance is actually defined, and the
lexical scope of a friend function defined in a class body. */ lexical scope of a friend function defined in a class body. */
#define DECL_CLASS_CONTEXT(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.context) #define DECL_CLASS_CONTEXT(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.context)
#define DECL_REAL_CONTEXT(NODE) \ #define DECL_REAL_CONTEXT(NODE) \
((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \ ((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \
...@@ -1079,12 +1098,24 @@ struct lang_decl ...@@ -1079,12 +1098,24 @@ struct lang_decl
/* For a FUNCTION_DECL: the chain through which the next method /* For a FUNCTION_DECL: the chain through which the next method
with the same name is found. We now use TREE_CHAIN to with the same name is found. We now use TREE_CHAIN to
walk through the methods in order of declaration. */ walk through the methods in order of declaration.
For a NAMESPACE_DECL: the list of using namespace directives
The PURPOSE is the used namespace, the value is the namespace
that is the common ancestor */
#if 1 #if 1
#define DECL_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->chain) #define DECL_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
#else #else
#define DECL_CHAIN(NODE) (TREE_CHAIN (NODE)) #define DECL_CHAIN(NODE) (TREE_CHAIN (NODE))
#endif #endif
#define DECL_NAMESPACE_USING(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users
of a namespace, to record the transitive closure of using namespace */
#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE)
/* In a TREE_LIST concatenating using directives, indicate indirekt
directives */
#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0)
/* In a VAR_DECL for a variable declared in a for statement, /* In a VAR_DECL for a variable declared in a for statement,
this is the shadowed (local) variable. */ this is the shadowed (local) variable. */
...@@ -1473,6 +1504,12 @@ extern int flag_new_for_scope; ...@@ -1473,6 +1504,12 @@ extern int flag_new_for_scope;
#define DECL_REALLY_EXTERN(NODE) \ #define DECL_REALLY_EXTERN(NODE) \
(DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
/* Records the namespace we are in */
#define DECL_NAMESPACE(NODE) \
(DECL_LANG_SPECIFIC (NODE) ? DECL_LANG_SPECIFIC (NODE)->decl_flags.in_namespace : 0)
#define SET_DECL_NAMESPACE(NODE, val) \
DECL_LANG_SPECIFIC (NODE)->decl_flags.in_namespace = val
/* Used to tell cp_finish_decl that it should approximate comdat linkage /* Used to tell cp_finish_decl that it should approximate comdat linkage
as best it can for this decl. */ as best it can for this decl. */
#define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat) #define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat)
...@@ -2122,11 +2159,14 @@ extern tree gettags PROTO((void)); ...@@ -2122,11 +2159,14 @@ extern tree gettags PROTO((void));
#if 0 #if 0
extern void set_current_level_tags_transparency PROTO((int)); extern void set_current_level_tags_transparency PROTO((int));
#endif #endif
extern tree binding_for_name PROTO((tree, tree));
extern tree lookup_namespace_name PROTO((tree, tree)); extern tree lookup_namespace_name PROTO((tree, tree));
extern tree make_typename_type PROTO((tree, tree)); extern tree make_typename_type PROTO((tree, tree));
extern tree lookup_name_nonclass PROTO((tree)); extern tree lookup_name_nonclass PROTO((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_using_namespace PROTO((tree,tree,tree,tree));
extern tree qualified_lookup_using_namespace PROTO((tree,tree));
extern tree auto_function PROTO((tree, tree, enum built_in_function)); extern tree auto_function PROTO((tree, tree, enum built_in_function));
extern void init_decl_processing PROTO((void)); extern void init_decl_processing PROTO((void));
extern int init_type_desc PROTO((void)); extern int init_type_desc PROTO((void));
...@@ -2375,6 +2415,7 @@ extern void synthesize_method PROTO((tree)); ...@@ -2375,6 +2415,7 @@ extern void synthesize_method PROTO((tree));
extern tree get_id_2 PROTO((char *, tree)); extern tree get_id_2 PROTO((char *, tree));
/* in pt.c */ /* in pt.c */
extern tree innermost_args PROTO ((tree, int));
extern tree tsubst PROTO ((tree, tree, tree)); extern tree tsubst PROTO ((tree, tree, tree));
extern tree tsubst_expr PROTO ((tree, tree, tree)); extern tree tsubst_expr PROTO ((tree, tree, tree));
extern tree tsubst_copy PROTO ((tree, tree, tree)); extern tree tsubst_copy PROTO ((tree, tree, tree));
......
...@@ -90,6 +90,12 @@ int at_eof; ...@@ -90,6 +90,12 @@ int at_eof;
/* Functions called along with real static constructors and destructors. */ /* Functions called along with real static constructors and destructors. */
tree static_ctors, static_dtors; tree static_ctors, static_dtors;
/* The current open namespace, and :: */
tree current_namespace;
tree global_namespace;
/* C (and C++) language-specific option variables. */ /* C (and C++) language-specific option variables. */
...@@ -2880,6 +2886,9 @@ get_sentry (base) ...@@ -2880,6 +2886,9 @@ get_sentry (base)
tree base; tree base;
{ {
tree sname = get_id_2 ("__sn", base); tree sname = get_id_2 ("__sn", base);
/* for struct X foo __attribute__((weak)), there is a counter
__snfoo. Since base is already an assembler name, sname should
be globally unique */
tree sentry = IDENTIFIER_GLOBAL_VALUE (sname); tree sentry = IDENTIFIER_GLOBAL_VALUE (sname);
if (! sentry) if (! sentry)
{ {
...@@ -3756,8 +3765,179 @@ check_cp_case_value (value) ...@@ -3756,8 +3765,179 @@ check_cp_case_value (value)
return value; return value;
} }
tree current_namespace; /* return 1 if root encloses child */
static int
is_namespace_ancestor (root, child)
tree root, child;
{
if (root == child)
return 1;
if (root == global_namespace)
return 1;
if (child == global_namespace)
return 0;
return is_namespace_ancestor (root, DECL_NAMESPACE (child));
}
/* return the namespace that is the common ancestor
of two given namespaces */
static tree
namespace_ancestor (ns1, ns2)
tree ns1, ns2;
{
if (is_namespace_ancestor (ns1, ns2))
return ns1;
return namespace_ancestor (DECL_NAMESPACE (ns1), ns2);
}
/* Insert used into the using list of user. Set indirect_flag if this
directive is not directly from the source. Also find the common
ancestor and let our users know about the new namespace */
static void
add_using_namespace (user, used, indirect)
tree user;
tree used;
int indirect;
{
tree iter;
/* 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;
/* add used to the user's using list */
DECL_NAMESPACE_USING (user)
= perm_tree_cons (used, namespace_ancestor (user, used),
DECL_NAMESPACE_USING (user));
TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
/* add user to the used's users list */
DECL_NAMESPACE_USERS (used)
= perm_tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
for (iter = DECL_NAMESPACE_USERS (user); iter; iter = TREE_CHAIN (iter))
/* indirect usage */
add_using_namespace (TREE_PURPOSE (iter), used, 1);
}
/* This should return an error not all definitions define functions.
It is not an error if we find two functions with exactly the
same signature, only if these are selected in overload resolution.
XXX Do we want to give *all* candidates in case of ambiguity?
XXX In what way should I treat extern declarations?
XXX I don't want to repeat the entire duplicate_decls here */
static tree
ambiguous_decl (name, val1, val2)
tree val1, val2;
{
my_friendly_assert (val1 != val2, 376);
if (is_overloaded_fn (val1) && is_overloaded_fn (val1))
{
/* now built a joint list of all overloaded declarations */
/* XXX if I chain'em together, they will be always considered
as overloaded */
sorry ("overloaded functions used from different namespaces");
}
cp_error ("ambiguous definition `%D' used", name);
cp_error_at ("first definition here", val1);
cp_error_at ("other definition here", val2);
return error_mark_node;
}
/* add the bindings of name in used namespaces to val
the using list is defined by current, and the lookup goes to scope */
tree
lookup_using_namespace (name, val, current, scope)
tree name, val, current, scope;
{
tree iter;
tree val1;
/* iterate over all namespaces from current to scope */
while (1)
{
/* iterate over all used namespaces in current, searching for
using directives of scope */
for (iter = DECL_NAMESPACE_USING (current);
iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope)
{
val1 = NAMESPACE_BINDING (name, TREE_PURPOSE (iter));
/* name not found in this space */
if (!val1)
continue;
/* first definition ever */
if (!val)
{
val = val1;
continue;
}
/* Hmmm. Ambiguity. As long as both are overloaded functions,
this is fine */
val = ambiguous_decl (name, val, val1);
if (val == error_mark_node)
break;
}
if (current == scope)
break;
current = DECL_NAMESPACE (current);
}
return val;
}
/* [namespace.qual] */
tree
qualified_lookup_using_namespace (name, scope)
tree name;
tree scope;
{
tree val = NULL_TREE;
tree val1;
/* maintain a list of namespaces visited */
tree seen = NULL_TREE;
/* and a list of namespace yet to see */
tree todo = NULL_TREE;
tree usings;
while (scope)
{
seen = temp_tree_cons (scope, NULL_TREE, seen);
val1 = NAMESPACE_BINDING (name, scope);
if (val1)
{
if (val)
{
val = ambiguous_decl (name, val, val1);
break;
}
else
val = val1;
}
else
/* consider using directives */
for (usings = DECL_NAMESPACE_USING (scope); usings;
usings = TREE_CHAIN (usings))
/* if this was a real directive, and we have not seen it */
if (!TREE_INDIRECT_USING (usings)
&& !purpose_member (seen, TREE_PURPOSE (usings)))
todo = temp_tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
if (todo)
{
scope = TREE_PURPOSE (todo);
todo = TREE_CHAIN (todo);
}
else
scope = NULL_TREE; /* if there never was a todo list */
}
return val;
}
#if 0
/* this is broken and should not be called anymore */
/* Get the inner part of a namespace id. It doesn't have any prefix, nor /* Get the inner part of a namespace id. It doesn't have any prefix, nor
postfix. Returns 0 if in global namespace. */ postfix. Returns 0 if in global namespace. */
...@@ -3789,12 +3969,35 @@ current_namespace_id (name) ...@@ -3789,12 +3969,35 @@ current_namespace_id (name)
IDENTIFIER_POINTER (name)); IDENTIFIER_POINTER (name));
return get_identifier (buf); return get_identifier (buf);
} }
#endif
void void
do_namespace_alias (alias, namespace) do_namespace_alias (alias, namespace)
tree alias, namespace; tree alias, namespace;
{ {
sorry ("namespace alias"); tree binding;
tree ns;
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
ns = lookup_name (namespace, 1);
else
ns = namespace;
if (TREE_CODE (ns) != NAMESPACE_DECL)
{
cp_error ("`%D' is not a namespace", namespace);
return;
}
binding = binding_for_name (alias, current_namespace);
if (BINDING_VALUE (binding) && BINDING_VALUE (binding) != namespace)
{
cp_error ("invalid namespace alias `%D'", alias);
cp_error_at ("`%D' previously declared here", alias);
}
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;
}
} }
void void
...@@ -3856,7 +4059,11 @@ do_using_directive (namespace) ...@@ -3856,7 +4059,11 @@ do_using_directive (namespace)
{ {
if (namespace == std_node) if (namespace == std_node)
return; return;
sorry ("using directive"); /* using A::B::C; */
if (TREE_CODE (namespace) == SCOPE_REF)
namespace = TREE_OPERAND (namespace, 1);
/* direct usage */
add_using_namespace (current_namespace, namespace, 0);
} }
void void
......
...@@ -697,6 +697,11 @@ dump_decl (t, v) ...@@ -697,6 +697,11 @@ dump_decl (t, v)
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
if (DECL_NAMESPACE (t) != global_namespace)
{
dump_decl (DECL_NAMESPACE (t), v);
OB_PUTC2 (':',':');
}
OB_PUTID (DECL_NAME (t)); OB_PUTID (DECL_NAME (t));
break; break;
......
...@@ -1703,6 +1703,9 @@ build_member_call (type, name, parmlist) ...@@ -1703,6 +1703,9 @@ build_member_call (type, name, parmlist)
if (type == std_node) if (type == std_node)
return build_x_function_call (do_scoped_id (name, 0), parmlist, return build_x_function_call (do_scoped_id (name, 0), parmlist,
current_class_ref); current_class_ref);
if (TREE_CODE (type) == NAMESPACE_DECL)
return build_x_function_call (lookup_namespace_name (type, name),
parmlist, current_class_ref);
if (TREE_CODE (name) != TEMPLATE_ID_EXPR) if (TREE_CODE (name) != TEMPLATE_ID_EXPR)
method_name = name; method_name = name;
...@@ -1840,20 +1843,8 @@ build_offset_ref (type, name) ...@@ -1840,20 +1843,8 @@ build_offset_ref (type, name)
return build_min_nt (SCOPE_REF, type, name); return build_min_nt (SCOPE_REF, type, name);
/* Handle namespace names fully here. */ /* Handle namespace names fully here. */
if (TREE_CODE (type) == IDENTIFIER_NODE if (TREE_CODE (type) == NAMESPACE_DECL)
&& get_aggr_from_typedef (type, 0) == 0) return lookup_namespace_name (type, name);
{
tree ns = lookup_name (type, 0);
tree val;
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
{
val = lookup_namespace_name (ns, name);
if (val)
return val;
cp_error ("namespace `%D' has no member named `%D'", ns, name);
return error_mark_node;
}
}
if (type == NULL_TREE || ! is_aggr_type (type, 1)) if (type == NULL_TREE || ! is_aggr_type (type, 1))
return error_mark_node; return error_mark_node;
......
...@@ -2800,7 +2800,7 @@ do_identifier (token, parsing) ...@@ -2800,7 +2800,7 @@ do_identifier (token, parsing)
yychar = yylex (); yychar = yylex ();
/* Scope class declarations before global /* Scope class declarations before global
declarations. */ declarations. */
if (id == IDENTIFIER_GLOBAL_VALUE (token) if (id == IDENTIFIER_NAMESPACE_VALUE (token)
&& current_class_type != 0 && current_class_type != 0
&& TYPE_SIZE (current_class_type) == 0) && TYPE_SIZE (current_class_type) == 0)
{ {
...@@ -2868,7 +2868,7 @@ do_identifier (token, parsing) ...@@ -2868,7 +2868,7 @@ do_identifier (token, parsing)
} }
else else
{ {
if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
{ {
static int undeclared_variable_notice; static int undeclared_variable_notice;
...@@ -2884,7 +2884,7 @@ do_identifier (token, parsing) ...@@ -2884,7 +2884,7 @@ do_identifier (token, parsing)
} }
id = error_mark_node; id = error_mark_node;
/* Prevent repeated error messages. */ /* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node; IDENTIFIER_NAMESPACE_VALUE (token) = error_mark_node;
SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
} }
} }
...@@ -2896,7 +2896,7 @@ do_identifier (token, parsing) ...@@ -2896,7 +2896,7 @@ do_identifier (token, parsing)
&& DECL_DEAD_FOR_LOCAL (shadowed)) && DECL_DEAD_FOR_LOCAL (shadowed))
shadowed = DECL_SHADOWED_FOR_VAR (shadowed); shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
if (!shadowed) if (!shadowed)
shadowed = IDENTIFIER_GLOBAL_VALUE (DECL_NAME (id)); shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
if (shadowed) if (shadowed)
{ {
if (!DECL_ERROR_REPORTED (id)) if (!DECL_ERROR_REPORTED (id))
...@@ -2953,7 +2953,7 @@ do_identifier (token, parsing) ...@@ -2953,7 +2953,7 @@ do_identifier (token, parsing)
{ {
tree t = build_min (LOOKUP_EXPR, unknown_type_node, tree t = build_min (LOOKUP_EXPR, unknown_type_node,
token, get_first_fn (id)); token, get_first_fn (id));
if (id != IDENTIFIER_GLOBAL_VALUE (token)) if (id != IDENTIFIER_NAMESPACE_VALUE (token))
TREE_OPERAND (t, 1) = error_mark_node; TREE_OPERAND (t, 1) = error_mark_node;
id = t; id = t;
} }
...@@ -2971,7 +2971,12 @@ do_scoped_id (token, parsing) ...@@ -2971,7 +2971,12 @@ do_scoped_id (token, parsing)
tree token; tree token;
int parsing; int parsing;
{ {
tree id = IDENTIFIER_GLOBAL_VALUE (token); tree id;
/* during parsing, this is ::name. Otherwise, it is black magic. */
if (parsing)
id = qualified_lookup_using_namespace (token, global_namespace);
else
id = IDENTIFIER_GLOBAL_VALUE (token);
if (parsing && yychar == YYEMPTY) if (parsing && yychar == YYEMPTY)
yychar = yylex (); yychar = yylex ();
if (! id) if (! id)
...@@ -2986,12 +2991,12 @@ do_scoped_id (token, parsing) ...@@ -2986,12 +2991,12 @@ do_scoped_id (token, parsing)
id = implicitly_declare (token); id = implicitly_declare (token);
else else
{ {
if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node) if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
error ("undeclared variable `%s' (first use here)", error ("undeclared variable `%s' (first use here)",
IDENTIFIER_POINTER (token)); IDENTIFIER_POINTER (token));
id = error_mark_node; id = error_mark_node;
/* Prevent repeated error messages. */ /* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node; IDENTIFIER_NAMESPACE_VALUE (token) = error_mark_node;
} }
} }
else else
...@@ -3040,7 +3045,7 @@ identifier_typedecl_value (node) ...@@ -3040,7 +3045,7 @@ identifier_typedecl_value (node)
} }
do (IDENTIFIER_LOCAL_VALUE (node)); do (IDENTIFIER_LOCAL_VALUE (node));
do (IDENTIFIER_CLASS_VALUE (node)); do (IDENTIFIER_CLASS_VALUE (node));
do (IDENTIFIER_GLOBAL_VALUE (node)); do (IDENTIFIER_NAMESPACE_VALUE (node));
#undef do #undef do
/* Will this one ever happen? */ /* Will this one ever happen? */
if (TYPE_MAIN_DECL (type)) if (TYPE_MAIN_DECL (type))
...@@ -4376,6 +4381,8 @@ build_lang_decl (code, name, type) ...@@ -4376,6 +4381,8 @@ build_lang_decl (code, name, type)
DECL_LANGUAGE (t) = lang_c; DECL_LANGUAGE (t) = lang_c;
else my_friendly_abort (64); else my_friendly_abort (64);
SET_DECL_NAMESPACE (t, current_namespace);
#if 0 /* not yet, should get fixed properly later */ #if 0 /* not yet, should get fixed properly later */
if (code == TYPE_DECL) if (code == TYPE_DECL)
{ {
......
...@@ -537,7 +537,14 @@ build_overload_nested_name (decl) ...@@ -537,7 +537,14 @@ build_overload_nested_name (decl)
} }
} }
} }
else if (decl == global_namespace)
return;
else if (DECL_NAMESPACE (decl))
build_overload_nested_name (DECL_NAMESPACE (decl));
else
/* XXX the above does not work for non-namespaces */
if (current_namespace && TREE_CODE (decl) != NAMESPACE_DECL)
build_overload_nested_name (current_namespace);
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
{ {
...@@ -553,6 +560,8 @@ build_overload_nested_name (decl) ...@@ -553,6 +560,8 @@ build_overload_nested_name (decl)
OB_PUTCP (label); OB_PUTCP (label);
numeric_output_need_bar = 1; numeric_output_need_bar = 1;
} }
else if (TREE_CODE (decl) == NAMESPACE_DECL)
build_overload_identifier (DECL_NAME (decl));
else /* TYPE_DECL */ else /* TYPE_DECL */
build_overload_identifier (decl); build_overload_identifier (decl);
} }
...@@ -969,16 +978,37 @@ build_qualified_name (decl) ...@@ -969,16 +978,37 @@ build_qualified_name (decl)
context = decl; context = decl;
/* if we can't find a Ktype, do it the hard way */ /* if we can't find a Ktype, do it the hard way */
if (check_ktype (context, FALSE) == -1) if (check_ktype (context, FALSE) == -1)
while (DECL_CONTEXT (context)) {
{ /* count type scopes */
i += 1; while (DECL_CONTEXT (context))
context = DECL_CONTEXT (context); {
if (check_ktype (context, FALSE) != -1) /* found it! */ i += 1;
break; context = DECL_CONTEXT (context);
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') if (check_ktype (context, FALSE) != -1) /* found it! */
context = TYPE_NAME (context); break;
} if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
context = TYPE_NAME (context);
}
/* now count namespace scopes */
if (TREE_CODE (decl) == NAMESPACE_DECL)
{
i = 0; /* we have nothing done, yet: reset */
context = decl;
}
else
/* decl must be a type, which we have to scope with the
namespace */
{
/* XXX MvL somehow, types have no lang_decl, so no namespace */
context = current_namespace;
}
}
while (context != global_namespace)
{
i += 1;
context = DECL_NAMESPACE (context);
}
if (i > 1) if (i > 1)
{ {
...@@ -1515,7 +1545,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, ...@@ -1515,7 +1545,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
} }
else if (tparms) else if (tparms)
OB_PUTC ('H'); OB_PUTC ('H');
else /* XXX this works only if we call this in the same namespace
as the declaration. Unfortunately, we don't have the _DECL,
only its name */
else if (current_namespace == global_namespace)
OB_PUTC ('F'); OB_PUTC ('F');
if (tparms) if (tparms)
...@@ -1524,6 +1557,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, ...@@ -1524,6 +1557,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
OB_PUTC ('_'); OB_PUTC ('_');
} }
/* qualify with namespace */
if (!for_method && current_namespace != global_namespace)
build_qualified_name (current_namespace);
if (parms == NULL_TREE) if (parms == NULL_TREE)
OB_PUTC ('e'); OB_PUTC ('e');
else if (parms == void_list_node) else if (parms == void_list_node)
...@@ -1552,7 +1589,14 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, ...@@ -1552,7 +1589,14 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
OB_PUTC ('e'); OB_PUTC ('e');
} }
else else
build_mangled_name (parms, 0, 0); {
/* the namespace qualifier for a global function
will count as type */
if (current_namespace != global_namespace
&& !flag_do_squangling)
typevec[maxtype++] = current_namespace;
build_mangled_name (parms, 0, 0);
}
if (!flag_do_squangling) /* Deallocate typevec array */ if (!flag_do_squangling) /* Deallocate typevec array */
{ {
......
...@@ -788,7 +788,7 @@ check_explicit_specialization (declarator, decl, template_count, flags) ...@@ -788,7 +788,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE,
0); 0);
if (!ctype) if (!ctype)
fns = IDENTIFIER_GLOBAL_VALUE (dname); fns = IDENTIFIER_NAMESPACE_VALUE (dname);
else else
fns = dname; fns = dname;
...@@ -1465,7 +1465,7 @@ push_template_decl (decl) ...@@ -1465,7 +1465,7 @@ push_template_decl (decl)
} }
} }
/* Get the innermost set of template arguments. */ /* Get the innermost set of template arguments. */
args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); args = innermost_args (args, 0);
DECL_TEMPLATE_RESULT (tmpl) = decl; DECL_TEMPLATE_RESULT (tmpl) = decl;
TREE_TYPE (tmpl) = TREE_TYPE (decl); TREE_TYPE (tmpl) = TREE_TYPE (decl);
...@@ -2359,7 +2359,7 @@ lookup_template_class (d1, arglist, in_decl, context) ...@@ -2359,7 +2359,7 @@ lookup_template_class (d1, arglist, in_decl, context)
template = IDENTIFIER_LOCAL_VALUE (d1); template = IDENTIFIER_LOCAL_VALUE (d1);
else else
{ {
template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */ template = IDENTIFIER_NAMESPACE_VALUE (d1); /* XXX */
if (! template) if (! template)
template = IDENTIFIER_CLASS_VALUE (d1); template = IDENTIFIER_CLASS_VALUE (d1);
} }
......
...@@ -163,3 +163,21 @@ print_lang_identifier (file, node, indent) ...@@ -163,3 +163,21 @@ print_lang_identifier (file, node, indent)
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4); print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
} }
void
lang_print_xnode (file, node, indent)
FILE *file;
tree node;
int indent;
{
switch (TREE_CODE (node))
{
case CPLUS_BINDING:
print_node (file, "scope", BINDING_SCOPE (node), indent+4);
print_node (file, "value", BINDING_VALUE (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);
break;
default:
break;
}
}
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