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

📄 gc.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
	  t = build_ptmd_desc (tdecl, type);	}      else	{	  t = build_ptr_desc (tdecl, type);	}    }  else if (TYPE_BUILT_IN (type))    t = build_bltn_desc (tdecl, type);  else if (IS_AGGR_TYPE (type))    {      if (TYPE_PTRMEMFUNC_P (type))	{	  t = build_ptmf_desc (tdecl, type);	}      else	{	  t = build_class_desc (tdecl, type);	}    }  else if (TREE_CODE (type) == FUNCTION_TYPE)    t = build_func_desc (tdecl);  else     t = build_user_desc (tdecl);  pop_obstacks ();  return t;}#if 0/* This is the old dossier type descriptor generation code, it's much   more extended than rtti. It's reserved for later use. *//* Build an initializer for a __t_desc node.  So that we can take advantage   of recursion, we accept NULL for TYPE.   DEFINITION is greater than zero iff we must define the type descriptor   (as opposed to merely referencing it).  1 means treat according to   #pragma interface/#pragma implementation rules.  2 means define as   global and public, no matter what.  */treebuild_t_desc (type, definition)     tree type;     int definition;{  tree tdecl;  tree tname, name_string;  tree elems, fields;  tree parents, vbases, offsets, ivars, methods, target_type;  int method_count = 0, field_count = 0;  if (type == NULL_TREE)    return NULL_TREE;  tname = build_t_desc_overload (type);  if (IDENTIFIER_AS_DESC (tname)      && (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))))    return IDENTIFIER_AS_DESC (tname);  tdecl = lookup_name (tname, 0);  if (tdecl == NULL_TREE)    {      tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node);      DECL_EXTERNAL (tdecl) = 1;      TREE_PUBLIC (tdecl) = 1;      tdecl = pushdecl_top_level (tdecl);    }  /* If we previously defined it, return the defined result.  */  else if (definition && DECL_INITIAL (tdecl))    return IDENTIFIER_AS_DESC (tname);  if (definition)    {      tree taggr = type;      /* Let T* and T& be written only when T is written (if T is an aggr).         We do this for const, but not for volatile, since volatile	 is rare and const is not.  */      if (!TYPE_VOLATILE (taggr)	  && (TREE_CODE (taggr) == POINTER_TYPE	      || TREE_CODE (taggr) == REFERENCE_TYPE)	  && IS_AGGR_TYPE (TREE_TYPE (taggr)))	taggr = TREE_TYPE (taggr);      /* If we know that we don't need to write out this type's	 vtable, then don't write out it's dossier.  Somebody	 else will take care of that.  */      if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr))	{	  if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr))	    {	      TREE_PUBLIC (tdecl) = ! CLASSTYPE_INTERFACE_ONLY (taggr)		&& CLASSTYPE_INTERFACE_KNOWN (taggr);	      DECL_EXTERNAL (tdecl) = 0;	    }	  else	    {	      if (write_virtuals != 0)		TREE_PUBLIC (tdecl) = 1;	    }	}      else	{	  DECL_EXTERNAL (tdecl) = 0;	  TREE_PUBLIC (tdecl) = (definition > 1);	}    }  SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0));  if (!definition || DECL_EXTERNAL (tdecl))    {      /* That's it!  */      cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);      return IDENTIFIER_AS_DESC (tname);    }  /* Show that we are defining the t_desc for this type.  */  DECL_INITIAL (tdecl) = error_mark_node;  parents = build_tree_list (NULL_TREE, integer_zero_node);  vbases = build_tree_list (NULL_TREE, integer_zero_node);  offsets = build_tree_list (NULL_TREE, integer_zero_node);  methods = NULL_TREE;  ivars = NULL_TREE;  if (TYPE_LANG_SPECIFIC (type))    {      int i = CLASSTYPE_N_BASECLASSES (type);      tree method_vec = CLASSTYPE_METHOD_VEC (type);      tree *meth, *end;      tree binfos = TYPE_BINFO_BASETYPES (type);      tree vb = CLASSTYPE_VBASECLASSES (type);      while (--i >= 0)	parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents);      while (vb)	{	  vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases);	  offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets);	  vb = TREE_CHAIN (vb);	}      if (method_vec)	for (meth = TREE_VEC_END (method_vec),	     end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; )	  if (*meth)	    {	      methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods);	      method_count++;	    }    }  if (IS_AGGR_TYPE (type))    {      for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))	if (TREE_CODE (fields) == FIELD_DECL	    || TREE_CODE (fields) == VAR_DECL)	  {	    ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars);	    field_count++;	  }      ivars = nreverse (ivars);    }  parents = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), parents, 0);  vbases = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), vbases, 0);  offsets = finish_table (NULL_TREE, integer_type_node, offsets, 0);  if (methods == NULL_TREE)    methods = null_pointer_node;  else    methods = build_unary_op (ADDR_EXPR,			      finish_table (NULL_TREE, __m_desc_type_node, methods, 0),			      0);  if (ivars == NULL_TREE)    ivars = null_pointer_node;  else    ivars = build_unary_op (ADDR_EXPR,			    finish_table (NULL_TREE, __i_desc_type_node, ivars, 0),			    0);  if (TREE_TYPE (type))    target_type = build_t_desc (TREE_TYPE (type), definition);  else    target_type = integer_zero_node;  name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname)));  elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),	   tree_cons (NULL_TREE,		      TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node,	     /* really should use bitfield initialization here.  */	     tree_cons (NULL_TREE, integer_zero_node,	      tree_cons (NULL_TREE, target_type,	       tree_cons (NULL_TREE, build_int_2 (field_count, 2),		tree_cons (NULL_TREE, build_int_2 (method_count, 2),		 tree_cons (NULL_TREE, ivars,		  tree_cons (NULL_TREE, methods,		   tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0),		    tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0),		     build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0))))))))))));  return build_generic_desc (tdecl, elems);}/* Build an initializer for a __i_desc node.  */treebuild_i_desc (decl)     tree decl;{  tree elems, name_string;  tree taggr;  name_string = DECL_NAME (decl);  name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));  /* Now decide whether this ivar should cause it's type to get     def'd or ref'd in this file.  If the type we are looking at     has a proxy definition, we look at the proxy (i.e., a     `foo *' is equivalent to a `foo').  */  taggr = TREE_TYPE (decl);  if ((TREE_CODE (taggr) == POINTER_TYPE       || TREE_CODE (taggr) == REFERENCE_TYPE)      && TYPE_VOLATILE (taggr) == 0)    taggr = TREE_TYPE (taggr);  elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),	     tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl),		build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl),							  ! IS_AGGR_TYPE (taggr)))));  taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems);  TREE_CONSTANT (taggr) = 1;  TREE_STATIC (taggr) = 1;  TREE_READONLY (taggr) = 1;  return taggr;}/* Build an initializer for a __m_desc node.  */treebuild_m_desc (decl)     tree decl;{  tree taggr, elems, name_string;  tree parm_count, req_count, vindex, vcontext;  tree parms;  int p_count, r_count;  tree parm_types = NULL_TREE;  for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0;       parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++)    {      taggr = TREE_VALUE (parms);      if ((TREE_CODE (taggr) == POINTER_TYPE	   || TREE_CODE (taggr) == REFERENCE_TYPE)	  && TYPE_VOLATILE (taggr) == 0)	taggr = TREE_TYPE (taggr);      parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms),						       ! IS_AGGR_TYPE (taggr)),			      parm_types);      if (TREE_PURPOSE (parms) == NULL_TREE)	r_count++;    }  parm_types = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node),			     nreverse (parm_types), 0);  parm_count = build_int_2 (p_count, 0);  req_count = build_int_2 (r_count, 0);  if (DECL_VINDEX (decl))    vindex = DECL_VINDEX (decl);  else    vindex = integer_zero_node;  if (DECL_CONTEXT (decl)      && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')    vcontext = build_t_desc (DECL_CONTEXT (decl), 0);  else    vcontext = integer_zero_node;  name_string = DECL_NAME (decl);  if (name_string == NULL)      name_string = DECL_ASSEMBLER_NAME (decl);  name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));  /* Now decide whether the return type of this mvar     should cause it's type to get def'd or ref'd in this file.     If the type we are looking at has a proxy definition,     we look at the proxy (i.e., a `foo *' is equivalent to a `foo').  */  taggr = TREE_TYPE (TREE_TYPE (decl));  if ((TREE_CODE (taggr) == POINTER_TYPE       || TREE_CODE (taggr) == REFERENCE_TYPE)      && TYPE_VOLATILE (taggr) == 0)    taggr = TREE_TYPE (taggr);  elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),	     tree_cons (NULL_TREE, vindex,		tree_cons (NULL_TREE, vcontext,		   tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)),						       ! IS_AGGR_TYPE (taggr)),		      tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0), 0),			 tree_cons (NULL_TREE, parm_count,			    tree_cons (NULL_TREE, req_count,			       build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0)))))))));  taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems);  TREE_CONSTANT (taggr) = 1;  TREE_STATIC (taggr) = 1;  TREE_READONLY (taggr) = 1;  return taggr;}#endif /* dossier *//* Conditionally emit code to set up an unwind-protect for the   garbage collector.  If this function doesn't do anything that involves   the garbage collector, then do nothing.  Otherwise, call __gc_push   at the beginning and __gc_pop at the end.   NOTE!  The __gc_pop function must operate transparently, since   it comes where the logical return label lies.  This means that   at runtime *it* must preserve any return value registers.  */voidexpand_gc_prologue_and_epilogue (){  extern tree maybe_gc_cleanup;  struct rtx_def *last_parm_insn, *mark;  extern struct rtx_def *get_last_insn ();  extern struct rtx_def *get_first_nonparm_insn ();  extern struct rtx_def *previous_insn ();  tree action;  /* If we didn't need the obstack, don't cons any space.  */  if (current_function_obstack_index == 0      || current_function_obstack_usage == 0)    return;  mark = get_last_insn ();  last_parm_insn = get_first_nonparm_insn ();  if (last_parm_insn == 0) last_parm_insn = mark;  else last_parm_insn = previous_insn (last_parm_insn);  action = build_function_call (gc_push_fndecl,				build_tree_list (NULL_TREE, size_int (++current_function_obstack_index)));  expand_expr_stmt (action);  reorder_insns (next_insn (mark), get_last_insn (), last_parm_insn);  /* This will be expanded as a cleanup.  */  TREE_VALUE (maybe_gc_cleanup)    = build_function_call (gc_pop_fndecl, NULL_TREE);}/* Some day we'll use this function as a call-back and clean   up all the unnecessary gc dribble that we otherwise create.  */voidlang_expand_end_bindings (first, last)     struct rtx_def *first, *last;{}voidinit_gc_processing (){  tree parmtypes = hash_tree_chain (class_star_type_node,				    hash_tree_chain (integer_type_node, NULL_TREE));  gc_protect_fndecl = define_function ("__gc_protect",				       build_function_type (class_star_type_node, parmtypes),				       NOT_BUILT_IN, 0, 0);  parmtypes = hash_tree_chain (integer_type_node, NULL_TREE);  gc_unprotect_fndecl = define_function ("__gc_unprotect",					 build_function_type (void_type_node, parmtypes),					 NOT_BUILT_IN, 0, 0);  gc_push_fndecl = define_function ("__gc_push",				    TREE_TYPE (gc_unprotect_fndecl),				    NOT_BUILT_IN, 0, 0);  gc_pop_fndecl = define_function ("__gc_pop",				   build_function_type (void_type_node,							void_list_node),				   NOT_BUILT_IN, 0, 0);  gc_nonobject = build_int_2 (0x80000000, 0);  gc_visible = build_int_2 (0x40000000, 0);  gc_white = integer_zero_node;  gc_offwhite = build_int_2 (0x10000000, 0);  gc_grey = build_int_2 (0x20000000, 0);  gc_black = build_int_2 (0x30000000, 0);}

⌨️ 快捷键说明

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