]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
8
authorJason Merrill <jason@gcc.gnu.org>
Sat, 18 Jul 1998 11:06:00 +0000 (07:06 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 18 Jul 1998 11:06:00 +0000 (07:06 -0400)
From-SVN: r21270

gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/pt.c

index 0801ab83a86bff38e427db22e4af06c09ec34832..913b9abd00aed3aa97d9351ebbb74d0e8a23df92 100644 (file)
@@ -2159,6 +2159,26 @@ set_identifier_type_value (id, type)
   set_identifier_type_value_with_scope (id, type, inner_binding_level);
 }
 
+void
+set_identifier_local_value_with_scope (id, val, b)
+     tree id, val;
+     struct binding_level *b;
+{
+  tree oldlocal;
+  my_friendly_assert (! b->namespace_p, 980716);
+
+  oldlocal = IDENTIFIER_LOCAL_VALUE (id);
+  b->shadowed = tree_cons (id, oldlocal, b->shadowed);
+  IDENTIFIER_LOCAL_VALUE (id) = val;
+}
+
+void
+set_identifier_local_value (id, val)
+     tree id, val;
+{
+  set_identifier_local_value_with_scope (id, val, current_binding_level);
+}
+
 /* Return the type associated with id. */
 
 tree
@@ -2444,6 +2464,11 @@ decls_match (newdecl, olddecl)
       tree p1 = TYPE_ARG_TYPES (f1);
       tree p2 = TYPE_ARG_TYPES (f2);
 
+      if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)
+         && ! (DECL_LANGUAGE (newdecl) == lang_c
+               && DECL_LANGUAGE (olddecl) == lang_c))
+       return 0;
+
       /* When we parse a static member function definition,
         we put together a FUNCTION_DECL which thinks its type
         is METHOD_TYPE.  Change that to FUNCTION_TYPE, and
@@ -2646,12 +2671,30 @@ duplicate_decls (newdecl, olddecl)
     }
   else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
+      if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
+          && TREE_CODE (newdecl) != TYPE_DECL
+          && ! (TREE_CODE (newdecl) == TEMPLATE_DECL
+                && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL))
+         || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
+             && TREE_CODE (olddecl) != TYPE_DECL
+             && ! (TREE_CODE (olddecl) == TEMPLATE_DECL
+                   && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
+                       == TYPE_DECL))))
+       {
+         /* We do nothing special here, because C++ does such nasty
+            things with TYPE_DECLs.  Instead, just let the TYPE_DECL
+            get shadowed, and know that if we need to find a TYPE_DECL
+            for a given name, we can look in the IDENTIFIER_TYPE_VALUE
+            slot of the identifier.  */
+         return 0;
+       }
+
       if ((TREE_CODE (newdecl) == FUNCTION_DECL
           && DECL_FUNCTION_TEMPLATE_P (olddecl))
          || (TREE_CODE (olddecl) == FUNCTION_DECL
              && DECL_FUNCTION_TEMPLATE_P (newdecl)))
        return 0;
-      
+
       cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
       if (TREE_CODE (olddecl) == TREE_LIST)
        olddecl = TREE_VALUE (olddecl);
@@ -3319,24 +3362,7 @@ pushdecl (x)
            }
          else if (TREE_CODE (t) != TREE_CODE (x))
            {
-             if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
-                  && TREE_CODE (x) != TYPE_DECL
-                  && ! (TREE_CODE (x) == TEMPLATE_DECL
-                        && TREE_CODE (DECL_TEMPLATE_RESULT (x)) == TYPE_DECL))
-                 || (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
-                     && TREE_CODE (t) != TYPE_DECL
-                     && ! (TREE_CODE (t) == TEMPLATE_DECL
-                           && (TREE_CODE (DECL_TEMPLATE_RESULT (t))
-                               == TYPE_DECL))))
-               {
-                 /* We do nothing special here, because C++ does such nasty
-                    things with TYPE_DECLs.  Instead, just let the TYPE_DECL
-                    get shadowed, and know that if we need to find a TYPE_DECL
-                    for a given name, we can look in the IDENTIFIER_TYPE_VALUE
-                    slot of the identifier.  */
-                 ;
-               }
-             else if (duplicate_decls (x, t))
+             if (duplicate_decls (x, t))
                return t;
            }
          else if (duplicate_decls (x, t))
@@ -3519,10 +3545,7 @@ pushdecl (x)
          if (TREE_CODE (x) != TYPE_DECL
              || t == NULL_TREE
              || ! DECL_ARTIFICIAL (x))
-           {
-             b->shadowed = tree_cons (name, oldlocal, b->shadowed);
-             IDENTIFIER_LOCAL_VALUE (name) = x;
-           }
+           set_identifier_local_value_with_scope (name, x, b);
 
          /* If this is a TYPE_DECL, push it into the type value slot.  */
          if (TREE_CODE (x) == TYPE_DECL)
@@ -3851,12 +3874,11 @@ push_using_decl (scope, name)
    TREE_LIST otherwise.  */
 
 tree
-push_using_directive (used, ancestor)
+push_using_directive (used)
      tree used;
-     tree ancestor;
 {
   tree ud = current_binding_level->using_directives;
-  tree iter;
+  tree iter, ancestor;
   
   /* Check if we already have this. */
   if (purpose_member (used, ud) != NULL_TREE)
@@ -3864,8 +3886,9 @@ push_using_directive (used, ancestor)
 
   /* Recursively add all namespaces used. */
   for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
-    push_using_directive (TREE_PURPOSE (iter), ancestor);
+    push_using_directive (TREE_PURPOSE (iter));
 
+  ancestor = namespace_ancestor (current_decl_namespace (), used);
   ud = current_binding_level->using_directives;
   ud = perm_tree_cons (used, ancestor, ud);
   current_binding_level->using_directives = ud;
@@ -4650,7 +4673,15 @@ lookup_namespace_name (namespace, name)
     return error_mark_node;
 
   if (BINDING_VALUE (val))
-    return BINDING_VALUE (val);
+    {
+      val = BINDING_VALUE (val);
+
+      /* If we have a single function from a using decl, pull it out.  */
+      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+       val = OVL_FUNCTION (val);
+      return val;
+    }
+
   cp_error ("`%D' undeclared in namespace `%D'", name, namespace);
   return error_mark_node;
 }
@@ -4760,6 +4791,7 @@ select_decl (binding, flags)
   else if (val && LOOKUP_TYPES_ONLY (flags)  && TREE_CODE (val) != TYPE_DECL
           && (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL))
     val = NULL_TREE;
+
   return val;
 }
 
@@ -4812,9 +4844,7 @@ unqualified_namespace_lookup (name, flags)
       val = select_decl (b, flags);
       if (scope == global_namespace)
        break;
-      scope = DECL_CONTEXT (scope);
-      if (scope == NULL_TREE)
-       scope = global_namespace;
+      scope = CP_DECL_CONTEXT (scope);
     }
   return val;
 }
@@ -4844,9 +4874,14 @@ qualify_lookup (val, flags)
 {
   if (val == NULL_TREE)
     return val;
-  if (LOOKUP_NAMESPACES_ONLY (flags) && TREE_CODE (val) != NAMESPACE_DECL)
-    return NULL_TREE;
-  if (LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL)
+  if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
+    return val;
+  if ((flags & LOOKUP_PREFER_TYPES)
+      && (TREE_CODE (val) == TYPE_DECL
+         || ((flags & LOOKUP_TEMPLATES_EXPECTED)
+             && DECL_CLASS_TEMPLATE_P (val))))
+    return val;
+  if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return NULL_TREE;
   return val;
 }
@@ -5061,6 +5096,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
        val = TYPE_MAIN_DECL (IDENTIFIER_TYPE_VALUE (name));
       else if (TREE_TYPE (val) == error_mark_node)
        val = error_mark_node;
+
+      /* If we have a single function from a using decl, pull it out.  */
+      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+       val = OVL_FUNCTION (val);
     }
   else if (from_obj)
     val = from_obj;
@@ -5120,16 +5159,41 @@ lookup_name_current_level (name)
       struct binding_level *b = current_binding_level;
       while (1)
        {
-         for (t = b->names; t; t = TREE_CHAIN (t))
-           if (DECL_NAME (t) == name || DECL_ASSEMBLER_NAME (t) == name)
-             goto out;
+         if (purpose_member (name, b->shadowed))
+           return IDENTIFIER_LOCAL_VALUE (name);
+         if (b->keep == 2)
+           b = b->level_chain;
+         else
+           break;
+       }
+    }
+
+  return t;
+}
+
+/* Like lookup_name_current_level, but for types.  */
+
+tree
+lookup_type_current_level (name)
+     tree name;
+{
+  register tree t = NULL_TREE;
+
+  my_friendly_assert (! current_binding_level->namespace_p, 980716);
+
+  if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
+      && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
+    {
+      struct binding_level *b = current_binding_level;
+      while (1)
+       {
+         if (purpose_member (name, b->type_shadowed))
+           return REAL_IDENTIFIER_TYPE_VALUE (name);
          if (b->keep == 2)
            b = b->level_chain;
          else
            break;
        }
-    out:
-      ;
     }
 
   return t;
@@ -7978,7 +8042,8 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
     {
       tree context = in_namespace ? in_namespace : current_namespace;
       decl = build_decl (VAR_DECL, declarator, complete_type (type));
-      if (context != global_namespace && namespace_bindings_p ())
+      if (context != global_namespace && namespace_bindings_p ()
+         && current_lang_name != lang_name_c)
        DECL_ASSEMBLER_NAME (decl) =  build_static_name (context,
                                                         declarator);
     }
index 2f8079971567eeab32c54a00864f275bc7265f50..dfe07b5239a4a92fd2d6d20883142a9572673d96 100644 (file)
@@ -1540,8 +1540,12 @@ build_offset_ref (type, name)
   if (TREE_CODE (type) == NAMESPACE_DECL)
     {
       t = lookup_namespace_name (type, name);
-      mark_used (t);
-      return convert_from_reference (t);
+      if (! type_unknown_p (t))
+       {
+         mark_used (t);
+         t = convert_from_reference (t);
+       }
+      return t;
     }
 
   if (type == NULL_TREE || ! is_aggr_type (type, 1))
index 5d1d5811394de09b16b11ee38ac109578ede77ec..ed23223d664efbc9251bfebb3096da162acf6698 100644 (file)
@@ -2985,7 +2985,7 @@ lookup_template_class (d1, arglist, in_decl, context)
 {
   tree template = NULL_TREE, parmlist;
   char *mangled_name;
-  tree id, t, id_context;
+  tree id, t;
 
   if (TREE_CODE (d1) == IDENTIFIER_NODE)
     {
@@ -3030,12 +3030,6 @@ lookup_template_class (d1, arglist, in_decl, context)
   else
     my_friendly_abort (272);
 
-  /* A namespace is used as context only for mangling.
-     Template IDs with namespace context are found 
-     in the global binding level.  */
-  if (context != NULL_TREE && TREE_CODE (context) == NAMESPACE_DECL)
-    context = global_namespace;
-
   /* With something like `template <class T> class X class X { ... };'
      we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
      We don't want to do that, but we have to deal with the situation, so
@@ -3043,15 +3037,8 @@ lookup_template_class (d1, arglist, in_decl, context)
   if (! template)
     return error_mark_node;
 
-  /* We need an id_context to get the mangling right. If this is a
-     nested template, use the context. If it is global, retrieve the
-     context from the template.  */
-  if (context && TREE_CODE (context) != NAMESPACE_DECL)
-    id_context = context;
-  else
-    id_context = DECL_CONTEXT (template);
-  if (id_context == NULL_TREE)
-    id_context = global_namespace;
+  if (context == NULL_TREE)
+    context = global_namespace;
 
   if (TREE_CODE (template) != TEMPLATE_DECL)
     {
@@ -3154,7 +3141,7 @@ lookup_template_class (d1, arglist, in_decl, context)
       mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1),
                                                     parmlist,
                                                     arglist_for_mangling,
-                                                    id_context);
+                                                    context);
       id = get_identifier (mangled_name);
       IDENTIFIER_TEMPLATE (id) = d1;
 
@@ -4642,7 +4629,10 @@ tsubst (t, args, in_decl)
            tmpl = DECL_TI_TEMPLATE (t);
 
            /* Start by getting the innermost args.  */
-           argvec = tsubst (DECL_TI_ARGS (t), args, in_decl);
+           if (DECL_TEMPLATE_SPECIALIZATION (tmpl))
+             argvec = args;
+           else
+             argvec = tsubst (DECL_TI_ARGS (t), args, in_decl);
 
            if (DECL_TEMPLATE_INFO (tmpl))
              argvec = complete_template_args (tmpl, argvec, 0);
@@ -5728,11 +5718,11 @@ instantiate_template (tmpl, targ_ptr)
 
   my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
 
-  /* FIXME this won't work with member templates; we only have one level
-     of args here.  */
+  /* Check to see if we already have this specialization.  This does work
+     for member template specializations; the list is set up from the
+     tsubst TEMPLATE_DECL case when the containing class is instantiated.  */
   if (DECL_FUNCTION_TEMPLATE_P (tmpl))
     {
-      /* Check to see if we already have this specialization.  */
       tree spec = retrieve_specialization (tmpl, targ_ptr);
       
       if (spec != NULL_TREE)