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

📄 cp-search.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (tp+((i+1)*increment) < search_tail)		  my_friendly_assert (base_binfo == tp[(i+1)*increment], 295);		if (rval = recursive_bounded_basetype_p (binfo, base_binfo, rval, 1))		  break;	      }	    if (rval > 0)	      BINFO_INHERITANCE_CHAIN (base_binfo) = *tp;	  }	/* Because I don't trust recursive_bounded_basetype_p to find	   all ambiguities, I will just make sure here.  When it is	   sure that all ambiguities are found, the two routines and	   this call can be removed.  Not toally sure this should be	   here, but I think it should. (mrs) */	if (get_binfo2 (parent, type) == error_mark_node && rval != -2)	  {#if 1	    /* This warning is here because the code over in	       prepare_fresh_vtable relies on partial completion	       offered by recursive_bounded_basetype_p I think, but	       that behavior is not documented.  It needs to be.  I	       don't think prepare_fresh_vtable is the only routine	       that relies upon path_ptr being set to something in a	       particular way when this routine returns -2.  (mrs) */	    warning ("internal consistency check failed, please report, recovering.");	    rval = -2;#endif	  }	/* Visibilities don't count if we found an ambiguous basetype.  */	if (rval == -2)	  rval_private = 0;      }  }  search_stack = pop_search_level (search_stack);  if (rval && protect && rval_private)    return -3;  if (path_ptr)    *path_ptr = binfo;  return rval;}/* Search for a member with name NAME in a multiple inheritance lattice   specified by TYPE.  If it does not exist, return NULL_TREE.   If the member is ambiguously referenced, return `error_mark_node'.   Otherwise, return the FIELD_DECL.  *//* Do a 1-level search for NAME as a member of TYPE.  The caller   must figure out whether it has a visible path to this field.   (Since it is only one level, this is reasonable.)  */static treelookup_field_1 (type, name)     tree type, name;{  register tree field = TYPE_FIELDS (type);#ifdef GATHER_STATISTICS  n_calls_lookup_field_1++;#endif  while (field)    {#ifdef GATHER_STATISTICS      n_fields_searched++;#endif      if (DECL_NAME (field) == NULL_TREE	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)	{	  tree temp = lookup_field_1 (TREE_TYPE (field), name);	  if (temp)	    return temp;	}      if (DECL_NAME (field) == name)	{	  if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)	      && DECL_ASSEMBLER_NAME (field) != NULL)	    GNU_xref_ref(current_function_decl,			 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (field)));	  return field;	}      field = TREE_CHAIN (field);    }  /* Not found.  */  if (name == _vptr_name)    {      /* Give the user what s/he thinks s/he wants.  */      if (TYPE_VIRTUAL_P (type))	return CLASSTYPE_VFIELD (type);    }  return NULL_TREE;}/* Compute the visibility of FIELD.  This is done by computing   the visibility available to each type in BASETYPES (which comes   as a list of [via_public/basetype] in reverse order, namely base   class before derived class).  The first one which defines a   visibility defines the visibility for the field.  Otherwise, the   visibility of the field is that which occurs normally.   Uses global variables CURRENT_CLASS_TYPE and   CURRENT_FUNCTION_DECL to use friend relationships   if necessary.   This will be static when lookup_fnfield comes into this file.  */#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), visibility_public#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), visibility_protected#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), visibility_privateenum visibility_typecompute_visibility (basetype_path, field)     tree basetype_path, field;{  enum visibility_type visibility = visibility_public;  tree types;  tree context = DECL_CLASS_CONTEXT (field);  /* Virtual function tables are never private.     But we should know that we are looking for this,     and not even try to hide it.  */  if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1)    return visibility_public;  /* Make these special cases fast.  */  if (BINFO_TYPE (basetype_path) == current_class_type)    {      if (DECL_PUBLIC (field))	return visibility_public;      if (DECL_PROTECTED (field))	return visibility_protected;      if (DECL_PRIVATE (field))	return visibility_private;    }  /* Member function manipulating its own members.  */  if (current_class_type == context)    PUBLIC_RETURN;  /* Member found immediately within object.  */  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)    {      /* At object's top level, public members are public.  */      if (TREE_PROTECTED (field) == 0 && TREE_PRIVATE (field) == 0)	PUBLIC_RETURN;      /* Friend function manipulating members it gets (for being a friend).  */      if (is_friend (context, current_function_decl))	PUBLIC_RETURN;      /* Inner than that, without special visibility,	   protected members are ok if type of object is current_class_type	   is derived therefrom.  This means that if the type of the object	   is a base type for our current class type, we cannot access	   protected members.	   private members are not ok.  */      if (current_class_type && DECL_VISIBILITY (field) == NULL_TREE)	{	  if (TREE_PRIVATE (field))	    PRIVATE_RETURN;	  if (TREE_PROTECTED (field))	    {	      if (context == current_class_type		  || UNIQUELY_DERIVED_FROM_P (context, current_class_type))		PUBLIC_RETURN;	      else		PROTECTED_RETURN;	    }	  else my_friendly_abort (94);	}    }  /* Friend function manipulating members it gets (for being a friend).  */  if (is_friend (context, current_function_decl))    PUBLIC_RETURN;  /* must reverse more than one element */  basetype_path = reverse_path (basetype_path);  types = basetype_path;  while (types)    {      tree member;      tree binfo = types;      tree type = BINFO_TYPE (binfo);      member = purpose_member (type, DECL_VISIBILITY (field));      if (member)	{	  visibility = (enum visibility_type)TREE_VALUE (member);	  if (visibility == visibility_public	      || is_friend (type, current_function_decl)	      || (visibility == visibility_protected		  && current_class_type		  && UNIQUELY_DERIVED_FROM_P (context, current_class_type)))	    visibility = visibility_public;	  goto ret;	}      /* Friends inherit the visibility of the class they inherit from.  */      if (is_friend (type, current_function_decl))	{	  if (type == context)	    {	      visibility = visibility_public;	      goto ret;	    }	  if (TREE_PROTECTED (field))	    {	      visibility = visibility_public;	      goto ret;	    }#if 0	  /* This short-cut is too short.  */	  if (visibility == visibility_public)	    goto ret;#endif	  /* else, may be a friend of a deeper base class */	}      if (type == context)	break;      types = BINFO_INHERITANCE_CHAIN (types);      /* If the next type was not VIA_PUBLIC, then fields of all	 remaining class past that one are private.  */      if (types)	{	  if (TREE_VIA_PROTECTED (types))	    visibility = visibility_protected;	  else if (! TREE_VIA_PUBLIC (types))	    visibility = visibility_private;	}    }  /* No special visibilities apply.  Use normal rules.     No assignment needed for BASETYPEs here from the nreverse.     This is because we use it only for information about the     path to the base.  The code earlier dealt with what     happens when we are at the base level.  */  if (visibility == visibility_public)    {      basetype_path = reverse_path (basetype_path);      if (TREE_PRIVATE (field))	PRIVATE_RETURN;      if (TREE_PROTECTED (field))	{	  /* Used to check if the current class type was derived from	     the type that contains the field.  This is wrong for	     multiple inheritance because is gives one class reference	     to protected members via another classes protected path.	     I.e., if A; B1 : A; B2 : A;  Then B1 and B2 can access	     their own members which are protected in A, but not	     those same members in one another.  */	  if (current_class_type	      && UNIQUELY_DERIVED_FROM_P (context, current_class_type))	    PUBLIC_RETURN;	  PROTECTED_RETURN;	}      PUBLIC_RETURN;    }  if (visibility == visibility_protected)    {      /* reverse_path? */      if (TREE_PRIVATE (field))	PRIVATE_RETURN;      /* We want to make sure that all non-private members in	 the current class (as derived) are accessible.  */      if (current_class_type	  && UNIQUELY_DERIVED_FROM_P (context, current_class_type))	PUBLIC_RETURN;      PROTECTED_RETURN;    }  if (visibility == visibility_private      && current_class_type != NULL_TREE)    {      if (TREE_PRIVATE (field))	{	  reverse_path (basetype_path);	  PRIVATE_RETURN;	}      /* See if the field isn't protected.  */      if (TREE_PROTECTED (field))	{	  tree test = basetype_path;	  while (test)	    {	      if (BINFO_TYPE (test) == current_class_type)		break;	      test = BINFO_INHERITANCE_CHAIN (test);	    }	  reverse_path (basetype_path);	  if (test)	    PUBLIC_RETURN;	  PROTECTED_RETURN;	}      /* See if the field isn't a public member of	 a private base class.  */      visibility = visibility_public;      types = BINFO_INHERITANCE_CHAIN (basetype_path);      while (types)	{	  if (! TREE_VIA_PUBLIC (types))	    {	      if (visibility == visibility_private)		{		  visibility = visibility_private;		  goto ret;		}	      visibility = visibility_private;	    }	  if (BINFO_TYPE (types) == context)	    {	      visibility = visibility_public;	      goto ret;	    }	  types = BINFO_INHERITANCE_CHAIN (types);	}      my_friendly_abort (95);    } ret:  reverse_path (basetype_path);  if (visibility == visibility_public)    DECL_PUBLIC (field) = 1;  else if (visibility == visibility_protected)    DECL_PROTECTED (field) = 1;  else if (visibility == visibility_private)    DECL_PRIVATE (field) = 1;  else my_friendly_abort (96);  return visibility;}/* Look for a field named NAME in an inheritance lattice dominated by   XBASETYPE.  PROTECT is zero if we can avoid computing visibility   information, otherwise it is 1.  WANT_TYPE is 1 when we should only   return TYPE_DECLs, if no TYPE_DECL can be found return NULL.  */treelookup_field (xbasetype, name, protect, want_type)     register tree xbasetype, name;     int protect, want_type;{  int head = 0, tail = 0;  tree rval;  tree type, basetype_chain, basetype_path;  enum visibility_type this_v = visibility_default;  tree entry, binfo;  enum visibility_type own_visibility = visibility_default;  int vbase_name_p = VBASE_NAME_P (name);  /* Things for memoization.  */  char *errstr = 0;  /* Set this to nonzero if we don't know how to compute     accurate error messages for visibility.  */  int index = MEMOIZED_HASH_FN (name);  if (TREE_CODE (xbasetype) == TREE_VEC)    basetype_path = xbasetype, type = BINFO_TYPE (xbasetype);  else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))    basetype_path = TYPE_BINFO (xbasetype), type = xbasetype;  else my_friendly_abort (97);  if (CLASSTYPE_MTABLE_ENTRY (type))    {      tree tem = MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);      while (tem && TREE_PURPOSE (tem) != name)	{	  memoized_fields_searched[0]++;	  tem = TREE_CHAIN (tem);	}      if (tem)	{	  if (protect && TREE_TYPE (tem))	    {	      error (TREE_STRING_POINTER (TREE_TYPE (tem)),		     IDENTIFIER_POINTER (name),		     TYPE_NAME_STRING (DECL_FIELD_CONTEXT (TREE_VALUE (tem))));	      return error_mark_node;	    }	  if (TREE_VALUE (tem) == NULL_TREE)	    memoized_fast_rejects[0] += 1;	  else	    memoized_fast_finds[0] += 1;	  return TREE_VALUE (tem);	}    }#ifdef GATHER_STATISTICS  n_calls_lookup_field++;#endif  if (protect && flag_memoize_lookups && ! global_bindings_p ())    entry = make_memoized_table_entry (type, name, 0);  else    entry = 0;  rval = lookup_field_1 (type, name);  if (rval && TREE_CODE (rval) != TYPE_DECL && want_type)    rval = NULL_TREE;  if (rval)    {      if (protect)	{	  if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval))	    this_v = compute_visibility (basetype_path, rval);	  if (TREE_CODE (rval) == CONST_DECL)	    {	      if (this_v == visibility_private)		errstr = "enum `%s' is a private value of class `%s'";	      else if (this_v == visibility_protected)		errstr = "enum `%s' is a protected value of class `%s'";	    }	  else	    {	      if (this_v == visibility_private)		errstr = "member `%s' is a private member of class `%s'";	      else if (this_v == visibility_protected)		errstr = "member `%s' is a protected member of class `%s'";	    }	}      if (entry)	{	  if (errstr)	    {	      /* This depends on behavior of lookup_field_1!  */	      tree error_string = my_build_string (errstr);	      TREE_TYPE (entry) = error_string;	    }	  else	    {	      /* Let entry know there is no problem with this access.  */	      TREE_TYPE (entry) = NULL_TREE;	    }	  TREE_VALUE (entry) = rval;	}      if (errstr && protect)	{	  error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));	  return error_mark_node;	}      return rval;    }

⌨️ 快捷键说明

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