expr.c revision 90075
118334Speter/* Convert language-specific tree expression to rtl instructions, 218334Speter for GNU compiler. 390075Sobrien Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 490075Sobrien 2000, 2001 Free Software Foundation, Inc. 518334Speter 618334SpeterThis file is part of GNU CC. 718334Speter 818334SpeterGNU CC is free software; you can redistribute it and/or modify 918334Speterit under the terms of the GNU General Public License as published by 1018334Speterthe Free Software Foundation; either version 2, or (at your option) 1118334Speterany later version. 1218334Speter 1318334SpeterGNU CC is distributed in the hope that it will be useful, 1418334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1518334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1618334SpeterGNU General Public License for more details. 1718334Speter 1818334SpeterYou should have received a copy of the GNU General Public License 1918334Speteralong with GNU CC; see the file COPYING. If not, write to 2018334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 2118334SpeterBoston, MA 02111-1307, USA. */ 2218334Speter 2318334Speter 2418334Speter#include "config.h" 2550397Sobrien#include "system.h" 2618334Speter#include "rtl.h" 2718334Speter#include "tree.h" 2818334Speter#include "flags.h" 2918334Speter#include "expr.h" 3018334Speter#include "cp-tree.h" 3150397Sobrien#include "toplev.h" 3290075Sobrien#include "except.h" 3390075Sobrien#include "tm_p.h" 3418334Speter 3590075Sobrienstatic rtx cplus_expand_expr PARAMS ((tree, rtx, enum machine_mode, 3650397Sobrien enum expand_modifier)); 3718334Speter 3852284Sobrien/* Hook used by output_constant to expand language-specific 3952284Sobrien constants. */ 4052284Sobrien 4190075Sobrientree 4252284Sobriencplus_expand_constant (cst) 4352284Sobrien tree cst; 4452284Sobrien{ 4552284Sobrien switch (TREE_CODE (cst)) 4652284Sobrien { 4752284Sobrien case PTRMEM_CST: 4852284Sobrien { 4952284Sobrien tree type = TREE_TYPE (cst); 5052284Sobrien tree member; 5152284Sobrien 5252284Sobrien /* Find the member. */ 5352284Sobrien member = PTRMEM_CST_MEMBER (cst); 5452284Sobrien 5552284Sobrien if (TREE_CODE (member) == FIELD_DECL) 5652284Sobrien { 5752284Sobrien /* Find the offset for the field. */ 5890075Sobrien tree offset = byte_position (member); 5990075Sobrien cst = fold (build1 (NOP_EXPR, type, offset)); 6052284Sobrien } 6152284Sobrien else 6252284Sobrien { 6352284Sobrien tree delta; 6452284Sobrien tree pfn; 6552284Sobrien 6690075Sobrien expand_ptrmemfunc_cst (cst, &delta, &pfn); 6790075Sobrien cst = build_ptrmemfunc1 (type, delta, pfn); 6852284Sobrien } 6952284Sobrien } 7052284Sobrien break; 7152284Sobrien 7252284Sobrien default: 7352284Sobrien /* There's nothing to do. */ 7452284Sobrien break; 7552284Sobrien } 7652284Sobrien 7752284Sobrien return cst; 7852284Sobrien} 7952284Sobrien 8018334Speter/* Hook used by expand_expr to expand language-specific tree codes. */ 8118334Speter 8250397Sobrienstatic rtx 8318334Spetercplus_expand_expr (exp, target, tmode, modifier) 8418334Speter tree exp; 8518334Speter rtx target; 8618334Speter enum machine_mode tmode; 8718334Speter enum expand_modifier modifier; 8818334Speter{ 8918334Speter tree type = TREE_TYPE (exp); 9018334Speter register enum machine_mode mode = TYPE_MODE (type); 9118334Speter register enum tree_code code = TREE_CODE (exp); 9290075Sobrien rtx ret; 9318334Speter 9418334Speter /* No sense saving up arithmetic to be done 9518334Speter if it's all in the wrong mode to form part of an address. 9618334Speter And force_operand won't know whether to sign-extend or zero-extend. */ 9718334Speter 9818334Speter if (mode != Pmode && modifier == EXPAND_SUM) 9918334Speter modifier = EXPAND_NORMAL; 10018334Speter 10118334Speter switch (code) 10218334Speter { 10352284Sobrien case PTRMEM_CST: 10452284Sobrien return expand_expr (cplus_expand_constant (exp), 10552284Sobrien target, tmode, modifier); 10652284Sobrien 10718334Speter case OFFSET_REF: 10890075Sobrien /* Offset refs should not make it through to here. */ 10990075Sobrien abort (); 11090075Sobrien return const0_rtx; 11190075Sobrien 11218334Speter case THROW_EXPR: 11390075Sobrien expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0); 11418334Speter return NULL; 11518334Speter 11690075Sobrien case MUST_NOT_THROW_EXPR: 11790075Sobrien expand_eh_region_start (); 11890075Sobrien ret = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); 11990075Sobrien expand_eh_region_end_must_not_throw (build_call (terminate_node, 0)); 12090075Sobrien return ret; 12118334Speter 12290075Sobrien case EMPTY_CLASS_EXPR: 12390075Sobrien /* We don't need to generate any code for an empty class. */ 12490075Sobrien return const0_rtx; 12550397Sobrien 12618334Speter default: 12790075Sobrien return c_expand_expr (exp, target, tmode, modifier); 12818334Speter } 12990075Sobrien abort (); 13018334Speter /* NOTREACHED */ 13118334Speter return NULL; 13218334Speter} 13318334Speter 13418334Spetervoid 13518334Speterinit_cplus_expand () 13618334Speter{ 13718334Speter lang_expand_expr = cplus_expand_expr; 13818334Speter} 13918334Speter 14018334Speterint 14118334Speterextract_init (decl, init) 14252284Sobrien tree decl ATTRIBUTE_UNUSED, init ATTRIBUTE_UNUSED; 14318334Speter{ 14418334Speter return 0; 14518334Speter} 14650397Sobrien 147