OSDN Git Service

Partial implementation of namespaces.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Feb 1998 00:49:51 +0000 (00:49 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Feb 1998 00:49:51 +0000 (00:49 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@18227 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/ptree.c

index 757a1fd..115e786 100644 (file)
@@ -1,3 +1,81 @@
+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>
 
        * pt.c (instantiate_class_template): Don't instantiate if pedantic
index 74d6441..1f39768 100644 (file)
@@ -169,6 +169,10 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
    the template will will be an IDENTIFIER_NODE.  */
 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
    templates.  */
 DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
index 22b4109..dcaf69f 100644 (file)
@@ -58,13 +58,28 @@ typedef struct
   tree decl;
 } 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
    flag `-Wtemplate-debugging'.  */
 #define HAVE_TEMPLATES 1
 
 /* 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)
 #define IDENTIFIER_CLASS_VALUE(NODE)   \
   (((struct lang_identifier *)(NODE))->class_value)
@@ -161,6 +176,9 @@ extern int current_function_returns_value;
 extern int current_function_returns_null;
 extern tree current_function_return_value;
 
+extern tree current_namespace;
+extern tree global_namespace;
+
 extern tree ridpointers[];
 extern tree ansi_opname[];
 extern tree ansi_assopname[];
@@ -967,6 +985,7 @@ struct lang_decl_flags
   tree memfunc_pointer_to;
   tree template_info;
   struct binding_level *level;
+  tree in_namespace;
 };
 
 struct lang_decl
@@ -1071,7 +1090,7 @@ struct lang_decl
 
 /* The _TYPE context in which this _DECL appears.  This field holds 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_REAL_CONTEXT(NODE) \
   ((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \
@@ -1079,12 +1098,24 @@ struct lang_decl
 
 /* For a FUNCTION_DECL: the chain through which the next method
    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
 #define DECL_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
 #else
 #define DECL_CHAIN(NODE) (TREE_CHAIN (NODE))
 #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,
    this is the shadowed (local) variable.  */
@@ -1473,6 +1504,12 @@ extern int flag_new_for_scope;
 #define DECL_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
    as best it can for this decl.  */
 #define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat)
@@ -2122,11 +2159,14 @@ extern tree gettags                             PROTO((void));
 #if 0
 extern void set_current_level_tags_transparency        PROTO((int));
 #endif
+extern tree binding_for_name                    PROTO((tree, tree));
 extern tree lookup_namespace_name              PROTO((tree, tree));
 extern tree make_typename_type                 PROTO((tree, tree));
 extern tree lookup_name_nonclass               PROTO((tree));
 extern tree lookup_name                                PROTO((tree, int));
 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 void init_decl_processing               PROTO((void));
 extern int init_type_desc                      PROTO((void));
@@ -2375,6 +2415,7 @@ extern void synthesize_method                     PROTO((tree));
 extern tree get_id_2                           PROTO((char *, tree));
 
 /* in pt.c */
+extern tree innermost_args                     PROTO ((tree, int));
 extern tree tsubst                             PROTO ((tree, tree, tree));
 extern tree tsubst_expr                                PROTO ((tree, tree, tree));
 extern tree tsubst_copy                                PROTO ((tree, tree, tree));
index df260a3..9273043 100644 (file)
@@ -63,6 +63,9 @@ extern tree static_ctors, static_dtors;
 
 extern int static_labelno;
 
+extern tree current_namespace;
+extern tree global_namespace;
+
 /* Stack of places to restore the search obstack back to.  */
    
 /* Obstack used for remembering local class declarations (like
@@ -1664,6 +1667,34 @@ print_binding_stack ()
   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;
 
 /* Get a unique name for each call to this routine for unnamed namespaces.
@@ -1692,7 +1723,7 @@ get_unique_name ()
   /* Don't need to pull weird characters out of global names.  */
   if (p != first_global_object_name)
     {
-      for (p = buf+11; *p; p++)
+      for (p = buf+2; *p; p++)
        if (! ((*p >= '0' && *p <= '9')
 #ifndef NO_DOLLAR_IN_LABEL     /* this for `$'; unlikely, but... -- kr */
               || *p == '$'
@@ -1716,13 +1747,42 @@ push_namespace (name)
      tree name;
 {
 #if 1
-  static int warned;
-  if (! warned)
-    sorry ("namespace");
+  tree d;
+  int need_new = 1;
+  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
-  extern tree current_namespace;
   tree old_id = get_namespace_id ();
   char *buf;
   tree d;
@@ -1766,8 +1826,9 @@ push_namespace (name)
 void
 pop_namespace ()
 {
-#if 0
-  extern tree current_namespace;
+#if 1
+  current_namespace = DECL_NAMESPACE (current_namespace);
+#else
   tree decls, link;
   current_namespace = TREE_CHAIN (current_namespace);
 
@@ -3242,11 +3303,12 @@ pushdecl (x)
       if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
        {
          tree decl;
+         tree bindings = binding_for_name (name, current_namespace);
 
-         if (IDENTIFIER_GLOBAL_VALUE (name) != NULL_TREE
-             && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
-                 || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
-           decl = IDENTIFIER_GLOBAL_VALUE (name);
+         if (BINDING_VALUE (bindings) != NULL_TREE
+             && (DECL_EXTERNAL (BINDING_VALUE (bindings))
+                 || TREE_PUBLIC (BINDING_VALUE (bindings))))
+           decl = BINDING_VALUE (bindings);
          else
            decl = NULL_TREE;
 
@@ -3265,10 +3327,11 @@ pushdecl (x)
       if (b == global_binding_level)
        {
          /* Install a global value.  */
+         tree bindings = binding_for_name (name, current_namespace);
 
          /* If the first global decl has external linkage,
             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;
 
          /* Don't install an artificial TYPE_DECL if we already have
@@ -3276,7 +3339,12 @@ pushdecl (x)
          if (TREE_CODE (x) != TYPE_DECL
              || t == NULL_TREE
              || ! 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.  */
          if (IDENTIFIER_IMPLICIT_DECL (name)
@@ -3305,7 +3373,7 @@ pushdecl (x)
        {
          /* Here to install a non-global value.  */
          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
             another _DECL with that name.  */
@@ -3331,24 +3399,24 @@ pushdecl (x)
             have a global definition or declaration for the function.  */
          if (oldlocal == NULL_TREE
              && DECL_EXTERNAL (x)
-             && oldglobal != NULL_TREE
+             && BINDING_VALUE (oldglobal) != NULL_TREE
              && TREE_CODE (x) == FUNCTION_DECL
-             && TREE_CODE (oldglobal) == FUNCTION_DECL)
+             && TREE_CODE (BINDING_VALUE (oldglobal)) == FUNCTION_DECL)
            {
              /* We have one.  Their types must agree.  */
-             if (decls_match (x, oldglobal))
+             if (decls_match (x, BINDING_VALUE (oldglobal)))
                /* OK */;
              else
                {
                  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,
             and no file-scope declaration has yet been seen,
             then if we later have a file-scope decl it must not be static.  */
          if (oldlocal == NULL_TREE
-             && oldglobal == NULL_TREE
+             && BINDING_VALUE (oldglobal) == NULL_TREE
              && DECL_EXTERNAL (x)
              && TREE_PUBLIC (x))
            {
@@ -3398,7 +3466,8 @@ pushdecl (x)
                warnstring = "declaration of `%s' shadows a member of `this'";
              else if (oldlocal != NULL_TREE)
                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";
 
              if (warnstring)
@@ -3641,7 +3710,7 @@ push_overloaded_decl (decl, forgettable)
 
   if (doing_global)
     {
-      old = IDENTIFIER_GLOBAL_VALUE (orig_name);
+      old =  IDENTIFIER_NAMESPACE_VALUE (orig_name);
       if (old && TREE_CODE (old) == FUNCTION_DECL
          && DECL_ARTIFICIAL (old)
          && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
@@ -3704,7 +3773,7 @@ push_overloaded_decl (decl, forgettable)
     old = decl;
 
   if (doing_global)
-    IDENTIFIER_GLOBAL_VALUE (orig_name) = old;
+    IDENTIFIER_NAMESPACE_VALUE (orig_name) = old;
   else
     IDENTIFIER_LOCAL_VALUE (orig_name) = old;
 
@@ -4207,7 +4276,8 @@ lookup_tag (form, name, binding_level, thislevel_only)
        {
          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
                  && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
                return TREE_TYPE (t);
@@ -4358,9 +4428,19 @@ tree
 lookup_namespace_name (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);
   tree x = NULL_TREE;
-
 #if 1
   /* This searches just one level.  */
   if (b)
@@ -4379,6 +4459,7 @@ lookup_namespace_name (namespace, name)
     }
 #endif
   return x;
+#endif
 }
 
 tree
@@ -4518,7 +4599,7 @@ lookup_name_real (name, prefer_type, nonclass)
            val = IDENTIFIER_GLOBAL_VALUE (name);
          else if (TREE_CODE (type) == NAMESPACE_DECL)
            {
-             val = lookup_namespace_name (type, name);
+             val = NAMESPACE_BINDING (name, type);
            }
          else if (! IS_AGGR_TYPE (type)
                   || TREE_CODE (type) == TEMPLATE_TYPE_PARM
@@ -4635,7 +4716,22 @@ lookup_name_real (name, prefer_type, nonclass)
   else if (classval)
     val = classval;
   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:
   if (val)
@@ -4695,7 +4791,7 @@ lookup_name_current_level (name)
 
   if (current_binding_level == global_binding_level)
     {
-      t = IDENTIFIER_GLOBAL_VALUE (name);
+      t =  IDENTIFIER_NAMESPACE_VALUE (name);
 
       /* extern "C" function() */
       if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
@@ -4782,6 +4878,7 @@ record_builtin_type (rid_index, name, type)
       tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
       set_identifier_type_value (tname, NULL_TREE);
       if ((int) rid_index < (int) RID_MAX)
+       /* builtin types live in the global namespace */
        IDENTIFIER_GLOBAL_VALUE (tname) = tdecl;
     }
   if (rname != NULL_TREE)
@@ -4851,6 +4948,14 @@ init_decl_processing ()
   lang_name_cplusplus = 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 (pedantic)
@@ -7484,6 +7589,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
       if (check == 0 && ! current_function_decl)
        {
+         /* assembler names live in the global namespace */
          tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
          if (tmp == NULL_TREE)
            IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
@@ -7611,9 +7717,12 @@ grokvardecl (type, declarator, specbits_in, initialized, constp)
       DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
     }
   else
-    decl = build_decl (VAR_DECL, declarator, complete_type (type));
-
-  DECL_ASSEMBLER_NAME (decl) = current_namespace_id (DECL_ASSEMBLER_NAME (decl));
+    {
+      decl = build_decl (VAR_DECL, declarator, complete_type (type));
+      if (current_namespace != global_namespace)
+       DECL_ASSEMBLER_NAME (decl) =  build_static_name (current_namespace,
+                                                        declarator);
+    }
 
   if (RIDBIT_SETP (RID_EXTERN, specbits))
     {
@@ -9928,7 +10037,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c
            && (! DECL_USE_TEMPLATE (decl) ||
                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);
+#else
+         DECL_ASSEMBLER_NAME (decl) = declarator;
+#endif 
        
        if (staticp == 1)
          {
@@ -10931,10 +11045,16 @@ xref_tag (code_type_node, name, binfo, globalize)
   else
     {
       /* 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
-         && IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE)
-       IDENTIFIER_GLOBAL_VALUE (name) = TYPE_NAME (ref);
+         && TREE_CODE (name) == IDENTIFIER_NODE)
+       {
+         tree binding;
+         binding = binding_for_name (name, current_namespace);
+         if (BINDING_VALUE (binding) == NULL_TREE)
+           BINDING_VALUE (binding) = TYPE_NAME (ref);
+       }
     }
 
   if (binfo)
@@ -11465,11 +11585,13 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
          && 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);
          if (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)))
-           cp_error_at ("previous declaration here", IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl1)));
+         else if (BINDING_VALUE (binding))
+           cp_error_at ("previous declaration here", BINDING_VALUE (binding));
        }
 
       fntype = TREE_TYPE (decl1);
index c847a27..b0363f1 100644 (file)
@@ -90,6 +90,12 @@ int at_eof;
 /* Functions called along with real static constructors and destructors.  */
 
 tree static_ctors, static_dtors;
+
+/* The current open namespace, and :: */
+
+tree current_namespace;
+tree global_namespace;
+
 \f
 /* C (and C++) language-specific option variables.  */
 
@@ -2880,6 +2886,9 @@ get_sentry (base)
      tree 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);
   if (! sentry)
     {
@@ -3756,8 +3765,179 @@ check_cp_case_value (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
    postfix.  Returns 0 if in global namespace.  */
 
@@ -3789,12 +3969,35 @@ current_namespace_id (name)
           IDENTIFIER_POINTER (name));
   return get_identifier (buf);
 }
+#endif
 
 void
 do_namespace_alias (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
@@ -3856,7 +4059,11 @@ do_using_directive (namespace)
 {
   if (namespace == std_node)
     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
index 0451781..31a38bb 100644 (file)
@@ -697,6 +697,11 @@ dump_decl (t, v)
       break;
 
     case NAMESPACE_DECL:
+      if (DECL_NAMESPACE (t) != global_namespace)
+       {
+         dump_decl (DECL_NAMESPACE (t), v);
+         OB_PUTC2 (':',':');
+       }
       OB_PUTID (DECL_NAME (t));
       break;
 
index ced15d4..c80403e 100644 (file)
@@ -1703,6 +1703,9 @@ build_member_call (type, name, parmlist)
   if (type == std_node)
     return build_x_function_call (do_scoped_id (name, 0), parmlist,
                                  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)
     method_name = name;
@@ -1840,20 +1843,8 @@ build_offset_ref (type, name)
     return build_min_nt (SCOPE_REF, type, name);
 
   /* Handle namespace names fully here.  */
-  if (TREE_CODE (type) == IDENTIFIER_NODE
-      && get_aggr_from_typedef (type, 0) == 0)
-    {
-      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 (TREE_CODE (type) == NAMESPACE_DECL)
+      return lookup_namespace_name (type, name);
 
   if (type == NULL_TREE || ! is_aggr_type (type, 1))
     return error_mark_node;
index 8d6d622..3b71c49 100644 (file)
@@ -2800,7 +2800,7 @@ do_identifier (token, parsing)
     yychar = yylex ();
   /* Scope class declarations before global
      declarations.  */
-  if (id == IDENTIFIER_GLOBAL_VALUE (token)
+  if (id == IDENTIFIER_NAMESPACE_VALUE (token)
       && current_class_type != 0
       && TYPE_SIZE (current_class_type) == 0)
     {
@@ -2868,7 +2868,7 @@ do_identifier (token, parsing)
        }
       else
        {
-         if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
+         if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
              || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
            {
              static int undeclared_variable_notice;
@@ -2884,7 +2884,7 @@ do_identifier (token, parsing)
            }
          id = error_mark_node;
          /* 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);
        }
     }
@@ -2896,7 +2896,7 @@ do_identifier (token, parsing)
             && DECL_DEAD_FOR_LOCAL (shadowed))
        shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
       if (!shadowed)
-       shadowed = IDENTIFIER_GLOBAL_VALUE (DECL_NAME (id));
+       shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
       if (shadowed)
        {
          if (!DECL_ERROR_REPORTED (id))
@@ -2953,7 +2953,7 @@ do_identifier (token, parsing)
        {
          tree t = build_min (LOOKUP_EXPR, unknown_type_node,
                              token, get_first_fn (id));
-         if (id != IDENTIFIER_GLOBAL_VALUE (token))
+         if (id != IDENTIFIER_NAMESPACE_VALUE (token))
            TREE_OPERAND (t, 1) = error_mark_node;
          id = t;
        }
@@ -2971,7 +2971,12 @@ do_scoped_id (token, parsing)
      tree token;
      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)
     yychar = yylex ();
   if (! id)
@@ -2986,12 +2991,12 @@ do_scoped_id (token, parsing)
        id = implicitly_declare (token);
       else
        {
-         if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node)
+         if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
            error ("undeclared variable `%s' (first use here)",
                   IDENTIFIER_POINTER (token));
          id = error_mark_node;
          /* Prevent repeated error messages.  */
-         IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
+         IDENTIFIER_NAMESPACE_VALUE (token) = error_mark_node;
        }
     }
   else
@@ -3040,7 +3045,7 @@ identifier_typedecl_value (node)
   }
   do (IDENTIFIER_LOCAL_VALUE (node));
   do (IDENTIFIER_CLASS_VALUE (node));
-  do (IDENTIFIER_GLOBAL_VALUE (node));
+  do (IDENTIFIER_NAMESPACE_VALUE (node));
 #undef do
   /* Will this one ever happen?  */
   if (TYPE_MAIN_DECL (type))
@@ -4376,6 +4381,8 @@ build_lang_decl (code, name, type)
     DECL_LANGUAGE (t) = lang_c;
   else my_friendly_abort (64);
 
+  SET_DECL_NAMESPACE (t, current_namespace);
+
 #if 0 /* not yet, should get fixed properly later */
   if (code == TYPE_DECL)
     {
index 1562f80..beb5f29 100644 (file)
@@ -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)
     {
@@ -553,6 +560,8 @@ build_overload_nested_name (decl)
       OB_PUTCP (label);
       numeric_output_need_bar = 1;
     }
+  else if (TREE_CODE (decl) == NAMESPACE_DECL)
+    build_overload_identifier (DECL_NAME (decl));
   else                         /* TYPE_DECL */
     build_overload_identifier (decl);
 }
@@ -969,16 +978,37 @@ build_qualified_name (decl)
   context = decl;
   /* if we can't find a Ktype, do it the hard way */
   if (check_ktype (context, FALSE) == -1)
-    while (DECL_CONTEXT (context))
-      {
-        i += 1;
-        context = DECL_CONTEXT (context);
-        if (check_ktype (context, FALSE) != -1)  /* found it! */
-          break;
-        if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
-          context = TYPE_NAME (context);
-      }
+    {
+      /* count type scopes */
+      while (DECL_CONTEXT (context))
+       {
+         i += 1;
+         context = DECL_CONTEXT (context);
+         if (check_ktype (context, FALSE) != -1)  /* found it! */
+           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)
     {
@@ -1515,7 +1545,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
     }
   else if (tparms)
     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');
 
   if (tparms)
@@ -1524,6 +1557,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
       OB_PUTC ('_');
     }
 
+  /* qualify with namespace */
+  if (!for_method && current_namespace != global_namespace)
+    build_qualified_name (current_namespace);
+
   if (parms == NULL_TREE)
     OB_PUTC ('e');
   else if (parms == void_list_node)
@@ -1552,7 +1589,14 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
            OB_PUTC ('e');
        }
       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 */
         {
index d70bc62..6783b12 100644 (file)
@@ -788,7 +788,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
          my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 
                              0);
          if (!ctype)
-           fns = IDENTIFIER_GLOBAL_VALUE (dname);
+           fns = IDENTIFIER_NAMESPACE_VALUE (dname);
          else
            fns = dname;
 
@@ -1465,7 +1465,7 @@ push_template_decl (decl)
        }
     }
   /* 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;
   TREE_TYPE (tmpl) = TREE_TYPE (decl);
@@ -2359,7 +2359,7 @@ lookup_template_class (d1, arglist, in_decl, context)
        template = IDENTIFIER_LOCAL_VALUE (d1);
       else
        {
-         template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */
+         template = IDENTIFIER_NAMESPACE_VALUE (d1); /* XXX */
          if (! template)
            template = IDENTIFIER_CLASS_VALUE (d1);
        }
index 4a6ce7b..13f171a 100644 (file)
@@ -163,3 +163,21 @@ print_lang_identifier (file, node, indent)
   print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (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;
+    }
+}