tree.c (build_tree_list_vec_stat): New function.

./:	* tree.c (build_tree_list_vec_stat): New function.
	(ctor_to_vec): New function.
	(build_nt_call_vec): New function.
	(build_call_array): Change args to be a const pointer.
	(build_call_vec): New function.
	* tree.h (build_nt_call_vec): Declare.
	(build_tree_list_vec_stat): Declare.
	(build_tree_list_vec): Define.
	(build_call_array): Update declaration.
	(build_call_vec): Declare.
	(ctor_to_vec): Declare.
	* c-common.c (tree_vector_cache): New static variable.
	(make_tree_vector): New function.
	(release_tree_vector): New function.
	(make_tree_vector_single): New function.
	(make_tree_vector_copy): New function.
	* c-common.h (tree_vector_cache, make_tree_vector): Declare.
	(make_tree_vector_single, make_tree_vector_copy): Declare.
	* c-parser.c (cached_expr_list_1, cached_expr_list_2): Remove.
	(c_parser_expr_list): Don't manage cache here, instead call
	make_tree_vector.
	(c_parser_release_expr_list): Remove static function.
	(c_parser_vec_to_tree_list): Remove static function.
	(c_parser_attributes): Call build_tree_list_vec instead of
	c_parser_vec_to_tree_list.  Call release_tree_vector instead of
	c_parser_release_expr_list.
	(c_parser_postfix_expression_after_primary): Likewise.
	(c_parser_objc_keywordexpr): Likewise.
cp/:
	* parser.c (cp_parser_postfix_expression): Change args to a vec.
	Release it when done.
	(tree_vector): Define typedef.  Define VEC functions.
	(cp_parser_parenthesized_expression_list): Change return type to
	vec.  Change all callers.
	(cp_parser_new_expression): Change placement and initializer to
	vecs.  Release them when done.
	(cp_parser_new_placement): Change return type to vec.  Change all
	callers.
	(cp_parser_new_initializer): Likewise.
	* typeck.c (build_function_call_vec): Just call
	cp_build_function_call_vec.
	(cp_build_function_call): Just build a vec and call
	cp_build_function_call_vec.
	(cp_build_function_call_vec): New function based on old
	cp_build_function_call.
	(convert_arguments): Remove nargs and argarray parameters.  Change
	values to a vec.  Change caller.
	(build_x_compound_expr_from_vec): New function.
	(cp_build_modify_expr): Build vec to pass to
	build_special_member_call.
	* call.c (struct z_candidate): Add first_arg field.  Change args
	field to vec.
	(convert_class_to_reference): Handle first argument separately.
	(add_candidate): Add first_arg parameter.  Change args parameter
	to vec.  Change all callers.
	(add_function_candidate, add_conv_candidate): Likewise.
	(add_template_candidate_real, add_template_candidate): Likewise.
	(add_template_conv_candidate): Likewise.
	(build_user_type_conversion_1): Handle first argument separately.
	(resolve_args): Change return type and parameter type to vecs.
	Change all callers.
	(perform_overload_resolution): Change args parameter to vec.
	Change all callers.
	(build_new_function_call, build_operator_new_call): Likewise.
	(add_candidates): Likewise.
	(build_op_call): New globally visible function, built from and
	replacing static function build_object_call.
	(build_new_op): Don't handle CALL_EXPR.  Build vec, not tree_list,
	of arguments.
	(build_op_delete_call): Build vec to pass to
	cp_build_function_call_vec.
	(build_temp): Build vec to pass to build_special_member_call.
	(convert_like_real): Likewise.
	(perform_direct_initialization_if_possible): Likewise.
	(build_over_call): Handle first_arg field.  Use build_call_array
	rather than build_call_list.
	(build_special_member_call): Change args parameter to vec.  Change
	all callers.
	(build_new_method_call): Likewise.
	* init.c (expand_default_init): Change parms to vec.
	(build_raw_new_expr): Change placement and init to vecs.  Change
	all callers.
	(build_new_1, build_new): Likewise.
	* class.c (resolve_address_of_overloaded_function): Build array to
	pass to fn_type_unification.
	* pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
	build_new.  For CALL_EXPR create a vec rather than a tree_list;
	expand a pack if necessary.
	(fn_type_unification): Change args parameter to const tree *.  Add
	nargs parameter.  Change all callers.
	(type_unification_real): Likewise.
	(unify): Build array to pass to type_unification_real.
	(get_bindings): Build array to pass to fn_type_unification.
	(any_type_dependent_arguments_p): Change args parameter to a vec.
	Change all callers.
	(make_args_non_dependent): Renamed from build_non_dependent_args.
	Change return type to void.  Change parameter type to vec.  Change
	all callers.
	(do_auto_deduction): Pass an array to type_unification_real.
	* semantics.c (perform_koenig_lookup): Change args to vec.  Change
	all callers.
	(finish_call_expr): Change args to vec.  Change all callers.  Call
	build_op_call instead of passing CALL_EXPR to build_new_op.
	(cxx_omp_create_clause_info): Allocate vec to pass to
	build_special_member_call.
	* decl2.c (build_offset_ref_call_from_tree): Change args parameter
	to vec.  Change all callers.
	* name-lookup.c (lookup_function_nonclass): Likewise.
	(struct arg_lookup): Change args to vec.
	(arg_assoc_namespace): Handle args as a vec.
	(arg_assoc_args_vec): New static function.
	(lookup_arg_dependent): Change args parameter to vec.  Change all
	callers.
	* method.c (do_build_assign_ref): Allocate vec to pass to
	build_special_member_call.
	* except.c (build_throw): Likewise.
	* typeck2.c (build_functional_cast): Likewise.
	* cvt.c (ocp_convert): Likewise.
	* tree.c (build_min_non_dep_call_vec): Change last parameter to
	vec.  Change all callers.
	* cp-tree.h: Update declarations.
	* name-lookup.h: Update declarations.
objc/:
	* objc-act.c (objc_generate_cxx_ctor_or_dtor): Pass NULL rather
	than NULL_TREE to build_special_member_call.

From-SVN: r147759
This commit is contained in:
Ian Lance Taylor 2009-05-21 05:58:39 +00:00 committed by Ian Lance Taylor
parent 40449a90d7
commit c166b8981f
25 changed files with 1405 additions and 721 deletions

View File

@ -1,3 +1,34 @@
2009-05-20 Ian Lance Taylor <iant@google.com>
* tree.c (build_tree_list_vec_stat): New function.
(ctor_to_vec): New function.
(build_nt_call_vec): New function.
(build_call_array): Change args to be a const pointer.
(build_call_vec): New function.
* tree.h (build_nt_call_vec): Declare.
(build_tree_list_vec_stat): Declare.
(build_tree_list_vec): Define.
(build_call_array): Update declaration.
(build_call_vec): Declare.
(ctor_to_vec): Declare.
* c-common.c (tree_vector_cache): New static variable.
(make_tree_vector): New function.
(release_tree_vector): New function.
(make_tree_vector_single): New function.
(make_tree_vector_copy): New function.
* c-common.h (tree_vector_cache, make_tree_vector): Declare.
(make_tree_vector_single, make_tree_vector_copy): Declare.
* c-parser.c (cached_expr_list_1, cached_expr_list_2): Remove.
(c_parser_expr_list): Don't manage cache here, instead call
make_tree_vector.
(c_parser_release_expr_list): Remove static function.
(c_parser_vec_to_tree_list): Remove static function.
(c_parser_attributes): Call build_tree_list_vec instead of
c_parser_vec_to_tree_list. Call release_tree_vector instead of
c_parser_release_expr_list.
(c_parser_postfix_expression_after_primary): Likewise.
(c_parser_objc_keywordexpr): Likewise.
2009-05-20 Sandra Loosemore <sandra@codesourcery.com>
* doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,

View File

@ -9132,4 +9132,69 @@ is_typedef_decl (tree x)
&& DECL_ORIGINAL_TYPE (x) != NULL_TREE);
}
/* The C and C++ parsers both use vectors to hold function arguments.
For efficiency, we keep a cache of unused vectors. This is the
cache. */
typedef VEC(tree,gc)* tree_gc_vec;
DEF_VEC_P(tree_gc_vec);
DEF_VEC_ALLOC_P(tree_gc_vec,gc);
static GTY((deletable)) VEC(tree_gc_vec,gc) *tree_vector_cache;
/* Return a new vector from the cache. If the cache is empty,
allocate a new vector. These vectors are GC'ed, so it is OK if the
pointer is not released.. */
VEC(tree,gc) *
make_tree_vector (void)
{
if (!VEC_empty (tree_gc_vec, tree_vector_cache))
return VEC_pop (tree_gc_vec, tree_vector_cache);
else
{
/* Passing 0 to VEC_alloc returns NULL, and our callers require
that we always return a non-NULL value. The vector code uses
4 when growing a NULL vector, so we do too. */
return VEC_alloc (tree, gc, 4);
}
}
/* Release a vector of trees back to the cache. */
void
release_tree_vector (VEC(tree,gc) *vec)
{
if (vec != NULL)
{
VEC_truncate (tree, vec, 0);
VEC_safe_push (tree_gc_vec, gc, tree_vector_cache, vec);
}
}
/* Get a new tree vector holding a single tree. */
VEC(tree,gc) *
make_tree_vector_single (tree t)
{
VEC(tree,gc) *ret = make_tree_vector ();
VEC_quick_push (tree, ret, t);
return ret;
}
/* Get a new tree vector which is a copy of an existing one. */
VEC(tree,gc) *
make_tree_vector_copy (const VEC(tree,gc) *orig)
{
VEC(tree,gc) *ret;
unsigned int ix;
tree t;
ret = make_tree_vector ();
VEC_reserve (tree, gc, ret, VEC_length (tree, orig));
for (ix = 0; VEC_iterate (tree, orig, ix, t); ++ix)
VEC_quick_push (tree, ret, t);
return ret;
}
#include "gt-c-common.h"

View File

@ -1013,6 +1013,10 @@ extern void warn_for_sign_compare (location_t,
enum tree_code resultcode);
extern void set_underlying_type (tree x);
extern bool is_typedef_decl (tree x);
extern VEC(tree,gc) *make_tree_vector (void);
extern void release_tree_vector (VEC(tree,gc) *);
extern VEC(tree,gc) *make_tree_vector_single (tree);
extern VEC(tree,gc) *make_tree_vector_copy (const VEC(tree,gc) *);
/* In c-gimplify.c */
extern void c_genericize (tree);

View File

@ -921,8 +921,6 @@ static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
VEC(tree,gc) **);
static void c_parser_release_expr_list (VEC(tree,gc) *);
static tree c_parser_vec_to_tree_list (VEC(tree,gc) *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@ -2889,9 +2887,9 @@ c_parser_attributes (c_parser *parser)
tree tree_list;
c_parser_consume_token (parser);
expr_list = c_parser_expr_list (parser, false, true, NULL);
tree_list = c_parser_vec_to_tree_list (expr_list);
tree_list = build_tree_list_vec (expr_list);
attr_args = tree_cons (NULL_TREE, arg1, tree_list);
c_parser_release_expr_list (expr_list);
release_tree_vector (expr_list);
}
}
else
@ -2901,8 +2899,8 @@ c_parser_attributes (c_parser *parser)
else
{
expr_list = c_parser_expr_list (parser, false, true, NULL);
attr_args = c_parser_vec_to_tree_list (expr_list);
c_parser_release_expr_list (expr_list);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
}
}
attr = build_tree_list (attr_name, attr_args);
@ -5719,8 +5717,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
expr.original_type = NULL;
if (exprlist != NULL)
{
c_parser_release_expr_list (exprlist);
c_parser_release_expr_list (origtypes);
release_tree_vector (exprlist);
release_tree_vector (origtypes);
}
break;
case CPP_DOT:
@ -5853,10 +5851,6 @@ c_parser_expression_conv (c_parser *parser)
nonempty-expr-list , assignment-expression
*/
/* We cache two vectors, to save most allocation and deallocation. */
static GTY((deletable)) VEC(tree,gc) *cached_expr_list_1;
static GTY((deletable)) VEC(tree,gc) *cached_expr_list_2;
static VEC(tree,gc) *
c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC(tree,gc) **p_orig_types)
@ -5865,34 +5859,11 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC(tree,gc) *orig_types;
struct c_expr expr;
if (cached_expr_list_1 != NULL)
{
ret = cached_expr_list_1;
cached_expr_list_1 = NULL;
VEC_truncate (tree, ret, 0);
}
else if (cached_expr_list_2 != NULL)
{
ret = cached_expr_list_2;
cached_expr_list_2 = NULL;
VEC_truncate (tree, ret, 0);
}
else
ret = VEC_alloc (tree, gc, 16);
ret = make_tree_vector ();
if (p_orig_types == NULL)
orig_types = NULL;
else
{
if (cached_expr_list_2 != NULL)
{
orig_types = cached_expr_list_2;
cached_expr_list_2 = NULL;
VEC_truncate (tree, orig_types, 0);
}
else
orig_types = VEC_alloc (tree, gc, 16);
}
orig_types = make_tree_vector ();
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
@ -5918,37 +5889,6 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
*p_orig_types = orig_types;
return ret;
}
/* Release a vector returned by c_parser_expr_list. */
static void
c_parser_release_expr_list (VEC(tree,gc) *vec)
{
if (cached_expr_list_1 == NULL)
cached_expr_list_1 = vec;
else if (cached_expr_list_2 == NULL)
cached_expr_list_2 = vec;
else
VEC_free (tree, gc, vec);
}
/* Convert a vector, as returned by c_parser_expr_list, to a
tree_list. */
static tree
c_parser_vec_to_tree_list (VEC(tree,gc) *vec)
{
tree ret = NULL_TREE;
tree *pp = &ret;
unsigned int i;
tree t;
for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
{
*pp = build_tree_list (NULL, t);
pp = &TREE_CHAIN (*pp);
}
return ret;
}
/* Parse Objective-C-specific constructs. */
@ -6830,9 +6770,9 @@ c_parser_objc_keywordexpr (c_parser *parser)
else
{
/* We have a comma expression, we will collapse later. */
ret = c_parser_vec_to_tree_list (expr_list);
ret = build_tree_list_vec (expr_list);
}
c_parser_release_expr_list (expr_list);
release_tree_vector (expr_list);
return ret;
}

View File

@ -1,3 +1,99 @@
2009-05-20 Ian Lance Taylor <iant@google.com>
* parser.c (cp_parser_postfix_expression): Change args to a vec.
Release it when done.
(tree_vector): Define typedef. Define VEC functions.
(cp_parser_parenthesized_expression_list): Change return type to
vec. Change all callers.
(cp_parser_new_expression): Change placement and initializer to
vecs. Release them when done.
(cp_parser_new_placement): Change return type to vec. Change all
callers.
(cp_parser_new_initializer): Likewise.
* typeck.c (build_function_call_vec): Just call
cp_build_function_call_vec.
(cp_build_function_call): Just build a vec and call
cp_build_function_call_vec.
(cp_build_function_call_vec): New function based on old
cp_build_function_call.
(convert_arguments): Remove nargs and argarray parameters. Change
values to a vec. Change caller.
(build_x_compound_expr_from_vec): New function.
(cp_build_modify_expr): Build vec to pass to
build_special_member_call.
* call.c (struct z_candidate): Add first_arg field. Change args
field to vec.
(convert_class_to_reference): Handle first argument separately.
(add_candidate): Add first_arg parameter. Change args parameter
to vec. Change all callers.
(add_function_candidate, add_conv_candidate): Likewise.
(add_template_candidate_real, add_template_candidate): Likewise.
(add_template_conv_candidate): Likewise.
(build_user_type_conversion_1): Handle first argument separately.
(resolve_args): Change return type and parameter type to vecs.
Change all callers.
(perform_overload_resolution): Change args parameter to vec.
Change all callers.
(build_new_function_call, build_operator_new_call): Likewise.
(add_candidates): Likewise.
(build_op_call): New globally visible function, built from and
replacing static function build_object_call.
(build_new_op): Don't handle CALL_EXPR. Build vec, not tree_list,
of arguments.
(build_op_delete_call): Build vec to pass to
cp_build_function_call_vec.
(build_temp): Build vec to pass to build_special_member_call.
(convert_like_real): Likewise.
(perform_direct_initialization_if_possible): Likewise.
(build_over_call): Handle first_arg field. Use build_call_array
rather than build_call_list.
(build_special_member_call): Change args parameter to vec. Change
all callers.
(build_new_method_call): Likewise.
* init.c (expand_default_init): Change parms to vec.
(build_raw_new_expr): Change placement and init to vecs. Change
all callers.
(build_new_1, build_new): Likewise.
* class.c (resolve_address_of_overloaded_function): Build array to
pass to fn_type_unification.
* pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
build_new. For CALL_EXPR create a vec rather than a tree_list;
expand a pack if necessary.
(fn_type_unification): Change args parameter to const tree *. Add
nargs parameter. Change all callers.
(type_unification_real): Likewise.
(unify): Build array to pass to type_unification_real.
(get_bindings): Build array to pass to fn_type_unification.
(any_type_dependent_arguments_p): Change args parameter to a vec.
Change all callers.
(make_args_non_dependent): Renamed from build_non_dependent_args.
Change return type to void. Change parameter type to vec. Change
all callers.
(do_auto_deduction): Pass an array to type_unification_real.
* semantics.c (perform_koenig_lookup): Change args to vec. Change
all callers.
(finish_call_expr): Change args to vec. Change all callers. Call
build_op_call instead of passing CALL_EXPR to build_new_op.
(cxx_omp_create_clause_info): Allocate vec to pass to
build_special_member_call.
* decl2.c (build_offset_ref_call_from_tree): Change args parameter
to vec. Change all callers.
* name-lookup.c (lookup_function_nonclass): Likewise.
(struct arg_lookup): Change args to vec.
(arg_assoc_namespace): Handle args as a vec.
(arg_assoc_args_vec): New static function.
(lookup_arg_dependent): Change args parameter to vec. Change all
callers.
* method.c (do_build_assign_ref): Allocate vec to pass to
build_special_member_call.
* except.c (build_throw): Likewise.
* typeck2.c (build_functional_cast): Likewise.
* cvt.c (ocp_convert): Likewise.
* tree.c (build_min_non_dep_call_vec): Change last parameter to
vec. Change all callers.
* cp-tree.h: Update declarations.
* name-lookup.h: Update declarations.
2009-05-20 Sandra Loosemore <sandra@codesourcery.com>
* typeck.c (default_conversion): Check targetm.promoted_type.

File diff suppressed because it is too large Load Diff

View File

@ -6072,6 +6072,9 @@ resolve_address_of_overloaded_function (tree target_type,
tree target_arg_types;
tree target_ret_type;
tree fns;
tree *args;
unsigned int nargs, ia;
tree arg;
if (is_ptrmem)
target_fn_type
@ -6085,6 +6088,14 @@ resolve_address_of_overloaded_function (tree target_type,
if (TREE_CODE (target_fn_type) == METHOD_TYPE)
target_arg_types = TREE_CHAIN (target_arg_types);
nargs = list_length (target_arg_types);
args = XALLOCAVEC (tree, nargs);
for (arg = target_arg_types, ia = 0;
arg != NULL_TREE && arg != void_list_node;
arg = TREE_CHAIN (arg), ++ia)
args[ia] = TREE_VALUE (arg);
nargs = ia;
for (fns = overload; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
@ -6104,9 +6115,9 @@ resolve_address_of_overloaded_function (tree target_type,
/* Try to do argument deduction. */
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
target_arg_types, target_ret_type,
DEDUCE_EXACT, LOOKUP_NORMAL))
if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
target_ret_type, DEDUCE_EXACT,
LOOKUP_NORMAL))
/* Argument deduction failed. */
continue;

View File

@ -4176,17 +4176,20 @@ extern bool null_ptr_cst_p (tree);
extern bool sufficient_parms_p (const_tree);
extern tree type_decays_to (tree);
extern tree build_user_type_conversion (tree, tree, int);
extern tree build_new_function_call (tree, tree, bool,
extern tree build_new_function_call (tree, VEC(tree,gc) **, bool,
tsubst_flags_t);
extern tree build_operator_new_call (tree, tree, tree *, tree *,
tree *);
extern tree build_new_method_call (tree, tree, tree, tree, int,
tree *, tsubst_flags_t);
extern tree build_special_member_call (tree, tree, tree, tree, int,
tsubst_flags_t);
extern tree build_operator_new_call (tree, VEC(tree,gc) **, tree *,
tree *, tree *);
extern tree build_new_method_call (tree, tree, VEC(tree,gc) **,
tree, int, tree *,
tsubst_flags_t);
extern tree build_special_member_call (tree, tree, VEC(tree,gc) **,
tree, int, tsubst_flags_t);
extern tree build_new_op (enum tree_code, int, tree,
tree, tree, bool *,
tsubst_flags_t);
extern tree build_op_call (tree, VEC(tree,gc) **,
tsubst_flags_t);
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
extern bool can_convert (tree, tree);
extern bool can_convert_arg (tree, tree, tree, int);
@ -4408,7 +4411,7 @@ extern void determine_visibility (tree);
extern void constrain_class_visibility (tree);
extern void import_export_decl (tree);
extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree);
extern tree build_offset_ref_call_from_tree (tree, VEC(tree,gc) **);
extern void check_default_args (tree);
extern void mark_used (tree);
extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
@ -4472,7 +4475,8 @@ extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree);
extern tree build_value_init_noctor (tree);
extern tree build_offset_ref (tree, tree, bool);
extern tree build_new (tree, tree, tree, tree, int,
extern tree build_new (VEC(tree,gc) **, tree, tree,
VEC(tree,gc) **, int,
tsubst_flags_t);
extern tree build_vec_init (tree, tree, tree, bool, int,
tsubst_flags_t);
@ -4554,7 +4558,8 @@ extern int uses_template_parms (tree);
extern int uses_template_parms_level (tree, int);
extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t);
extern int fn_type_unification (tree, tree, tree, tree,
extern int fn_type_unification (tree, tree, tree,
const tree *, unsigned int,
tree, unification_kind_t, int);
extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int);
@ -4592,7 +4597,7 @@ extern bool any_dependent_template_arguments_p (const_tree);
extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
extern bool any_type_dependent_arguments_p (const_tree);
extern bool any_type_dependent_arguments_p (const VEC(tree,gc) *);
extern bool type_dependent_expression_p_push (tree);
extern bool value_dependent_expression_p (tree);
extern bool any_value_dependent_elements_p (const_tree);
@ -4600,7 +4605,7 @@ extern bool dependent_omp_for_p (tree, tree, tree, tree);
extern tree resolve_typename_type (tree, bool);
extern tree template_for_substitution (tree);
extern tree build_non_dependent_expr (tree);
extern tree build_non_dependent_args (tree);
extern void make_args_non_dependent (VEC(tree,gc) *);
extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
@ -4748,9 +4753,9 @@ extern tree begin_stmt_expr (void);
extern tree finish_stmt_expr_expr (tree, tree);
extern tree finish_stmt_expr (tree, bool);
extern tree stmt_expr_value_expr (tree);
extern tree perform_koenig_lookup (tree, tree);
extern tree finish_call_expr (tree, tree, bool, bool,
tsubst_flags_t);
extern tree perform_koenig_lookup (tree, VEC(tree,gc) *);
extern tree finish_call_expr (tree, VEC(tree,gc) **, bool,
bool, tsubst_flags_t);
extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void);
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
@ -4832,7 +4837,7 @@ extern bool builtin_valid_in_constant_expr_p (const_tree);
extern tree build_min (enum tree_code, tree, ...);
extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree, ...);
extern tree build_min_non_dep_call_list (tree, tree, tree);
extern tree build_min_non_dep_call_vec (tree, tree, VEC(tree,gc) *);
extern tree build_cplus_new (tree, tree);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
@ -4932,6 +4937,8 @@ extern tree cp_build_indirect_ref (tree, const char *,
extern tree build_array_ref (tree, tree, location_t);
extern tree get_member_function_from_ptrfunc (tree *, tree);
extern tree cp_build_function_call (tree, tree, tsubst_flags_t);
extern tree cp_build_function_call_vec (tree, VEC(tree,gc) **,
tsubst_flags_t);
extern tree build_x_binary_op (enum tree_code, tree,
enum tree_code, tree,
enum tree_code, bool *,
@ -4945,6 +4952,7 @@ extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree,
tsubst_flags_t);
extern tree build_x_compound_expr_from_list (tree, const char *);
extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *);
extern tree build_x_compound_expr (tree, tree, tsubst_flags_t);
extern tree build_compound_expr (tree, tree);
extern tree cp_build_compound_expr (tree, tree, tsubst_flags_t);

View File

@ -1,6 +1,6 @@
/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@ -755,11 +755,15 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
the target with the temp (see [dcl.init]). */
ctor = build_user_type_conversion (type, ctor, flags);
else
ctor = build_special_member_call (NULL_TREE,
complete_ctor_identifier,
build_tree_list (NULL_TREE, ctor),
type, flags,
tf_warning_or_error);
{
VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
ctor = build_special_member_call (NULL_TREE,
complete_ctor_identifier,
&ctor_vec,
type, flags,
tf_warning_or_error);
release_tree_vector (ctor_vec);
}
if (ctor)
return build_cplus_new (type, ctor);
}

View File

@ -3680,18 +3680,18 @@ cp_write_global_declarations (void)
/* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
function to call in parse-tree form; it has not yet been
semantically analyzed. ARGS are the arguments to the function.
They have already been semantically analyzed. */
They have already been semantically analyzed. This may change
ARGS. */
tree
build_offset_ref_call_from_tree (tree fn, tree args)
build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
{
tree orig_fn;
tree orig_args;
VEC(tree,gc) *orig_args = NULL;
tree expr;
tree object;
orig_fn = fn;
orig_args = args;
object = TREE_OPERAND (fn, 0);
if (processing_template_decl)
@ -3699,17 +3699,19 @@ build_offset_ref_call_from_tree (tree fn, tree args)
gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
|| TREE_CODE (fn) == MEMBER_REF);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
return build_nt_call_list (fn, args);
|| any_type_dependent_arguments_p (*args))
return build_nt_call_vec (fn, *args);
orig_args = make_tree_vector_copy (*args);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
because we depend on the form of FN. */
args = build_non_dependent_args (args);
make_args_non_dependent (*args);
object = build_non_dependent_expr (object);
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
args = tree_cons (NULL_TREE, object, args);
VEC_safe_insert (tree, gc, *args, 0, object);
/* Now that the arguments are done, transform FN. */
fn = build_non_dependent_expr (fn);
}
@ -3726,12 +3728,16 @@ build_offset_ref_call_from_tree (tree fn, tree args)
tf_warning_or_error);
fn = TREE_OPERAND (fn, 1);
fn = get_member_function_from_ptrfunc (&object_addr, fn);
args = tree_cons (NULL_TREE, object_addr, args);
VEC_safe_insert (tree, gc, *args, 0, object_addr);
}
expr = cp_build_function_call (fn, args, tf_warning_or_error);
expr = cp_build_function_call_vec (fn, args, tf_warning_or_error);
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep_call_list (expr, orig_fn, orig_args);
expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
if (orig_args != NULL)
release_tree_vector (orig_args);
return expr;
}

View File

@ -1,6 +1,6 @@
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
@ -736,6 +736,7 @@ build_throw (tree exp)
if (CLASS_TYPE_P (temp_type))
{
int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
VEC(tree,gc) *exp_vec;
/* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
treated as an rvalue for the purposes of overload resolution
@ -749,11 +750,11 @@ build_throw (tree exp)
flags = flags | LOOKUP_PREFER_RVALUE;
/* Call the copy constructor. */
exp_vec = make_tree_vector_single (exp);
exp = (build_special_member_call
(object, complete_ctor_identifier,
build_tree_list (NULL_TREE, exp),
TREE_TYPE (object),
flags, tf_warning_or_error));
(object, complete_ctor_identifier, &exp_vec,
TREE_TYPE (object), flags, tf_warning_or_error));
release_tree_vector (exp_vec);
if (exp == error_mark_node)
{
error (" in thrown expression");

View File

@ -302,7 +302,7 @@ build_value_init (tree type)
return build_aggr_init_expr
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL,
NULL, type, LOOKUP_NORMAL,
tf_warning_or_error));
else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
{
@ -312,7 +312,7 @@ build_value_init (tree type)
This will be handled in simplify_aggr_init_expr. */
tree ctor = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
NULL, type, LOOKUP_NORMAL, tf_warning_or_error);
ctor = build_aggr_init_expr (type, ctor);
AGGR_INIT_ZERO_FIRST (ctor) = 1;
@ -951,7 +951,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
/* Call the destructor. */
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
NULL_TREE,
NULL,
binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
@ -1285,7 +1285,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
followed by initialization by X. If neither of these work
out, then look hard. */
tree rval;
tree parms;
VEC(tree,gc) *parms;
if (init && TREE_CODE (init) != TREE_LIST
&& (flags & LOOKUP_ONLYCONVERTING))
@ -1325,23 +1325,28 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
return;
}
if (init == NULL_TREE
|| (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
if (init == NULL_TREE)
parms = NULL;
else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
{
parms = init;
if (parms)
init = TREE_VALUE (parms);
parms = make_tree_vector ();
for (; init != NULL_TREE; init = TREE_CHAIN (init))
VEC_safe_push (tree, gc, parms, TREE_VALUE (init));
}
else
parms = build_tree_list (NULL_TREE, init);
parms = make_tree_vector_single (init);
if (true_exp == exp)
ctor_name = complete_ctor_identifier;
else
ctor_name = base_ctor_identifier;
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags,
rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
complain);
if (parms != NULL)
release_tree_vector (parms);
if (TREE_SIDE_EFFECTS (rval))
finish_expr_stmt (convert_to_void (rval, NULL, complain));
}
@ -1706,18 +1711,31 @@ build_builtin_delete_call (tree addr)
the type of the object being allocated; otherwise, it's just TYPE.
INIT is the initializer, if any. USE_GLOBAL_NEW is true if the
user explicitly wrote "::operator new". PLACEMENT, if non-NULL, is
the TREE_LIST of arguments to be provided as arguments to a
placement new operator. This routine performs no semantic checks;
it just creates and returns a NEW_EXPR. */
a vector of arguments to be provided as arguments to a placement
new operator. This routine performs no semantic checks; it just
creates and returns a NEW_EXPR. */
static tree
build_raw_new_expr (tree placement, tree type, tree nelts, tree init,
int use_global_new)
build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
VEC(tree,gc) *init, int use_global_new)
{
tree init_list;
tree new_expr;
new_expr = build4 (NEW_EXPR, build_pointer_type (type), placement, type,
nelts, init);
/* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
If INIT is not NULL, then we want to store VOID_ZERO_NODE. This
permits us to distinguish the case of a missing initializer "new
int" from an empty initializer "new int()". */
if (init == NULL)
init_list = NULL_TREE;
else if (VEC_empty (tree, init))
init_list = void_zero_node;
else
init_list = build_tree_list_vec (init);
new_expr = build4 (NEW_EXPR, build_pointer_type (type),
build_tree_list_vec (placement), type, nelts,
init_list);
NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
TREE_SIDE_EFFECTS (new_expr) = 1;
@ -1776,11 +1794,12 @@ avoid_placement_new_aliasing (tree t, tree placement)
/* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for
build_raw_new_expr. */
build_raw_new_expr. This may change PLACEMENT and INIT. */
static tree
build_new_1 (tree placement, tree type, tree nelts, tree init,
bool globally_qualified_p, tsubst_flags_t complain)
build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
VEC(tree,gc) **init, bool globally_qualified_p,
tsubst_flags_t complain)
{
tree size, rval;
/* True iff this is a call to "operator new[]" instead of just
@ -1807,11 +1826,12 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
beginning of the storage allocated for an array-new expression in
order to store the number of elements. */
tree cookie_size = NULL_TREE;
bool have_placement;
tree placement_first;
tree placement_expr = NULL_TREE;
/* True if the function we are calling is a placement allocation
function. */
bool placement_allocation_fn_p;
tree args = NULL_TREE;
/* True if the storage must be initialized, either by a constructor
or due to an explicit new-initializer. */
bool is_initialized;
@ -1855,9 +1875,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (abstract_virtuals_error (NULL_TREE, elt_type))
return error_mark_node;
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
if (CP_TYPE_CONST_P (elt_type) && !init
if (CP_TYPE_CONST_P (elt_type) && *init == NULL
&& !type_has_user_provided_default_constructor (elt_type))
{
if (complain & tf_error)
@ -1871,8 +1891,18 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
alloc_fn = NULL_TREE;
/* If PLACEMENT is a single simple pointer type not passed by
reference, prepare to capture it in a temporary variable. Do
this now, since PLACEMENT will change in the calls below. */
have_placement = !VEC_empty (tree, *placement);
placement_first = NULL_TREE;
if (VEC_length (tree, *placement) == 1
&& (TREE_CODE (TREE_TYPE (VEC_index (tree, *placement, 0)))
== POINTER_TYPE))
placement_first = VEC_index (tree, *placement, 0);
/* Allocate the object. */
if (! placement && TYPE_FOR_JAVA (elt_type))
if (VEC_empty (tree, *placement) && TYPE_FOR_JAVA (elt_type))
{
tree class_addr;
tree class_decl = build_java_class_ref (elt_type);
@ -1928,7 +1958,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
size = size_binop (PLUS_EXPR, size, cookie_size);
}
/* Create the argument list. */
args = tree_cons (NULL_TREE, size, placement);
VEC_safe_insert (tree, gc, *placement, 0, size);
/* Do name-lookup to find the appropriate operator. */
fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
if (fns == NULL_TREE)
@ -1947,7 +1977,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
}
alloc_call = build_new_method_call (build_dummy_object (elt_type),
fns, args,
fns, placement,
/*conversion_path=*/NULL_TREE,
LOOKUP_NORMAL,
&alloc_fn,
@ -1973,12 +2003,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
gcc_assert (alloc_fn != NULL_TREE);
/* If PLACEMENT is a simple pointer type and is not passed by reference,
then copy it into PLACEMENT_EXPR. */
/* If we found a simple case of PLACEMENT_EXPR above, then copy it
into a temporary variable. */
if (!processing_template_decl
&& placement != NULL_TREE
&& TREE_CHAIN (placement) == NULL_TREE
&& TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) == POINTER_TYPE
&& placement_first != NULL_TREE
&& TREE_CODE (alloc_call) == CALL_EXPR
&& call_expr_nargs (alloc_call) == 2
&& TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
@ -1989,7 +2017,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
|| VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
{
placement_expr = get_target_expr (TREE_VALUE (placement));
placement_expr = get_target_expr (placement_first);
CALL_EXPR_ARG (alloc_call, 1)
= convert (TREE_TYPE (placement_arg), placement_expr);
}
@ -2000,7 +2028,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (!cookie_size && !is_initialized)
{
rval = build_nop (pointer_type, alloc_call);
if (placement != NULL)
if (have_placement)
rval = avoid_placement_new_aliasing (rval, placement_expr);
return rval;
}
@ -2109,15 +2137,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
bool stable;
bool explicit_value_init_p = false;
if (init == void_zero_node)
if (*init != NULL && VEC_empty (tree, *init))
{
init = NULL_TREE;
*init = NULL;
explicit_value_init_p = true;
}
if (array_p)
{
if (init)
if (*init)
{
if (complain & tf_error)
permerror (input_location, "ISO C++ forbids initialization in array new");
@ -2130,7 +2158,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
MINUS_EXPR, outer_nelts,
integer_one_node,
complain),
init,
build_tree_list_vec (*init),
explicit_value_init_p,
/*from_array=*/0,
complain);
@ -2160,17 +2188,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
else
{
tree ie;
/* We are processing something like `new int (10)', which
means allocate an int, and initialize it with 10. */
if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init,
"new initializer");
else
gcc_assert (TREE_CODE (init) != CONSTRUCTOR
|| TREE_TYPE (init) != NULL_TREE);
init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
ie = build_x_compound_expr_from_vec (*init, "new initializer");
init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
complain);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
@ -2283,60 +2307,58 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* A new-expression is never an lvalue. */
gcc_assert (!lvalue_p (rval));
if (placement != NULL)
if (have_placement)
rval = avoid_placement_new_aliasing (rval, placement_expr);
return rval;
}
/* Generate a representation for a C++ "new" expression. PLACEMENT is
a TREE_LIST of placement-new arguments (or NULL_TREE if none). If
NELTS is NULL, TYPE is the type of the storage to be allocated. If
NELTS is not NULL, then this is an array-new allocation; TYPE is
the type of the elements in the array and NELTS is the number of
elements in the array. INIT, if non-NULL, is the initializer for
the new object, or void_zero_node to indicate an initializer of
"()". If USE_GLOBAL_NEW is true, then the user explicitly wrote
"::new" rather than just "new". */
/* Generate a representation for a C++ "new" expression. *PLACEMENT
is a vector of placement-new arguments (or NULL if none). If NELTS
is NULL, TYPE is the type of the storage to be allocated. If NELTS
is not NULL, then this is an array-new allocation; TYPE is the type
of the elements in the array and NELTS is the number of elements in
the array. *INIT, if non-NULL, is the initializer for the new
object, or an empty vector to indicate an initializer of "()". If
USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
rather than just "new". This may change PLACEMENT and INIT. */
tree
build_new (tree placement, tree type, tree nelts, tree init,
int use_global_new, tsubst_flags_t complain)
build_new (VEC(tree,gc) **placement, tree type, tree nelts,
VEC(tree,gc) **init, int use_global_new, tsubst_flags_t complain)
{
tree rval;
tree orig_placement;
tree orig_nelts;
tree orig_init;
VEC(tree,gc) *orig_placement = NULL;
tree orig_nelts = NULL_TREE;
VEC(tree,gc) *orig_init = NULL;
if (placement == error_mark_node || type == error_mark_node
|| init == error_mark_node)
if (type == error_mark_node)
return error_mark_node;
orig_placement = placement;
orig_nelts = nelts;
orig_init = init;
if (nelts == NULL_TREE && init != void_zero_node && list_length (init) == 1)
if (nelts == NULL_TREE && VEC_length (tree, *init) == 1)
{
tree auto_node = type_uses_auto (type);
if (auto_node && describable_type (TREE_VALUE (init)))
type = do_auto_deduction (type, TREE_VALUE (init), auto_node);
if (auto_node && describable_type (VEC_index (tree, *init, 0)))
type = do_auto_deduction (type, VEC_index (tree, *init, 0), auto_node);
}
if (processing_template_decl)
{
if (dependent_type_p (type)
|| any_type_dependent_arguments_p (placement)
|| any_type_dependent_arguments_p (*placement)
|| (nelts && type_dependent_expression_p (nelts))
|| (init != void_zero_node
&& any_type_dependent_arguments_p (init)))
return build_raw_new_expr (placement, type, nelts, init,
|| any_type_dependent_arguments_p (*init))
return build_raw_new_expr (*placement, type, nelts, *init,
use_global_new);
placement = build_non_dependent_args (placement);
orig_placement = make_tree_vector_copy (*placement);
orig_nelts = nelts;
orig_init = make_tree_vector_copy (*init);
make_args_non_dependent (*placement);
if (nelts)
nelts = build_non_dependent_expr (nelts);
if (init != void_zero_node)
init = build_non_dependent_args (init);
make_args_non_dependent (*init);
}
if (nelts)
@ -2381,8 +2403,13 @@ build_new (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
if (processing_template_decl)
return build_raw_new_expr (orig_placement, type, orig_nelts, orig_init,
use_global_new);
{
tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
orig_init, use_global_new);
release_tree_vector (orig_placement);
release_tree_vector (orig_init);
return ret;
}
/* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
@ -2954,7 +2981,7 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
}
fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
return build_new_method_call (exp, fn,
/*args=*/NULL_TREE,
/*args=*/NULL,
/*conversion_path=*/NULL_TREE,
flags,
/*fn_p=*/NULL,
@ -3172,7 +3199,7 @@ push_base_cleanups (void)
{
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
NULL_TREE,
NULL,
base_binfo,
(LOOKUP_NORMAL
| LOOKUP_NONVIRTUAL),
@ -3194,7 +3221,7 @@ push_base_cleanups (void)
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
NULL_TREE, base_binfo,
NULL, base_binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
finish_decl_cleanup (NULL_TREE, expr);

View File

@ -1,7 +1,7 @@
/* Handle the hair of processing (but not expanding) inline functions.
Also manage function and variable name overloading.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
@ -661,19 +661,21 @@ do_build_assign_ref (tree fndecl)
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
tree converted_parm;
VEC(tree,gc) *parmvec;
/* We must convert PARM directly to the base class
explicitly since the base class may be ambiguous. */
converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
/* Call the base class assignment operator. */
parmvec = make_tree_vector_single (converted_parm);
finish_expr_stmt
(build_special_member_call (current_class_ref,
ansi_assopname (NOP_EXPR),
build_tree_list (NULL_TREE,
converted_parm),
&parmvec,
base_binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error));
release_tree_vector (parmvec);
}
/* Assign to each of the non-static data members. */

View File

@ -4235,7 +4235,7 @@ lookup_name_nonclass (tree name)
}
tree
lookup_function_nonclass (tree name, tree args, bool block_p)
lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
{
return
lookup_arg_dependent (name,
@ -4427,7 +4427,7 @@ lookup_type_current_level (tree name)
struct arg_lookup
{
tree name;
tree args;
VEC(tree,gc) *args;
tree namespaces;
tree classes;
tree functions;
@ -4435,6 +4435,7 @@ struct arg_lookup
static bool arg_assoc (struct arg_lookup*, tree);
static bool arg_assoc_args (struct arg_lookup*, tree);
static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool add_function (struct arg_lookup *, tree);
static bool arg_assoc_namespace (struct arg_lookup *, tree);
@ -4589,13 +4590,13 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
classes. */
if (hidden_name_p (OVL_CURRENT (value)))
{
tree args;
unsigned int ix;
tree arg;
for (args = k->args; args; args = TREE_CHAIN (args))
if (friend_of_associated_class_p (TREE_VALUE (args),
OVL_CURRENT (value)))
for (ix = 0; VEC_iterate (tree, k->args, ix, arg); ++ix)
if (friend_of_associated_class_p (arg, OVL_CURRENT (value)))
break;
if (!args)
if (ix >= VEC_length (tree, k->args))
continue;
}
@ -4805,6 +4806,21 @@ arg_assoc_args (struct arg_lookup *k, tree args)
return false;
}
/* Adds everything associated with an argument vector. Returns true
on error. */
static bool
arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
{
unsigned int ix;
tree arg;
for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
if (arg_assoc (k, arg))
return true;
return false;
}
/* Adds everything associated with a given tree_node. Returns 1 on error. */
static bool
@ -4884,7 +4900,7 @@ arg_assoc (struct arg_lookup *k, tree n)
are the functions found in normal lookup. */
tree
lookup_arg_dependent (tree name, tree fns, tree args)
lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
{
struct arg_lookup k;
@ -4907,7 +4923,7 @@ lookup_arg_dependent (tree name, tree fns, tree args)
picking up later definitions) in the second stage. */
k.namespaces = NULL_TREE;
arg_assoc_args (&k, args);
arg_assoc_args_vec (&k, args);
fns = k.functions;

View File

@ -1,5 +1,6 @@
/* Declarations for C++ name lookup routines.
Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@ -317,7 +318,7 @@ extern tree remove_hidden_names (tree);
extern tree lookup_qualified_name (tree, tree, bool, bool);
extern tree lookup_name_nonclass (tree);
extern tree lookup_name_innermost_nonclass_level (tree);
extern tree lookup_function_nonclass (tree, tree, bool);
extern tree lookup_function_nonclass (tree, VEC(tree,gc) *, bool);
extern void push_local_binding (tree, tree, int);
extern bool pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree, bool);
@ -332,7 +333,7 @@ extern void do_toplevel_using_decl (tree, tree, tree);
extern void do_local_using_decl (tree, tree, tree);
extern tree do_class_using_decl (tree, tree);
extern void do_using_directive (tree);
extern tree lookup_arg_dependent (tree, tree, tree);
extern tree lookup_arg_dependent (tree, tree, VEC(tree,gc) *);
extern bool is_associated_namespace (tree, tree);
extern void parse_using_directive (tree, tree);
extern tree innermost_non_namespace_value (tree);

View File

@ -1584,7 +1584,7 @@ static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static tree cp_parser_parenthesized_expression_list
static VEC(tree,gc) *cp_parser_parenthesized_expression_list
(cp_parser *, bool, bool, bool, bool *);
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
@ -1594,7 +1594,7 @@ static enum tree_code cp_parser_unary_operator
(cp_token *);
static tree cp_parser_new_expression
(cp_parser *);
static tree cp_parser_new_placement
static VEC(tree,gc) *cp_parser_new_placement
(cp_parser *);
static tree cp_parser_new_type_id
(cp_parser *, tree *);
@ -1602,7 +1602,7 @@ static cp_declarator *cp_parser_new_declarator_opt
(cp_parser *);
static cp_declarator *cp_parser_direct_new_declarator
(cp_parser *);
static tree cp_parser_new_initializer
static VEC(tree,gc) *cp_parser_new_initializer
(cp_parser *);
static tree cp_parser_delete_expression
(cp_parser *);
@ -4685,7 +4685,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
bool is_builtin_constant_p;
bool saved_integral_constant_expression_p = false;
bool saved_non_integral_constant_expression_p = false;
tree args;
VEC(tree,gc) *args;
is_member_access = false;
@ -4713,7 +4713,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
= saved_non_integral_constant_expression_p;
}
if (args == error_mark_node)
if (args == NULL)
{
postfix_expression = error_mark_node;
break;
@ -4726,6 +4726,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
"a function call"))
{
postfix_expression = error_mark_node;
release_tree_vector (args);
break;
}
@ -4735,7 +4736,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
{
if (args)
if (!VEC_empty (tree, args))
{
koenig_p = true;
if (!any_type_dependent_arguments_p (args))
@ -4749,7 +4750,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* We do not perform argument-dependent lookup if
normal lookup finds a non-function, in accordance
with the expected resolution of DR 218. */
else if (args && is_overloaded_fn (postfix_expression))
else if (!VEC_empty (tree, args)
&& is_overloaded_fn (postfix_expression))
{
tree fn = get_first_fn (postfix_expression);
@ -4782,7 +4784,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|| any_type_dependent_arguments_p (args)))
{
postfix_expression
= build_nt_call_list (postfix_expression, args);
= build_nt_call_vec (postfix_expression, args);
release_tree_vector (args);
break;
}
@ -4790,7 +4793,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
postfix_expression
= (build_new_method_call
(instance, fn, args, NULL_TREE,
(instance, fn, &args, NULL_TREE,
(idk == CP_ID_KIND_QUALIFIED
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
/*fn_p=*/NULL,
@ -4798,7 +4801,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
else
postfix_expression
= finish_call_expr (postfix_expression, args,
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
/*koenig_p=*/false,
tf_warning_or_error);
@ -4807,25 +4810,27 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|| TREE_CODE (postfix_expression) == MEMBER_REF
|| TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
postfix_expression = (build_offset_ref_call_from_tree
(postfix_expression, args));
(postfix_expression, &args));
else if (idk == CP_ID_KIND_QUALIFIED)
/* A call to a static class member, or a namespace-scope
function. */
postfix_expression
= finish_call_expr (postfix_expression, args,
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/true,
koenig_p,
tf_warning_or_error);
else
/* All other function calls. */
postfix_expression
= finish_call_expr (postfix_expression, args,
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
koenig_p,
tf_warning_or_error);
/* The POSTFIX_EXPRESSION is certainly no longer an id. */
idk = CP_ID_KIND_NONE;
release_tree_vector (args);
}
break;
@ -5132,24 +5137,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
ALLOW_EXPANSION_P is true if this expression allows expansion of an
argument pack.
Returns a TREE_LIST. The TREE_VALUE of each node is a
representation of an assignment-expression. Note that a TREE_LIST
is returned even if there is only a single expression in the list.
error_mark_node is returned if the ( and or ) are
missing. NULL_TREE is returned on no expressions. The parentheses
are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute
list being parsed. If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P
indicates whether or not all of the expressions in the list were
constant. */
Returns a vector of trees. Each element is a representation of an
assignment-expression. NULL is returned if the ( and or ) are
missing. An empty, but allocated, vector is returned on no
expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is true
if this is really an attribute list being parsed. If
NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
not all of the expressions in the list were constant. */
static tree
static VEC(tree,gc) *
cp_parser_parenthesized_expression_list (cp_parser* parser,
bool is_attribute_list,
bool cast_p,
bool allow_expansion_p,
bool *non_constant_p)
{
tree expression_list = NULL_TREE;
VEC(tree,gc) *expression_list;
bool fold_expr_p = is_attribute_list;
tree identifier = NULL_TREE;
bool saved_greater_than_is_operator_p;
@ -5159,7 +5162,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return error_mark_node;
return NULL;
expression_list = make_tree_vector ();
/* Within a parenthesized expression, a `>' token is always
the greater-than operator. */
@ -5228,7 +5233,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
expressions to the list, so that we can still tell if
the correct form for a parenthesized expression-list
is found. That gives better errors. */
expression_list = tree_cons (NULL_TREE, expr, expression_list);
VEC_safe_push (tree, gc, expression_list, expr);
if (expr == error_mark_node)
goto skip_comma;
@ -5264,17 +5269,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
{
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
return error_mark_node;
return NULL;
}
}
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
/* We built up the list in reverse order so we must reverse it now. */
expression_list = nreverse (expression_list);
if (identifier)
expression_list = tree_cons (NULL_TREE, identifier, expression_list);
VEC_safe_insert (tree, gc, expression_list, 0, identifier);
return expression_list;
}
@ -5618,10 +5621,11 @@ static tree
cp_parser_new_expression (cp_parser* parser)
{
bool global_scope_p;
tree placement;
VEC(tree,gc) *placement;
tree type;
tree initializer;
VEC(tree,gc) *initializer;
tree nelts;
tree ret;
/* Look for the optional `::' operator. */
global_scope_p
@ -5637,7 +5641,11 @@ cp_parser_new_expression (cp_parser* parser)
placement = cp_parser_new_placement (parser);
/* If that didn't work out, there's no new-placement. */
if (!cp_parser_parse_definitely (parser))
placement = NULL_TREE;
{
if (placement != NULL)
release_tree_vector (placement);
placement = NULL;
}
/* If the next token is a `(', then we have a parenthesized
type-id. */
@ -5673,16 +5681,25 @@ cp_parser_new_expression (cp_parser* parser)
|| cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
initializer = cp_parser_new_initializer (parser);
else
initializer = NULL_TREE;
initializer = NULL;
/* A new-expression may not appear in an integral constant
expression. */
if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
return error_mark_node;
ret = error_mark_node;
else
{
/* Create a representation of the new-expression. */
ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
tf_warning_or_error);
}
/* Create a representation of the new-expression. */
return build_new (placement, type, nelts, initializer, global_scope_p,
tf_warning_or_error);
if (placement != NULL)
release_tree_vector (placement);
if (initializer != NULL)
release_tree_vector (initializer);
return ret;
}
/* Parse a new-placement.
@ -5692,10 +5709,10 @@ cp_parser_new_expression (cp_parser* parser)
Returns the same representation as for an expression-list. */
static tree
static VEC(tree,gc) *
cp_parser_new_placement (cp_parser* parser)
{
tree expression_list;
VEC(tree,gc) *expression_list;
/* Parse the expression-list. */
expression_list = (cp_parser_parenthesized_expression_list
@ -5885,28 +5902,26 @@ cp_parser_direct_new_declarator (cp_parser* parser)
( expression-list [opt] )
braced-init-list
Returns a representation of the expression-list. If there is no
expression-list, VOID_ZERO_NODE is returned. */
Returns a representation of the expression-list. */
static tree
static VEC(tree,gc) *
cp_parser_new_initializer (cp_parser* parser)
{
tree expression_list;
VEC(tree,gc) *expression_list;
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
tree t;
bool expr_non_constant_p;
maybe_warn_cpp0x ("extended initializer lists");
expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
expression_list = build_tree_list (NULL_TREE, expression_list);
t = cp_parser_braced_list (parser, &expr_non_constant_p);
CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
expression_list = make_tree_vector_single (t);
}
else
expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL));
if (!expression_list)
expression_list = void_zero_node;
return expression_list;
}
@ -9225,11 +9240,18 @@ cp_parser_mem_initializer (cp_parser* parser)
expression_list = build_tree_list (NULL_TREE, expression_list);
}
else
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
{
VEC(tree,gc)* vec;
vec = cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
if (vec == NULL)
return error_mark_node;
expression_list = build_tree_list_vec (vec);
release_tree_vector (vec);
}
if (expression_list == error_mark_node)
return error_mark_node;
if (!expression_list)
@ -14585,10 +14607,17 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
init = cp_parser_initializer_clause (parser, non_constant_p);
}
else if (token->type == CPP_OPEN_PAREN)
init = cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
non_constant_p);
{
VEC(tree,gc) *vec;
vec = cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
non_constant_p);
if (vec == NULL)
return error_mark_node;
init = build_tree_list_vec (vec);
release_tree_vector (vec);
}
else if (token->type == CPP_OPEN_BRACE)
{
maybe_warn_cpp0x ("extended initializer lists");
@ -16850,10 +16879,18 @@ cp_parser_attribute_list (cp_parser* parser)
/* If it's an `(', then parse the attribute arguments. */
if (token->type == CPP_OPEN_PAREN)
{
arguments = cp_parser_parenthesized_expression_list
(parser, true, /*cast_p=*/false,
/*allow_expansion_p=*/false,
/*non_constant_p=*/NULL);
VEC(tree,gc) *vec;
vec = cp_parser_parenthesized_expression_list
(parser, true, /*cast_p=*/false,
/*allow_expansion_p=*/false,
/*non_constant_p=*/NULL);
if (vec == NULL)
arguments = error_mark_node;
else
{
arguments = build_tree_list_vec (vec);
release_tree_vector (vec);
}
/* Save the arguments away. */
TREE_VALUE (attribute) = arguments;
}
@ -17981,6 +18018,7 @@ cp_parser_simple_cast_expression (cp_parser *parser)
static tree
cp_parser_functional_cast (cp_parser* parser, tree type)
{
VEC(tree,gc) *vec;
tree expression_list;
tree cast;
bool nonconst_p;
@ -17995,11 +18033,18 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
return finish_compound_literal (type, expression_list);
}
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/true,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
vec = cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/true,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
if (vec == NULL)
expression_list = error_mark_node;
else
{
expression_list = build_tree_list_vec (vec);
release_tree_vector (vec);
}
cast = build_functional_cast (type, expression_list,
tf_warning_or_error);

View File

@ -118,8 +118,8 @@ static tree add_outermost_template_args (tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree);
static int type_unification_real (tree, tree, tree, tree,
int, unification_kind_t, int);
static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t, int);
static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree);
static tree convert_nontype_argument (tree, tree);
@ -11430,24 +11430,54 @@ tsubst_copy_and_build (tree t,
case NEW_EXPR:
{
tree placement = RECUR (TREE_OPERAND (t, 0));
tree init = RECUR (TREE_OPERAND (t, 3));
VEC(tree,gc) *placement_vec;
VEC(tree,gc) *init_vec;
tree ret;
if (TREE_OPERAND (t, 3) && !init)
/* If there was an initializer in the original tree, but
it instantiated to an empty list, then we should pass on
VOID_ZERO_NODE to tell build_new that it was an empty
initializer () rather than no initializer. This can only
happen when the initializer is a pack expansion whose
parameter packs are of length zero. */
init = void_zero_node;
if (placement == NULL_TREE)
placement_vec = NULL;
else
{
placement_vec = make_tree_vector ();
for (; placement != NULL_TREE; placement = TREE_CHAIN (placement))
VEC_safe_push (tree, gc, placement_vec, TREE_VALUE (placement));
}
return build_new
(RECUR (TREE_OPERAND (t, 0)),
RECUR (TREE_OPERAND (t, 1)),
RECUR (TREE_OPERAND (t, 2)),
init,
NEW_EXPR_USE_GLOBAL (t),
complain);
/* If there was an initializer in the original tree, but it
instantiated to an empty list, then we should pass a
non-NULL empty vector to tell build_new that it was an
empty initializer() rather than no initializer. This can
only happen when the initializer is a pack expansion whose
parameter packs are of length zero. */
if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE)
init_vec = NULL;
else
{
init_vec = make_tree_vector ();
if (init == void_zero_node)
gcc_assert (init_vec != NULL);
else
{
for (; init != NULL_TREE; init = TREE_CHAIN (init))
VEC_safe_push (tree, gc, init_vec, TREE_VALUE (init));
}
}
ret = build_new (&placement_vec,
RECUR (TREE_OPERAND (t, 1)),
RECUR (TREE_OPERAND (t, 2)),
&init_vec,
NEW_EXPR_USE_GLOBAL (t),
complain);
if (placement_vec != NULL)
release_tree_vector (placement_vec);
if (init_vec != NULL)
release_tree_vector (init_vec);
return ret;
}
case DELETE_EXPR:
@ -11465,9 +11495,11 @@ tsubst_copy_and_build (tree t,
case CALL_EXPR:
{
tree function;
tree call_args;
VEC(tree,gc) *call_args;
unsigned int nargs, i;
bool qualified_p;
bool koenig_p;
tree ret;
function = CALL_EXPR_FN (t);
/* When we parsed the expression, we determined whether or
@ -11502,8 +11534,40 @@ tsubst_copy_and_build (tree t,
qualified_p = true;
}
/* FIXME: Rewrite this so as not to construct an arglist. */
call_args = RECUR (CALL_EXPR_ARGS (t));
nargs = call_expr_nargs (t);
call_args = make_tree_vector ();
for (i = 0; i < nargs; ++i)
{
tree arg = CALL_EXPR_ARG (t, i);
if (!PACK_EXPANSION_P (arg))
VEC_safe_push (tree, gc, call_args,
RECUR (CALL_EXPR_ARG (t, i)));
else
{
/* Expand the pack expansion and push each entry onto
CALL_ARGS. */
arg = tsubst_pack_expansion (arg, args, complain, in_decl);
if (TREE_CODE (arg) == TREE_VEC)
{
unsigned int len, j;
len = TREE_VEC_LENGTH (arg);
for (j = 0; j < len; ++j)
{
tree value = TREE_VEC_ELT (arg, j);
if (value != NULL_TREE)
value = convert_from_reference (value);
VEC_safe_push (tree, gc, call_args, value);
}
}
else
{
/* A partial substitution. Add one entry. */
VEC_safe_push (tree, gc, call_args, arg);
}
}
}
/* We do not perform argument-dependent lookup if normal
lookup finds a non-function, in accordance with the
@ -11524,6 +11588,7 @@ tsubst_copy_and_build (tree t,
if (TREE_CODE (function) == IDENTIFIER_NODE)
{
unqualified_name_lookup_error (function);
release_tree_vector (call_args);
return error_mark_node;
}
@ -11532,27 +11597,32 @@ tsubst_copy_and_build (tree t,
mark_used (function);
if (TREE_CODE (function) == OFFSET_REF)
return build_offset_ref_call_from_tree (function, call_args);
if (TREE_CODE (function) == COMPONENT_REF)
ret = build_offset_ref_call_from_tree (function, &call_args);
else if (TREE_CODE (function) == COMPONENT_REF)
{
if (!BASELINK_P (TREE_OPERAND (function, 1)))
return finish_call_expr (function, call_args,
ret = finish_call_expr (function, &call_args,
/*disallow_virtual=*/false,
/*koenig_p=*/false,
complain);
else
return (build_new_method_call
ret = (build_new_method_call
(TREE_OPERAND (function, 0),
TREE_OPERAND (function, 1),
call_args, NULL_TREE,
&call_args, NULL_TREE,
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
/*fn_p=*/NULL,
complain));
}
return finish_call_expr (function, call_args,
/*disallow_virtual=*/qualified_p,
koenig_p,
complain);
else
ret = finish_call_expr (function, &call_args,
/*disallow_virtual=*/qualified_p,
koenig_p,
complain);
release_tree_vector (call_args);
return ret;
}
case COND_EXPR:
@ -12112,9 +12182,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
return fndecl;
}
/* The FN is a TEMPLATE_DECL for a function. The ARGS are the
arguments that are being used when calling it. TARGS is a vector
into which the deduced template arguments are placed.
/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with
NARGS elements of the arguments that are being used when calling
it. TARGS is a vector into which the deduced template arguments
are placed.
Return zero for success, 2 for an incomplete match that doesn't resolve
all the types, and 1 for complete failure. An error message will be
@ -12146,7 +12217,8 @@ int
fn_type_unification (tree fn,
tree explicit_targs,
tree targs,
tree args,
const tree *args,
unsigned int nargs,
tree return_type,
unification_kind_t strict,
int flags)
@ -12263,8 +12335,14 @@ fn_type_unification (tree fn,
if (return_type)
{
tree *new_args;
parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
args = tree_cons (NULL_TREE, return_type, args);
new_args = XALLOCAVEC (tree, nargs + 1);
new_args[0] = return_type;
memcpy (new_args + 1, args, nargs * sizeof (tree));
args = new_args;
++nargs;
}
/* We allow incomplete unification without an error message here
@ -12272,7 +12350,7 @@ fn_type_unification (tree fn,
callers must be ready to deal with unification failures in any
event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, /*subr=*/0,
targs, parms, args, nargs, /*subr=*/0,
strict, flags);
if (result == 0 && incomplete_argument_packs_p)
@ -12337,14 +12415,14 @@ fn_type_unification (tree fn,
parameters are used in non-deduced contexts. */
if (strict == DEDUCE_EXACT)
{
unsigned int i;
tree sarg
= skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed));
tree arg = args;
if (return_type)
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
for (; arg && sarg;
arg = TREE_CHAIN (arg), sarg = TREE_CHAIN (sarg))
if (!same_type_p (TREE_VALUE (arg), TREE_VALUE (sarg)))
for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
if (!same_type_p (args[i], TREE_VALUE (sarg)))
return 1;
}
}
@ -12459,7 +12537,8 @@ static int
type_unification_real (tree tparms,
tree targs,
tree xparms,
tree xargs,
const tree *xargs,
unsigned int xnargs,
int subr,
unification_kind_t strict,
int flags)
@ -12469,11 +12548,13 @@ type_unification_real (tree tparms,
int ntparms = TREE_VEC_LENGTH (tparms);
int sub_strict;
int saw_undeduced = 0;
tree parms, args;
tree parms;
const tree *args;
unsigned int nargs;
unsigned int ia;
gcc_assert (TREE_CODE (tparms) == TREE_VEC);
gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
gcc_assert (ntparms > 0);
switch (strict)
@ -12498,17 +12579,19 @@ type_unification_real (tree tparms,
again:
parms = xparms;
args = xargs;
nargs = xnargs;
ia = 0;
while (parms && parms != void_list_node
&& args && args != void_list_node)
&& ia < nargs)
{
if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
break;
parm = TREE_VALUE (parms);
parms = TREE_CHAIN (parms);
arg = TREE_VALUE (args);
args = TREE_CHAIN (args);
arg = args[ia];
++ia;
arg_expr = NULL;
if (arg == error_mark_node)
@ -12587,20 +12670,11 @@ type_unification_real (tree tparms,
/* Unify the remaining arguments with the pack expansion type. */
tree argvec;
tree parmvec = make_tree_vec (1);
int len = 0;
tree t;
/* Count the number of arguments that remain. */
for (t = args; t && t != void_list_node; t = TREE_CHAIN (t))
len++;
/* Allocate a TREE_VEC and copy in all of the arguments */
argvec = make_tree_vec (len);
for (i = 0; args && args != void_list_node; args = TREE_CHAIN (args))
{
TREE_VEC_ELT (argvec, i) = TREE_VALUE (args);
++i;
}
argvec = make_tree_vec (nargs - ia);
for (i = 0; ia < nargs; ++ia, ++i)
TREE_VEC_ELT (argvec, i) = args[ia];
/* Copy the parameter into parmvec. */
TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
@ -12614,7 +12688,7 @@ type_unification_real (tree tparms,
/* Fail if we've reached the end of the parm list, and more args
are present, and the parm list isn't variadic. */
if (args && args != void_list_node && parms == void_list_node)
if (ia < nargs && parms == void_list_node)
return 1;
/* Fail if parms are left and they don't have default values. */
if (parms && parms != void_list_node
@ -13896,26 +13970,42 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case METHOD_TYPE:
case FUNCTION_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
{
unsigned int nargs;
tree *args;
tree a;
unsigned int i;
/* CV qualifications for methods can never be deduced, they must
match exactly. We need to check them explicitly here,
because type_unification_real treats them as any other
cv-qualified parameter. */
if (TREE_CODE (parm) == METHOD_TYPE
&& (!check_cv_quals_for_unify
(UNIFY_ALLOW_NONE,
TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
return 1;
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
if (unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), UNIFY_ALLOW_NONE))
return 1;
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
LOOKUP_NORMAL);
/* CV qualifications for methods can never be deduced, they must
match exactly. We need to check them explicitly here,
because type_unification_real treats them as any other
cv-qualified parameter. */
if (TREE_CODE (parm) == METHOD_TYPE
&& (!check_cv_quals_for_unify
(UNIFY_ALLOW_NONE,
TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
return 1;
if (unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), UNIFY_ALLOW_NONE))
return 1;
nargs = list_length (TYPE_ARG_TYPES (arg));
args = XALLOCAVEC (tree, nargs);
for (a = TYPE_ARG_TYPES (arg), i = 0;
a != NULL_TREE && a != void_list_node;
a = TREE_CHAIN (a), ++i)
args[i] = TREE_VALUE (a);
nargs = i;
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
args, nargs, 1, DEDUCE_EXACT,
LOOKUP_NORMAL);
}
case OFFSET_TYPE:
/* Unify a pointer to member with a pointer to member function, which
@ -14469,6 +14559,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
tree targs = make_tree_vec (ntparms);
tree decl_type;
tree decl_arg_types;
tree *args;
unsigned int nargs, ix;
tree arg;
/* Substitute the explicit template arguments into the type of DECL.
The call to fn_type_unification will handle substitution into the
@ -14503,8 +14596,15 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
decl_arg_types = skip_artificial_parms_for (decl,
TYPE_ARG_TYPES (decl_type));
nargs = list_length (decl_arg_types);
args = XALLOCAVEC (tree, nargs);
for (arg = decl_arg_types, ix = 0;
arg != NULL_TREE && arg != void_list_node;
arg = TREE_CHAIN (arg), ++ix)
args[ix] = TREE_VALUE (arg);
if (fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
args, ix,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
DEDUCE_EXACT, LOOKUP_NORMAL))
@ -16580,19 +16680,18 @@ type_dependent_expression_p_push (tree expr)
return b;
}
/* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call)
contains a type-dependent expression. */
/* Returns TRUE if ARGS contains a type-dependent expression. */
bool
any_type_dependent_arguments_p (const_tree args)
any_type_dependent_arguments_p (const VEC(tree,gc) *args)
{
while (args)
{
tree arg = TREE_VALUE (args);
unsigned int i;
tree arg;
for (i = 0; VEC_iterate (tree, args, i, arg); ++i)
{
if (type_dependent_expression_p (arg))
return true;
args = TREE_CHAIN (args);
}
return false;
}
@ -17012,22 +17111,22 @@ build_non_dependent_expr (tree expr)
return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr);
}
/* ARGS is a TREE_LIST of expressions as arguments to a function call.
Return a new TREE_LIST with the various arguments replaced with
equivalent non-dependent expressions. */
/* ARGS is a vector of expressions as arguments to a function call.
Replace the arguments with equivalent non-dependent expressions.
This modifies ARGS in place. */
tree
build_non_dependent_args (tree args)
void
make_args_non_dependent (VEC(tree,gc) *args)
{
tree a;
tree new_args;
unsigned int ix;
tree arg;
new_args = NULL_TREE;
for (a = args; a; a = TREE_CHAIN (a))
new_args = tree_cons (NULL_TREE,
build_non_dependent_expr (TREE_VALUE (a)),
new_args);
return nreverse (new_args);
for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
{
tree newarg = build_non_dependent_expr (arg);
if (newarg != arg)
VEC_replace (tree, args, ix, newarg);
}
}
/* Returns a type which represents 'auto'. We use a TEMPLATE_TYPE_PARM
@ -17084,7 +17183,8 @@ listify_autos (tree type, tree auto_node)
tree
do_auto_deduction (tree type, tree init, tree auto_node)
{
tree parms, args, tparms, targs;
tree parms, tparms, targs;
tree args[1];
int val;
/* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
@ -17095,12 +17195,12 @@ do_auto_deduction (tree type, tree init, tree auto_node)
type = listify_autos (type, auto_node);
parms = build_tree_list (NULL_TREE, type);
args = build_tree_list (NULL_TREE, init);
args[0] = init;
tparms = make_tree_vec (1);
targs = make_tree_vec (1);
TREE_VEC_ELT (tparms, 0)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
val = type_unification_real (tparms, targs, parms, args, 0,
val = type_unification_real (tparms, targs, parms, args, 1, 0,
DEDUCE_CALL, LOOKUP_NORMAL);
if (val > 0)
{

View File

@ -1820,7 +1820,7 @@ stmt_expr_value_expr (tree stmt_expr)
resolution. */
tree
perform_koenig_lookup (tree fn, tree args)
perform_koenig_lookup (tree fn, VEC(tree,gc) *args)
{
tree identifier = NULL_TREE;
tree functions = NULL_TREE;
@ -1865,7 +1865,8 @@ perform_koenig_lookup (tree fn, tree args)
return fn;
}
/* Generate an expression for `FN (ARGS)'.
/* Generate an expression for `FN (ARGS)'. This may change the
contents of ARGS.
If DISALLOW_VIRTUAL is true, the call to FN will be not generated
as a virtual call, even if FN is virtual. (This flag is set when
@ -1876,29 +1877,26 @@ perform_koenig_lookup (tree fn, tree args)
Returns code for the call. */
tree
finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
tsubst_flags_t complain)
finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
bool koenig_p, tsubst_flags_t complain)
{
tree result;
tree orig_fn;
tree orig_args;
VEC(tree,gc) *orig_args = NULL;
if (fn == error_mark_node || args == error_mark_node)
if (fn == error_mark_node)
return error_mark_node;
/* ARGS should be a list of arguments. */
gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
gcc_assert (!TYPE_P (fn));
orig_fn = fn;
orig_args = args;
if (processing_template_decl)
{
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
|| any_type_dependent_arguments_p (*args))
{
result = build_nt_call_list (fn, args);
result = build_nt_call_vec (fn, *args);
KOENIG_LOOKUP_P (result) = koenig_p;
if (cfun)
{
@ -1916,11 +1914,12 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
}
return result;
}
orig_args = make_tree_vector_copy (*args);
if (!BASELINK_P (fn)
&& TREE_CODE (fn) != PSEUDO_DTOR_EXPR
&& TREE_TYPE (fn) != unknown_type_node)
fn = build_non_dependent_expr (fn);
args = build_non_dependent_args (orig_args);
make_args_non_dependent (*args);
}
if (is_overloaded_fn (fn))
@ -1969,7 +1968,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
return build_nt_call_list (orig_fn, orig_args);
{
tree ret = build_nt_call_vec (orig_fn, orig_args);
release_tree_vector (orig_args);
return ret;
}
object = build_non_dependent_expr (object);
}
@ -1985,15 +1988,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
if (TREE_CODE (fn) == FUNCTION_DECL
&& (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
{
VEC(tree,gc)* vec = VEC_alloc (tree, gc, list_length (args));
tree p;
for (p = args; p != NULL_TREE; p = TREE_CHAIN (p))
VEC_quick_push (tree, vec, TREE_VALUE (p));
result = resolve_overloaded_builtin (fn, vec);
VEC_free (tree, gc, vec);
}
result = resolve_overloaded_builtin (fn, *args);
if (!result)
/* A call to a namespace-scope function. */
@ -2001,7 +1996,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
}
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
if (args)
if (!VEC_empty (tree, *args))
error ("arguments to destructor are not allowed");
/* Mark the pseudo-destructor call as having side-effects so
that we do not issue warnings about its use. */
@ -2013,18 +2008,19 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
/* If the "function" is really an object of class type, it might
have an overloaded `operator ()'. */
result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE,
/*overloaded_p=*/NULL, complain);
result = build_op_call (fn, args, complain);
if (!result)
/* A call where the function is unknown. */
result = cp_build_function_call (fn, args, complain);
result = cp_build_function_call_vec (fn, args, complain);
if (processing_template_decl)
{
result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
KOENIG_LOOKUP_P (result) = koenig_p;
release_tree_vector (orig_args);
}
return result;
}
@ -3423,18 +3419,23 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
if (need_default_ctor
|| (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type)))
{
VEC(tree,gc) *vec;
if (need_default_ctor)
t = NULL;
vec = NULL;
else
{
t = build_int_cst (build_pointer_type (type), 0);
t = build1 (INDIRECT_REF, type, t);
t = build_tree_list (NULL, t);
vec = make_tree_vector_single (t);
}
t = build_special_member_call (NULL_TREE, complete_ctor_identifier,
t, type, LOOKUP_NORMAL,
&vec, type, LOOKUP_NORMAL,
tf_warning_or_error);
if (vec != NULL)
release_tree_vector (vec);
if (targetm.cxx.cdtor_returns_this () || errorcount)
/* Because constructors and destructors return this,
the call will have been cast to "void". Remove the
@ -3472,12 +3473,15 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type))
{
VEC(tree,gc) *vec;
t = build_int_cst (build_pointer_type (type), 0);
t = build1 (INDIRECT_REF, type, t);
vec = make_tree_vector_single (t);
t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
build_tree_list (NULL, t),
type, LOOKUP_NORMAL,
&vec, type, LOOKUP_NORMAL,
tf_warning_or_error);
release_tree_vector (vec);
/* We'll have called convert_from_reference on the call, which
may well have added an indirect_ref. It's unneeded here,
@ -4433,7 +4437,9 @@ void
finish_omp_barrier (void)
{
tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
VEC(tree,gc) *vec = make_tree_vector ();
tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
release_tree_vector (vec);
finish_expr_stmt (stmt);
}
@ -4441,7 +4447,9 @@ void
finish_omp_flush (void)
{
tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
VEC(tree,gc) *vec = make_tree_vector ();
tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
release_tree_vector (vec);
finish_expr_stmt (stmt);
}
@ -4449,7 +4457,9 @@ void
finish_omp_taskwait (void)
{
tree fn = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
VEC(tree,gc) *vec = make_tree_vector ();
tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
release_tree_vector (vec);
finish_expr_stmt (stmt);
}

View File

@ -1719,9 +1719,9 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
built. */
tree
build_min_non_dep_call_list (tree non_dep, tree fn, tree arglist)
build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec)
{
tree t = build_nt_call_list (fn, arglist);
tree t = build_nt_call_vec (fn, argvec);
TREE_TYPE (t) = TREE_TYPE (non_dep);
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
return t;

View File

@ -61,7 +61,7 @@ static void casts_away_constness_r (tree *, tree *);
static bool casts_away_constness (tree, tree);
static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree);
static int convert_arguments (int, tree *, tree, tree, tree, int,
static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
tsubst_flags_t);
/* Do `exp = require_complete_type (exp);' to make sure exp
@ -2866,38 +2866,57 @@ tree
build_function_call_vec (tree function, VEC(tree,gc) *params,
VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
{
tree p;
tree *pp;
unsigned int i;
tree t;
VEC(tree,gc) *orig_params = params;
tree ret = cp_build_function_call_vec (function, &params,
tf_warning_or_error);
/* FIXME: Should just change cp_build_function_call to use a
VEC. */
p = NULL_TREE;
pp = &p;
for (i = 0; VEC_iterate (tree, params, i, t); ++i)
{
*pp = build_tree_list (NULL, t);
pp = &TREE_CHAIN (*pp);
}
return cp_build_function_call (function, p, tf_warning_or_error);
/* cp_build_function_call_vec can reallocate PARAMS by adding
default arguments. That should never happen here. Verify
that. */
gcc_assert (params == orig_params);
return ret;
}
/* Build a function call using a tree list of arguments. */
tree
cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
{
VEC(tree,gc) *vec;
tree ret;
vec = make_tree_vector ();
for (; params != NULL_TREE; params = TREE_CHAIN (params))
VEC_safe_push (tree, gc, vec, TREE_VALUE (params));
ret = cp_build_function_call_vec (function, &vec, complain);
release_tree_vector (vec);
return ret;
}
/* Build a function call using a vector of arguments. PARAMS may be
NULL if there are no parameters. This changes the contents of
PARAMS. */
tree
cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
tsubst_flags_t complain)
{
tree fntype, fndecl;
tree name = NULL_TREE;
int is_method;
tree original = function;
int nargs, parm_types_len;
int nargs;
tree *argarray;
tree parm_types;
VEC(tree,gc) *allocated = NULL;
tree ret;
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
expressions, like those used for ObjC messenger dispatches. */
if (params != NULL_TREE)
function = objc_rewrite_function_call (function, TREE_VALUE (params));
if (params != NULL && !VEC_empty (tree, *params))
function = objc_rewrite_function_call (function,
VEC_index (tree, *params, 0));
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */
@ -2957,57 +2976,55 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
fntype = TREE_TYPE (fntype);
parm_types = TYPE_ARG_TYPES (fntype);
/* Allocate storage for converted arguments. */
parm_types_len = list_length (parm_types);
nargs = list_length (params);
if (parm_types_len > nargs)
nargs = parm_types_len;
argarray = (tree *) alloca (nargs * sizeof (tree));
if (params == NULL)
{
allocated = make_tree_vector ();
params = &allocated;
}
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
nargs = convert_arguments (nargs, argarray, parm_types,
params, fndecl, LOOKUP_NORMAL,
complain);
nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
complain);
if (nargs < 0)
return error_mark_node;
argarray = VEC_address (tree, *params);
/* Check for errors in format strings and inappropriately
null parameters. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
parm_types);
return build_cxx_call (function, nargs, argarray);
ret = build_cxx_call (function, nargs, argarray);
if (allocated != NULL)
release_tree_vector (allocated);
return ret;
}
/* Convert the actual parameter expressions in the list VALUES
to the types in the list TYPELIST.
/* Convert the actual parameter expressions in the list VALUES to the
types in the list TYPELIST. The converted expressions are stored
back in the VALUES vector.
If parmdecls is exhausted, or when an element has NULL as its type,
perform the default conversions.
Store the converted arguments in ARGARRAY. NARGS is the size of this array.
NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
This is also where warnings about wrong number of args are generated.
Returns the actual number of arguments processed (which might be less
than NARGS), or -1 on error.
VALUES is a chain of TREE_LIST nodes with the elements of the list
in the TREE_VALUE slots of those nodes.
than the length of the vector), or -1 on error.
In C++, unspecified trailing parameters can be filled in with their
default arguments, if such were specified. Do so here. */
static int
convert_arguments (int nargs, tree *argarray,
tree typelist, tree values, tree fndecl, int flags,
tsubst_flags_t complain)
convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
int flags, tsubst_flags_t complain)
{
tree typetail, valtail;
tree typetail;
const char *called_thing = 0;
int i = 0;
unsigned int i;
/* Argument passing is always copy-initialization. */
flags |= LOOKUP_ONLYCONVERTING;
@ -3026,12 +3043,12 @@ convert_arguments (int nargs, tree *argarray,
called_thing = "function";
}
for (valtail = values, typetail = typelist;
valtail;
valtail = TREE_CHAIN (valtail), i++)
for (i = 0, typetail = typelist;
i < VEC_length (tree, *values);
i++)
{
tree type = typetail ? TREE_VALUE (typetail) : 0;
tree val = TREE_VALUE (valtail);
tree val = VEC_index (tree, *values, i);
if (val == error_mark_node || type == error_mark_node)
return -1;
@ -3100,7 +3117,7 @@ convert_arguments (int nargs, tree *argarray,
if (parmval == error_mark_node)
return -1;
argarray[i] = parmval;
VEC_replace (tree, *values, i, parmval);
}
else
{
@ -3113,7 +3130,7 @@ convert_arguments (int nargs, tree *argarray,
else
val = convert_arg_to_ellipsis (val);
argarray[i] = val;
VEC_replace (tree, *values, i, val);
}
if (typetail)
@ -3142,7 +3159,7 @@ convert_arguments (int nargs, tree *argarray,
if (parmval == error_mark_node)
return -1;
argarray[i] = parmval;
VEC_safe_push (tree, gc, *values, parmval);
typetail = TREE_CHAIN (typetail);
/* ends with `...'. */
if (typetail == NULL_TREE)
@ -3166,8 +3183,7 @@ convert_arguments (int nargs, tree *argarray,
}
}
gcc_assert (i <= nargs);
return i;
return (int) i;
}
/* Build a binary-operation expression, after performing default
@ -4994,6 +5010,34 @@ tree build_x_compound_expr_from_list (tree list, const char *msg)
return expr;
}
/* Like build_x_compound_expr_from_list, but using a VEC. */
tree
build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
{
if (VEC_empty (tree, vec))
return NULL_TREE;
else if (VEC_length (tree, vec) == 1)
return VEC_index (tree, vec, 0);
else
{
tree expr;
unsigned int ix;
tree t;
if (msg != NULL)
permerror (input_location,
"%s expression list treated as compound expression",
msg);
expr = VEC_index (tree, vec, 0);
for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
expr = build_x_compound_expr (expr, t, tf_warning_or_error);
return expr;
}
}
/* Handle overloading of the ',' operator when needed. */
tree
@ -6038,10 +6082,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
/* Do the default thing. */;
else
{
VEC(tree,gc) *rhs_vec = make_tree_vector_single (rhs);
result = build_special_member_call (lhs, complete_ctor_identifier,
build_tree_list (NULL_TREE, rhs),
lhstype, LOOKUP_NORMAL,
&rhs_vec, lhstype, LOOKUP_NORMAL,
complain);
release_tree_vector (rhs_vec);
if (result == NULL_TREE)
return error_mark_node;
return result;

View File

@ -1442,6 +1442,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
/* The type to which we are casting. */
tree type;
VEC(tree,gc) *parmvec;
if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node;
@ -1512,8 +1513,12 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
}
/* Call the constructor. */
exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
type, LOOKUP_NORMAL, complain);
parmvec = make_tree_vector ();
for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
VEC_safe_push (tree, gc, parmvec, TREE_VALUE (parms));
exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
&parmvec, type, LOOKUP_NORMAL, complain);
release_tree_vector (parmvec);
if (exp == error_mark_node)
return error_mark_node;

View File

@ -1,3 +1,8 @@
2009-05-20 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_generate_cxx_ctor_or_dtor): Pass NULL rather
than NULL_TREE to build_special_member_call.
2009-05-10 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_building_struct): New static variable.

View File

@ -4538,7 +4538,7 @@ objc_generate_cxx_ctor_or_dtor (bool dtor)
(build_special_member_call
(build_ivar_reference (DECL_NAME (ivar)),
dtor ? complete_dtor_identifier : complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
}
}

View File

@ -1827,6 +1827,23 @@ build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
return t;
}
/* Build a chain of TREE_LIST nodes from a vector. */
tree
build_tree_list_vec_stat (const VEC(tree,gc) *vec MEM_STAT_DECL)
{
tree ret = NULL_TREE;
tree *pp = &ret;
unsigned int i;
tree t;
for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
{
*pp = build_tree_list_stat (NULL, t PASS_MEM_STAT);
pp = &TREE_CHAIN (*pp);
}
return ret;
}
/* Return a newly created TREE_LIST node whose
purpose and value fields are PURPOSE and VALUE
and whose TREE_CHAIN is CHAIN. */
@ -1870,6 +1887,22 @@ ctor_to_list (tree ctor)
return list;
}
/* Return the values of the elements of a CONSTRUCTOR as a vector of
trees. */
VEC(tree,gc) *
ctor_to_vec (tree ctor)
{
VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor));
unsigned int ix;
tree val;
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val)
VEC_quick_push (tree, vec, val);
return vec;
}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
@ -3483,6 +3516,23 @@ build_nt_call_list (tree fn, tree arglist)
CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
return t;
}
/* Similar to build_nt, but for creating a CALL_EXPR object with a
tree VEC. */
tree
build_nt_call_vec (tree fn, VEC(tree,gc) *args)
{
tree ret, t;
unsigned int ix;
ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
CALL_EXPR_FN (ret) = fn;
CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
CALL_EXPR_ARG (ret, ix) = t;
return ret;
}
/* Create a DECL_... node of code CODE, name NAME and data type TYPE.
We do NOT enter this node in any sort of symbol table.
@ -8240,7 +8290,7 @@ build_call_valist (tree return_type, tree fn, int nargs, va_list args)
which are specified as a tree array ARGS. */
tree
build_call_array (tree return_type, tree fn, int nargs, tree *args)
build_call_array (tree return_type, tree fn, int nargs, const tree *args)
{
tree t;
int i;
@ -8255,6 +8305,24 @@ build_call_array (tree return_type, tree fn, int nargs, tree *args)
return t;
}
/* Like build_call_array, but takes a VEC. */
tree
build_call_vec (tree return_type, tree fn, VEC(tree,gc) *args)
{
tree ret, t;
unsigned int ix;
ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
TREE_TYPE (ret) = return_type;
CALL_EXPR_FN (ret) = fn;
CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
CALL_EXPR_ARG (ret, ix) = t;
process_call_operands (ret);
return ret;
}
/* Returns true if it is possible to prove that the index of
an array access REF (an ARRAY_REF expression) falls into the

View File

@ -3833,6 +3833,7 @@ extern tree maybe_get_identifier (const char *);
extern tree build_nt (enum tree_code, ...);
extern tree build_nt_call_list (tree, tree);
extern tree build_nt_call_vec (tree, VEC(tree,gc) *);
extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
#define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
@ -3870,6 +3871,8 @@ extern tree build_one_cst (tree);
extern tree build_string (int, const char *);
extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
#define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
extern tree build_tree_list_vec_stat (const VEC(tree,gc) * MEM_STAT_DECL);
#define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO)
extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
extern tree build_fn_decl (const char *, tree);
#define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
@ -3883,7 +3886,8 @@ extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
extern tree build_call_list (tree, tree, tree);
extern tree build_call_nary (tree, tree, int, ...);
extern tree build_call_valist (tree, tree, int, va_list);
extern tree build_call_array (tree, tree, int, tree*);
extern tree build_call_array (tree, tree, int, const tree *);
extern tree build_call_vec (tree, tree, VEC(tree,gc) *);
/* Construct various nodes representing data types. */
@ -4310,6 +4314,10 @@ extern bool initializer_zerop (const_tree);
extern tree ctor_to_list (tree);
/* Given a CONSTRUCTOR CTOR, return the element values as a vector. */
extern VEC(tree,gc) *ctor_to_vec (tree);
/* Examine CTOR to discover:
* how many scalar fields are set to nonzero values,
and place it in *P_NZ_ELTS;