summaryrefslogtreecommitdiffstats
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c80
1 files changed, 45 insertions, 35 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 18aa0519e1c..2b12448eefd 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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);
}
OpenPOWER on IntegriCloud