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));
......
...@@ -63,6 +63,9 @@ extern tree static_ctors, static_dtors; ...@@ -63,6 +63,9 @@ extern tree static_ctors, static_dtors;
extern int static_labelno; extern int static_labelno;
extern tree current_namespace;
extern tree global_namespace;
/* Stack of places to restore the search obstack back to. */ /* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like /* Obstack used for remembering local class declarations (like
...@@ -1664,6 +1667,34 @@ print_binding_stack () ...@@ -1664,6 +1667,34 @@ print_binding_stack ()
print_binding_level (global_binding_level); print_binding_level (global_binding_level);
} }
/* Return the tree_binding for the name in the given scope
If there are no bindings for the name in the scope, make a new
bindings node. This bindings list of this node will be empty, though. */
tree
binding_for_name (name, scope)
tree name;
tree scope;
{
tree iter;
for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
iter = TREE_CHAIN (iter))
{
my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
return iter;
}
/* not found, make a new permanent one */
push_obstacks (&permanent_obstack, &permanent_obstack);
iter = make_node (CPLUS_BINDING);
TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
BINDING_SCOPE (iter) = scope;
BINDING_VALUE (iter) = NULL_TREE;
pop_obstacks ();
return iter;
}
extern char * first_global_object_name; extern char * first_global_object_name;
/* Get a unique name for each call to this routine for unnamed namespaces. /* Get a unique name for each call to this routine for unnamed namespaces.
...@@ -1692,7 +1723,7 @@ get_unique_name () ...@@ -1692,7 +1723,7 @@ get_unique_name ()
/* Don't need to pull weird characters out of global names. */ /* Don't need to pull weird characters out of global names. */
if (p != first_global_object_name) if (p != first_global_object_name)
{ {
for (p = buf+11; *p; p++) for (p = buf+2; *p; p++)
if (! ((*p >= '0' && *p <= '9') if (! ((*p >= '0' && *p <= '9')
#ifndef NO_DOLLAR_IN_LABEL /* this for `$'; unlikely, but... -- kr */ #ifndef NO_DOLLAR_IN_LABEL /* this for `$'; unlikely, but... -- kr */
|| *p == '$' || *p == '$'
...@@ -1716,13 +1747,42 @@ push_namespace (name) ...@@ -1716,13 +1747,42 @@ push_namespace (name)
tree name; tree name;
{ {
#if 1 #if 1
static int warned; tree d;
if (! warned) int need_new = 1;
sorry ("namespace"); int implicit_use = 0;
int nodecl = 0;
if (!global_namespace)
{
/* this must be :: */
my_friendly_assert (name == get_identifier ("::"), 377);
nodecl = 1;
}
else if (!name)
{
name = get_unique_name ();
implicit_use = 1;
}
else
{
/* 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;
}
warned = 1; if (need_new)
{
/* make a new namespace, binding the name to it */
d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
if (!nodecl)
d = pushdecl (d);
}
if (implicit_use)
do_using_directive (d);
/* enter the name space */
current_namespace = d;
#else #else
extern tree current_namespace;
tree old_id = get_namespace_id (); tree old_id = get_namespace_id ();
char *buf; char *buf;
tree d; tree d;
...@@ -1766,8 +1826,9 @@ push_namespace (name) ...@@ -1766,8 +1826,9 @@ push_namespace (name)
void void
pop_namespace () pop_namespace ()
{ {
#if 0 #if 1
extern tree current_namespace; current_namespace = DECL_NAMESPACE (current_namespace);
#else
tree decls, link; tree decls, link;
current_namespace = TREE_CHAIN (current_namespace); current_namespace = TREE_CHAIN (current_namespace);
...@@ -3242,11 +3303,12 @@ pushdecl (x) ...@@ -3242,11 +3303,12 @@ pushdecl (x)
if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL) if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
{ {
tree decl; tree decl;
tree bindings = binding_for_name (name, current_namespace);
if (IDENTIFIER_GLOBAL_VALUE (name) != NULL_TREE if (BINDING_VALUE (bindings) != NULL_TREE
&& (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) && (DECL_EXTERNAL (BINDING_VALUE (bindings))
|| TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name)))) || TREE_PUBLIC (BINDING_VALUE (bindings))))
decl = IDENTIFIER_GLOBAL_VALUE (name); decl = BINDING_VALUE (bindings);
else else
decl = NULL_TREE; decl = NULL_TREE;
...@@ -3265,10 +3327,11 @@ pushdecl (x) ...@@ -3265,10 +3327,11 @@ pushdecl (x)
if (b == global_binding_level) if (b == global_binding_level)
{ {
/* Install a global value. */ /* Install a global value. */
tree bindings = binding_for_name (name, current_namespace);
/* If the first global decl has external linkage, /* If the first global decl has external linkage,
warn if we later see static one. */ warn if we later see static one. */
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x)) if (BINDING_VALUE (bindings) == NULL_TREE && TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1; TREE_PUBLIC (name) = 1;
/* Don't install an artificial TYPE_DECL if we already have /* Don't install an artificial TYPE_DECL if we already have
...@@ -3276,7 +3339,12 @@ pushdecl (x) ...@@ -3276,7 +3339,12 @@ pushdecl (x)
if (TREE_CODE (x) != TYPE_DECL if (TREE_CODE (x) != TYPE_DECL
|| t == NULL_TREE || t == NULL_TREE
|| ! DECL_ARTIFICIAL (x)) || ! DECL_ARTIFICIAL (x))
IDENTIFIER_GLOBAL_VALUE (name) = x; {
if (TREE_CODE (x) == FUNCTION_DECL)
my_friendly_assert ((BINDING_VALUE (bindings) == NULL_TREE)
|| BINDING_VALUE (bindings) == x, 378);
BINDING_VALUE (bindings) = x;
}
/* Don't forget if the function was used via an implicit decl. */ /* Don't forget if the function was used via an implicit decl. */
if (IDENTIFIER_IMPLICIT_DECL (name) if (IDENTIFIER_IMPLICIT_DECL (name)
...@@ -3305,7 +3373,7 @@ pushdecl (x) ...@@ -3305,7 +3373,7 @@ pushdecl (x)
{ {
/* Here to install a non-global value. */ /* Here to install a non-global value. */
tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name); tree oldglobal = binding_for_name (name, current_namespace);
/* Don't install an artificial TYPE_DECL if we already have /* Don't install an artificial TYPE_DECL if we already have
another _DECL with that name. */ another _DECL with that name. */
...@@ -3331,24 +3399,24 @@ pushdecl (x) ...@@ -3331,24 +3399,24 @@ pushdecl (x)
have a global definition or declaration for the function. */ have a global definition or declaration for the function. */
if (oldlocal == NULL_TREE if (oldlocal == NULL_TREE
&& DECL_EXTERNAL (x) && DECL_EXTERNAL (x)
&& oldglobal != NULL_TREE && BINDING_VALUE (oldglobal) != NULL_TREE
&& TREE_CODE (x) == FUNCTION_DECL && TREE_CODE (x) == FUNCTION_DECL
&& TREE_CODE (oldglobal) == FUNCTION_DECL) && TREE_CODE (BINDING_VALUE (oldglobal)) == FUNCTION_DECL)
{ {
/* We have one. Their types must agree. */ /* We have one. Their types must agree. */
if (decls_match (x, oldglobal)) if (decls_match (x, BINDING_VALUE (oldglobal)))
/* OK */; /* OK */;
else else
{ {
cp_warning ("extern declaration of `%#D' doesn't match", x); cp_warning ("extern declaration of `%#D' doesn't match", x);
cp_warning_at ("global declaration `%#D'", oldglobal); cp_warning_at ("global declaration `%#D'", BINDING_VALUE (oldglobal));
} }
} }
/* If we have a local external declaration, /* If we have a local external declaration,
and no file-scope declaration has yet been seen, and no file-scope declaration has yet been seen,
then if we later have a file-scope decl it must not be static. */ then if we later have a file-scope decl it must not be static. */
if (oldlocal == NULL_TREE if (oldlocal == NULL_TREE
&& oldglobal == NULL_TREE && BINDING_VALUE (oldglobal) == NULL_TREE
&& DECL_EXTERNAL (x) && DECL_EXTERNAL (x)
&& TREE_PUBLIC (x)) && TREE_PUBLIC (x))
{ {
...@@ -3398,7 +3466,8 @@ pushdecl (x) ...@@ -3398,7 +3466,8 @@ pushdecl (x)
warnstring = "declaration of `%s' shadows a member of `this'"; warnstring = "declaration of `%s' shadows a member of `this'";
else if (oldlocal != NULL_TREE) else if (oldlocal != NULL_TREE)
warnstring = "declaration of `%s' shadows previous local"; warnstring = "declaration of `%s' shadows previous local";
else if (oldglobal != NULL_TREE) else if (BINDING_VALUE (oldglobal) != NULL_TREE)
/* XXX shadow warnings in outer-more namespaces */
warnstring = "declaration of `%s' shadows global declaration"; warnstring = "declaration of `%s' shadows global declaration";
if (warnstring) if (warnstring)
...@@ -3641,7 +3710,7 @@ push_overloaded_decl (decl, forgettable) ...@@ -3641,7 +3710,7 @@ push_overloaded_decl (decl, forgettable)
if (doing_global) if (doing_global)
{ {
old = IDENTIFIER_GLOBAL_VALUE (orig_name); old = IDENTIFIER_NAMESPACE_VALUE (orig_name);
if (old && TREE_CODE (old) == FUNCTION_DECL if (old && TREE_CODE (old) == FUNCTION_DECL
&& DECL_ARTIFICIAL (old) && DECL_ARTIFICIAL (old)
&& (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
...@@ -3704,7 +3773,7 @@ push_overloaded_decl (decl, forgettable) ...@@ -3704,7 +3773,7 @@ push_overloaded_decl (decl, forgettable)
old = decl; old = decl;
if (doing_global) if (doing_global)
IDENTIFIER_GLOBAL_VALUE (orig_name) = old; IDENTIFIER_NAMESPACE_VALUE (orig_name) = old;
else else
IDENTIFIER_LOCAL_VALUE (orig_name) = old; IDENTIFIER_LOCAL_VALUE (orig_name) = old;
...@@ -4207,7 +4276,8 @@ lookup_tag (form, name, binding_level, thislevel_only) ...@@ -4207,7 +4276,8 @@ lookup_tag (form, name, binding_level, thislevel_only)
{ {
if (level->pseudo_global) if (level->pseudo_global)
{ {
tree t = IDENTIFIER_GLOBAL_VALUE (name); /* XXX MvL */
tree t = IDENTIFIER_NAMESPACE_VALUE (name);
if (t && TREE_CODE (t) == TEMPLATE_DECL if (t && TREE_CODE (t) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
return TREE_TYPE (t); return TREE_TYPE (t);
...@@ -4358,9 +4428,19 @@ tree ...@@ -4358,9 +4428,19 @@ tree
lookup_namespace_name (namespace, name) lookup_namespace_name (namespace, name)
tree namespace, name; tree namespace, name;
{ {
#if 1
tree val;
my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
val = qualified_lookup_using_namespace (name, namespace);
if (val)
return val;
cp_error ("`%D' undeclared in namespace `%D'", name, namespace);
return error_mark_node;
#else
struct binding_level *b = (struct binding_level *)NAMESPACE_LEVEL (namespace); struct binding_level *b = (struct binding_level *)NAMESPACE_LEVEL (namespace);
tree x = NULL_TREE; tree x = NULL_TREE;
#if 1 #if 1
/* This searches just one level. */ /* This searches just one level. */
if (b) if (b)
...@@ -4379,6 +4459,7 @@ lookup_namespace_name (namespace, name) ...@@ -4379,6 +4459,7 @@ lookup_namespace_name (namespace, name)
} }
#endif #endif
return x; return x;
#endif
} }
tree tree
...@@ -4518,7 +4599,7 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4518,7 +4599,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = IDENTIFIER_GLOBAL_VALUE (name); val = IDENTIFIER_GLOBAL_VALUE (name);
else if (TREE_CODE (type) == NAMESPACE_DECL) else if (TREE_CODE (type) == NAMESPACE_DECL)
{ {
val = lookup_namespace_name (type, name); val = NAMESPACE_BINDING (name, type);
} }
else if (! IS_AGGR_TYPE (type) else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TYPE_PARM
...@@ -4635,7 +4716,22 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4635,7 +4716,22 @@ lookup_name_real (name, prefer_type, nonclass)
else if (classval) else if (classval)
val = classval; val = classval;
else else
val = IDENTIFIER_GLOBAL_VALUE (name); {
/* unscoped lookup of a global, iterate over namespaces,
considering using namespace statements */
tree binding;
tree scope = current_namespace;
do
{
binding = binding_for_name (name, scope);
val = BINDING_VALUE (binding);
val = lookup_using_namespace (name, val, current_namespace, scope);
if (scope == global_namespace)
break;
scope = DECL_NAMESPACE (scope);
}
while (!val);
}
done: done:
if (val) if (val)
...@@ -4695,7 +4791,7 @@ lookup_name_current_level (name) ...@@ -4695,7 +4791,7 @@ lookup_name_current_level (name)
if (current_binding_level == global_binding_level) if (current_binding_level == global_binding_level)
{ {
t = IDENTIFIER_GLOBAL_VALUE (name); t = IDENTIFIER_NAMESPACE_VALUE (name);
/* extern "C" function() */ /* extern "C" function() */
if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
...@@ -4782,6 +4878,7 @@ record_builtin_type (rid_index, name, type) ...@@ -4782,6 +4878,7 @@ record_builtin_type (rid_index, name, type)
tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
set_identifier_type_value (tname, NULL_TREE); set_identifier_type_value (tname, NULL_TREE);
if ((int) rid_index < (int) RID_MAX) if ((int) rid_index < (int) RID_MAX)
/* builtin types live in the global namespace */
IDENTIFIER_GLOBAL_VALUE (tname) = tdecl; IDENTIFIER_GLOBAL_VALUE (tname) = tdecl;
} }
if (rname != NULL_TREE) if (rname != NULL_TREE)
...@@ -4851,6 +4948,14 @@ init_decl_processing () ...@@ -4851,6 +4948,14 @@ init_decl_processing ()
lang_name_cplusplus = get_identifier ("C++"); lang_name_cplusplus = get_identifier ("C++");
lang_name_c = get_identifier ("C"); lang_name_c = get_identifier ("C");
/* enter the global namespace */
my_friendly_assert (global_namespace == NULL_TREE, 375);
my_friendly_assert (current_lang_name == NULL_TREE, 375);
current_lang_name = lang_name_cplusplus;
push_namespace (get_identifier ("::"));
global_namespace = current_namespace;
current_lang_name = NULL_TREE;
if (flag_strict_prototype == 2) if (flag_strict_prototype == 2)
{ {
if (pedantic) if (pedantic)
...@@ -7484,6 +7589,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, ...@@ -7484,6 +7589,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (check == 0 && ! current_function_decl) if (check == 0 && ! current_function_decl)
{ {
/* assembler names live in the global namespace */
tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)); tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
if (tmp == NULL_TREE) if (tmp == NULL_TREE)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
...@@ -7611,9 +7717,12 @@ grokvardecl (type, declarator, specbits_in, initialized, constp) ...@@ -7611,9 +7717,12 @@ grokvardecl (type, declarator, specbits_in, initialized, constp)
DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator); DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
} }
else else
decl = build_decl (VAR_DECL, declarator, complete_type (type)); {
decl = build_decl (VAR_DECL, declarator, complete_type (type));
DECL_ASSEMBLER_NAME (decl) = current_namespace_id (DECL_ASSEMBLER_NAME (decl)); if (current_namespace != global_namespace)
DECL_ASSEMBLER_NAME (decl) = build_static_name (current_namespace,
declarator);
}
if (RIDBIT_SETP (RID_EXTERN, specbits)) if (RIDBIT_SETP (RID_EXTERN, specbits))
{ {
...@@ -9928,7 +10037,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9928,7 +10037,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c
&& (! DECL_USE_TEMPLATE (decl) || && (! DECL_USE_TEMPLATE (decl) ||
name_mangling_version < 1)) name_mangling_version < 1))
#if 0
/* XXX is support for the old __ns_ mangling really needed? MvL */
DECL_ASSEMBLER_NAME (decl) = current_namespace_id (declarator); DECL_ASSEMBLER_NAME (decl) = current_namespace_id (declarator);
#else
DECL_ASSEMBLER_NAME (decl) = declarator;
#endif
if (staticp == 1) if (staticp == 1)
{ {
...@@ -10931,10 +11045,16 @@ xref_tag (code_type_node, name, binfo, globalize) ...@@ -10931,10 +11045,16 @@ xref_tag (code_type_node, name, binfo, globalize)
else else
{ {
/* If it no longer looks like a nested type, make sure it's /* If it no longer looks like a nested type, make sure it's
in global scope. */ in global scope.
If it is not an IDENTIFIER, this is not a declaration */
if (b == global_binding_level && !class_binding_level if (b == global_binding_level && !class_binding_level
&& IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE) && TREE_CODE (name) == IDENTIFIER_NODE)
IDENTIFIER_GLOBAL_VALUE (name) = TYPE_NAME (ref); {
tree binding;
binding = binding_for_name (name, current_namespace);
if (BINDING_VALUE (binding) == NULL_TREE)
BINDING_VALUE (binding) = TYPE_NAME (ref);
}
} }
if (binfo) if (binfo)
...@@ -11465,11 +11585,13 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -11465,11 +11585,13 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
&& TYPE_IDENTIFIER (DECL_CONTEXT (decl1)) && TYPE_IDENTIFIER (DECL_CONTEXT (decl1))
&& IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (DECL_CONTEXT (decl1)))) && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (DECL_CONTEXT (decl1))))
{ {
tree binding = binding_for_name (DECL_NAME (decl1),
current_namespace);
cp_error ("redeclaration of `%#D'", decl1); cp_error ("redeclaration of `%#D'", decl1);
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))) if (IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1)))
cp_error_at ("previous declaration here", IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))); cp_error_at ("previous declaration here", IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1)));
else if (IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl1))) else if (BINDING_VALUE (binding))
cp_error_at ("previous declaration here", IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl1))); cp_error_at ("previous declaration here", BINDING_VALUE (binding));
} }
fntype = TREE_TYPE (decl1); fntype = TREE_TYPE (decl1);
......
...@@ -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