expr.c revision 50397
1207753Smm/* Convert language-specific tree expression to rtl instructions, 2207753Smm for GNU compiler. 3207753Smm Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 4207753Smm 5207753SmmThis file is part of GNU CC. 6207753Smm 7207753SmmGNU CC is free software; you can redistribute it and/or modify 8207753Smmit under the terms of the GNU General Public License as published by 9207753Smmthe Free Software Foundation; either version 2, or (at your option) 10207753Smmany later version. 11207753Smm 12207753SmmGNU CC is distributed in the hope that it will be useful, 13207753Smmbut WITHOUT ANY WARRANTY; without even the implied warranty of 14207753SmmMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15207753SmmGNU General Public License for more details. 16207753Smm 17207753SmmYou should have received a copy of the GNU General Public License 18207753Smmalong with GNU CC; see the file COPYING. If not, write to 19207753Smmthe Free Software Foundation, 59 Temple Place - Suite 330, 20207753SmmBoston, MA 02111-1307, USA. */ 21207753Smm 22207753Smm 23207753Smm#include "config.h" 24207753Smm#include "system.h" 25207753Smm#include "rtl.h" 26207753Smm#include "tree.h" 27207753Smm#include "flags.h" 28207753Smm#include "expr.h" 29207753Smm#include "cp-tree.h" 30207753Smm#include "toplev.h" 31207753Smm 32207753Smm#if 0 33207753Smmstatic tree extract_aggr_init PROTO((tree, tree)); 34207753Smmstatic tree extract_scalar_init PROTO((tree, tree)); 35207753Smm#endif 36207753Smmstatic rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode, 37207753Smm enum expand_modifier)); 38207753Smm 39207753Smm/* Hook used by expand_expr to expand language-specific tree codes. */ 40207753Smm 41207753Smmstatic rtx 42207753Smmcplus_expand_expr (exp, target, tmode, modifier) 43207753Smm tree exp; 44207753Smm rtx target; 45207753Smm enum machine_mode tmode; 46207753Smm enum expand_modifier modifier; 47207753Smm{ 48207753Smm tree type = TREE_TYPE (exp); 49207753Smm register enum machine_mode mode = TYPE_MODE (type); 50207753Smm register enum tree_code code = TREE_CODE (exp); 51207753Smm int ignore = target == const0_rtx; 52207753Smm 53207753Smm if (ignore) 54207753Smm target = 0; 55207753Smm 56207753Smm /* No sense saving up arithmetic to be done 57207753Smm if it's all in the wrong mode to form part of an address. 58207753Smm And force_operand won't know whether to sign-extend or zero-extend. */ 59207753Smm 60207753Smm if (mode != Pmode && modifier == EXPAND_SUM) 61207753Smm modifier = EXPAND_NORMAL; 62207753Smm 63207753Smm switch (code) 64207753Smm { 65207753Smm case AGGR_INIT_EXPR: 66207753Smm { 67207753Smm /* Something needs to be initialized, but we didn't know 68207753Smm 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