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

📄 class.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Each base class which needs to have initialization     of some kind gets to make such requests known here.  */  for (i = n_baseclasses-1; i >= 0; i--)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree blist;      /* Don't initialize virtual baseclasses this way.  */      if (TREE_VIA_VIRTUAL (base_binfo))	continue;      if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo)))	{	  /* ...and the last shall come first...  */	  base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);	  base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);	  continue;	}      if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE)	/* Nothing to initialize.  */	continue;      /* ...ditto...  */      base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);      /* This is normally true for single inheritance.	 The win is we can shrink the chain of initializations	 to be done by only converting to the actual type	 we are interested in.  */      if (TREE_VALUE (blist)	  && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC	  && tree_int_cst_equal (BINFO_OFFSET (base_binfo),				 BINFO_OFFSET (TREE_VALUE (blist))))	{	  if (base_init_list)	    {	      /* Does it do more than just fill in a		 virtual function table pointer?  */	      if (! TREE_ADDRESSABLE (blist))		base_init_list = build_tree_list (blist, base_init_list);	      /* Can we get by just with the virtual function table		 pointer that it fills in?  */	      else if (TREE_ADDRESSABLE (base_init_list)		       && TREE_VALUE (base_init_list) == 0)		base_init_list = blist;	      /* Maybe, but it is not obvious as the previous case.  */	      else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type))		{		  tree last = tree_last (base_init_list);		  while (TREE_VALUE (last)			 && TREE_CODE (TREE_VALUE (last)) == TREE_LIST)		    last = tree_last (TREE_VALUE (last));		  if (TREE_VALUE (last) == 0)		    base_init_list = build_tree_list (blist, base_init_list);		}	    }	  else	    base_init_list = blist;	}      else	{	  /* The function expand_aggr_init knows how to do the	     initialization of `basetype' without getting	     an explicit `blist'.  */	  if (base_init_list)	    base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);	  else	    base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo));	}    }  if (base_init_list)    if (member_init_list)      CLASSTYPE_BASE_INIT_LIST (type) = build_tree_list (base_init_list, member_init_list);    else      CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;  else if (member_init_list)    CLASSTYPE_BASE_INIT_LIST (type) = member_init_list;}struct base_info{  int has_virtual;  int max_has_virtual;  int n_ancestors;  tree vfield;  tree vfields;  char cant_have_default_ctor;  char cant_have_const_ctor;  char cant_synth_copy_ctor;  char cant_synth_asn_ref;  char no_const_asn_ref;  char needs_virtual_dtor;};/* Record information about type T derived from its base classes.   Store most of that information in T itself, and place the   remaining information in the struct BASE_INFO.   Propagate basetype offsets throughout the lattice.  Note that the   lattice topped by T is really a pair: it's a DAG that gives the   structure of the derivation hierarchy, and it's a list of the   virtual baseclasses that appear anywhere in the DAG.  When a vbase   type appears in the DAG, it's offset is 0, and it's children start   their offsets from that point.  When a vbase type appears in the list,   its offset is the offset it has in the hierarchy, and its children's   offsets include that offset in theirs.   Returns the index of the first base class to have virtual functions,   or -1 if no such base class.   Note that at this point TYPE_BINFO (t) != t_binfo.  */static intfinish_base_struct (t, b, t_binfo)     tree t;     struct base_info *b;     tree t_binfo;{  tree binfos = BINFO_BASETYPES (t_binfo);  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;  int first_vfn_base_index = -1;  bzero ((char *) b, sizeof (struct base_info));  for (i = 0; i < n_baseclasses; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree basetype = BINFO_TYPE (base_binfo);      /* If the type of basetype is incomplete, then	 we already complained about that fact	 (and we should have fixed it up as well).  */      if (TYPE_SIZE (basetype) == 0)	{	  int j;	  /* The base type is of incomplete type.  It is	     probably best to pretend that it does not	     exist.  */	  if (i == n_baseclasses-1)	    TREE_VEC_ELT (binfos, i) = NULL_TREE;	  TREE_VEC_LENGTH (binfos) -= 1;	  n_baseclasses -= 1;	  for (j = i; j+1 < n_baseclasses; j++)	    TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);	}      if (TYPE_HAS_INIT_REF (basetype)	  && !TYPE_HAS_CONST_INIT_REF (basetype))	b->cant_have_const_ctor = 1;      if (! TYPE_HAS_INIT_REF (basetype)	  || (TYPE_HAS_NONPUBLIC_CTOR (basetype) == 2	      && ! is_friend_type (t, basetype)))	b->cant_synth_copy_ctor = 1;      if (TYPE_HAS_CONSTRUCTOR (basetype)	  && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))	{	  b->cant_have_default_ctor = 1;	  if (! TYPE_HAS_CONSTRUCTOR (t))	    {	      cp_pedwarn ("base `%T' with only non-default constructor",			  basetype);	      cp_pedwarn ("in class without a constructor");	    }	}      if (TYPE_HAS_ASSIGN_REF (basetype)	  && !TYPE_HAS_CONST_ASSIGN_REF (basetype))	b->no_const_asn_ref = 1;      if (! TYPE_HAS_ASSIGN_REF (basetype)	  || TYPE_HAS_ABSTRACT_ASSIGN_REF (basetype)	  || (TYPE_HAS_NONPUBLIC_ASSIGN_REF (basetype) == 2	      && ! is_friend_type (t, basetype)))	b->cant_synth_asn_ref = 1;      b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);      TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);      TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);      TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);      TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);      TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);      TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);      TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);      if (! TREE_VIA_VIRTUAL (base_binfo)#if 0	  /* This cannot be done, as prepare_fresh_vtable wants to modify	     binfos associated with vfields anywhere in the hierarchy, not	     just immediate base classes.  Due to unsharing, the compiler	     might consume 3% more memory on a real program.	     */	  && ! BINFO_OFFSET_ZEROP (base_binfo)#endif	  && BINFO_BASETYPES (base_binfo))	{	  tree base_binfos = BINFO_BASETYPES (base_binfo);	  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) = base_binfo;	    }	  /* Completely unshare potentially shared data, and	     update what is ours.  */	  propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));	}      if (! TREE_VIA_VIRTUAL (base_binfo))	CLASSTYPE_N_SUPERCLASSES (t) += 1;      if (TYPE_VIRTUAL_P (basetype))	{	  /* If there's going to be a destructor needed, make	     sure it will be virtual.  */	  b->needs_virtual_dtor = 1;	  /* Don't borrow virtuals from virtual baseclasses.  */	  if (TREE_VIA_VIRTUAL (base_binfo))	    continue;	  if (first_vfn_base_index < 0)	    {	      tree vfields;	      first_vfn_base_index = i;	      /* Update these two, now that we know what vtable we are		 going to extend.  This is so that we can add virtual		 functions, and override them properly.  */	      BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);	      BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);	      b->has_virtual = CLASSTYPE_VSIZE (basetype);	      b->vfield = CLASSTYPE_VFIELD (basetype);	      b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype));	      vfields = b->vfields;	      while (vfields)		{		  if (VF_BINFO_VALUE (vfields) == NULL_TREE		      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))		    {		      tree value = VF_BASETYPE_VALUE (vfields);		      if (DECL_NAME (CLASSTYPE_VFIELD (value))			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))			VF_NORMAL_VALUE (b->vfields) = basetype;		      else			VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);		    }		  vfields = TREE_CHAIN (vfields);		}	      CLASSTYPE_VFIELD (t) = b->vfield;	    }	  else	    {	      /* Only add unique vfields, and flatten them out as we go.  */	      tree vfields = CLASSTYPE_VFIELDS (basetype);	      while (vfields)		{		  if (VF_BINFO_VALUE (vfields) == NULL_TREE		      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))		    {		      tree value = VF_BASETYPE_VALUE (vfields);		      b->vfields = tree_cons (base_binfo, value, b->vfields);		      if (DECL_NAME (CLASSTYPE_VFIELD (value))			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))			VF_NORMAL_VALUE (b->vfields) = basetype;		      else			VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);		    }		  vfields = TREE_CHAIN (vfields);		}	      if (b->has_virtual == 0)		{		  first_vfn_base_index = i;		  /* Update these two, now that we know what vtable we are		     going to extend.  This is so that we can add virtual		     functions, and override them properly.  */		  BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);		  BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);		  b->has_virtual = CLASSTYPE_VSIZE (basetype);		  b->vfield = CLASSTYPE_VFIELD (basetype);		  CLASSTYPE_VFIELD (t) = b->vfield;		  /* When we install the first one, set the VF_NORMAL_VALUE		     to be the current class, as this it is the most derived		     class.  Hopefully, this is not set to something else		     later.  (mrs) */		  vfields = b->vfields;		  while (vfields)		    {		      if (DECL_NAME (CLASSTYPE_VFIELD (t))			  == DECL_NAME (CLASSTYPE_VFIELD (basetype)))			{			  VF_NORMAL_VALUE (vfields) = t;			  /* There should only be one of them!  And it should			     always be found, if we get into here.  (mrs)  */			  break;			}		      vfields = TREE_CHAIN (vfields);		    }		}	    }	}    }  /* Must come after offsets are fixed for all bases.  */  for (i = 0; i < n_baseclasses; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree basetype = BINFO_TYPE (base_binfo);      if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)	{	  cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",		      basetype, t);	  b->cant_synth_asn_ref = 1;	  b->cant_synth_copy_ctor = 1;	}    }  {    tree v = get_vbase_types (t_binfo);    for (; v; v = TREE_CHAIN (v))      {	tree basetype = BINFO_TYPE (v);	if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)	  {	    if (extra_warnings)	      cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",			  basetype, t);	    b->cant_synth_asn_ref = 1;	    b->cant_synth_copy_ctor = 1;	  }      }  }      {    tree vfields;    /* Find the base class with the largest number of virtual functions.  */    for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields))      {	if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual)	  b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields));	if (VF_DERIVED_VALUE (vfields)	    && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual)	  b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields));      }  }  if (b->vfield == 0)    /* If all virtual functions come only from virtual baseclasses.  */    return -1;  return first_vfn_base_index;}static inttypecode_p (type, code)     tree type;     enum tree_code code;{  return (TREE_CODE (type) == code	  || (TREE_CODE (type) == REFERENCE_TYPE	      && TREE_CODE (TREE_TYPE (type)) == code));}/* Set memoizing fields and bits of T (and its variants) for later use.   MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables.  */static voidfinish_struct_bits (t, max_has_virtual)     tree t;     int max_has_virtual;{  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);  tree method_vec = CLASSTYPE_METHOD_VEC (t);  /* Fix up variants (if any).  */  tree variants = TYPE_NEXT_VARIANT (t);  while (variants)    {      /* These fields are in the _TYPE part of the node, not in	 the TYPE_LANG_SPECIFIC component, so they are not shared.  */      TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);      TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t);      TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);      TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t);      TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t);      TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t);      TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);      /* Copy whatever these are holding today.  */      TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);      TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);      variants = TYPE_NEXT_VARIANT (variants);    }  if (n_baseclasses && max_has_virtual)    {      /* Done by `finish_struct' for classes without baseclasses.  */      int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;      tree binfos = TYPE_BINFO_BASETYPES (t);      for (i = n_baseclasses-1; i >= 0; i--)	{	  might_have_abstract_virtuals	    |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0);

⌨️ 快捷键说明

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