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

📄 cp-except.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (in_try_block (1))    {#if 1      my_friendly_abort (35);#else      expand_raise (decl);#endif    }  else if (! current_function_decl)    error ("invalid throw outside of functions");  else    {#if 0      /* Test this raise against what this function permits.  */      tree names = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl));      while (names)	{	  if (decl == TREE_TYPE (names))	    break;	  names = TREE_CHAIN (names);	}      if (names == NULL_TREE)	{	  error ("current function not declared to raise exception `%s'",		 IDENTIFIER_POINTER (name));	  return;	}#endif    }  store_expr (exp, EHS_parms_as_rtx, 0);  /* Set the global exception handler stack's NAME field     to the `name' of this exception.  The global exception     handler stack is the container for the exception object     we just built.     We go through a function call to make life easier when debugging.  */#if 0  expand_assignment (EHS_name, build_unary_op (ADDR_EXPR, decl, 0), 0, 0);#else  parms = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, EHS_name, 0),		     build_tree_list (NULL_TREE,				      build_unary_op (ADDR_EXPR, decl, 0)));  expand_expr (build_function_call (BIR, parms), 0, 0, 0);#endif  /* Activate thrower.  If we are inside a TRY statement,     we can cheat and not do this, saving a longjmp.  */  if (in_try_block (1) == 0)    {      sets_exception_throw_decl = 1;      emit_move_insn (DECL_RTL (exception_throw_decl), const1_rtx);    }  if (xexp == NULL_TREE)    {          /* Invoke destructors for current procedure or handler.  */      if (! expand_escape_except ())	compiler_error ("except nesting botch");      /* Throw via `longjmp'... Done as side-effect of goto.  */    }  /* To avoid spurious warning messages, we add a goto to the end     of the function.  This code is dead, and the compiler should     know how to delete it, but for now, we are stuck with it.  */  if (! for_reraise      && TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node)    expand_null_return ();}treecplus_expand_start_catch (raise_id)     tree raise_id;{  tree cname = lookup_exception_cname (current_class_type, current_class_name, raise_id);  tree decl;  tree cond;  if (cname == error_mark_node)    {      decl = error_mark_node;      cond = error_mark_node;    }  else    {      decl = lookup_exception_object (cname, TREE_VALUE (raise_id), 1);      if (decl == NULL_TREE)	cond = error_mark_node;      else	cond = build_binary_op (EQ_EXPR, build_unary_op (ADDR_EXPR, decl, 0),				build (COMPONENT_REF, ptr_type_node,				       current_exception_decl, TREE_OPERAND (EHS_name, 1)));    }  expand_start_cond (cond, 0);  /* Does nothing right now.  */  expand_catch (decl);  if (current_exception_type      && TYPE_NEEDS_DESTRUCTOR (current_exception_type))    {      /* Make a cleanup for the name-specific exception object now in scope.  */      tree cleanup = maybe_build_cleanup (current_exception_object);      expand_start_bindings (0);      expand_decl_cleanup (NULL_TREE, cleanup);    }  return decl;}treeansi_expand_start_catch (raise_type)     tree raise_type;{  tree decl = ansi_exception_object_lookup (raise_type);  tree cond;  if (decl == NULL_TREE)      cond = error_mark_node;  else      cond = build_binary_op (EQ_EXPR, build_unary_op (ADDR_EXPR, decl, 0),			      build (COMPONENT_REF, ptr_type_node,				     current_exception_decl,				     TREE_OPERAND (EHS_name, 1)));  expand_start_cond (cond, 0);  /* Does nothing right now.  */  expand_catch (decl);  return decl;}voidcplus_expand_end_catch (for_reraise)     int for_reraise;{  if (current_exception_type      && TYPE_NEEDS_DESTRUCTOR (current_exception_type))    {      /* Destroy the specific exception object now in scope.  */      expand_end_bindings (getdecls (), 0, 1);    }  if (for_reraise)    {      if (! expand_escape_except ())	my_friendly_abort (36);    }  else    {      if (! expand_end_catch ())	my_friendly_abort (37);    }  expand_end_cond ();}/* Reraise an exception.   If EXCEPTIONS is NULL_TREE, it means reraise whatever exception was caught.   If EXCEPTIONS is an IDENTIFIER_NODE, it means reraise the exception   object named by EXCEPTIONS.  This must be a variable declared in   an `except' clause.   If EXCEPTIONS is a TREE_LIST, it is the list of exceptions we are   willing to reraise.  */voidcplus_expand_reraise (exceptions)     tree exceptions;{  tree ex_ptr;  tree ex_object = current_exception_object;  rtx ex_ptr_as_rtx;  if (exceptions && TREE_CODE (exceptions) == IDENTIFIER_NODE)    {      /* Don't get tripped up if its TREE_TYPE is `error_mark_node'.  */      ex_object = IDENTIFIER_LOCAL_VALUE (exceptions);      if (ex_object == NULL_TREE || TREE_CODE (ex_object) != INDIRECT_REF)	{	  error ("`%s' is not an exception decl", IDENTIFIER_POINTER (exceptions));	  return;	}      my_friendly_assert (TREE_CODE (TREE_OPERAND (ex_object, 0)) == VAR_DECL,			  204);      exceptions = NULL_TREE;    }  ex_ptr = build1 (NOP_EXPR, ptr_type_node, TREE_OPERAND (ex_object, 0));  ex_ptr_as_rtx = expand_expr (ex_ptr, 0, 0, 0);  /* reraise ALL, used by compiler.  */  if (exceptions == NULL_TREE)    {      /* Now treat reraise like catch/raise.  */      expand_catch (error_mark_node);      expand_raise (error_mark_node);      emit_move_insn (EHS_name_as_rtx, current_exception_name_as_rtx);      store_expr (EHS_parms_as_rtx, current_exception_parms_as_rtx, 0);      if (in_try_block (1) == 0)	{	  sets_exception_throw_decl = 1;	  emit_move_insn (DECL_RTL (exception_throw_decl), const1_rtx);	}      /* Set to zero so that destructor will not be called.  */      emit_move_insn (ex_ptr_as_rtx, const0_rtx);      if (! expand_escape_except ())	my_friendly_abort (38);      /* To avoid spurious warning messages, we add a goto to the end	 of the function.  This code is dead, and the compiler should	 know how to delete it, but for now, we are stuck with it.  */      if (TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node)	expand_null_return ();      return;    }  /* reraise from a list of exceptions.  */  while (exceptions)    {      tree type = lookup_exception_type (current_class_type, current_class_name,					 exceptions);      if (type == NULL_TREE)	{	  error ("`%s' is not an exception type",		 IDENTIFIER_POINTER (TREE_VALUE (exceptions)));	  current_exception_type = NULL_TREE;	  TREE_TYPE (ex_object) = error_mark_node;	  TREE_TYPE (ex_ptr) = error_mark_node;	}      else	{	  current_exception_type = type;	  /* In-place union.  */	  TREE_TYPE (ex_object) = type;	  TREE_TYPE (ex_ptr) = TYPE_POINTER_TO (type);	}      /* Now treat reraise like catch/raise.  */      cplus_expand_start_catch (exceptions);      cplus_expand_raise (exceptions, NULL_TREE, ex_ptr, 1);      /* Set to zero so that destructor will not be called.  */      if (TREE_TYPE (ex_ptr) != error_mark_node)	emit_move_insn (ex_ptr_as_rtx, const0_rtx);      cplus_expand_end_catch (1);      exceptions = TREE_CHAIN (exceptions);    }  /* Don't propagate any unhandled exceptions.  */  expand_expr (call_to_unhandled_exception (), 0, VOIDmode, 0);  /* To avoid spurious warning messages, we add a goto to the end     of the function.  This code is dead, and the compiler should     know how to delete it, but for now, we are stuck with it.  */  if (TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node)    expand_null_return ();}voidsetup_exception_throw_decl (){  tree call_to_longjmp, parms;  int old = suspend_momentary ();  exception_throw_decl = build_decl (VAR_DECL, get_identifier (THROW_NAME), integer_type_node);  pushdecl (exception_throw_decl);  parms = tree_cons (NULL_TREE, EHS_handler,		     build_tree_list (0, integer_one_node));  call_to_longjmp = build_function_call (BILJ, parms);  expand_decl (exception_throw_decl);  expand_decl_cleanup (exception_throw_decl,		       build (COND_EXPR, void_type_node,			      exception_throw_decl,			      call_to_longjmp, integer_zero_node));  DECL_INITIAL (exception_throw_decl) = integer_zero_node;  sets_exception_throw_decl = 0;  resume_momentary (old);  /* Cache these, since they won't change throughout the function.  */  EHS_parms_as_rtx = expand_expr (EHS_parms, 0, 0, 0);  EHS_name_as_rtx = expand_expr (EHS_name, 0, 0, 0);}voidinit_exception_processing (){  extern tree unhandled_exception_fndecl;  tree cname = get_identifier ("ExceptionHandler");  tree field, chain;  tree ctor, dtor;  tree jmp_buf_type = build_array_type (integer_type_node,					build_index_type (build_int_2 (_JBLEN-1, 0)));  tree jmp_buf_arg_type = build_pointer_type (integer_type_node);  tree parmtypes = hash_tree_chain (jmp_buf_arg_type, void_list_node);  tree setjmp_fndecl, longjmp_fndecl, raise_fndecl;  int old_interface_only = interface_only;  int old_interface_unknown = interface_unknown;  interface_only = 1;  interface_unknown = 0;  EHS_type = xref_tag (record_type_node, cname, NULL_TREE);  push_lang_context (lang_name_c);  setjmp_fndecl = define_function ("setjmp",				   build_function_type (integer_type_node,							parmtypes),				   NOT_BUILT_IN, pushdecl, 0);  BISJ = default_conversion (setjmp_fndecl);  parmtypes = hash_tree_chain (jmp_buf_arg_type,			       hash_tree_chain (integer_type_node, void_list_node));  longjmp_fndecl = define_function ("longjmp",				    build_function_type (void_type_node, parmtypes),				    NOT_BUILT_IN, pushdecl, 0);  raise_fndecl = define_function ("__raise_exception",				  build_function_type (void_type_node,						       hash_tree_chain (ptr_type_node,									hash_tree_chain (build_pointer_type (ptr_type_node), void_list_node))),				  NOT_BUILT_IN, pushdecl, 0);  BILJ = default_conversion (longjmp_fndecl);  BIR = default_conversion (raise_fndecl);  BIUE = default_conversion (unhandled_exception_fndecl);  pop_lang_context ();  /* finish_struct will pop this.  */  pushclass (EHS_type, 0);  field = build_lang_field_decl (FIELD_DECL, get_identifier ("parms"), ptr_type_node);  chain = field;  field = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),				 build_pointer_type (default_function_type));  TREE_CHAIN (field) = chain;  chain = field;  field = build_lang_field_decl (FIELD_DECL, get_identifier ("handler"), jmp_buf_type);  TREE_CHAIN (field) = chain;  chain = field;  field = build_lang_field_decl (FIELD_DECL, get_identifier ("prev"),				 TYPE_POINTER_TO (EHS_type));  TREE_CHAIN (field) = chain;  chain = field;  ctor = build_lang_decl (FUNCTION_DECL, cname,			  build_cplus_method_type (EHS_type, TYPE_POINTER_TO (EHS_type), void_list_node));  DECL_CONSTRUCTOR_P (ctor) = 1;  TREE_STATIC (ctor) = 1;  TREE_PUBLIC (ctor) = 1;  DECL_EXTERNAL (ctor) = 1;  grokclassfn (EHS_type, cname, ctor, NO_SPECIAL, 0);  grok_ctor_properties (EHS_type, ctor);  finish_decl (pushdecl (ctor), 0, 0, 0);  /* Must copy the node here because the FUNCTION_DECL     used inside the struct ain't the same as the     FUNCTION_DECL we stick into the global binding     contour.  */  ctor = copy_node (ctor);  TREE_CHAIN (ctor) = chain;  chain = ctor;  dtor = build_lang_decl (FUNCTION_DECL, cname,			  build_cplus_method_type (EHS_type, TYPE_POINTER_TO (EHS_type), void_list_node));  TREE_STATIC (dtor) = 1;  TREE_PUBLIC (dtor) = 1;  DECL_EXTERNAL (dtor) = 1;  grokclassfn (EHS_type, cname, dtor, DTOR_FLAG, 0);  finish_decl (pushdecl (dtor), 0, 0, 0);  /* Copy for the same reason as copying ctor.  */  dtor = copy_node (dtor);  TREE_CHAIN (dtor) = chain;  chain = dtor;  TYPE_HAS_CONSTRUCTOR (EHS_type) = 1;  TYPE_HAS_DESTRUCTOR (EHS_type) = 1;  finish_struct (EHS_type, temp_tree_cons (NULL_TREE, chain, NULL_TREE), 0, 0);  interface_only = old_interface_only;  interface_unknown = old_interface_unknown;}voidinit_exception_processing_1 (){  register tree EHS_id = get_identifier ("exceptionHandlerStack");  EHS_decl = IDENTIFIER_GLOBAL_VALUE (EHS_id);  /* If we have no other definition, default to library implementation.  */  if (EHS_decl == NULL_TREE)    {      EHS_decl = build_decl (VAR_DECL, EHS_id, TYPE_POINTER_TO (EHS_type));      /* If we don't push this, its definition, should it be encountered,	 will not be seen.  */      EHS_decl = pushdecl (EHS_decl);      DECL_EXTERNAL (EHS_decl) = 1;      TREE_STATIC (EHS_decl) = 1;      TREE_PUBLIC (EHS_decl) = 1;      finish_decl (EHS_decl, 0, 0, 0);    }  else if (TREE_CODE (EHS_decl) != VAR_DECL	   || TREE_TYPE (EHS_decl) != TYPE_POINTER_TO (EHS_type))    fatal ("exception handling declarations conflict with compiler's internal model");  if (EHS_prev == NULL_TREE)    {      register tree EHS_DECL = build1 (INDIRECT_REF, EHS_type, EHS_decl);      EHS_prev = build_component_ref (EHS_DECL, get_identifier ("prev"), 0, 0);      EHS_handler = build_component_ref (EHS_DECL, get_identifier ("handler"), 0, 0);      EHS_parms = build_component_ref (EHS_DECL, get_identifier ("parms"), 0, 0);      EHS_name = build_component_ref (EHS_DECL, get_identifier ("name"), 0, 0);    }}

⌨️ 快捷键说明

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