118334Speter/* Convert language-specific tree expression to rtl instructions, 218334Speter for GNU compiler. 390075Sobrien Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 4132718Skan 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 518334Speter 6132718SkanThis file is part of GCC. 718334Speter 8132718SkanGCC 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 13132718SkanGCC 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 19132718Skanalong with GCC; see the file COPYING. If not, write to 20169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 21169689SkanBoston, MA 02110-1301, USA. */ 2218334Speter 2318334Speter 2418334Speter#include "config.h" 2550397Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2818334Speter#include "rtl.h" 2918334Speter#include "tree.h" 3018334Speter#include "flags.h" 3118334Speter#include "expr.h" 3218334Speter#include "cp-tree.h" 3350397Sobrien#include "toplev.h" 3490075Sobrien#include "except.h" 3590075Sobrien#include "tm_p.h" 3618334Speter 3752284Sobrien/* Hook used by output_constant to expand language-specific 3852284Sobrien constants. */ 3952284Sobrien 4090075Sobrientree 41132718Skancplus_expand_constant (tree cst) 4252284Sobrien{ 4352284Sobrien switch (TREE_CODE (cst)) 4452284Sobrien { 4552284Sobrien case PTRMEM_CST: 4652284Sobrien { 4752284Sobrien tree type = TREE_TYPE (cst); 4852284Sobrien tree member; 49169689Skan 5052284Sobrien /* Find the member. */ 5152284Sobrien member = PTRMEM_CST_MEMBER (cst); 5252284Sobrien 53169689Skan if (TREE_CODE (member) == FIELD_DECL) 5452284Sobrien { 5552284Sobrien /* Find the offset for the field. */ 56132718Skan cst = byte_position (member); 57132718Skan while (!same_type_p (DECL_CONTEXT (member), 58132718Skan TYPE_PTRMEM_CLASS_TYPE (type))) 59132718Skan { 60132718Skan /* The MEMBER must have been nestled within an 61132718Skan anonymous aggregate contained in TYPE. Find the 62132718Skan anonymous aggregate. */ 63132718Skan member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type), 64132718Skan DECL_CONTEXT (member)); 65132718Skan cst = size_binop (PLUS_EXPR, cst, byte_position (member)); 66132718Skan } 67132718Skan cst = fold (build_nop (type, cst)); 6852284Sobrien } 6952284Sobrien else 7052284Sobrien { 7152284Sobrien tree delta; 7252284Sobrien tree pfn; 7352284Sobrien 7490075Sobrien expand_ptrmemfunc_cst (cst, &delta, &pfn); 7590075Sobrien cst = build_ptrmemfunc1 (type, delta, pfn); 7652284Sobrien } 7752284Sobrien } 7852284Sobrien break; 7952284Sobrien 8052284Sobrien default: 8152284Sobrien /* There's nothing to do. */ 8252284Sobrien break; 8352284Sobrien } 8452284Sobrien 8552284Sobrien return cst; 8652284Sobrien} 8752284Sobrien 8818334Speter/* Hook used by expand_expr to expand language-specific tree codes. */ 89169689Skan/* ??? The only thing that should be here are things needed to expand 90169689Skan constant initializers; everything else should be handled by the 91169689Skan gimplification routines. Are EMPTY_CLASS_EXPR or BASELINK needed? */ 9218334Speter 93117395Skanrtx 94132718Skancxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier, 95132718Skan rtx *alt_rtl) 9618334Speter{ 9718334Speter tree type = TREE_TYPE (exp); 98132718Skan enum machine_mode mode = TYPE_MODE (type); 99132718Skan enum tree_code code = TREE_CODE (exp); 10018334Speter 10118334Speter /* No sense saving up arithmetic to be done 10218334Speter if it's all in the wrong mode to form part of an address. 10318334Speter And force_operand won't know whether to sign-extend or zero-extend. */ 10418334Speter 10518334Speter if (mode != Pmode && modifier == EXPAND_SUM) 10618334Speter modifier = EXPAND_NORMAL; 10718334Speter 10818334Speter switch (code) 10918334Speter { 11052284Sobrien case PTRMEM_CST: 11152284Sobrien return expand_expr (cplus_expand_constant (exp), 11252284Sobrien target, tmode, modifier); 11352284Sobrien 11418334Speter case OFFSET_REF: 115117395Skan /* Offset refs should not make it through to here. */ 116169689Skan gcc_unreachable (); 11718334Speter 11890075Sobrien case EMPTY_CLASS_EXPR: 11990075Sobrien /* We don't need to generate any code for an empty class. */ 12090075Sobrien return const0_rtx; 12150397Sobrien 122132718Skan case BASELINK: 123132718Skan return expand_expr (BASELINK_FUNCTIONS (exp), target, tmode, 124132718Skan modifier); 125132718Skan 12618334Speter default: 127132718Skan return c_expand_expr (exp, target, tmode, modifier, alt_rtl); 12818334Speter } 12918334Speter} 130