- implemented __builtin_(return|frame)_address() FE support
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 17 Dec 2008 23:46:51 +0000 (23:46 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 17 Dec 2008 23:46:51 +0000 (23:46 +0000)
- fixed some warnings

[r24764]

ast.c
ast.h
ast2firm.c
ast_t.h
parser.c
tokens.inc

diff --git a/ast.c b/ast.c
index b54b745..78ff46a 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -116,6 +116,7 @@ static unsigned get_expression_precedence(expression_kind_t kind)
                [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,
@@ -608,6 +609,19 @@ static void print_builtin_constant(const builtin_constant_expression_t *expressi
        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.
  *
@@ -825,6 +839,9 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
        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;
@@ -1869,6 +1886,7 @@ bool is_constant_expression(const expression_t *expression)
 
        case EXPR_BUILTIN_SYMBOL:
        case EXPR_BUILTIN_PREFETCH:
+       case EXPR_BUILTIN_ADDRESS:
        case EXPR_SELECT:
        case EXPR_VA_START:
        case EXPR_VA_ARG:
diff --git a/ast.h b/ast.h
index 938181b..f6eee84 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -50,6 +50,7 @@ typedef struct va_start_expression_t            va_start_expression_t;
 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;
index e558b9b..28ccd7e 100644 (file)
@@ -1375,7 +1375,7 @@ static ir_node *deref_address(dbg_info *const dbgi, type_t *const type,
        }
 
        ir_cons_flags  flags    = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE
-                                 ? cons_volatile : 0;
+                                 ? cons_volatile : cons_none;
        ir_mode *const mode     = get_type_mode(irtype);
        ir_node *const memory   = get_store();
        ir_node *const load     = new_d_Load(dbgi, memory, addr, mode, flags);
@@ -1389,7 +1389,7 @@ static ir_node *deref_address(dbg_info *const dbgi, type_t *const type,
 }
 
 /**
- * Creates a strict Conv if neccessary.
+ * Creates a strict Conv if necessary.
  */
 static ir_node *do_strict_conv(dbg_info *dbgi, ir_node *node)
 {
@@ -1813,7 +1813,7 @@ static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type,
 
        if (is_type_scalar(type)) {
                ir_cons_flags flags = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE
-                                     ? cons_volatile : 0;
+                                     ? cons_volatile : cons_none;
                ir_node  *store     = new_d_Store(dbgi, memory, addr, value, flags);
                ir_node  *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M);
                set_store(store_mem);
@@ -1871,7 +1871,7 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
        /* load current value */
        ir_node  *mem             = get_store();
        ir_node  *load            = new_d_Load(dbgi, mem, addr, mode,
-                                       set_volatile ? cons_volatile : 0);
+                                       set_volatile ? cons_volatile : cons_none);
        ir_node  *load_mem        = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
        ir_node  *load_res        = new_d_Proj(dbgi, load, mode, pn_Load_res);
        tarval   *shift_mask      = create_bitfield_mask(mode, bitoffset, bitsize);
@@ -1882,7 +1882,7 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
        /* construct new value and store */
        ir_node *new_val   = new_d_Or(dbgi, load_res_masked, value_maskshift, mode);
        ir_node *store     = new_d_Store(dbgi, load_mem, addr, new_val,
-                                        set_volatile ? cons_volatile : 0);
+                                        set_volatile ? cons_volatile : cons_none);
        ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M);
        set_store(store_mem);
 
@@ -1896,7 +1896,7 @@ static ir_node *bitfield_extract_to_firm(const select_expression_t *expression,
        type_t   *type     = expression->base.type;
        ir_mode  *mode     = get_ir_mode_storage(type);
        ir_node  *mem      = get_store();
-       ir_node  *load     = new_d_Load(dbgi, mem, addr, mode, 0);
+       ir_node  *load     = new_d_Load(dbgi, mem, addr, mode, cons_none);
        ir_node  *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
        ir_node  *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res);
 
@@ -3156,6 +3156,12 @@ static ir_node *builtin_constant_to_firm(
        return new_Const_long(mode, v);
 }
 
+static ir_node *builtin_address_to_firm(
+               const builtin_address_expression_t *expression)
+{
+       panic("builtin_address_expression not implemented yet");
+}
+
 static ir_node *builtin_prefetch_to_firm(
                const builtin_prefetch_expression_t *expression)
 {
@@ -3280,6 +3286,8 @@ static ir_node *_expression_to_firm(const 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:
@@ -3896,7 +3904,7 @@ static void create_dynamic_null_initializer(ir_type *type, dbg_info *dbgi,
 
                /* TODO: bitfields */
                ir_node *mem    = get_store();
-               ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst, 0);
+               ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst, cons_none);
                ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
                set_store(proj_m);
        } else {
@@ -3954,7 +3962,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
 
                assert(get_type_mode(type) == mode);
                ir_node *mem    = get_store();
-               ir_node *store  = new_d_Store(dbgi, mem, base_addr, node, 0);
+               ir_node *store  = new_d_Store(dbgi, mem, base_addr, node, cons_none);
                ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
                set_store(proj_m);
                return;
@@ -3974,7 +3982,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
 
                assert(get_type_mode(type) == mode);
                ir_node *mem    = get_store();
-               ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst, 0);
+               ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst, cons_none);
                ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
                set_store(proj_m);
                return;
diff --git a/ast_t.h b/ast_t.h
index 2c32f85..423591f 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -83,6 +83,7 @@ typedef enum expression_kind_t {
        EXPR_FUNCNAME,
        EXPR_BUILTIN_SYMBOL,
        EXPR_BUILTIN_CONSTANT_P,
+       EXPR_BUILTIN_ADDRESS,
        EXPR_BUILTIN_PREFETCH,
        EXPR_OFFSETOF,
        EXPR_VA_START,
@@ -280,6 +281,17 @@ struct builtin_constant_expression_t {
        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;
@@ -389,6 +401,7 @@ union expression_t {
        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;
index 5c189c2..5ab8418 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -430,6 +430,7 @@ static size_t get_expression_struct_size(expression_kind_t kind)
                [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),
@@ -2139,6 +2140,7 @@ unary:
                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
@@ -5126,7 +5128,7 @@ static entity_t *record_entity(entity_t *entity, const bool is_definition)
                                         prev_decl->type, symbol);
                        }
 
-                       storage_class_tag_t new_storage_class = decl->storage_class;
+                       storage_class_t new_storage_class = decl->storage_class;
 
                        /* pretend no storage class means extern for function
                         * declarations (except if the previous declaration is neither
@@ -5746,6 +5748,7 @@ static bool expression_returns(expression_t const *const expr)
                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:
@@ -6939,6 +6942,9 @@ static type_t *get_builtin_symbol_type(symbol_t *symbol)
                return make_function_1_type(type_void, type_valist);
        case T___builtin_expect:
                return make_function_2_type(type_long, type_long, type_long);
+       case T___builtin_return_address:
+       case T___builtin_frame_address:
+               return make_function_1_type(type_void_ptr, type_unsigned_int);
        default:
                internal_errorf(HERE, "not implemented builtin identifier found");
        }
@@ -7569,6 +7575,32 @@ end_error:
        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.
  */
@@ -7816,6 +7848,8 @@ static expression_t *parse_primary_expression(void)
                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)
index 22990df..16a8215 100644 (file)
@@ -109,6 +109,8 @@ S(_ALL, __builtin_isunordered)
 S(_ALL, __builtin_constant_p)
 S(_ALL, __builtin_prefetch)
 S(_ALL, __builtin_huge_val)
+S(_ALL, __builtin_return_address)
+S(_ALL, __builtin_frame_address)
 S(_ALL, __PRETTY_FUNCTION__)
 S(_ALL, __FUNCTION__)
 S(_ALL, __label__)