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