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

📄 class.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		      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);	}    }  {    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);	  }      }  }      {    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;}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);  /* 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);      TYPE_FIELDS (variants) = TYPE_FIELDS (t);      TYPE_SIZE (variants) = TYPE_SIZE (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);	  if (might_have_abstract_virtuals)	    break;	}      if (might_have_abstract_virtuals)	{	  /* We use error_mark_node from override_one_vtable to signal	     an artificial abstract.  */	  if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node)	    CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE;	  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));	  if (TYPE_HAS_CONVERSION (basetype))	    {	      TYPE_HAS_CONVERSION (t) = 1;	      TYPE_HAS_INT_CONVERSION (t) |= TYPE_HAS_INT_CONVERSION (basetype);	      TYPE_HAS_REAL_CONVERSION (t) |= TYPE_HAS_REAL_CONVERSION (basetype);	    }	  if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t))	    CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1;	}    }  /* 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;	}    }}/* Add FNDECL to the method_vec growing on the class_obstack.  Used by   finish_struct_methods.  Note, FNDECL cannot be a constructor or   destructor, those cases are handled by the caller.  */static voidgrow_method (fndecl, method_vec_ptr)     tree fndecl;     tree *method_vec_ptr;{  tree method_vec = (tree)obstack_base (&class_obstack);  /* Start off past the constructors and destructor.  */  tree *testp = &TREE_VEC_ELT (method_vec, 2);  while (testp < (tree *) obstack_next_free (&class_obstack)	 && (*testp == NULL_TREE || DECL_NAME (*testp) != DECL_NAME (fndecl)))    testp++;  if (testp < (tree *) obstack_next_free (&class_obstack))    {      tree *p;      for (p = testp; *p; )	p = &DECL_CHAIN (*p);      *p = fndecl;    }  else    {      obstack_ptr_grow (&class_obstack, fndecl);      *method_vec_ptr = (tree)obstack_base (&class_obstack);    }}/* Warn about duplicate methods in fn_fields.  Also compact method   lists so that lookup can be made faster.   Algorithm: Outer loop builds lists by method name.  Inner loop   checks for redundant method names within a list.   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.  */treefinish_struct_methods (t, fn_fields, nonprivate_method)     tree t;     tree fn_fields;     int nonprivate_method;{  tree method_vec;  tree save_fn_fields = fn_fields;  tree ctor_name = constructor_name (t);  int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);  /* Now prepare to gather fn_fields into vector.  */  struct obstack *ambient_obstack = current_obstack;  current_obstack = &class_obstack;  method_vec = make_tree_vec (2);  current_obstack = ambient_obstack;  /* Now make this a live vector.  */  obstack_free (&class_obstack, method_vec);  /* Save room for constructors and destructors.  */  obstack_blank (&class_obstack, sizeof (struct tree_vec) + sizeof (struct tree *));  /* 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; 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 that a copy ctor is private, so we don't dare generate 	 a default copy constructor for a class that has a member 	 of this type without making sure they have access to it.  */      if (fn_name == ctor_name) 	{ 	  tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields); 	  tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;	   	  if (TREE_CODE (parmtype) == REFERENCE_TYPE 	      && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t) 	    { 	      if (TREE_CHAIN (parmtypes) == NULL_TREE 		  || TREE_CHAIN (parmtypes) == void_list_node 		  || TREE_PURPOSE (TREE_CHAIN (parmtypes))) 		{ 		  if (TREE_PROTECTED (fn_fields)) 		    TYPE_HAS_NONPUBLIC_CTOR (t) = 1; 		  else if (TREE_PRIVATE (fn_fields)) 		    TYPE_HAS_NONPUBLIC_CTOR (t) = 2; 		} 	    }	  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))	    {	    	      /* Destructors go in slot 1.  */	      DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 1);	      TREE_VEC_ELT (method_vec, 1) = fn_fields;	    }	  else	    {	      /* Constructors go in slot 0.  */	      DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);	      TREE_VEC_ELT (method_vec, 0) = fn_fields;	    } 	}      else if (IDENTIFIER_TYPENAME_P (fn_name))	{	  tree return_type = TREE_TYPE (TREE_TYPE (fn_fields));	  if (typecode_p (return_type, INTEGER_TYPE)	      || typecode_p (return_type, BOOLEAN_TYPE)	      || typecode_p (return_type, ENUMERAL_TYPE))	    TYPE_HAS_INT_CONVERSION (t) = 1;	  else if (typecode_p (return_type, REAL_TYPE))	    TYPE_HAS_REAL_CONVERSION (t) = 1;	  grow_method (fn_fields, &method_vec);	}    }  fn_fields = save_fn_fields;  for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))    {      tree fn_name = DECL_NAME (fn_fields);      if (fn_name == ctor_name || IDENTIFIER_TYPENAME_P (fn_name))	continue;      if (fn_name == ansi_opname[(int) MODIFY_EXPR])	{	  tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));	  if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))	    {	      if (TREE_PROTECTED (fn_fields))		TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;	      else if (TREE_PRIVATE (fn_fields))		TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2;	    }	}      grow_method (fn_fields, &method_vec);    }  TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack)    - (&TREE_VEC_ELT (method_vec, 0));  obstack_finish (&class_obstack);  CLASSTYPE_METHOD_VEC (t) = method_vec;  if (nonprivate_method == 0      && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE      && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)    {      tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));      for (i = 0; i < n_baseclasses; i++)	if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))	    || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))	  {	    nonprivate_method = 1;	    break;	  }      if (nonprivate_method == 0 	  && warn_ctor_dtor_privacy)	cp_warning ("all member functions in class `%T' are private", t);    }  /* Warn if all destructors are private (in which case this class is     effectively unusable.  */  if (TYPE_HAS_DESTRUCTOR (t))    {      tree dtor = TREE_VEC_ELT (method_vec, 1);      /* Wild parse errors can cause this to happen.  */      if (dtor == NULL_TREE)	TYPE_HAS_DESTRUCTOR (t) = 0;      else if (TREE_PRIVATE (dtor)	       && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE	       && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE	       && warn_ctor_dtor_privacy)	cp_warning ("`%#T' only defines a private destructor and has no friends",		    t);    }  /* Now for each member function (except for constructors and     destructors), compute where member functions of the same     name reside in base classes.  */  if (n_baseclasses != 0      && TREE_VEC_LENGTH (method_ve

⌨️ 快捷键说明

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