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

📄 search.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));      int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;      for (i = 0; i < n_baselinks; i++)	{	  tree base_binfo = TREE_VEC_ELT (binfos, i);	  if (parent == BINFO_TYPE (base_binfo))	    return 1;	}    }  return 0;}#endif/* Check whether the type given in BINFO is derived from PARENT.  If   it isn't, return 0.  If it is, but the derivation is MI-ambiguous   AND protect != 0, emit an error message and return error_mark_node.   Otherwise, if TYPE is derived from PARENT, return the actual base   information, unless a one of the protection violations below   occurs, in which case emit an error message and return error_mark_node.   If PROTECT is 1, then check if access to a public field of PARENT   would be private.  Also check for ambiguity.  */treeget_binfo (parent, binfo, protect)     register tree parent, binfo;     int protect;{  tree type;  int dist;  tree rval = NULL_TREE;    if (TREE_CODE (parent) == TREE_VEC)    parent = BINFO_TYPE (parent);  else if (! IS_AGGR_TYPE_CODE (TREE_CODE (parent)))    my_friendly_abort (89);  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))    type = binfo;  else    my_friendly_abort (90);    dist = get_base_distance (parent, binfo, protect, &rval);  if (dist == -3)    {      cp_error ("fields of `%T' are inaccessible in `%T' due to private inheritance",		parent, type);      return error_mark_node;    }  else if (dist == -2 && protect)    {      cp_error ("type `%T' is ambiguous base class for type `%T'", parent,		type);      return error_mark_node;    }  return rval;}/* This is the newer depth first get_base_distance routine.  */static intget_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,			     rval_private_ptr, new_binfo_ptr, parent, path_ptr,			     protect, via_virtual_ptr, via_virtual)     tree binfo, basetype_path, *new_binfo_ptr, parent, *path_ptr;     int *rval_private_ptr, depth, is_private, rval, protect, *via_virtual_ptr,       via_virtual;{  tree binfos;  int i, n_baselinks;  if (BINFO_TYPE (binfo) == parent || binfo == parent)    {      if (rval == -1)	{	  rval = depth;	  *rval_private_ptr = is_private;	  *new_binfo_ptr = binfo;	  *via_virtual_ptr = via_virtual;	}      else	{	  int same_object = (tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr),						 BINFO_OFFSET (binfo))			     && *via_virtual_ptr && via_virtual);			     	  if (*via_virtual_ptr && via_virtual==0)	    {	      *rval_private_ptr = is_private;	      *new_binfo_ptr = binfo;	      *via_virtual_ptr = via_virtual;	    }	  else if (same_object)	    {	      if (*rval_private_ptr && ! is_private)		{		  *rval_private_ptr = is_private;		  *new_binfo_ptr = binfo;		  *via_virtual_ptr = via_virtual;		}	      return rval;	    }	  rval = -2;	}      return rval;    }  binfos = BINFO_BASETYPES (binfo);  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;  depth += 1;  /* Process base types.  */  for (i = 0; i < n_baselinks; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      /* Find any specific instance of a virtual base, when searching with	 a binfo... */      if (BINFO_MARKED (base_binfo) == 0 || TREE_CODE (parent) == TREE_VEC)	{	  int via_private	    = (protect	       && (is_private		   || (!TREE_VIA_PUBLIC (base_binfo)		       && !is_friend (BINFO_TYPE (binfo), current_scope ()))));	  int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);	  int was;	  /* When searching for a non-virtual, we cannot mark	     virtually found binfos. */	  if (! this_virtual)	    SET_BINFO_MARKED (base_binfo);#define WATCH_VALUES(rval, via_private) (rval == -1 ? 3 : via_private)	  was = WATCH_VALUES (rval, *via_virtual_ptr);	  rval = get_base_distance_recursive (base_binfo, depth, via_private,					      binfo, rval, rval_private_ptr,					      new_binfo_ptr, parent, path_ptr,					      protect, via_virtual_ptr,					      this_virtual);	  /* watch for updates; only update if path is good. */	  if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was)	    BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;	  if (rval == -2 && *via_virtual_ptr == 0)	    return rval;#undef WATCH_VALUES	}    }  return rval;}/* Return the number of levels between type PARENT and the type given   in BINFO, following the leftmost path to PARENT not found along a   virtual path, if there are no real PARENTs (all come from virtual   base classes), then follow the leftmost path to PARENT.   Return -1 if TYPE is not derived from PARENT.   Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is    non-negative.   Return -3 if PARENT is private to TYPE, and PROTECT is non-zero.   If PATH_PTR is non-NULL, then also build the list of types   from PARENT to TYPE, with TREE_VIA_VIRTUAL and TREE_VIA_PUBLIC   set.   PARENT can also be a binfo, in which case that exact parent is found   and no other.  convert_pointer_to_real uses this functionality.   If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone.  */intget_base_distance (parent, binfo, protect, path_ptr)     register tree parent, binfo;     int protect;     tree *path_ptr;{  int rval;  int rval_private = 0;  tree type;  tree new_binfo = NULL_TREE;  int via_virtual;  int watch_access = protect;  if (TREE_CODE (parent) != TREE_VEC)    parent = TYPE_MAIN_VARIANT (parent);  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))    {      type = binfo;      binfo = TYPE_BINFO (type);      if (path_ptr)	BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;    }  else    my_friendly_abort (92);  if (parent == type || parent == binfo)    {      /* If the distance is 0, then we don't really need	 a path pointer, but we shouldn't let garbage go back.  */      if (path_ptr)	*path_ptr = binfo;      return 0;    }  if (path_ptr)    watch_access = 1;  rval = get_base_distance_recursive (binfo, 0, 0, NULL_TREE, -1,				      &rval_private, &new_binfo, parent,				      path_ptr, watch_access, &via_virtual, 0);  dfs_walk (binfo, dfs_unmark, markedp);  /* Access restrictions don't count if we found an ambiguous basetype.  */  if (rval == -2 && protect >= 0)    rval_private = 0;  if (rval && protect && rval_private)    return -3;  /* find real virtual base classes. */  if (rval == -1 && TREE_CODE (parent) == TREE_VEC      && parent == binfo_member (BINFO_TYPE (parent),				 CLASSTYPE_VBASECLASSES (type)))    {      BINFO_INHERITANCE_CHAIN (parent) = binfo;      new_binfo = parent;      rval = 1;    }  if (path_ptr)    *path_ptr = new_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 can access 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;}/* There are a number of cases we need to be aware of here:			 current_class_type	current_function_decl   * global			NULL			NULL   * fn-local			NULL			SET   * class-local		SET			NULL   * class->fn			SET			SET   * fn->class			SET			SET   Those last two make life interesting.  If we're in a function which is   itself inside a class, we need decls to go into the fn's decls (our   second case below).  But if we're in a class and the class itself is   inside a function, we need decls to go into the decls for the class.  To   achieve this last goal, we must see if, when both current_class_decl and   current_function_decl are set, the class was declared inside that   function.  If so, we know to put the decls into the class's scope.  */treecurrent_scope (){  if (current_function_decl == NULL_TREE)    return current_class_type;  if (current_class_type == NULL_TREE)    return current_function_decl;  if (DECL_CLASS_CONTEXT (current_function_decl) == current_class_type)    return current_function_decl;  return current_class_type;}/* Compute the access of FIELD.  This is done by computing   the access 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   access defines the access for the field.  Otherwise, the   access 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.   access_public means that the field can be accessed by the current lexical   scope.   access_protected means that the field cannot be accessed by the current   lexical scope because it is protected.   access_private means that the field cannot be accessed by the current   lexical scope because it is private. */#if 0#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private#else#define PUBLIC_RETURN return access_public#define PROTECTED_RETURN return access_protected#define PRIVATE_RETURN return access_private#endif#if 0/* Disabled with DECL_PUBLIC &c.  */static tree previous_scope = NULL_TREE;#endifenum access_typecompute_access (basetype_path, field)     tree basetype_path, field;{  enum access_type access;  tree types;  tree context;  int protected_ok, via_protected;  extern int flag_access_control;#if 1  /* Replaces static decl above.  */  tree previous_scope;#endif  int static_mem =    ((TREE_CODE (field) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (field))     || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));  if (! flag_access_control)    return access_public;  /* The field lives in the current class.  */  if (BINFO_TYPE (basetype_path) == current_class_type)    return access_public;#if 0  /* Disabled until pushing function scope clears these out.  If ever.  */  /* Make these special cases fast.  */  if (current_scope () == previous_scope)    {      if (DECL_PUBLIC (field))	return access_public;      if (DECL_PROTECTED (field))	return access_protected;      if (DECL_PRIVATE (field))	return access_private;    }#endif  /* We don't currently support access control on nested types.  */  if (TREE_CODE (field) == TYPE_DECL)    return access_public;  previous_scope = current_scope ();    context = DECL_CLASS_CONTEXT (field);  if (context == NULL_TREE)    context = DECL_CONTEXT (field);  /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT     slot set to the union type rather than the record type containing     the anonymous union.  In this case, DECL_FIELD_CONTEXT is correct.  */  if (context && TREE_CODE (context) == UNION_TYPE      && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))    context = DECL_FIELD_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)    PUBLIC_RETURN;  /* Member found immediately within object.  */  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)    {      /* Are we (or an enclosing scope) friends with the class that has         FIELD? */      if (is_friend (context, previous_scope))	PUBLIC_RETURN;      /* If it's private, it's private, you letch.  */      if (TREE_PRIVATE (field))	PRIVATE_RETURN;      /* ARM $11.5.  Member functions of a derived class can access the	 non-static protected members of a base class only through a	 pointer to the derived class, a reference to it, or an object	 of it. Also any subsequently derived classes also have	 access.  */      else if (TREE_PROTECTED (field))	{	  if (current_class_type	      && static_mem  	      && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))	    PUBLIC_RETURN;	  else	    PROTECTED_RETURN;	}      else	PUBLIC_RETURN;

⌨️ 快捷键说明

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