void finish_eh_spec_block (tree raw_raises, tree eh_spec_block) { tree raises; TREE_OPERAND (eh_spec_block, 0) = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0)); if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR) return; /* Strip cv quals, etc, from the specification types. */ for (raises = NULL_TREE; raw_raises && TREE_VALUE (raw_raises); raw_raises = TREE_CHAIN (raw_raises)) { tree type = prepare_eh_type (TREE_VALUE (raw_raises)); tree tinfo = eh_type_info (type); mark_used (tinfo); raises = tree_cons (NULL_TREE, type, raises); } EH_SPEC_RAISES (eh_spec_block) = raises; }
static tree build_eh_type_type (tree type) { tree exp = eh_type_info (type); if (!exp) return NULL; mark_used (exp); return convert (ptr_type_node, build_address (exp)); }
static tree build_eh_type_type (tree type) { tree exp = eh_type_info (type); if (!exp) return NULL; mark_used (exp); return build1 (ADDR_EXPR, ptr_type_node, exp); }
void finish_eh_spec_block (tree raw_raises, tree eh_spec_block) { tree raises; EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (EH_SPEC_STMTS (eh_spec_block)); /* Strip cv quals, etc, from the specification types. */ for (raises = NULL_TREE; raw_raises && TREE_VALUE (raw_raises); raw_raises = TREE_CHAIN (raw_raises)) { tree type = prepare_eh_type (TREE_VALUE (raw_raises)); tree tinfo = eh_type_info (type); mark_used (tinfo); raises = tree_cons (NULL_TREE, type, raises); } EH_SPEC_RAISES (eh_spec_block) = raises; }
tree expand_start_catch_block (tree decl) { tree exp; tree type, init; if (! doing_eh ()) return NULL_TREE; if (decl) { if (!is_admissible_throw_operand_or_catch_parameter (decl, false)) decl = error_mark_node; type = prepare_eh_type (TREE_TYPE (decl)); mark_used (eh_type_info (type)); } else type = NULL_TREE; /* Call __cxa_end_catch at the end of processing the exception. */ push_eh_cleanup (type); init = do_begin_catch (); /* If there's no decl at all, then all we need to do is make sure to tell the runtime that we've begun handling the exception. */ if (decl == NULL || decl == error_mark_node || init == error_mark_node) finish_expr_stmt (init); /* If the C++ object needs constructing, we need to do that before calling __cxa_begin_catch, so that std::uncaught_exception gets the right value during the copy constructor. */ else if (flag_use_cxa_get_exception_ptr && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) { exp = do_get_exception_ptr (); initialize_handler_parm (decl, exp); finish_expr_stmt (init); } /* Otherwise the type uses a bitwise copy, and we don't have to worry about the value of std::uncaught_exception and therefore can do the copy with the return value of __cxa_end_catch instead. */ else { tree init_type = type; /* Pointers are passed by values, everything else by reference. */ if (!TYPE_PTR_P (type)) init_type = build_pointer_type (type); if (init_type != TREE_TYPE (init)) init = build1 (NOP_EXPR, init_type, init); exp = create_temporary_var (init_type); cp_finish_decl (exp, init, /*init_const_expr=*/false, NULL_TREE, LOOKUP_ONLYCONVERTING); DECL_REGISTER (exp) = 1; initialize_handler_parm (decl, exp); } return type; }