OSDN Git Service

* except.c (expand_eh_region_start_tree): Add DECL argument so we
[pf3gnuchains/gcc-fork.git] / gcc / convert.c
index 2cb5990..472f47e 100644 (file)
@@ -1,5 +1,5 @@
 /* Utility routines for data type conversion for GNU C.
-   Copyright (C) 1987, 1988, 1991, 1992, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 91, 92, 94, 1995 Free Software Foundation, Inc.
 
 This file is part of GNU C.
 
@@ -15,21 +15,22 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* These routines are somewhat language-independent utility function
-   intended to be called by the language-specific convert () functions. */
+   intended to be called by the language-specific convert () functions.  */
 
 #include "config.h"
 #include "tree.h"
 #include "flags.h"
 #include "convert.h"
 
-/* Convert EXPR to some pointer type TYPE.
+/* Convert EXPR to some pointer or reference type TYPE.
 
-   EXPR must be pointer, integer, enumeral, or literal zero;
-   in other cases error is called. */
+   EXPR must be pointer, reference, integer, enumeral, or literal zero;
+   in other cases error is called.  */
 
 tree
 convert_to_pointer (type, expr)
@@ -40,14 +41,12 @@ convert_to_pointer (type, expr)
   
   if (integer_zerop (expr))
     {
-      if (type == TREE_TYPE (null_pointer_node))
-       return null_pointer_node;
       expr = build_int_2 (0, 0);
       TREE_TYPE (expr) = type;
       return expr;
     }
 
-  if (form == POINTER_TYPE)
+  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
     return build1 (NOP_EXPR, type, expr);
 
 
@@ -67,13 +66,15 @@ convert_to_pointer (type, expr)
 
   error ("cannot convert to a pointer type");
 
-  return null_pointer_node;
+  expr = build_int_2 (0, 0);
+  TREE_TYPE (expr) = type;
+  return expr;
 }
 
 /* Convert EXPR to some floating-point type TYPE.
 
    EXPR must be float, integer, or enumeral;
-   in other cases error is called. */
+   in other cases error is called.  */
 
 tree
 convert_to_real (type, expr)
@@ -92,7 +93,7 @@ convert_to_real (type, expr)
     return convert (type, fold (build1 (REALPART_EXPR,
                                        TREE_TYPE (TREE_TYPE (expr)), expr)));
 
-  if (form == POINTER_TYPE)
+  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
     error ("pointer value used where a floating point value was expected");
   else
     error ("aggregate value used where a float was expected");
@@ -120,7 +121,7 @@ convert_to_integer (type, expr)
   register tree intype = TREE_TYPE (expr);
   register enum tree_code form = TREE_CODE (intype);
 
-  if (form == POINTER_TYPE)
+  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
     {
       if (integer_zerop (expr))
        expr = integer_zero_node;
@@ -170,6 +171,17 @@ convert_to_integer (type, expr)
       else if (outprec >= inprec)
        return build1 (NOP_EXPR, type, expr);
 
+      /* If TYPE is an enumeral type or a type with a precision less
+        than the number of bits in its mode, do the conversion to the
+        type corresponding to its mode, then do a nop conversion
+        to TYPE.  */
+      else if (TREE_CODE (type) == ENUMERAL_TYPE
+              || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
+       return build1 (NOP_EXPR, type,
+                      convert (type_for_mode (TYPE_MODE (type),
+                                              TREE_UNSIGNED (type)),
+                               expr));
+
       /* Here detect when we can distribute the truncation down past some
         arithmetic.  For example, if adding two longs and converting to an
         int, we can equally well convert both to ints and then add.
@@ -449,7 +461,7 @@ convert_to_complex (type, expr)
        }
     }
 
-  if (form == POINTER_TYPE)
+  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
     error ("pointer value used where a complex was expected");
   else
     error ("aggregate value used where a complex was expected");