1*1debfc3dSmrg /* This file contains subroutine used by the C front-end to construct GENERIC. 2*1debfc3dSmrg Copyright (C) 2000-2017 Free Software Foundation, Inc. 3*1debfc3dSmrg Written by Benjamin Chelf (chelf@codesourcery.com). 4*1debfc3dSmrg 5*1debfc3dSmrg This file is part of GCC. 6*1debfc3dSmrg 7*1debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under 8*1debfc3dSmrg the terms of the GNU General Public License as published by the Free 9*1debfc3dSmrg Software Foundation; either version 3, or (at your option) any later 10*1debfc3dSmrg version. 11*1debfc3dSmrg 12*1debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13*1debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 14*1debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15*1debfc3dSmrg for more details. 16*1debfc3dSmrg 17*1debfc3dSmrg You should have received a copy of the GNU General Public License 18*1debfc3dSmrg along with GCC; see the file COPYING3. If not see 19*1debfc3dSmrg <http://www.gnu.org/licenses/>. */ 20*1debfc3dSmrg 21*1debfc3dSmrg #include "config.h" 22*1debfc3dSmrg #include "system.h" 23*1debfc3dSmrg #include "coretypes.h" 24*1debfc3dSmrg #include "c-common.h" 25*1debfc3dSmrg #include "tree-iterator.h" 26*1debfc3dSmrg 27*1debfc3dSmrg /* Create an empty statement tree rooted at T. */ 28*1debfc3dSmrg 29*1debfc3dSmrg tree 30*1debfc3dSmrg push_stmt_list (void) 31*1debfc3dSmrg { 32*1debfc3dSmrg tree t; 33*1debfc3dSmrg t = alloc_stmt_list (); 34*1debfc3dSmrg vec_safe_push (stmt_list_stack, t); 35*1debfc3dSmrg return t; 36*1debfc3dSmrg } 37*1debfc3dSmrg 38*1debfc3dSmrg /* Finish the statement tree rooted at T. */ 39*1debfc3dSmrg 40*1debfc3dSmrg tree 41*1debfc3dSmrg pop_stmt_list (tree t) 42*1debfc3dSmrg { 43*1debfc3dSmrg tree u = NULL_TREE; 44*1debfc3dSmrg 45*1debfc3dSmrg /* Pop statement lists until we reach the target level. The extra 46*1debfc3dSmrg nestings will be due to outstanding cleanups. */ 47*1debfc3dSmrg while (1) 48*1debfc3dSmrg { 49*1debfc3dSmrg u = stmt_list_stack->pop (); 50*1debfc3dSmrg if (!stmt_list_stack->is_empty ()) 51*1debfc3dSmrg { 52*1debfc3dSmrg tree x = stmt_list_stack->last (); 53*1debfc3dSmrg STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u); 54*1debfc3dSmrg } 55*1debfc3dSmrg if (t == u) 56*1debfc3dSmrg break; 57*1debfc3dSmrg } 58*1debfc3dSmrg 59*1debfc3dSmrg gcc_assert (u != NULL_TREE); 60*1debfc3dSmrg 61*1debfc3dSmrg /* If the statement list is completely empty, just return it. This is 62*1debfc3dSmrg just as good small as build_empty_stmt, with the advantage that 63*1debfc3dSmrg statement lists are merged when they appended to one another. So 64*1debfc3dSmrg using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P 65*1debfc3dSmrg statements. */ 66*1debfc3dSmrg if (TREE_SIDE_EFFECTS (t)) 67*1debfc3dSmrg { 68*1debfc3dSmrg tree_stmt_iterator i = tsi_start (t); 69*1debfc3dSmrg 70*1debfc3dSmrg /* If the statement list contained exactly one statement, then 71*1debfc3dSmrg extract it immediately. */ 72*1debfc3dSmrg if (tsi_one_before_end_p (i)) 73*1debfc3dSmrg { 74*1debfc3dSmrg u = tsi_stmt (i); 75*1debfc3dSmrg tsi_delink (&i); 76*1debfc3dSmrg free_stmt_list (t); 77*1debfc3dSmrg t = u; 78*1debfc3dSmrg } 79*1debfc3dSmrg } 80*1debfc3dSmrg 81*1debfc3dSmrg return t; 82*1debfc3dSmrg } 83*1debfc3dSmrg 84*1debfc3dSmrg /* Build a generic statement based on the given type of node and 85*1debfc3dSmrg arguments. Similar to `build_nt', except that we set 86*1debfc3dSmrg EXPR_LOCATION to LOC. */ 87*1debfc3dSmrg /* ??? This should be obsolete with the lineno_stmt productions 88*1debfc3dSmrg in the grammar. */ 89*1debfc3dSmrg 90*1debfc3dSmrg tree 91*1debfc3dSmrg build_stmt (location_t loc, enum tree_code code, ...) 92*1debfc3dSmrg { 93*1debfc3dSmrg tree ret; 94*1debfc3dSmrg int length, i; 95*1debfc3dSmrg va_list p; 96*1debfc3dSmrg bool side_effects; 97*1debfc3dSmrg 98*1debfc3dSmrg /* This function cannot be used to construct variably-sized nodes. */ 99*1debfc3dSmrg gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp); 100*1debfc3dSmrg 101*1debfc3dSmrg va_start (p, code); 102*1debfc3dSmrg 103*1debfc3dSmrg ret = make_node (code); 104*1debfc3dSmrg TREE_TYPE (ret) = void_type_node; 105*1debfc3dSmrg length = TREE_CODE_LENGTH (code); 106*1debfc3dSmrg SET_EXPR_LOCATION (ret, loc); 107*1debfc3dSmrg 108*1debfc3dSmrg /* TREE_SIDE_EFFECTS will already be set for statements with 109*1debfc3dSmrg implicit side effects. Here we make sure it is set for other 110*1debfc3dSmrg expressions by checking whether the parameters have side 111*1debfc3dSmrg effects. */ 112*1debfc3dSmrg 113*1debfc3dSmrg side_effects = false; 114*1debfc3dSmrg for (i = 0; i < length; i++) 115*1debfc3dSmrg { 116*1debfc3dSmrg tree t = va_arg (p, tree); 117*1debfc3dSmrg if (t && !TYPE_P (t)) 118*1debfc3dSmrg side_effects |= TREE_SIDE_EFFECTS (t); 119*1debfc3dSmrg TREE_OPERAND (ret, i) = t; 120*1debfc3dSmrg } 121*1debfc3dSmrg 122*1debfc3dSmrg TREE_SIDE_EFFECTS (ret) |= side_effects; 123*1debfc3dSmrg 124*1debfc3dSmrg va_end (p); 125*1debfc3dSmrg return ret; 126*1debfc3dSmrg } 127*1debfc3dSmrg 128*1debfc3dSmrg /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */ 129*1debfc3dSmrg 130*1debfc3dSmrg tree 131*1debfc3dSmrg build_real_imag_expr (location_t location, enum tree_code code, tree arg) 132*1debfc3dSmrg { 133*1debfc3dSmrg tree ret; 134*1debfc3dSmrg tree arg_type = TREE_TYPE (arg); 135*1debfc3dSmrg 136*1debfc3dSmrg gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR); 137*1debfc3dSmrg 138*1debfc3dSmrg if (TREE_CODE (arg_type) == COMPLEX_TYPE) 139*1debfc3dSmrg { 140*1debfc3dSmrg ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg); 141*1debfc3dSmrg SET_EXPR_LOCATION (ret, location); 142*1debfc3dSmrg } 143*1debfc3dSmrg else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type)) 144*1debfc3dSmrg { 145*1debfc3dSmrg ret = (code == REALPART_EXPR 146*1debfc3dSmrg ? arg 147*1debfc3dSmrg : omit_one_operand_loc (location, arg_type, 148*1debfc3dSmrg integer_zero_node, arg)); 149*1debfc3dSmrg } 150*1debfc3dSmrg else 151*1debfc3dSmrg { 152*1debfc3dSmrg error_at (location, "wrong type argument to %s", 153*1debfc3dSmrg code == REALPART_EXPR ? "__real" : "__imag"); 154*1debfc3dSmrg ret = error_mark_node; 155*1debfc3dSmrg } 156*1debfc3dSmrg 157*1debfc3dSmrg return ret; 158*1debfc3dSmrg } 159