aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/gimple-parser.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-05-17 10:52:58 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-05-17 10:52:58 +0000
commite4f81565ce768256ff3f7acc368c38fa450098cc (patch)
tree0a8bc7b8cca8bc8c488119cf5a5f80dd27acc639 /gcc/c/gimple-parser.c
parenteb69361d0c5e98423e7ad7a537bc3250e083de4a (diff)
downloadgcc-e4f81565ce768256ff3f7acc368c38fa450098cc.zip
gcc-e4f81565ce768256ff3f7acc368c38fa450098cc.tar.gz
gcc-e4f81565ce768256ff3f7acc368c38fa450098cc.tar.bz2
Gimple FE support for internal functions
This patch gets the gimple FE to parse calls to internal functions. The only non-obvious thing was how the functions should be written to avoid clashes with real function names. One option would be to go the magic number of underscores route, but we already do that for built-in functions, and it would be good to keep them visually distinct. In the end I borrowed the local/internal label convention from asm and used: x = .SQRT (y); 2018-05-17 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * internal-fn.h (lookup_internal_fn): Declare * internal-fn.c (lookup_internal_fn): New function. * gimple.c (gimple_build_call_from_tree): Handle calls to internal functions. * gimple-pretty-print.c (dump_gimple_call): Print "." before internal function names. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise. gcc/c/ * gimple-parser.c: Include internal-fn.h. (c_parser_gimple_statement): Treat a leading CPP_DOT as a call. (c_parser_gimple_call_internal): New function. (c_parser_gimple_postfix_expression): Use it to handle CPP_DOT. Fix typos in comment. gcc/testsuite/ * gcc.dg/gimplefe-28.c: New test. * gcc.dg/asan/use-after-scope-9.c: Adjust expected output for internal function calls. * gcc.dg/goacc/loop-processing-1.c: Likewise. From-SVN: r260316
Diffstat (limited to 'gcc/c/gimple-parser.c')
-rw-r--r--gcc/c/gimple-parser.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 32513f1..c9abe24 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssanames.h"
#include "gimple-ssa.h"
#include "tree-dfa.h"
+#include "internal-fn.h"
/* Gimple parsing functions. */
@@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *parser, gimple_seq *seq)
}
/* GIMPLE call with lhs. */
- if (c_parser_next_token_is (parser, CPP_NAME)
- && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
- && lookup_name (c_parser_peek_token (parser)->value))
+ if (c_parser_next_token_is (parser, CPP_DOT)
+ || (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
+ && lookup_name (c_parser_peek_token (parser)->value)))
{
rhs = c_parser_gimple_unary_expression (parser);
if (rhs.value != error_mark_node)
@@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parser,
return name;
}
+/* Parse a gimple call to an internal function.
+
+ gimple-call-internal:
+ . identifier ( gimple-argument-expression-list[opt] ) */
+
+static struct c_expr
+c_parser_gimple_call_internal (c_parser *parser)
+{
+ struct c_expr expr;
+ expr.set_error ();
+
+ gcc_assert (c_parser_next_token_is (parser, CPP_DOT));
+ c_parser_consume_token (parser);
+ location_t loc = c_parser_peek_token (parser)->location;
+ if (!c_parser_next_token_is (parser, CPP_NAME)
+ || c_parser_peek_token (parser)->id_kind != C_ID_ID)
+ {
+ c_parser_error (parser, "expecting internal function name");
+ return expr;
+ }
+ tree id = c_parser_peek_token (parser)->value;
+ internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));
+ c_parser_consume_token (parser);
+ if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ {
+ auto_vec<tree> exprlist;
+ if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ c_parser_gimple_expr_list (parser, &exprlist);
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+ if (ifn == IFN_LAST)
+ error_at (loc, "unknown internal function %qE", id);
+ else
+ {
+ expr.value = build_call_expr_internal_loc_array
+ (loc, ifn, void_type_node, exprlist.length (),
+ exprlist.address ());
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
+ }
+ }
+ return expr;
+}
+
/* Parse gimple postfix expression.
gimple-postfix-expression:
gimple-primary-expression
- gimple-primary-xpression [ gimple-primary-expression ]
+ gimple-primary-expression [ gimple-primary-expression ]
gimple-primary-expression ( gimple-argument-expression-list[opt] )
- postfix-expression . identifier
- postfix-expression -> identifier
+ gimple-postfix-expression . identifier
+ gimple-postfix-expression -> identifier
gimple-argument-expression-list:
gimple-unary-expression
@@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parser,
identifier
constant
string-literal
+ gimple-call-internal
*/
@@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_parser *parser)
expr.original_code = STRING_CST;
c_parser_consume_token (parser);
break;
+ case CPP_DOT:
+ expr = c_parser_gimple_call_internal (parser);
+ break;
case CPP_NAME:
if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
{