__builtin_constant_p() implemented
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 7 Dec 2007 15:47:56 +0000 (15:47 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 7 Dec 2007 15:47:56 +0000 (15:47 +0000)
[r18641]

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

diff --git a/ast.c b/ast.c
index 4f4a13f..11c25ce 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -282,6 +282,13 @@ static void print_builtin_symbol(const builtin_symbol_expression_t *expression)
        fputs(expression->symbol->string, out);
 }
 
+static void print_builtin_constant(const builtin_constant_expression_t *expression)
+{
+       fputs("__builtin_constant_p(", out);
+       print_expression(expression->value);
+       fputs(")", out);
+}
+
 static void print_conditional(const conditional_expression_t *expression)
 {
        fputs("(", out);
@@ -405,6 +412,9 @@ void print_expression(const expression_t *expression)
        case EXPR_BUILTIN_SYMBOL:
                print_builtin_symbol(&expression->builtin_symbol);
                break;
+       case EXPR_BUILTIN_CONSTANT_P:
+               print_builtin_constant(&expression->builtin_constant);
+               break;
        case EXPR_CONDITIONAL:
                print_conditional(&expression->conditional);
                break;
@@ -819,6 +829,7 @@ bool is_constant_expression(const expression_t *expression)
        case EXPR_PRETTY_FUNCTION:
        case EXPR_OFFSETOF:
        case EXPR_ALIGNOF:
+       case EXPR_BUILTIN_CONSTANT_P:
                return true;
 
        case EXPR_BUILTIN_SYMBOL:
diff --git a/ast.h b/ast.h
index 709420d..2674146 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -30,6 +30,7 @@ typedef struct offsetof_expression_t            offsetof_expression_t;
 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 classify_type_expression_t       classify_type_expression_t;
 typedef union  expression_t                     expression_t;
 
index 304c82d..25545b8 100644 (file)
@@ -2173,6 +2173,19 @@ static ir_node *expression_to_addr(const expression_t *expression)
        panic("trying to get address of non-lvalue");
 }
 
+static ir_node *builtin_constant_to_firm(const builtin_constant_expression_t *expression)
+{
+       ir_mode *mode = get_ir_mode(expression->expression.datatype);
+       long     v;
+
+       if (is_constant_expression(expression->value)) {
+               v = 1;
+       } else {
+               v = 0;
+       }
+       return new_Const_long(mode, v);
+}
+
 static ir_node *_expression_to_firm(const expression_t *expression)
 {
        switch(expression->kind) {
@@ -2214,6 +2227,8 @@ static ir_node *_expression_to_firm(const expression_t *expression)
        case EXPR_OFFSETOF:
        case EXPR_BUILTIN_SYMBOL:
                panic("unimplemented expression found");
+       case EXPR_BUILTIN_CONSTANT_P:
+               return builtin_constant_to_firm(&expression->builtin_constant);
 
        case EXPR_UNKNOWN:
        case EXPR_INVALID:
diff --git a/ast_t.h b/ast_t.h
index 792af0c..56bca34 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -30,6 +30,7 @@ typedef enum {
        EXPR_FUNCTION,
        EXPR_PRETTY_FUNCTION,
        EXPR_BUILTIN_SYMBOL,
+       EXPR_BUILTIN_CONSTANT_P,
        EXPR_OFFSETOF,
        EXPR_VA_START,
        EXPR_VA_ARG,
@@ -181,6 +182,11 @@ struct builtin_symbol_expression_t {
        symbol_t          *symbol;
 };
 
+struct builtin_constant_expression_t {
+       expression_base_t  expression;
+       expression_t      *value;
+};
+
 struct reference_expression_t {
        expression_base_t  expression;
        symbol_t          *symbol;
@@ -282,6 +288,7 @@ union expression_t {
        string_literal_expression_t      string;
        wide_string_literal_expression_t wide_string;
        builtin_symbol_expression_t      builtin_symbol;
+       builtin_constant_expression_t    builtin_constant;
        reference_expression_t           reference;
        call_expression_t                call;
        unary_expression_t               unary;
index 0dde06f..5d2a6ab 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -180,6 +180,7 @@ static size_t get_expression_struct_size(expression_kind_t type)
                [EXPR_FUNCTION]            = sizeof(string_literal_expression_t),
                [EXPR_PRETTY_FUNCTION]     = sizeof(string_literal_expression_t),
                [EXPR_BUILTIN_SYMBOL]      = sizeof(builtin_symbol_expression_t),
+               [EXPR_BUILTIN_CONSTANT_P]  = sizeof(builtin_constant_expression_t),
                [EXPR_OFFSETOF]            = sizeof(offsetof_expression_t),
                [EXPR_VA_START]            = sizeof(va_start_expression_t),
                [EXPR_VA_ARG]              = sizeof(va_arg_expression_t),
@@ -3177,6 +3178,20 @@ static expression_t *parse_builtin_symbol(void)
        return expression;
 }
 
+static expression_t *parse_builtin_constant(void)
+{
+       eat(T___builtin_constant_p);
+
+       expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_CONSTANT_P);
+
+       expect('(');
+       expression->builtin_constant.value = parse_expression();
+       expect(')');
+       expression->base.datatype = type_int;
+
+       return expression;
+}
+
 static expression_t *parse_compare_builtin(void)
 {
        expression_t *expression;
@@ -3312,6 +3327,8 @@ static expression_t *parse_primary_expression(void)
        case T___builtin_islessgreater:
        case T___builtin_isunordered:
                return parse_compare_builtin();
+       case T___builtin_constant_p:
+               return parse_builtin_constant();
        case T___alignof__:
                return parse_alignof();
        case T_assume:
index e01ffd4..17ca6a3 100644 (file)
@@ -61,6 +61,7 @@ S(_GNUC, __builtin_isless)
 S(_GNUC, __builtin_islessequal)
 S(_GNUC, __builtin_islessgreater)
 S(_GNUC, __builtin_isunordered)
+S(_GNUC, __builtin_constant_p)
 S(_C99, __PRETTY_FUNCTION__)
 S(_ALL, __FUNCTION__)
 S(_C99, __func__)