__leave implemented
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 20 Mar 2008 16:25:39 +0000 (16:25 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 20 Mar 2008 16:25:39 +0000 (16:25 +0000)
[r19004]

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

diff --git a/ast.c b/ast.c
index b203ee8..6a44eab 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1116,6 +1116,17 @@ static void print_ms_try_statement(const ms_try_statement_t *statement)
        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.
  *
@@ -1175,6 +1186,9 @@ void print_statement(const statement_t *statement)
        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;
diff --git a/ast.h b/ast.h
index d8109e4..678cceb 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -85,6 +85,7 @@ typedef struct asm_constraint_t             asm_constraint_t;
 typedef struct asm_clobber_t                asm_clobber_t;
 typedef struct asm_statement_t              asm_statement_t;
 typedef struct ms_try_statement_t           ms_try_statement_t;
+typedef struct leave_statement_t            leave_statement_t;
 typedef union  statement_t                  statement_t;
 
 typedef struct translation_unit_t           translation_unit_t;
index ac287d6..be92bc3 100644 (file)
@@ -4280,6 +4280,10 @@ static void      ms_try_statement_to_firm(ms_try_statement_t *statement) {
        warningf(&statement->base.source_position, "structured exception handling ignored");
 }
 
+static void    leave_statement_to_firm(leave_statement_t *statement) {
+       errorf(&statement->base.source_position, "__leave not supported yet");
+}
+
 static void statement_to_firm(statement_t *statement)
 {
        switch(statement->kind) {
@@ -4337,6 +4341,9 @@ static void statement_to_firm(statement_t *statement)
        case STATEMENT_MS_TRY:
                ms_try_statement_to_firm(&statement->ms_try);
                return;
+       case STATEMENT_LEAVE:
+               leave_statement_to_firm(&statement->leave);
+               return;
        }
        panic("Statement not implemented\n");
 }
@@ -4543,6 +4550,7 @@ static int count_decls_in_stmts(const statement_t *stmt)
                        }
 
                        case STATEMENT_GOTO:
+                       case STATEMENT_LEAVE:
                        case STATEMENT_INVALID:
                                break;
 
diff --git a/ast_t.h b/ast_t.h
index aa556a1..3bc1974 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -587,6 +587,7 @@ typedef enum {
        STATEMENT_FOR,
        STATEMENT_ASM,
        STATEMENT_MS_TRY,
+       STATEMENT_LEAVE
 } statement_kind_t;
 
 struct statement_base_t {
@@ -709,6 +710,10 @@ struct ms_try_statement_t {
        statement_t      *final_statement;
 };
 
+struct leave_statement_t {
+       statement_base_t  base;
+};
+
 union statement_t {
        statement_kind_t         kind;
        statement_base_t         base;
@@ -726,6 +731,7 @@ union statement_t {
        for_statement_t          fors;
        asm_statement_t          asms;
        ms_try_statement_t       ms_try;
+       leave_statement_t        leave;
 };
 
 struct translation_unit_t {
index 9b68f38..1678418 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -99,6 +99,7 @@ static declaration_t      *last_declaration  = NULL;
 static declaration_t      *current_function  = NULL;
 static switch_statement_t *current_switch    = NULL;
 static statement_t        *current_loop      = NULL;
+static ms_try_statement_t *current_try       = NULL;
 static goto_statement_t   *goto_first        = NULL;
 static goto_statement_t   *goto_last         = NULL;
 static label_statement_t  *label_first       = NULL;
@@ -246,7 +247,8 @@ static size_t get_statement_struct_size(statement_kind_t kind)
                [STATEMENT_DO_WHILE]    = sizeof(do_while_statement_t),
                [STATEMENT_FOR]         = sizeof(for_statement_t),
                [STATEMENT_ASM]         = sizeof(asm_statement_t),
-               [STATEMENT_MS_TRY]      = sizeof(ms_try_statement_t)
+               [STATEMENT_MS_TRY]      = sizeof(ms_try_statement_t),
+               [STATEMENT_LEAVE]       = sizeof(leave_statement_t)
        };
        assert(kind <= sizeof(sizes) / sizeof(sizes[0]));
        assert(sizes[kind] != 0);
@@ -7358,7 +7360,7 @@ static statement_t *parse_continue(void)
        statement_t *statement;
        if (current_loop == NULL) {
                errorf(HERE, "continue statement not within loop");
-               statement = NULL;
+               statement = create_invalid_statement();
        } else {
                statement = allocate_statement_zero(STATEMENT_CONTINUE);
 
@@ -7381,7 +7383,7 @@ static statement_t *parse_break(void)
        statement_t *statement;
        if (current_switch == NULL && current_loop == NULL) {
                errorf(HERE, "break statement not within loop or switch");
-               statement = NULL;
+               statement = create_invalid_statement();
        } else {
                statement = allocate_statement_zero(STATEMENT_BREAK);
 
@@ -7396,6 +7398,29 @@ end_error:
        return create_invalid_statement();
 }
 
+/**
+ * Parse a __leave statement.
+ */
+static statement_t *parse_leave(void)
+{
+       statement_t *statement;
+       if (current_try == NULL) {
+               errorf(HERE, "__leave statement not within __try");
+               statement = create_invalid_statement();
+       } else {
+               statement = allocate_statement_zero(STATEMENT_LEAVE);
+
+               statement->base.source_position = token.source_position;
+       }
+
+       eat(T___leave);
+       expect(';');
+
+       return statement;
+end_error:
+       return create_invalid_statement();
+}
+
 /**
  * Check if a given declaration represents a local variable.
  */
@@ -7567,7 +7592,10 @@ static statement_t *parse_ms_try_statment(void) {
        statement->base.source_position  = token.source_position;
        eat(T___try);
 
+       ms_try_statement_t *rem = current_try;
+       current_try = &statement->ms_try;
        statement->ms_try.try_statement = parse_compound_statement();
+       current_try = rem;
 
        if(token.type == T___except) {
                eat(T___except);
@@ -7656,6 +7684,10 @@ static statement_t *parse_statement(void)
                statement = parse_break();
                break;
 
+       case T___leave:
+               statement = parse_leave();
+               break;
+
        case T_return:
                statement = parse_return();
                break;