⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 except.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
  decl = decay_conversion (decl);  fn = get_identifier ("__check_eh_spec");  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      push_obstacks_nochange ();      end_temporary_allocation ();      tmp = tree_cons	(NULL_TREE, integer_type_node, tree_cons	 (NULL_TREE, TREE_TYPE (decl), void_list_node));      tmp = build_function_type	(void_type_node, tmp);        fn = build_lang_decl (FUNCTION_DECL, fn, tmp);      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      TREE_THIS_VOLATILE (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  tmp = expr_tree_cons (NULL_TREE, build_int_2 (count, 0), expr_tree_cons			(NULL_TREE, decl, NULL_TREE));  tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp);  expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL);  expand_end_catch_block ();  expand_end_all_catch ();}/* This is called to expand all the toplevel exception handling   finalization for a function.  It should only be called once per   function.  */voidexpand_exception_blocks (){  do_pending_stack_adjust ();  push_to_sequence (catch_clauses);  expand_leftover_cleanups ();  do_pending_stack_adjust ();  catch_clauses = get_insns ();  end_sequence ();  /* Do this after we expand leftover cleanups, so that the     expand_eh_region_end that expand_end_eh_spec does will match the     right expand_eh_region_start, and make sure it comes out before     the terminate protected region.  */  if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))    {     expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));     do_pending_stack_adjust ();     push_to_sequence (catch_clauses);     expand_leftover_cleanups ();     do_pending_stack_adjust ();     catch_clauses = get_insns ();     end_sequence ();    }  if (catch_clauses)    {      rtx funcend = gen_label_rtx ();      emit_jump (funcend);      /* We cannot protect n regions this way if we must flow into the	 EH region through the top of the region, as we have to with	 the setjmp/longjmp approach.  */      if (exceptions_via_longjmp == 0)	expand_eh_region_start ();      emit_insns (catch_clauses);      catch_clauses = NULL_RTX;      if (exceptions_via_longjmp == 0)	expand_eh_region_end (build_terminate_handler ());      expand_leftover_cleanups ();      emit_label (funcend);    }}treestart_anon_func (){  static int counter = 0;  int old_interface_unknown = interface_unknown;  char name[32];  tree params;  tree t;  push_cp_function_context (NULL_TREE);  push_to_top_level ();  /* No need to mangle this.  */  push_lang_context (lang_name_c);  interface_unknown = 1;  params = void_list_node;  /* tcf stands for throw clean function.  */  sprintf (name, "__tcf_%d", counter++);  t = make_call_declarator (get_identifier (name), params, NULL_TREE,			    NULL_TREE);  start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"),				  void_list_node),		  t, NULL_TREE, 0);  store_parm_decls ();  pushlevel (0);  clear_last_expr ();  push_momentary ();  expand_start_bindings (0);  emit_line_note (input_filename, lineno);  interface_unknown = old_interface_unknown;  pop_lang_context ();  return current_function_decl;}voidend_anon_func (){  expand_end_bindings (getdecls (), 1, 0);  poplevel (1, 0, 0);  pop_momentary ();  finish_function (lineno, 0, 0);  pop_from_top_level ();  pop_cp_function_context (NULL_TREE);}/* Return a pointer to a buffer for an exception object of type TYPE.  */static treealloc_eh_object (type)     tree type;{  tree fn, exp;  fn = get_identifier ("__eh_alloc");  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      /* Declare __eh_alloc (size_t), as defined in exception.cc.  */      tree tmp;      push_obstacks_nochange ();      end_temporary_allocation ();      tmp = tree_cons (NULL_TREE, sizetype, void_list_node);      fn = build_lang_decl (FUNCTION_DECL, fn,			    build_function_type (ptr_type_node, tmp));      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  exp = build_function_call (fn, expr_tree_cons			     (NULL_TREE, size_in_bytes (type), NULL_TREE));  exp = build1 (NOP_EXPR, build_pointer_type (type), exp);  return exp;}/* Expand a throw statement.  This follows the following   algorithm:	1. Allocate space to save the current PC onto the stack.	2. Generate and emit a label and save its address into the		newly allocated stack space since we can't save the pc directly.	3. If this is the first call to throw in this function:		generate a label for the throw block	4. jump to the throw block label.  */voidexpand_throw (exp)     tree exp;{  tree fn;  static tree cleanup_type;  if (! doing_eh (1))    return;  if (exp)    {      tree throw_type;      tree cleanup = NULL_TREE, e;      /* throw expression */      /* First, decay it.  */      exp = decay_conversion (exp);      /* cleanup_type is void (*)(void *, int),	 the internal type of a destructor. */      if (cleanup_type == NULL_TREE)	{	  push_obstacks_nochange ();	  end_temporary_allocation ();	  cleanup_type = build_pointer_type	    (build_function_type	     (void_type_node, tree_cons	      (NULL_TREE, ptr_type_node, tree_cons	       (NULL_TREE, integer_type_node, void_list_node))));	  pop_obstacks ();	}      if (TYPE_PTR_P (TREE_TYPE (exp)))	throw_type = build_eh_type (exp);      else	{	  tree object, ptr;	  /* OK, this is kind of wacky.  The WP says that we call	     terminate	     when the exception handling mechanism, after completing	     evaluation of the expression to be thrown but before the	     exception is caught (_except.throw_), calls a user function	     that exits via an uncaught exception.	     So we have to protect the actual initialization of the	     exception object with terminate(), but evaluate the expression	     first.  We also expand the call to __eh_alloc	     first.  Since there could be temps in the expression, we need	     to handle that, too.  */	  expand_start_target_temps ();#if 0	  /* Unfortunately, this doesn't work.  */	  preexpand_calls (exp);#else	  /* Store the throw expression into a temp.  This can be less	     efficient than storing it into the allocated space directly, but	     oh well.  To do this efficiently we would need to insinuate	     ourselves into expand_call.  */	  if (TREE_SIDE_EFFECTS (exp))	    {	      tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));	      DECL_ARTIFICIAL (temp) = 1;	      DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1);	      DECL_INITIAL (temp) = exp;	      cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);	      exp = temp;	    }#endif	  /* Allocate the space for the exception.  */	  ptr = save_expr (alloc_eh_object (TREE_TYPE (exp)));	  expand_expr (ptr, const0_rtx, VOIDmode, 0);	  expand_eh_region_start ();	  object = build_indirect_ref (ptr, NULL_PTR);	  exp = build_modify_expr (object, INIT_EXPR, exp);	  if (exp == error_mark_node)	    error ("  in thrown expression");	  expand_expr (exp, const0_rtx, VOIDmode, 0);	  expand_eh_region_end (build_terminate_handler ());	  expand_end_target_temps ();	  throw_type = build_eh_type (object);	  if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))	    {	      cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),					 dtor_identifier, 0);	      cleanup = TREE_VALUE (cleanup);	      mark_used (cleanup);	      mark_addressable (cleanup);	      /* Pretend it's a normal function.  */	      cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);	    }	  exp = ptr;	}      /* Cast EXP to `void *' so that it will match the prototype for	 __cp_push_exception.  */      exp = convert (ptr_type_node, exp);      if (cleanup == NULL_TREE)	{	  cleanup = build_int_2 (0, 0);	  TREE_TYPE (cleanup) = cleanup_type;	}      fn = get_identifier ("__cp_push_exception");      if (IDENTIFIER_GLOBAL_VALUE (fn))	fn = IDENTIFIER_GLOBAL_VALUE (fn);      else	{	  /* Declare __cp_push_exception (void*, void*, void (*)(void*, int)),	     as defined in exception.cc.  */	  tree tmp;	  push_obstacks_nochange ();	  end_temporary_allocation ();	  tmp = tree_cons	    (NULL_TREE, ptr_type_node, tree_cons	     (NULL_TREE, ptr_type_node, tree_cons	      (NULL_TREE, cleanup_type, void_list_node)));	  fn = build_lang_decl (FUNCTION_DECL, fn,				build_function_type (void_type_node, tmp));	  DECL_EXTERNAL (fn) = 1;	  TREE_PUBLIC (fn) = 1;	  DECL_ARTIFICIAL (fn) = 1;	  pushdecl_top_level (fn);	  make_function_rtl (fn);	  pop_obstacks ();	}      mark_used (fn);      e = expr_tree_cons (NULL_TREE, exp, expr_tree_cons			  (NULL_TREE, throw_type, expr_tree_cons			   (NULL_TREE, cleanup, NULL_TREE)));      e = build_function_call (fn, e);      expand_expr (e, const0_rtx, VOIDmode, 0);    }  else    {      /* rethrow current exception; note that it's no longer caught.  */      tree fn = get_identifier ("__uncatch_exception");      if (IDENTIFIER_GLOBAL_VALUE (fn))	fn = IDENTIFIER_GLOBAL_VALUE (fn);      else	{	  /* Declare void __uncatch_exception (void)	     as defined in exception.cc. */	  push_obstacks_nochange ();	  end_temporary_allocation ();	  fn = build_lang_decl (FUNCTION_DECL, fn,				build_function_type (void_type_node,						     void_list_node));	  DECL_EXTERNAL (fn) = 1;	  TREE_PUBLIC (fn) = 1;	  DECL_ARTIFICIAL (fn) = 1;	  pushdecl_top_level (fn);	  make_function_rtl (fn);	  pop_obstacks ();	}      mark_used (fn);      exp = build_function_call (fn, NULL_TREE);      expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);    }  expand_internal_throw ();}/* Build a throw expression.  */treebuild_throw (e)     tree e;{  if (e == error_mark_node)    return e;  if (processing_template_decl)    return build_min (THROW_EXPR, void_type_node, e);  if (e == null_node)    cp_warning ("throwing NULL, which has integral, not pointer type");  e = build1 (THROW_EXPR, void_type_node, e);  TREE_SIDE_EFFECTS (e) = 1;  TREE_USED (e) = 1;  return e;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -