aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r--gcc/ada/gcc-interface/utils2.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 4c0853e..0671308 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1372,6 +1372,33 @@ build_cond_expr (tree result_type, tree condition_operand,
return result;
}
+/* Similar, but for COMPOUND_EXPR. */
+
+tree
+build_compound_expr (tree result_type, tree stmt_operand, tree expr_operand)
+{
+ bool addr_p = false;
+ tree result;
+
+ /* If the result type is unconstrained, take the address of the operand and
+ then dereference the result. Likewise if the result type is passed by
+ reference, but this is natively handled in the gimplifier. */
+ if (TREE_CODE (result_type) == UNCONSTRAINED_ARRAY_TYPE
+ || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (result_type)))
+ {
+ result_type = build_pointer_type (result_type);
+ expr_operand = build_unary_op (ADDR_EXPR, result_type, expr_operand);
+ addr_p = true;
+ }
+
+ result = fold_build2 (COMPOUND_EXPR, result_type, stmt_operand,
+ expr_operand);
+
+ if (addr_p)
+ result = build_unary_op (INDIRECT_REF, NULL_TREE, result);
+
+ return result;
+}
/* Similar, but for RETURN_EXPR. If RET_VAL is non-null, build a RETURN_EXPR
around the assignment of RET_VAL to RET_OBJ. Otherwise just build a bare
RETURN_EXPR around RESULT_OBJ, which may be null in this case. */