[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,
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);
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.
*
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;
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 ||
{
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);
}
}
+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) {
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_PREFETCH:
- case EXPR_CALL:
case EXPR_SELECT:
case EXPR_VA_START:
case EXPR_VA_ARG:
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:
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: