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