tree.c revision 90075
118334Speter/* Language-dependent node constructors for parse phase of GNU compiler. 290075Sobrien Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 390075Sobrien 1999, 2000, 2001 Free Software Foundation, Inc. 418334Speter Hacked by Michael Tiemann (tiemann@cygnus.com) 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#include "config.h" 2450397Sobrien#include "system.h" 2518334Speter#include "obstack.h" 2618334Speter#include "tree.h" 2718334Speter#include "cp-tree.h" 2818334Speter#include "flags.h" 2918334Speter#include "rtl.h" 3050397Sobrien#include "toplev.h" 3190075Sobrien#include "ggc.h" 3290075Sobrien#include "insn-config.h" 3390075Sobrien#include "integrate.h" 3490075Sobrien#include "tree-inline.h" 3518334Speter 3690075Sobrienstatic tree bot_manip PARAMS ((tree *, int *, void *)); 3790075Sobrienstatic tree bot_replace PARAMS ((tree *, int *, void *)); 3890075Sobrienstatic tree build_cplus_array_type_1 PARAMS ((tree, tree)); 3990075Sobrienstatic int list_hash_eq PARAMS ((const void *, const void *)); 4090075Sobrienstatic hashval_t list_hash_pieces PARAMS ((tree, tree, tree)); 4190075Sobrienstatic hashval_t list_hash PARAMS ((const void *)); 4290075Sobrienstatic cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int)); 4390075Sobrienstatic tree no_linkage_helper PARAMS ((tree *, int *, void *)); 4490075Sobrienstatic tree build_srcloc PARAMS ((const char *, int)); 4590075Sobrienstatic tree mark_local_for_remap_r PARAMS ((tree *, int *, void *)); 4690075Sobrienstatic tree cp_unsave_r PARAMS ((tree *, int *, void *)); 4790075Sobrienstatic void cp_unsave PARAMS ((tree *)); 4890075Sobrienstatic tree build_target_expr PARAMS ((tree, tree)); 4990075Sobrienstatic tree count_trees_r PARAMS ((tree *, int *, void *)); 5090075Sobrienstatic tree verify_stmt_tree_r PARAMS ((tree *, int *, void *)); 5190075Sobrienstatic tree find_tree_r PARAMS ((tree *, int *, void *)); 5290075Sobrienextern int cp_statement_code_p PARAMS ((enum tree_code)); 5350397Sobrien 5490075Sobrienstatic tree handle_java_interface_attribute PARAMS ((tree *, tree, tree, int, bool *)); 5590075Sobrienstatic tree handle_com_interface_attribute PARAMS ((tree *, tree, tree, int, bool *)); 5690075Sobrienstatic tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, bool *)); 5718334Speter 5890075Sobrien/* If REF is an lvalue, returns the kind of lvalue that REF is. 5990075Sobrien Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is 6090075Sobrien non-zero, rvalues of class type are considered lvalues. */ 6118334Speter 6290075Sobrienstatic cp_lvalue_kind 6352284Sobrienlvalue_p_1 (ref, treat_class_rvalues_as_lvalues) 6418334Speter tree ref; 6552284Sobrien int treat_class_rvalues_as_lvalues; 6618334Speter{ 6790075Sobrien cp_lvalue_kind op1_lvalue_kind = clk_none; 6890075Sobrien cp_lvalue_kind op2_lvalue_kind = clk_none; 6990075Sobrien 7018334Speter if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) 7190075Sobrien return clk_ordinary; 7218334Speter 7390075Sobrien if (ref == current_class_ptr) 7490075Sobrien return clk_none; 7518334Speter 7618334Speter switch (TREE_CODE (ref)) 7718334Speter { 7818334Speter /* preincrements and predecrements are valid lvals, provided 7950397Sobrien what they refer to are valid lvals. */ 8018334Speter case PREINCREMENT_EXPR: 8118334Speter case PREDECREMENT_EXPR: 8218334Speter case SAVE_EXPR: 8350397Sobrien case UNSAVE_EXPR: 8450397Sobrien case TRY_CATCH_EXPR: 8550397Sobrien case WITH_CLEANUP_EXPR: 8652284Sobrien case REALPART_EXPR: 8752284Sobrien case IMAGPART_EXPR: 8890075Sobrien /* This shouldn't be here, but there are lots of places in the compiler 8990075Sobrien that are sloppy about tacking on NOP_EXPRs to the same type when 9090075Sobrien no actual conversion is happening. */ 9152284Sobrien case NOP_EXPR: 9252284Sobrien return lvalue_p_1 (TREE_OPERAND (ref, 0), 9352284Sobrien treat_class_rvalues_as_lvalues); 9418334Speter 9590075Sobrien case COMPONENT_REF: 9690075Sobrien op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), 9790075Sobrien treat_class_rvalues_as_lvalues); 9890075Sobrien if (op1_lvalue_kind 9990075Sobrien /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some 10090075Sobrien situations. */ 10190075Sobrien && TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL 10290075Sobrien && DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1))) 10390075Sobrien { 10490075Sobrien /* Clear the ordinary bit. If this object was a class 10590075Sobrien rvalue we want to preserve that information. */ 10690075Sobrien op1_lvalue_kind &= ~clk_ordinary; 10790075Sobrien /* The lvalue is for a btifield. */ 10890075Sobrien op1_lvalue_kind |= clk_bitfield; 10990075Sobrien } 11090075Sobrien return op1_lvalue_kind; 11190075Sobrien 11218334Speter case STRING_CST: 11390075Sobrien return clk_ordinary; 11418334Speter 11518334Speter case VAR_DECL: 11618334Speter if (TREE_READONLY (ref) && ! TREE_STATIC (ref) 11718334Speter && DECL_LANG_SPECIFIC (ref) 11818334Speter && DECL_IN_AGGR_P (ref)) 11990075Sobrien return clk_none; 12018334Speter case INDIRECT_REF: 12118334Speter case ARRAY_REF: 12218334Speter case PARM_DECL: 12318334Speter case RESULT_DECL: 12452284Sobrien if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) 12590075Sobrien return clk_ordinary; 12618334Speter break; 12718334Speter 12818334Speter /* A currently unresolved scope ref. */ 12918334Speter case SCOPE_REF: 13090075Sobrien abort (); 13118334Speter case OFFSET_REF: 13218334Speter if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL) 13390075Sobrien return clk_ordinary; 13490075Sobrien /* Fall through. */ 13590075Sobrien case MAX_EXPR: 13690075Sobrien case MIN_EXPR: 13790075Sobrien op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), 13890075Sobrien treat_class_rvalues_as_lvalues); 13990075Sobrien op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1), 14090075Sobrien treat_class_rvalues_as_lvalues); 14118334Speter break; 14218334Speter 14318334Speter case COND_EXPR: 14490075Sobrien op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1), 14590075Sobrien treat_class_rvalues_as_lvalues); 14690075Sobrien op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2), 14790075Sobrien treat_class_rvalues_as_lvalues); 14890075Sobrien break; 14918334Speter 15018334Speter case MODIFY_EXPR: 15190075Sobrien return clk_ordinary; 15218334Speter 15318334Speter case COMPOUND_EXPR: 15452284Sobrien return lvalue_p_1 (TREE_OPERAND (ref, 1), 15590075Sobrien treat_class_rvalues_as_lvalues); 15618334Speter 15752284Sobrien case TARGET_EXPR: 15890075Sobrien return treat_class_rvalues_as_lvalues ? clk_class : clk_none; 15952284Sobrien 16052284Sobrien case CALL_EXPR: 16190075Sobrien case VA_ARG_EXPR: 16290075Sobrien return ((treat_class_rvalues_as_lvalues 16390075Sobrien && IS_AGGR_TYPE (TREE_TYPE (ref))) 16490075Sobrien ? clk_class : clk_none); 16552284Sobrien 16652284Sobrien case FUNCTION_DECL: 16752284Sobrien /* All functions (except non-static-member functions) are 16852284Sobrien lvalues. */ 16990075Sobrien return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref) 17090075Sobrien ? clk_none : clk_ordinary); 17152284Sobrien 17250397Sobrien default: 17350397Sobrien break; 17418334Speter } 17518334Speter 17690075Sobrien /* If one operand is not an lvalue at all, then this expression is 17790075Sobrien not an lvalue. */ 17890075Sobrien if (!op1_lvalue_kind || !op2_lvalue_kind) 17990075Sobrien return clk_none; 18090075Sobrien 18190075Sobrien /* Otherwise, it's an lvalue, and it has all the odd properties 18290075Sobrien contributed by either operand. */ 18390075Sobrien op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind; 18490075Sobrien /* It's not an ordinary lvalue if it involves either a bit-field or 18590075Sobrien a class rvalue. */ 18690075Sobrien if ((op1_lvalue_kind & ~clk_ordinary) != clk_none) 18790075Sobrien op1_lvalue_kind &= ~clk_ordinary; 18890075Sobrien return op1_lvalue_kind; 18918334Speter} 19018334Speter 19190075Sobrien/* If REF is an lvalue, returns the kind of lvalue that REF is. 19290075Sobrien Otherwise, returns clk_none. Lvalues can be assigned, unless they 19390075Sobrien have TREE_READONLY, or unless they are FUNCTION_DECLs. Lvalues can 19490075Sobrien have their address taken, unless they have DECL_REGISTER. */ 19552284Sobrien 19690075Sobriencp_lvalue_kind 19752284Sobrienreal_lvalue_p (ref) 19852284Sobrien tree ref; 19952284Sobrien{ 20052284Sobrien return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0); 20152284Sobrien} 20252284Sobrien 20390075Sobrien/* This differs from real_lvalue_p in that class rvalues are 20490075Sobrien considered lvalues. */ 20552284Sobrien 20618334Speterint 20718334Speterlvalue_p (ref) 20818334Speter tree ref; 20918334Speter{ 21090075Sobrien return 21190075Sobrien (lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1) != clk_none); 21218334Speter} 21318334Speter 21418334Speter/* Return nonzero if REF is an lvalue valid for this language; 21518334Speter otherwise, print an error message and return zero. */ 21618334Speter 21718334Speterint 21818334Speterlvalue_or_else (ref, string) 21918334Speter tree ref; 22052284Sobrien const char *string; 22118334Speter{ 22218334Speter int win = lvalue_p (ref); 22318334Speter if (! win) 22418334Speter error ("non-lvalue in %s", string); 22518334Speter return win; 22618334Speter} 22718334Speter 22890075Sobrien/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */ 22990075Sobrien 23090075Sobrienstatic tree 23190075Sobrienbuild_target_expr (decl, value) 23290075Sobrien tree decl; 23390075Sobrien tree value; 23490075Sobrien{ 23590075Sobrien tree t; 23690075Sobrien 23790075Sobrien t = build (TARGET_EXPR, TREE_TYPE (decl), decl, value, 23890075Sobrien maybe_build_cleanup (decl), NULL_TREE); 23990075Sobrien /* We always set TREE_SIDE_EFFECTS so that expand_expr does not 24090075Sobrien ignore the TARGET_EXPR. If there really turn out to be no 24190075Sobrien side-effects, then the optimizer should be able to get rid of 24290075Sobrien whatever code is generated anyhow. */ 24390075Sobrien TREE_SIDE_EFFECTS (t) = 1; 24490075Sobrien 24590075Sobrien return t; 24690075Sobrien} 24790075Sobrien 24818334Speter/* INIT is a CALL_EXPR which needs info about its target. 24918334Speter TYPE is the type that this initialization should appear to have. 25018334Speter 25118334Speter Build an encapsulation of the initialization to perform 25218334Speter and return it so that it can be processed by language-independent 25350397Sobrien and language-specific expression expanders. */ 25418334Speter 25518334Spetertree 25650397Sobrienbuild_cplus_new (type, init) 25718334Speter tree type; 25818334Speter tree init; 25918334Speter{ 26090075Sobrien tree fn; 26118334Speter tree slot; 26218334Speter tree rval; 26318334Speter 26490075Sobrien /* Make sure that we're not trying to create an instance of an 26590075Sobrien abstract class. */ 26690075Sobrien abstract_virtuals_error (NULL_TREE, type); 26790075Sobrien 26850397Sobrien if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR) 26952284Sobrien return convert (type, init); 27050397Sobrien 27118334Speter slot = build (VAR_DECL, type); 27250397Sobrien DECL_ARTIFICIAL (slot) = 1; 27390075Sobrien DECL_CONTEXT (slot) = current_function_decl; 27418334Speter layout_decl (slot, 0); 27590075Sobrien 27690075Sobrien /* We split the CALL_EXPR into its function and its arguments here. 27790075Sobrien Then, in expand_expr, we put them back together. The reason for 27890075Sobrien this is that this expression might be a default argument 27990075Sobrien expression. In that case, we need a new temporary every time the 28090075Sobrien expression is used. That's what break_out_target_exprs does; it 28190075Sobrien replaces every AGGR_INIT_EXPR with a copy that uses a fresh 28290075Sobrien temporary slot. Then, expand_expr builds up a call-expression 28390075Sobrien using the new slot. */ 28490075Sobrien fn = TREE_OPERAND (init, 0); 28590075Sobrien rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot); 28618334Speter TREE_SIDE_EFFECTS (rval) = 1; 28790075Sobrien AGGR_INIT_VIA_CTOR_P (rval) 28890075Sobrien = (TREE_CODE (fn) == ADDR_EXPR 28990075Sobrien && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL 29090075Sobrien && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0))); 29190075Sobrien rval = build_target_expr (slot, rval); 29218334Speter 29318334Speter return rval; 29418334Speter} 29518334Speter 29690075Sobrien/* Buidl a TARGET_EXPR using INIT to initialize a new temporary of the 29790075Sobrien indicated TYPE. */ 29850397Sobrien 29950397Sobrientree 30090075Sobrienbuild_target_expr_with_type (init, type) 30150397Sobrien tree init; 30290075Sobrien tree type; 30350397Sobrien{ 30450397Sobrien tree slot; 30550397Sobrien tree rval; 30650397Sobrien 30790075Sobrien if (TREE_CODE (init) == TARGET_EXPR) 30890075Sobrien return init; 30990075Sobrien 31090075Sobrien slot = build (VAR_DECL, type); 31150397Sobrien DECL_ARTIFICIAL (slot) = 1; 31290075Sobrien DECL_CONTEXT (slot) = current_function_decl; 31350397Sobrien layout_decl (slot, 0); 31490075Sobrien rval = build_target_expr (slot, init); 31550397Sobrien 31650397Sobrien return rval; 31750397Sobrien} 31850397Sobrien 31990075Sobrien/* Like build_target_expr_with_type, but use the type of INIT. */ 32018334Speter 32118334Spetertree 32290075Sobrienget_target_expr (init) 32390075Sobrien tree init; 32418334Speter{ 32590075Sobrien return build_target_expr_with_type (init, TREE_TYPE (init)); 32618334Speter} 32718334Speter 32818334Speter/* Recursively perform a preorder search EXP for CALL_EXPRs, making 32918334Speter copies where they are found. Returns a deep copy all nodes transitively 33018334Speter containing CALL_EXPRs. */ 33118334Speter 33218334Spetertree 33318334Speterbreak_out_calls (exp) 33418334Speter tree exp; 33518334Speter{ 33650397Sobrien register tree t1, t2 = NULL_TREE; 33718334Speter register enum tree_code code; 33818334Speter register int changed = 0; 33918334Speter register int i; 34018334Speter 34118334Speter if (exp == NULL_TREE) 34218334Speter return exp; 34318334Speter 34418334Speter code = TREE_CODE (exp); 34518334Speter 34618334Speter if (code == CALL_EXPR) 34718334Speter return copy_node (exp); 34818334Speter 34950397Sobrien /* Don't try and defeat a save_expr, as it should only be done once. */ 35018334Speter if (code == SAVE_EXPR) 35118334Speter return exp; 35218334Speter 35318334Speter switch (TREE_CODE_CLASS (code)) 35418334Speter { 35518334Speter default: 35618334Speter abort (); 35718334Speter 35818334Speter case 'c': /* a constant */ 35918334Speter case 't': /* a type node */ 36018334Speter case 'x': /* something random, like an identifier or an ERROR_MARK. */ 36118334Speter return exp; 36218334Speter 36318334Speter case 'd': /* A decl node */ 36418334Speter#if 0 /* This is bogus. jason 9/21/94 */ 36518334Speter 36618334Speter t1 = break_out_calls (DECL_INITIAL (exp)); 36718334Speter if (t1 != DECL_INITIAL (exp)) 36818334Speter { 36918334Speter exp = copy_node (exp); 37018334Speter DECL_INITIAL (exp) = t1; 37118334Speter } 37218334Speter#endif 37318334Speter return exp; 37418334Speter 37518334Speter case 'b': /* A block node */ 37618334Speter { 37718334Speter /* Don't know how to handle these correctly yet. Must do a 37818334Speter break_out_calls on all DECL_INITIAL values for local variables, 37918334Speter and also break_out_calls on all sub-blocks and sub-statements. */ 38018334Speter abort (); 38118334Speter } 38218334Speter return exp; 38318334Speter 38418334Speter case 'e': /* an expression */ 38518334Speter case 'r': /* a reference */ 38618334Speter case 's': /* an expression with side effects */ 38790075Sobrien for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; i--) 38818334Speter { 38918334Speter t1 = break_out_calls (TREE_OPERAND (exp, i)); 39018334Speter if (t1 != TREE_OPERAND (exp, i)) 39118334Speter { 39218334Speter exp = copy_node (exp); 39318334Speter TREE_OPERAND (exp, i) = t1; 39418334Speter } 39518334Speter } 39618334Speter return exp; 39718334Speter 39818334Speter case '<': /* a comparison expression */ 39918334Speter case '2': /* a binary arithmetic expression */ 40018334Speter t2 = break_out_calls (TREE_OPERAND (exp, 1)); 40118334Speter if (t2 != TREE_OPERAND (exp, 1)) 40218334Speter changed = 1; 40318334Speter case '1': /* a unary arithmetic expression */ 40418334Speter t1 = break_out_calls (TREE_OPERAND (exp, 0)); 40518334Speter if (t1 != TREE_OPERAND (exp, 0)) 40618334Speter changed = 1; 40718334Speter if (changed) 40818334Speter { 40990075Sobrien if (TREE_CODE_LENGTH (code) == 1) 41018334Speter return build1 (code, TREE_TYPE (exp), t1); 41118334Speter else 41218334Speter return build (code, TREE_TYPE (exp), t1, t2); 41318334Speter } 41418334Speter return exp; 41518334Speter } 41618334Speter 41718334Speter} 41818334Speter 41918334Speter/* Construct, lay out and return the type of methods belonging to class 42018334Speter BASETYPE and whose arguments are described by ARGTYPES and whose values 42118334Speter are described by RETTYPE. If each type exists already, reuse it. */ 42250397Sobrien 42318334Spetertree 42418334Speterbuild_cplus_method_type (basetype, rettype, argtypes) 42518334Speter tree basetype, rettype, argtypes; 42618334Speter{ 42718334Speter register tree t; 42818334Speter tree ptype; 42918334Speter int hashcode; 43018334Speter 43118334Speter /* Make a node of the sort we want. */ 43218334Speter t = make_node (METHOD_TYPE); 43318334Speter 43418334Speter TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); 43518334Speter TREE_TYPE (t) = rettype; 43690075Sobrien ptype = build_pointer_type (basetype); 43718334Speter 43818334Speter /* The actual arglist for this function includes a "hidden" argument 43918334Speter which is "this". Put it into the list of argument types. */ 44018334Speter argtypes = tree_cons (NULL_TREE, ptype, argtypes); 44118334Speter TYPE_ARG_TYPES (t) = argtypes; 44218334Speter TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */ 44318334Speter 44418334Speter /* If we already have such a type, use the old one and free this one. 44518334Speter Note that it also frees up the above cons cell if found. */ 44690075Sobrien hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + 44790075Sobrien type_hash_list (argtypes); 44890075Sobrien 44918334Speter t = type_hash_canon (hashcode, t); 45018334Speter 45190075Sobrien if (!COMPLETE_TYPE_P (t)) 45218334Speter layout_type (t); 45318334Speter 45418334Speter return t; 45518334Speter} 45618334Speter 45750397Sobrienstatic tree 45850397Sobrienbuild_cplus_array_type_1 (elt_type, index_type) 45918334Speter tree elt_type; 46018334Speter tree index_type; 46118334Speter{ 46218334Speter tree t; 46318334Speter 46490075Sobrien if (elt_type == error_mark_node || index_type == error_mark_node) 46590075Sobrien return error_mark_node; 46618334Speter 46752284Sobrien if (processing_template_decl 46852284Sobrien || uses_template_parms (elt_type) 46950397Sobrien || uses_template_parms (index_type)) 47050397Sobrien { 47150397Sobrien t = make_node (ARRAY_TYPE); 47250397Sobrien TREE_TYPE (t) = elt_type; 47350397Sobrien TYPE_DOMAIN (t) = index_type; 47450397Sobrien } 47550397Sobrien else 47650397Sobrien t = build_array_type (elt_type, index_type); 47718334Speter 47818334Speter /* Push these needs up so that initialization takes place 47918334Speter more easily. */ 48090075Sobrien TYPE_NEEDS_CONSTRUCTING (t) 48190075Sobrien = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); 48290075Sobrien TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) 48390075Sobrien = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); 48418334Speter return t; 48518334Speter} 48650397Sobrien 48750397Sobrientree 48850397Sobrienbuild_cplus_array_type (elt_type, index_type) 48950397Sobrien tree elt_type; 49050397Sobrien tree index_type; 49150397Sobrien{ 49250397Sobrien tree t; 49390075Sobrien int type_quals = cp_type_quals (elt_type); 49452284Sobrien 49590075Sobrien if (type_quals != TYPE_UNQUALIFIED) 49690075Sobrien elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED); 49750397Sobrien 49850397Sobrien t = build_cplus_array_type_1 (elt_type, index_type); 49950397Sobrien 50052284Sobrien if (type_quals != TYPE_UNQUALIFIED) 50152284Sobrien t = cp_build_qualified_type (t, type_quals); 50250397Sobrien 50350397Sobrien return t; 50450397Sobrien} 50518334Speter 50690075Sobrien/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles 50790075Sobrien arrays correctly. In particular, if TYPE is an array of T's, and 50890075Sobrien TYPE_QUALS is non-empty, returns an array of qualified T's. If 50990075Sobrien at attempt is made to qualify a type illegally, and COMPLAIN is 51090075Sobrien non-zero, an error is issued. If COMPLAIN is zero, error_mark_node 51190075Sobrien is returned. */ 51218334Speter 51318334Spetertree 51490075Sobriencp_build_qualified_type_real (type, type_quals, complain) 51518334Speter tree type; 51652284Sobrien int type_quals; 51790075Sobrien int complain; 51818334Speter{ 51990075Sobrien tree result; 52090075Sobrien 52150397Sobrien if (type == error_mark_node) 52250397Sobrien return type; 52390075Sobrien 52490075Sobrien if (type_quals == cp_type_quals (type)) 52590075Sobrien return type; 52690075Sobrien 52752284Sobrien /* A restrict-qualified pointer type must be a pointer (or reference) 52852284Sobrien to object or incomplete type. */ 52952284Sobrien if ((type_quals & TYPE_QUAL_RESTRICT) 53090075Sobrien && TREE_CODE (type) != TEMPLATE_TYPE_PARM 53152284Sobrien && (!POINTER_TYPE_P (type) 53252284Sobrien || TYPE_PTRMEM_P (type) 53352284Sobrien || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)) 53452284Sobrien { 53590075Sobrien if (complain) 53690075Sobrien error ("`%T' cannot be `restrict'-qualified", type); 53790075Sobrien else 53890075Sobrien return error_mark_node; 53990075Sobrien 54052284Sobrien type_quals &= ~TYPE_QUAL_RESTRICT; 54152284Sobrien } 54252284Sobrien 54390075Sobrien if (type_quals != TYPE_UNQUALIFIED 54490075Sobrien && TREE_CODE (type) == FUNCTION_TYPE) 54518334Speter { 54690075Sobrien if (complain) 54790075Sobrien error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type); 54890075Sobrien else 54990075Sobrien return error_mark_node; 55090075Sobrien type_quals = TYPE_UNQUALIFIED; 55190075Sobrien } 55290075Sobrien else if (TREE_CODE (type) == ARRAY_TYPE) 55390075Sobrien { 55490075Sobrien /* In C++, the qualification really applies to the array element 55590075Sobrien type. Obtain the appropriately qualified element type. */ 55690075Sobrien tree t; 55790075Sobrien tree element_type 55890075Sobrien = cp_build_qualified_type_real (TREE_TYPE (type), 55990075Sobrien type_quals, 56090075Sobrien complain); 56118334Speter 56290075Sobrien if (element_type == error_mark_node) 56390075Sobrien return error_mark_node; 56418334Speter 56590075Sobrien /* See if we already have an identically qualified type. */ 56690075Sobrien t = get_qualified_type (type, type_quals); 56718334Speter 56890075Sobrien /* If we didn't already have it, create it now. */ 56990075Sobrien if (!t) 57018334Speter { 57190075Sobrien /* Make a new array type, just like the old one, but with the 57290075Sobrien appropriately qualified element type. */ 57390075Sobrien t = build_type_copy (type); 57490075Sobrien TREE_TYPE (t) = element_type; 57518334Speter } 57618334Speter 57790075Sobrien /* Even if we already had this variant, we update 57890075Sobrien TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case 57990075Sobrien they changed since the variant was originally created. 58090075Sobrien 58190075Sobrien This seems hokey; if there is some way to use a previous 58290075Sobrien variant *without* coming through here, 58390075Sobrien TYPE_NEEDS_CONSTRUCTING will never be updated. */ 58490075Sobrien TYPE_NEEDS_CONSTRUCTING (t) 58590075Sobrien = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (element_type)); 58690075Sobrien TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) 58790075Sobrien = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type)); 58890075Sobrien return t; 58918334Speter } 59090075Sobrien else if (TYPE_PTRMEMFUNC_P (type)) 59190075Sobrien { 59290075Sobrien /* For a pointer-to-member type, we can't just return a 59390075Sobrien cv-qualified version of the RECORD_TYPE. If we do, we 59490075Sobrien haven't change the field that contains the actual pointer to 59590075Sobrien a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */ 59690075Sobrien tree t; 59790075Sobrien 59890075Sobrien t = TYPE_PTRMEMFUNC_FN_TYPE (type); 59990075Sobrien t = cp_build_qualified_type_real (t, type_quals, complain); 60090075Sobrien return build_ptrmemfunc_type (t); 60190075Sobrien } 60290075Sobrien 60390075Sobrien /* Retrieve (or create) the appropriately qualified variant. */ 60490075Sobrien result = build_qualified_type (type, type_quals); 60590075Sobrien 60690075Sobrien /* If this was a pointer-to-method type, and we just made a copy, 60790075Sobrien then we need to clear the cached associated 60890075Sobrien pointer-to-member-function type; it is not valid for the new 60990075Sobrien type. */ 61090075Sobrien if (result != type 61190075Sobrien && TREE_CODE (type) == POINTER_TYPE 61290075Sobrien && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) 61390075Sobrien TYPE_SET_PTRMEMFUNC_TYPE (result, NULL_TREE); 61490075Sobrien 61590075Sobrien return result; 61618334Speter} 61750397Sobrien 61850397Sobrien/* Returns the canonical version of TYPE. In other words, if TYPE is 61950397Sobrien a typedef, returns the underlying type. The cv-qualification of 62050397Sobrien the type returned matches the type input; they will always be 62150397Sobrien compatible types. */ 62250397Sobrien 62350397Sobrientree 62450397Sobriencanonical_type_variant (t) 62550397Sobrien tree t; 62650397Sobrien{ 62790075Sobrien return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t)); 62850397Sobrien} 62918334Speter 63052284Sobrien/* Makes new binfos for the indirect bases under BINFO, and updates 63150397Sobrien BINFO_OFFSET for them and their bases. */ 63218334Speter 63352284Sobrienvoid 63452284Sobrienunshare_base_binfos (binfo) 63552284Sobrien tree binfo; 63650397Sobrien{ 63752284Sobrien tree binfos = BINFO_BASETYPES (binfo); 63852284Sobrien tree new_binfo; 63952284Sobrien int j; 64050397Sobrien 64152284Sobrien if (binfos == NULL_TREE) 64252284Sobrien return; 64350397Sobrien 64452284Sobrien /* Now unshare the structure beneath BINFO. */ 64552284Sobrien for (j = TREE_VEC_LENGTH (binfos)-1; 64652284Sobrien j >= 0; j--) 64752284Sobrien { 64852284Sobrien tree base_binfo = TREE_VEC_ELT (binfos, j); 64952284Sobrien new_binfo = TREE_VEC_ELT (binfos, j) 65052284Sobrien = make_binfo (BINFO_OFFSET (base_binfo), 65152284Sobrien base_binfo, 65252284Sobrien BINFO_VTABLE (base_binfo), 65352284Sobrien BINFO_VIRTUALS (base_binfo)); 65452284Sobrien TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo); 65552284Sobrien TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo); 65652284Sobrien TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo); 65752284Sobrien BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; 65890075Sobrien BINFO_PRIMARY_BASE_OF (new_binfo) = NULL_TREE; 65952284Sobrien unshare_base_binfos (new_binfo); 66050397Sobrien } 66150397Sobrien} 66250397Sobrien 66318334Speter 66418334Speter/* Hashing of lists so that we don't make duplicates. 66518334Speter The entry point is `list_hash_canon'. */ 66618334Speter 66718334Speter/* Now here is the hash table. When recording a list, it is added 66818334Speter to the slot whose index is the hash code mod the table size. 66918334Speter Note that the hash table is used for several kinds of lists. 67018334Speter While all these live in the same table, they are completely independent, 67118334Speter and the hash code is computed differently for each of these. */ 67218334Speter 67390075Sobrienstatic htab_t list_hash_table; 67418334Speter 67590075Sobrienstruct list_proxy 67690075Sobrien{ 67790075Sobrien tree purpose; 67890075Sobrien tree value; 67990075Sobrien tree chain; 68090075Sobrien}; 68190075Sobrien 68290075Sobrien/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy 68390075Sobrien for a node we are thinking about adding). */ 68490075Sobrien 68590075Sobrienstatic int 68690075Sobrienlist_hash_eq (entry, data) 68790075Sobrien const void *entry; 68890075Sobrien const void *data; 68990075Sobrien{ 69090075Sobrien tree t = (tree) entry; 69190075Sobrien struct list_proxy *proxy = (struct list_proxy *) data; 69290075Sobrien 69390075Sobrien return (TREE_VALUE (t) == proxy->value 69490075Sobrien && TREE_PURPOSE (t) == proxy->purpose 69590075Sobrien && TREE_CHAIN (t) == proxy->chain); 69690075Sobrien} 69790075Sobrien 69818334Speter/* Compute a hash code for a list (chain of TREE_LIST nodes 69918334Speter with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the 70018334Speter TREE_COMMON slots), by adding the hash codes of the individual entries. */ 70118334Speter 70290075Sobrienstatic hashval_t 70390075Sobrienlist_hash_pieces (purpose, value, chain) 70490075Sobrien tree purpose; 70590075Sobrien tree value; 70690075Sobrien tree chain; 70718334Speter{ 70890075Sobrien hashval_t hashcode = 0; 70990075Sobrien 71050397Sobrien if (chain) 71150397Sobrien hashcode += TYPE_HASH (chain); 71290075Sobrien 71350397Sobrien if (value) 71450397Sobrien hashcode += TYPE_HASH (value); 71518334Speter else 71618334Speter hashcode += 1007; 71750397Sobrien if (purpose) 71850397Sobrien hashcode += TYPE_HASH (purpose); 71918334Speter else 72018334Speter hashcode += 1009; 72118334Speter return hashcode; 72218334Speter} 72318334Speter 72490075Sobrien/* Hash an already existing TREE_LIST. */ 72518334Speter 72690075Sobrienstatic hashval_t 72790075Sobrienlist_hash (p) 72890075Sobrien const void *p; 72918334Speter{ 73090075Sobrien tree t = (tree) p; 73190075Sobrien return list_hash_pieces (TREE_PURPOSE (t), 73290075Sobrien TREE_VALUE (t), 73390075Sobrien TREE_CHAIN (t)); 73418334Speter} 73518334Speter 73652284Sobrien/* Given list components PURPOSE, VALUE, AND CHAIN, return the canonical 73752284Sobrien object for an identical list if one already exists. Otherwise, build a 73852284Sobrien new one, and record it as the canonical object. */ 73918334Speter 74018334Spetertree 74152284Sobrienhash_tree_cons (purpose, value, chain) 74218334Speter tree purpose, value, chain; 74318334Speter{ 74450397Sobrien int hashcode = 0; 74590075Sobrien PTR* slot; 74690075Sobrien struct list_proxy proxy; 74718334Speter 74890075Sobrien /* Hash the list node. */ 74990075Sobrien hashcode = list_hash_pieces (purpose, value, chain); 75090075Sobrien /* Create a proxy for the TREE_LIST we would like to create. We 75190075Sobrien don't actually create it so as to avoid creating garbage. */ 75290075Sobrien proxy.purpose = purpose; 75390075Sobrien proxy.value = value; 75490075Sobrien proxy.chain = chain; 75590075Sobrien /* See if it is already in the table. */ 75690075Sobrien slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode, 75790075Sobrien INSERT); 75890075Sobrien /* If not, create a new node. */ 75990075Sobrien if (!*slot) 76090075Sobrien *slot = (PTR) tree_cons (purpose, value, chain); 76190075Sobrien return *slot; 76218334Speter} 76318334Speter 76418334Speter/* Constructor for hashed lists. */ 76550397Sobrien 76618334Spetertree 76718334Speterhash_tree_chain (value, chain) 76818334Speter tree value, chain; 76918334Speter{ 77052284Sobrien return hash_tree_cons (NULL_TREE, value, chain); 77118334Speter} 77218334Speter 77318334Speter/* Similar, but used for concatenating two lists. */ 77450397Sobrien 77518334Spetertree 77618334Speterhash_chainon (list1, list2) 77718334Speter tree list1, list2; 77818334Speter{ 77918334Speter if (list2 == 0) 78018334Speter return list1; 78118334Speter if (list1 == 0) 78218334Speter return list2; 78318334Speter if (TREE_CHAIN (list1) == NULL_TREE) 78418334Speter return hash_tree_chain (TREE_VALUE (list1), list2); 78518334Speter return hash_tree_chain (TREE_VALUE (list1), 78618334Speter hash_chainon (TREE_CHAIN (list1), list2)); 78718334Speter} 78818334Speter 78918334Speter/* Build an association between TYPE and some parameters: 79018334Speter 79118334Speter OFFSET is the offset added to `this' to convert it to a pointer 79218334Speter of type `TYPE *' 79318334Speter 79418334Speter BINFO is the base binfo to use, if we are deriving from one. This 79518334Speter is necessary, as we want specialized parent binfos from base 79618334Speter classes, so that the VTABLE_NAMEs of bases are for the most derived 79750397Sobrien type, instead of the simple type. 79818334Speter 79918334Speter VTABLE is the virtual function table with which to initialize 80018334Speter sub-objects of type TYPE. 80118334Speter 80252284Sobrien VIRTUALS are the virtual functions sitting in VTABLE. */ 80318334Speter 80418334Spetertree 80552284Sobrienmake_binfo (offset, binfo, vtable, virtuals) 80618334Speter tree offset, binfo; 80718334Speter tree vtable, virtuals; 80818334Speter{ 80990075Sobrien tree new_binfo = make_tree_vec (11); 81018334Speter tree type; 81118334Speter 81218334Speter if (TREE_CODE (binfo) == TREE_VEC) 81318334Speter type = BINFO_TYPE (binfo); 81418334Speter else 81518334Speter { 81618334Speter type = binfo; 81752284Sobrien binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE; 81818334Speter } 81918334Speter 82018334Speter TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); 82118334Speter BINFO_OFFSET (new_binfo) = offset; 82218334Speter BINFO_VTABLE (new_binfo) = vtable; 82318334Speter BINFO_VIRTUALS (new_binfo) = virtuals; 82418334Speter 82518334Speter if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE) 82618334Speter BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); 82718334Speter return new_binfo; 82818334Speter} 82918334Speter 83090075Sobrien/* Return a TREE_LIST whose TREE_VALUE nodes along the 83190075Sobrien BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In 83290075Sobrien other words, while the BINFO_INHERITANCE_CHAIN goes from base 83390075Sobrien classes to derived classes, the reversed path goes from derived 83490075Sobrien classes to base classes. */ 83518334Speter 83618334Spetertree 83790075Sobrienreverse_path (binfo) 83890075Sobrien tree binfo; 83918334Speter{ 84090075Sobrien tree reversed_path; 84118334Speter 84290075Sobrien reversed_path = NULL_TREE; 84390075Sobrien while (binfo) 84418334Speter { 84590075Sobrien reversed_path = tree_cons (NULL_TREE, binfo, reversed_path); 84690075Sobrien binfo = BINFO_INHERITANCE_CHAIN (binfo); 84718334Speter } 84890075Sobrien 84990075Sobrien return reversed_path; 85018334Speter} 85118334Speter 85218334Spetervoid 85318334Speterdebug_binfo (elem) 85418334Speter tree elem; 85518334Speter{ 85690075Sobrien HOST_WIDE_INT n; 85718334Speter tree virtuals; 85818334Speter 85990075Sobrien fprintf (stderr, "type \"%s\", offset = ", 86090075Sobrien TYPE_NAME_STRING (BINFO_TYPE (elem))); 86190075Sobrien fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, 86290075Sobrien TREE_INT_CST_LOW (BINFO_OFFSET (elem))); 86390075Sobrien fprintf (stderr, "\nvtable type:\n"); 86418334Speter debug_tree (BINFO_TYPE (elem)); 86518334Speter if (BINFO_VTABLE (elem)) 86690075Sobrien fprintf (stderr, "vtable decl \"%s\"\n", 86790075Sobrien IDENTIFIER_POINTER (DECL_NAME (get_vtbl_decl_for_binfo (elem)))); 86818334Speter else 86918334Speter fprintf (stderr, "no vtable decl yet\n"); 87018334Speter fprintf (stderr, "virtuals:\n"); 87118334Speter virtuals = BINFO_VIRTUALS (elem); 87290075Sobrien n = 0; 87318334Speter 87418334Speter while (virtuals) 87518334Speter { 87690075Sobrien tree fndecl = TREE_VALUE (virtuals); 87750397Sobrien fprintf (stderr, "%s [%ld =? %ld]\n", 87818334Speter IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)), 87950397Sobrien (long) n, (long) TREE_INT_CST_LOW (DECL_VINDEX (fndecl))); 88018334Speter ++n; 88118334Speter virtuals = TREE_CHAIN (virtuals); 88218334Speter } 88318334Speter} 88418334Speter 88518334Speterint 88618334Spetercount_functions (t) 88718334Speter tree t; 88818334Speter{ 88950397Sobrien int i; 89018334Speter if (TREE_CODE (t) == FUNCTION_DECL) 89118334Speter return 1; 89250397Sobrien else if (TREE_CODE (t) == OVERLOAD) 89350397Sobrien { 89450397Sobrien for (i=0; t; t = OVL_CHAIN (t)) 89550397Sobrien i++; 89650397Sobrien return i; 89750397Sobrien } 89818334Speter 89990075Sobrien abort (); 90018334Speter return 0; 90118334Speter} 90218334Speter 90318334Speterint 90418334Speteris_overloaded_fn (x) 90518334Speter tree x; 90618334Speter{ 90752284Sobrien /* A baselink is also considered an overloaded function. */ 90852284Sobrien if (TREE_CODE (x) == OFFSET_REF) 90952284Sobrien x = TREE_OPERAND (x, 1); 91052284Sobrien if (BASELINK_P (x)) 91152284Sobrien x = TREE_VALUE (x); 91250397Sobrien return (TREE_CODE (x) == FUNCTION_DECL 91350397Sobrien || TREE_CODE (x) == TEMPLATE_ID_EXPR 91450397Sobrien || DECL_FUNCTION_TEMPLATE_P (x) 91550397Sobrien || TREE_CODE (x) == OVERLOAD); 91618334Speter} 91718334Speter 91818334Speterint 91918334Speterreally_overloaded_fn (x) 92018334Speter tree x; 92118334Speter{ 92252284Sobrien /* A baselink is also considered an overloaded function. */ 92352284Sobrien if (TREE_CODE (x) == OFFSET_REF) 92452284Sobrien x = TREE_OPERAND (x, 1); 92552284Sobrien if (BASELINK_P (x)) 92650397Sobrien x = TREE_VALUE (x); 92750397Sobrien return (TREE_CODE (x) == OVERLOAD 92850397Sobrien && (TREE_CHAIN (x) != NULL_TREE 92950397Sobrien || DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x)))); 93018334Speter} 93118334Speter 93218334Spetertree 93318334Speterget_first_fn (from) 93418334Speter tree from; 93518334Speter{ 93650397Sobrien my_friendly_assert (is_overloaded_fn (from), 9); 93750397Sobrien /* A baselink is also considered an overloaded function. */ 93852284Sobrien if (BASELINK_P (from)) 93950397Sobrien from = TREE_VALUE (from); 94050397Sobrien return OVL_CURRENT (from); 94150397Sobrien} 94218334Speter 94352284Sobrien/* Returns nonzero if T is a ->* or .* expression that refers to a 94452284Sobrien member function. */ 94552284Sobrien 94652284Sobrienint 94752284Sobrienbound_pmf_p (t) 94852284Sobrien tree t; 94952284Sobrien{ 95052284Sobrien return (TREE_CODE (t) == OFFSET_REF 95152284Sobrien && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1)))); 95252284Sobrien} 95352284Sobrien 95450397Sobrien/* Return a new OVL node, concatenating it with the old one. */ 95550397Sobrien 95650397Sobrientree 95750397Sobrienovl_cons (decl, chain) 95850397Sobrien tree decl; 95950397Sobrien tree chain; 96050397Sobrien{ 96150397Sobrien tree result = make_node (OVERLOAD); 96250397Sobrien TREE_TYPE (result) = unknown_type_node; 96350397Sobrien OVL_FUNCTION (result) = decl; 96450397Sobrien TREE_CHAIN (result) = chain; 96518334Speter 96650397Sobrien return result; 96718334Speter} 96818334Speter 96950397Sobrien/* Build a new overloaded function. If this is the first one, 97050397Sobrien just return it; otherwise, ovl_cons the _DECLs */ 97150397Sobrien 97250397Sobrientree 97350397Sobrienbuild_overload (decl, chain) 97450397Sobrien tree decl; 97550397Sobrien tree chain; 97618334Speter{ 97752284Sobrien if (! chain && TREE_CODE (decl) != TEMPLATE_DECL) 97850397Sobrien return decl; 97952284Sobrien if (chain && TREE_CODE (chain) != OVERLOAD) 98050397Sobrien chain = ovl_cons (chain, NULL_TREE); 98150397Sobrien return ovl_cons (decl, chain); 98218334Speter} 98318334Speter 98490075Sobrienint 98590075Sobrienis_aggr_type_2 (t1, t2) 98690075Sobrien tree t1, t2; 98718334Speter{ 98890075Sobrien if (TREE_CODE (t1) != TREE_CODE (t2)) 98990075Sobrien return 0; 99090075Sobrien return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2); 99118334Speter} 99218334Speter 99390075Sobrien/* Returns non-zero if CODE is the code for a statement. */ 99450397Sobrien 99518334Speterint 99690075Sobriencp_statement_code_p (code) 99790075Sobrien enum tree_code code; 99818334Speter{ 99990075Sobrien switch (code) 100090075Sobrien { 100190075Sobrien case SUBOBJECT: 100290075Sobrien case CLEANUP_STMT: 100390075Sobrien case CTOR_STMT: 100490075Sobrien case CTOR_INITIALIZER: 100590075Sobrien case RETURN_INIT: 100690075Sobrien case TRY_BLOCK: 100790075Sobrien case HANDLER: 100890075Sobrien case EH_SPEC_BLOCK: 100990075Sobrien case USING_STMT: 101090075Sobrien case TAG_DEFN: 101150397Sobrien return 1; 101218334Speter 101390075Sobrien default: 101490075Sobrien return 0; 101590075Sobrien } 101618334Speter} 101718334Speter 101818334Speter#define PRINT_RING_SIZE 4 101918334Speter 102090075Sobrienconst char * 102150397Sobrienlang_printable_name (decl, v) 102218334Speter tree decl; 102350397Sobrien int v; 102418334Speter{ 102518334Speter static tree decl_ring[PRINT_RING_SIZE]; 102618334Speter static char *print_ring[PRINT_RING_SIZE]; 102718334Speter static int ring_counter; 102818334Speter int i; 102918334Speter 103018334Speter /* Only cache functions. */ 103150397Sobrien if (v < 2 103250397Sobrien || TREE_CODE (decl) != FUNCTION_DECL 103318334Speter || DECL_LANG_SPECIFIC (decl) == 0) 103450397Sobrien return lang_decl_name (decl, v); 103518334Speter 103618334Speter /* See if this print name is lying around. */ 103718334Speter for (i = 0; i < PRINT_RING_SIZE; i++) 103818334Speter if (decl_ring[i] == decl) 103918334Speter /* yes, so return it. */ 104018334Speter return print_ring[i]; 104118334Speter 104218334Speter if (++ring_counter == PRINT_RING_SIZE) 104318334Speter ring_counter = 0; 104418334Speter 104518334Speter if (current_function_decl != NULL_TREE) 104618334Speter { 104718334Speter if (decl_ring[ring_counter] == current_function_decl) 104818334Speter ring_counter += 1; 104918334Speter if (ring_counter == PRINT_RING_SIZE) 105018334Speter ring_counter = 0; 105118334Speter if (decl_ring[ring_counter] == current_function_decl) 105290075Sobrien abort (); 105318334Speter } 105418334Speter 105518334Speter if (print_ring[ring_counter]) 105618334Speter free (print_ring[ring_counter]); 105718334Speter 105850397Sobrien print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v)); 105950397Sobrien decl_ring[ring_counter] = decl; 106018334Speter return print_ring[ring_counter]; 106118334Speter} 106218334Speter 106318334Speter/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions 106418334Speter listed in RAISES. */ 106550397Sobrien 106618334Spetertree 106718334Speterbuild_exception_variant (type, raises) 106818334Speter tree type; 106918334Speter tree raises; 107018334Speter{ 107118334Speter tree v = TYPE_MAIN_VARIANT (type); 107252284Sobrien int type_quals = TYPE_QUALS (type); 107318334Speter 107450397Sobrien for (; v; v = TYPE_NEXT_VARIANT (v)) 107590075Sobrien if (TYPE_QUALS (v) == type_quals 107690075Sobrien && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)) 107790075Sobrien return v; 107852284Sobrien 107918334Speter /* Need to build a new variant. */ 108050397Sobrien v = build_type_copy (type); 108118334Speter TYPE_RAISES_EXCEPTIONS (v) = raises; 108218334Speter return v; 108318334Speter} 108418334Speter 108590075Sobrien/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new 108690075Sobrien BOUND_TEMPLATE_TEMPLATE_PARM bound with NEWARGS as its template 108790075Sobrien arguments. */ 108850397Sobrien 108950397Sobrientree 109090075Sobrienbind_template_template_parm (t, newargs) 109150397Sobrien tree t; 109290075Sobrien tree newargs; 109350397Sobrien{ 109490075Sobrien tree decl = TYPE_NAME (t); 109552284Sobrien tree t2; 109652284Sobrien 109790075Sobrien t2 = make_aggr_type (BOUND_TEMPLATE_TEMPLATE_PARM); 109890075Sobrien decl = build_decl (TYPE_DECL, DECL_NAME (decl), NULL_TREE); 109952284Sobrien 110090075Sobrien /* These nodes have to be created to reflect new TYPE_DECL and template 110190075Sobrien arguments. */ 110290075Sobrien TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t)); 110390075Sobrien TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl; 110490075Sobrien TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2) 110590075Sobrien = tree_cons (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), 110690075Sobrien newargs, NULL_TREE); 110752284Sobrien 110890075Sobrien TREE_TYPE (decl) = t2; 110990075Sobrien TYPE_NAME (t2) = decl; 111090075Sobrien TYPE_STUB_DECL (t2) = decl; 111190075Sobrien TYPE_SIZE (t2) = 0; 111250397Sobrien 111350397Sobrien return t2; 111450397Sobrien} 111550397Sobrien 111690075Sobrien/* Called from count_trees via walk_tree. */ 111718334Speter 111890075Sobrienstatic tree 111990075Sobriencount_trees_r (tp, walk_subtrees, data) 112090075Sobrien tree *tp ATTRIBUTE_UNUSED; 112190075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 112290075Sobrien void *data; 112318334Speter{ 112490075Sobrien ++ *((int*) data); 112590075Sobrien return NULL_TREE; 112690075Sobrien} 112752284Sobrien 112890075Sobrien/* Debugging function for measuring the rough complexity of a tree 112990075Sobrien representation. */ 113018334Speter 113190075Sobrienint 113290075Sobriencount_trees (t) 113390075Sobrien tree t; 113490075Sobrien{ 113590075Sobrien int n_trees = 0; 113690075Sobrien walk_tree_without_duplicates (&t, count_trees_r, &n_trees); 113790075Sobrien return n_trees; 113890075Sobrien} 113918334Speter 114090075Sobrien/* Called from verify_stmt_tree via walk_tree. */ 114118334Speter 114290075Sobrienstatic tree 114390075Sobrienverify_stmt_tree_r (tp, walk_subtrees, data) 114490075Sobrien tree *tp; 114590075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 114690075Sobrien void *data; 114790075Sobrien{ 114890075Sobrien tree t = *tp; 114990075Sobrien htab_t *statements = (htab_t *) data; 115090075Sobrien void **slot; 115152284Sobrien 115290075Sobrien if (!statement_code_p (TREE_CODE (t))) 115390075Sobrien return NULL_TREE; 115452284Sobrien 115590075Sobrien /* If this statement is already present in the hash table, then 115690075Sobrien there is a circularity in the statement tree. */ 115790075Sobrien if (htab_find (*statements, t)) 115890075Sobrien abort (); 115990075Sobrien 116090075Sobrien slot = htab_find_slot (*statements, t, INSERT); 116190075Sobrien *slot = t; 116252284Sobrien 116352284Sobrien return NULL_TREE; 116452284Sobrien} 116552284Sobrien 116690075Sobrien/* Debugging function to check that the statement T has not been 116790075Sobrien corrupted. For now, this function simply checks that T contains no 116890075Sobrien circularities. */ 116952284Sobrien 117090075Sobrienvoid 117190075Sobrienverify_stmt_tree (t) 117252284Sobrien tree t; 117352284Sobrien{ 117490075Sobrien htab_t statements; 117590075Sobrien statements = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL); 117690075Sobrien walk_tree (&t, verify_stmt_tree_r, &statements, NULL); 117790075Sobrien htab_delete (statements); 117852284Sobrien} 117952284Sobrien 118090075Sobrien/* Called from find_tree via walk_tree. */ 118152284Sobrien 118290075Sobrienstatic tree 118390075Sobrienfind_tree_r (tp, walk_subtrees, data) 118490075Sobrien tree *tp; 118590075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 118690075Sobrien void *data; 118752284Sobrien{ 118890075Sobrien if (*tp == (tree) data) 118990075Sobrien return (tree) data; 119090075Sobrien 119152284Sobrien return NULL_TREE; 119252284Sobrien} 119352284Sobrien 119490075Sobrien/* Returns X if X appears in the tree structure rooted at T. */ 119552284Sobrien 119652284Sobrientree 119790075Sobrienfind_tree (t, x) 119852284Sobrien tree t; 119990075Sobrien tree x; 120052284Sobrien{ 120190075Sobrien return walk_tree_without_duplicates (&t, find_tree_r, x); 120218334Speter} 120318334Speter 120490075Sobrien/* Passed to walk_tree. Checks for the use of types with no linkage. */ 120552284Sobrien 120690075Sobrienstatic tree 120790075Sobrienno_linkage_helper (tp, walk_subtrees, data) 120890075Sobrien tree *tp; 120990075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 121090075Sobrien void *data ATTRIBUTE_UNUSED; 121152284Sobrien{ 121290075Sobrien tree t = *tp; 121352284Sobrien 121490075Sobrien if (TYPE_P (t) 121590075Sobrien && (CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE) 121690075Sobrien && (decl_function_context (TYPE_MAIN_DECL (t)) 121790075Sobrien || TYPE_ANONYMOUS_P (t))) 121818334Speter return t; 121918334Speter return NULL_TREE; 122018334Speter} 122118334Speter 122290075Sobrien/* Check if the type T depends on a type with no linkage and if so, return 122390075Sobrien it. */ 122450397Sobrien 122518334Spetertree 122690075Sobrienno_linkage_check (t) 122718334Speter tree t; 122818334Speter{ 122990075Sobrien /* There's no point in checking linkage on template functions; we 123090075Sobrien can't know their complete types. */ 123190075Sobrien if (processing_template_decl) 123290075Sobrien return NULL_TREE; 123390075Sobrien 123490075Sobrien t = walk_tree_without_duplicates (&t, no_linkage_helper, NULL); 123590075Sobrien if (t != error_mark_node) 123618334Speter return t; 123790075Sobrien return NULL_TREE; 123818334Speter} 123918334Speter 124050397Sobrien#ifdef GATHER_STATISTICS 124150397Sobrienextern int depth_reached; 124250397Sobrien#endif 124350397Sobrien 124418334Spetervoid 124590075Sobriencxx_print_statistics () 124618334Speter{ 124718334Speter print_search_statistics (); 124818334Speter print_class_statistics (); 124950397Sobrien#ifdef GATHER_STATISTICS 125050397Sobrien fprintf (stderr, "maximum template instantiation depth reached: %d\n", 125150397Sobrien depth_reached); 125250397Sobrien#endif 125318334Speter} 125418334Speter 125550397Sobrien/* Return, as an INTEGER_CST node, the number of elements for TYPE 125650397Sobrien (which is an ARRAY_TYPE). This counts only elements of the top 125750397Sobrien array. */ 125818334Speter 125918334Spetertree 126018334Speterarray_type_nelts_top (type) 126118334Speter tree type; 126218334Speter{ 126318334Speter return fold (build (PLUS_EXPR, sizetype, 126418334Speter array_type_nelts (type), 126518334Speter integer_one_node)); 126618334Speter} 126718334Speter 126850397Sobrien/* Return, as an INTEGER_CST node, the number of elements for TYPE 126950397Sobrien (which is an ARRAY_TYPE). This one is a recursive count of all 127050397Sobrien ARRAY_TYPEs that are clumped together. */ 127118334Speter 127218334Spetertree 127318334Speterarray_type_nelts_total (type) 127418334Speter tree type; 127518334Speter{ 127618334Speter tree sz = array_type_nelts_top (type); 127718334Speter type = TREE_TYPE (type); 127818334Speter while (TREE_CODE (type) == ARRAY_TYPE) 127918334Speter { 128018334Speter tree n = array_type_nelts_top (type); 128118334Speter sz = fold (build (MULT_EXPR, sizetype, sz, n)); 128218334Speter type = TREE_TYPE (type); 128318334Speter } 128418334Speter return sz; 128518334Speter} 128618334Speter 128790075Sobrien/* Called from break_out_target_exprs via mapcar. */ 128890075Sobrien 128990075Sobrienstatic tree 129090075Sobrienbot_manip (tp, walk_subtrees, data) 129190075Sobrien tree *tp; 129290075Sobrien int *walk_subtrees; 129390075Sobrien void *data; 129418334Speter{ 129590075Sobrien splay_tree target_remap = ((splay_tree) data); 129690075Sobrien tree t = *tp; 129790075Sobrien 129890075Sobrien if (TREE_CONSTANT (t)) 129950397Sobrien { 130090075Sobrien /* There can't be any TARGET_EXPRs or their slot variables below 130190075Sobrien this point. We used to check !TREE_SIDE_EFFECTS, but then we 130290075Sobrien failed to copy an ADDR_EXPR of the slot VAR_DECL. */ 130390075Sobrien *walk_subtrees = 0; 130490075Sobrien return NULL_TREE; 130590075Sobrien } 130690075Sobrien if (TREE_CODE (t) == TARGET_EXPR) 130790075Sobrien { 130890075Sobrien tree u; 130990075Sobrien 131050397Sobrien if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR) 131150397Sobrien { 131250397Sobrien mark_used (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 1), 0), 0)); 131390075Sobrien u = build_cplus_new 131450397Sobrien (TREE_TYPE (t), break_out_target_exprs (TREE_OPERAND (t, 1))); 131550397Sobrien } 131690075Sobrien else 131790075Sobrien { 131890075Sobrien u = build_target_expr_with_type 131990075Sobrien (break_out_target_exprs (TREE_OPERAND (t, 1)), TREE_TYPE (t)); 132090075Sobrien } 132190075Sobrien 132290075Sobrien /* Map the old variable to the new one. */ 132390075Sobrien splay_tree_insert (target_remap, 132490075Sobrien (splay_tree_key) TREE_OPERAND (t, 0), 132590075Sobrien (splay_tree_value) TREE_OPERAND (u, 0)); 132690075Sobrien 132790075Sobrien /* Replace the old expression with the new version. */ 132890075Sobrien *tp = u; 132990075Sobrien /* We don't have to go below this point; the recursive call to 133090075Sobrien break_out_target_exprs will have handled anything below this 133190075Sobrien point. */ 133290075Sobrien *walk_subtrees = 0; 133390075Sobrien return NULL_TREE; 133450397Sobrien } 133550397Sobrien else if (TREE_CODE (t) == CALL_EXPR) 133650397Sobrien mark_used (TREE_OPERAND (TREE_OPERAND (t, 0), 0)); 133750397Sobrien 133890075Sobrien /* Make a copy of this node. */ 133990075Sobrien return copy_tree_r (tp, walk_subtrees, NULL); 134018334Speter} 134118334Speter 134290075Sobrien/* Replace all remapped VAR_DECLs in T with their new equivalents. 134390075Sobrien DATA is really a splay-tree mapping old variables to new 134490075Sobrien variables. */ 134550397Sobrien 134690075Sobrienstatic tree 134790075Sobrienbot_replace (t, walk_subtrees, data) 134890075Sobrien tree *t; 134990075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 135090075Sobrien void *data; 135190075Sobrien{ 135290075Sobrien splay_tree target_remap = ((splay_tree) data); 135390075Sobrien 135490075Sobrien if (TREE_CODE (*t) == VAR_DECL) 135590075Sobrien { 135690075Sobrien splay_tree_node n = splay_tree_lookup (target_remap, 135790075Sobrien (splay_tree_key) *t); 135890075Sobrien if (n) 135990075Sobrien *t = (tree) n->value; 136090075Sobrien } 136190075Sobrien 136290075Sobrien return NULL_TREE; 136390075Sobrien} 136490075Sobrien 136590075Sobrien/* When we parse a default argument expression, we may create 136690075Sobrien temporary variables via TARGET_EXPRs. When we actually use the 136790075Sobrien default-argument expression, we make a copy of the expression, but 136890075Sobrien we must replace the temporaries with appropriate local versions. */ 136990075Sobrien 137018334Spetertree 137118334Speterbreak_out_target_exprs (t) 137218334Speter tree t; 137318334Speter{ 137490075Sobrien static int target_remap_count; 137590075Sobrien static splay_tree target_remap; 137690075Sobrien 137790075Sobrien if (!target_remap_count++) 137890075Sobrien target_remap = splay_tree_new (splay_tree_compare_pointers, 137990075Sobrien /*splay_tree_delete_key_fn=*/NULL, 138090075Sobrien /*splay_tree_delete_value_fn=*/NULL); 138190075Sobrien walk_tree (&t, bot_manip, target_remap, NULL); 138290075Sobrien walk_tree (&t, bot_replace, target_remap, NULL); 138390075Sobrien 138490075Sobrien if (!--target_remap_count) 138590075Sobrien { 138690075Sobrien splay_tree_delete (target_remap); 138790075Sobrien target_remap = NULL; 138890075Sobrien } 138990075Sobrien 139090075Sobrien return t; 139118334Speter} 139218334Speter 139350397Sobrien/* Obstack used for allocating nodes in template function and variable 139450397Sobrien definitions. */ 139550397Sobrien 139690075Sobrien/* Similar to `build_nt', except that we set TREE_COMPLEXITY to be the 139790075Sobrien current line number. */ 139850397Sobrien 139918334Spetertree 140090075Sobrienbuild_min_nt VPARAMS ((enum tree_code code, ...)) 140118334Speter{ 140250397Sobrien register tree t; 140350397Sobrien register int length; 140450397Sobrien register int i; 140518334Speter 140690075Sobrien VA_OPEN (p, code); 140790075Sobrien VA_FIXEDARG (p, enum tree_code, code); 140850397Sobrien 140950397Sobrien t = make_node (code); 141090075Sobrien length = TREE_CODE_LENGTH (code); 141150397Sobrien TREE_COMPLEXITY (t) = lineno; 141250397Sobrien 141350397Sobrien for (i = 0; i < length; i++) 141450397Sobrien { 141550397Sobrien tree x = va_arg (p, tree); 141690075Sobrien TREE_OPERAND (t, i) = x; 141750397Sobrien } 141850397Sobrien 141990075Sobrien VA_CLOSE (p); 142018334Speter return t; 142118334Speter} 142218334Speter 142390075Sobrien/* Similar to `build', except we set TREE_COMPLEXITY to the current 142490075Sobrien line-number. */ 142550397Sobrien 142618334Spetertree 142790075Sobrienbuild_min VPARAMS ((enum tree_code code, tree tt, ...)) 142818334Speter{ 142950397Sobrien register tree t; 143050397Sobrien register int length; 143118334Speter register int i; 143218334Speter 143390075Sobrien VA_OPEN (p, tt); 143490075Sobrien VA_FIXEDARG (p, enum tree_code, code); 143590075Sobrien VA_FIXEDARG (p, tree, tt); 143618334Speter 143750397Sobrien t = make_node (code); 143890075Sobrien length = TREE_CODE_LENGTH (code); 143990075Sobrien TREE_TYPE (t) = tt; 144050397Sobrien TREE_COMPLEXITY (t) = lineno; 144150397Sobrien 144250397Sobrien for (i = 0; i < length; i++) 144318334Speter { 144450397Sobrien tree x = va_arg (p, tree); 144590075Sobrien TREE_OPERAND (t, i) = x; 144650397Sobrien } 144750397Sobrien 144890075Sobrien VA_CLOSE (p); 144950397Sobrien return t; 145050397Sobrien} 145150397Sobrien 145290075Sobrien/* Returns an INTEGER_CST (of type `int') corresponding to I. 145390075Sobrien Multiple calls with the same value of I may or may not yield the 145490075Sobrien same node; therefore, callers should never modify the node 145590075Sobrien returned. */ 145650397Sobrien 145750397Sobrientree 145890075Sobrienbuild_shared_int_cst (i) 145990075Sobrien int i; 146050397Sobrien{ 146190075Sobrien static tree cache[256]; 146250397Sobrien 146390075Sobrien if (i >= 256) 146490075Sobrien return build_int_2 (i, 0); 146590075Sobrien 146690075Sobrien if (!cache[i]) 146790075Sobrien cache[i] = build_int_2 (i, 0); 146890075Sobrien 146990075Sobrien return cache[i]; 147050397Sobrien} 147150397Sobrien 147250397Sobrientree 147350397Sobrienget_type_decl (t) 147450397Sobrien tree t; 147550397Sobrien{ 147650397Sobrien if (TREE_CODE (t) == TYPE_DECL) 147750397Sobrien return t; 147890075Sobrien if (TYPE_P (t)) 147950397Sobrien return TYPE_STUB_DECL (t); 148090075Sobrien if (t == error_mark_node) 148190075Sobrien return t; 148250397Sobrien 148390075Sobrien abort (); 148450397Sobrien 148550397Sobrien /* Stop compiler from complaining control reaches end of non-void function. */ 148650397Sobrien return 0; 148750397Sobrien} 148850397Sobrien 148950397Sobrien/* Return first vector element whose BINFO_TYPE is ELEM. 149050397Sobrien Return 0 if ELEM is not in VEC. VEC may be NULL_TREE. */ 149150397Sobrien 149250397Sobrientree 149350397Sobrienvec_binfo_member (elem, vec) 149450397Sobrien tree elem, vec; 149550397Sobrien{ 149650397Sobrien int i; 149750397Sobrien 149850397Sobrien if (vec) 149950397Sobrien for (i = 0; i < TREE_VEC_LENGTH (vec); ++i) 150052284Sobrien if (same_type_p (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i)))) 150150397Sobrien return TREE_VEC_ELT (vec, i); 150250397Sobrien 150350397Sobrien return NULL_TREE; 150450397Sobrien} 150550397Sobrien 150652284Sobrien/* Returns the namespace that contains DECL, whether directly or 150752284Sobrien indirectly. */ 150852284Sobrien 150952284Sobrientree 151052284Sobriendecl_namespace_context (decl) 151152284Sobrien tree decl; 151252284Sobrien{ 151352284Sobrien while (1) 151452284Sobrien { 151552284Sobrien if (TREE_CODE (decl) == NAMESPACE_DECL) 151652284Sobrien return decl; 151752284Sobrien else if (TYPE_P (decl)) 151852284Sobrien decl = CP_DECL_CONTEXT (TYPE_MAIN_DECL (decl)); 151952284Sobrien else 152052284Sobrien decl = CP_DECL_CONTEXT (decl); 152152284Sobrien } 152252284Sobrien} 152352284Sobrien 152450397Sobrien/* Return truthvalue of whether T1 is the same tree structure as T2. 152550397Sobrien Return 1 if they are the same. 152650397Sobrien Return 0 if they are understandably different. 152750397Sobrien Return -1 if either contains tree structure not understood by 152850397Sobrien this function. */ 152950397Sobrien 153050397Sobrienint 153150397Sobriencp_tree_equal (t1, t2) 153250397Sobrien tree t1, t2; 153350397Sobrien{ 153450397Sobrien register enum tree_code code1, code2; 153550397Sobrien int cmp; 153650397Sobrien 153750397Sobrien if (t1 == t2) 153850397Sobrien return 1; 153950397Sobrien if (t1 == 0 || t2 == 0) 154050397Sobrien return 0; 154150397Sobrien 154250397Sobrien code1 = TREE_CODE (t1); 154350397Sobrien code2 = TREE_CODE (t2); 154450397Sobrien 154550397Sobrien if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR) 154650397Sobrien { 154750397Sobrien if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR) 154850397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 154950397Sobrien else 155050397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 0), t2); 155150397Sobrien } 155250397Sobrien else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR 155350397Sobrien || code2 == NON_LVALUE_EXPR) 155450397Sobrien return cp_tree_equal (t1, TREE_OPERAND (t2, 0)); 155550397Sobrien 155650397Sobrien if (code1 != code2) 155750397Sobrien return 0; 155850397Sobrien 155950397Sobrien switch (code1) 156050397Sobrien { 156150397Sobrien case INTEGER_CST: 156250397Sobrien return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2) 156350397Sobrien && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2); 156450397Sobrien 156550397Sobrien case REAL_CST: 156650397Sobrien return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); 156750397Sobrien 156850397Sobrien case STRING_CST: 156950397Sobrien return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2) 157090075Sobrien && !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2), 157150397Sobrien TREE_STRING_LENGTH (t1)); 157250397Sobrien 157350397Sobrien case CONSTRUCTOR: 157450397Sobrien /* We need to do this when determining whether or not two 157550397Sobrien non-type pointer to member function template arguments 157650397Sobrien are the same. */ 157752284Sobrien if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) 157850397Sobrien /* The first operand is RTL. */ 157950397Sobrien && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0))) 158050397Sobrien return 0; 158150397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); 158250397Sobrien 158350397Sobrien case TREE_LIST: 158450397Sobrien cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)); 158550397Sobrien if (cmp <= 0) 158650397Sobrien return cmp; 158750397Sobrien cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)); 158850397Sobrien if (cmp <= 0) 158950397Sobrien return cmp; 159050397Sobrien return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2)); 159150397Sobrien 159218334Speter case SAVE_EXPR: 159350397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 159418334Speter 159550397Sobrien case CALL_EXPR: 159650397Sobrien cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 159750397Sobrien if (cmp <= 0) 159850397Sobrien return cmp; 159950397Sobrien return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); 160050397Sobrien 160118334Speter case TARGET_EXPR: 160250397Sobrien /* Special case: if either target is an unallocated VAR_DECL, 160350397Sobrien it means that it's going to be unified with whatever the 160450397Sobrien TARGET_EXPR is really supposed to initialize, so treat it 160550397Sobrien as being equivalent to anything. */ 160650397Sobrien if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL 160750397Sobrien && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE 160890075Sobrien && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0))) 160950397Sobrien || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL 161050397Sobrien && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE 161190075Sobrien && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0)))) 161250397Sobrien cmp = 1; 161350397Sobrien else 161450397Sobrien cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 161550397Sobrien if (cmp <= 0) 161650397Sobrien return cmp; 161750397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); 161850397Sobrien 161950397Sobrien case WITH_CLEANUP_EXPR: 162050397Sobrien cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 162150397Sobrien if (cmp <= 0) 162250397Sobrien return cmp; 162390075Sobrien return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1)); 162450397Sobrien 162550397Sobrien case COMPONENT_REF: 162650397Sobrien if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1)) 162750397Sobrien return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 162850397Sobrien return 0; 162950397Sobrien 163050397Sobrien case VAR_DECL: 163150397Sobrien case PARM_DECL: 163250397Sobrien case CONST_DECL: 163350397Sobrien case FUNCTION_DECL: 163450397Sobrien return 0; 163550397Sobrien 163650397Sobrien case TEMPLATE_PARM_INDEX: 163750397Sobrien return TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) 163850397Sobrien && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2); 163950397Sobrien 164050397Sobrien case SIZEOF_EXPR: 164150397Sobrien case ALIGNOF_EXPR: 164250397Sobrien if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0))) 164350397Sobrien return 0; 164490075Sobrien if (TYPE_P (TREE_OPERAND (t1, 0))) 164552284Sobrien return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 164618334Speter break; 164750397Sobrien 164852284Sobrien case PTRMEM_CST: 164952284Sobrien /* Two pointer-to-members are the same if they point to the same 165052284Sobrien field or function in the same class. */ 165152284Sobrien return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2) 165252284Sobrien && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2))); 165352284Sobrien 165450397Sobrien default: 165518334Speter break; 165650397Sobrien } 165718334Speter 165850397Sobrien switch (TREE_CODE_CLASS (code1)) 165950397Sobrien { 166050397Sobrien case '1': 166150397Sobrien case '2': 166250397Sobrien case '<': 166350397Sobrien case 'e': 166450397Sobrien case 'r': 166550397Sobrien case 's': 166690075Sobrien { 166790075Sobrien int i; 166890075Sobrien 166990075Sobrien cmp = 1; 167090075Sobrien for (i = 0; i < TREE_CODE_LENGTH (code1); ++i) 167190075Sobrien { 167290075Sobrien cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)); 167390075Sobrien if (cmp <= 0) 167490075Sobrien return cmp; 167590075Sobrien } 167690075Sobrien return cmp; 167790075Sobrien } 167890075Sobrien 167990075Sobrien case 't': 168090075Sobrien return same_type_p (t1, t2) ? 1 : 0; 168118334Speter } 168218334Speter 168350397Sobrien return -1; 168450397Sobrien} 168518334Speter 168650397Sobrien/* Build a wrapper around some pointer PTR so we can use it as a tree. */ 168750397Sobrien 168850397Sobrientree 168950397Sobrienbuild_ptr_wrapper (ptr) 169050397Sobrien void *ptr; 169150397Sobrien{ 169250397Sobrien tree t = make_node (WRAPPER); 169350397Sobrien WRAPPER_PTR (t) = ptr; 169450397Sobrien return t; 169550397Sobrien} 169650397Sobrien 169750397Sobrien/* Build a wrapper around some integer I so we can use it as a tree. */ 169850397Sobrien 169950397Sobrientree 170050397Sobrienbuild_int_wrapper (i) 170150397Sobrien int i; 170250397Sobrien{ 170350397Sobrien tree t = make_node (WRAPPER); 170450397Sobrien WRAPPER_INT (t) = i; 170550397Sobrien return t; 170650397Sobrien} 170750397Sobrien 170852284Sobrienstatic tree 170950397Sobrienbuild_srcloc (file, line) 171090075Sobrien const char *file; 171150397Sobrien int line; 171250397Sobrien{ 171350397Sobrien tree t; 171450397Sobrien 171550397Sobrien t = make_node (SRCLOC); 171650397Sobrien SRCLOC_FILE (t) = file; 171750397Sobrien SRCLOC_LINE (t) = line; 171850397Sobrien 171950397Sobrien return t; 172050397Sobrien} 172150397Sobrien 172250397Sobrientree 172350397Sobrienbuild_srcloc_here () 172450397Sobrien{ 172550397Sobrien return build_srcloc (input_filename, lineno); 172650397Sobrien} 172750397Sobrien 172850397Sobrien/* The type of ARG when used as an lvalue. */ 172950397Sobrien 173050397Sobrientree 173150397Sobrienlvalue_type (arg) 173250397Sobrien tree arg; 173350397Sobrien{ 173450397Sobrien tree type = TREE_TYPE (arg); 173550397Sobrien if (TREE_CODE (arg) == OVERLOAD) 173650397Sobrien type = unknown_type_node; 173752284Sobrien return type; 173850397Sobrien} 173950397Sobrien 174050397Sobrien/* The type of ARG for printing error messages; denote lvalues with 174150397Sobrien reference types. */ 174250397Sobrien 174350397Sobrientree 174450397Sobrienerror_type (arg) 174550397Sobrien tree arg; 174650397Sobrien{ 174750397Sobrien tree type = TREE_TYPE (arg); 174850397Sobrien if (TREE_CODE (type) == ARRAY_TYPE) 174950397Sobrien ; 175050397Sobrien else if (real_lvalue_p (arg)) 175150397Sobrien type = build_reference_type (lvalue_type (arg)); 175250397Sobrien else if (IS_AGGR_TYPE (type)) 175350397Sobrien type = lvalue_type (arg); 175450397Sobrien 175550397Sobrien return type; 175650397Sobrien} 175750397Sobrien 175850397Sobrien/* Does FUNCTION use a variable-length argument list? */ 175950397Sobrien 176018334Speterint 176150397Sobrienvarargs_function_p (function) 176250397Sobrien tree function; 176318334Speter{ 176450397Sobrien tree parm = TYPE_ARG_TYPES (TREE_TYPE (function)); 176550397Sobrien for (; parm; parm = TREE_CHAIN (parm)) 176650397Sobrien if (TREE_VALUE (parm) == void_type_node) 176750397Sobrien return 0; 176850397Sobrien return 1; 176918334Speter} 177050397Sobrien 177150397Sobrien/* Returns 1 if decl is a member of a class. */ 177250397Sobrien 177350397Sobrienint 177450397Sobrienmember_p (decl) 177550397Sobrien tree decl; 177650397Sobrien{ 177790075Sobrien const tree ctx = DECL_CONTEXT (decl); 177890075Sobrien return (ctx && TYPE_P (ctx)); 177950397Sobrien} 178052284Sobrien 178152284Sobrien/* Create a placeholder for member access where we don't actually have an 178252284Sobrien object that the access is against. */ 178352284Sobrien 178452284Sobrientree 178552284Sobrienbuild_dummy_object (type) 178652284Sobrien tree type; 178752284Sobrien{ 178852284Sobrien tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node); 178990075Sobrien return build_indirect_ref (decl, NULL); 179052284Sobrien} 179152284Sobrien 179252284Sobrien/* We've gotten a reference to a member of TYPE. Return *this if appropriate, 179352284Sobrien or a dummy object otherwise. If BINFOP is non-0, it is filled with the 179452284Sobrien binfo path from current_class_type to TYPE, or 0. */ 179552284Sobrien 179652284Sobrientree 179752284Sobrienmaybe_dummy_object (type, binfop) 179852284Sobrien tree type; 179952284Sobrien tree *binfop; 180052284Sobrien{ 180152284Sobrien tree decl, context; 180290075Sobrien tree binfo; 180390075Sobrien 180452284Sobrien if (current_class_type 180590075Sobrien && (binfo = lookup_base (current_class_type, type, 180690075Sobrien ba_ignore | ba_quiet, NULL))) 180752284Sobrien context = current_class_type; 180852284Sobrien else 180952284Sobrien { 181052284Sobrien /* Reference from a nested class member function. */ 181152284Sobrien context = type; 181290075Sobrien binfo = TYPE_BINFO (type); 181352284Sobrien } 181452284Sobrien 181590075Sobrien if (binfop) 181690075Sobrien *binfop = binfo; 181790075Sobrien 181852284Sobrien if (current_class_ref && context == current_class_type) 181952284Sobrien decl = current_class_ref; 182052284Sobrien else 182152284Sobrien decl = build_dummy_object (context); 182252284Sobrien 182352284Sobrien return decl; 182452284Sobrien} 182552284Sobrien 182652284Sobrien/* Returns 1 if OB is a placeholder object, or a pointer to one. */ 182752284Sobrien 182852284Sobrienint 182952284Sobrienis_dummy_object (ob) 183052284Sobrien tree ob; 183152284Sobrien{ 183252284Sobrien if (TREE_CODE (ob) == INDIRECT_REF) 183352284Sobrien ob = TREE_OPERAND (ob, 0); 183452284Sobrien return (TREE_CODE (ob) == NOP_EXPR 183552284Sobrien && TREE_OPERAND (ob, 0) == void_zero_node); 183652284Sobrien} 183752284Sobrien 183852284Sobrien/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ 183952284Sobrien 184052284Sobrienint 184152284Sobrienpod_type_p (t) 184252284Sobrien tree t; 184352284Sobrien{ 184490075Sobrien t = strip_array_types (t); 184552284Sobrien 184690075Sobrien if (INTEGRAL_TYPE_P (t)) 184790075Sobrien return 1; /* integral, character or enumeral type */ 184890075Sobrien if (FLOAT_TYPE_P (t)) 184952284Sobrien return 1; 185090075Sobrien if (TYPE_PTR_P (t)) 185190075Sobrien return 1; /* pointer to non-member */ 185290075Sobrien if (TYPE_PTRMEM_P (t)) 185390075Sobrien return 1; /* pointer to member object */ 185490075Sobrien if (TYPE_PTRMEMFUNC_P (t)) 185590075Sobrien return 1; /* pointer to member function */ 185690075Sobrien 185790075Sobrien if (! CLASS_TYPE_P (t)) 185890075Sobrien return 0; /* other non-class type (reference or function) */ 185990075Sobrien if (CLASSTYPE_NON_POD_P (t)) 186052284Sobrien return 0; 186190075Sobrien return 1; 186290075Sobrien} 186352284Sobrien 186490075Sobrien/* Table of valid C++ attributes. */ 186590075Sobrienconst struct attribute_spec cp_attribute_table[] = 186690075Sobrien{ 186790075Sobrien /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ 186890075Sobrien { "java_interface", 0, 0, false, false, false, handle_java_interface_attribute }, 186990075Sobrien { "com_interface", 0, 0, false, false, false, handle_com_interface_attribute }, 187090075Sobrien { "init_priority", 1, 1, true, false, false, handle_init_priority_attribute }, 187190075Sobrien { NULL, 0, 0, false, false, false, NULL } 187290075Sobrien}; 187390075Sobrien 187490075Sobrien/* Handle a "java_interface" attribute; arguments as in 187590075Sobrien struct attribute_spec.handler. */ 187690075Sobrienstatic tree 187790075Sobrienhandle_java_interface_attribute (node, name, args, flags, no_add_attrs) 187890075Sobrien tree *node; 187990075Sobrien tree name; 188090075Sobrien tree args ATTRIBUTE_UNUSED; 188190075Sobrien int flags; 188290075Sobrien bool *no_add_attrs; 188390075Sobrien{ 188490075Sobrien if (DECL_P (*node) 188590075Sobrien || !CLASS_TYPE_P (*node) 188690075Sobrien || !TYPE_FOR_JAVA (*node)) 188752284Sobrien { 188890075Sobrien error ("`%s' attribute can only be applied to Java class definitions", 188990075Sobrien IDENTIFIER_POINTER (name)); 189090075Sobrien *no_add_attrs = true; 189190075Sobrien return NULL_TREE; 189252284Sobrien } 189390075Sobrien if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 189490075Sobrien *node = build_type_copy (*node); 189590075Sobrien TYPE_JAVA_INTERFACE (*node) = 1; 189652284Sobrien 189790075Sobrien return NULL_TREE; 189852284Sobrien} 189952284Sobrien 190090075Sobrien/* Handle a "com_interface" attribute; arguments as in 190190075Sobrien struct attribute_spec.handler. */ 190290075Sobrienstatic tree 190390075Sobrienhandle_com_interface_attribute (node, name, args, flags, no_add_attrs) 190490075Sobrien tree *node; 190590075Sobrien tree name; 190690075Sobrien tree args ATTRIBUTE_UNUSED; 190790075Sobrien int flags ATTRIBUTE_UNUSED; 190890075Sobrien bool *no_add_attrs; 190952284Sobrien{ 191090075Sobrien static int warned; 191152284Sobrien 191290075Sobrien *no_add_attrs = true; 191352284Sobrien 191490075Sobrien if (DECL_P (*node) 191590075Sobrien || !CLASS_TYPE_P (*node) 191690075Sobrien || *node != TYPE_MAIN_VARIANT (*node)) 191790075Sobrien { 191890075Sobrien warning ("`%s' attribute can only be applied to class definitions", 191990075Sobrien IDENTIFIER_POINTER (name)); 192090075Sobrien return NULL_TREE; 192152284Sobrien } 192252284Sobrien 192390075Sobrien if (!warned++) 192490075Sobrien warning ("`%s' is obsolete; g++ vtables are now COM-compatible by default", 192590075Sobrien IDENTIFIER_POINTER (name)); 192690075Sobrien 192790075Sobrien return NULL_TREE; 192890075Sobrien} 192990075Sobrien 193090075Sobrien/* Handle an "init_priority" attribute; arguments as in 193190075Sobrien struct attribute_spec.handler. */ 193290075Sobrienstatic tree 193390075Sobrienhandle_init_priority_attribute (node, name, args, flags, no_add_attrs) 193490075Sobrien tree *node; 193590075Sobrien tree name; 193690075Sobrien tree args; 193790075Sobrien int flags ATTRIBUTE_UNUSED; 193890075Sobrien bool *no_add_attrs; 193990075Sobrien{ 194090075Sobrien tree initp_expr = TREE_VALUE (args); 194190075Sobrien tree decl = *node; 194290075Sobrien tree type = TREE_TYPE (decl); 194390075Sobrien int pri; 194490075Sobrien 194590075Sobrien STRIP_NOPS (initp_expr); 194652284Sobrien 194790075Sobrien if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST) 194890075Sobrien { 194990075Sobrien error ("requested init_priority is not an integer constant"); 195090075Sobrien *no_add_attrs = true; 195190075Sobrien return NULL_TREE; 195290075Sobrien } 195352284Sobrien 195490075Sobrien pri = TREE_INT_CST_LOW (initp_expr); 195552284Sobrien 195690075Sobrien type = strip_array_types (type); 195752284Sobrien 195890075Sobrien if (decl == NULL_TREE 195990075Sobrien || TREE_CODE (decl) != VAR_DECL 196090075Sobrien || !TREE_STATIC (decl) 196190075Sobrien || DECL_EXTERNAL (decl) 196290075Sobrien || (TREE_CODE (type) != RECORD_TYPE 196390075Sobrien && TREE_CODE (type) != UNION_TYPE) 196490075Sobrien /* Static objects in functions are initialized the 196590075Sobrien first time control passes through that 196690075Sobrien function. This is not precise enough to pin down an 196790075Sobrien init_priority value, so don't allow it. */ 196890075Sobrien || current_function_decl) 196990075Sobrien { 197090075Sobrien error ("can only use `%s' attribute on file-scope definitions of objects of class type", 197190075Sobrien IDENTIFIER_POINTER (name)); 197290075Sobrien *no_add_attrs = true; 197390075Sobrien return NULL_TREE; 197490075Sobrien } 197552284Sobrien 197690075Sobrien if (pri > MAX_INIT_PRIORITY || pri <= 0) 197790075Sobrien { 197890075Sobrien error ("requested init_priority is out of range"); 197990075Sobrien *no_add_attrs = true; 198090075Sobrien return NULL_TREE; 198190075Sobrien } 198252284Sobrien 198390075Sobrien /* Check for init_priorities that are reserved for 198490075Sobrien language and runtime support implementations.*/ 198590075Sobrien if (pri <= MAX_RESERVED_INIT_PRIORITY) 198690075Sobrien { 198790075Sobrien warning 198890075Sobrien ("requested init_priority is reserved for internal use"); 198990075Sobrien } 199052284Sobrien 199190075Sobrien if (SUPPORTS_INIT_PRIORITY) 199290075Sobrien { 199352284Sobrien DECL_INIT_PRIORITY (decl) = pri; 199490075Sobrien return NULL_TREE; 199552284Sobrien } 199690075Sobrien else 199790075Sobrien { 199890075Sobrien error ("`%s' attribute is not supported on this platform", 199990075Sobrien IDENTIFIER_POINTER (name)); 200090075Sobrien *no_add_attrs = true; 200190075Sobrien return NULL_TREE; 200290075Sobrien } 200352284Sobrien} 200452284Sobrien 200552284Sobrien/* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the 200652284Sobrien thing pointed to by the constant. */ 200752284Sobrien 200852284Sobrientree 200952284Sobrienmake_ptrmem_cst (type, member) 201052284Sobrien tree type; 201152284Sobrien tree member; 201252284Sobrien{ 201352284Sobrien tree ptrmem_cst = make_node (PTRMEM_CST); 201452284Sobrien /* If would seem a great convenience if make_node would set 201552284Sobrien TREE_CONSTANT for things of class `c', but it does not. */ 201652284Sobrien TREE_CONSTANT (ptrmem_cst) = 1; 201752284Sobrien TREE_TYPE (ptrmem_cst) = type; 201852284Sobrien PTRMEM_CST_MEMBER (ptrmem_cst) = member; 201952284Sobrien return ptrmem_cst; 202052284Sobrien} 202152284Sobrien 202290075Sobrien/* Apply FUNC to all language-specific sub-trees of TP in a pre-order 202390075Sobrien traversal. Called from walk_tree(). */ 202490075Sobrien 202590075Sobrientree 202690075Sobriencp_walk_subtrees (tp, walk_subtrees_p, func, data, htab) 202790075Sobrien tree *tp; 202890075Sobrien int *walk_subtrees_p; 202990075Sobrien walk_tree_fn func; 203090075Sobrien void *data; 203190075Sobrien void *htab; 203290075Sobrien{ 203390075Sobrien enum tree_code code = TREE_CODE (*tp); 203490075Sobrien tree result; 203590075Sobrien 203690075Sobrien#define WALK_SUBTREE(NODE) \ 203790075Sobrien do \ 203890075Sobrien { \ 203990075Sobrien result = walk_tree (&(NODE), func, data, htab); \ 204090075Sobrien if (result) \ 204190075Sobrien return result; \ 204290075Sobrien } \ 204390075Sobrien while (0) 204490075Sobrien 204590075Sobrien /* Not one of the easy cases. We must explicitly go through the 204690075Sobrien children. */ 204790075Sobrien switch (code) 204890075Sobrien { 204990075Sobrien case DEFAULT_ARG: 205090075Sobrien case TEMPLATE_TEMPLATE_PARM: 205190075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 205290075Sobrien case UNBOUND_CLASS_TEMPLATE: 205390075Sobrien case TEMPLATE_PARM_INDEX: 205490075Sobrien case TEMPLATE_TYPE_PARM: 205590075Sobrien case TYPENAME_TYPE: 205690075Sobrien case TYPEOF_TYPE: 205790075Sobrien /* None of thse have subtrees other than those already walked 205890075Sobrien above. */ 205990075Sobrien *walk_subtrees_p = 0; 206090075Sobrien break; 206190075Sobrien 206290075Sobrien case PTRMEM_CST: 206390075Sobrien WALK_SUBTREE (TREE_TYPE (*tp)); 206490075Sobrien *walk_subtrees_p = 0; 206590075Sobrien break; 206690075Sobrien 206790075Sobrien case TREE_LIST: 206890075Sobrien /* A BASELINK_P's TREE_PURPOSE is a BINFO, and hence circular. */ 206990075Sobrien if (!BASELINK_P (*tp)) 207090075Sobrien WALK_SUBTREE (TREE_PURPOSE (*tp)); 207190075Sobrien break; 207290075Sobrien 207390075Sobrien case OVERLOAD: 207490075Sobrien WALK_SUBTREE (OVL_FUNCTION (*tp)); 207590075Sobrien WALK_SUBTREE (OVL_CHAIN (*tp)); 207690075Sobrien *walk_subtrees_p = 0; 207790075Sobrien break; 207890075Sobrien 207990075Sobrien case RECORD_TYPE: 208090075Sobrien if (TYPE_PTRMEMFUNC_P (*tp)) 208190075Sobrien WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp)); 208290075Sobrien break; 208390075Sobrien 208490075Sobrien default: 208590075Sobrien break; 208690075Sobrien } 208790075Sobrien 208890075Sobrien /* We didn't find what we were looking for. */ 208990075Sobrien return NULL_TREE; 209090075Sobrien 209190075Sobrien#undef WALK_SUBTREE 209290075Sobrien} 209390075Sobrien 209490075Sobrien/* Decide whether there are language-specific reasons to not inline a 209590075Sobrien function as a tree. */ 209690075Sobrien 209790075Sobrienint 209890075Sobriencp_cannot_inline_tree_fn (fnp) 209990075Sobrien tree *fnp; 210090075Sobrien{ 210190075Sobrien tree fn = *fnp; 210290075Sobrien 210390075Sobrien /* We can inline a template instantiation only if it's fully 210490075Sobrien instantiated. */ 210590075Sobrien if (DECL_TEMPLATE_INFO (fn) 210690075Sobrien && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn))) 210790075Sobrien { 210890075Sobrien fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0); 210990075Sobrien return TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)); 211090075Sobrien } 211190075Sobrien 211290075Sobrien if (varargs_function_p (fn)) 211390075Sobrien { 211490075Sobrien DECL_UNINLINABLE (fn) = 1; 211590075Sobrien return 1; 211690075Sobrien } 211790075Sobrien 211890075Sobrien if (! function_attribute_inlinable_p (fn)) 211990075Sobrien { 212090075Sobrien DECL_UNINLINABLE (fn) = 1; 212190075Sobrien return 1; 212290075Sobrien } 212390075Sobrien 212490075Sobrien return 0; 212590075Sobrien} 212690075Sobrien 212790075Sobrien/* Add any pending functions other than the current function (already 212890075Sobrien handled by the caller), that thus cannot be inlined, to FNS_P, then 212990075Sobrien return the latest function added to the array, PREV_FN. */ 213090075Sobrien 213190075Sobrientree 213290075Sobriencp_add_pending_fn_decls (fns_p, prev_fn) 213390075Sobrien void *fns_p; 213490075Sobrien tree prev_fn; 213590075Sobrien{ 213690075Sobrien varray_type *fnsp = (varray_type *)fns_p; 213790075Sobrien struct saved_scope *s; 213890075Sobrien 213990075Sobrien for (s = scope_chain; s; s = s->prev) 214090075Sobrien if (s->function_decl && s->function_decl != prev_fn) 214190075Sobrien { 214290075Sobrien VARRAY_PUSH_TREE (*fnsp, s->function_decl); 214390075Sobrien prev_fn = s->function_decl; 214490075Sobrien } 214590075Sobrien 214690075Sobrien return prev_fn; 214790075Sobrien} 214890075Sobrien 214990075Sobrien/* Determine whether a tree node is an OVERLOAD node. Used to decide 215090075Sobrien whether to copy a node or to preserve its chain when inlining a 215190075Sobrien function. */ 215290075Sobrien 215390075Sobrienint 215490075Sobriencp_is_overload_p (t) 215590075Sobrien tree t; 215690075Sobrien{ 215790075Sobrien return TREE_CODE (t) == OVERLOAD; 215890075Sobrien} 215990075Sobrien 216090075Sobrien/* Determine whether VAR is a declaration of an automatic variable in 216190075Sobrien function FN. */ 216290075Sobrien 216390075Sobrienint 216490075Sobriencp_auto_var_in_fn_p (var, fn) 216590075Sobrien tree var, fn; 216690075Sobrien{ 216790075Sobrien return (DECL_P (var) && DECL_CONTEXT (var) == fn 216890075Sobrien && nonstatic_local_decl_p (var)); 216990075Sobrien} 217090075Sobrien 217190075Sobrien/* Tell whether a declaration is needed for the RESULT of a function 217290075Sobrien FN being inlined into CALLER or if the top node of target_exprs is 217390075Sobrien to be used. */ 217490075Sobrien 217590075Sobrientree 217690075Sobriencp_copy_res_decl_for_inlining (result, fn, caller, decl_map_, 217790075Sobrien need_decl, target_exprs) 217890075Sobrien tree result, fn, caller; 217990075Sobrien void *decl_map_; 218090075Sobrien int *need_decl; 218190075Sobrien void *target_exprs; 218290075Sobrien{ 218390075Sobrien splay_tree decl_map = (splay_tree)decl_map_; 218490075Sobrien varray_type *texps = (varray_type *)target_exprs; 218590075Sobrien tree var; 218690075Sobrien int aggregate_return_p; 218790075Sobrien 218890075Sobrien /* Figure out whether or not FN returns an aggregate. */ 218990075Sobrien aggregate_return_p = IS_AGGR_TYPE (TREE_TYPE (result)); 219090075Sobrien *need_decl = ! aggregate_return_p; 219190075Sobrien 219290075Sobrien /* If FN returns an aggregate then the caller will always create the 219390075Sobrien temporary (using a TARGET_EXPR) and the call will be the 219490075Sobrien initializing expression for the TARGET_EXPR. If we were just to 219590075Sobrien create a new VAR_DECL here, then the result of this function 219690075Sobrien would be copied (bitwise) into the variable initialized by the 219790075Sobrien TARGET_EXPR. That's incorrect, so we must transform any 219890075Sobrien references to the RESULT into references to the target. */ 219990075Sobrien if (aggregate_return_p) 220090075Sobrien { 220190075Sobrien if (VARRAY_ACTIVE_SIZE (*texps) == 0) 220290075Sobrien abort (); 220390075Sobrien var = TREE_OPERAND (VARRAY_TOP_TREE (*texps), 0); 220490075Sobrien if (! same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (var), 220590075Sobrien TREE_TYPE (result))) 220690075Sobrien abort (); 220790075Sobrien } 220890075Sobrien /* Otherwise, make an appropriate copy. */ 220990075Sobrien else 221090075Sobrien var = copy_decl_for_inlining (result, fn, caller); 221190075Sobrien 221290075Sobrien if (DECL_SAVED_FUNCTION_DATA (fn)) 221390075Sobrien { 221490075Sobrien tree nrv = DECL_SAVED_FUNCTION_DATA (fn)->x_return_value; 221590075Sobrien if (nrv) 221690075Sobrien { 221790075Sobrien /* We have a named return value; copy the name and source 221890075Sobrien position so we can get reasonable debugging information, and 221990075Sobrien register the return variable as its equivalent. */ 222090075Sobrien DECL_NAME (var) = DECL_NAME (nrv); 222190075Sobrien DECL_SOURCE_FILE (var) = DECL_SOURCE_FILE (nrv); 222290075Sobrien DECL_SOURCE_LINE (var) = DECL_SOURCE_LINE (nrv); 222390075Sobrien DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv); 222490075Sobrien splay_tree_insert (decl_map, 222590075Sobrien (splay_tree_key) nrv, 222690075Sobrien (splay_tree_value) var); 222790075Sobrien } 222890075Sobrien } 222990075Sobrien 223090075Sobrien return var; 223190075Sobrien} 223290075Sobrien 223390075Sobrien/* Record that we're about to start inlining FN, and return non-zero if 223490075Sobrien that's OK. Used for lang_hooks.tree_inlining.start_inlining. */ 223590075Sobrien 223690075Sobrienint 223790075Sobriencp_start_inlining (fn) 223890075Sobrien tree fn; 223990075Sobrien{ 224090075Sobrien if (DECL_TEMPLATE_INSTANTIATION (fn)) 224190075Sobrien return push_tinst_level (fn); 224290075Sobrien else 224390075Sobrien return 1; 224490075Sobrien} 224590075Sobrien 224690075Sobrien/* Record that we're done inlining FN. Used for 224790075Sobrien lang_hooks.tree_inlining.end_inlining. */ 224890075Sobrien 224990075Sobrienvoid 225090075Sobriencp_end_inlining (fn) 225190075Sobrien tree fn ATTRIBUTE_UNUSED; 225290075Sobrien{ 225390075Sobrien if (DECL_TEMPLATE_INSTANTIATION (fn)) 225490075Sobrien pop_tinst_level (); 225590075Sobrien} 225690075Sobrien 225790075Sobrien/* Initialize tree.c. */ 225890075Sobrien 225990075Sobrienvoid 226090075Sobrieninit_tree () 226190075Sobrien{ 226290075Sobrien make_lang_type_fn = cp_make_lang_type; 226390075Sobrien lang_unsave = cp_unsave; 226490075Sobrien lang_statement_code_p = cp_statement_code_p; 226590075Sobrien lang_set_decl_assembler_name = mangle_decl; 226690075Sobrien list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL); 226790075Sobrien ggc_add_root (&list_hash_table, 1, 226890075Sobrien sizeof (list_hash_table), 226990075Sobrien mark_tree_hashtable); 227090075Sobrien} 227190075Sobrien 227290075Sobrien/* Called via walk_tree. If *TP points to a DECL_STMT for a local 227390075Sobrien declaration, copies the declaration and enters it in the splay_tree 227490075Sobrien pointed to by DATA (which is really a `splay_tree *'). */ 227590075Sobrien 227690075Sobrienstatic tree 227790075Sobrienmark_local_for_remap_r (tp, walk_subtrees, data) 227890075Sobrien tree *tp; 227990075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 228090075Sobrien void *data; 228190075Sobrien{ 228290075Sobrien tree t = *tp; 228390075Sobrien splay_tree st = (splay_tree) data; 228490075Sobrien tree decl; 228590075Sobrien 228690075Sobrien 228790075Sobrien if (TREE_CODE (t) == DECL_STMT 228890075Sobrien && nonstatic_local_decl_p (DECL_STMT_DECL (t))) 228990075Sobrien decl = DECL_STMT_DECL (t); 229090075Sobrien else if (TREE_CODE (t) == LABEL_STMT) 229190075Sobrien decl = LABEL_STMT_LABEL (t); 229290075Sobrien else if (TREE_CODE (t) == TARGET_EXPR 229390075Sobrien && nonstatic_local_decl_p (TREE_OPERAND (t, 0))) 229490075Sobrien decl = TREE_OPERAND (t, 0); 229590075Sobrien else if (TREE_CODE (t) == CASE_LABEL) 229690075Sobrien decl = CASE_LABEL_DECL (t); 229790075Sobrien else 229890075Sobrien decl = NULL_TREE; 229990075Sobrien 230090075Sobrien if (decl) 230190075Sobrien { 230290075Sobrien tree copy; 230390075Sobrien 230490075Sobrien /* Make a copy. */ 230590075Sobrien copy = copy_decl_for_inlining (decl, 230690075Sobrien DECL_CONTEXT (decl), 230790075Sobrien DECL_CONTEXT (decl)); 230890075Sobrien 230990075Sobrien /* Remember the copy. */ 231090075Sobrien splay_tree_insert (st, 231190075Sobrien (splay_tree_key) decl, 231290075Sobrien (splay_tree_value) copy); 231390075Sobrien } 231490075Sobrien 231590075Sobrien return NULL_TREE; 231690075Sobrien} 231790075Sobrien 231890075Sobrien/* Called via walk_tree when an expression is unsaved. Using the 231990075Sobrien splay_tree pointed to by ST (which is really a `splay_tree'), 232090075Sobrien remaps all local declarations to appropriate replacements. */ 232190075Sobrien 232290075Sobrienstatic tree 232390075Sobriencp_unsave_r (tp, walk_subtrees, data) 232490075Sobrien tree *tp; 232590075Sobrien int *walk_subtrees; 232690075Sobrien void *data; 232790075Sobrien{ 232890075Sobrien splay_tree st = (splay_tree) data; 232990075Sobrien splay_tree_node n; 233090075Sobrien 233190075Sobrien /* Only a local declaration (variable or label). */ 233290075Sobrien if (nonstatic_local_decl_p (*tp)) 233390075Sobrien { 233490075Sobrien /* Lookup the declaration. */ 233590075Sobrien n = splay_tree_lookup (st, (splay_tree_key) *tp); 233690075Sobrien 233790075Sobrien /* If it's there, remap it. */ 233890075Sobrien if (n) 233990075Sobrien *tp = (tree) n->value; 234090075Sobrien } 234190075Sobrien else if (TREE_CODE (*tp) == SAVE_EXPR) 234290075Sobrien remap_save_expr (tp, st, current_function_decl, walk_subtrees); 234390075Sobrien else 234490075Sobrien { 234590075Sobrien copy_tree_r (tp, walk_subtrees, NULL); 234690075Sobrien 234790075Sobrien /* Do whatever unsaving is required. */ 234890075Sobrien unsave_expr_1 (*tp); 234990075Sobrien } 235090075Sobrien 235190075Sobrien /* Keep iterating. */ 235290075Sobrien return NULL_TREE; 235390075Sobrien} 235490075Sobrien 235590075Sobrien/* Called by unsave_expr_now whenever an expression (*TP) needs to be 235690075Sobrien unsaved. */ 235790075Sobrien 235890075Sobrienstatic void 235990075Sobriencp_unsave (tp) 236090075Sobrien tree *tp; 236190075Sobrien{ 236290075Sobrien splay_tree st; 236390075Sobrien 236490075Sobrien /* Create a splay-tree to map old local variable declarations to new 236590075Sobrien ones. */ 236690075Sobrien st = splay_tree_new (splay_tree_compare_pointers, NULL, NULL); 236790075Sobrien 236890075Sobrien /* Walk the tree once figuring out what needs to be remapped. */ 236990075Sobrien walk_tree (tp, mark_local_for_remap_r, st, NULL); 237090075Sobrien 237190075Sobrien /* Walk the tree again, copying, remapping, and unsaving. */ 237290075Sobrien walk_tree (tp, cp_unsave_r, st, NULL); 237390075Sobrien 237490075Sobrien /* Clean up. */ 237590075Sobrien splay_tree_delete (st); 237690075Sobrien} 237790075Sobrien 237890075Sobrien/* Returns the kind of special function that DECL (a FUNCTION_DECL) 237990075Sobrien is. Note that this sfk_none is zero, so this function can be used 238090075Sobrien as a predicate to test whether or not DECL is a special function. */ 238190075Sobrien 238290075Sobrienspecial_function_kind 238390075Sobrienspecial_function_p (decl) 238490075Sobrien tree decl; 238590075Sobrien{ 238690075Sobrien /* Rather than doing all this stuff with magic names, we should 238790075Sobrien probably have a field of type `special_function_kind' in 238890075Sobrien DECL_LANG_SPECIFIC. */ 238990075Sobrien if (DECL_COPY_CONSTRUCTOR_P (decl)) 239090075Sobrien return sfk_copy_constructor; 239190075Sobrien if (DECL_CONSTRUCTOR_P (decl)) 239290075Sobrien return sfk_constructor; 239390075Sobrien if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR) 239490075Sobrien return sfk_assignment_operator; 239590075Sobrien if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) 239690075Sobrien return sfk_destructor; 239790075Sobrien if (DECL_COMPLETE_DESTRUCTOR_P (decl)) 239890075Sobrien return sfk_complete_destructor; 239990075Sobrien if (DECL_BASE_DESTRUCTOR_P (decl)) 240090075Sobrien return sfk_base_destructor; 240190075Sobrien if (DECL_DELETING_DESTRUCTOR_P (decl)) 240290075Sobrien return sfk_deleting_destructor; 240390075Sobrien if (DECL_CONV_FN_P (decl)) 240490075Sobrien return sfk_conversion; 240590075Sobrien 240690075Sobrien return sfk_none; 240790075Sobrien} 240890075Sobrien 240990075Sobrien/* Returns non-zero if TYPE is a character type, including wchar_t. */ 241090075Sobrien 241190075Sobrienint 241290075Sobrienchar_type_p (type) 241390075Sobrien tree type; 241490075Sobrien{ 241590075Sobrien return (same_type_p (type, char_type_node) 241690075Sobrien || same_type_p (type, unsigned_char_type_node) 241790075Sobrien || same_type_p (type, signed_char_type_node) 241890075Sobrien || same_type_p (type, wchar_type_node)); 241990075Sobrien} 242090075Sobrien 242190075Sobrien/* Returns the kind of linkage associated with the indicated DECL. Th 242290075Sobrien value returned is as specified by the language standard; it is 242390075Sobrien independent of implementation details regarding template 242490075Sobrien instantiation, etc. For example, it is possible that a declaration 242590075Sobrien to which this function assigns external linkage would not show up 242690075Sobrien as a global symbol when you run `nm' on the resulting object file. */ 242790075Sobrien 242890075Sobrienlinkage_kind 242990075Sobriendecl_linkage (decl) 243090075Sobrien tree decl; 243190075Sobrien{ 243290075Sobrien /* This function doesn't attempt to calculate the linkage from first 243390075Sobrien principles as given in [basic.link]. Instead, it makes use of 243490075Sobrien the fact that we have already set TREE_PUBLIC appropriately, and 243590075Sobrien then handles a few special cases. Ideally, we would calculate 243690075Sobrien linkage first, and then transform that into a concrete 243790075Sobrien implementation. */ 243890075Sobrien 243990075Sobrien /* Things that don't have names have no linkage. */ 244090075Sobrien if (!DECL_NAME (decl)) 244190075Sobrien return lk_none; 244290075Sobrien 244390075Sobrien /* Things that are TREE_PUBLIC have external linkage. */ 244490075Sobrien if (TREE_PUBLIC (decl)) 244590075Sobrien return lk_external; 244690075Sobrien 244790075Sobrien /* Some things that are not TREE_PUBLIC have external linkage, too. 244890075Sobrien For example, on targets that don't have weak symbols, we make all 244990075Sobrien template instantiations have internal linkage (in the object 245090075Sobrien file), but the symbols should still be treated as having external 245190075Sobrien linkage from the point of view of the language. */ 245290075Sobrien if (DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) 245390075Sobrien return lk_external; 245490075Sobrien 245590075Sobrien /* Things in local scope do not have linkage, if they don't have 245690075Sobrien TREE_PUBLIC set. */ 245790075Sobrien if (decl_function_context (decl)) 245890075Sobrien return lk_none; 245990075Sobrien 246090075Sobrien /* Everything else has internal linkage. */ 246190075Sobrien return lk_internal; 246290075Sobrien} 2463