- implement __alignof__
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 7 Dec 2007 00:32:34 +0000 (00:32 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 7 Dec 2007 00:32:34 +0000 (00:32 +0000)
- use SymConsts of sizeof, alignof
- use new SymConst constructors

[r18636]

ast.c
ast.h
ast2firm.c
ast_t.h
parser.c

diff --git a/ast.c b/ast.c
index 43387ff..4cfa3db 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -270,6 +270,13 @@ static void print_sizeof_expression(const sizeof_expression_t *expression)
        }
 }
 
+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);
@@ -392,6 +399,9 @@ void print_expression(const expression_t *expression)
        case EXPR_SIZEOF:
                print_sizeof_expression(&expression->sizeofe);
                break;
+       case EXPR_ALIGNOF:
+               print_alignof_expression(&expression->alignofe);
+               break;
        case EXPR_BUILTIN_SYMBOL:
                print_builtin_symbol(&expression->builtin_symbol);
                break;
diff --git a/ast.h b/ast.h
index 2fa7c4c..709420d 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -20,6 +20,7 @@ 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 conditional_expression_t         conditional_expression_t;
 typedef struct expression_list_element_t        expression_list_element_t;
 typedef struct comma_expression_t               comma_expression_t;
index c0bb332..a452d0b 100644 (file)
@@ -812,12 +812,12 @@ static ir_node *const_to_firm(const const_expression_t *cnst)
        return new_d_Const(dbgi, mode, tv);
 }
 
-static ir_node *create_symconst(dbg_info *dbgi, ir_entity *entity)
+static ir_node *create_symconst(dbg_info *dbgi, ir_mode *mode, ir_entity *entity)
 {
        assert(entity != NULL);
        union symconst_symbol sym;
        sym.entity_p = entity;
-       return new_d_SymConst(dbgi, sym, symconst_addr_ent);
+       return new_d_SymConst(dbgi, mode, sym, symconst_addr_ent);
 }
 
 static ir_node *string_to_firm(const source_position_t *const src_pos,
@@ -853,7 +853,7 @@ static ir_node *string_to_firm(const source_position_t *const src_pos,
        set_array_entity_values(entity, tvs, slen);
        free(tvs);
 
-       return create_symconst(dbgi, entity);
+       return create_symconst(dbgi, mode_P_data, entity);
 }
 
 static ir_node *string_literal_to_firm(
@@ -896,7 +896,7 @@ static ir_node *wide_string_literal_to_firm(
        set_array_entity_values(entity, tvs, slen);
        free(tvs);
 
-       return create_symconst(dbgi, entity);
+       return create_symconst(dbgi, mode_P_data, entity);
 }
 
 static ir_node *deref_address(ir_type *const irtype, ir_node *const addr,
@@ -951,7 +951,7 @@ static ir_node *get_global_var_address(dbg_info *const dbgi,
                }
 
                default:
-                       return create_symconst(dbgi, entity);
+                       return create_symconst(dbgi, mode_P_data, entity);
        }
 }
 
@@ -975,11 +975,12 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        }
 
        case DECLARATION_TYPE_LOCAL_VARIABLE: {
-               ir_mode *mode = get_ir_mode(type);
+               ir_mode *const mode = get_ir_mode(type);
                return get_value(declaration->v.value_number, mode);
        }
        case DECLARATION_TYPE_FUNCTION: {
-               return create_symconst(dbgi, declaration->v.entity);
+               ir_mode *const mode = get_ir_mode(type);
+               return create_symconst(dbgi, mode, declaration->v.entity);
        }
        case DECLARATION_TYPE_GLOBAL_VARIABLE: {
                ir_node *const addr   = get_global_var_address(dbgi, declaration);
@@ -1014,7 +1015,9 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        case DECLARATION_TYPE_LOCAL_VARIABLE:
                panic("local variable without entity has no address");
        case DECLARATION_TYPE_FUNCTION: {
-               return create_symconst(dbgi, declaration->v.entity);
+               type_t *const  type = skip_typeref(ref->expression.datatype);
+               ir_mode *const mode = get_ir_mode(type);
+               return create_symconst(dbgi, mode, declaration->v.entity);
        }
        case DECLARATION_TYPE_GLOBAL_VARIABLE: {
                ir_node *const addr = get_global_var_address(dbgi, declaration);
@@ -1863,11 +1866,19 @@ static ir_node *sizeof_to_firm(const sizeof_expression_t *expression)
                assert(type != NULL);
        }
 
-       ir_mode  *mode      = get_ir_mode(expression->expression.datatype);
-       unsigned  size      = get_type_size(type);
-       ir_node  *size_node = new_Const_long(mode, size);
+       ir_mode *const mode = get_ir_mode(expression->expression.datatype);
+       symconst_symbol sym;
+       sym.type_p = get_ir_type(type);
+       return new_SymConst(mode, sym, symconst_type_size);
+}
 
-       return size_node;
+static ir_node *alignof_to_firm(const alignof_expression_t *expression)
+{
+       type_t *const  type = expression->type;
+       ir_mode *const mode = get_ir_mode(expression->expression.datatype);
+       symconst_symbol sym;
+       sym.type_p = get_ir_type(type);
+       return new_SymConst(mode, sym, symconst_type_align);
 }
 
 static long fold_constant(const expression_t *expression)
@@ -2183,6 +2194,8 @@ static ir_node *_expression_to_firm(const expression_t *expression)
                return array_access_to_firm(&expression->array_access);
        case EXPR_SIZEOF:
                return sizeof_to_firm(&expression->sizeofe);
+       case EXPR_ALIGNOF:
+               return alignof_to_firm(&expression->alignofe);
        case EXPR_CONDITIONAL:
                return conditional_to_firm(&expression->conditional);
        case EXPR_SELECT:
@@ -2578,7 +2591,7 @@ static void create_initializer_local_variable_entity(declaration_t *declaration)
        assert(current_ir_graph == get_const_code_irg());
        current_ir_graph = old_current_ir_graph;
 
-       ir_node *const src_addr  = create_symconst(dbgi, init_entity);
+       ir_node *const src_addr  = create_symconst(dbgi, mode_P_data, init_entity);
        ir_node *const copyb     = new_d_CopyB(dbgi, memory, addr, src_addr, irtype);
 
        ir_node *const copyb_mem = new_Proj(copyb, mode_M, pn_CopyB_M_regular);
diff --git a/ast_t.h b/ast_t.h
index 5860cc1..1bc501f 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -25,6 +25,7 @@ typedef enum {
        EXPR_ARRAY_ACCESS,
        EXPR_SIZEOF,
        EXPR_CLASSIFY_TYPE,
+       EXPR_ALIGNOF,
 
        EXPR_FUNCTION,
        EXPR_PRETTY_FUNCTION,
@@ -229,6 +230,11 @@ struct sizeof_expression_t {
        expression_t      *size_expression;
 };
 
+struct alignof_expression_t {
+       expression_base_t  expression;
+       type_t            *type;
+};
+
 struct designator_t {
        symbol_t     *symbol;
        expression_t *array_access;
@@ -289,6 +295,7 @@ union expression_t {
        conditional_expression_t         conditional;
        statement_expression_t           statement;
        classify_type_expression_t       classify_type;
+       alignof_expression_t             alignofe;
 };
 
 typedef enum {
index 20cb99c..5ad72c2 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3413,6 +3413,20 @@ static expression_t *parse_assume(void) {
        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) {
@@ -3450,6 +3464,8 @@ static expression_t *parse_primary_expression(void)
        case T___builtin_islessgreater:
        case T___builtin_isunordered:
                return parse_compare_builtin();
+       case T___alignof__:
+               return parse_alignof();
        case T_assume:
                return parse_assume();