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

📄 class.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
	  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.  */  if (! TYPE_HAS_TRIVIAL_INIT_REF (t))    {      tree variants;      if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)	DECL_MODE (TYPE_NAME (t)) = BLKmode;      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))	{	  TYPE_MODE (variants) = BLKmode;	  TREE_ADDRESSABLE (variants) = 1;	}    }}/* Add FN to the method_vec growing on the class_obstack.  Used by   finish_struct_methods.  */static voidgrow_method (fn, method_vec_ptr)     tree fn;     tree *method_vec_ptr;{  tree method_vec = (tree)obstack_base (&class_obstack);  tree *testp = &TREE_VEC_ELT (method_vec, 0);  if (*testp == NULL_TREE)    testp++;  while (((HOST_WIDE_INT) testp	  < (HOST_WIDE_INT) obstack_next_free (&class_obstack))	 && DECL_NAME (*testp) != DECL_NAME (fn))    testp++;  if ((HOST_WIDE_INT) testp      < (HOST_WIDE_INT) obstack_next_free (&class_obstack))    {      tree x, prev_x;      for (x = *testp; x; x = DECL_CHAIN (x))	{	  if (DECL_NAME (fn) == ansi_opname[(int) DELETE_EXPR]	      || DECL_NAME (fn) == ansi_opname[(int) VEC_DELETE_EXPR])	    {	      /* ANSI C++ June 5 1992 WP 12.5.5.1 */	      cp_error_at ("`%D' overloaded", fn);	      cp_error_at ("previous declaration as `%D' here", x);	    }	  if (DECL_ASSEMBLER_NAME (fn)==DECL_ASSEMBLER_NAME (x))	    {	      /* We complain about multiple destructors on sight,		 so we do not repeat the warning here.  Friend-friend		 ambiguities are warned about outside this loop.  */	      if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn)))		cp_error_at ("ambiguous method `%#D' in structure", fn);	      break;	    }	  prev_x = x;	}      if (x == 0)	{	  if (*testp)	    DECL_CHAIN (prev_x) = fn;	  else	    *testp = fn;	}    }  else    {      obstack_ptr_grow (&class_obstack, fn);      *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.  */static treefinish_struct_methods (t, fn_fields, nonprivate_method)     tree t;     tree fn_fields;     int nonprivate_method;{  tree method_vec;  tree save_fn_fields = tree_cons (NULL_TREE, NULL_TREE, fn_fields);  tree lastp;  tree 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_node (TREE_VEC);  /* Room has been saved for constructors and destructors.  */  current_obstack = ambient_obstack;  /* Now make this a live vector.  */  obstack_free (&class_obstack, method_vec);  obstack_blank (&class_obstack, sizeof (struct tree_vec));  /* First fill in entry 0 with the constructors, and the next few with     type conversion operators (if any).  */  for (lastp = save_fn_fields; fn_fields; fn_fields = TREE_CHAIN (lastp))    {      tree fn_name = DECL_NAME (fn_fields);      if (fn_name == NULL_TREE)	fn_name = name;      /* 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 == 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; 		} 	    }	  /* Constructors are handled easily in search routines.  */	  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);	}      else	{	  lastp = fn_fields;	  continue;	}      TREE_CHAIN (lastp) = TREE_CHAIN (fn_fields);      TREE_CHAIN (fn_fields) = NULL_TREE;    }  fn_fields = TREE_CHAIN (save_fn_fields);  while (fn_fields)    {      tree nextp;      tree fn_name = DECL_NAME (fn_fields);      if (fn_name == NULL_TREE)	fn_name = name;      nextp = TREE_CHAIN (fn_fields);      TREE_CHAIN (fn_fields) = NULL_TREE;      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);      fn_fields = nextp;    }  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_NAME (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)	cp_warning ("all member functions in class `%T' are private", t);    }  /* If there are constructors (and destructors), they are at the     front.  Place destructors at very front.  Also warn if all     constructors and/or destructors are private (in which case this     class is effectively unusable.  */  if (TYPE_HAS_DESTRUCTOR (t))    {      tree dtor, prev;      for (dtor = TREE_VEC_ELT (method_vec, 0);	   dtor;	   prev = dtor, dtor = DECL_CHAIN (dtor))	{	  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor)))	    {	      if (TREE_PRIVATE (dtor)		  && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE		  && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE		  && warn_ctor_dtor_privacy)		cp_warning ("`%#T' only defines a private destructor and has no friends",			    t);	      break;	    }	}      /* Wild parse errors can cause this to happen.  */      if (dtor == NULL_TREE)	TYPE_HAS_DESTRUCTOR (t) = 0;      else if (dtor != TREE_VEC_ELT (method_vec, 0))	{	  DECL_CHAIN (prev) = DECL_CHAIN (dtor);	  DECL_CHAIN (dtor) = TREE_VEC_ELT (method_vec, 0);	  TREE_VEC_ELT (method_vec, 0) = dtor;	}    }  /* 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_vec) > 1)    {      int len = TREE_VEC_LENGTH (method_vec);      tree baselink_vec = make_tree_vec (len);      int any_links = 0;      tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t));      for (i = 1; i < len; i++)	{	  TREE_VEC_ELT (baselink_vec, i)	    = get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i)));	  if (TREE_VEC_ELT (baselink_vec, i) != 0)	    any_links = 1;	}      if (any_links != 0)	CLASSTYPE_BASELINK_VEC (t) = baselink_vec;      else	obstack_free (current_obstack, baselink_vec);    }  /* Now add the methods to the TYPE_METHODS of T, arranged in a chain.  */  {    tree x, last_x = NULL_TREE;    int limit = TREE_VEC_LENGTH (method_vec);    for (i = 1; i < limit; i++)      {	for (x = TREE_VEC_ELT (method_vec, i); x; x = DECL_CHAIN (x))	  {	    if (last_x != NULL_TREE)	      TREE_CHAIN (last_x) = x;	    last_x = x;	  }      }    /* Put ctors and dtors at the front of the list.  */    x = TREE_VEC_ELT (method_vec, 0);    if (x)      {	while (DECL_CHAIN (x))	  {	    /* Let's avoid being circular about this.  */	    if (x == DECL_CHAIN (x))	      break;	    TREE_CHAIN (x) = DECL_CHAIN (x);	    x = DECL_CHAIN (x);	  }	if (TREE_VEC_LENGTH (method_vec) > 1)	  TREE_CHAIN (x) = TREE_VEC_ELT (method_vec, 1);	else	  TREE_CHAIN (x) = NULL_TREE;      }  }  TYPE_METHODS (t) = method_vec;  return method_vec;}/* Emit error when a duplicate definition of a type is seen.  Patch up. */voidduplicate_tag_error (t)     tree t;{  cp_error ("redefinition of `%#T'", t);  cp_error_at ("previous definition here", t);  /* Pretend we haven't defined this type.  */  /* All of the component_decl's were TREE_CHAINed together in the parser.     finish_struct_methods walks these chains and assembles all methods with     the same base name into DECL_CHAINs. Now we don't need the parser chains     anymore, so we unravel them.   */  /*   * This used to be in finish_struct, but it turns out that the   * TREE_CHAIN is used by dbxout_type_methods and perhaps some other things...   */  if (CLASSTYPE_METHOD_VEC(t))     {      tree tv = CLASSTYPE_METHOD_VEC(t);      int i, len  = TREE_VEC_LENGTH (tv);      for (i = 0; i < len; i++)	{	  tree unchain = TREE_VEC_ELT (tv, i);	  while (unchain != NULL_TREE) 	    {	      TREE_CHAIN (unchain) = NULL_TREE;	      unchain = DECL_CHAIN(unchain);	    }	}    }  if (TYPE_LANG_SPECIFIC (t))    {      tree as_list = CLASSTYPE_AS_LIST (t);      tree binfo = TYPE_BINFO (t);      tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t);      int interface_only = CLASSTYPE_INTERFACE_ONLY (t);      int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);      bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type));      BINFO_BASETYPES(binfo) = NULL_TREE;      CLASSTYPE_AS_LIST (t) = as_list;      TYPE_BINFO (t) = binfo;      CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list;      CLASSTYPE_INTERFACE_ONLY (t) = interface_only;      SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);      CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;      TYPE_REDEFINED (t) = 1;    }  TYPE_SIZE (t) 

⌨️ 快捷键说明

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