118334Speter/* Language-level data type conversion for GNU C.
2169689Skan   Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003, 2004, 2005
3132718Skan   Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2218334Speter
2318334Speter/* This file contains the functions for converting C expressions
2418334Speter   to different data types.  The only entry point is `convert'.
2518334Speter   Every language front end must have a `convert' function
2618334Speter   but what kind of conversions it does will depend on the language.  */
2718334Speter
2818334Speter#include "config.h"
2990075Sobrien#include "system.h"
30132718Skan#include "coretypes.h"
31132718Skan#include "tm.h"
3218334Speter#include "tree.h"
3318334Speter#include "flags.h"
3418334Speter#include "convert.h"
35117395Skan#include "c-common.h"
36169689Skan#include "c-tree.h"
37169689Skan#include "langhooks.h"
3850397Sobrien#include "toplev.h"
39169689Skan#include "target.h"
4018334Speter
4118334Speter/* Change of width--truncation and extension of integers or reals--
4218334Speter   is represented with NOP_EXPR.  Proper functioning of many things
4318334Speter   assumes that no other conversions can be NOP_EXPRs.
4418334Speter
4518334Speter   Conversion between integer and pointer is represented with CONVERT_EXPR.
4618334Speter   Converting integer to real uses FLOAT_EXPR
4718334Speter   and real to integer uses FIX_TRUNC_EXPR.
4818334Speter
4918334Speter   Here is a list of all the functions that assume that widening and
5018334Speter   narrowing is always done with a NOP_EXPR:
5118334Speter     In convert.c, convert_to_integer.
52117395Skan     In c-typeck.c, build_binary_op (boolean ops), and
53117395Skan	c_common_truthvalue_conversion.
5418334Speter     In expr.c: expand_expr, for operands of a MULT_EXPR.
5518334Speter     In fold-const.c: fold.
5618334Speter     In tree.c: get_narrower and get_unwidened.  */
5718334Speter
5818334Speter/* Subroutines of `convert'.  */
5918334Speter
6018334Speter
6118334Speter
6218334Speter/* Create an expression whose value is that of EXPR,
6318334Speter   converted to type TYPE.  The TREE_TYPE of the value
6418334Speter   is always TYPE.  This function implements all reasonable
6518334Speter   conversions; callers should filter out those that are
6618334Speter   not permitted by the language being compiled.  */
6718334Speter
6818334Spetertree
69132718Skanconvert (tree type, tree expr)
7018334Speter{
7190075Sobrien  tree e = expr;
7290075Sobrien  enum tree_code code = TREE_CODE (type);
73169689Skan  const char *invalid_conv_diag;
7418334Speter
75169689Skan  if (type == error_mark_node
76169689Skan      || expr == error_mark_node
77169689Skan      || TREE_TYPE (expr) == error_mark_node)
78169689Skan    return error_mark_node;
79169689Skan
80169689Skan  if ((invalid_conv_diag
81169689Skan       = targetm.invalid_conversion (TREE_TYPE (expr), type)))
82169689Skan    {
83260011Spfg      error (invalid_conv_diag, "");
84169689Skan      return error_mark_node;
85169689Skan    }
86169689Skan
87169689Skan  if (type == TREE_TYPE (expr))
8818334Speter    return expr;
8990075Sobrien
9018334Speter  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
91169689Skan    return fold_convert (type, expr);
9218334Speter  if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
9318334Speter    return error_mark_node;
9418334Speter  if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
9518334Speter    {
9618334Speter      error ("void value not ignored as it ought to be");
9718334Speter      return error_mark_node;
9818334Speter    }
9918334Speter  if (code == VOID_TYPE)
100169689Skan    return fold_convert (type, e);
10118334Speter  if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
10218334Speter    return fold (convert_to_integer (type, e));
10390075Sobrien  if (code == BOOLEAN_TYPE)
104169689Skan    return fold_convert (type, c_objc_common_truthvalue_conversion (expr));
10590075Sobrien  if (code == POINTER_TYPE || code == REFERENCE_TYPE)
10618334Speter    return fold (convert_to_pointer (type, e));
107261188Spfg  /* APPLE LOCAL begin blocks (C++ ck) */
108261188Spfg  if (code == BLOCK_POINTER_TYPE)
109261188Spfg    return fold (convert_to_block_pointer (type, e));
110261188Spfg  /* APPLE LOCAL end blocks (C++ ck) */
11118334Speter  if (code == REAL_TYPE)
11218334Speter    return fold (convert_to_real (type, e));
11318334Speter  if (code == COMPLEX_TYPE)
11418334Speter    return fold (convert_to_complex (type, e));
11590075Sobrien  if (code == VECTOR_TYPE)
11690075Sobrien    return fold (convert_to_vector (type, e));
117169689Skan  if ((code == RECORD_TYPE || code == UNION_TYPE)
118169689Skan      && lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
119169689Skan      return e;
12018334Speter
12118334Speter  error ("conversion to non-scalar type requested");
12218334Speter  return error_mark_node;
12318334Speter}
124