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:
parent
40449a90d7
commit
c166b8981f
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
686
gcc/cp/call.c
686
gcc/cp/call.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
16
gcc/cp/cvt.c
16
gcc/cp/cvt.c
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
191
gcc/cp/init.c
191
gcc/cp/init.c
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
179
gcc/cp/parser.c
179
gcc/cp/parser.c
@ -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);
|
||||
|
300
gcc/cp/pt.c
300
gcc/cp/pt.c
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
153
gcc/cp/typeck.c
153
gcc/cp/typeck.c
@ -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, ¶ms,
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
70
gcc/tree.c
70
gcc/tree.c
@ -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
|
||||
|
10
gcc/tree.h
10
gcc/tree.h
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user