[EXPR_FUNCNAME] = PREC_PRIMARY,
[EXPR_BUILTIN_SYMBOL] = PREC_PRIMARY,
[EXPR_BUILTIN_CONSTANT_P] = PREC_PRIMARY,
- [EXPR_BUILTIN_ADDRESS] = PREC_PRIMARY,
[EXPR_BUILTIN_PREFETCH] = PREC_PRIMARY,
[EXPR_OFFSETOF] = PREC_PRIMARY,
[EXPR_VA_START] = PREC_PRIMARY,
fputc(')', out);
}
-/**
- * Prints a builtin address expression.
- *
- * @param expression the builtin address expression
- */
-static void print_builtin_address(const builtin_address_expression_t *expression)
-{
- fputs(expression->kind == builtin_return_address ?
- "__builtin_return_address(" : "__builtin_frame_address(", out);
- print_assignment_expression(expression->value);
- fputc(')', out);
-}
-
/**
* Prints a builtin prefetch expression.
*
case EXPR_BUILTIN_CONSTANT_P:
print_builtin_constant(&expression->builtin_constant);
break;
- case EXPR_BUILTIN_ADDRESS:
- print_builtin_address(&expression->builtin_address);
- break;
case EXPR_BUILTIN_PREFETCH:
print_builtin_prefetch(&expression->builtin_prefetch);
break;
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_PREFETCH:
- case EXPR_BUILTIN_ADDRESS:
case EXPR_SELECT:
case EXPR_VA_START:
case EXPR_VA_ARG:
typedef struct va_arg_expression_t va_arg_expression_t;
typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
typedef struct builtin_constant_expression_t builtin_constant_expression_t;
-typedef struct builtin_address_expression_t builtin_address_expression_t;
typedef struct builtin_prefetch_expression_t builtin_prefetch_expression_t;
typedef struct classify_type_expression_t classify_type_expression_t;
typedef struct bitfield_extract_expression_t bitfield_extract_expression_t;
}
case T___builtin_va_end:
/* evaluate the argument of va_end for its side effects */
- _expression_to_firm(call->arguments->expression);
+ _expression_to_firm(call->arguments->expression);
return NULL;
+ case T___builtin_frame_address: {
+ long val = fold_constant(call->arguments->expression);
+ if (val == 0) {
+ /* this nice case */
+ return get_irg_frame(current_ir_graph);
+ }
+ panic("__builtin_frame_address(!= 0) not implemented yet");
+ }
+ case T___builtin_return_address:
+ panic("__builtin_return_address() not implemented yet");
default:
panic("unsupported builtin found");
}
return new_Const_long(mode, v);
}
-static ir_node *builtin_address_to_firm(
- const builtin_address_expression_t *expression)
-{
- (void)expression;
- panic("builtin_address_expression not implemented yet");
-}
-
static ir_node *builtin_prefetch_to_firm(
const builtin_prefetch_expression_t *expression)
{
return builtin_symbol_to_firm(&expression->builtin_symbol);
case EXPR_BUILTIN_CONSTANT_P:
return builtin_constant_to_firm(&expression->builtin_constant);
- case EXPR_BUILTIN_ADDRESS:
- return builtin_address_to_firm(&expression->builtin_address);
case EXPR_BUILTIN_PREFETCH:
return builtin_prefetch_to_firm(&expression->builtin_prefetch);
case EXPR_OFFSETOF:
EXPR_FUNCNAME,
EXPR_BUILTIN_SYMBOL,
EXPR_BUILTIN_CONSTANT_P,
- EXPR_BUILTIN_ADDRESS,
EXPR_BUILTIN_PREFETCH,
EXPR_OFFSETOF,
EXPR_VA_START,
expression_t *value;
};
-typedef enum buitin_address_kind {
- builtin_return_address,
- builtin_frame_address
-} builtin_address_kind;
-
-struct builtin_address_expression_t {
- expression_base_t base;
- builtin_address_kind kind;
- expression_t *value;
-};
-
struct builtin_prefetch_expression_t {
expression_base_t base;
expression_t *adr;
compound_literal_expression_t compound_literal;
builtin_symbol_expression_t builtin_symbol;
builtin_constant_expression_t builtin_constant;
- builtin_address_expression_t builtin_address;
builtin_prefetch_expression_t builtin_prefetch;
reference_expression_t reference;
call_expression_t call;
[EXPR_FUNCNAME] = sizeof(funcname_expression_t),
[EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
[EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
- [EXPR_BUILTIN_ADDRESS] = sizeof(builtin_address_expression_t),
[EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
[EXPR_OFFSETOF] = sizeof(offsetof_expression_t),
[EXPR_VA_START] = sizeof(va_start_expression_t),
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
- case EXPR_BUILTIN_ADDRESS:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_STATEMENT: // TODO
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
- case EXPR_BUILTIN_ADDRESS:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_INVALID:
return create_invalid_expression();
}
-/**
- * Parses a __buildin_return_address of a __builtin_frame_address() expression.
- *
- * @param tok_type either T___buildin_return_address or T___builtin_frame_address
- */
-static expression_t *parse_builtin_address(int tok_type)
-{
- expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_ADDRESS);
-
- expression->builtin_address.kind = tok_type == T___builtin_return_address ?
- builtin_return_address : builtin_frame_address;
-
- eat(tok_type);
-
- expect('(', end_error);
- add_anchor_token(')');
- expression->builtin_address.value = parse_constant_expression();
- rem_anchor_token(')');
- expect(')', end_error);
- expression->base.type = type_void_ptr;
-
- return expression;
-end_error:
- return create_invalid_expression();
-}
-
/**
* Parses a __builtin_is_*() compare expression.
*/
case T___builtin_nanf:
case T___builtin_nanl:
case T___builtin_huge_val:
- case T___builtin_va_end: return parse_builtin_symbol();
+ case T___builtin_va_end:
+ case T___builtin_return_address:
+ case T___builtin_frame_address: return parse_builtin_symbol();
case T___builtin_isgreater:
case T___builtin_isgreaterequal:
case T___builtin_isless:
case T___builtin_isunordered: return parse_compare_builtin();
case T___builtin_constant_p: return parse_builtin_constant();
case T___builtin_prefetch: return parse_builtin_prefetch();
- case T___builtin_return_address: return parse_builtin_address(T___builtin_return_address);
- case T___builtin_frame_address: return parse_builtin_address(T___builtin_frame_address);
case T__assume: return parse_assume();
case T_ANDAND:
if (GNU_MODE)
}
}
+/**
+ * Handle the semantic restrictions of builtin calls
+ */
+static void handle_builtin_argument_restrictions(call_expression_t *call) {
+ switch (call->function->builtin_symbol.symbol->ID) {
+ case T___builtin_return_address:
+ case T___builtin_frame_address: {
+ /* argument must be constant */
+ call_argument_t *argument = call->arguments;
+
+ if (! is_constant_expression(argument->expression)) {
+ errorf(&call->base.source_position,
+ "argument of '%Y' must be a constant expression",
+ call->function->builtin_symbol.symbol);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
/**
* Parse a call expression, ie. expression '( ... )'.
*
"function call has aggregate value");
}
+ if (call->function->kind == EXPR_BUILTIN_SYMBOL) {
+ handle_builtin_argument_restrictions(&result->call);
+ }
+
end_error:
return result;
}
case EXPR_FUNCNAME: return false;
case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */
case EXPR_BUILTIN_CONSTANT_P: return false;
- case EXPR_BUILTIN_ADDRESS: return false;
case EXPR_BUILTIN_PREFETCH: return true;
case EXPR_OFFSETOF: return false;
case EXPR_VA_START: return true;
walk_expression(expr->conditional.false_expression, callback, env);
return;
- case EXPR_BUILTIN_ADDRESS:
- walk_expression(expr->builtin_address.value, callback, env);
- return;
-
case EXPR_BUILTIN_PREFETCH: {
builtin_prefetch_expression_t const *const pf = &expr->builtin_prefetch;
walk_expression(pf->adr, callback, env);