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 statement.
*
case STATEMENT_ASM:
print_asm_statement(&statement->asms);
break;
+ case STATEMENT_MS_TRY:
+ print_ms_try_statement(&statement->ms_try);
+ break;
case STATEMENT_INVALID:
fprintf(out, "$invalid statement$");
break;
#endif
}
+static void ms_try_statement_to_firm(ms_try_statement_t *statement) {
+ statement_to_firm(statement->try_statement);
+ warningf(&statement->base.source_position, "structured exception handling ignored");
+}
+
static void statement_to_firm(statement_t *statement)
{
switch(statement->kind) {
case STATEMENT_ASM:
asm_statement_to_firm(&statement->asms);
return;
+ case STATEMENT_MS_TRY:
+ ms_try_statement_to_firm(&statement->ms_try);
+ return;
}
panic("Statement not implemented\n");
}
count += count_decls_in_expression(ret_stmt->value);
break;
}
+
+ case STATEMENT_MS_TRY: {
+ const ms_try_statement_t *const try_stmt = &stmt->ms_try;
+ count += count_decls_in_stmts(try_stmt->try_statement);
+ if(try_stmt->except_expression != NULL)
+ count += count_decls_in_expression(try_stmt->except_expression);
+ count += count_decls_in_stmts(try_stmt->final_statement);
+ break;
+ }
}
}
return count;
[STATEMENT_WHILE] = sizeof(while_statement_t),
[STATEMENT_DO_WHILE] = sizeof(do_while_statement_t),
[STATEMENT_FOR] = sizeof(for_statement_t),
- [STATEMENT_ASM] = sizeof(asm_statement_t)
+ [STATEMENT_ASM] = sizeof(asm_statement_t),
+ [STATEMENT_MS_TRY] = sizeof(ms_try_statement_t)
};
assert(kind <= sizeof(sizes) / sizeof(sizes[0]));
assert(sizes[kind] != 0);
}
va_list ap;
va_start(ap, message);
- errorf(HERE, "got %K, expected %#k", &token, &ap, "a ");
+ errorf(HERE, "got %K, expected %#k", &token, &ap, ", ");
va_end(ap);
}
static void parse_gnu_attribute_string_arg(gnu_attribute_t *attribute, string_t *string) {
add_anchor_token('(');
if(token.type != T_STRING_LITERAL) {
- parse_error_expected("while parsing attribute directive", T_STRING_LITERAL);
+ parse_error_expected("while parsing attribute directive", T_STRING_LITERAL, 0);
goto end_error;
}
*string = parse_string_literals();
int i;
if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing format attribute directive", T_IDENTIFIER);
+ parse_error_expected("while parsing format attribute directive", T_IDENTIFIER, 0);
goto end_error;
}
const char *name = token.v.symbol->string;
/* __attribute__((cdecl)), WITH ms mode */
name = "cdecl";
} else if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing GNU attribute", T_IDENTIFIER);
+ parse_error_expected("while parsing GNU attribute", T_IDENTIFIER, 0);
break;
}
const symbol_t *sym = token.v.symbol;
expect('(');
if(token.type != T_STRING_LITERAL) {
parse_error_expected("while parsing assembler attribute",
- T_STRING_LITERAL);
+ T_STRING_LITERAL, 0);
eat_until_matching_token('(');
break;
} else {
return create_invalid_statement();
}
+/**
+ * Parse a microsoft __try { } __finally { } or
+ * __try{ } __except() { }
+ */
+static statement_t *parse_ms_try_statment(void) {
+ statement_t *statement = allocate_statement_zero(STATEMENT_MS_TRY);
+
+ statement->base.source_position = token.source_position;
+ eat(T___try);
+
+ statement->ms_try.try_statement = parse_compound_statement();
+
+ if(token.type == T___except) {
+ eat(T___except);
+ expect('(');
+ add_anchor_token(')');
+ expression_t *const expr = parse_expression();
+ type_t * type = skip_typeref(expr->base.type);
+ if (is_type_integer(type)) {
+ type = promote_integer(type);
+ } else if (is_type_valid(type)) {
+ errorf(&expr->base.source_position,
+ "__expect expression is not an integer, but '%T'", type);
+ type = type_error_type;
+ }
+ statement->ms_try.except_expression = create_implicit_cast(expr, type);
+ rem_anchor_token(')');
+ expect(')');
+ statement->ms_try.final_statement = parse_compound_statement();
+ } else if(token.type == T__finally) {
+ eat(T___finally);
+ statement->ms_try.final_statement = parse_compound_statement();
+ } else {
+ parse_error_expected("while parsing __try statement", T___except, T___finally, 0);
+ return create_invalid_statement();
+ }
+ return statement;
+end_error:
+ return create_invalid_statement();
+}
+
/**
* Parse a statement.
*/
statement = parse_declaration_statement();
break;
+ case T___try:
+ statement = parse_ms_try_statment();
+ break;
+
default:
statement = parse_expression_statement();
break;