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

📄 class.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			   || TREE_CODE (x) == TYPE_DECL)		    {		      /* Hide tag decls.  */		      if ((TREE_CODE (field) == TYPE_DECL			   && DECL_ARTIFICIAL (field))			  || (TREE_CODE (x) == TYPE_DECL			      && DECL_ARTIFICIAL (x)))			continue;		      cp_error_at ("duplicate field `%D' (as type and non-type)",				   x);		    }		  else		    cp_error_at ("duplicate member `%D'", x);		  if (prev == 0)		    fields = TREE_CHAIN (fields);		  else		    TREE_CHAIN (prev) = TREE_CHAIN (x);		}	    }	}    }  return fields;}static voiddelete_duplicate_fields (fields)     tree fields;{  tree x;  for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))    TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));}/* Change the access of FDECL to ACCESS in T.   Return 1 if change was legit, otherwise return 0.  */static intalter_access (t, fdecl, access)     tree t;     tree fdecl;     tree access;{  tree elem = purpose_member (t, DECL_ACCESS (fdecl));  if (elem && TREE_VALUE (elem) != access)    {      if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)	{	  cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));	}      else	error ("conflicting access specifications for field `%s', ignored",	       IDENTIFIER_POINTER (DECL_NAME (fdecl)));    }  else if (TREE_PRIVATE (fdecl))    {      if (access != access_private_node)	cp_error_at ("cannot make private `%D' non-private", fdecl);      goto alter;    }  else if (TREE_PROTECTED (fdecl))    {      if (access != access_protected_node)	cp_error_at ("cannot make protected `%D' non-protected", fdecl);      goto alter;    }  /* ARM 11.3: an access declaration may not be used to restrict access     to a member that is accessible in the base class.  */  else if (access != access_public_node)    cp_error_at ("cannot reduce access of public member `%D'", fdecl);  else if (elem == NULL_TREE)    {    alter:      DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));      return 1;    }  return 0;}/* 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 basetype = VF_NORMAL_VALUE (vfields)	? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields))	  : VF_BASETYPE_VALUE (vfields);      tree base_binfo = get_binfo (basetype, for_type, 0);      /* Punt until this is implemented.  */      if (1 /* BINFO_MODIFIED (base_binfo) */)	{	  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;  tree rtti;  char cant_have_default_ctor;  char cant_have_const_ctor;  char no_const_asn_ref;};/* 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_CONST_INIT_REF (basetype))	b->cant_have_const_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;      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)	  && 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))	{	  /* Ensure that this is set from at least a virtual base             class.  */	  if (b->rtti == NULL_TREE)	    b->rtti = CLASSTYPE_RTTI (basetype);	  /* 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)))		    {

⌨️ 快捷键说明

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