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

📄 cp-class.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
alter_visibility (t, fdecl, visibility)     tree t;     tree fdecl;     enum visibility_type visibility;{  tree elem = purpose_member (t, DECL_VISIBILITY (fdecl));  if (elem && TREE_VALUE (elem) != (tree)visibility)    {      if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)	{	  error_with_decl (TREE_TYPE (fdecl), "conflicting visibility specifications for method `%s', ignored");	}      else error ("conflicting visibility specifications for field `%s', ignored", IDENTIFIER_POINTER (DECL_NAME (fdecl)));    }  else if (TREE_PRIVATE (fdecl) && visibility != visibility_private)    error_with_decl (fdecl, "cannot make private %s non-private");  else if (TREE_PROTECTED (fdecl) && visibility == visibility_public)		        error_with_decl (fdecl, "cannot make protected %s public");  else if (elem == NULL_TREE)    {      DECL_VISIBILITY (fdecl) = tree_cons (t, (tree)visibility,					   DECL_VISIBILITY (fdecl));      return 1;    }  return 0;}static treeget_vfield_offset (binfo)     tree binfo;{  return size_binop (PLUS_EXPR,		     DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),		     BINFO_OFFSET (binfo));}/* If FOR_TYPE needs to reinitialize virtual function table pointers   for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.   Returns BASE_INIT_LIST appropriately modified.  */static treemaybe_fixup_vptrs (for_type, binfo, base_init_list)     tree for_type, binfo, base_init_list;{  /* Now reinitialize any slots that don't fall under our virtual     function table pointer.  */  tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo));  while (vfields)    {      tree base_binfo = get_binfo (VF_BASETYPE_VALUE (vfields), for_type, 0);      if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (VF_BASETYPE_VALUE (vfields)))	{	  tree base_offset = get_vfield_offset (base_binfo);	  if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type)))	      && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo)))	    base_init_list = tree_cons (error_mark_node, base_binfo,					base_init_list);	}      vfields = TREE_CHAIN (vfields);    }  return base_init_list;}/* If TYPE does not have a constructor, then the compiler must   manually deal with all of the initialization this type requires.   If a base initializer exists only to fill in the virtual function   table pointer, then we mark that fact with the TREE_VIRTUAL bit.   This way, we avoid multiple initializations of the same field by   each virtual function table up the class hierarchy.   Virtual base class pointers are not initialized here.  They are   initialized only at the "top level" of object creation.  If we   initialized them here, we would have to skip a lot of work.  */static voidbuild_class_init_list (type)     tree type;{  tree base_init_list = NULL_TREE;  tree member_init_list = NULL_TREE;  /* Since we build member_init_list and base_init_list using     tree_cons, backwards fields the all through work.  */  tree x;  tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;  for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x))    {      if (TREE_CODE (x) != FIELD_DECL)	continue;      if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x))	  || DECL_INITIAL (x) != NULL_TREE)	member_init_list = tree_cons (x, type, member_init_list);    }  member_init_list = nreverse (member_init_list);  /* We will end up doing this last.  Need special marker     to avoid infinite regress.  */  if (TYPE_VIRTUAL_P (type))    {      base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type));      if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0)	TREE_VALUE (base_init_list) = NULL_TREE;      TREE_ADDRESSABLE (base_init_list) = 1;    }  /* 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 needs_default_ctor;  char cant_have_default_ctor;  char needs_const_ctor;  char cant_have_const_ctor;  char members_need_dtors;  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 zero if no such base class.  */static intfinish_base_struct (t, b, binfos)     tree t;     struct base_info *b;     tree binfos;{  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;  int first_vfn_base_index = -1;  bzero (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_NEEDS_DESTRUCTOR (basetype))	b->members_need_dtors = 1;      if (TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))	b->needs_default_ctor = 1;      else if (TYPE_HAS_CONSTRUCTOR (basetype))	b->cant_have_default_ctor = 1;      if (TYPE_GETS_CONST_INIT_REF (basetype))	b->needs_const_ctor = 1;      else if (TYPE_GETS_INIT_REF (basetype))	b->cant_have_const_ctor = 1;      CLASSTYPE_ALTERS_VISIBILITIES_P (t)	|= CLASSTYPE_ALTERS_VISIBILITIES_P (basetype);      b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);      TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);      TYPE_NEEDS_CONSTRUCTOR (t) |= TYPE_NEEDS_CONSTRUCTOR (basetype);      TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);      TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (basetype);      TYPE_GETS_INIT_REF (t) |= TYPE_GETS_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)	  && ! BINFO_OFFSET_ZEROP (base_binfo)	  && 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),				BINFO_TYPE (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);	    }	  /* 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)	    {	      first_vfn_base_index = i;	      b->has_virtual = CLASSTYPE_VSIZE (basetype);	      b->vfield = CLASSTYPE_VFIELD (basetype);	      b->vfields = CLASSTYPE_VFIELDS (basetype);	      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;		  b->has_virtual = CLASSTYPE_VSIZE (basetype);		  b->vfield = CLASSTYPE_VFIELD (basetype);		  CLASSTYPE_VFIELD (t) = b->vfield;		}	    }	}    }  {    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));}extern tree constructor_name ();/* 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);

⌨️ 快捷键说明

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