Resolve undefined functions to compiler builtins if they exist.

This commit is contained in:
Dale Weiler 2013-11-23 06:57:40 -05:00
parent b1fd85b711
commit 292c8150b4
5 changed files with 38 additions and 0 deletions

View file

@ -338,6 +338,12 @@ for QuakeWorld to compile it needs to be treated as a warning
instead, as such this warning only works when -std=qcc.
.It Fl W Ns Cm directive-inmacro
Warn about the use of preprocessor directives inside macros.
.It Fl W Ns Cm builtins
When using a function that is not explicitly defined, the compiler
will search its intrinsics table for something that matches that
function name by appending "__builtin_" to it. This behaviour may
be unexpected, so enabling this will produce a diagnostic when
such a function is resolved to a builtin.
.El
.Sh COMPILE FLAGS
.Bl -tag -width Ds

View file

@ -537,6 +537,14 @@
DIRECTIVE_INMACRO = true
#When using a function that is not explicitly defined, the compiler
#will search its intrinsics table for something that matches that
#function name by appending "__builtin_" to it. This behaviour may
#be unexpected, so enabling this will produce a diagnostic when
#such a function is resolved to a builtin.
BUILTINS = true
[optimizations]
#Some general peephole optimizations. For instance the code `a = b

1
opts.c
View file

@ -92,6 +92,7 @@ static void opts_setdefault(void) {
opts_set(opts.warn, WARN_PARENTHESIS, true);
opts_set(opts.warn, WARN_CONST_OVERWRITE, true);
opts_set(opts.warn, WARN_DIRECTIVE_INMACRO, true);
opts_set(opts.warn, WARN_BUILTINS, true);
/* flags */
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);

View file

@ -96,6 +96,7 @@
GMQCC_DEFINE_FLAG(BREAKDEF)
GMQCC_DEFINE_FLAG(CONST_OVERWRITE)
GMQCC_DEFINE_FLAG(DIRECTIVE_INMACRO)
GMQCC_DEFINE_FLAG(BUILTINS)
#endif
#ifdef GMQCC_TYPE_OPTIMIZATIONS

View file

@ -1575,6 +1575,8 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
var = (ast_expression*)fold_constgen_string(parser->fold, parser->function->name, false);
if (!var) {
char *tryintrinsic = NULL;
/*
* now we try for the real intrinsic hashtable. If the string
* begins with __builtin, we simply skip past it, otherwise we
@ -1584,6 +1586,26 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
var = intrin_func(parser->intrin, parser_tokval(parser));
}
/*
* Try it as an instruction by appending __builtin_ to the token
* and emit a warning if an intrinsic function matching that
* name exists.
*/
if (!var) {
util_asprintf(&tryintrinsic, "__builtin_%s", parser_tokval(parser));
if ((var = intrin_func(parser->intrin, tryintrinsic))) {
(void)!!compile_warning(
parser_ctx(parser),
WARN_BUILTINS,
"using implicitly defined builtin `%s' for `%s'",
tryintrinsic,
parser_tokval(parser)
);
}
mem_d(tryintrinsic);
}
if (!var) {
char *correct = NULL;
size_t i;