OSDN Git Service

fix bogus email for myself
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index 38eb73f..88db80f 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -297,7 +297,7 @@ build_base_path (enum tree_code code,
     {
       expr = build_nop (build_pointer_type (target_type), expr);
       if (!want_pointer)
-       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL);
+       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
       return expr;
     }
 
@@ -343,7 +343,7 @@ build_base_path (enum tree_code code,
         interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
       expr = build_simple_base_path (expr, binfo);
       if (want_pointer)
        expr = build_address (expr);
@@ -368,11 +368,11 @@ build_base_path (enum tree_code code,
          t = TREE_TYPE (TYPE_VFIELD (current_class_type));
          t = build_pointer_type (t);
          v_offset = convert (t, current_vtt_parm);
-         v_offset = cp_build_indirect_ref (v_offset, NULL, 
+         v_offset = cp_build_indirect_ref (v_offset, RO_NULL, 
                                             tf_warning_or_error);
        }
       else
-       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, NULL,
+       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
                                                             tf_warning_or_error),
                                     TREE_TYPE (TREE_TYPE (expr)));
 
@@ -381,7 +381,7 @@ build_base_path (enum tree_code code,
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
-      v_offset = cp_build_indirect_ref (v_offset, NULL, tf_warning_or_error);
+      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error);
       TREE_CONSTANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
@@ -424,7 +424,7 @@ build_base_path (enum tree_code code,
     null_test = NULL;
 
   if (!want_pointer)
-    expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+    expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
 
  out:
   if (null_test)
@@ -458,7 +458,7 @@ build_simple_base_path (tree expr, tree binfo)
         in the back end.  */
       temp = unary_complex_lvalue (ADDR_EXPR, expr);
       if (temp)
-       expr = cp_build_indirect_ref (temp, NULL, tf_warning_or_error);
+       expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
 
       return expr;
     }
@@ -506,10 +506,12 @@ build_simple_base_path (tree expr, tree binfo)
    assumed to be non-NULL.  */
 
 tree
-convert_to_base (tree object, tree type, bool check_access, bool nonnull)
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+                tsubst_flags_t complain)
 {
   tree binfo;
   tree object_type;
+  base_access access;
 
   if (TYPE_PTR_P (TREE_TYPE (object)))
     {
@@ -519,8 +521,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull)
   else
     object_type = TREE_TYPE (object);
 
+  access = check_access ? ba_check : ba_unique;
+  if (!(complain & tf_error))
+    access |= ba_quiet;
   binfo = lookup_base (object_type, type,
-                      check_access ? ba_check : ba_unique,
+                      access,
                       NULL);
   if (!binfo || binfo == error_mark_node)
     return error_mark_node;
@@ -575,7 +580,7 @@ build_vfield_ref (tree datum, tree type)
   /* First, convert to the requested type.  */
   if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
     datum = convert_to_base (datum, type, /*check_access=*/false,
-                            /*nonnull=*/true);
+                            /*nonnull=*/true, tf_warning_or_error);
 
   /* Second, the requested type may not be the owner of its own vptr.
      If not, convert to the base class that owns it.  We cannot use
@@ -646,7 +651,7 @@ build_vfn_ref (tree instance_ptr, tree idx)
 {
   tree aref;
 
-  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, 0,
+  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
                                                   tf_warning_or_error), 
                            idx);
 
@@ -2781,14 +2786,8 @@ check_bitfield_decl (tree field)
               && TREE_CODE (type) != BOOLEAN_TYPE)
        warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
-              && (0 > compare_tree_int (w,
-                                        tree_int_cst_min_precision
-                                        (TYPE_MIN_VALUE (type),
-                                         TYPE_UNSIGNED (type)))
-                  ||  0 > compare_tree_int (w,
-                                            tree_int_cst_min_precision
-                                            (TYPE_MAX_VALUE (type),
-                                             TYPE_UNSIGNED (type)))))
+              && (0 > (compare_tree_int
+                       (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
        warning (0, "%q+D is too small to hold all values of %q#T", field, type);
     }
 
@@ -4177,6 +4176,34 @@ type_has_user_nondefault_constructor (tree t)
   return false;
 }
 
+/* Returns the defaulted constructor if T has one. Otherwise, returns
+   NULL_TREE.  */
+
+tree
+in_class_defaulted_default_constructor (tree t)
+{
+  tree fns, args;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return NULL_TREE;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+
+      if (DECL_DEFAULTED_IN_CLASS_P (fn))
+       {
+         args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+         while (args && TREE_PURPOSE (args))
+           args = TREE_CHAIN (args);
+         if (!args || args == void_list_node)
+           return fn;
+       }
+    }
+
+  return NULL_TREE;
+}
+
 /* Returns true iff FN is a user-provided function, i.e. user-declared
    and not defaulted at its first declaration; or explicit, private,
    protected, or non-const.  */
@@ -4254,7 +4281,12 @@ remove_zero_width_bit_fields (tree t)
     {
       if (TREE_CODE (*fieldsp) == FIELD_DECL
          && DECL_C_BIT_FIELD (*fieldsp)
-         && DECL_INITIAL (*fieldsp))
+          /* We should not be confused by the fact that grokbitfield
+            temporarily sets the width of the bit field into
+            DECL_INITIAL (*fieldsp).
+            check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
+            to that width.  */
+         && integer_zerop (DECL_SIZE (*fieldsp)))
        *fieldsp = TREE_CHAIN (*fieldsp);
       else
        fieldsp = &TREE_CHAIN (*fieldsp);
@@ -4549,6 +4581,8 @@ create_vtable_ptr (tree t, tree* virtuals_p)
       DECL_ARTIFICIAL (field) = 1;
       DECL_FIELD_CONTEXT (field) = t;
       DECL_FCONTEXT (field) = t;
+      if (TYPE_PACKED (t))
+       DECL_PACKED (field) = 1;
 
       TYPE_VFIELD (t) = field;
 
@@ -5037,6 +5071,7 @@ layout_class_type (tree t, tree *virtuals_p)
       /* G++ used to use DECL_FIELD_OFFSET as if it were the byte
         offset of the field.  */
       if (warn_abi
+         && !abi_version_at_least (2)
          && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
                                  byte_position (field))
          && contains_empty_class_p (TREE_TYPE (field)))
@@ -5211,6 +5246,11 @@ layout_class_type (tree t, tree *virtuals_p)
                 build_decl (input_location,
                             FIELD_DECL, NULL_TREE, char_type_node));
 
+  /* If this is a non-POD, declaring it packed makes a difference to how it
+     can be used as a field; don't let finalize_record_size undo it.  */
+  if (TYPE_PACKED (t) && !layout_pod_type_p (t))
+    rli->packed_maybe_necessary = true;
+
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
@@ -5925,6 +5965,34 @@ currently_open_derived_class (tree t)
   return NULL_TREE;
 }
 
+/* Returns the innermost class type which is not a lambda closure type.  */
+
+tree
+current_nonlambda_class_type (void)
+{
+  int i;
+
+  /* We start looking from 1 because entry 0 is from global scope,
+     and has no type.  */
+  for (i = current_class_depth; i > 0; --i)
+    {
+      tree c;
+      if (i == current_class_depth)
+       c = current_class_type;
+      else
+       {
+         if (current_class_stack[i].hidden)
+           break;
+         c = current_class_stack[i].type;
+       }
+      if (!c)
+       continue;
+      if (!LAMBDA_TYPE_P (c))
+       return c;
+    }
+  return NULL_TREE;
+}
+
 /* When entering a class scope, all enclosing class scopes' names with
    static meaning (static variables, static functions, types and
    enumerators) have to be visible.  This recursive function calls
@@ -6059,7 +6127,6 @@ resolve_address_of_overloaded_function (tree target_type,
        selected function.  */
 
   int is_ptrmem = 0;
-  int is_reference = 0;
   /* We store the matches in a TREE_LIST rooted here.  The functions
      are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
      interoperability with most_specialized_instantiation.  */
@@ -6082,12 +6149,9 @@ resolve_address_of_overloaded_function (tree target_type,
     /* This is OK, too.  */
     is_ptrmem = 1;
   else if (TREE_CODE (target_type) == FUNCTION_TYPE)
-    {
-      /* This is OK, too.  This comes from a conversion to reference
-        type.  */
-      target_type = build_reference_type (target_type);
-      is_reference = 1;
-    }
+    /* This is OK, too.  This comes from a conversion to reference
+       type.  */
+    target_type = build_reference_type (target_type);
   else
     {
       if (flags & tf_error)
@@ -6334,7 +6398,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 
   flags &= ~tf_ptrmem_ok;
 
-  if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
+  if (lhstype == unknown_type_node)
     {
       if (flags & tf_error)
        error ("not enough type information");
@@ -6513,7 +6577,7 @@ build_self_reference (void)
   DECL_CONTEXT (value) = current_class_type;
   DECL_ARTIFICIAL (value) = 1;
   SET_DECL_SELF_REFERENCE_P (value);
-  set_underlying_type (value);
+  cp_set_underlying_type (value);
 
   if (processing_template_decl)
     value = push_template_decl (value);
@@ -8043,12 +8107,10 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
 {
   tree b;
   tree t;
-  tree basetype;
   tree offset;
   tree decl;
   tree init;
 
-  basetype = BINFO_TYPE (binfo);
   t = BINFO_TYPE (vid->rtti_binfo);
 
   /* To find the complete object, we will first convert to our most