class.c (finish_struct_methods): Remove unncessary code.
authorMark Mitchell <mark@codesourcery.com>
Sat, 17 Jul 2004 07:31:08 +0000 (07:31 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 17 Jul 2004 07:31:08 +0000 (07:31 +0000)
* class.c (finish_struct_methods): Remove unncessary code.
(add_implicitly_declared_members): Create declarations for default
constructors and copy constructors lazily.
* cp-tree.h (lang_type_class): Remove lazy_default_ctor and
lazy_copy_ctor.
(CLASSTYPE_LAZY_DEFAULT_CTOR): New macro.
(CLASSTYPE_LAZY_COPY_CTOR): Likewise.
* decl2.c (check_classfn): Robustify.
(locate_dtor): Handle empty CLASSTYPE_METHOD_VEC.
(locate_ctor): Handle lazy default constructors.
(locate_copy): Handle lazy copy constructors.
(implicitly_declare_fn): Make sure we're looking at the
TYPE_MAIN_VARIANT for a class before creating functions.  Don't
set TYPE_HAS_CONSTRUCTOR.
(lazily_declare_fn): New function.
* name-lookup.c (constructor_name_full): Simplify.
* search.c (lookup_fnfields_1): Lazily create methods, as
necessary.
(lookup_for_overrides): Handle empty CLASSTYPE_METHOD_VEC.

From-SVN: r84851

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/method.c
gcc/cp/name-lookup.c
gcc/cp/search.c

index 472b101436e6125ee9edd261660d8a9d58690b19..a67bfc37713892a20caf0e444c2e0aa2bb082451 100644 (file)
@@ -1,3 +1,25 @@
+2004-07-16  Mark Mitchell  <mark@codesourcery.com>
+
+       * class.c (finish_struct_methods): Remove unncessary code.
+       (add_implicitly_declared_members): Create declarations for default
+       constructors and copy constructors lazily.
+       * cp-tree.h (lang_type_class): Remove lazy_default_ctor and
+       lazy_copy_ctor.
+       (CLASSTYPE_LAZY_DEFAULT_CTOR): New macro.
+       (CLASSTYPE_LAZY_COPY_CTOR): Likewise.
+       * decl2.c (check_classfn): Robustify.
+       (locate_dtor): Handle empty CLASSTYPE_METHOD_VEC.
+       (locate_ctor): Handle lazy default constructors.
+       (locate_copy): Handle lazy copy constructors.
+       (implicitly_declare_fn): Make sure we're looking at the
+       TYPE_MAIN_VARIANT for a class before creating functions.  Don't
+       set TYPE_HAS_CONSTRUCTOR.
+       (lazily_declare_fn): New function.
+       * name-lookup.c (constructor_name_full): Simplify.
+       * search.c (lookup_fnfields_1): Lazily create methods, as
+       necessary.
+       (lookup_for_overrides): Handle empty CLASSTYPE_METHOD_VEC.
+
 2004-07-16  Steven Bosscher  <stevenb@suse.de>
 
        * cp-tree.h (struct lang_type): Don't have three GTY options on a
index c916d5fba219db563f8a0e7a17f0c5260eb05888..cc1dc7639000871bc0ee6a741005f94606f4fb82 100644 (file)
@@ -1714,18 +1714,10 @@ finish_struct_methods (tree t)
   VEC(tree) *method_vec;
   int slot, len;
 
-  if (!TYPE_METHODS (t))
-    {
-      /* Clear these for safety; perhaps some parsing error could set
-        these incorrectly.  */
-      TYPE_HAS_CONSTRUCTOR (t) = 0;
-      TYPE_HAS_DESTRUCTOR (t) = 0;
-      CLASSTYPE_METHOD_VEC (t) = NULL;
-      return;
-    }
-
   method_vec = CLASSTYPE_METHOD_VEC (t);
-  my_friendly_assert (method_vec, 19991215);
+  if (!method_vec)
+    return;
+
   len = VEC_length (tree, method_vec);
 
   /* First fill in entry 0 with the constructors, entry 1 with destructors,
@@ -2554,21 +2546,17 @@ add_implicitly_declared_members (tree t,
   /* Default constructor.  */
   if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor)
     {
-      default_fn = implicitly_declare_fn (sfk_constructor, t, /*const_p=*/0);
-      TREE_CHAIN (default_fn) = implicit_fns;
-      implicit_fns = default_fn;
+      TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
+      CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
     }
 
   /* Copy constructor.  */
   if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
     {
-      /* ARM 12.18: You get either X(X&) or X(const X&), but
-        not both.  --Chip  */
-      default_fn 
-       = implicitly_declare_fn (sfk_copy_constructor, t,
-                                /*const_p=*/!cant_have_const_cctor);
-      TREE_CHAIN (default_fn) = implicit_fns;
-      implicit_fns = default_fn;
+      TYPE_HAS_INIT_REF (t) = 1;
+      TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
+      CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
+      TYPE_HAS_CONSTRUCTOR (t) = 1;
     }
 
   /* If there is no assignment operator, one will be created if and
index e7069ba51e8d761df5c526ccf1f53d0c1972879d..a7d35d46ecd0a6a4f0b24b401e92d13bbb75ba3c 100644 (file)
@@ -991,6 +991,8 @@ struct lang_type_class GTY(())
   unsigned ptrmemfunc_flag : 1;
   unsigned was_anonymous : 1;
 
+  unsigned lazy_default_ctor : 1;
+  unsigned lazy_copy_ctor : 1;
   unsigned has_const_init_ref : 1;
   unsigned has_complex_init_ref : 1;
   unsigned has_complex_assign_ref : 1;
@@ -1004,7 +1006,7 @@ struct lang_type_class GTY(())
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 11;
+  unsigned dummy : 9;
 
   tree primary_base;
   tree vfields;
@@ -1089,6 +1091,16 @@ struct lang_type GTY(())
 #define TYPE_HAS_CONVERSION(NODE) \
   (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion)
 
+/* Nonzero means that NODE (a class type) has a default constructor --
+   but that it has not yet been declared.  */
+#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor)
+
+/* Nonzero means that NODE (a class type) has a copy constructor --
+   but that it has not yet been declared.  */
+#define CLASSTYPE_LAZY_COPY_CTOR(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor)
+
 /* Nonzero means that this _CLASSTYPE node overloads operator=(X&).  */
 #define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
 
@@ -3884,6 +3896,7 @@ extern void finish_thunk (tree);
 extern void use_thunk (tree, bool);
 extern void synthesize_method (tree);
 extern tree implicitly_declare_fn (special_function_kind, tree, bool);
+extern tree lazily_declare_fn (special_function_kind, tree);
 extern tree skip_artificial_parms_for (tree, tree);
 
 /* In optimize.c */
index 8467ad62e7b2e9320bba68f3c0ae7e382ff91b94..7257f696952bca817ee7f52655413e8a0ab01862 100644 (file)
@@ -693,9 +693,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
 
          if (!fndecls && is_conv_op)
            {
-             if (VEC_length (tree, methods) > (size_t) ix)
+             if (VEC_length (tree, methods) > (size_t) ++ix)
                {
-                 ix++;
                  fndecls = VEC_index (tree, methods, ix);
                  if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
                    {
index 1a9ecadbd77b1b8685000b5239ae7b4ecaac3ad8..984e0e90557da3b8052f8df473f3e7648d6efce3 100644 (file)
@@ -825,7 +825,9 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
 static tree
 locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
 {
-  return CLASSTYPE_DESTRUCTORS (type);
+  return (CLASSTYPE_METHOD_VEC (type) 
+         ? CLASSTYPE_DESTRUCTORS (type) 
+         : NULL_TREE);
 }
 
 /* Locate the default ctor of TYPE.  */
@@ -838,6 +840,11 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
   if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
     return NULL_TREE;
 
+  /* Call lookup_fnfields_1 to create the constructor declarations, if
+     necessary.  */
+  if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
+    return lazily_declare_fn (sfk_constructor, type);
+
   for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
@@ -864,21 +871,27 @@ locate_copy (tree type, void *client_)
 {
   struct copy_data *client = (struct copy_data *)client_;
   tree fns;
-  int ix = -1;
   tree best = NULL_TREE;
   bool excess_p = false;
   
   if (client->name)
     {
-      if (TYPE_HAS_ASSIGN_REF (type))
-        ix = lookup_fnfields_1 (type, client->name);
+      int ix;
+      ix = lookup_fnfields_1 (type, client->name);
+      if (ix < 0)
+       return NULL_TREE;
+      fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
     }
   else if (TYPE_HAS_INIT_REF (type))
-    ix = CLASSTYPE_CONSTRUCTOR_SLOT;
-  if (ix < 0)
+    {
+      /* If construction of the copy constructor was postponed, create
+        it now.  */
+      if (CLASSTYPE_LAZY_COPY_CTOR (type))
+       lazily_declare_fn (sfk_copy_constructor, type);
+      fns = CLASSTYPE_CONSTRUCTORS (type);
+    }
+  else
     return NULL_TREE;
-  fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
-  
   for (; fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
@@ -927,6 +940,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
   tree rhs_parm_type = NULL_TREE;
   tree name;
 
+  type = TYPE_MAIN_VARIANT (type);
+
   switch (kind)
     {
     case sfk_destructor:
@@ -939,12 +954,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
       /* Default constructor.  */
       name = constructor_name (type);
       raises = synthesize_exception_spec (type, &locate_ctor, 0);
-      TYPE_HAS_CONSTRUCTOR (type) = 1;
       break;
 
     case sfk_copy_constructor:
-      TYPE_HAS_CONSTRUCTOR (type) = 1;
-      /* Fall through. */
     case sfk_assignment_operator:
     {
       struct copy_data data;
@@ -1019,6 +1031,47 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
   return fn;
 }
 
+/* Add an implicit declaration to TYPE for the kind of function
+   indicated by SFK.  Return the FUNCTION_DECL for the new implicit
+   declaration.  */
+
+tree
+lazily_declare_fn (special_function_kind sfk, tree type)
+{
+  tree fn;
+  bool const_p;
+
+  /* Figure out whether or not the argument has a const reference
+     type.  */
+  if (sfk == sfk_copy_constructor)
+    const_p = TYPE_HAS_CONST_INIT_REF (type);
+  else if (sfk == sfk_assignment_operator)
+    const_p = TYPE_HAS_CONST_ASSIGN_REF (type);
+  else
+    /* In this case, CONST_P will be ignored.  */
+    const_p = false;
+  /* Declare the function.  */
+  fn = implicitly_declare_fn (sfk, type, const_p);
+  /* Add it to CLASSTYPE_METHOD_VEC.  */
+  add_method (type, fn);
+  /* Add it to TYPE_METHODS.  */
+  TREE_CHAIN (fn) = TYPE_METHODS (type);
+  TYPE_METHODS (type) = fn;
+  maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
+  if (sfk == sfk_constructor || sfk == sfk_copy_constructor)
+    {
+      /* Remember that the function has been created.  */
+      if (sfk == sfk_constructor)
+       CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
+      else
+       CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
+      /* Create appropriate clones.  */
+      clone_function_decl (fn, /*update_method_vec=*/true);
+    }
+
+  return fn;
+}
+
 /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
    as there are artificial parms in FN.  */
 
index fd3776faf512cb64cbc76f6840b9f06fe7ee39b5..3a2f71ccaf71ad3162a4b37d746210853088cb3f 100644 (file)
@@ -1794,12 +1794,7 @@ set_identifier_type_value (tree id, tree decl)
 tree
 constructor_name_full (tree type)
 {
-  type = TYPE_MAIN_VARIANT (type);
-  if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type) 
-      && TYPE_HAS_CONSTRUCTOR (type))
-    return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
-  else
-    return TYPE_IDENTIFIER (type);
+  return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
 }
 
 /* Return the name for the constructor (or destructor) for the
index 97b97899e4fad045f44f0160b671e982ecfbf78d..ceefa3cd05f1c3c98f6d65463e1e0d3e4ccdc2aa 100644 (file)
@@ -1368,8 +1368,24 @@ lookup_fnfields_1 (tree type, tree name)
   if (!CLASS_TYPE_P (type))
     return -1;
 
-  method_vec = CLASSTYPE_METHOD_VEC (type);
+  if (COMPLETE_TYPE_P (type))
+    {
+      if ((name == ctor_identifier
+          || name == base_ctor_identifier
+          || name == complete_ctor_identifier))
+       {
+         if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
+           lazily_declare_fn (sfk_constructor, type);
+         if (CLASSTYPE_LAZY_COPY_CTOR (type))
+           lazily_declare_fn (sfk_copy_constructor, type);
+       }
+      else if (name == ansi_assopname(NOP_EXPR)
+              && !TYPE_HAS_ASSIGN_REF (type)
+              && !TYPE_FOR_JAVA (type))
+       lazily_declare_fn (sfk_assignment_operator, type);
+    }
 
+  method_vec = CLASSTYPE_METHOD_VEC (type);
   if (!method_vec)
     return -1;
 
@@ -1405,24 +1421,6 @@ lookup_fnfields_1 (tree type, tree name)
       int lo;
       int hi;
 
-      /* All non-Java classes have "operator=" -- but we do not
-        actually create the declaration until it is needed.  */
-      if (name == ansi_assopname(NOP_EXPR)
-         && !TYPE_HAS_ASSIGN_REF (type)
-         && !TYPE_FOR_JAVA (type))
-       {
-         tree fn;
-
-         /* Declare the function.  */
-         fn = implicitly_declare_fn (sfk_assignment_operator, type,
-                                     TYPE_HAS_CONST_ASSIGN_REF (type));
-         add_method (type, fn);
-         TREE_CHAIN (fn) = TYPE_METHODS (type);
-         TYPE_METHODS (type) = fn;
-         maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
-         method_vec = CLASSTYPE_METHOD_VEC (type);
-       }
-
       lo = i;
       hi = VEC_length (tree, method_vec);
       while (lo < hi)
@@ -1789,6 +1787,12 @@ look_for_overrides_here (tree type, tree fndecl)
 {
   int ix;
 
+  /* If there are no methods in TYPE (meaning that only implicitly
+     declared methods will ever be provided for TYPE), then there are
+     no virtual functions.  */
+  if (!CLASSTYPE_METHOD_VEC (type))
+    return NULL_TREE;
+
   if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fndecl))
     ix = CLASSTYPE_DESTRUCTOR_SLOT;
   else