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

📄 class.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
      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 (CLASSTYPE_COM_INTERFACE (basetype))	{	  CLASSTYPE_COM_INTERFACE (t) = 1;	  if (i > 0)	    cp_error	      ("COM interface type `%T' must be the leftmost base class",	       basetype);	}      else if (CLASSTYPE_COM_INTERFACE (t))	{	  cp_error ("COM interface type `%T' with non-COM base class `%T'",		    t, basetype);	  CLASSTYPE_COM_INTERFACE (t) = 0;	}      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.  */	      TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);	      TYPE_BINFO_VIRTUALS (t) = 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.  */		  TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);		  TYPE_BINFO_VIRTUALS (t) = 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);		    }		}	    }	}    }  {    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;  /* Update the rtti base if we have a non-virtual base class version     of it.  */  b->rtti = CLASSTYPE_RTTI (BINFO_TYPE (TREE_VEC_ELT (binfos, first_vfn_base_index)));  return first_vfn_base_index;}/* 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);  /* 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);      TYPE_USES_PVBASES (variants) = TYPE_USES_PVBASES (t);      /* Copy whatever these are holding today.  */      TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);      TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);      TYPE_FIELDS (variants) = TYPE_FIELDS (t);      TYPE_SIZE (variants) = TYPE_SIZE (t);      TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);      variants = TYPE_NEXT_VARIANT (variants);    }  if (n_baseclasses && max_has_virtual)    {      /* For a class w/o baseclasses, `finish_struct' has set         CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly         for a class who's base classes do not have vtables. When neither         of these is true, we might have removed abstract virtuals (by         providing a definition), added some (by declaring new ones), or         redeclared ones from a base class. We need to recalculate what's         really an abstract virtual at this point (by looking in the         vtables).  */      CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);    }  if (n_baseclasses)    {      /* Notice whether this class has type conversion functions defined.  */      tree binfo = TYPE_BINFO (t);      tree binfos = BINFO_BASETYPES (binfo);      tree basetype;      for (i = n_baseclasses-1; i >= 0; i--)	{	  basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));	  TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype);	}    }  /* If this type has a copy constructor, force its mode to be BLKmode, and     force its TREE_ADDRESSABLE bit to be nonzero.  This will cause it to     be passed by invisible reference and prevent it from being returned in     a register.     Also do this if the class has BLKmode but can still be returned in     registers, since function_cannot_inline_p won't let us inline     functions returning such a type.  This affects the HP-PA.  */  if (! TYPE_HAS_TRIVIAL_INIT_REF (t)      || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)	  && CLASSTYPE_NON_AGGREGATE (t)))    {      tree variants;      DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))	{	  TYPE_MODE (variants) = BLKmode;	  TREE_ADDRESSABLE (variants) = 1;	}    }}/* Issue warnings about T having private constructors, but no friends,   and so forth.     HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or   static members.  HAS_NONPRIVATE_STATIC_FN is nonzero if T has any   non-private static member functions.  */static voidmaybe_warn_about_overly_private_class (t)     tree t;{  int has_member_fn = 0;  int has_nonprivate_method = 0;  tree fn;  if (!warn_ctor_dtor_privacy      /* If the class has friends, those entities might create and	 access instances, so we should not warn.  */      || (CLASSTYPE_FRIEND_CLASSES (t)	  || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))      /* We will have warned when the template was declared; there's	 no need to warn on every instantiation.  */      || CLASSTYPE_TEMPLATE_INSTANTIATION (t))    /* There's no reason to even consider warning about this        class.  */    return;      /* We only issue one warning, if more than one applies, because     otherwise, on code like:     class A {       // Oops - forgot `public:'       A();       A(const A&);       ~A();     };     we warn several times about essentially the same problem.  */  /* Check to see if all (non-constructor, non-destructor) member     functions are private.  (Since there are no friends or     non-private statics, we can't ever call any of the private member     functions.)  */  for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))    /* We're not interested in compiler-generated methods; they don't       provide any way to call private members.  */    if (!DECL_ARTIFICIAL (fn))       {	if (!TREE_PRIVATE (fn))	  {	    if (DECL_STATIC_FUNCTION_P (fn)) 	      /* A non-private static member function is just like a		 friend; it can create and invoke private member		 functions, and be accessed without a class		 instance.  */	      return;			    has_nonprivate_method = 1;	    break;	  }	else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))	  has_member_fn = 1;      }   if (!has_nonprivate_method && has_member_fn)     {      /* There are no non-private methods, and there's at least one	 private member function that isn't a constructor or	 destructor.  (If all the private members are	 constructors/destructors we want to use the code below that	 issues error messages specifically referring to	 constructors/destructors.)  */      int i;      tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));      for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)	if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))	    || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))	  {	    has_nonprivate_method = 1;	    break;	  }      if (!has_nonprivate_method) 	{	  cp_warning ("all member functions in class `%T' are private", t);	  return;	}    }  /* Even if some of the member functions are non-private, the class     won't be useful for much if all the constructors or destructors     are private: such an object can never be created or destroyed.  */  if (TYPE_HAS_DESTRUCTOR (t))    {      tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);      if (TREE_PRIVATE (dtor))	{	  cp_warning ("`%#T' only defines a private destructor and has no friends",		      t);	  return;	}    }  if (TYPE_HAS_CONSTRUCTOR (t))    {      int nonprivate_ctor = 0;	        /* If a non-template class does not define a copy	 constructor, one is defined for it, enabling it to avoid	 this warning.  For a template class, this does not	 happen, and so we would normally get a warning on:	   template <class T> class C { private: C(); };  	  	 To avoid this asymmetry, we check TYPE_HAS_INIT_REF.  All	 complete non-template or fully instantiated classes have this	 flag set.  */      if (!TYPE_HAS_INIT_REF (t))	nonprivate_ctor = 1;      else 	for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);	     fn;	     fn = OVL_NEXT (fn)) 	  {	    tree ctor = OVL_CURRENT (fn);	    /* Ideally, we wouldn't count copy constructors (or, in	       fact, any constructor that takes an argument of the	       class type as a parameter) because such things cannot	       be used to construct an instance of the class unless	       you already have one.  But, for now at least, we're	       more generous.  */	    if (! TREE_PRIVATE (ctor))	      {		nonprivate_ctor = 1;		break;	      }	  }      if (nonprivate_ctor == 0)	{	  cp_warning ("`%#T' only defines private constructors and has no friends",		      t);	  return;	}    }}/* Warn about duplicate methods in fn_fields.  Also compact method   lists so that lookup can be made faster.   Data Structure: List of method lists.  The outer list is a   TREE_LIST, whose TREE_PURPOSE field is the field name and the   TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs.  TREE_CHAIN   links the entire list of methods for TYPE_METHODS.  Friends are   chained in the same way as member functions (? TREE_CHAIN or   DECL_CHAIN), but they live in the TREE_TYPE field of the outer   list.  That allows them to be quickly deleted, and requires no   extra storage.   If there are any constructors/destructors, they are moved to the   front of the list.  This makes pushclass more efficient.   We also link each field which has shares a name with its baseclass   to the head of the list of fields for that base class.  This allows   us to reduce search time in places like `build_method_call' to   consider only reasonably likely functions.   */static voidfinish_struct_methods (t)     tree t;{  tree fn_fields;  tree method_vec = CLASSTYPE_METHOD_VEC (t);  tree ctor_name = constructor_name (t);  /* First fill in entry 0 with the constructors, entry 1 with destructors,     and the next few with type conversion operators (if any).  */  for (fn_fields = TYPE_METHODS (t); fn_fields;        fn_fields = TREE_CHAIN (fn_fields))    {      tree fn_name = DECL_NAME (fn_fields);      /* Clear out this flag.	 @@ Doug may figure out how to break	 @@ this with nested classes and friends.  */      DECL_IN_AGGR_P (fn_fields) = 0;      /* Note here th

⌨️ 快捷键说明

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