}
}
-static void print_sizeof_expression(const sizeof_expression_t *expression)
+static void print_typeprop_expression(const typeprop_expression_t *expression)
{
- fputs("sizeof", out);
- if(expression->size_expression != NULL) {
+ if (expression->expression.kind == EXPR_SIZEOF) {
+ fputs("sizeof", out);
+ } else {
+ assert(expression->expression.kind == EXPR_ALIGNOF);
+ fputs("__alignof__", out);
+ }
+ if(expression->tp_expression != NULL) {
fputc('(', out);
- print_expression(expression->size_expression);
+ print_expression(expression->tp_expression);
fputc(')', out);
} else {
fputc('(', out);
}
}
-static void print_alignof_expression(const alignof_expression_t *expression)
-{
- fputs("__alignof__(", out);
- print_type(expression->type);
- fputc(')', out);
-}
-
static void print_builtin_symbol(const builtin_symbol_expression_t *expression)
{
fputs(expression->symbol->string, out);
print_unary_expression(&expression->unary);
break;
case EXPR_SIZEOF:
- print_sizeof_expression(&expression->sizeofe);
- break;
case EXPR_ALIGNOF:
- print_alignof_expression(&expression->alignofe);
+ print_typeprop_expression(&expression->typeprop);
break;
case EXPR_BUILTIN_SYMBOL:
print_builtin_symbol(&expression->builtin_symbol);
typedef struct unary_expression_t unary_expression_t;
typedef struct select_expression_t select_expression_t;
typedef struct array_access_expression_t array_access_expression_t;
-typedef struct sizeof_expression_t sizeof_expression_t;
-typedef struct alignof_expression_t alignof_expression_t;
+typedef struct typeprop_expression_t typeprop_expression_t;
+typedef struct typeprop_expression_t typeprop_expression_t;
typedef struct conditional_expression_t conditional_expression_t;
typedef struct expression_list_element_t expression_list_element_t;
typedef struct comma_expression_t comma_expression_t;
return deref_address(irtype, addr, dbgi);
}
-static ir_node *sizeof_to_firm(const sizeof_expression_t *expression)
+/**
+ * Transform a sizeof expression into Firm code.
+ */
+static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
{
type_t *type = expression->type;
if(type == NULL) {
- type = expression->size_expression->base.datatype;
+ type = expression->tp_expression->base.datatype;
assert(type != NULL);
}
return new_SymConst(mode, sym, symconst_type_size);
}
-static ir_node *alignof_to_firm(const alignof_expression_t *expression)
+/**
+ * Transform an alignof expression into Firm code.
+ */
+static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
{
- type_t *const type = expression->type;
+ type_t *type = expression->type;
+ if(type == NULL) {
+ type = expression->tp_expression->base.datatype;
+ assert(type != NULL);
+ }
+
ir_mode *const mode = get_ir_mode(expression->expression.datatype);
symconst_symbol sym;
sym.type_p = get_ir_type(type);
case EXPR_ARRAY_ACCESS:
return array_access_to_firm(&expression->array_access);
case EXPR_SIZEOF:
- return sizeof_to_firm(&expression->sizeofe);
+ return sizeof_to_firm(&expression->typeprop);
case EXPR_ALIGNOF:
- return alignof_to_firm(&expression->alignofe);
+ return alignof_to_firm(&expression->typeprop);
case EXPR_CONDITIONAL:
return conditional_to_firm(&expression->conditional);
case EXPR_SELECT:
bool flipped; /* index/ref was written in a 5[a] way */
};
-struct sizeof_expression_t {
- expression_base_t expression;
- type_t *type;
- expression_t *size_expression;
-};
-
-struct alignof_expression_t {
+struct typeprop_expression_t {
expression_base_t expression;
type_t *type;
+ expression_t *tp_expression;
};
struct designator_t {
binary_expression_t binary;
select_expression_t select;
array_access_expression_t array_access;
- sizeof_expression_t sizeofe;
+ typeprop_expression_t typeprop;
offsetof_expression_t offsetofe;
va_start_expression_t va_starte;
va_arg_expression_t va_arge;
conditional_expression_t conditional;
statement_expression_t statement;
classify_type_expression_t classify_type;
- alignof_expression_t alignofe;
};
typedef enum {
[EXPR_CONDITIONAL] = sizeof(conditional_expression_t),
[EXPR_SELECT] = sizeof(select_expression_t),
[EXPR_ARRAY_ACCESS] = sizeof(array_access_expression_t),
- [EXPR_SIZEOF] = sizeof(sizeof_expression_t),
+ [EXPR_SIZEOF] = sizeof(typeprop_expression_t),
+ [EXPR_ALIGNOF] = sizeof(typeprop_expression_t),
[EXPR_CLASSIFY_TYPE] = sizeof(classify_type_expression_t),
[EXPR_FUNCTION] = sizeof(string_literal_expression_t),
[EXPR_PRETTY_FUNCTION] = sizeof(string_literal_expression_t),
return expression;
}
-static expression_t *parse_alignof(void) {
- eat(T___alignof__);
-
- expression_t *expression
- = allocate_expression_zero(EXPR_ALIGNOF);
-
- expect('(');
- expression->alignofe.type = parse_typename();
- expect(')');
-
- expression->base.datatype = type_size_t;
- return expression;
-}
-
static expression_t *parse_primary_expression(void)
{
switch(token.type) {
return parse_builtin_constant();
case T___builtin_prefetch:
return parse_builtin_prefetch();
- case T___alignof__:
- return parse_alignof();
case T_assume:
return parse_assume();
return (expression_t*) array_access;
}
-static expression_t *parse_sizeof(unsigned precedence)
+static expression_t *parse_typeprop(expression_kind_t kind, unsigned precedence)
{
- eat(T_sizeof);
-
- sizeof_expression_t *sizeof_expression
- = allocate_ast_zero(sizeof(sizeof_expression[0]));
- sizeof_expression->expression.kind = EXPR_SIZEOF;
- sizeof_expression->expression.datatype = type_size_t;
+ expression_t *tp_expression
+ = allocate_expression_zero(kind);
+ tp_expression->base.datatype = type_size_t;
if(token.type == '(' && is_declaration_specifier(look_ahead(1), true)) {
next_token();
- sizeof_expression->type = parse_typename();
+ tp_expression->typeprop.type = parse_typename();
expect(')');
} else {
expression_t *expression = parse_sub_expression(precedence);
expression->base.datatype = revert_automatic_type_conversion(expression);
- sizeof_expression->type = expression->base.datatype;
- sizeof_expression->size_expression = expression;
+ tp_expression->typeprop.type = expression->base.datatype;
+ tp_expression->typeprop.tp_expression = expression;
}
- return (expression_t*) sizeof_expression;
+ return tp_expression;
+}
+
+static expression_t *parse_sizeof(unsigned precedence)
+{
+ eat(T_sizeof);
+ return parse_typeprop(EXPR_SIZEOF, precedence);
+}
+
+static expression_t *parse_alignof(unsigned precedence)
+{
+ eat(T___alignof__);
+ return parse_typeprop(EXPR_SIZEOF, precedence);
}
static expression_t *parse_select_expression(unsigned precedence,
T_PLUSPLUS, 25);
register_expression_parser(parse_EXPR_UNARY_PREFIX_DECREMENT,
T_MINUSMINUS, 25);
- register_expression_parser(parse_sizeof, T_sizeof, 25);
+ register_expression_parser(parse_sizeof, T_sizeof, 25);
+ register_expression_parser(parse_alignof, T___alignof__, 25);
register_expression_parser(parse_extension, T___extension__, 25);
register_expression_parser(parse_builtin_classify_type,
T___builtin_classify_type, 25);