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

📄 tree.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 4 页
字号:
	  type = copy_node (type);	  TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0;	}      TYPE_MAIN_VARIANT (type) = real_main_variant;      pop_obstacks ();    }  return build_type_variant (type, constp, volatilep);}/* Add OFFSET to all base types of T.   OFFSET, which is a type offset, is number of bytes.   Note that we don't have to worry about having two paths to the   same base type, since this type owns its association list.  */voidpropagate_binfo_offsets (binfo, offset)     tree binfo;     tree offset;{  tree binfos = BINFO_BASETYPES (binfo);  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;  for (i = 0; i < n_baselinks; /* note increment is done in the loop.  */)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      if (TREE_VIA_VIRTUAL (base_binfo))	i += 1;      else	{	  int j;	  tree base_binfos = BINFO_BASETYPES (base_binfo);	  tree delta;	  for (j = i+1; j < n_baselinks; j++)	    if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j)))	      {		/* The next basetype offset must take into account the space		   between the classes, not just the size of each class.  */		delta = size_binop (MINUS_EXPR,				    BINFO_OFFSET (TREE_VEC_ELT (binfos, j)),				    BINFO_OFFSET (base_binfo));		break;	      }#if 0	  if (BINFO_OFFSET_ZEROP (base_binfo))	    BINFO_OFFSET (base_binfo) = offset;	  else	    BINFO_OFFSET (base_binfo)	      = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset);#else	  BINFO_OFFSET (base_binfo) = offset;#endif	  if (base_binfos)	    {	      int k;	      tree chain = NULL_TREE;	      /* Now unshare the structure beneath BASE_BINFO.  */	      for (k = TREE_VEC_LENGTH (base_binfos)-1;		   k >= 0; k--)		{		  tree base_base_binfo = TREE_VEC_ELT (base_binfos, k);		  if (! TREE_VIA_VIRTUAL (base_base_binfo))		    TREE_VEC_ELT (base_binfos, k)		      = make_binfo (BINFO_OFFSET (base_base_binfo),				    base_base_binfo,				    BINFO_VTABLE (base_base_binfo),				    BINFO_VIRTUALS (base_base_binfo),				    chain);		  chain = TREE_VEC_ELT (base_binfos, k);		  TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);		  TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);		  BINFO_INHERITANCE_CHAIN (chain) = base_binfo;		}	      /* Now propagate the offset to the base types.  */	      propagate_binfo_offsets (base_binfo, offset);	    }	  /* Go to our next class that counts for offset propagation.  */	  i = j;	  if (i < n_baselinks)	    offset = size_binop (PLUS_EXPR, offset, delta);	}    }}/* Compute the actual offsets that our virtual base classes   will have *for this type*.  This must be performed after   the fields are laid out, since virtual baseclasses must   lay down at the end of the record.   Returns the maximum number of virtual functions any of the virtual   baseclasses provide.  */intlayout_vbasetypes (rec, max)     tree rec;     int max;{  /* Get all the virtual base types that this type uses.     The TREE_VALUE slot holds the virtual baseclass type.  */  tree vbase_types = get_vbase_types (rec);#ifdef STRUCTURE_SIZE_BOUNDARY  unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));#else  unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));#endif  int desired_align;  /* Record size so far is CONST_SIZE + VAR_SIZE bits,     where CONST_SIZE is an integer     and VAR_SIZE is a tree expression.     If VAR_SIZE is null, the size is just CONST_SIZE.     Naturally we try to avoid using VAR_SIZE.  */  register unsigned const_size = 0;  register tree var_size = 0;  int nonvirtual_const_size;  tree nonvirtual_var_size;  CLASSTYPE_VBASECLASSES (rec) = vbase_types;  if (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST)    const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));  else    var_size = TYPE_SIZE (rec);  nonvirtual_const_size = const_size;  nonvirtual_var_size = var_size;  while (vbase_types)    {      tree basetype = BINFO_TYPE (vbase_types);      tree offset;      desired_align = TYPE_ALIGN (basetype);      record_align = MAX (record_align, desired_align);      if (const_size == 0)	offset = integer_zero_node;      else	{	  /* Give each virtual base type the alignment it wants.  */	  const_size = CEIL (const_size, TYPE_ALIGN (basetype))	    * TYPE_ALIGN (basetype);	  offset = size_int (CEIL (const_size, BITS_PER_UNIT));	}      if (CLASSTYPE_VSIZE (basetype) > max)	max = CLASSTYPE_VSIZE (basetype);      BINFO_OFFSET (vbase_types) = offset;      if (TREE_CODE (TYPE_SIZE (basetype)) == INTEGER_CST)	{	  /* Every virtual baseclass takes a least a UNIT, so that we can	     take it's address and get something different for each base.  */	  const_size += MAX (BITS_PER_UNIT,			     TREE_INT_CST_LOW (TYPE_SIZE (basetype))			     - TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype)));	}      else if (var_size == 0)	var_size = TYPE_SIZE (basetype);      else	var_size = size_binop (PLUS_EXPR, var_size, TYPE_SIZE (basetype));      vbase_types = TREE_CHAIN (vbase_types);    }  if (const_size)    {      /* Because a virtual base might take a single byte above,	 we have to re-adjust the total size to make sure it it	 a multiple of the alignment.  */      /* Give the whole object the alignment it wants.  */      const_size = CEIL (const_size, record_align) * record_align;    }  /* Set the alignment in the complete type.  We don't set CLASSTYPE_ALIGN   here, as that is for this class, without any virtual base classes.  */  TYPE_ALIGN (rec) = record_align;  if (const_size != nonvirtual_const_size)    {      CLASSTYPE_VBASE_SIZE (rec)	= size_int (const_size - nonvirtual_const_size);      TYPE_SIZE (rec) = size_int (const_size);    }  /* Now propagate offset information throughout the lattice     under the vbase type.  */  for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;       vbase_types = TREE_CHAIN (vbase_types))    {      tree base_binfos = BINFO_BASETYPES (vbase_types);      BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);      if (base_binfos)	{	  tree chain = NULL_TREE;	  int j;	  /* Now unshare the structure beneath BASE_BINFO.  */	  for (j = TREE_VEC_LENGTH (base_binfos)-1;	       j >= 0; j--)	    {	      tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);	      if (! TREE_VIA_VIRTUAL (base_base_binfo))		TREE_VEC_ELT (base_binfos, j)		  = make_binfo (BINFO_OFFSET (base_base_binfo),				base_base_binfo,				BINFO_VTABLE (base_base_binfo),				BINFO_VIRTUALS (base_base_binfo),				chain);	      chain = TREE_VEC_ELT (base_binfos, j);	      TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);	      TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);	      BINFO_INHERITANCE_CHAIN (chain) = vbase_types;	    }	  propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));	}    }  return max;}/* Lay out the base types of a record type, REC.   Tentatively set the size and alignment of REC   according to the base types alone.   Offsets for immediate nonvirtual baseclasses are also computed here.   TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine   creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS.   Returns list of virtual base classes in a FIELD_DECL chain.  */treelayout_basetypes (rec, binfos)     tree rec, binfos;{  /* Chain to hold all the new FIELD_DECLs which point at virtual     base classes.  */  tree vbase_decls = NULL_TREE;#ifdef STRUCTURE_SIZE_BOUNDARY  unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));#else  unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));#endif  /* Record size so far is CONST_SIZE + VAR_SIZE bits, where CONST_SIZE is     an integer and VAR_SIZE is a tree expression.  If VAR_SIZE is null,     the size is just CONST_SIZE.  Naturally we try to avoid using     VAR_SIZE.  And so far, we've been successful. */#if 0  register tree var_size = 0;#endif  register unsigned const_size = 0;  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;  /* Handle basetypes almost like fields, but record their     offsets differently.  */  for (i = 0; i < n_baseclasses; i++)    {      int inc, desired_align, int_vbase_size;      register tree base_binfo = TREE_VEC_ELT (binfos, i);      register tree basetype = BINFO_TYPE (base_binfo);      tree decl, offset;      if (TYPE_SIZE (basetype) == 0)	{#if 0	  /* This error is now reported in xref_tag, thus giving better	     location information.  */	  error_with_aggr_type (base_binfo,				"base class `%s' has incomplete type");	  TREE_VIA_PUBLIC (base_binfo) = 1;	  TREE_VIA_PROTECTED (base_binfo) = 0;	  TREE_VIA_VIRTUAL (base_binfo) = 0;	  /* Should handle this better so that	     class A;	     class B: private A { virtual void F(); };	     does not dump core when compiled. */	  my_friendly_abort (121);#endif	  continue;	}      /* All basetypes are recorded in the association list of the	 derived type.  */      if (TREE_VIA_VIRTUAL (base_binfo))	{	  int j;	  char *name = (char *)alloca (TYPE_NAME_LENGTH (basetype)				       + sizeof (VBASE_NAME) + 1);	  /* The offset for a virtual base class is only used in computing	     virtual function tables and for initializing virtual base	     pointers.  It is built once `get_vbase_types' is called.  */	  /* If this basetype can come from another vbase pointer	     without an additional indirection, we will share	     that pointer.  If an indirection is involved, we	     make our own pointer.  */	  for (j = 0; j < n_baseclasses; j++)	    {	      tree other_base_binfo = TREE_VEC_ELT (binfos, j);	      if (! TREE_VIA_VIRTUAL (other_base_binfo)		  && binfo_member (basetype,				   CLASSTYPE_VBASECLASSES (BINFO_TYPE (other_base_binfo))))		goto got_it;	    }	  sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));	  decl = build_lang_decl (FIELD_DECL, get_identifier (name),				  build_pointer_type (basetype));	  /* If you change any of the below, take a look at all the	     other VFIELD_BASEs and VTABLE_BASEs in the code, and change	     them too. */	  DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE);	  DECL_VIRTUAL_P (decl) = 1;	  DECL_FIELD_CONTEXT (decl) = rec;	  DECL_CLASS_CONTEXT (decl) = rec;	  DECL_FCONTEXT (decl) = basetype;	  DECL_SAVED_INSNS (decl) = NULL_RTX;	  DECL_FIELD_SIZE (decl) = 0;	  DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node);	  TREE_CHAIN (decl) = vbase_decls;	  BINFO_VPTR_FIELD (base_binfo) = decl;	  vbase_decls = decl;	  if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)	      && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)	    {	      warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),				 "destructor `%s' non-virtual");	      warning ("in inheritance relationship `%s: virtual %s'",		       TYPE_NAME_STRING (rec),		       TYPE_NAME_STRING (basetype));	    }	got_it:	  /* The space this decl occupies has already been accounted for.  */	  continue;	}      if (const_size == 0)	offset = integer_zero_node;      else	{	  /* Give each base type the alignment it wants.  */	  const_size = CEIL (const_size, TYPE_ALIGN (basetype))	    * TYPE_ALIGN (basetype);	  offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);#if 0	  /* bpk: Disabled this check until someone is willing to	     claim it as theirs and explain exactly what circumstances	     warrant the warning.  */ 	  if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)	      && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)	    {	      warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),				 "destructor `%s' non-virtual");	      warning ("in inheritance relationship `%s:%s %s'",		       TYPE_NAME_STRING (rec),		       TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",		       TYPE_NAME_STRING (basetype));	    }#endif	}      BINFO_OFFSET (base_binfo) = offset;      if (CLASSTYPE_VSIZE (basetype))	{	  BINFO_VTABLE (base_binfo) = TYPE_BINFO_VTABLE (basetype);	  BINFO_VIRTUALS (base_binfo) = TYPE_BINFO_VIRTUALS (basetype);	}      TREE_CHAIN (base_binfo) = TYPE_BINFO (rec);      TYPE_BINFO (rec) = base_binfo;      /* Add only the amount of storage not present in	 the virtual baseclasses.  */      int_vbase_size = TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype));      if (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) > int_vbase_size)	{	  inc = MAX (record_align,		     (TREE_INT_CST_LOW (TYPE_SIZE (basetype))		      - int_vbase_size));	  /* Record must have at least as much alignment as any field.  */	  desired_align = TYPE_ALIGN (basetype);	  record_align = MAX (record_align, desired_align);	  const_size += inc;	}    }  if (const_size)    CLASSTYPE_SIZE (rec) = size_int (const_size);  else    CLASSTYPE_SIZE (rec) = integer_zero_node;  CLASSTYPE_ALIGN (rec) = record_align;  return vbase_decls;}/* Hashing of lists so that we don't make duplicates.   The entry point is `list_hash_canon'.  *//* Each hash table slot is a bucket containing a chain   of these structures.  */struct list_hash{  struct list_hash *next;	/* Next structure in the bucket.  */  int hashcode;			/* Hash code of this list.  */  tree list;			/* The list recorded here.  */};/* Now here is the hash table.  When recording a list, it is added   to the slot whose index is the hash code mod the table size.   Note that the hash table is used for several kinds of lists.   While all these live in the same table, they are completely independent,   and the hash code is computed differently for each of these.  */#define TYPE_HASH_SIZE 59struct list_hash *list_hash_table[TYPE_HASH_SIZE];/* Compute a hash code for a list (chain of TREE_LIST nodes   with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the   TREE_COMMON slots), by adding the hash codes of the individual entries.  */intlist_hash (list)     tree list;{  register int hashcode = 0;  if (TREE_CHAIN (list))    hashcode += TYPE_HASH (TREE_CHAIN (list));  if (TREE_VALUE (list))    hashcode += TYPE_HASH (TREE_VALUE (list));  else    hashcode += 1007;  if (TREE_PURPOSE (list))    hashcode += TYPE_HASH (TREE_PURPOSE (list));  else    hashcode += 1009;  return hashcode;}/* Look in the type hash table for a type isomorphic to TYPE.   If one is found, return it.  Otherwise return 0.  */treelist_hash_lookup (hashcode, list)     int hashcode;     tree list;{  register struct list_hash *h;  for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)    if (h->hashcode == hashcode	&& TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list)	&& TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list)	&& TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list)	&& TREE_PURPOSE (h->list) == TREE_PURPOSE (list)	&& TREE_VALUE (h->list) == TREE_VALUE (list)	&& TREE_CHAIN (h->list) == TREE_CHAIN (list))      {	my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299);	return h->list;      }  return 0;}/* Add an entry to the list-hash-table   for a list TYPE whose hash code is HASHCODE.  */voidlist_hash_add (hashcode, list)     int hashcode;     tree list;{  register struct list_hash *h;  h = (struct list_hash *) obstack_alloc (&class_obstack, sizeof (struct list_hash));  h->hashcode = hashcode;  h->list = list;  h->next = list_hash_table[hashcode % TYPE_HASH_SIZE];

⌨️ 快捷键说明

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