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

📄 class.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* We better not run out of stuff to make it unique.  */      my_friendly_assert (path != NULL_TREE, 368);      basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));      if (for_type == basetype)	{	  /* If we run out of basetypes in the path, we have already	     found created a vtable with that name before, we now	     resort to tacking on _%d to distinguish them.  */	  int j = 2;	  i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;	  buf1 = (char *) alloca (i);	  do {	    sprintf (buf1, "%s%c%s%c%d",		     TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,		     buf2, joiner, j);	    buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)				   + strlen (buf1) + 1);	    sprintf (buf, VTABLE_NAME_FORMAT, buf1);	    name = get_identifier (buf);	    /* If this name doesn't clash, then we can use it,	       otherwise we add something different to the name until	       it is unique.  */	  } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));	  /* Hey, they really like MI don't they?  Increase the 3             above to 6, and the 999 to 999999.  :-)  */	  my_friendly_assert (j <= 999, 369);	  break;	}      i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;      new_buf2 = (char *) alloca (i);      sprintf (new_buf2, "%s%c%s",	       TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2);      buf2 = new_buf2;    }  new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl));  /* Remember which class this vtable is really for.  */  DECL_CONTEXT (new_decl) = for_type;  DECL_ARTIFICIAL (new_decl) = 1;  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))    {      tree binfo1 = binfo_member (BINFO_TYPE (binfo), 				  CLASSTYPE_VBASECLASSES (for_type));      /* XXX - This should never happen, if it does, the caller should	 ensure that the binfo is from for_type's binfos, not from any	 base type's.  We can remove all this code after a while.  */      if (binfo1 != binfo)	warning ("internal inconsistency: binfo offset error for rtti");      offset = BINFO_OFFSET (binfo1);    }  else    offset = BINFO_OFFSET (binfo);  set_rtti_entry (BINFO_VIRTUALS (binfo),		  ssize_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);}/* Return a new vtable for use in initialization of the BASE subobject   of COMPLETE_TYPE. The vtable there goes into the vfield of the   VBASEBASE virtual subobject.  */static treeprepare_ctor_vtable (complete_type, base, vbasebase)     tree complete_type, base, vbasebase;{  tree orig_decl = BINFO_VTABLE (vbasebase);  tree name = get_vlist_vtable_id (base, vbasebase);  tree new_decl;  new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl));  /* Remember which class this vtable is really for.  */  DECL_CONTEXT (new_decl) = complete_type;  DECL_ARTIFICIAL (new_decl) = 1;  TREE_STATIC (new_decl) = 1;  new_decl = 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);#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, complete_type, 0);  return new_decl;}#if 0/* 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;}#endif/* 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 N.  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 voidadd_virtual_function (pv, phv, has_virtual, fndecl, t)     tree *pv, *phv;     int *has_virtual;     tree fndecl;     tree t; /* Structure type.  */{  tree pending_virtuals = *pv;  tree pending_hard_virtuals = *phv;  /* 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;      /* We remember that this was the base sub-object for rtti.  */      CLASSTYPE_RTTI (t) = t;      /* If we are using thunks, use two slots at the front, one	 for the offset pointer, one for the tdesc pointer.         For ARM-style vtables, use the same slot for both.  */      if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t))	{	  if (flag_vtable_thunks)	    *has_virtual = 2;	  else	    *has_virtual = 1;	}      /* Build a new INT_CST for this DECL_VINDEX.  */      {	static tree index_table[256];	tree idx;	/* We skip a slot for the offset/tdesc entry.  */	int i = (*has_virtual)++;	if (i >= 256 || index_table[i] == 0)	  {	    idx = build_int_2 (i, 0);	    if (i < 256)	      index_table[i] = idx;	  }	else	  idx = index_table[i];	/* Now assign virtual dispatch information.  */	DECL_VINDEX (fndecl) = idx;	DECL_CONTEXT (fndecl) = t;      }      entry = build_vtable_entry (integer_zero_node, vfn);      pending_virtuals = tree_cons (DECL_VINDEX (fndecl), entry, pending_virtuals);    }  /* Might already be INTEGER_CST if declared twice in class.  We will     give error later or we've already given it.  */  else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)    {      /* Need an entry in some other virtual function table.         Deal with this after we have laid out our virtual base classes.  */      pending_hard_virtuals = temp_tree_cons (fndecl, vfn, pending_hard_virtuals);    }  *pv = pending_virtuals;  *phv = pending_hard_virtuals;}/* Obstack on which to build the vector of class methods.  */struct obstack class_obstack;extern struct obstack *current_obstack;/* These are method vectors that were too small for the number of   methods in some class, and so were abandoned.  */static tree free_method_vecs;/* Returns a method vector with enough room for N methods.  N should   be a power of two.  */static treemake_method_vec (n)     int n;{  tree new_vec;  tree* t;    for (t = &free_method_vecs; *t; t = &(TREE_CHAIN (*t)))    /* Note that we don't use >= n here because we don't want to       allocate a very large vector where it isn't needed.  */    if (TREE_VEC_LENGTH (*t) == n)      {	new_vec = *t;	*t = TREE_CHAIN (new_vec);	TREE_CHAIN (new_vec) = NULL_TREE;	bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree));	return new_vec;      }  new_vec = make_tree_vec (n);  return new_vec;}/* Free the method vector VEC.  */static voidfree_method_vec (vec)     tree vec;{  TREE_CHAIN (vec) = free_method_vecs;  free_method_vecs = vec;}/* Add method METHOD to class TYPE.   If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of   the class type where the method should be added.  */voidadd_method (type, fields, method)     tree type, *fields, method;{  push_obstacks_nochange ();  end_temporary_allocation ();  /* Setting the DECL_CONTEXT and DECL_CLASS_CONTEXT here is probably     redundant.  */  DECL_CONTEXT (method) = type;  DECL_CLASS_CONTEXT (method) = type;    if (fields && *fields)    *fields = build_overload (method, *fields);  else     {      int len;      int slot;      tree method_vec;      if (!CLASSTYPE_METHOD_VEC (type))	/* Make a new method vector.  We start with 8 entries.  We must	   allocate at least two (for constructors and destructors), and	   we're going to end up with an assignment operator at some	   point as well.  	   We could use a TREE_LIST for now, and convert it to a	   TREE_VEC in finish_struct, but we would probably waste more	   memory making the links in the list than we would by	   over-allocating the size of the vector here.  Furthermore,	   we would complicate all the code that expects this to be a	   vector.  We keep a free list of vectors that we outgrew so	   that we don't really waste any memory.  */	CLASSTYPE_METHOD_VEC (type) = make_method_vec (8);      method_vec = CLASSTYPE_METHOD_VEC (type);      len = TREE_VEC_LENGTH (method_vec);      if (DECL_NAME (method) == constructor_name (type))	/* A new constructor or destructor.  Constructors go in 	   slot 0; destructors go in slot 1.  */	slot = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0;      else	{	  /* See if we already have an entry with this name.  */	  for (slot = 2; slot < len; ++slot)	    if (!TREE_VEC_ELT (method_vec, slot)		|| (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, 							  slot))) 		    == DECL_NAME (method)))	      break;			  if (slot == len)	    {	      /* We need a bigger method vector.  */	      tree new_vec = make_method_vec (2 * len);	      bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0),		     (PTR) &TREE_VEC_ELT (new_vec, 0),		     len * sizeof (tree));	      free_method_vec (method_vec);	      len = 2 * len;	      method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;	    }	  if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot))	    {	      /* Type conversion operators have to come before		 ordinary methods; add_conversions depends on this to		 speed up looking for conversion operators.  So, if		 necessary, we slide some of the vector elements up.		 In theory, this makes this algorithm O(N^2) but we		 don't expect many conversion operators.  */	      for (slot = 2; slot < len; ++slot)		{		  tree fn = TREE_VEC_ELT (method_vec, slot);  		  if (!fn)		    /* There are no more entries in the vector, so we		       can insert the new conversion operator here.  */		    break;  		  

⌨️ 快捷键说明

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