]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/class.c
cp-tree.h (build_binary_op): Remove unneeded parameter.
[gcc.git] / gcc / cp / class.c
index 07f8f9737e146ff0e7d58a5ad80f2b18f5f227b5..87a82c7beea1a583d282beba8e7a52522b38ac27 100644 (file)
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "output.h"
 #include "toplev.h"
+#include "splay-tree.h"
 
 #include "obstack.h"
 #define obstack_chunk_alloc xmalloc
@@ -62,6 +63,9 @@ typedef struct class_stack_node {
   /* The access specifier pending for new declarations in the scope of
      this class.  */
   tree access;
+
+  /* If were defining TYPE, the names used in this class.  */
+  splay_tree names_used;
 }* class_stack_node_t;
 
 /* The stack itself.  This is an dynamically resized array.  The
@@ -117,7 +121,6 @@ static void merge_overrides PROTO((tree, tree, int, tree));
 static void override_one_vtable PROTO((tree, tree, tree));
 static void mark_overriders PROTO((tree, tree));
 static void check_for_override PROTO((tree, tree));
-static tree maybe_fixup_vptrs PROTO((tree, tree, tree));
 static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree));
 static tree get_class_offset PROTO((tree, tree, tree, tree));
 static void modify_one_vtable PROTO((tree, tree, tree, tree));
@@ -126,14 +129,16 @@ static void modify_all_direct_vtables PROTO((tree, int, tree, tree,
                                             tree));
 static void modify_all_indirect_vtables PROTO((tree, int, int, tree,
                                               tree, tree));
-static void build_class_init_list PROTO((tree));
 static int finish_base_struct PROTO((tree, struct base_info *));
 static void finish_struct_methods PROTO((tree));
 static void maybe_warn_about_overly_private_class PROTO ((tree));
-static void check_member_decl_is_same_in_complete_scope PROTO((tree, tree));
 static tree make_method_vec PROTO((int));
 static void free_method_vec PROTO((tree));
 static tree add_implicitly_declared_members PROTO((tree, int, int, int));
+static tree fixed_type_or_null PROTO((tree, int *));
+static tree resolve_address_of_overloaded_function PROTO((tree, tree, int,
+                                                         int, tree));
+static void build_vtable_entry_ref PROTO((tree, tree, tree));
 
 /* Way of stacking language names.  */
 tree *current_lang_base, *current_lang_stack;
@@ -484,7 +489,7 @@ build_vtable_entry_ref (basetype, vtbl, idx)
   i = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i, 0));
   i2 = build_array_ref (vtbl, build_int_2(0,0));
   i2 = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i2, 0));
-  i = build_binary_op (MINUS_EXPR, i, i2, 0);
+  i = build_binary_op (MINUS_EXPR, i, i2);
   i = build_tree_list (build_string (1, "i"), i);
 
   expand_asm_operands (build_string (sizeof(asm_stmt)-1, asm_stmt),
@@ -604,7 +609,7 @@ get_vtable_name (type)
   tree type_id = build_typename_overload (type);
   char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
                               + IDENTIFIER_LENGTH (type_id) + 2);
-  char *ptr = IDENTIFIER_POINTER (type_id);
+  const char *ptr = IDENTIFIER_POINTER (type_id);
   int i;
   for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
 #if 0
@@ -666,6 +671,9 @@ set_rtti_entry (virtuals, offset, type)
 {
   tree vfn;
 
+  if (CLASSTYPE_COM_INTERFACE (type))
+    return;
+
   if (flag_rtti)
     vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type));
   else
@@ -1030,10 +1038,14 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t)
       CLASSTYPE_RTTI (t) = t;
 
       /* If we are using thunks, use two slots at the front, one
-        for the offset pointer, one for the tdesc pointer.  */
-      if (*has_virtual == 0 && flag_vtable_thunks)
+        for the offset pointer, one for the tdesc pointer.
+         For ARM-style vtables, use the same slot for both.  */
+      if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t))
        {
-         *has_virtual = 1;
+         if (flag_vtable_thunks)
+           *has_virtual = 2;
+         else
+           *has_virtual = 1;
        }
 
       /* Build a new INT_CST for this DECL_VINDEX.  */
@@ -1041,7 +1053,7 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t)
        static tree index_table[256];
        tree idx;
        /* We skip a slot for the offset/tdesc entry.  */
-       int i = ++(*has_virtual);
+       int i = (*has_virtual)++;
 
        if (i >= 256 || index_table[i] == 0)
          {
@@ -1282,7 +1294,7 @@ add_method (type, fields, method)
 
              /* We don't call duplicate_decls here to merge the
                 declarations because that will confuse things if the
-                methods have inline definitions In particular, we
+                methods have inline definitions In particular, we
                 will crash while processing the definitions.  */
              return;
            }
@@ -1292,17 +1304,11 @@ add_method (type, fields, method)
       TREE_VEC_ELT (method_vec, slot) 
        = build_overload (method, TREE_VEC_ELT (method_vec, slot));
 
-      if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type))
-       {
-         /* ??? May be better to know whether these can be extended?  */
-         tree baselink_vec = CLASSTYPE_BASELINK_VEC (type);
-         
-         TREE_VEC_LENGTH (baselink_vec) += 1;
-         CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec);
-         TREE_VEC_LENGTH (baselink_vec) -= 1;
-         
-         TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0;
-       }
+      /* Add the new binding.  */ 
+      if (!DECL_CONSTRUCTOR_P (method)
+         && !DECL_DESTRUCTOR_P (method))
+       push_class_level_binding (DECL_NAME (method),
+                                 TREE_VEC_ELT (method_vec, slot));
     }
   pop_obstacks ();
 }
@@ -1539,174 +1545,11 @@ handle_using_decl (using_decl, t, method_vec, fields)
   else
     alter_access (t, binfo, fdecl, access);
 }
-
-/* If FOR_TYPE needs to reinitialize virtual function table pointers
-   for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.
-   Returns BASE_INIT_LIST appropriately modified.  */
-
-static tree
-maybe_fixup_vptrs (for_type, binfo, base_init_list)
-     tree for_type, binfo, base_init_list;
-{
-  /* Now reinitialize any slots that don't fall under our virtual
-     function table pointer.  */
-  tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo));
-  while (vfields)
-    {
-      tree basetype = VF_NORMAL_VALUE (vfields)
-       ? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields))
-         : VF_BASETYPE_VALUE (vfields);
-
-      tree base_binfo = get_binfo (basetype, for_type, 0);
-      /* Punt until this is implemented.  */
-      if (1 /* BINFO_MODIFIED (base_binfo) */)
-       {
-         tree base_offset = get_vfield_offset (base_binfo);
-         if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type)))
-             && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo)))
-           base_init_list = tree_cons (error_mark_node, base_binfo,
-                                       base_init_list);
-       }
-      vfields = TREE_CHAIN (vfields);
-    }
-  return base_init_list;
-}
-
-/* If TYPE does not have a constructor, then the compiler must
-   manually deal with all of the initialization this type requires.
-
-   If a base initializer exists only to fill in the virtual function
-   table pointer, then we mark that fact with the TREE_VIRTUAL bit.
-   This way, we avoid multiple initializations of the same field by
-   each virtual function table up the class hierarchy.
-
-   Virtual base class pointers are not initialized here.  They are
-   initialized only at the "top level" of object creation.  If we
-   initialized them here, we would have to skip a lot of work.  */
-
-static void
-build_class_init_list (type)
-     tree type;
-{
-  tree base_init_list = NULL_TREE;
-  tree member_init_list = NULL_TREE;
-
-  /* Since we build member_init_list and base_init_list using
-     tree_cons, backwards fields the all through work.  */
-  tree x;
-  tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
-  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
-  for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x))
-    {
-      if (TREE_CODE (x) != FIELD_DECL)
-       continue;
-
-      if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x))
-         || DECL_INITIAL (x) != NULL_TREE)
-       member_init_list = tree_cons (x, type, member_init_list);
-    }
-  member_init_list = nreverse (member_init_list);
-
-  /* We will end up doing this last.  Need special marker
-     to avoid infinite regress.  */
-  if (TYPE_VIRTUAL_P (type))
-    {
-      base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type));
-      if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0)
-       TREE_VALUE (base_init_list) = NULL_TREE;
-      TREE_ADDRESSABLE (base_init_list) = 1;
-    }
-
-  /* Each base class which needs to have initialization
-     of some kind gets to make such requests known here.  */
-  for (i = n_baseclasses-1; i >= 0; i--)
-    {
-      tree base_binfo = TREE_VEC_ELT (binfos, i);
-      tree blist;
-
-      /* Don't initialize virtual baseclasses this way.  */
-      if (TREE_VIA_VIRTUAL (base_binfo))
-       continue;
-
-      if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo)))
-       {
-         /* ...and the last shall come first...  */
-         base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);
-         base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
-         continue;
-       }
-
-      if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE)
-       /* Nothing to initialize.  */
-       continue;
-
-      /* ...ditto...  */
-      base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);
-
-      /* This is normally true for single inheritance.
-        The win is we can shrink the chain of initializations
-        to be done by only converting to the actual type
-        we are interested in.  */
-      if (TREE_VALUE (blist)
-         && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC
-         && tree_int_cst_equal (BINFO_OFFSET (base_binfo),
-                                BINFO_OFFSET (TREE_VALUE (blist))))
-       {
-         if (base_init_list)
-           {
-             /* Does it do more than just fill in a
-                virtual function table pointer?  */
-             if (! TREE_ADDRESSABLE (blist))
-               base_init_list = build_tree_list (blist, base_init_list);
-             /* Can we get by just with the virtual function table
-                pointer that it fills in?  */
-             else if (TREE_ADDRESSABLE (base_init_list)
-                      && TREE_VALUE (base_init_list) == 0)
-               base_init_list = blist;
-             /* Maybe, but it is not obvious as the previous case.  */
-             else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type))
-               {
-                 tree last = tree_last (base_init_list);
-                 while (TREE_VALUE (last)
-                        && TREE_CODE (TREE_VALUE (last)) == TREE_LIST)
-                   last = tree_last (TREE_VALUE (last));
-                 if (TREE_VALUE (last) == 0)
-                   base_init_list = build_tree_list (blist, base_init_list);
-               }
-           }
-         else
-           base_init_list = blist;
-       }
-      else
-       {
-         /* The function expand_aggr_init knows how to do the
-            initialization of `basetype' without getting
-            an explicit `blist'.  */
-         if (base_init_list)
-           base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
-         else
-           base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo));
-       }
-    }
-
-  if (base_init_list)
-    {
-      if (member_init_list)
-       CLASSTYPE_BASE_INIT_LIST (type) =
-         build_tree_list (base_init_list, member_init_list);
-      else
-       CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;
-    }
-  else if (member_init_list)
-    CLASSTYPE_BASE_INIT_LIST (type) = member_init_list;
-}
 \f
 struct base_info
 {
   int has_virtual;
   int max_has_virtual;
-  int n_ancestors;
   tree vfield;
   tree vfields;
   tree rtti;
@@ -1789,7 +1632,6 @@ finish_base_struct (t, b)
          && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
        b->no_const_asn_ref = 1;
 
-      b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);
       TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
       TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);
       TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
@@ -1799,8 +1641,20 @@ finish_base_struct (t, b)
       TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
       TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
 
-      if (! TREE_VIA_VIRTUAL (base_binfo))
-       CLASSTYPE_N_SUPERCLASSES (t) += 1;
+      if (CLASSTYPE_COM_INTERFACE (basetype))
+       {
+         CLASSTYPE_COM_INTERFACE (t) = 1;
+         if (i > 0)
+           cp_error
+             ("COM interface type `%T' must be the leftmost base class",
+              basetype);
+       }
+      else if (CLASSTYPE_COM_INTERFACE (t))
+       {
+         cp_error ("COM interface type `%T' with non-COM base class `%T'",
+                   t, basetype);
+         CLASSTYPE_COM_INTERFACE (t) = 0;
+       }
 
       if (TYPE_VIRTUAL_P (basetype))
        {
@@ -1956,14 +1810,14 @@ finish_struct_bits (t, max_has_virtual)
 
   if (n_baseclasses && max_has_virtual)
     {
-      /* for a class w/o baseclasses, `finish_struct' has set
-       * CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly
-       * for a class who's base classes do not have vtables. When neither of
-       * these is true, we might have removed abstract virtuals (by
-       * providing a definition), added some (by declaring new ones), or
-       * redeclared ones from a base class. We need to recalculate what's
-       * really an abstract virtual at this point (by looking in the vtables).
-       */
+      /* For a class w/o baseclasses, `finish_struct' has set
+         CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly
+         for a class who's base classes do not have vtables. When neither
+         of these is true, we might have removed abstract virtuals (by
+         providing a definition), added some (by declaring new ones), or
+         redeclared ones from a base class. We need to recalculate what's
+         really an abstract virtual at this point (by looking in the
+         vtables).  */
       CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
     }
 
@@ -1979,8 +1833,6 @@ finish_struct_bits (t, max_has_virtual)
          basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
 
          TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype);
-         if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t))
-           CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1;
        }
     }
 
@@ -2181,7 +2033,6 @@ finish_struct_methods (t)
   tree fn_fields;
   tree method_vec = CLASSTYPE_METHOD_VEC (t);
   tree ctor_name = constructor_name (t);
-  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
 
   /* First fill in entry 0 with the constructors, entry 1 with destructors,
      and the next few with type conversion operators (if any).  */
@@ -2240,34 +2091,6 @@ finish_struct_methods (t)
   /* Issue warnings about private constructors and such.  If there are
      no methods, then some public defaults are generated.  */
   maybe_warn_about_overly_private_class (t); 
-
-  /* Now for each member function (except for constructors and
-     destructors), compute where member functions of the same
-     name reside in base classes.  */
-  if (n_baseclasses != 0
-      && method_vec
-      && TREE_VEC_LENGTH (method_vec) > 2)
-    {
-      int len = TREE_VEC_LENGTH (method_vec);
-      tree baselink_vec = make_tree_vec (len);
-      int any_links = 0;
-      tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t));
-
-      for (i = 2; i < len && TREE_VEC_ELT (method_vec, i); i++)
-       {
-         tree ovl = TREE_VEC_ELT (method_vec, i);
-
-         TREE_VEC_ELT (baselink_vec, i)
-           = get_baselinks (baselink_binfo, t, 
-                            DECL_NAME (OVL_CURRENT (ovl)));
-         if (TREE_VEC_ELT (baselink_vec, i) != 0)
-           any_links = 1;
-       }
-      if (any_links != 0)
-       CLASSTYPE_BASELINK_VEC (t) = baselink_vec;
-      else
-       obstack_free (current_obstack, baselink_vec);
-    }
 }
 
 /* Emit error when a duplicate definition of a type is seen.  Patch up.  */
@@ -2306,18 +2129,14 @@ duplicate_tag_error (t)
 
   if (TYPE_LANG_SPECIFIC (t))
     {
-      tree as_list = CLASSTYPE_AS_LIST (t);
       tree binfo = TYPE_BINFO (t);
-      tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t);
       int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
       int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
 
       bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type));
       BINFO_BASETYPES(binfo) = NULL_TREE;
 
-      CLASSTYPE_AS_LIST (t) = as_list;
       TYPE_BINFO (t) = binfo;
-      CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list;
       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
       TYPE_REDEFINED (t) = 1;
@@ -2488,11 +2307,14 @@ get_class_offset (context, t, binfo, fndecl)
 /* Skip RTTI information at the front of the virtual list.  */
 
 unsigned HOST_WIDE_INT
-skip_rtti_stuff (virtuals)
-     tree *virtuals;
+skip_rtti_stuff (virtuals, t)
+     tree *virtuals, t;
 {
   int n;
 
+  if (CLASSTYPE_COM_INTERFACE (t))
+    return 0;
+
   n = 0;
   if (*virtuals)
     {
@@ -2534,7 +2356,7 @@ modify_one_vtable (binfo, t, fndecl, pfn)
   if (fndecl == NULL_TREE)
     return;
 
-  n = skip_rtti_stuff (&virtuals);
+  n = skip_rtti_stuff (&virtuals, t);
 
   while (virtuals)
     {
@@ -2628,7 +2450,7 @@ fixup_vtable_deltas1 (binfo, t)
   tree virtuals = BINFO_VIRTUALS (binfo);
   unsigned HOST_WIDE_INT n;
   
-  n = skip_rtti_stuff (&virtuals);
+  n = skip_rtti_stuff (&virtuals, t);
 
   while (virtuals)
     {
@@ -2801,8 +2623,8 @@ override_one_vtable (binfo, old, t)
   if (BINFO_NEW_VTABLE_MARKED (binfo))
     choose = NEITHER;
 
-  skip_rtti_stuff (&virtuals);
-  skip_rtti_stuff (&old_virtuals);
+  skip_rtti_stuff (&virtuals, t);
+  skip_rtti_stuff (&old_virtuals, t);
 
   while (virtuals)
     {
@@ -3321,7 +3143,7 @@ finish_struct_1 (t, warn_anon)
        cp_error ("redefinition of `%#T'", t);
       else
        my_friendly_abort (172);
-      popclass (0);
+      popclass ();
       return t;
     }
 
@@ -3366,7 +3188,6 @@ finish_struct_1 (t, warn_anon)
       CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index;
       has_virtual = base_info.has_virtual;
       max_has_virtual = base_info.max_has_virtual;
-      CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors;
       vfield = base_info.vfield;
       vfields = base_info.vfields;
       CLASSTYPE_RTTI (t) = base_info.rtti;
@@ -3564,7 +3385,7 @@ finish_struct_1 (t, warn_anon)
         has_mutable = 1;
 
       /* If any field is const, the structure type is pseudo-const.  */
-      if (TREE_READONLY (x))
+      if (CP_TYPE_CONST_P (TREE_TYPE (x)))
        {
          C_TYPE_FIELDS_READONLY (t) = 1;
          if (DECL_INITIAL (x) == NULL_TREE)
@@ -3718,7 +3539,7 @@ finish_struct_1 (t, warn_anon)
                      
              if (code == UNION_TYPE)
                {
-                 char *fie = NULL;
+                 const char *fie = NULL;
                  if (TYPE_NEEDS_CONSTRUCTING (type))
                    fie = "constructor";
                  else if (TYPE_NEEDS_DESTRUCTOR (type))
@@ -3895,7 +3716,7 @@ finish_struct_1 (t, warn_anon)
        fields = vfield;
 #endif
       empty = 0;
-      vfields = chainon (vfields, CLASSTYPE_AS_LIST (t));
+      vfields = chainon (vfields, build_tree_list (NULL_TREE, t));
     }
 
   /* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
@@ -3905,32 +3726,6 @@ finish_struct_1 (t, warn_anon)
   /* Delete all duplicate fields from the fields */
   delete_duplicate_fields (fields);
 
-  /* Catch function/field name conflict.  We don't need to do this for a
-     signature, since it can only contain the fields constructed in
-     append_signature_fields.  */
-  if (! IS_SIGNATURE (t))
-    {
-      int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
-      for (x = fields; x; x = TREE_CHAIN (x))
-       {
-         tree name = DECL_NAME (x);
-         int i;
-
-         if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
-           continue;
-
-         for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i)
-           if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
-               == name)
-             {
-               cp_error_at ("data member `%#D' conflicts with", x);
-               cp_error_at ("function member `%#D'",
-                            OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
-               break;
-             }
-       }
-    }
-
   /* Now we have the nearly final fieldlist for the data fields.  Record it,
      then lay out the structure or union (including the fields).  */
 
@@ -3985,7 +3780,7 @@ finish_struct_1 (t, warn_anon)
   if (n_baseclasses)
     /* layout_basetypes will remove the base subobject fields.  */
     max_has_virtual = layout_basetypes (t, max_has_virtual);
-  else if (empty)
+  if (empty)
     TYPE_FIELDS (t) = fields;
 
   my_friendly_assert (TYPE_FIELDS (t) == fields, 981117);
@@ -4010,7 +3805,6 @@ finish_struct_1 (t, warn_anon)
       tree vbases;
 
       vbases = CLASSTYPE_VBASECLASSES (t);
-      CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
 
       {
        /* Now fixup overrides of all functions in vtables from all
@@ -4105,15 +3899,18 @@ finish_struct_1 (t, warn_anon)
       /* We must enter these virtuals into the table.  */
       if (first_vfn_base_index < 0)
        {
-         /* The second slot is for the tdesc pointer when thunks are used.  */
-         if (flag_vtable_thunks)
-           pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
+         if (! CLASSTYPE_COM_INTERFACE (t))
+           {
+             /* The second slot is for the tdesc pointer when thunks are used.  */
+             if (flag_vtable_thunks)
+               pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
 
-         /* The first slot is for the rtti offset.  */
-         pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
+             /* The first slot is for the rtti offset.  */
+             pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
 
-         set_rtti_entry (pending_virtuals,
-                         convert (ssizetype, integer_zero_node), t);
+             set_rtti_entry (pending_virtuals,
+                             convert (ssizetype, integer_zero_node), t);
+           }
          build_vtable (NULL_TREE, t);
        }
       else
@@ -4221,11 +4018,7 @@ finish_struct_1 (t, warn_anon)
            TREE_ADDRESSABLE (vfields) = 1;
          vfields = TREE_CHAIN (vfields);
        }
-      if (any_default_members != 0)
-       build_class_init_list (t);
     }
-  else if (TYPE_NEEDS_CONSTRUCTING (t))
-    build_class_init_list (t);
 
   /* Write out inline function definitions.  */
   do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
@@ -4326,54 +4119,6 @@ finish_struct_1 (t, warn_anon)
   return t;
 }
 
-/* In [basic.scope.class] we have:
-
-     A name N used in a class S shall refer to the same declaration in
-     its context and when re-evaluated in the completed scope of S.
-     
-   This function checks this condition for X, which is a member of
-   T.  */
-
-static void
-check_member_decl_is_same_in_complete_scope (t, x)
-     tree t;
-     tree x;
-{
-  /* A name N used in a class S shall refer to the same declaration in
-     its context and when re-evaluated in the completed scope of S.
-     
-     Enums, types and static vars have already been checked.  */
-  if (TREE_CODE (x) != USING_DECL 
-      && TREE_CODE (x) != TYPE_DECL && !DECL_CLASS_TEMPLATE_P (x)
-      && TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
-    {
-      tree name = DECL_NAME (x);
-      tree icv;
-
-      /* Don't get confused by access decls.  */
-      if (name && TREE_CODE (name) == IDENTIFIER_NODE)
-       icv = IDENTIFIER_CLASS_VALUE (name);
-      else
-       icv = NULL_TREE;
-
-      /* This should match pushdecl_class_level.  */
-      if (icv && icv != x
-         && flag_optional_diags
-         /* Don't complain about constructors.  */
-         && name != constructor_name (current_class_type)
-         /* Or inherited names.  */
-         && id_in_current_class (name)
-         /* Or shadowed tags.  */
-         && !(TREE_CODE (icv) == TYPE_DECL && DECL_CONTEXT (icv) == t))
-       {
-         cp_pedwarn_at ("declaration of identifier `%D' as `%+#D'",
-                        name, x);
-         cp_pedwarn_at ("conflicts with other use in class as `%#D'",
-                        icv);
-       }
-    }
-}
-
 /* When T was built up, the member declarations were added in reverse
    order.  Rearrange them to declaration order.  */
 
@@ -4415,7 +4160,6 @@ finish_struct (t, attributes, warn_anon)
      int warn_anon;
 {
   tree name = TYPE_NAME (t);
-  tree x;
 
   if (TREE_CODE (name) == TYPE_DECL)
     {
@@ -4440,18 +4184,6 @@ finish_struct (t, attributes, warn_anon)
      as necessary.  */
   unreverse_member_declarations (t);
 
-  if (flag_optional_diags) 
-    {
-      for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
-       check_member_decl_is_same_in_complete_scope (t, x);
-      for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
-       check_member_decl_is_same_in_complete_scope (t, x);
-    }
-
-  /* Mark all the tags in the class as class-local.  */
-  for (x = CLASSTYPE_TAGS (t); x; x = TREE_CHAIN (x))
-    TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
-
   cplus_decl_attributes (t, attributes, NULL_TREE);
 
   if (processing_template_decl)
@@ -4481,8 +4213,9 @@ finish_struct (t, attributes, warn_anon)
     t = finish_struct_1 (t, warn_anon);
 
   TYPE_BEING_DEFINED (t) = 0;
+
   if (current_class_type)
-    popclass (0);
+    popclass ();
   else
     error ("trying to finish struct, but kicked out due to previous parse errors.");
 
@@ -4496,7 +4229,7 @@ finish_struct (t, attributes, warn_anon)
    *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
    of our knowledge of its type.  */
 
-tree
+static tree
 fixed_type_or_null (instance, nonnull)
      tree instance;
      int *nonnull;
@@ -4704,6 +4437,7 @@ pushclass (type, modify)
   current_class_stack[current_class_depth].name = current_class_name;
   current_class_stack[current_class_depth].type = current_class_type;
   current_class_stack[current_class_depth].access = current_access_specifier;
+  current_class_stack[current_class_depth].names_used = 0;
   current_class_depth++;
 
   /* Now set up the new type.  */
@@ -4719,12 +4453,12 @@ pushclass (type, modify)
                              : access_public_node);
 
   if (previous_class_type != NULL_TREE
-      && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE)
+      && (type != previous_class_type 
+         || TYPE_SIZE (previous_class_type) == NULL_TREE)
       && current_class_depth == 1)
     {
       /* Forcibly remove any old class remnants.  */
-      popclass (-1);
-      previous_class_type = NULL_TREE;
+      invalidate_class_lookup_cache ();
 
       /* Now, free the obstack on which we cached all the values.  */
       obstack_free (&class_cache_obstack, class_cache_firstobj);
@@ -4732,6 +4466,11 @@ pushclass (type, modify)
        = (char*) obstack_finish (&class_cache_obstack);
     }
 
+  /* If we're about to enter a nested class, clear
+     IDENTIFIER_CLASS_VALUE for the enclosing classes.  */
+  if (modify && current_class_depth > 1)
+    clear_identifier_class_values ();
+
   pushlevel_class ();
 
 #if 0
@@ -4741,26 +4480,8 @@ pushclass (type, modify)
 
   if (modify)
     {
-      tree tags;
-      tree this_fndecl = current_function_decl;
-
-      if (current_function_decl
-         && DECL_CONTEXT (current_function_decl)
-         && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL)
-       current_function_decl = DECL_CONTEXT (current_function_decl);
-      else
-       current_function_decl = NULL_TREE;
-
       if (type != previous_class_type || current_class_depth > 1)
-       {
-#ifdef MI_MATRIX
-         build_mi_matrix (type);
-         push_class_decls (type);
-         free_mi_matrix ();
-#else
-         push_class_decls (type);
-#endif
-       }
+       push_class_decls (type);
       else
        {
          tree item;
@@ -4783,78 +4504,46 @@ pushclass (type, modify)
          unuse_fields (type);
        }
 
-      for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
-       {
-         tree tag_type = TREE_VALUE (tags);
+      storetags (CLASSTYPE_TAGS (type));
+    }
+}
 
-         TREE_NONLOCAL_FLAG (tag_type) = 1;
-         if (! TREE_PURPOSE (tags))
-           continue;
-         if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
-                && CLASSTYPE_IS_TEMPLATE (tag_type)))
-           pushtag (TREE_PURPOSE (tags), tag_type, 0);
-       }
+/* When we exit a toplevel class scope, we save the
+   IDENTIFIER_CLASS_VALUEs so that we can restore them quickly if we
+   reenter the class.  Here, we've entered some other class, so we
+   must invalidate our cache.  */
 
-      current_function_decl = this_fndecl;
-    }
+void
+invalidate_class_lookup_cache ()
+{
+  tree t;
+  
+  /* This code can be seen as a cache miss.  When we've cached a
+     class' scope's bindings and we can't use them, we need to reset
+     them.  This is it!  */
+  for (t = previous_class_values; t; t = TREE_CHAIN (t))
+    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
+  
+  previous_class_type = NULL_TREE;
 }
  
 /* Get out of the current class scope. If we were in a class scope
-   previously, that is the one popped to.  The flag MODIFY tells whether
-   the current scope declarations needs to be modified as a result of
-   popping to the previous scope.  0 is used for class definitions.  */
+   previously, that is the one popped to.  */
 
 void
-popclass (modify)
-     int modify;
+popclass ()
 {
-  if (modify < 0)
-    {
-      /* Back this old class out completely.  */
-      tree tags = CLASSTYPE_TAGS (previous_class_type);
-      tree t;
-
-      /* This code can be seen as a cache miss.  When we've cached a
-        class' scope's bindings and we can't use them, we need to reset
-        them.  This is it!  */
-      for (t = previous_class_values; t; t = TREE_CHAIN (t))
-       IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
-      while (tags)
-       {
-         TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
-         tags = TREE_CHAIN (tags);
-       }
-
-      return;
-    }
-
-  if (modify)
-    {
-      /* Just remove from this class what didn't make
-        it into IDENTIFIER_CLASS_VALUE.  */
-      tree tags = CLASSTYPE_TAGS (current_class_type);
-
-      while (tags)
-       {
-         TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
-         tags = TREE_CHAIN (tags);
-       }
-    }
-
-  /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
-     since not all class decls make it there currently.  */
-  poplevel_class (! modify);
-
+  poplevel (1, 0, 0);
   /* Since poplevel_class does the popping of class decls nowadays,
-     this really only frees the obstack used for these decls.
-     That's why it had to be moved down here.  */
-  if (modify)
-    pop_class_decls ();
+     this really only frees the obstack used for these decls.  */
+  pop_class_decls ();
 
   current_class_depth--;
   current_class_name = current_class_stack[current_class_depth].name;
   current_class_type = current_class_stack[current_class_depth].type;
   current_access_specifier = current_class_stack[current_class_depth].access;
+  if (current_class_stack[current_class_depth].names_used)
+    splay_tree_delete (current_class_stack[current_class_depth].names_used);
 }
 
 /* Returns 1 if current_class_type is either T or a nested type of T.  */
@@ -4895,7 +4584,7 @@ push_nested_class (type, modify)
   
   context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
 
-  if (context && TREE_CODE (context) == RECORD_TYPE)
+  if (context && CLASS_TYPE_P (context))
     push_nested_class (context, 2);
   pushclass (type, modify);
 }
@@ -4903,14 +4592,13 @@ push_nested_class (type, modify)
 /* Undoes a push_nested_class call.  MODIFY is passed on to popclass.  */
 
 void
-pop_nested_class (modify)
-     int modify;
+pop_nested_class ()
 {
   tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
 
-  popclass (modify);
-  if (context && TREE_CODE (context) == RECORD_TYPE)
-    pop_nested_class (modify);
+  popclass ();
+  if (context && CLASS_TYPE_P (context))
+    pop_nested_class ();
 }
 
 /* Set global variables CURRENT_LANG_NAME to appropriate value
@@ -5214,14 +4902,19 @@ resolve_address_of_overloaded_function (target_type,
    try many possible instantiations, in hopes that at least one will
    work.
 
+   FLAGS is a bitmask, as we see at the top of the function.
+
    For non-recursive calls, LHSTYPE should be a function, pointer to
    function, or a pointer to member function.  */
 
 tree
-instantiate_type (lhstype, rhs, complain)
+instantiate_type (lhstype, rhs, flags)
      tree lhstype, rhs;
-     int complain;
+     int flags;
 {
+  int complain = (flags & 1);
+  int strict = (flags & 2) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
+
   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
     {
       if (complain)
@@ -5231,7 +4924,7 @@ instantiate_type (lhstype, rhs, complain)
 
   if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
     {
-      if (same_type_p (lhstype, TREE_TYPE (rhs)))
+      if (comptypes (lhstype, TREE_TYPE (rhs), strict))
        return rhs;
       if (complain)
        cp_error ("argument of type `%T' does not match `%T'",
@@ -5265,7 +4958,7 @@ instantiate_type (lhstype, rhs, complain)
        tree new_rhs;
 
        new_rhs = instantiate_type (build_pointer_type (lhstype),
-                                   TREE_OPERAND (rhs, 0), complain);
+                                   TREE_OPERAND (rhs, 0), flags);
        if (new_rhs == error_mark_node)
          return error_mark_node;
 
@@ -5277,31 +4970,29 @@ instantiate_type (lhstype, rhs, complain)
     case NOP_EXPR:
       rhs = copy_node (TREE_OPERAND (rhs, 0));
       TREE_TYPE (rhs) = unknown_type_node;
-      return instantiate_type (lhstype, rhs, complain);
+      return instantiate_type (lhstype, rhs, flags);
 
     case COMPONENT_REF:
       {
        tree field = TREE_OPERAND (rhs, 1);
        tree r;
 
-       my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
-
-       r = instantiate_type (lhstype, field, complain);
+       r = instantiate_type (lhstype, field, flags);
 
        if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
          {
            if (complain)
              {
                tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
-               tree fn = TREE_VALUE (field);
-               if (TREE_CODE (fn) == OVERLOAD)
-                 fn = OVL_FUNCTION (fn);
-               if (TREE_CODE (fn) == FUNCTION_DECL)
+
+               if (TREE_CODE (field) == OVERLOAD)
+                 field = OVL_FUNCTION (field);
+               if (TREE_CODE (field) == FUNCTION_DECL)
                  {
                    cp_error ("object-dependent reference `%E' can only be used in a call",
-                             DECL_NAME (fn));
+                             DECL_NAME (field));
                    cp_error ("  to form a pointer to member function, say `&%T::%E'",
-                             t, DECL_NAME (fn));
+                             t, DECL_NAME (field));
                  }
                else
                  cp_error ("object-dependent reference can only be used in a call");
@@ -5337,27 +5028,10 @@ instantiate_type (lhstype, rhs, complain)
                                                /*explicit_targs=*/NULL_TREE);
 
     case TREE_LIST:
-      {
-       if (TREE_PURPOSE (rhs) == error_mark_node)
-         {
-           /* Make sure we don't drop the non-local flag, as the old code
-              would rely on it. */
-           int nl = TREE_NONLOCAL_FLAG (rhs);
-           /* We don't need the type of this node. */
-           rhs = TREE_VALUE (rhs);
-           my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331);
-         }
-
-       /* Now we should have a baselink. */
-       my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
-                           980331);
-       my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
-       my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
-                           || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
-                           182);
+      /* Now we should have a baselink. */
+      my_friendly_assert (BASELINK_P (rhs), 990412);
 
-       return instantiate_type (lhstype, TREE_VALUE (rhs), complain);
-      }
+      return instantiate_type (lhstype, TREE_VALUE (rhs), flags);
 
     case CALL_EXPR:
       /* This is too hard for now.  */
@@ -5368,11 +5042,11 @@ instantiate_type (lhstype, rhs, complain)
     case MINUS_EXPR:
     case COMPOUND_EXPR:
       TREE_OPERAND (rhs, 0)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
+       = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
       if (TREE_OPERAND (rhs, 0) == error_mark_node)
        return error_mark_node;
       TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
+       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        return error_mark_node;
 
@@ -5440,11 +5114,11 @@ instantiate_type (lhstype, rhs, complain)
          return error_mark_node;
        }
       TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
+       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        return error_mark_node;
       TREE_OPERAND (rhs, 2)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain);
+       = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);
       if (TREE_OPERAND (rhs, 2) == error_mark_node)
        return error_mark_node;
 
@@ -5453,7 +5127,7 @@ instantiate_type (lhstype, rhs, complain)
 
     case MODIFY_EXPR:
       TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
+       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        return error_mark_node;
 
@@ -5461,7 +5135,7 @@ instantiate_type (lhstype, rhs, complain)
       return rhs;
       
     case ADDR_EXPR:
-      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
+      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
 
     case ENTRY_VALUE_EXPR:
       my_friendly_abort (184);
@@ -5558,8 +5232,6 @@ build_self_reference ()
   DECL_CLASS_CONTEXT (value) = current_class_type;
   DECL_ARTIFICIAL (value) = 1;
 
-  pushdecl_class_level (value);
-
   saved_cas = current_access_specifier;
   current_access_specifier = access_public_node;
   finish_member_declaration (value);
@@ -5636,3 +5308,64 @@ is_base_of_enclosing_class (base, type)
     }
   return 0;
 }
+
+/* Note that NAME was looked up while the current class was being
+   defined and that the result of that lookup was DECL.  */
+
+void
+maybe_note_name_used_in_class (name, decl)
+     tree name;
+     tree decl;
+{
+  splay_tree names_used;
+
+  /* If we're not defining a class, there's nothing to do.  */
+  if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type))
+    return;
+  
+  /* If there's already a binding for this NAME, then we don't have
+     anything to worry about.  */
+  if (IDENTIFIER_CLASS_VALUE (name))
+    return;
+
+  if (!current_class_stack[current_class_depth - 1].names_used)
+    current_class_stack[current_class_depth - 1].names_used
+      = splay_tree_new (splay_tree_compare_pointers, 0, 0);
+  names_used = current_class_stack[current_class_depth - 1].names_used;
+
+  splay_tree_insert (names_used,
+                    (splay_tree_key) name, 
+                    (splay_tree_value) decl);
+}
+
+/* Note that NAME was declared (as DECL) in the current class.  Check
+   to see that the declaration is legal.  */
+
+void
+note_name_declared_in_class (name, decl)
+     tree name;
+     tree decl;
+{
+  splay_tree names_used;
+  splay_tree_node n;
+
+  /* Look to see if we ever used this name.  */
+  names_used 
+    = current_class_stack[current_class_depth - 1].names_used;
+  if (!names_used)
+    return;
+
+  n = splay_tree_lookup (names_used, (splay_tree_key) name);
+  if (n)
+    {
+      /* [basic.scope.class]
+        
+        A name N used in a class S shall refer to the same declaration
+        in its context and when re-evaluated in the completed scope of
+        S.  */
+      cp_error ("declaration of `%#D'", decl);
+      cp_error_at ("changes meaning of `%s' from `%+#D'", 
+                  IDENTIFIER_POINTER (DECL_NAME (decl)),
+                  (tree) n->value);
+    }
+}
This page took 0.058013 seconds and 5 git commands to generate.