OSDN Git Service

(struct function): Make frame_offset be HOST_WIDE_INT.
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck2.c
index ea24acb..1c00297 100644 (file)
@@ -44,6 +44,7 @@ extern int sorrycount;
 
 /* Print an error message stemming from an attempt to use
    BASETYPE as a base class for TYPE.  */
+
 tree
 error_not_base_type (basetype, type)
      tree basetype, type;
@@ -71,33 +72,11 @@ binfo_or_else (parent_or_type, type)
   return NULL_TREE;
 }
 
-/* Print an error message stemming from an invalid use of an
-   aggregate type.
-
-   TYPE is the type or binfo which draws the error.
-   MSG is the message to print.
-   ARG is an optional argument which may provide more information.  */
-void
-error_with_aggr_type (type, msg, arg)
-     tree type;
-     char *msg;
-     HOST_WIDE_INT arg;
-{
-  tree name;
-
-  if (TREE_CODE (type) == TREE_VEC)
-    type = BINFO_TYPE (type);
-
-  name = TYPE_NAME (type);
-  if (TREE_CODE (name) == TYPE_DECL)
-    name = DECL_NAME (name);
-  error (msg, IDENTIFIER_POINTER (name), arg);
-}
-
 /* According to ARM $7.1.6, "A `const' object may be initialized, but its
    value may not be changed thereafter.  Thus, we emit hard errors for these,
    rather than just pedwarns.  If `SOFT' is 1, then we just pedwarn.  (For
    example, conversions to references.)  */
+
 void
 readonly_error (arg, string, soft)
      tree arg;
@@ -108,46 +87,44 @@ readonly_error (arg, string, soft)
   void (*fn)();
 
   if (soft)
-    fn = pedwarn;
+    fn = cp_pedwarn;
   else
-    fn = error;
+    fn = cp_error;
 
   if (TREE_CODE (arg) == COMPONENT_REF)
     {
       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
-        fmt = "%s of member `%s' in read-only structure";
+        fmt = "%s of member `%D' in read-only structure";
       else
-        fmt = "%s of read-only member `%s'";
-      (*fn) (fmt, string, lang_printable_name (TREE_OPERAND (arg, 1)));
+        fmt = "%s of read-only member `%D'";
+      (*fn) (fmt, string, TREE_OPERAND (arg, 1));
     }
   else if (TREE_CODE (arg) == VAR_DECL)
     {
       if (DECL_LANG_SPECIFIC (arg)
          && DECL_IN_AGGR_P (arg)
          && !TREE_STATIC (arg))
-       fmt = "%s of constant field `%s'";
+       fmt = "%s of constant field `%D'";
       else
-       fmt = "%s of read-only variable `%s'";
-      (*fn) (fmt, string, lang_printable_name (arg));
+       fmt = "%s of read-only variable `%D'";
+      (*fn) (fmt, string, arg);
     }
   else if (TREE_CODE (arg) == PARM_DECL)
-    (*fn) ("%s of read-only parameter `%s'", string,
-          lang_printable_name (arg));
+    (*fn) ("%s of read-only parameter `%D'", string, arg);
   else if (TREE_CODE (arg) == INDIRECT_REF
            && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
            && (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
                || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
-    (*fn) ("%s of read-only reference `%s'",
-          string, lang_printable_name (TREE_OPERAND (arg, 0)));
+    (*fn) ("%s of read-only reference `%D'", string, TREE_OPERAND (arg, 0));
   else if (TREE_CODE (arg) == RESULT_DECL)
-    (*fn) ("%s of read-only named return value `%s'",
-          string, lang_printable_name (arg));
+    (*fn) ("%s of read-only named return value `%D'", string, arg);
   else        
     (*fn) ("%s of read-only location", string);
 }
 
 /* Print an error message for invalid use of a type which declares
    virtual functions which are not inheritable.  */
+
 void
 abstract_virtuals_error (decl, type)
      tree decl;
@@ -193,6 +170,7 @@ abstract_virtuals_error (decl, type)
 /* Print an error message for invalid use of a signature type.
    Signatures are treated similar to abstract classes here, they
    cannot be instantiated.  */
+
 void
 signature_error (decl, type)
      tree decl;
@@ -239,8 +217,7 @@ incomplete_type_error (value, type)
 
   if (value != 0 && (TREE_CODE (value) == VAR_DECL
                     || TREE_CODE (value) == PARM_DECL))
-    error ("`%s' has an incomplete type",
-          IDENTIFIER_POINTER (DECL_NAME (value)));
+    cp_error ("`%D' has incomplete type", value);
   else
     {
     retry:
@@ -249,15 +226,9 @@ incomplete_type_error (value, type)
       switch (TREE_CODE (type))
        {
        case RECORD_TYPE:
-         errmsg = "invalid use of undefined type `struct %s'";
-         break;
-
        case UNION_TYPE:
-         errmsg = "invalid use of undefined type `union %s'";
-         break;
-
        case ENUMERAL_TYPE:
-         errmsg = "invalid use of undefined type `enum %s'";
+         errmsg = "invalid use of undefined type `%#T'";
          break;
 
        case VOID_TYPE:
@@ -281,11 +252,12 @@ incomplete_type_error (value, type)
          my_friendly_abort (108);
        }
 
-      error_with_aggr_type (type, errmsg);
+      cp_error (errmsg, type);
     }
 }
 
 /* Like error(), but don't call report_error_function().  */
+
 static void
 ack (s, v, v2)
      char *s;
@@ -330,7 +302,7 @@ ack (s, v, v2)
    silly.  So instead, we just do the equivalent of a call to fatal in the
    same situation (call exit).  */
 
-/* First used: 0 (reserved), Last used: 366.  Free: */
+/* First used: 0 (reserved), Last used: 367.  Free: */
 
 static int abortcount = 0;
 
@@ -468,8 +440,8 @@ initializer_constant_valid_p (value, endtype)
       return 0;
 
     case PLUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
+      if ((TREE_CODE (endtype) == INTEGER_TYPE)
+         && (TYPE_PRECISION (endtype) < POINTER_SIZE))
        return 0;
       {
        tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
@@ -485,8 +457,8 @@ initializer_constant_valid_p (value, endtype)
       }
 
     case MINUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
+      if ((TREE_CODE (endtype) == INTEGER_TYPE)
+         && (TYPE_PRECISION (endtype) < POINTER_SIZE))
        return 0;
       {
        tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
@@ -569,8 +541,6 @@ store_init_value (decl, init)
       if (TREE_CODE (init) == CONSTRUCTOR)
        {
          tree field;
-         tree funcs;
-         int func;
 
          /* Check that we're really an aggregate as ARM 8.4.1 defines it.  */
          if (CLASSTYPE_N_BASECLASSES (type))
@@ -588,16 +558,11 @@ store_init_value (decl, init)
                cp_error_at ("initializer list construction invalid for `%D'", decl);
                cp_error_at ("due to non-public access of member `%D'", field);
              }
-         funcs = TYPE_METHODS (type);
-         if (funcs)
-           for (func = 0; func < TREE_VEC_LENGTH (funcs); func++)
+         for (field = TYPE_METHODS (type); field; field = TREE_CHAIN (field))
+           if (TREE_PRIVATE (field) || TREE_PROTECTED (field))
              {
-               field = TREE_VEC_ELT (funcs, func);
-               if (field && (TREE_PRIVATE (field) || TREE_PROTECTED (field)))
-                 {
-                   cp_error_at ("initializer list construction invalid for `%D'", decl);
-                   cp_error_at ("due to non-public access of member `%D'", field);
-                 }
+               cp_error_at ("initializer list construction invalid for `%D'", decl);
+               cp_error_at ("due to non-public access of member `%D'", field);
              }
        }
 #endif
@@ -642,6 +607,10 @@ store_init_value (decl, init)
        }
     }
 
+  if (TYPE_PTRMEMFUNC_P (type) && TREE_CODE (init) == CONSTRUCTOR
+      && TREE_TYPE (init) == NULL_TREE)
+    cp_pedwarn ("initializer list for `%T'", type);
+
   /* End of special C++ code.  */
 
   /* Digest the specified initializer into an expression.  */
@@ -860,7 +829,9 @@ digest_init (type, init, tail)
            }
          init = element;
        }
-      while (TREE_CODE (init) == CONSTRUCTOR)
+      while (TREE_CODE (init) == CONSTRUCTOR
+            && ! (TREE_TYPE (init)
+                  && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))))
        {
          cp_pedwarn ("braces around scalar initializer for `%T'", type);
          init = CONSTRUCTOR_ELTS (init);
@@ -884,28 +855,35 @@ digest_init (type, init, tail)
 
   if (code == ARRAY_TYPE || code == RECORD_TYPE || code == UNION_TYPE)
     {
-      if (raw_constructor)
+      if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type))
+       {
+         cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
+                   type, init);
+         return error_mark_node;
+       }
+      else if (raw_constructor)
        return process_init_constructor (type, init, (tree *)0);
-      else if (TYPE_NEEDS_CONSTRUCTING (type))
+      else if (TYPE_NON_AGGREGATE_CLASS (type))
        {
+#if 0
+         /* This isn't true.  */
          /* This can only be reached when caller is initializing
             ARRAY_TYPE.  In that case, we don't want to convert
             INIT to TYPE.  We will let `expand_vec_init' do it.  */
          return init;
+#else
+         return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
+                                            "initialization", NULL_TREE, 0);
+#endif
        }
       else if (tail != 0)
        {
          *tail = old_tail_contents;
          return process_init_constructor (type, 0, tail);
        }
-      else if (flag_traditional)
-       /* Traditionally one can say `char x[100] = 0;'.  */
-       return process_init_constructor (type,
-                                        build_nt (CONSTRUCTOR, 0,
-                                                  tree_cons (0, init, 0)),
-                                        0);
+
       if (code != ARRAY_TYPE)
-       return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
+       return convert_for_initialization (NULL_TREE, type, init, LOOKUP_NORMAL,
                                           "initialization", NULL_TREE, 0);
     }
 
@@ -1111,7 +1089,8 @@ process_init_constructor (type, init, elts)
 
       /* Find the first named field.  ANSI decided in September 1990
         that only named fields count here.  */
-      while (field && DECL_NAME (field) == 0)
+      while (field && (DECL_NAME (field) == 0
+                      || TREE_CODE (field) != FIELD_DECL))
        field = TREE_CHAIN (field);
 
       /* If this element specifies a field, initialize via that field.  */
@@ -1194,7 +1173,7 @@ process_init_constructor (type, init, elts)
 \f
 /* Given a structure or union value DATUM, construct and return
    the structure or union component which results from narrowing
-   that value by the types specified in TYPES.  For example, given the
+   that value by the type specified in BASETYPE.  For example, given the
    hierarchy
 
    class L { int ii; };
@@ -1208,23 +1187,14 @@ process_init_constructor (type, init, elts)
 
    then the expression
 
-   x::C::A::L::ii refers to the ii member of the L part of
+   x.A::ii refers to the ii member of the L part of
    of A part of the C object named by X.  In this case,
-   DATUM would be x, and TYPES would be a SCOPE_REF consisting of
-
-       SCOPE_REF
-               SCOPE_REF
-                       C       A
-               L
-
-   The last entry in the SCOPE_REF is always an IDENTIFIER_NODE.
-
-*/
+   DATUM would be x, and BASETYPE would be A.  */
 
 tree
-build_scoped_ref (datum, types)
+build_scoped_ref (datum, basetype)
      tree datum;
-     tree types;
+     tree basetype;
 {
   tree ref;
   tree type = TREE_TYPE (datum);
@@ -1237,62 +1207,17 @@ build_scoped_ref (datum, types)
 
   type = TYPE_MAIN_VARIANT (type);
 
-  if (TREE_CODE (types) == SCOPE_REF)
-    {
-      /* We have some work to do.  */
-      struct type_chain
-       { tree type; struct type_chain *next; }
-      *chain = NULL, *head = NULL, scratch;
-      ref = build_unary_op (ADDR_EXPR, datum, 0);
-      while (TREE_CODE (types) == SCOPE_REF)
-       {
-         tree t = TREE_OPERAND (types, 1);
-         if (is_aggr_typedef (t, 1))
-           {
-             head = (struct type_chain *)alloca (sizeof (struct type_chain));
-             head->type = IDENTIFIER_TYPE_VALUE (t);
-             head->next = chain;
-             chain = head;
-             types = TREE_OPERAND (types, 0);
-           }
-         else return error_mark_node;
-       }
-      if (! is_aggr_typedef (types, 1))
-       return error_mark_node;
-
-      head = &scratch;
-      head->type = IDENTIFIER_TYPE_VALUE (types);
-      head->next = chain;
-      chain = head;
-      while (chain)
-       {
-         tree binfo = chain->type;
-         type = TREE_TYPE (TREE_TYPE (ref));
-         if (binfo != TYPE_BINFO (type))
-           {
-             binfo = get_binfo (binfo, type, 1);
-             if (binfo == error_mark_node)
-               return error_mark_node;
-             if (binfo == 0)
-               return error_not_base_type (chain->type, type);
-             ref = convert_pointer_to (binfo, ref);
-           }
-         chain = chain->next;
-       }
-      return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
-    }
-
   /* This is an easy conversion.  */
-  if (is_aggr_typedef (types, 1))
+  if (is_aggr_type (basetype, 1))
     {
-      tree binfo = TYPE_BINFO (IDENTIFIER_TYPE_VALUE (types));
+      tree binfo = TYPE_BINFO (basetype);
       if (binfo != TYPE_BINFO (type))
        {
          binfo = get_binfo (binfo, type, 1);
          if (binfo == error_mark_node)
            return error_mark_node;
          if (binfo == 0)
-           return error_not_base_type (IDENTIFIER_TYPE_VALUE (types), type);
+           return error_not_base_type (basetype, type);
        }
 
       switch (TREE_CODE (datum))
@@ -1322,6 +1247,7 @@ build_scoped_ref (datum, types)
    performed until an object which does not have the `->' operator
    overloaded is found.  An error is reported when circular pointer
    delegation is detected.  */
+
 tree
 build_x_arrow (datum)
      tree datum;
@@ -1334,6 +1260,9 @@ build_x_arrow (datum)
   if (type == error_mark_node)
     return error_mark_node;
 
+  if (processing_template_decl)
+    return build_min_nt (ARROW_EXPR, rval);
+
   if (TREE_CODE (rval) == OFFSET_REF)
     {
       rval = resolve_offset_ref (datum);
@@ -1346,7 +1275,7 @@ build_x_arrow (datum)
       type = TREE_TYPE (rval);
     }
 
-  if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (type))
+  if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (complete_type (type)))
     {
       while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, NULL_TREE, NULL_TREE)))
        {
@@ -1397,6 +1326,7 @@ build_x_arrow (datum)
    As a special case, if there is only one method by that name,
    it is returned.  Otherwise we return an expression which other
    routines will have to know how to deal with later.  */
+
 tree
 build_m_component_ref (datum, component)
      tree datum, component;
@@ -1406,6 +1336,9 @@ build_m_component_ref (datum, component)
   tree rettype;
   tree binfo;
 
+  if (processing_template_decl)
+    return build_min_nt (DOTSTAR_EXPR, datum, component);
+
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
     {
       type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
@@ -1415,7 +1348,7 @@ build_m_component_ref (datum, component)
     {
       component = build_indirect_ref (component, NULL_PTR);
       type = TREE_TYPE (component);
-      rettype = TREE_TYPE (TREE_TYPE (component));
+      rettype = TREE_TYPE (type);
     }
 
   if (datum == error_mark_node || component == error_mark_node)
@@ -1451,28 +1384,24 @@ build_m_component_ref (datum, component)
   return build (OFFSET_REF, rettype, datum, component);
 }
 
-/* Return a tree node for the expression TYPENAME '(' PARMS ')'.
+/* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
 
-   Because we cannot tell whether this construct is really a call to a
-   constructor or a request for a type conversion, we try both, and
-   report any ambiguities we find.  */
 tree
 build_functional_cast (exp, parms)
      tree exp;
      tree parms;
 {
+  tree binfo;
+
   /* This is either a call to a constructor,
      or a C cast in C++'s `functional' notation.  */
-  tree type, name = NULL_TREE;
-  tree expr_as_ctor = NULL_TREE;
+  tree type;
 
   if (exp == error_mark_node || parms == error_mark_node)
     return error_mark_node;
 
   if (TREE_CODE (exp) == IDENTIFIER_NODE)
     {
-      name = exp;
-
       if (IDENTIFIER_HAS_TYPE_VALUE (exp))
        /* Either an enum or an aggregate type.  */
        type = IDENTIFIER_TYPE_VALUE (exp);
@@ -1481,35 +1410,26 @@ build_functional_cast (exp, parms)
          type = lookup_name (exp, 1);
          if (!type || TREE_CODE (type) != TYPE_DECL)
            {
-             cp_error ("`%T' fails to be a typedef or built-in type", name);
+             cp_error ("`%T' fails to be a typedef or built-in type", exp);
              return error_mark_node;
            }
          type = TREE_TYPE (type);
        }
     }
+  else if (TREE_CODE (exp) == TYPE_DECL)
+    type = TREE_TYPE (exp);
   else
     type = exp;
 
+  if (processing_template_decl)
+    return build_min (CAST_EXPR, type, parms);
+
   if (IS_SIGNATURE (type))
     {
       error ("signature type not allowed in cast or constructor expression");
       return error_mark_node;
     }
 
-  /* Prepare to evaluate as a call to a constructor.  If this expression
-     is actually used, for example,
-        
-     return X (arg1, arg2, ...);
-        
-     then the slot being initialized will be filled in.  */
-
-  if (name == NULL_TREE)
-    {
-      name = TYPE_NAME (type);
-      if (TREE_CODE (name) == TYPE_DECL)
-       name = DECL_NESTED_TYPENAME (name);
-    }
-
   if (! IS_AGGR_TYPE (type))
     {
       /* this must build a C cast */
@@ -1525,26 +1445,34 @@ build_functional_cast (exp, parms)
       return build_c_cast (type, parms, 1);
     }
 
-  if (TYPE_SIZE (type) == NULL_TREE)
+  /* Prepare to evaluate as a call to a constructor.  If this expression
+     is actually used, for example,
+        
+     return X (arg1, arg2, ...);
+        
+     then the slot being initialized will be filled in.  */
+
+  if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
     {
       cp_error ("type `%T' is not yet defined", type);
       return error_mark_node;
     }
 
   if (parms && TREE_CHAIN (parms) == NULL_TREE)
-    return build_c_cast (type, parms, 1);
+    return build_c_cast (type, TREE_VALUE (parms), 1);
 
-  expr_as_ctor = build_method_call (NULL_TREE, name, parms,
-                                   NULL_TREE, LOOKUP_NORMAL);
+  exp = build_method_call (NULL_TREE, ctor_identifier, parms,
+                          TYPE_BINFO (type), LOOKUP_NORMAL);
 
-  if (expr_as_ctor == error_mark_node)
+  if (exp == error_mark_node)
     return error_mark_node;
 
-  return build_cplus_new (type, expr_as_ctor, 1);
+  return build_cplus_new (type, exp);
 }
 \f
 /* Return the character string for the name that encodes the
    enumeral value VALUE in the domain TYPE.  */
+
 char *
 enum_name_string (value, type)
      tree value;
@@ -1576,6 +1504,7 @@ enum_name_string (value, type)
    TYPE is the type of the switch index expression.
    NEW is the new value that we were trying to add.
    OLD is the old value that stopped us from adding it.  */
+
 void
 report_case_error (code, type, new_value, old_value)
      int code;
@@ -1673,3 +1602,12 @@ report_case_error (code, type, new_value, old_value)
     }
 }
 #endif
+
+void
+check_for_new_type (string, inptree)
+     char *string;
+     flagged_type_tree inptree;
+{
+  if (pedantic && inptree.new_type_flag)
+    pedwarn ("ANSI C++ forbids defining types within %s",string);
+}