builtin_nanf is const
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index 175f632..690bec4 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -137,7 +137,6 @@ static unsigned get_expression_precedence(expression_kind_t kind)
                [EXPR_UNARY_CAST]                = PREC_UNARY,
                [EXPR_UNARY_CAST_IMPLICIT]       = PREC_UNARY,
                [EXPR_UNARY_ASSUME]              = PREC_PRIM,
-               [EXPR_UNARY_BITFIELD_EXTRACT]    = PREC_ACCESS,
 
                [EXPR_BINARY_ADD]                = PREC_PLUS,
                [EXPR_BINARY_SUB]                = PREC_PLUS,
@@ -455,10 +454,6 @@ static void print_unary_expression(const unary_expression_t *unexpr)
        case EXPR_UNARY_DEREFERENCE:      fputs("*", out);  break;
        case EXPR_UNARY_TAKE_ADDRESS:     fputs("&", out);  break;
 
-       case EXPR_UNARY_BITFIELD_EXTRACT:
-               print_expression_prec(unexpr->value, prec);
-               return;
-
        case EXPR_UNARY_POSTFIX_INCREMENT:
                print_expression_prec(unexpr->value, prec);
                fputs("++", out);
@@ -1096,6 +1091,37 @@ end_of_print_asm_statement:
        fputs(");\n", out);
 }
 
+/**
+ * Print a microsoft __try statement.
+ *
+ * @param statement   the statement
+ */
+static void print_ms_try_statement(const ms_try_statement_t *statement)
+{
+       fputs("__try ", out);
+       print_statement(statement->try_statement);
+       print_indent();
+       if(statement->except_expression != NULL) {
+               fputs("__except(", out);
+               print_expression(statement->except_expression);
+               fputs(") ", out);
+       } else {
+               fputs("__finally ", out);
+       }
+       print_statement(statement->final_statement);
+}
+
+/**
+ * Print a microsoft __leave statement.
+ *
+ * @param statement   the statement
+ */
+static void print_leave_statement(const leave_statement_t *statement)
+{
+       (void) statement;
+       fputs("__leave;\n", out);
+}
+
 /**
  * Print a statement.
  *
@@ -1152,6 +1178,12 @@ void print_statement(const statement_t *statement)
        case STATEMENT_ASM:
                print_asm_statement(&statement->asms);
                break;
+       case STATEMENT_MS_TRY:
+               print_ms_try_statement(&statement->ms_try);
+               break;
+       case STATEMENT_LEAVE:
+               print_leave_statement(&statement->leave);
+               break;
        case STATEMENT_INVALID:
                fprintf(out, "$invalid statement$");
                break;
@@ -1236,7 +1268,7 @@ static void print_ms_modifiers(const declaration_t *declaration) {
        if((c_mode & _MS) == 0)
                return;
 
-       decl_modifiers_t modifiers = declaration->modifiers;
+       decl_modifiers_t modifiers = declaration->decl_modifiers;
 
        /* DM_FORCEINLINE handled outside. */
        if((modifiers & ~DM_FORCEINLINE) != 0 ||
@@ -1310,10 +1342,10 @@ static void print_normal_declaration(const declaration_t *declaration)
 {
        print_storage_class((storage_class_tag_t) declaration->declared_storage_class);
        if(declaration->is_inline) {
-               if(declaration->modifiers & DM_FORCEINLINE)
+               if(declaration->decl_modifiers & DM_FORCEINLINE)
                        fputs("__forceinline ", out);
                else {
-                       if(declaration->modifiers & DM_MICROSOFT_INLINE)
+                       if(declaration->decl_modifiers & DM_MICROSOFT_INLINE)
                                fputs("__inline ", out);
                        else
                                fputs("inline ", out);
@@ -1514,6 +1546,26 @@ bool is_address_constant(const expression_t *expression)
        }
 }
 
+static bool is_builtin_const_call(const expression_t *expression)
+{
+       expression_t *function = expression->call.function;
+       if (function->kind != EXPR_BUILTIN_SYMBOL) {
+               return false;
+       }
+
+       symbol_t *symbol = function->builtin_symbol.symbol;
+
+       switch (symbol->ID) {
+       case T___builtin_huge_val:
+       case T___builtin_nan:
+       case T___builtin_nanf:
+       case T___builtin_nand:
+               return true;
+       }
+
+       return false;
+}
+
 bool is_constant_expression(const expression_t *expression)
 {
        switch(expression->kind) {
@@ -1533,7 +1585,6 @@ bool is_constant_expression(const expression_t *expression)
 
        case EXPR_BUILTIN_SYMBOL:
        case EXPR_BUILTIN_PREFETCH:
-       case EXPR_CALL:
        case EXPR_SELECT:
        case EXPR_VA_START:
        case EXPR_VA_ARG:
@@ -1542,7 +1593,6 @@ bool is_constant_expression(const expression_t *expression)
        case EXPR_UNARY_POSTFIX_DECREMENT:
        case EXPR_UNARY_PREFIX_INCREMENT:
        case EXPR_UNARY_PREFIX_DECREMENT:
-       case EXPR_UNARY_BITFIELD_EXTRACT:
        case EXPR_UNARY_ASSUME: /* has VOID type */
        case EXPR_UNARY_TAKE_ADDRESS:
        case EXPR_UNARY_DEREFERENCE:
@@ -1560,6 +1610,9 @@ bool is_constant_expression(const expression_t *expression)
        case EXPR_BINARY_COMMA:
                return false;
 
+       case EXPR_CALL:
+               return is_builtin_const_call(expression);
+
        case EXPR_UNARY_NEGATE:
        case EXPR_UNARY_PLUS:
        case EXPR_UNARY_BITWISE_NEGATE: