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

📄 sig.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
{  tree x;  tree mfptr;  tree last_mfptr = NULL_TREE;  tree mfptr_list = NULL_TREE;	        for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))    {      if (TREE_CODE (x) == FUNCTION_DECL)	{	  mfptr = build_member_function_pointer (x);	  DECL_MEMFUNC_POINTER_TO (x) = mfptr;	  DECL_MEMFUNC_POINTING_TO (mfptr) = x;	  DECL_IGNORED_P (x) = 1;	  DECL_IN_AGGR_P (mfptr) = 1;	  if (! mfptr_list)	    mfptr_list = last_mfptr = mfptr;	  else	    {	      TREE_CHAIN (last_mfptr) = mfptr;	      last_mfptr = mfptr;	    }	}    }  /* The member function pointers must come after the TYPE_DECLs, in     this case, because build_signature_table_constructor depends on     finding opaque TYPE_DECLS before the functions that make use of     them.  */  if (last_mfptr)    TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), mfptr_list);}/* Compare the types of a signature member function and a class member   function.  Returns 1 if the types are in the C++ `<=' relationship.   If we have a signature pointer/reference as argument or return type   we don't want to do a recursive conformance check.  The conformance   check only succeeds if both LHS and RHS refer to the same signature   pointer.  Otherwise we need to keep information about parameter types   around at run time to initialize the signature table correctly.  */static intmatch_method_types (sig_mtype, class_mtype)     tree sig_mtype, class_mtype;{  tree sig_return_type = TREE_TYPE (sig_mtype);  tree sig_arg_types = TYPE_ARG_TYPES (sig_mtype);  tree class_return_type = TREE_TYPE (class_mtype);  tree class_arg_types = TYPE_ARG_TYPES (class_mtype);  /* The return types have to be the same.  */  if (!same_type_p (sig_return_type, class_return_type))    return 0;  /* Compare the first argument `this.'  */  {    /* Get the type of what the `optr' is pointing to.  */    tree sig_this      = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (sig_arg_types))));    tree class_this = TREE_VALUE (class_arg_types);    if (TREE_CODE (class_this) == RECORD_TYPE)	/* Is `this' a sig ptr?  */      class_this = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (class_this)));    else      class_this = TREE_TYPE (class_this);    /* If a signature method's `this' is const or volatile, so has to be       the corresponding class method's `this.'  */    if (!at_least_as_qualified_p (class_this, sig_this))      return 0;  }  sig_arg_types = TREE_CHAIN (sig_arg_types);  class_arg_types = TREE_CHAIN (class_arg_types);  /* The number of arguments and the argument types have to be the same.  */  return compparms (sig_arg_types, class_arg_types);}/* Undo casts of opaque type variables to the RHS types.  */static voidundo_casts (sig_ty)     tree sig_ty;{  tree field = TYPE_FIELDS (sig_ty);  /* Since all the FIELD_DECLs for the signature table entries are at the end     of the chain (see `append_signature_fields'), we can do it this way.  */  for (; field && TREE_CODE (field) != FIELD_DECL; field = TREE_CHAIN (field))    if (TYPE_MAIN_VARIANT (TREE_TYPE (field)) == opaque_type_node)      TREE_TYPE (TREE_TYPE (field)) = TREE_TYPE (ptr_type_node);}/* Do the type checking necessary to see whether the `rhs' conforms to   the lhs's `sig_ty'.  Depending on the type of `rhs' return a NULL_TREE,   an integer_zero_node, a constructor, or an expression offsetting the   `rhs' signature table.  */static treebuild_signature_table_constructor (sig_ty, rhs)     tree sig_ty, rhs;{  tree rhstype = TREE_TYPE (rhs);  tree sig_field = TYPE_FIELDS (sig_ty);  tree result = NULL_TREE;  tree first_rhs_field = NULL_TREE;  tree last_rhs_field = NULL_TREE;  int sig_ptr_p = IS_SIGNATURE (rhstype);  int offset_p = sig_ptr_p;  rhstype = sig_ptr_p ? rhstype : TREE_TYPE (rhstype);  if (CLASSTYPE_TAGS (sig_ty))    {      sorry ("conformance check with signature containing class declarations");      return error_mark_node;    }  for (; sig_field; sig_field = TREE_CHAIN (sig_field))    {      tree basetype_path, baselink, basetypes;      tree sig_method, sig_mname, sig_mtype;      tree rhs_method, tbl_entry;      if (TREE_CODE (sig_field) == TYPE_DECL)	{	  tree sig_field_type = TREE_TYPE (sig_field);	  if (TYPE_MAIN_VARIANT (sig_field_type) == opaque_type_node)	    {	      /* We've got an opaque type here.  */	      tree oty_name = DECL_NAME (sig_field);	      tree oty_type = lookup_field (rhstype, oty_name, 1, 1);	      if (oty_type == NULL_TREE || oty_type == error_mark_node)		{		  cp_error ("class `%T' does not contain type `%T'",			    rhstype, oty_type);		  undo_casts (sig_ty);		  return error_mark_node;		}	      oty_type = TREE_TYPE (oty_type);	      /* Cast `sig_field' to be of type `oty_type'.  This will be		 undone in `undo_casts' by walking over all the TYPE_DECLs.  */	      TREE_TYPE (sig_field_type) = TREE_TYPE (oty_type);	    }	  /* If we don't have an opaque type, we can ignore the `typedef'.  */	  continue;	}      /* Find the signature method corresponding to `sig_field'.  */      sig_method = DECL_MEMFUNC_POINTING_TO (sig_field);      sig_mname = DECL_NAME (sig_method);      sig_mtype = TREE_TYPE (sig_method);      basetype_path = TYPE_BINFO (rhstype);      baselink = lookup_fnfields (basetype_path, sig_mname, 0);      if (baselink == NULL_TREE || baselink == error_mark_node)	{	  if (! IS_DEFAULT_IMPLEMENTATION (sig_method))	    {	      cp_error ("class `%T' does not contain method `%D'",			rhstype, sig_mname);	      undo_casts (sig_ty);	      return error_mark_node;	    }	  else	    {	      /* We use the signature's default implementation.  */	      rhs_method = sig_method;	    }	}      else	{	  /* Find the class method of the correct type.  */	  tree rhs_methods;	  basetypes = TREE_PURPOSE (baselink);	  if (TREE_CODE (basetypes) == TREE_LIST)	    basetypes = TREE_VALUE (basetypes);	  rhs_methods = TREE_VALUE (baselink);	  for (; rhs_methods; rhs_methods = OVL_NEXT (rhs_methods))	    if ((rhs_method = OVL_CURRENT (rhs_methods))		&& sig_mname == DECL_NAME (rhs_method)		&& ! DECL_STATIC_FUNCTION_P (rhs_method)		&& match_method_types (sig_mtype, TREE_TYPE (rhs_method)))	      break;	  if (rhs_methods == NULL_TREE	      || !accessible_p (basetypes, rhs_method))	    {	      cp_error ("`%T' does not contain a method conforming to `%#D'",		     rhstype, sig_method);	      undo_casts (sig_ty);	      return error_mark_node;	    }	}      if (sig_ptr_p && rhs_method != sig_method)	{	  tree rhs_field = DECL_MEMFUNC_POINTER_TO (rhs_method);	  if (first_rhs_field == NULL_TREE)	    {	      first_rhs_field = rhs_field;	      last_rhs_field = rhs_field;	    }	  else if (TREE_CHAIN (last_rhs_field) == rhs_field)	    last_rhs_field = rhs_field;	  else	    offset_p = 0;	  	  tbl_entry = build_component_ref (rhs, DECL_NAME (rhs_field),					   NULL_TREE, 1);	}      else	{	  tree tag, vb_off, delta, idx, pfn = NULL_TREE, vt_off = NULL_TREE;	  tree tag_decl, vb_off_decl, delta_decl, index_decl;	  tree pfn_decl, vt_off_decl;	  if (rhs_method == sig_method)	    {	      /* default implementation */	      tag = build_unary_op (NEGATE_EXPR, integer_one_node, 0);	      vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);	      delta = integer_zero_node;	      idx = integer_zero_node;	      pfn = build_addr_func (rhs_method);	      TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;	      TREE_TYPE (pfn) = ptr_type_node;	      TREE_ADDRESSABLE (rhs_method) = 1;	      offset_p = 0;	/* we can't offset the rhs sig table */	    }	  else if (DECL_VINDEX (rhs_method))	    {	      /* virtual member function */	      tag = integer_one_node;	      vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);	      if (flag_vtable_thunks)		delta = BINFO_OFFSET		  (get_binfo (DECL_CONTEXT (rhs_method), rhstype, 1));	      else		delta = BINFO_OFFSET		  (get_binfo (DECL_CLASS_CONTEXT (rhs_method), rhstype, 1));	      idx = DECL_VINDEX (rhs_method);	      vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method),						     rhstype, 0));	    }	  else	    {	      /* non-virtual member function */	      tag = integer_zero_node;	      vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);	      delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),					       rhstype, 1));	      idx = integer_zero_node;	      pfn = build_addr_func (rhs_method);	      TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;	      TREE_TYPE (pfn) = ptr_type_node;	      TREE_ADDRESSABLE (rhs_method) = 1;	    }	  /* Since digest_init doesn't handle initializing selected fields	     of a struct (i.e., anonymous union), we build the constructor	     by hand, without calling digest_init.  */	  tag_decl = TYPE_FIELDS (sigtable_entry_type);	  vb_off_decl = TREE_CHAIN (tag_decl);	  delta_decl = TREE_CHAIN (vb_off_decl);	  index_decl = TREE_CHAIN (delta_decl);	  pfn_decl = TREE_CHAIN (index_decl);	  vt_off_decl = TREE_CHAIN (pfn_decl);	  	  tag = cp_convert (TREE_TYPE (tag_decl), tag);	  vb_off = cp_convert (TREE_TYPE (vb_off_decl), vb_off);	  delta = cp_convert (TREE_TYPE (delta_decl), delta);	  idx = cp_convert (TREE_TYPE (index_decl), idx);	  if (DECL_VINDEX (rhs_method))	    {	      vt_off = cp_convert (TREE_TYPE (vt_off_decl), vt_off);	      tbl_entry = build_tree_list (vt_off_decl, vt_off);	    }	  else	    {	      pfn = cp_convert (TREE_TYPE (pfn_decl), pfn);	      tbl_entry = build_tree_list (pfn_decl, pfn);	    }	  tbl_entry = tree_cons (delta_decl, delta,				 tree_cons (index_decl, idx, tbl_entry));	  tbl_entry = tree_cons (tag_decl, tag,				 tree_cons (vb_off_decl, vb_off, tbl_entry));	  tbl_entry = build (CONSTRUCTOR, sigtable_entry_type,			     NULL_TREE, tbl_entry);	  TREE_CONSTANT (tbl_entry) = 1;	}      /* Chain those function address expressions together.  */      if (result)	result = tree_cons (NULL_TREE, tbl_entry, result);      else	result = build_tree_list (NULL_TREE, tbl_entry);    }  if (result == NULL_TREE)    {      /* The signature was empty, we don't need a signature table.  */      undo_casts (sig_ty);      return NULL_TREE;    }  if (offset_p)    {      if (first_rhs_field == TYPE_FIELDS (rhstype))	{	  /* The sptr field on the lhs can be copied from the rhs.  */	  undo_casts (sig_ty);	  return integer_zero_node;	}      else	{	  /* The sptr field on the lhs will point into the rhs sigtable.  */	  undo_casts (sig_ty);	  return build_component_ref (rhs, DECL_NAME (first_rhs_field),				      NULL_TREE, 0);	}    }  /* We need to construct a new signature table.  */  result = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (result));  TREE_HAS_CONSTRUCTOR (result) = 1;  TREE_CONSTANT (result) = !sig_ptr_p;  undo_casts (sig_ty);  return result;}/* Build a signature table declaration and initialize it or return an   existing one if we built one already.  If we don't get a constructor   as initialization expression, we don't need a new signature table   variable and just hand back the init expression.   The declaration processing is done by hand instead of using `cp_finish_decl'   so that we can make signature pointers global variables instead of   static ones.  */static treebuild_sigtable (sig_type, rhs_type, init_from)     tree sig_type, rhs_type, init_from;{

⌨️ 快捷键说明

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