summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/tree.c')
-rw-r--r--contrib/gcc/cp/tree.c1400
1 files changed, 667 insertions, 733 deletions
diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c
index 1551df0..d39ff76 100644
--- a/contrib/gcc/cp/tree.c
+++ b/contrib/gcc/cp/tree.c
@@ -1,69 +1,67 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "real.h"
#include "rtl.h"
#include "toplev.h"
-#include "ggc.h"
#include "insn-config.h"
#include "integrate.h"
#include "tree-inline.h"
#include "target.h"
-static tree bot_manip PARAMS ((tree *, int *, void *));
-static tree bot_replace PARAMS ((tree *, int *, void *));
-static tree build_cplus_array_type_1 PARAMS ((tree, tree));
-static int list_hash_eq PARAMS ((const void *, const void *));
-static hashval_t list_hash_pieces PARAMS ((tree, tree, tree));
-static hashval_t list_hash PARAMS ((const void *));
-static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int, int));
-static tree no_linkage_helper PARAMS ((tree *, int *, void *));
-static tree build_srcloc PARAMS ((const char *, int));
-static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
-static tree cp_unsave_r PARAMS ((tree *, int *, void *));
-static tree build_target_expr PARAMS ((tree, tree));
-static tree count_trees_r PARAMS ((tree *, int *, void *));
-static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *));
-static tree find_tree_r PARAMS ((tree *, int *, void *));
-extern int cp_statement_code_p PARAMS ((enum tree_code));
-
-static tree handle_java_interface_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree handle_com_interface_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, bool *));
+static tree bot_manip (tree *, int *, void *);
+static tree bot_replace (tree *, int *, void *);
+static tree build_cplus_array_type_1 (tree, tree);
+static int list_hash_eq (const void *, const void *);
+static hashval_t list_hash_pieces (tree, tree, tree);
+static hashval_t list_hash (const void *);
+static cp_lvalue_kind lvalue_p_1 (tree, int);
+static tree no_linkage_helper (tree *, int *, void *);
+static tree mark_local_for_remap_r (tree *, int *, void *);
+static tree cp_unsave_r (tree *, int *, void *);
+static tree build_target_expr (tree, tree);
+static tree count_trees_r (tree *, int *, void *);
+static tree verify_stmt_tree_r (tree *, int *, void *);
+static tree find_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
+
+static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is
nonzero, rvalues of class type are considered lvalues. */
static cp_lvalue_kind
-lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
- tree ref;
- int treat_class_rvalues_as_lvalues;
- int allow_cast_as_lvalue;
+lvalue_p_1 (tree ref,
+ int treat_class_rvalues_as_lvalues)
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -87,39 +85,31 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
case REALPART_EXPR:
case IMAGPART_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
-
- case NOP_EXPR:
- /* If expression doesn't change the type, we consider it as an
- lvalue even when cast_as_lvalue extension isn't selected.
- That's because parts of the compiler are alleged to be sloppy
- about sticking in NOP_EXPR node for no good reason. */
- if (allow_cast_as_lvalue ||
- same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)),
- TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0)))))
- return lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
- else
- return clk_none;
+ treat_class_rvalues_as_lvalues);
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
- if (op1_lvalue_kind
- /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
- situations. */
- && TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL
- && DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
+ treat_class_rvalues_as_lvalues);
+ /* In an expression of the form "X.Y", the packed-ness of the
+ expression does not depend on "X". */
+ op1_lvalue_kind &= ~clk_packed;
+ /* Look at the member designator. */
+ if (!op1_lvalue_kind
+ /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
+ situations. */
+ || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
+ ;
+ else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
{
/* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */
op1_lvalue_kind &= ~clk_ordinary;
- /* The lvalue is for a btifield. */
+ /* The lvalue is for a bitfield. */
op1_lvalue_kind |= clk_bitfield;
}
+ else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
+ op1_lvalue_kind |= clk_packed;
+
return op1_lvalue_kind;
case STRING_CST:
@@ -141,27 +131,19 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
/* A currently unresolved scope ref. */
case SCOPE_REF:
abort ();
- case OFFSET_REF:
- if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
- return clk_ordinary;
- /* Fall through. */
case MAX_EXPR:
case MIN_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
break;
case COND_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
break;
case MODIFY_EXPR:
@@ -169,17 +151,15 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
case COMPOUND_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
case TARGET_EXPR:
return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
case CALL_EXPR:
case VA_ARG_EXPR:
- return ((treat_class_rvalues_as_lvalues
- && IS_AGGR_TYPE (TREE_TYPE (ref)))
- ? clk_class : clk_none);
+ /* Any class-valued call would be wrapped in a TARGET_EXPR. */
+ return clk_none;
case FUNCTION_DECL:
/* All functions (except non-static-member functions) are
@@ -187,6 +167,14 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
? clk_none : clk_ordinary);
+ case NON_DEPENDENT_EXPR:
+ /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
+ things like "&E" where "E" is an expression with a
+ non-dependent type work. It is safe to be lenient because an
+ error will be issued when the template is instantiated if "E"
+ is not an lvalue. */
+ return clk_ordinary;
+
default:
break;
}
@@ -206,82 +194,45 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
return op1_lvalue_kind;
}
-/* If REF is an lvalue, returns the kind of lvalue that REF is.
- Otherwise, returns clk_none. Lvalues can be assigned, unless they
- have TREE_READONLY, or unless they are FUNCTION_DECLs. Lvalues can
- have their address taken, unless they have DECL_REGISTER. */
-
-cp_lvalue_kind
-real_lvalue_p (ref)
- tree ref;
-{
- return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);
-}
-
/* Returns the kind of lvalue that REF is, in the sense of
[basic.lval]. This function should really be named lvalue_p; it
computes the C++ definition of lvalue. */
cp_lvalue_kind
-real_non_cast_lvalue_p (tree ref)
+real_lvalue_p (tree ref)
{
return lvalue_p_1 (ref,
- /*treat_class_rvalues_as_lvalues=*/0,
- /*allow_cast_as_lvalue=*/0);
+ /*treat_class_rvalues_as_lvalues=*/0);
}
/* This differs from real_lvalue_p in that class rvalues are
considered lvalues. */
int
-lvalue_p (ref)
- tree ref;
-{
- return
- (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);
-}
-
-int
-non_cast_lvalue_p (ref)
- tree ref;
+lvalue_p (tree ref)
{
return
- (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 0) != clk_none);
+ (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
}
/* Return nonzero if REF is an lvalue valid for this language;
otherwise, print an error message and return zero. */
int
-lvalue_or_else (ref, string)
- tree ref;
- const char *string;
+lvalue_or_else (tree ref, const char* string)
{
- int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1);
- int win = (ret != clk_none);
- if (! win)
- error ("non-lvalue in %s", string);
- return win;
-}
-
-int
-non_cast_lvalue_or_else (ref, string)
- tree ref;
- const char *string;
-{
- int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0);
- int win = (ret != clk_none);
- if (! win)
- error ("non-lvalue in %s", string);
- return win;
+ if (!lvalue_p (ref))
+ {
+ error ("non-lvalue in %s", string);
+ return 0;
+ }
+ return 1;
}
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
static tree
-build_target_expr (decl, value)
- tree decl;
- tree value;
+build_target_expr (tree decl, tree value)
{
tree t;
@@ -296,6 +247,19 @@ build_target_expr (decl, value)
return t;
}
+/* Return an undeclared local temporary of type TYPE for use in building a
+ TARGET_EXPR. */
+
+static tree
+build_local_temp (tree type)
+{
+ tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (slot) = 1;
+ DECL_CONTEXT (slot) = current_function_decl;
+ layout_decl (slot, 0);
+ return slot;
+}
+
/* INIT is a CALL_EXPR which needs info about its target.
TYPE is the type that this initialization should appear to have.
@@ -304,13 +268,12 @@ build_target_expr (decl, value)
and language-specific expression expanders. */
tree
-build_cplus_new (type, init)
- tree type;
- tree init;
+build_cplus_new (tree type, tree init)
{
tree fn;
tree slot;
tree rval;
+ int is_ctor;
/* Make sure that we're not trying to create an instance of an
abstract class. */
@@ -319,10 +282,12 @@ build_cplus_new (type, init)
if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
return convert (type, init);
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
+ fn = TREE_OPERAND (init, 0);
+ is_ctor = (TREE_CODE (fn) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+
+ slot = build_local_temp (type);
/* We split the CALL_EXPR into its function and its arguments here.
Then, in expand_expr, we put them back together. The reason for
@@ -332,13 +297,18 @@ build_cplus_new (type, init)
replaces every AGGR_INIT_EXPR with a copy that uses a fresh
temporary slot. Then, expand_expr builds up a call-expression
using the new slot. */
- fn = TREE_OPERAND (init, 0);
- rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot);
- TREE_SIDE_EFFECTS (rval) = 1;
- AGGR_INIT_VIA_CTOR_P (rval)
- = (TREE_CODE (fn) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
- && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+
+ /* If we don't need to use a constructor to create an object of this
+ type, don't mess with AGGR_INIT_EXPR. */
+ if (is_ctor || TREE_ADDRESSABLE (type))
+ {
+ rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot);
+ TREE_SIDE_EFFECTS (rval) = 1;
+ AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
+ }
+ else
+ rval = init;
+
rval = build_target_expr (slot, rval);
return rval;
@@ -348,98 +318,58 @@ build_cplus_new (type, init)
indicated TYPE. */
tree
-build_target_expr_with_type (init, type)
- tree init;
- tree type;
+build_target_expr_with_type (tree init, tree type)
{
tree slot;
- tree rval;
if (TREE_CODE (init) == TARGET_EXPR)
return init;
else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)
&& TREE_CODE (init) != COND_EXPR
- && TREE_CODE (init) != CONSTRUCTOR)
+ && TREE_CODE (init) != CONSTRUCTOR
+ && TREE_CODE (init) != VA_ARG_EXPR)
/* We need to build up a copy constructor call. COND_EXPR is a special
case because we already have copies on the arms and we don't want
another one here. A CONSTRUCTOR is aggregate initialization, which
- is handled separately. */
+ is handled separately. A VA_ARG_EXPR is magic creation of an
+ aggregate; there's no additional work to be done. */
return force_rvalue (init);
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
- rval = build_target_expr (slot, init);
-
- return rval;
+ slot = build_local_temp (type);
+ return build_target_expr (slot, init);
}
-/* Like build_target_expr_with_type, but use the type of INIT. */
+/* Like the above function, but without the checking. This function should
+ only be used by code which is deliberately trying to subvert the type
+ system, such as call_builtin_trap. */
tree
-get_target_expr (init)
- tree init;
+force_target_expr (tree type, tree init)
{
- return build_target_expr_with_type (init, TREE_TYPE (init));
+ tree slot = build_local_temp (type);
+ return build_target_expr (slot, init);
}
-
-/* Construct, lay out and return the type of methods belonging to class
- BASETYPE and whose arguments are described by ARGTYPES and whose values
- are described by RETTYPE. If each type exists already, reuse it. */
+
+/* Like build_target_expr_with_type, but use the type of INIT. */
tree
-build_cplus_method_type (basetype, rettype, argtypes)
- tree basetype, rettype, argtypes;
+get_target_expr (tree init)
{
- register tree t;
- tree ptype;
- int hashcode;
-
- /* Make a node of the sort we want. */
- t = make_node (METHOD_TYPE);
-
- TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
- TREE_TYPE (t) = rettype;
- ptype = build_pointer_type (basetype);
-
- /* The actual arglist for this function includes a "hidden" argument
- which is "this". Put it into the list of argument types. */
- argtypes = tree_cons (NULL_TREE, ptype, argtypes);
- TYPE_ARG_TYPES (t) = argtypes;
- TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
-
- /* If we already have such a type, use the old one and free this one.
- Note that it also frees up the above cons cell if found. */
- hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
- type_hash_list (argtypes);
-
- t = type_hash_canon (hashcode, t);
-
- if (!COMPLETE_TYPE_P (t))
- layout_type (t);
-
- return t;
+ return build_target_expr_with_type (init, TREE_TYPE (init));
}
+
static tree
-build_cplus_array_type_1 (elt_type, index_type)
- tree elt_type;
- tree index_type;
+build_cplus_array_type_1 (tree elt_type, tree index_type)
{
tree t;
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- /* Don't do the minimal thing just because processing_template_decl is
- set; we want to give string constants the right type immediately, so
- we don't have to fix them up at instantiation time. */
- if ((processing_template_decl
- && index_type && TYPE_MAX_VALUE (index_type)
- && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST)
- || uses_template_parms (elt_type)
- || (index_type && uses_template_parms (index_type)))
+ if (dependent_type_p (elt_type)
+ || (index_type
+ && value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
@@ -458,22 +388,18 @@ build_cplus_array_type_1 (elt_type, index_type)
}
tree
-build_cplus_array_type (elt_type, index_type)
- tree elt_type;
- tree index_type;
+build_cplus_array_type (tree elt_type, tree index_type)
{
tree t;
int type_quals = cp_type_quals (elt_type);
- int cv_quals = type_quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- int other_quals = type_quals & ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- if (cv_quals)
- elt_type = cp_build_qualified_type (elt_type, other_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
t = build_cplus_array_type_1 (elt_type, index_type);
- if (cv_quals)
- t = cp_build_qualified_type (t, cv_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ t = cp_build_qualified_type (t, type_quals);
return t;
}
@@ -495,22 +421,16 @@ build_cplus_array_type (elt_type, index_type)
via a typedef or template type argument. [dcl.ref] No such
dispensation is provided for qualifying a function type. [dcl.fct]
DR 295 queries this and the proposed resolution brings it into line
- with qualifiying a reference. We implement the DR. We also behave
+ with qualifying a reference. We implement the DR. We also behave
in a similar manner for restricting non-pointer types. */
tree
-cp_build_qualified_type_real (type, type_quals, complain)
- tree type;
- int type_quals;
- tsubst_flags_t complain;
+cp_build_qualified_type_real (tree type,
+ int type_quals,
+ tsubst_flags_t complain)
{
tree result;
int bad_quals = TYPE_UNQUALIFIED;
- /* We keep bad function qualifiers separate, so that we can decide
- whether to implement DR 295 or not. DR 295 break existing code,
- unfortunately. Remove this variable to implement the defect
- report. */
- int bad_func_quals = TYPE_UNQUALIFIED;
if (type == error_mark_node)
return type;
@@ -518,54 +438,6 @@ cp_build_qualified_type_real (type, type_quals, complain)
if (type_quals == cp_type_quals (type))
return type;
- /* A reference, fucntion or method type shall not be cv qualified.
- [dcl.ref], [dct.fct] */
- if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
- && (TREE_CODE (type) == REFERENCE_TYPE
- || TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE))
- {
- bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- if (TREE_CODE (type) != REFERENCE_TYPE)
- bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- }
-
- /* A restrict-qualified type must be a pointer (or reference)
- to object or incomplete type. */
- if ((type_quals & TYPE_QUAL_RESTRICT)
- && TREE_CODE (type) != TEMPLATE_TYPE_PARM
- && TREE_CODE (type) != TYPENAME_TYPE
- && !POINTER_TYPE_P (type))
- {
- bad_quals |= TYPE_QUAL_RESTRICT;
- type_quals &= ~TYPE_QUAL_RESTRICT;
- }
-
- if (bad_quals == TYPE_UNQUALIFIED)
- /*OK*/;
- else if (!(complain & (tf_error | tf_ignore_bad_quals)))
- return error_mark_node;
- else if (bad_func_quals && !(complain & tf_error))
- return error_mark_node;
- else
- {
- if (complain & tf_ignore_bad_quals)
- /* We're not going to warn about constifying things that can't
- be constified. */
- bad_quals &= ~TYPE_QUAL_CONST;
- bad_quals |= bad_func_quals;
- if (bad_quals)
- {
- tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-
- if (!(complain & tf_ignore_bad_quals)
- || bad_func_quals)
- error ("`%V' qualifiers cannot be applied to `%T'",
- bad_type, type);
- }
- }
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* In C++, the qualification really applies to the array element
@@ -620,6 +492,48 @@ cp_build_qualified_type_real (type, type_quals, complain)
return build_ptrmemfunc_type (t);
}
+ /* A reference, function or method type shall not be cv qualified.
+ [dcl.ref], [dct.fct] */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* A restrict-qualified type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
+ {
+ bad_quals |= TYPE_QUAL_RESTRICT;
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ if (bad_quals == TYPE_UNQUALIFIED)
+ /*OK*/;
+ else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ return error_mark_node;
+ else
+ {
+ if (complain & tf_ignore_bad_quals)
+ /* We're not going to warn about constifying things that can't
+ be constified. */
+ bad_quals &= ~TYPE_QUAL_CONST;
+ if (bad_quals)
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+
+ if (!(complain & tf_ignore_bad_quals))
+ error ("`%V' qualifiers cannot be applied to `%T'",
+ bad_type, type);
+ }
+ }
+
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);
@@ -641,43 +555,85 @@ cp_build_qualified_type_real (type, type_quals, complain)
compatible types. */
tree
-canonical_type_variant (t)
- tree t;
+canonical_type_variant (tree t)
{
return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t));
}
-/* Makes new binfos for the indirect bases under BINFO, and updates
- BINFO_OFFSET for them and their bases. */
+/* Makes new binfos for the indirect bases under BINFO. T is the most
+ derived TYPE. PREV is the previous binfo, whose TREE_CHAIN we make
+ point to this binfo. We return the last BINFO created.
-void
-unshare_base_binfos (binfo)
- tree binfo;
+ The CLASSTYPE_VBASECLASSES list of T is constructed in reverse
+ order (pre-order, depth-first, right-to-left). You must nreverse it.
+
+ The BINFO_INHERITANCE of a virtual base class points to the binfo
+ og the most derived type.
+
+ The binfo's TREE_CHAIN is set to inheritance graph order, but bases
+ for non-class types are not included (i.e. those which are
+ dependent bases in non-instantiated templates). */
+
+tree
+copy_base_binfos (tree binfo, tree t, tree prev)
{
tree binfos = BINFO_BASETYPES (binfo);
- tree new_binfo;
- int j;
+ int n, ix;
+ if (prev)
+ TREE_CHAIN (prev) = binfo;
+ prev = binfo;
+
if (binfos == NULL_TREE)
- return;
+ return prev;
- /* Now unshare the structure beneath BINFO. */
- for (j = TREE_VEC_LENGTH (binfos)-1;
- j >= 0; j--)
+ n = TREE_VEC_LENGTH (binfos);
+
+ /* Now copy the structure beneath BINFO. */
+ for (ix = 0; ix != n; ix++)
{
- tree base_binfo = TREE_VEC_ELT (binfos, j);
- new_binfo = TREE_VEC_ELT (binfos, j)
- = make_binfo (BINFO_OFFSET (base_binfo),
- base_binfo,
- BINFO_VTABLE (base_binfo),
- BINFO_VIRTUALS (base_binfo));
- TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo);
- TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo);
- TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo);
- BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
- BINFO_PRIMARY_BASE_OF (new_binfo) = NULL_TREE;
- unshare_base_binfos (new_binfo);
+ tree base_binfo = TREE_VEC_ELT (binfos, ix);
+ tree new_binfo = NULL_TREE;
+
+ if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))
+ {
+ my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
+
+ new_binfo = base_binfo;
+ TREE_CHAIN (prev) = new_binfo;
+ prev = new_binfo;
+ BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
+ BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
+ }
+ else if (TREE_VIA_VIRTUAL (base_binfo))
+ {
+ new_binfo = purpose_member (BINFO_TYPE (base_binfo),
+ CLASSTYPE_VBASECLASSES (t));
+ if (new_binfo)
+ new_binfo = TREE_VALUE (new_binfo);
+ }
+
+ if (!new_binfo)
+ {
+ new_binfo = make_binfo (BINFO_OFFSET (base_binfo),
+ base_binfo, NULL_TREE,
+ BINFO_VIRTUALS (base_binfo));
+ prev = copy_base_binfos (new_binfo, t, prev);
+ if (TREE_VIA_VIRTUAL (base_binfo))
+ {
+ CLASSTYPE_VBASECLASSES (t)
+ = tree_cons (BINFO_TYPE (new_binfo), new_binfo,
+ CLASSTYPE_VBASECLASSES (t));
+ TREE_VIA_VIRTUAL (new_binfo) = 1;
+ BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
+ }
+ else
+ BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
+ }
+ TREE_VEC_ELT (binfos, ix) = new_binfo;
}
+
+ return prev;
}
@@ -703,9 +659,7 @@ struct list_proxy
for a node we are thinking about adding). */
static int
-list_hash_eq (entry, data)
- const void *entry;
- const void *data;
+list_hash_eq (const void* entry, const void* data)
{
tree t = (tree) entry;
struct list_proxy *proxy = (struct list_proxy *) data;
@@ -720,10 +674,7 @@ list_hash_eq (entry, data)
TREE_COMMON slots), by adding the hash codes of the individual entries. */
static hashval_t
-list_hash_pieces (purpose, value, chain)
- tree purpose;
- tree value;
- tree chain;
+list_hash_pieces (tree purpose, tree value, tree chain)
{
hashval_t hashcode = 0;
@@ -744,8 +695,7 @@ list_hash_pieces (purpose, value, chain)
/* Hash an already existing TREE_LIST. */
static hashval_t
-list_hash (p)
- const void *p;
+list_hash (const void* p)
{
tree t = (tree) p;
return list_hash_pieces (TREE_PURPOSE (t),
@@ -758,11 +708,10 @@ list_hash (p)
new one, and record it as the canonical object. */
tree
-hash_tree_cons (purpose, value, chain)
- tree purpose, value, chain;
+hash_tree_cons (tree purpose, tree value, tree chain)
{
int hashcode = 0;
- PTR* slot;
+ void **slot;
struct list_proxy proxy;
/* Hash the list node. */
@@ -777,15 +726,14 @@ hash_tree_cons (purpose, value, chain)
INSERT);
/* If not, create a new node. */
if (!*slot)
- *slot = (PTR) tree_cons (purpose, value, chain);
+ *slot = tree_cons (purpose, value, chain);
return *slot;
}
/* Constructor for hashed lists. */
tree
-hash_tree_chain (value, chain)
- tree value, chain;
+hash_tree_chain (tree value, tree chain)
{
return hash_tree_cons (NULL_TREE, value, chain);
}
@@ -793,8 +741,7 @@ hash_tree_chain (value, chain)
/* Similar, but used for concatenating two lists. */
tree
-hash_chainon (list1, list2)
- tree list1, list2;
+hash_chainon (tree list1, tree list2)
{
if (list2 == 0)
return list1;
@@ -822,19 +769,21 @@ hash_chainon (list1, list2)
VIRTUALS are the virtual functions sitting in VTABLE. */
tree
-make_binfo (offset, binfo, vtable, virtuals)
- tree offset, binfo;
- tree vtable, virtuals;
+make_binfo (tree offset, tree binfo, tree vtable, tree virtuals)
{
- tree new_binfo = make_tree_vec (11);
+ tree new_binfo = make_tree_vec (BINFO_LANG_ELTS);
tree type;
if (TREE_CODE (binfo) == TREE_VEC)
- type = BINFO_TYPE (binfo);
+ {
+ type = BINFO_TYPE (binfo);
+ BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo);
+ }
else
{
type = binfo;
- binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE;
+ binfo = NULL_TREE;
+ BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
}
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
@@ -842,45 +791,26 @@ make_binfo (offset, binfo, vtable, virtuals)
BINFO_VTABLE (new_binfo) = vtable;
BINFO_VIRTUALS (new_binfo) = virtuals;
- if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)
- BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
- return new_binfo;
-}
-
-/* Return a TREE_LIST whose TREE_VALUE nodes along the
- BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In
- other words, while the BINFO_INHERITANCE_CHAIN goes from base
- classes to derived classes, the reversed path goes from derived
- classes to base classes. */
-
-tree
-reverse_path (binfo)
- tree binfo;
-{
- tree reversed_path;
-
- reversed_path = NULL_TREE;
- while (binfo)
+ if (binfo && !BINFO_DEPENDENT_BASE_P (binfo)
+ && BINFO_BASETYPES (binfo) != NULL_TREE)
{
- reversed_path = tree_cons (NULL_TREE, binfo, reversed_path);
- binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
+ /* We do not need to copy the accesses, as they are read only. */
+ BINFO_BASEACCESSES (new_binfo) = BINFO_BASEACCESSES (binfo);
}
-
- return reversed_path;
+ return new_binfo;
}
void
-debug_binfo (elem)
- tree elem;
+debug_binfo (tree elem)
{
HOST_WIDE_INT n;
tree virtuals;
- fprintf (stderr, "type \"%s\", offset = ",
- TYPE_NAME_STRING (BINFO_TYPE (elem)));
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC,
+ fprintf (stderr, "type \"%s\", offset = " HOST_WIDE_INT_PRINT_DEC
+ "\nvtable type:\n",
+ TYPE_NAME_STRING (BINFO_TYPE (elem)),
TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
- fprintf (stderr, "\nvtable type:\n");
debug_tree (BINFO_TYPE (elem));
if (BINFO_VTABLE (elem))
fprintf (stderr, "vtable decl \"%s\"\n",
@@ -903,15 +833,14 @@ debug_binfo (elem)
}
int
-count_functions (t)
- tree t;
+count_functions (tree t)
{
int i;
if (TREE_CODE (t) == FUNCTION_DECL)
return 1;
else if (TREE_CODE (t) == OVERLOAD)
{
- for (i=0; t; t = OVL_CHAIN (t))
+ for (i = 0; t; t = OVL_CHAIN (t))
i++;
return i;
}
@@ -921,8 +850,7 @@ count_functions (t)
}
int
-is_overloaded_fn (x)
- tree x;
+is_overloaded_fn (tree x)
{
/* A baselink is also considered an overloaded function. */
if (TREE_CODE (x) == OFFSET_REF)
@@ -936,8 +864,7 @@ is_overloaded_fn (x)
}
int
-really_overloaded_fn (x)
- tree x;
+really_overloaded_fn (tree x)
{
/* A baselink is also considered an overloaded function. */
if (TREE_CODE (x) == OFFSET_REF)
@@ -950,23 +877,8 @@ really_overloaded_fn (x)
|| TREE_CODE (x) == TEMPLATE_ID_EXPR);
}
-/* Return the OVERLOAD or FUNCTION_DECL inside FNS. FNS can be an
- OVERLOAD, FUNCTION_DECL, TEMPLATE_ID_EXPR, or baselink. */
-
tree
-get_overloaded_fn (fns)
- tree fns;
-{
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- fns = TREE_OPERAND (fns, 0);
- if (BASELINK_P (fns))
- fns = BASELINK_FUNCTIONS (fns);
- return fns;
-}
-
-tree
-get_first_fn (from)
- tree from;
+get_first_fn (tree from)
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
@@ -979,8 +891,7 @@ get_first_fn (from)
member function. */
int
-bound_pmf_p (t)
- tree t;
+bound_pmf_p (tree t)
{
return (TREE_CODE (t) == OFFSET_REF
&& TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1))));
@@ -989,9 +900,7 @@ bound_pmf_p (t)
/* Return a new OVL node, concatenating it with the old one. */
tree
-ovl_cons (decl, chain)
- tree decl;
- tree chain;
+ovl_cons (tree decl, tree chain)
{
tree result = make_node (OVERLOAD);
TREE_TYPE (result) = unknown_type_node;
@@ -1005,9 +914,7 @@ ovl_cons (decl, chain)
just return it; otherwise, ovl_cons the _DECLs */
tree
-build_overload (decl, chain)
- tree decl;
- tree chain;
+build_overload (tree decl, tree chain)
{
if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
return decl;
@@ -1016,43 +923,11 @@ build_overload (decl, chain)
return ovl_cons (decl, chain);
}
-int
-is_aggr_type_2 (t1, t2)
- tree t1, t2;
-{
- if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
- return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
-}
-
-/* Returns nonzero if CODE is the code for a statement. */
-
-int
-cp_statement_code_p (code)
- enum tree_code code;
-{
- switch (code)
- {
- case CTOR_INITIALIZER:
- case RETURN_INIT:
- case TRY_BLOCK:
- case HANDLER:
- case EH_SPEC_BLOCK:
- case USING_STMT:
- case TAG_DEFN:
- return 1;
-
- default:
- return 0;
- }
-}
#define PRINT_RING_SIZE 4
const char *
-cxx_printable_name (decl, v)
- tree decl;
- int v;
+cxx_printable_name (tree decl, int v)
{
static tree decl_ring[PRINT_RING_SIZE];
static char *print_ring[PRINT_RING_SIZE];
@@ -1096,16 +971,15 @@ cxx_printable_name (decl, v)
listed in RAISES. */
tree
-build_exception_variant (type, raises)
- tree type;
- tree raises;
+build_exception_variant (tree type, tree raises)
{
tree v = TYPE_MAIN_VARIANT (type);
int type_quals = TYPE_QUALS (type);
for (; v; v = TYPE_NEXT_VARIANT (v))
if (TYPE_QUALS (v) == type_quals
- && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1))
+ && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)
+ && (*targetm.comp_type_attributes) (type, v))
return v;
/* Need to build a new variant. */
@@ -1119,9 +993,7 @@ build_exception_variant (type, raises)
arguments. */
tree
-bind_template_template_parm (t, newargs)
- tree t;
- tree newargs;
+bind_template_template_parm (tree t, tree newargs)
{
tree decl = TYPE_NAME (t);
tree t2;
@@ -1148,10 +1020,9 @@ bind_template_template_parm (t, newargs)
/* Called from count_trees via walk_tree. */
static tree
-count_trees_r (tp, walk_subtrees, data)
- tree *tp ATTRIBUTE_UNUSED;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+count_trees_r (tree* tp ATTRIBUTE_UNUSED ,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
++ *((int*) data);
return NULL_TREE;
@@ -1161,8 +1032,7 @@ count_trees_r (tp, walk_subtrees, data)
representation. */
int
-count_trees (t)
- tree t;
+count_trees (tree t)
{
int n_trees = 0;
walk_tree_without_duplicates (&t, count_trees_r, &n_trees);
@@ -1172,16 +1042,15 @@ count_trees (t)
/* Called from verify_stmt_tree via walk_tree. */
static tree
-verify_stmt_tree_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+verify_stmt_tree_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
tree t = *tp;
htab_t *statements = (htab_t *) data;
void **slot;
- if (!statement_code_p (TREE_CODE (t)))
+ if (!STATEMENT_CODE_P (TREE_CODE (t)))
return NULL_TREE;
/* If this statement is already present in the hash table, then
@@ -1200,8 +1069,7 @@ verify_stmt_tree_r (tp, walk_subtrees, data)
circularities. */
void
-verify_stmt_tree (t)
- tree t;
+verify_stmt_tree (tree t)
{
htab_t statements;
statements = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
@@ -1212,10 +1080,9 @@ verify_stmt_tree (t)
/* Called from find_tree via walk_tree. */
static tree
-find_tree_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+find_tree_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
if (*tp == (tree) data)
return (tree) data;
@@ -1226,9 +1093,7 @@ find_tree_r (tp, walk_subtrees, data)
/* Returns X if X appears in the tree structure rooted at T. */
tree
-find_tree (t, x)
- tree t;
- tree x;
+find_tree (tree t, tree x)
{
return walk_tree_without_duplicates (&t, find_tree_r, x);
}
@@ -1236,10 +1101,9 @@ find_tree (t, x)
/* Passed to walk_tree. Checks for the use of types with no linkage. */
static tree
-no_linkage_helper (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+no_linkage_helper (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data ATTRIBUTE_UNUSED )
{
tree t = *tp;
@@ -1255,8 +1119,7 @@ no_linkage_helper (tp, walk_subtrees, data)
it. */
tree
-no_linkage_check (t)
- tree t;
+no_linkage_check (tree t)
{
/* There's no point in checking linkage on template functions; we
can't know their complete types. */
@@ -1274,7 +1137,7 @@ extern int depth_reached;
#endif
void
-cxx_print_statistics ()
+cxx_print_statistics (void)
{
print_search_statistics ();
print_class_statistics ();
@@ -1289,8 +1152,7 @@ cxx_print_statistics ()
array. */
tree
-array_type_nelts_top (type)
- tree type;
+array_type_nelts_top (tree type)
{
return fold (build (PLUS_EXPR, sizetype,
array_type_nelts (type),
@@ -1302,8 +1164,7 @@ array_type_nelts_top (type)
ARRAY_TYPEs that are clumped together. */
tree
-array_type_nelts_total (type)
- tree type;
+array_type_nelts_total (tree type)
{
tree sz = array_type_nelts_top (type);
type = TREE_TYPE (type);
@@ -1319,10 +1180,7 @@ array_type_nelts_total (type)
/* Called from break_out_target_exprs via mapcar. */
static tree
-bot_manip (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+bot_manip (tree* tp, int* walk_subtrees, void* data)
{
splay_tree target_remap = ((splay_tree) data);
tree t = *tp;
@@ -1376,10 +1234,9 @@ bot_manip (tp, walk_subtrees, data)
variables. */
static tree
-bot_replace (t, walk_subtrees, data)
- tree *t;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+bot_replace (tree* t,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
splay_tree target_remap = ((splay_tree) data);
@@ -1400,8 +1257,7 @@ bot_replace (t, walk_subtrees, data)
we must replace the temporaries with appropriate local versions. */
tree
-break_out_target_exprs (t)
- tree t;
+break_out_target_exprs (tree t)
{
static int target_remap_count;
static splay_tree target_remap;
@@ -1422,25 +1278,22 @@ break_out_target_exprs (t)
return t;
}
-/* Obstack used for allocating nodes in template function and variable
- definitions. */
-
-/* Similar to `build_nt', except that we set TREE_COMPLEXITY to be the
- current line number. */
+/* Similar to `build_nt', but for template definitions of dependent
+ expressions */
tree
-build_min_nt VPARAMS ((enum tree_code code, ...))
+build_min_nt (enum tree_code code, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
+ va_list p;
- VA_OPEN (p, code);
- VA_FIXEDARG (p, enum tree_code, code);
+ va_start (p, code);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
- TREE_COMPLEXITY (t) = lineno;
+ TREE_COMPLEXITY (t) = input_line;
for (i = 0; i < length; i++)
{
@@ -1448,28 +1301,58 @@ build_min_nt VPARAMS ((enum tree_code code, ...))
TREE_OPERAND (t, i) = x;
}
- VA_CLOSE (p);
+ va_end (p);
return t;
}
-/* Similar to `build', except we set TREE_COMPLEXITY to the current
- line-number. */
+/* Similar to `build', but for template definitions. */
tree
-build_min VPARAMS ((enum tree_code code, tree tt, ...))
+build_min (enum tree_code code, tree tt, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
+ va_list p;
- VA_OPEN (p, tt);
- VA_FIXEDARG (p, enum tree_code, code);
- VA_FIXEDARG (p, tree, tt);
+ va_start (p, tt);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
TREE_TYPE (t) = tt;
- TREE_COMPLEXITY (t) = lineno;
+ TREE_COMPLEXITY (t) = input_line;
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = x;
+ if (x && TREE_SIDE_EFFECTS (x))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+
+ va_end (p);
+ return t;
+}
+
+/* Similar to `build', but for template definitions of non-dependent
+ expressions. NON_DEP is the non-dependent expression that has been
+ built. */
+
+tree
+build_min_non_dep (enum tree_code code, tree non_dep, ...)
+{
+ tree t;
+ int length;
+ int i;
+ va_list p;
+
+ va_start (p, non_dep);
+
+ t = make_node (code);
+ length = TREE_CODE_LENGTH (code);
+ TREE_TYPE (t) = TREE_TYPE (non_dep);
+ TREE_COMPLEXITY (t) = input_line;
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
for (i = 0; i < length; i++)
{
@@ -1477,7 +1360,12 @@ build_min VPARAMS ((enum tree_code code, tree tt, ...))
TREE_OPERAND (t, i) = x;
}
- VA_CLOSE (p);
+ if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
+ /* This should not be considered a COMPOUND_EXPR, because it
+ resolves to an overload. */
+ COMPOUND_EXPR_OVERLOADED (t) = 1;
+
+ va_end (p);
return t;
}
@@ -1489,8 +1377,7 @@ build_min VPARAMS ((enum tree_code code, tree tt, ...))
static GTY(()) tree shared_int_cache[256];
tree
-build_shared_int_cst (i)
- int i;
+build_shared_int_cst (int i)
{
if (i >= 256)
return build_int_2 (i, 0);
@@ -1502,8 +1389,7 @@ build_shared_int_cst (i)
}
tree
-get_type_decl (t)
- tree t;
+get_type_decl (tree t)
{
if (TREE_CODE (t) == TYPE_DECL)
return t;
@@ -1522,8 +1408,7 @@ get_type_decl (t)
Return 0 if ELEM is not in VEC. VEC may be NULL_TREE. */
tree
-vec_binfo_member (elem, vec)
- tree elem, vec;
+vec_binfo_member (tree elem, tree vec)
{
int i;
@@ -1539,8 +1424,7 @@ vec_binfo_member (elem, vec)
indirectly. */
tree
-decl_namespace_context (decl)
- tree decl;
+decl_namespace_context (tree decl)
{
while (1)
{
@@ -1554,39 +1438,35 @@ decl_namespace_context (decl)
}
/* Return truthvalue of whether T1 is the same tree structure as T2.
- Return 1 if they are the same.
- Return 0 if they are understandably different.
- Return -1 if either contains tree structure not understood by
- this function. */
+ Return 1 if they are the same. Return 0 if they are different. */
-int
-cp_tree_equal (t1, t2)
- tree t1, t2;
+bool
+cp_tree_equal (tree t1, tree t2)
{
- register enum tree_code code1, code2;
- int cmp;
+ enum tree_code code1, code2;
if (t1 == t2)
- return 1;
- if (t1 == 0 || t2 == 0)
- return 0;
-
- code1 = TREE_CODE (t1);
- code2 = TREE_CODE (t2);
-
- if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR)
- {
- if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR)
- return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- else
- return cp_tree_equal (TREE_OPERAND (t1, 0), t2);
- }
- else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR
- || code2 == NON_LVALUE_EXPR)
- return cp_tree_equal (t1, TREE_OPERAND (t2, 0));
-
+ return true;
+ if (!t1 || !t2)
+ return false;
+
+ for (code1 = TREE_CODE (t1);
+ code1 == NOP_EXPR || code1 == CONVERT_EXPR
+ || code1 == NON_LVALUE_EXPR;
+ code1 = TREE_CODE (t1))
+ t1 = TREE_OPERAND (t1, 0);
+ for (code2 = TREE_CODE (t2);
+ code2 == NOP_EXPR || code2 == CONVERT_EXPR
+ || code1 == NON_LVALUE_EXPR;
+ code2 = TREE_CODE (t2))
+ t2 = TREE_OPERAND (t2, 0);
+
+ /* They might have become equal now. */
+ if (t1 == t2)
+ return true;
+
if (code1 != code2)
- return 0;
+ return false;
switch (code1)
{
@@ -1600,7 +1480,7 @@ cp_tree_equal (t1, t2)
case STRING_CST:
return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
&& !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
- TREE_STRING_LENGTH (t1));
+ TREE_STRING_LENGTH (t1));
case CONSTRUCTOR:
/* We need to do this when determining whether or not two
@@ -1609,61 +1489,62 @@ cp_tree_equal (t1, t2)
if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
/* The first operand is RTL. */
&& TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
- return 0;
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
case TREE_LIST:
- cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
- if (cmp <= 0)
- return cmp;
- cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
+ return false;
+ if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
+ return false;
return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
case SAVE_EXPR:
return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
case CALL_EXPR:
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
- return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
-
- case TARGET_EXPR:
- /* Special case: if either target is an unallocated VAR_DECL,
- it means that it's going to be unified with whatever the
- TARGET_EXPR is really supposed to initialize, so treat it
- as being equivalent to anything. */
- if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
- && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
- && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
- || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
- && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
- && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
- cmp = 1;
- else
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+ case TARGET_EXPR:
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ /* Special case: if either target is an unallocated VAR_DECL,
+ it means that it's going to be unified with whatever the
+ TARGET_EXPR is really supposed to initialize, so treat it
+ as being equivalent to anything. */
+ if (TREE_CODE (o1) == VAR_DECL && DECL_NAME (o1) == NULL_TREE
+ && !DECL_RTL_SET_P (o1))
+ /*Nop*/;
+ else if (TREE_CODE (o2) == VAR_DECL && DECL_NAME (o2) == NULL_TREE
+ && !DECL_RTL_SET_P (o2))
+ /*Nop*/;
+ else if (!cp_tree_equal (o1, o2))
+ return false;
+
+ return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+ }
+
case WITH_CLEANUP_EXPR:
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
case COMPONENT_REF:
- if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
- return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- return 0;
+ if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1))
+ return false;
+ return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
case VAR_DECL:
case PARM_DECL:
case CONST_DECL:
case FUNCTION_DECL:
- return 0;
+ case TEMPLATE_DECL:
+ case IDENTIFIER_NODE:
+ return false;
case TEMPLATE_PARM_INDEX:
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
@@ -1671,19 +1552,51 @@ cp_tree_equal (t1, t2)
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
+ case TEMPLATE_ID_EXPR:
+ {
+ unsigned ix;
+ tree vec1, vec2;
+
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
+ vec1 = TREE_OPERAND (t1, 1);
+ vec2 = TREE_OPERAND (t2, 1);
+
+ if (!vec1 || !vec2)
+ return !vec1 && !vec2;
+
+ if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
+ return false;
+
+ for (ix = TREE_VEC_LENGTH (vec1); ix--;)
+ if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
+ TREE_VEC_ELT (vec2, ix)))
+ return false;
+
+ return true;
+ }
+
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
- if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
- return 0;
- if (TYPE_P (TREE_OPERAND (t1, 0)))
- return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- break;
-
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ if (TREE_CODE (o1) != TREE_CODE (o2))
+ return false;
+ if (TYPE_P (o1))
+ return same_type_p (o1, o2);
+ else
+ return cp_tree_equal (o1, o2);
+ }
+
case PTRMEM_CST:
/* Two pointer-to-members are the same if they point to the same
field or function in the same class. */
- return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2)
- && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)));
+ if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
+ return false;
+
+ return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
default:
break;
@@ -1700,64 +1613,38 @@ cp_tree_equal (t1, t2)
{
int i;
- cmp = 1;
for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
- {
- cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
- if (cmp <= 0)
- return cmp;
- }
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
+ return false;
+
+ return true;
}
- case 't':
- return same_type_p (t1, t2) ? 1 : 0;
+ case 't':
+ return same_type_p (t1, t2);
}
- return -1;
+ my_friendly_assert (0, 20030617);
+ return false;
}
/* Build a wrapper around a 'struct z_candidate' so we can use it as a
tree. */
tree
-build_zc_wrapper (ptr)
- struct z_candidate *ptr;
+build_zc_wrapper (struct z_candidate* ptr)
{
tree t = make_node (WRAPPER);
WRAPPER_ZC (t) = ptr;
return t;
}
-static tree
-build_srcloc (file, line)
- const char *file;
- int line;
-{
- tree t;
-
- t = make_node (SRCLOC);
- SRCLOC_FILE (t) = file;
- SRCLOC_LINE (t) = line;
-
- return t;
-}
-
-tree
-build_srcloc_here ()
-{
- return build_srcloc (input_filename, lineno);
-}
-
/* The type of ARG when used as an lvalue. */
tree
-lvalue_type (arg)
- tree arg;
+lvalue_type (tree arg)
{
tree type = TREE_TYPE (arg);
- if (TREE_CODE (arg) == OVERLOAD)
- type = unknown_type_node;
return type;
}
@@ -1765,12 +1652,14 @@ lvalue_type (arg)
reference types. */
tree
-error_type (arg)
- tree arg;
+error_type (tree arg)
{
tree type = TREE_TYPE (arg);
+
if (TREE_CODE (type) == ARRAY_TYPE)
;
+ else if (TREE_CODE (type) == ERROR_MARK)
+ ;
else if (real_lvalue_p (arg))
type = build_reference_type (lvalue_type (arg));
else if (IS_AGGR_TYPE (type))
@@ -1782,8 +1671,7 @@ error_type (arg)
/* Does FUNCTION use a variable-length argument list? */
int
-varargs_function_p (function)
- tree function;
+varargs_function_p (tree function)
{
tree parm = TYPE_ARG_TYPES (TREE_TYPE (function));
for (; parm; parm = TREE_CHAIN (parm))
@@ -1795,8 +1683,7 @@ varargs_function_p (function)
/* Returns 1 if decl is a member of a class. */
int
-member_p (decl)
- tree decl;
+member_p (tree decl)
{
const tree ctx = DECL_CONTEXT (decl);
return (ctx && TYPE_P (ctx));
@@ -1806,8 +1693,7 @@ member_p (decl)
object that the access is against. */
tree
-build_dummy_object (type)
- tree type;
+build_dummy_object (tree type)
{
tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
return build_indirect_ref (decl, NULL);
@@ -1818,9 +1704,7 @@ build_dummy_object (type)
binfo path from current_class_type to TYPE, or 0. */
tree
-maybe_dummy_object (type, binfop)
- tree type;
- tree *binfop;
+maybe_dummy_object (tree type, tree* binfop)
{
tree decl, context;
tree binfo;
@@ -1855,8 +1739,7 @@ maybe_dummy_object (type, binfop)
/* Returns 1 if OB is a placeholder object, or a pointer to one. */
int
-is_dummy_object (ob)
- tree ob;
+is_dummy_object (tree ob)
{
if (TREE_CODE (ob) == INDIRECT_REF)
ob = TREE_OPERAND (ob, 0);
@@ -1867,8 +1750,7 @@ is_dummy_object (ob)
/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
int
-pod_type_p (t)
- tree t;
+pod_type_p (tree t)
{
t = strip_array_types (t);
@@ -1880,10 +1762,8 @@ pod_type_p (t)
return 1;
if (TYPE_PTR_P (t))
return 1; /* pointer to non-member */
- if (TYPE_PTRMEM_P (t))
- return 1; /* pointer to member object */
- if (TYPE_PTRMEMFUNC_P (t))
- return 1; /* pointer to member function */
+ if (TYPE_PTR_TO_MEMBER_P (t))
+ return 1; /* pointer to member */
if (! CLASS_TYPE_P (t))
return 0; /* other non-class type (reference or function) */
@@ -1896,8 +1776,7 @@ pod_type_p (t)
zeros in it. */
int
-zero_init_p (t)
- tree t;
+zero_init_p (tree t)
{
t = strip_array_types (t);
@@ -1929,12 +1808,11 @@ const struct attribute_spec cxx_attribute_table[] =
/* Handle a "java_interface" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_java_interface_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_java_interface_attribute (tree* node,
+ tree name,
+ tree args ATTRIBUTE_UNUSED ,
+ int flags,
+ bool* no_add_attrs)
{
if (DECL_P (*node)
|| !CLASS_TYPE_P (*node)
@@ -1955,12 +1833,11 @@ handle_java_interface_attribute (node, name, args, flags, no_add_attrs)
/* Handle a "com_interface" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_com_interface_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_com_interface_attribute (tree* node,
+ tree name,
+ tree args ATTRIBUTE_UNUSED ,
+ int flags ATTRIBUTE_UNUSED ,
+ bool* no_add_attrs)
{
static int warned;
@@ -1985,12 +1862,11 @@ handle_com_interface_attribute (node, name, args, flags, no_add_attrs)
/* Handle an "init_priority" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_init_priority_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_init_priority_attribute (tree* node,
+ tree name,
+ tree args,
+ int flags ATTRIBUTE_UNUSED ,
+ bool* no_add_attrs)
{
tree initp_expr = TREE_VALUE (args);
tree decl = *node;
@@ -2061,9 +1937,7 @@ handle_init_priority_attribute (node, name, args, flags, no_add_attrs)
thing pointed to by the constant. */
tree
-make_ptrmem_cst (type, member)
- tree type;
- tree member;
+make_ptrmem_cst (tree type, tree member)
{
tree ptrmem_cst = make_node (PTRMEM_CST);
/* If would seem a great convenience if make_node would set
@@ -2074,16 +1948,32 @@ make_ptrmem_cst (type, member)
return ptrmem_cst;
}
+/* Build a variant of TYPE that has the indicated ATTRIBUTES. May
+ return an existing type of an appropriate type already exists. */
+
+tree
+cp_build_type_attribute_variant (tree type, tree attributes)
+{
+ tree new_type;
+
+ new_type = build_type_attribute_variant (type, attributes);
+ if (TREE_CODE (new_type) == FUNCTION_TYPE
+ && (TYPE_RAISES_EXCEPTIONS (new_type)
+ != TYPE_RAISES_EXCEPTIONS (type)))
+ new_type = build_exception_variant (new_type,
+ TYPE_RAISES_EXCEPTIONS (type));
+ return new_type;
+}
+
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
traversal. Called from walk_tree(). */
tree
-cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
- tree *tp;
- int *walk_subtrees_p;
- walk_tree_fn func;
- void *data;
- void *htab;
+cp_walk_subtrees (tree* tp,
+ int* walk_subtrees_p,
+ walk_tree_fn func,
+ void* data,
+ void* htab)
{
enum tree_code code = TREE_CODE (*tp);
tree result;
@@ -2109,7 +1999,8 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
case TEMPLATE_TYPE_PARM:
case TYPENAME_TYPE:
case TYPEOF_TYPE:
- /* None of thse have subtrees other than those already walked
+ case BASELINK:
+ /* None of these have subtrees other than those already walked
above. */
*walk_subtrees_p = 0;
break;
@@ -2120,9 +2011,7 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
break;
case TREE_LIST:
- /* A BASELINK_P's TREE_PURPOSE is a BINFO, and hence circular. */
- if (!BASELINK_P (*tp))
- WALK_SUBTREE (TREE_PURPOSE (*tp));
+ WALK_SUBTREE (TREE_PURPOSE (*tp));
break;
case OVERLOAD:
@@ -2150,25 +2039,31 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
function as a tree. */
int
-cp_cannot_inline_tree_fn (fnp)
- tree *fnp;
+cp_cannot_inline_tree_fn (tree* fnp)
{
tree fn = *fnp;
- if (flag_really_no_inline
- && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
- return 1;
-
/* We can inline a template instantiation only if it's fully
instantiated. */
if (DECL_TEMPLATE_INFO (fn)
&& TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
{
+ /* Don't instantiate functions that are not going to be
+ inlined. */
+ if (!DECL_INLINE (DECL_TEMPLATE_RESULT
+ (template_for_substitution (fn))))
+ return 1;
+
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
+
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;
}
+ if (flag_really_no_inline
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
+ return 1;
+
/* Don't auto-inline anything that might not be bound within
this unit of translation. */
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
@@ -2197,9 +2092,7 @@ cp_cannot_inline_tree_fn (fnp)
return the latest function added to the array, PREV_FN. */
tree
-cp_add_pending_fn_decls (fns_p, prev_fn)
- void *fns_p;
- tree prev_fn;
+cp_add_pending_fn_decls (void* fns_p, tree prev_fn)
{
varray_type *fnsp = (varray_type *)fns_p;
struct saved_scope *s;
@@ -2219,8 +2112,7 @@ cp_add_pending_fn_decls (fns_p, prev_fn)
function. */
int
-cp_is_overload_p (t)
- tree t;
+cp_is_overload_p (tree t)
{
return TREE_CODE (t) == OVERLOAD;
}
@@ -2229,8 +2121,7 @@ cp_is_overload_p (t)
function FN. */
int
-cp_auto_var_in_fn_p (var, fn)
- tree var, fn;
+cp_auto_var_in_fn_p (tree var, tree fn)
{
return (DECL_P (var) && DECL_CONTEXT (var) == fn
&& nonstatic_local_decl_p (var));
@@ -2241,34 +2132,33 @@ cp_auto_var_in_fn_p (var, fn)
to be used. */
tree
-cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
- need_decl, target_exprs)
- tree result, fn, caller;
- void *decl_map_;
- int *need_decl;
- void *target_exprs;
+cp_copy_res_decl_for_inlining (tree result,
+ tree fn,
+ tree caller,
+ void* decl_map_,
+ int* need_decl,
+ tree return_slot_addr)
{
splay_tree decl_map = (splay_tree)decl_map_;
- varray_type *texps = (varray_type *)target_exprs;
tree var;
- int aggregate_return_p;
-
- /* Figure out whether or not FN returns an aggregate. */
- aggregate_return_p = IS_AGGR_TYPE (TREE_TYPE (result));
- *need_decl = ! aggregate_return_p;
- /* If FN returns an aggregate then the caller will always create the
- temporary (using a TARGET_EXPR) and the call will be the
- initializing expression for the TARGET_EXPR. If we were just to
+ /* If FN returns an aggregate then the caller will always pass the
+ address of the return slot explicitly. If we were just to
create a new VAR_DECL here, then the result of this function
would be copied (bitwise) into the variable initialized by the
TARGET_EXPR. That's incorrect, so we must transform any
references to the RESULT into references to the target. */
- if (aggregate_return_p)
+
+ /* We should have an explicit return slot iff the return type is
+ TREE_ADDRESSABLE. See simplify_aggr_init_expr. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (result))
+ != (return_slot_addr != NULL_TREE))
+ abort ();
+
+ *need_decl = !return_slot_addr;
+ if (return_slot_addr)
{
- if (VARRAY_ACTIVE_SIZE (*texps) == 0)
- abort ();
- var = TREE_OPERAND (VARRAY_TOP_TREE (*texps), 0);
+ var = build_indirect_ref (return_slot_addr, "");
if (! same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (var),
TREE_TYPE (result)))
abort ();
@@ -2285,13 +2175,19 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
- DECL_NAME (var) = DECL_NAME (nrv);
- DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
- DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
- /* Don't lose initialization info. */
- DECL_INITIAL (var) = DECL_INITIAL (nrv);
- /* Don't forget that it needs to go in the stack. */
- TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
+ if (TREE_CODE (var) == VAR_DECL
+ /* But not if we're initializing a variable from the
+ enclosing function which already has its own name. */
+ && DECL_NAME (var) == NULL_TREE)
+ {
+ DECL_NAME (var) = DECL_NAME (nrv);
+ DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
+ DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
+ /* Don't lose initialization info. */
+ DECL_INITIAL (var) = DECL_INITIAL (nrv);
+ /* Don't forget that it needs to go in the stack. */
+ TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
+ }
splay_tree_insert (decl_map,
(splay_tree_key) nrv,
@@ -2302,36 +2198,11 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
return var;
}
-/* Record that we're about to start inlining FN, and return nonzero if
- that's OK. Used for lang_hooks.tree_inlining.start_inlining. */
-
-int
-cp_start_inlining (fn)
- tree fn;
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- return push_tinst_level (fn);
- else
- return 1;
-}
-
-/* Record that we're done inlining FN. Used for
- lang_hooks.tree_inlining.end_inlining. */
-
-void
-cp_end_inlining (fn)
- tree fn ATTRIBUTE_UNUSED;
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- pop_tinst_level ();
-}
-
/* Initialize tree.c. */
void
-init_tree ()
+init_tree (void)
{
- lang_statement_code_p = cp_statement_code_p;
list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
}
@@ -2340,10 +2211,9 @@ init_tree ()
pointed to by DATA (which is really a `splay_tree *'). */
static tree
-mark_local_for_remap_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+mark_local_for_remap_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
tree t = *tp;
splay_tree st = (splay_tree) data;
@@ -2386,10 +2256,9 @@ mark_local_for_remap_r (tp, walk_subtrees, data)
remaps all local declarations to appropriate replacements. */
static tree
-cp_unsave_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+cp_unsave_r (tree* tp,
+ int* walk_subtrees,
+ void* data)
{
splay_tree st = (splay_tree) data;
splay_tree_node n;
@@ -2421,8 +2290,7 @@ cp_unsave_r (tp, walk_subtrees, data)
/* Called whenever an expression needs to be unsaved. */
tree
-cxx_unsave_expr_now (tp)
- tree tp;
+cxx_unsave_expr_now (tree tp)
{
splay_tree st;
@@ -2447,8 +2315,7 @@ cxx_unsave_expr_now (tp)
predicate to test whether or not DECL is a special function. */
special_function_kind
-special_function_p (decl)
- tree decl;
+special_function_p (tree decl)
{
/* Rather than doing all this stuff with magic names, we should
probably have a field of type `special_function_kind' in
@@ -2492,8 +2359,7 @@ name_p (tree node)
/* Returns nonzero if TYPE is a character type, including wchar_t. */
int
-char_type_p (type)
- tree type;
+char_type_p (tree type)
{
return (same_type_p (type, char_type_node)
|| same_type_p (type, unsigned_char_type_node)
@@ -2509,8 +2375,7 @@ char_type_p (type)
as a global symbol when you run `nm' on the resulting object file. */
linkage_kind
-decl_linkage (decl)
- tree decl;
+decl_linkage (tree decl)
{
/* This function doesn't attempt to calculate the linkage from first
principles as given in [basic.link]. Instead, it makes use of
@@ -2549,15 +2414,13 @@ decl_linkage (decl)
expression to use the precalculated result. */
tree
-stabilize_expr (exp, initp)
- tree exp;
- tree *initp;
+stabilize_expr (tree exp, tree* initp)
{
tree init_expr;
if (!TREE_SIDE_EFFECTS (exp))
{
- init_expr = void_zero_node;
+ init_expr = NULL_TREE;
}
else if (!real_lvalue_p (exp)
|| !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
@@ -2576,16 +2439,87 @@ stabilize_expr (exp, initp)
*initp = init_expr;
return exp;
}
+
+/* Like stabilize_expr, but for a call whose args we want to
+ pre-evaluate. */
+
+void
+stabilize_call (tree call, tree *initp)
+{
+ tree inits = NULL_TREE;
+ tree t;
+
+ if (call == error_mark_node)
+ return;
+
+ if (TREE_CODE (call) != CALL_EXPR
+ && TREE_CODE (call) != AGGR_INIT_EXPR)
+ abort ();
+
+ for (t = TREE_OPERAND (call, 1); t; t = TREE_CHAIN (t))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
+ {
+ tree init;
+ TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
+ if (!init)
+ /* Nothing. */;
+ else if (inits)
+ inits = build (COMPOUND_EXPR, void_type_node, inits, init);
+ else
+ inits = init;
+ }
+
+ *initp = inits;
+}
+
+/* Like stabilize_expr, but for an initialization. If we are initializing
+ an object of class type, we don't want to introduce an extra temporary,
+ so we look past the TARGET_EXPR and stabilize the arguments of the call
+ instead. */
+
+bool
+stabilize_init (tree init, tree *initp)
+{
+ tree t = init;
+
+ if (t == error_mark_node)
+ return true;
+
+ if (TREE_CODE (t) == INIT_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
+ TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
+ else
+ {
+ if (TREE_CODE (t) == INIT_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+ if (TREE_CODE (t) == CONSTRUCTOR
+ && CONSTRUCTOR_ELTS (t) == NULL_TREE)
+ {
+ /* Default-initialization. */
+ *initp = NULL_TREE;
+ return true;
+ }
+
+ /* If the initializer is a COND_EXPR, we can't preevaluate
+ anything. */
+ if (TREE_CODE (t) == COND_EXPR)
+ return false;
+
+ stabilize_call (t, initp);
+ }
+
+ return true;
+}
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
node has been accessed improperly. */
void
-lang_check_failed (file, line, function)
- const char *file;
- int line;
- const char *function;
+lang_check_failed (const char* file, int line, const char* function)
{
internal_error ("lang_* check: failed in %s, at %s:%d",
function, trim_filename (file), line);
OpenPOWER on IntegriCloud