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

📄 class.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
treebuild_vfn_ref (ptr_to_instptr, instance, idx)     tree *ptr_to_instptr, instance;     tree idx;{  extern int building_cleanup;  tree vtbl, aref;  tree basetype = TREE_TYPE (instance);  if (TREE_CODE (basetype) == REFERENCE_TYPE)    basetype = TREE_TYPE (basetype);  if (instance == C_C_D)    vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),			       NULL_PTR);  else    {      if (optimize)	{	  /* Try to figure out what a reference refers to, and	     access its virtual function table directly.  */	  tree ref = NULL_TREE;	  if (TREE_CODE (instance) == INDIRECT_REF	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)	    ref = TREE_OPERAND (instance, 0);	  else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)	    ref = instance;	  if (ref && TREE_CODE (ref) == VAR_DECL	      && DECL_INITIAL (ref))	    {	      tree init = DECL_INITIAL (ref);	      while (TREE_CODE (init) == NOP_EXPR		     || TREE_CODE (init) == NON_LVALUE_EXPR)		init = TREE_OPERAND (init, 0);	      if (TREE_CODE (init) == ADDR_EXPR)		{		  init = TREE_OPERAND (init, 0);		  if (IS_AGGR_TYPE (TREE_TYPE (init))		      && (TREE_CODE (init) == PARM_DECL			  || TREE_CODE (init) == VAR_DECL))		    instance = init;		}	    }	}      if (IS_AGGR_TYPE (TREE_TYPE (instance))	  && (TREE_CODE (instance) == RESULT_DECL	      || TREE_CODE (instance) == PARM_DECL	      || TREE_CODE (instance) == VAR_DECL))	vtbl = TYPE_BINFO_VTABLE (basetype);      else	vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),				   NULL_PTR);    }  assemble_external (vtbl);  aref = build_array_ref (vtbl, idx);  /* Save the intermediate result in a SAVE_EXPR so we don't have to     compute each component of the virtual function pointer twice.  */   if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF)    TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));  if (flag_vtable_thunks)    return aref;  else    {      if (ptr_to_instptr)	*ptr_to_instptr	  = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),		   *ptr_to_instptr,		   convert (ptrdiff_type_node,			    build_component_ref (aref, delta_identifier, 0, 0)));      return build_component_ref (aref, pfn_identifier, 0, 0);    }}/* Return the name of the virtual function table (as an IDENTIFIER_NODE)   for the given TYPE.  */static treeget_vtable_name (type)     tree type;{  tree type_id = build_typename_overload (type);  char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT)			      + IDENTIFIER_LENGTH (type_id) + 2);  char *ptr = IDENTIFIER_POINTER (type_id);  int i;  for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;#if 0  /* We don't take off the numbers; prepare_fresh_vtable uses the     DECL_ASSEMBLER_NAME for the type, which includes the number     in `3foo'.  If we were to pull them off here, we'd end up with     something like `_vt.foo.3bar', instead of a uniform definition.  */  while (ptr[i] >= '0' && ptr[i] <= '9')    i += 1;#endif  sprintf (buf, VTABLE_NAME_FORMAT, ptr+i);  return get_identifier (buf);}/* Build a virtual function for type TYPE.   If BINFO is non-NULL, build the vtable starting with the initial   approximation that it is the same as the one which is the head of   the association list.  */static treebuild_vtable (binfo, type)     tree binfo, type;{  tree name = get_vtable_name (type);  tree virtuals, decl;  if (binfo)    {      virtuals = copy_list (BINFO_VIRTUALS (binfo));      decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo)));    }  else    {      virtuals = NULL_TREE;      decl = build_decl (VAR_DECL, name, void_type_node);    }#ifdef GATHER_STATISTICS  n_vtables += 1;  n_vtable_elems += list_length (virtuals);#endif  /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */  import_export_vtable (decl, type, 0);  IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);  /* Initialize the association list for this type, based     on our first approximation.  */  TYPE_BINFO_VTABLE (type) = decl;  TYPE_BINFO_VIRTUALS (type) = virtuals;  TREE_STATIC (decl) = 1;#ifndef WRITABLE_VTABLES  /* Make them READONLY by default. (mrs) */  TREE_READONLY (decl) = 1;#endif  /* At one time the vtable info was grabbed 2 words at a time.  This     fails on sparc unless you have 8-byte alignment.  (tiemann) */  DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),			   DECL_ALIGN (decl));  /* Why is this conditional? (mrs) */  if (binfo && write_virtuals >= 0)    DECL_VIRTUAL_P (decl) = 1;  DECL_CONTEXT (decl) = type;  binfo = TYPE_BINFO (type);  SET_BINFO_NEW_VTABLE_MARKED (binfo);  return decl;}/* Given a base type PARENT, and a derived type TYPE, build   a name which distinguishes exactly the PARENT member of TYPE's type.   FORMAT is a string which controls how sprintf formats the name   we have generated.   For example, given	class A; class B; class C : A, B;   it is possible to distinguish "A" from "C's A".  And given	class L;	class A : L; class B : L; class C : A, B;   it is possible to distinguish "L" from "A's L", and also from   "C's L from A".   Make sure to use the DECL_ASSEMBLER_NAME of the TYPE_NAME of the   type, as template have DECL_NAMEs like: X<int>, whereas the   DECL_ASSEMBLER_NAME is set to be something the assembler can handle.  */static treebuild_type_pathname (format, parent, type)     char *format;     tree parent, type;{  extern struct obstack temporary_obstack;  char *first, *base, *name;  int i;  tree id;  parent = TYPE_MAIN_VARIANT (parent);  /* Remember where to cut the obstack to.  */  first = obstack_base (&temporary_obstack);  /* Put on TYPE+PARENT.  */  obstack_grow (&temporary_obstack,		TYPE_ASSEMBLER_NAME_STRING (type),		TYPE_ASSEMBLER_NAME_LENGTH (type));#ifdef JOINER  obstack_1grow (&temporary_obstack, JOINER);#else  obstack_1grow (&temporary_obstack, '_');#endif  obstack_grow0 (&temporary_obstack,		 TYPE_ASSEMBLER_NAME_STRING (parent),		 TYPE_ASSEMBLER_NAME_LENGTH (parent));  i = obstack_object_size (&temporary_obstack);  base = obstack_base (&temporary_obstack);  obstack_finish (&temporary_obstack);  /* Put on FORMAT+TYPE+PARENT.  */  obstack_blank (&temporary_obstack, strlen (format) + i + 1);  name = obstack_base (&temporary_obstack);  sprintf (name, format, base);  id = get_identifier (name);  obstack_free (&temporary_obstack, first);  return id;}/* Update the rtti info for this class.  */static voidset_rtti_entry (virtuals, offset, type)     tree virtuals, offset, type;{  if (! flag_vtable_thunks)    TREE_VALUE (virtuals)      = build_vtable_entry (offset,			    (flag_rtti			     ? build_t_desc (type, 0)			     : integer_zero_node));  else    {      tree vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);      TREE_CONSTANT (vfn) = 1;      TREE_VALUE (virtuals)	= build_vtable_entry (integer_zero_node, vfn);      /* The second slot is for the tdesc pointer when thunks are used.  */      vfn = flag_rtti	     ? build_t_desc (type, 0)	     : integer_zero_node;      vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, vfn);      TREE_CONSTANT (vfn) = 1;      TREE_VALUE (TREE_CHAIN (virtuals))	= build_vtable_entry (integer_zero_node, vfn);    }}/* Give TYPE a new virtual function table which is initialized   with a skeleton-copy of its original initialization.  The only   entry that changes is the `delta' entry, so we can really   share a lot of structure.   FOR_TYPE is the derived type which caused this table to   be needed.   BINFO is the type association which provided TYPE for FOR_TYPE.  */static voidprepare_fresh_vtable (binfo, for_type)     tree binfo, for_type;{  tree basetype = BINFO_TYPE (binfo);  tree orig_decl = BINFO_VTABLE (binfo);  /* This name is too simplistic.  We can have multiple basetypes for     for_type, and we really want different names.  (mrs) */  tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);  tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));  tree path, offset;  int result;  /* Remember which class this vtable is really for.  */  DECL_CONTEXT (new_decl) = for_type;  TREE_STATIC (new_decl) = 1;  BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl);  DECL_VIRTUAL_P (new_decl) = 1;#ifndef WRITABLE_VTABLES  /* Make them READONLY by default. (mrs) */  TREE_READONLY (new_decl) = 1;#endif  DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl);  /* Make fresh virtual list, so we can smash it later.  */  BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));  if (TREE_VIA_VIRTUAL (binfo))    offset = BINFO_OFFSET (binfo_member (BINFO_TYPE (binfo), 			    CLASSTYPE_VBASECLASSES (for_type)));  else    offset = BINFO_OFFSET (binfo);  set_rtti_entry (BINFO_VIRTUALS (binfo),		  size_binop (MINUS_EXPR, integer_zero_node, offset),		  for_type);#ifdef GATHER_STATISTICS  n_vtables += 1;  n_vtable_elems += list_length (BINFO_VIRTUALS (binfo));#endif  /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */  import_export_vtable (new_decl, for_type, 0);  if (TREE_VIA_VIRTUAL (binfo))    my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),				   CLASSTYPE_VBASECLASSES (current_class_type)),			170);  SET_BINFO_NEW_VTABLE_MARKED (binfo);}/* Access the virtual function table entry that logically   contains BASE_FNDECL.  VIRTUALS is the virtual function table's   initializer.  We can run off the end, when dealing with virtual   destructors in MI situations, return NULL_TREE in that case.  */static treeget_vtable_entry (virtuals, base_fndecl)     tree virtuals, base_fndecl;{  unsigned HOST_WIDE_INT n = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD	   ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))	      & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1))	   : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)));#ifdef GATHER_STATISTICS  n_vtable_searches += n;#endif  while (n > 0 && virtuals)    {      --n;      virtuals = TREE_CHAIN (virtuals);    }  return virtuals;}/* Put new entry ENTRY into virtual function table initializer   VIRTUALS.   Also update DECL_VINDEX (FNDECL).  */static voidmodify_vtable_entry (old_entry_in_list, new_entry, fndecl)     tree old_entry_in_list, new_entry, fndecl;{  tree base_fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)), 0);#ifdef NOTQUITE  cp_warning ("replaced %D with %D", DECL_ASSEMBLER_NAME (base_fndecl),	      DECL_ASSEMBLER_NAME (fndecl));#endif  TREE_VALUE (old_entry_in_list) = new_entry;  /* Now assign virtual dispatch information, if unset.  */  /* We can dispatch this, through any overridden base function. */  if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)    {      DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl);      DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl);    }}/* Access the virtual function table entry i.  VIRTUALS is the virtual   function table's initializer.  */static treeget_vtable_entry_n (virtuals, n)     tree virtuals;     unsigned HOST_WIDE_INT n;{  while (n > 0)    {      --n;      virtuals = TREE_CHAIN (virtuals);    }  return virtuals;}/* Add a virtual function to all the appropriate vtables for the class   T.  DECL_VINDEX(X) should be error_mark_node, if we want to   allocate a new slot in our table.  If it is error_mark_node, we   know that no other function from another vtable is overridden by X.   HAS_VIRTUAL keeps track of how many virtuals there are in our main   vtable for the type, and we build upon the PENDING_VIRTUALS list   and return it.  */static treeadd_virtual_function (pending_virtuals, has_virtual, fndecl, t)     tree pending_virtuals;     int *has_virtual;     tree fndecl;     tree t; /* Structure type. */{  /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely     convert to void *.  Make such a conversion here.  */  tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);  TREE_CONSTANT (vfn) = 1;#ifndef DUMB_USER  if (current_class_type == 0)    cp_warning ("internal problem, current_class_type is zero when adding `%D', please report",		fndecl);  if (current_class_type && t != current_class_type)    cp_warning ("internal problem, current_class_type differs when adding `%D', please report",		fndecl);#endif  /* If the virtual function is a redefinition of a prior one,     figure out in which base class the new definition goes,     and if necessary, make a fresh virtual function table     to hold that entry.  */  if (DECL_VINDEX (fndecl) == error_mark_node)    {      tree entry;      if (flag_rtti && *has_virtual == 0)	{	  /* CLASSTYPE_RTTI is only used as a Boolean (NULL or not). */	  CLASSTYPE_RTTI (t) = integer_one_node;        }

⌨️ 快捷键说明

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