expr.c revision 50397
1/* Convert language-specific tree expression to rtl instructions, 2 for GNU compiler. 3 Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 4 5This file is part of GNU CC. 6 7GNU CC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU CC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU CC; see the file COPYING. If not, write to 19the Free Software Foundation, 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22 23#include "config.h" 24#include "system.h" 25#include "rtl.h" 26#include "tree.h" 27#include "flags.h" 28#include "expr.h" 29#include "cp-tree.h" 30#include "toplev.h" 31 32#if 0 33static tree extract_aggr_init PROTO((tree, tree)); 34static tree extract_scalar_init PROTO((tree, tree)); 35#endif 36static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode, 37 enum expand_modifier)); 38 39/* Hook used by expand_expr to expand language-specific tree codes. */ 40 41static rtx 42cplus_expand_expr (exp, target, tmode, modifier) 43 tree exp; 44 rtx target; 45 enum machine_mode tmode; 46 enum expand_modifier modifier; 47{ 48 tree type = TREE_TYPE (exp); 49 register enum machine_mode mode = TYPE_MODE (type); 50 register enum tree_code code = TREE_CODE (exp); 51 int ignore = target == const0_rtx; 52 53 if (ignore) 54 target = 0; 55 56 /* No sense saving up arithmetic to be done 57 if it's all in the wrong mode to form part of an address. 58 And force_operand won't know whether to sign-extend or zero-extend. */ 59 60 if (mode != Pmode && modifier == EXPAND_SUM) 61 modifier = EXPAND_NORMAL; 62 63 switch (code) 64 { 65 case AGGR_INIT_EXPR: 66 { 67 /* Something needs to be initialized, but we didn't know 68 where that thing was when building the tree. For example, 69 it could be the return value of a function, or a parameter 70 to a function which lays down in the stack, or a temporary 71 variable which must be passed by reference. 72 73 Cleanups are handled in a language-specific way: they 74 might be run by the called function (true in GNU C++ 75 for parameters with cleanups), or they might be 76 run by the caller, after the call (true in GNU C++ 77 for other cleanup needs). */ 78 79 tree func = TREE_OPERAND (exp, 0); 80 tree args = TREE_OPERAND (exp, 1); 81 tree type = TREE_TYPE (exp), slot; 82 tree call_exp; 83 rtx call_target, return_target; 84 int pcc_struct_return = 0; 85 86 /* The expression `init' wants to initialize what 87 `target' represents. SLOT holds the slot for TARGET. */ 88 slot = TREE_OPERAND (exp, 2); 89 90 /* Should always be called with a target. */ 91 my_friendly_assert (target != NULL_RTX, 205); 92 93 /* The target the initializer will initialize (CALL_TARGET) 94 must now be directed to initialize the target we are 95 supposed to initialize (TARGET). The semantics for 96 choosing what CALL_TARGET is is language-specific, 97 as is building the call which will perform the 98 initialization. It is left here to show the choices that 99 exist for C++. */ 100 101 if (TREE_CODE (func) == ADDR_EXPR 102 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL 103 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) 104 { 105 type = build_pointer_type (type); 106 /* Don't clobber a value that might be part of a default 107 parameter value. */ 108 mark_addressable (slot); 109 if (TREE_PERMANENT (args)) 110 args = expr_tree_cons (0, build1 (ADDR_EXPR, type, slot), 111 TREE_CHAIN (args)); 112 else 113 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot); 114 call_target = 0; 115 } 116 else 117 { 118 call_target = target; 119#ifdef PCC_STATIC_STRUCT_RETURN 120 if (aggregate_value_p (type)) 121 { 122 pcc_struct_return = 1; 123 call_target = 0; 124 } 125#endif 126 } 127 128 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE); 129 TREE_SIDE_EFFECTS (call_exp) = 1; 130 return_target = expand_call (call_exp, call_target, ignore); 131 132 if (call_target) 133 /* Trust that the right thing has been done; it's too hard to 134 verify. */ 135 return return_target; 136 137 /* If we're suffering under the ancient PCC_STATIC_STRUCT_RETURN 138 calling convention, we need to copy the return value out of 139 the static return buffer into slot. */ 140 if (pcc_struct_return) 141 { 142 extern int flag_access_control; 143 int old_ac = flag_access_control; 144 145 tree init = build_decl (VAR_DECL, NULL_TREE, 146 build_reference_type (type)); 147 DECL_RTL (init) = XEXP (return_target, 0); 148 init = convert_from_reference (init); 149 150 flag_access_control = 0; 151 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); 152 flag_access_control = old_ac; 153 154 if (TYPE_NEEDS_DESTRUCTOR (type)) 155 { 156 init = maybe_build_cleanup (init); 157 if (init != NULL_TREE) 158 expand_expr (init, const0_rtx, VOIDmode, 0); 159 } 160 } 161 162 return DECL_RTL (slot); 163 } 164 165 case OFFSET_REF: 166 { 167#if 1 168 return expand_expr (default_conversion (resolve_offset_ref (exp)), 169 target, tmode, EXPAND_NORMAL); 170#else 171 /* This is old crusty code, and does not handle all that the 172 resolve_offset_ref function does. (mrs) */ 173 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0); 174 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0); 175 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset), 176 target, tmode, EXPAND_NORMAL); 177#endif 178 } 179 180 case THUNK_DECL: 181 return DECL_RTL (exp); 182 183 case THROW_EXPR: 184 expand_throw (TREE_OPERAND (exp, 0)); 185 return NULL; 186 187 case VEC_INIT_EXPR: 188 return expand_expr 189 (expand_vec_init 190 (NULL_TREE, TREE_OPERAND (exp, 0), 191 build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2), 192 integer_one_node, 1), 193 TREE_OPERAND (exp, 1), 0), target, tmode, modifier); 194 195 case NEW_EXPR: 196 return expand_expr (build_new_1 (exp), target, tmode, modifier); 197 198 default: 199 break; 200 } 201 my_friendly_abort (40); 202 /* NOTREACHED */ 203 return NULL; 204} 205 206void 207init_cplus_expand () 208{ 209 lang_expand_expr = cplus_expand_expr; 210} 211 212/* If DECL had its rtl moved from where callers expect it 213 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL, 214 which may be a pseudo instead of a hard register. */ 215 216void 217fixup_result_decl (decl, result) 218 tree decl; 219 rtx result; 220{ 221 if (REG_P (result)) 222 { 223 if (REGNO (result) >= FIRST_PSEUDO_REGISTER) 224 { 225 rtx real_decl_result; 226 227#ifdef FUNCTION_OUTGOING_VALUE 228 real_decl_result 229 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl); 230#else 231 real_decl_result 232 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl); 233#endif 234 REG_FUNCTION_VALUE_P (real_decl_result) = 1; 235 result = real_decl_result; 236 } 237 store_expr (decl, result, 0); 238 emit_insn (gen_rtx (USE, VOIDmode, result)); 239 } 240} 241 242#if 0 243/* Expand this initialization inline and see if it's simple enough that 244 it can be done at compile-time. */ 245 246static tree 247extract_aggr_init (decl, init) 248 tree decl, init; 249{ 250 return 0; 251} 252 253static tree 254extract_scalar_init (decl, init) 255 tree decl, init; 256{ 257 rtx value, insns, insn; 258 extern struct obstack temporary_obstack; 259 tree t = NULL_TREE; 260 261 push_obstacks (&temporary_obstack, &temporary_obstack); 262 start_sequence (); 263 value = expand_expr (init, NULL_RTX, VOIDmode, 0); 264 insns = get_insns (); 265 end_sequence (); 266 reg_scan (insns, max_reg_num (), 0); 267 jump_optimize (insns, 0, 0, 1); 268 pop_obstacks (); 269 270 for (insn = insns; insn; insn = NEXT_INSN (insn)) 271 { 272 rtx r, to; 273 274 if (GET_CODE (insn) == NOTE) 275 continue; 276 else if (GET_CODE (insn) != INSN) 277 return 0; 278 279 r = PATTERN (insn); 280 if (GET_CODE (r) != SET) 281 return 0; 282 283 to = XEXP (r, 0); 284 285 if (! (to == value 286 || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value))) 287 return 0; 288 289 r = XEXP (r, 1); 290 291 switch (GET_CODE (r)) 292 { 293 case CONST_INT: 294 t = build_int_2 (XEXP (r, 0), 0); 295 break; 296 default: 297 return 0; 298 } 299 } 300 301 return t; 302} 303#endif 304 305int 306extract_init (decl, init) 307 tree decl, init; 308{ 309 return 0; 310 311#if 0 312 if (IS_AGGR_TYPE (TREE_TYPE (decl)) 313 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 314 init = extract_aggr_init (decl, init); 315 else 316 init = extract_scalar_init (decl, init); 317 318 if (init == NULL_TREE) 319 return 0; 320 321 DECL_INITIAL (decl) = init; 322 return 1; 323#endif 324} 325 326void 327do_case (start, end) 328 tree start, end; 329{ 330 tree value1 = NULL_TREE, value2 = NULL_TREE, label; 331 332 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE 333 && POINTER_TYPE_P (TREE_TYPE (start))) 334 error ("pointers are not permitted as case values"); 335 336 if (end && pedantic) 337 pedwarn ("ANSI C++ forbids range expressions in switch statement"); 338 339 if (processing_template_decl) 340 { 341 add_tree (build_min_nt (CASE_LABEL, start, end)); 342 return; 343 } 344 345 if (start) 346 value1 = check_cp_case_value (start); 347 if (end) 348 value2 = check_cp_case_value (end); 349 350 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 351 352 if (value1 != error_mark_node 353 && value2 != error_mark_node) 354 { 355 tree duplicate; 356 int success; 357 358 if (end) 359 success = pushcase_range (value1, value2, convert_and_check, 360 label, &duplicate); 361 else if (start) 362 success = pushcase (value1, convert_and_check, label, &duplicate); 363 else 364 success = pushcase (NULL_TREE, 0, label, &duplicate); 365 366 if (success == 1) 367 { 368 if (end) 369 error ("case label not within a switch statement"); 370 else if (start) 371 cp_error ("case label `%E' not within a switch statement", start); 372 else 373 error ("default label not within a switch statement"); 374 } 375 else if (success == 2) 376 { 377 if (end) 378 { 379 error ("duplicate (or overlapping) case value"); 380 cp_error_at ("this is the first entry overlapping that value", 381 duplicate); 382 } 383 else if (start) 384 { 385 cp_error ("duplicate case value `%E'", start); 386 cp_error_at ("previously used here", duplicate); 387 } 388 else 389 { 390 error ("multiple default labels in one switch"); 391 cp_error_at ("this is the first default label", duplicate); 392 } 393 } 394 else if (success == 3) 395 warning ("case value out of range"); 396 else if (success == 4) 397 warning ("empty range specified"); 398 else if (success == 5) 399 { 400 if (end) 401 error ("case label within scope of cleanup or variable array"); 402 else if (! start) 403 error ("`default' label within scope of cleanup or variable array"); 404 else 405 cp_error ("case label `%E' within scope of cleanup or variable array", start); 406 } 407 } 408 if (start) 409 define_case_label (label); 410 else 411 define_case_label (NULL_TREE); 412} 413