aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2014-11-19 05:31:24 -0800
committerRichard Henderson <rth@gcc.gnu.org>2014-11-19 05:31:24 -0800
commit74893f25916c3cdcc7ad26af391c3f59a2a51a98 (patch)
tree6e11f41a5ade384361d3bf280fa4e43b0e99fa63 /gcc/c
parentf2d3d07ee55fa52b41c1ec08e51269831961a772 (diff)
downloadgcc-74893f25916c3cdcc7ad26af391c3f59a2a51a98.zip
gcc-74893f25916c3cdcc7ad26af391c3f59a2a51a98.tar.gz
gcc-74893f25916c3cdcc7ad26af391c3f59a2a51a98.tar.bz2
Allow the static chain to be set from C
We need to be able to set the static chain on a few calls within the Go runtime, so expose this with __builtin_call_with_static_chain. * c-family/c-common.c (c_common_reswords): Add __builtin_call_with_static_chain. * c-family/c-common.h (RID_BUILTIN_CALL_WITH_STATIC_CHAIN): New. * c/c-parser.c (c_parser_postfix_expression): Handle it. * doc/extend.texi (__builtin_call_with_static_chain): Document it. From-SVN: r217771
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-parser.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index f90f6af..8a4fd39 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7414,6 +7414,46 @@ c_parser_postfix_expression (c_parser *parser)
= comptypes (e1, e2) ? integer_one_node : integer_zero_node;
}
break;
+ case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
+ {
+ vec<c_expr_t, va_gc> *cexpr_list;
+ c_expr_t *e2_p;
+ tree chain_value;
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_call_with_static_chain",
+ &cexpr_list, false))
+ {
+ expr.value = error_mark_node;
+ break;
+ }
+ if (vec_safe_length (cexpr_list) != 2)
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_call_with_static_chain%>");
+ expr.value = error_mark_node;
+ break;
+ }
+
+ expr = (*cexpr_list)[0];
+ e2_p = &(*cexpr_list)[1];
+ *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
+ chain_value = e2_p->value;
+ mark_exp_read (chain_value);
+
+ if (TREE_CODE (expr.value) != CALL_EXPR)
+ error_at (loc, "first argument to "
+ "%<__builtin_call_with_static_chain%> "
+ "must be a call expression");
+ else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
+ error_at (loc, "second argument to "
+ "%<__builtin_call_with_static_chain%> "
+ "must be a pointer type");
+ else
+ CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
+ break;
+ }
case RID_BUILTIN_COMPLEX:
{
vec<c_expr_t, va_gc> *cexpr_list;