OSDN Git Service

2001-11-12 H.J. Lu <hjl@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cp / cvt.c
index 1672f26..81d0577 100644 (file)
@@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA.  */
 
 static tree cp_convert_to_pointer PARAMS ((tree, tree, int));
 static tree convert_to_pointer_force PARAMS ((tree, tree));
-static tree build_up_reference PARAMS ((tree, tree, int));
+static tree build_up_reference PARAMS ((tree, tree, int, tree));
 static void warn_ref_binding PARAMS ((tree, tree, tree));
 
 /* Change of width--truncation and extension of integers or reals--
@@ -258,9 +258,9 @@ cp_convert_to_pointer (type, expr, force)
       if (TYPE_PTRMEMFUNC_P (type))
        return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
 
-      if (flag_new_abi && TYPE_PTRMEM_P (type))
-       /* Under the new ABI, a NULL pointer-to-member is represented
-          by -1, not by zero.  */
+      if (TYPE_PTRMEM_P (type))
+       /* A NULL pointer-to-member is represented by -1, not by
+          zero.  */
        expr = build_int_2 (-1, -1);
       else
        expr = build_int_2 (0, 0);
@@ -358,11 +358,12 @@ convert_to_pointer_force (type, expr)
    value we have to begin with is in ARG.
 
    FLAGS controls how we manage access checking.
-   DIRECT_BIND in FLAGS controls how any temporaries are generated.  */
+   DIRECT_BIND in FLAGS controls how any temporaries are generated.
+     If DIRECT_BIND is set, DECL is the reference we're binding to.  */
 
 static tree
-build_up_reference (type, arg, flags)
-     tree type, arg;
+build_up_reference (type, arg, flags, decl)
+     tree type, arg, decl;
      int flags;
 {
   tree rval;
@@ -374,14 +375,28 @@ build_up_reference (type, arg, flags)
 
   if ((flags & DIRECT_BIND) && ! real_lvalue_p (arg))
     {
-      /* Create a new temporary variable.  */
+      /* Create a new temporary variable.  We can't just use a TARGET_EXPR
+        here because it needs to live as long as DECL.  */
       tree targ = arg;
-      if (toplevel_bindings_p ())
-       arg = get_temp_name (argtype);
+
+      arg = build_decl (VAR_DECL, NULL_TREE, argtype);
+      DECL_ARTIFICIAL (arg) = 1;
+      TREE_USED (arg) = 1;
+      TREE_STATIC (arg) = TREE_STATIC (decl);
+
+      if (TREE_STATIC (decl))
+       {
+         /* Namespace-scope or local static; give it a mangled name.  */
+         tree name = mangle_ref_init_variable (decl);
+         DECL_NAME (arg) = name;
+         SET_DECL_ASSEMBLER_NAME (arg, name);
+         arg = pushdecl_top_level (arg);
+       }
       else
        {
-         arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
-         DECL_ARTIFICIAL (arg) = 1;
+         /* Automatic; make sure we handle the cleanup properly.  */
+         maybe_push_cleanup_level (argtype);
+         arg = pushdecl (arg);
        }
 
       /* Process the initializer for the declaration.  */
@@ -392,7 +407,7 @@ build_up_reference (type, arg, flags)
   else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
     return get_target_expr (arg);
 
-  /* If we had a way to wrap this up, and say, if we ever needed it's
+  /* If we had a way to wrap this up, and say, if we ever needed its
      address, transform all occurrences of the register, into a memory
      reference we could win better.  */
   rval = build_unary_op (ADDR_EXPR, arg, 1);
@@ -530,7 +545,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
                        ttr, reftype);
        }
 
-      return build_up_reference (reftype, expr, flags);
+      return build_up_reference (reftype, expr, flags, decl);
     }
   else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
     {
@@ -561,7 +576,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
       if (rval == NULL_TREE || rval == error_mark_node)
        return rval;
       warn_ref_binding (reftype, intype, decl);
-      rval = build_up_reference (reftype, rval, flags);
+      rval = build_up_reference (reftype, rval, flags, decl);
     }
 
   if (rval)
@@ -593,9 +608,23 @@ convert_from_reference (val)
   if (TREE_CODE (type) == OFFSET_TYPE)
     type = TREE_TYPE (type);
   if (TREE_CODE (type) == REFERENCE_TYPE)
-    return build_indirect_ref (val, NULL_PTR);
+    return build_indirect_ref (val, NULL);
   return val;
 }
+
+/* Implicitly convert the lvalue EXPR to another lvalue of type TOTYPE,
+   preserving cv-qualification.  */
+
+tree
+convert_lvalue (totype, expr)
+     tree totype, expr;
+{
+  totype = cp_build_qualified_type (totype, TYPE_QUALS (TREE_TYPE (expr)));
+  totype = build_reference_type (totype);
+  expr = convert_to_reference (totype, expr, CONV_IMPLICIT, LOOKUP_NORMAL,
+                              NULL_TREE);
+  return convert_from_reference (expr);
+}
 \f
 /* Call this when we know (for any reason) that expr is not, in fact,
    zero.  This routine is like convert_pointer_to, but it pays
@@ -785,15 +814,17 @@ ocp_convert (type, expr, convtype, flags)
          else if (TREE_CODE (expr) == ADDR_EXPR 
                   && TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL)
            fn = TREE_OPERAND (expr, 0);
-         if (fn)
+         if (fn && !DECL_WEAK (fn))
            cp_warning ("the address of `%D', will always be `true'", fn);
-         return truthvalue_conversion (e);
+         return cp_truthvalue_conversion (e);
        }
       return fold (convert_to_integer (type, e));
     }
   if (code == POINTER_TYPE || code == REFERENCE_TYPE
       || TYPE_PTRMEMFUNC_P (type))
     return fold (cp_convert_to_pointer (type, e, 0));
+  if (code == VECTOR_TYPE)
+    return fold (convert_to_vector (type, e));
   if (code == REAL_TYPE || code == COMPLEX_TYPE)
     {
       if (IS_AGGR_TYPE (TREE_TYPE (e)))
@@ -841,7 +872,7 @@ ocp_convert (type, expr, convtype, flags)
           with a user-defined conversion sequence, then we direct-initialize
           the target with the temp (see [dcl.init]).  */
        ctor = build_user_type_conversion (type, ctor, flags);
-      if (ctor)
+      else
        ctor = build_method_call (NULL_TREE, 
                                  complete_ctor_identifier,
                                  build_tree_list (NULL_TREE, ctor),
@@ -919,8 +950,13 @@ convert_to_void (expr, implicit)
         tree new_op1 = convert_to_void (op1, implicit);
         
         if (new_op1 != op1)
-          expr = build (COMPOUND_EXPR, TREE_TYPE (new_op1),
-                        TREE_OPERAND (expr, 0), new_op1);
+         {
+           tree t = build (COMPOUND_EXPR, TREE_TYPE (new_op1),
+                           TREE_OPERAND (expr, 0), new_op1);
+           TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr);
+           expr = t;
+         }
+
         break;
       }
     
@@ -976,19 +1012,17 @@ convert_to_void (expr, implicit)
   
     if (TREE_CODE (probe) == ADDR_EXPR)
       probe = TREE_OPERAND (expr, 0);
-    if (!is_overloaded_fn (probe))
-      ;/* OK */
-    else if (really_overloaded_fn (probe))
-        {
-          /* [over.over] enumerates the places where we can take the address
-             of an overloaded function, and this is not one of them.  */
-          cp_pedwarn ("%s has no context for overloaded function name `%E'",
-                      implicit ? implicit : "void cast", expr);
-        }
-    else if (implicit && probe == expr)
+    if (type_unknown_p (probe))
+      {
+       /* [over.over] enumerates the places where we can take the address
+          of an overloaded function, and this is not one of them.  */
+       cp_pedwarn ("%s cannot resolve address of overloaded function",
+                   implicit ? implicit : "void cast");
+      }
+    else if (implicit && probe == expr && is_overloaded_fn (probe))
       /* Only warn when there is no &.  */
       cp_warning ("%s is a reference, not call, to function `%E'",
-                    implicit, expr);
+                 implicit, expr);
   }
   
   if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
@@ -1016,7 +1050,7 @@ convert_to_void (expr, implicit)
    conversions to/from basetypes may involve memory references
    (vbases) and adding or subtracting small values (multiple
    inheritance), but it calls convert from the constant folding code
-   on subtrees of already build trees after it has ripped them apart.
+   on subtrees of already built trees after it has ripped them apart.
 
    Also, if we ever support range variables, we'll probably also have to
    do a little bit more work.  */
@@ -1257,7 +1291,7 @@ type_promotes_to (type)
       else
        type = totype;
     }
-  else if (C_PROMOTING_INTEGER_TYPE_P (type))
+  else if (c_promoting_integer_type_p (type))
     {
       /* Retain unsignedness if really not getting bigger.  */
       if (TREE_UNSIGNED (type)