- reimplemented __builtin_frame_address() and __builtin_return_address() as a builtin...
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Dec 2008 10:53:43 +0000 (10:53 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Dec 2008 10:53:43 +0000 (10:53 +0000)
- generate code for __builtin_frame_address(0)

[r24773]

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

diff --git a/ast.c b/ast.c
index 0ace5f4..a3eb83a 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -116,7 +116,6 @@ 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,
@@ -609,19 +608,6 @@ 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.
  *
@@ -839,9 +825,6 @@ 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;
@@ -1884,7 +1867,6 @@ 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 f6eee84..938181b 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -50,7 +50,6 @@ 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 ed5610b..1ec4681 100644 (file)
@@ -1645,8 +1645,18 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        }
        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");
        }
@@ -3156,13 +3166,6 @@ 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)
-{
-       (void)expression;
-       panic("builtin_address_expression not implemented yet");
-}
-
 static ir_node *builtin_prefetch_to_firm(
                const builtin_prefetch_expression_t *expression)
 {
@@ -3287,8 +3290,6 @@ 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:
diff --git a/ast_t.h b/ast_t.h
index 423591f..2c32f85 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -83,7 +83,6 @@ 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,
@@ -281,17 +280,6 @@ 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;
@@ -401,7 +389,6 @@ 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 b8d2ebe..d4e3abc 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -430,7 +430,6 @@ 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),
@@ -2140,7 +2139,6 @@ 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
@@ -5748,7 +5746,6 @@ 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:
@@ -7575,32 +7572,6 @@ 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.
  */
@@ -7839,7 +7810,9 @@ static expression_t *parse_primary_expression(void)
                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:
@@ -7848,8 +7821,6 @@ 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)
@@ -8133,6 +8104,28 @@ static void check_call_argument(const function_parameter_t *parameter,
        }
 }
 
+/**
+ * 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 '( ... )'.
  *
@@ -8225,6 +8218,10 @@ static expression_t *parse_call_expression(expression_t *expression)
                         "function call has aggregate value");
        }
 
+       if (call->function->kind == EXPR_BUILTIN_SYMBOL) {
+               handle_builtin_argument_restrictions(&result->call);
+       }
+
 end_error:
        return result;
 }
@@ -9395,7 +9392,6 @@ static bool expression_has_effect(const expression_t *const expr)
                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;
index 52e6046..8edc790 100644 (file)
@@ -49,10 +49,6 @@ static void walk_expression(expression_t const *const expr,
                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);