diff options
author | Richard Henderson <rth@redhat.com> | 2004-06-20 02:18:13 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-06-20 02:18:13 -0700 |
commit | 5a5086621e8751f9666cf0a3d5956149202e1487 (patch) | |
tree | 5f34633f30f7aaefd64e454886114b31df3b8155 /gcc/cp | |
parent | 500e12641f0f7fb4fde1221f7f8052ef351de5f7 (diff) | |
download | gcc-5a5086621e8751f9666cf0a3d5956149202e1487.zip gcc-5a5086621e8751f9666cf0a3d5956149202e1487.tar.gz gcc-5a5086621e8751f9666cf0a3d5956149202e1487.tar.bz2 |
c-common.def (IF_STMT, [...]): Move to cp-tree.def.
* c-common.def (IF_STMT, CLEANUP_STMT): Move to cp-tree.def.
* c-common.h (IF_COND, THEN_CLAUSE, ELSE_CLAUSE, CLEANUP_BODY,
CLEANUP_EXPR, CLEANUP_DECL): Move to cp-tree.h.
(c_common_stmt_codes): Remove IF_STMT, CLEANUP_STMT.
* c-dump.c (c_dump_tree): Move IF_STMT, CLEANUP_STMT to cp_dump_tree.
* c-pretty-print.c (pp_c_statement): Similarly.
* c-gimplify.c (gimplify_cleanup_stmt, gimplify_cleanup_stmts,
gimplify_if_stmt): Move to cp-gimplify.c.
(c_genericize, c_gimplify_expr): Don't call them.
* c-semantics.c (push_cleanup): Move to cp/semantics.c.
* c-typeck.c (push_cleanup): New.
(c_begin_if_stmt, c_finish_if_cond, c_finish_then, c_finish_else,
c_finish_if_stmt): Use COND_EXPR.
* tree.h (CLEANUP_EH_ONLY): Update documentation.
cp/
* cp-tree.def (CLEANUP_STMT, IF_STMT): Move from c-common.def.
* cp-gimplify.c (gimplify_if_stmt): Move from c-gimplify.c.
(cp_gimplify_expr): Call it.
(gimplify_cleanup_stmt): Move from c-gimplify.c.
(cp_genericize): New.
* decl.c (finish_function): Call it.
* cp-tree.h (cp_stmt_codes): Add CLEANUP_STMT, IF_STMT.
(CLEANUP_BODY, CLEANUP_EXPR, CLEANUP_DECL): Move from c-common.h.
(IF_COND, THEN_CLAUSE, ELSE_CLAUSE): Likewise.
(cp_genericize): Declare.
* cxx-pretty-print.c (pp_cxx_statement): Add CLEANUP_STMT, IF_STMT.
* dump.c (cp_dump_tree): Likewise.
* semantics.c (push_cleanup): Move from c-semantics.c.
From-SVN: r83407
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 55 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 14 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 17 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.c | 37 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/dump.c | 18 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 13 |
8 files changed, 169 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e3048d3..b01e1f8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2004-06-20 Richard Henderson <rth@redhat.com> + + * cp-tree.def (CLEANUP_STMT, IF_STMT): Move from c-common.def. + * cp-gimplify.c (gimplify_if_stmt): Move from c-gimplify.c. + (cp_gimplify_expr): Call it. + (gimplify_cleanup_stmt): Move from c-gimplify.c. + (cp_genericize): New. + * decl.c (finish_function): Call it. + * cp-tree.h (cp_stmt_codes): Add CLEANUP_STMT, IF_STMT. + (CLEANUP_BODY, CLEANUP_EXPR, CLEANUP_DECL): Move from c-common.h. + (IF_COND, THEN_CLAUSE, ELSE_CLAUSE): Likewise. + (cp_genericize): Declare. + * cxx-pretty-print.c (pp_cxx_statement): Add CLEANUP_STMT, IF_STMT. + * dump.c (cp_dump_tree): Likewise. + * semantics.c (push_cleanup): Move from c-semantics.c. + 2004-06-20 Zack Weinberg <zack@codesourcery.com> * cp-lang.c (has_c_linkage): Implement. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 9901643..8bdf5f4 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -79,6 +79,26 @@ genericize_eh_spec_block (tree *stmt_p) *stmt_p = gimple_build_eh_filter (body, allowed, failure); } +/* Genericize an IF_STMT by turning it into a COND_EXPR. */ + +static void +gimplify_if_stmt (tree *stmt_p) +{ + tree stmt, then_, else_; + + stmt = *stmt_p; + then_ = THEN_CLAUSE (stmt); + else_ = ELSE_CLAUSE (stmt); + + if (!then_) + then_ = build_empty_stmt (); + if (!else_) + else_ = build_empty_stmt (); + + stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_); + *stmt_p = stmt; +} + /* Gimplify initialization from an AGGR_INIT_EXPR. */ static void @@ -224,6 +244,11 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p) ret = GS_ALL_DONE; break; + case IF_STMT: + gimplify_if_stmt (expr_p); + ret = GS_OK; + break; + default: ret = c_gimplify_expr (expr_p, pre_p, post_p); break; @@ -236,3 +261,33 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p) return ret; } + +/* Genericize a CLEANUP_STMT. This just turns into a TRY_FINALLY or + TRY_CATCH depending on whether it's EH-only. */ + +static tree +gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees, + void *data ATTRIBUTE_UNUSED) +{ + tree stmt = *stmt_p; + + if (DECL_P (stmt) || TYPE_P (stmt)) + *walk_subtrees = 0; + else if (TREE_CODE (stmt) == CLEANUP_STMT) + *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR, + void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt)); + + return NULL; +} + +void +cp_genericize (tree fndecl) +{ + /* Due to the way voidify_wrapper_expr is written, we don't get a chance + to lower this construct before scanning it. So we need to lower these + before doing anything else. */ + walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL); + + /* Do everything else. */ + c_genericize (fndecl); +} diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 3b4c6e6e..4f7961b 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -243,8 +243,11 @@ DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", 'e', 1) /* CTOR_INITIALIZER is a placeholder in template code for a call to setup_vtbl_pointer (and appears in all functions, not just ctors). */ DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1) + DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2) + DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2) + /* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is CATCH_ALL_TYPE, then the handler catches all types. The declaration of the catch variable is in HANDLER_PARMS, and the body block in @@ -255,6 +258,17 @@ DEFTREECODE (HANDLER, "handler", 'e', 2) throw, and must call terminate if it does. */ DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1) +/* A CLEANUP_STMT marks the point at which a declaration is fully + constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL + when CLEANUP_BODY completes. */ +DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 3) + +/* Represents an 'if' statement. The operands are IF_COND, + THEN_CLAUSE, and ELSE_CLAUSE, respectively. */ +/* ??? It is currently still necessary to distinguish between IF_STMT + and COND_EXPR for the benefit of templates. */ +DEFTREECODE (IF_STMT, "if_stmt", 'e', 3) + DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0) /* Template instantiation level node. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1838c82..ae62adc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -892,7 +892,8 @@ enum cplus_tree_code { #define cp_stmt_codes \ CTOR_INITIALIZER, TRY_BLOCK, HANDLER, \ - EH_SPEC_BLOCK, USING_STMT, TAG_DEFN + EH_SPEC_BLOCK, USING_STMT, TAG_DEFN, \ + IF_STMT, CLEANUP_STMT enum languages { lang_c, lang_cplusplus, lang_java }; @@ -2939,6 +2940,19 @@ struct lang_decl GTY(()) #define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1) #define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE)) +/* CLEANUP_STMT accessors. The statement(s) covered, the cleanup to run + and the VAR_DECL for which this cleanup exists. */ +#define CLEANUP_BODY(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0) +#define CLEANUP_EXPR(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1) +#define CLEANUP_DECL(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2) + +/* IF_STMT accessors. These give access to the condition of the if + statement, the then block of the if statement, and the else block + of the if statement if it exists. */ +#define IF_COND(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 0) +#define THEN_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 1) +#define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2) + /* The parameters for a call-declarator. */ #define CALL_DECLARATOR_PARMS(NODE) \ (TREE_PURPOSE (TREE_OPERAND (NODE, 1))) @@ -4304,6 +4318,7 @@ extern bool cp_dump_tree (void *, tree); /* in cp-simplify.c */ extern int cp_gimplify_expr (tree *, tree *, tree *); +extern void cp_genericize (tree); /* -- end of C++ */ diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index a50ecc4..cd08611 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -1517,6 +1517,43 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t) pp_needs_newline (pp) = true; break; + /* selection-statement: + if ( expression ) statement + if ( expression ) statement else statement */ + case IF_STMT: + pp_cxx_identifier (pp, "if"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + pp_cxx_expression (pp, IF_COND (t)); + pp_cxx_right_paren (pp); + pp_newline_and_indent (pp, 2); + pp_cxx_statement (pp, THEN_CLAUSE (t)); + pp_newline_and_indent (pp, -2); + if (ELSE_CLAUSE (t)) + { + tree else_clause = ELSE_CLAUSE (t); + pp_cxx_identifier (pp, "else"); + if (TREE_CODE (else_clause) == IF_STMT) + pp_cxx_whitespace (pp); + else + pp_newline_and_indent (pp, 2); + pp_cxx_statement (pp, else_clause); + if (TREE_CODE (else_clause) != IF_STMT) + pp_newline_and_indent (pp, -2); + } + break; + + case CLEANUP_STMT: + pp_cxx_identifier (pp, "try"); + pp_newline_and_indent (pp, 2); + pp_cxx_statement (pp, CLEANUP_BODY (t)); + pp_newline_and_indent (pp, -2); + pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally"); + pp_newline_and_indent (pp, 2); + pp_cxx_statement (pp, CLEANUP_EXPR (t)); + pp_newline_and_indent (pp, -2); + break; + default: pp_c_statement (pp_c_base (pp), t); break; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dfdfe56..84f3b84 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10812,7 +10812,7 @@ finish_function (int flags) /* Genericize before inlining. */ if (!processing_template_decl) { - c_genericize (fndecl); + cp_genericize (fndecl); /* Handle attribute((warn_unused_result)). Relies on gimple input. */ c_warn_unused_result (&DECL_SAVED_TREE (fndecl)); diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index 17b30c9..fd0a847 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -411,7 +411,23 @@ cp_dump_tree (void* dump_info, tree t) dump_child ("nmsp", USING_STMT_NAMESPACE (t)); dump_next_stmt (di, t); break; - + + case CLEANUP_STMT: + dump_stmt (di, t); + dump_child ("decl", CLEANUP_DECL (t)); + dump_child ("expr", CLEANUP_EXPR (t)); + dump_child ("body", CLEANUP_BODY (t)); + dump_next_stmt (di, t); + break; + + case IF_STMT: + dump_stmt (di, t); + dump_child ("cond", IF_COND (t)); + dump_child ("then", THEN_CLAUSE (t)); + dump_child ("else", ELSE_CLAUSE (t)); + dump_next_stmt (di, t); + break; + default: break; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 74a513a..e53222f 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -346,6 +346,19 @@ do_pushlevel (scope_kind sk) return ret; } +/* Queue a cleanup. CLEANUP is an expression/statement to be executed + when the current scope is exited. EH_ONLY is true when this is not + meant to apply to normal control flow transfer. */ + +void +push_cleanup (tree decl, tree cleanup, bool eh_only) +{ + tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl); + CLEANUP_EH_ONLY (stmt) = eh_only; + add_stmt (stmt); + CLEANUP_BODY (stmt) = push_stmt_list (); +} + /* Begin a conditional that might contain a declaration. When generating normal code, we want the declaration to appear before the statement containing the conditional. When generating template code, we want the |