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

📄 search.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (flag_memoize_lookups)    {      len = type_stack->len;      while (len--)	CLASSTYPE_MTABLE_ENTRY (tem[len*2])	  = (char *)MEMOIZED_CHAIN (CLASSTYPE_MTABLE_ENTRY (tem[len*2]));    }  if (! use_old)    type_stack = pop_type_level (type_stack);  else    type_stack = (struct type_level *)type_stack->base.prev;}/* Get a virtual binfo that is found inside BINFO's hierarchy that is   the same type as the type given in PARENT.  To be optimal, we want   the first one that is found by going through the least number of   virtual bases.  */static treeget_vbase_1 (parent, binfo, depth)     tree parent, binfo;     unsigned int *depth;{  tree binfos;  int i, n_baselinks;  tree rval = NULL_TREE;  if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo))    {      *depth = 0;      return binfo;    }  *depth = *depth - 1;  binfos = BINFO_BASETYPES (binfo);  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;  /* Process base types.  */  for (i = 0; i < n_baselinks; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree nrval;      if (*depth == 0)	break;      nrval = get_vbase_1 (parent, base_binfo, depth);      if (nrval)	rval = nrval;    }  *depth = *depth+1;  return rval;}treeget_vbase (parent, binfo)     tree parent;     tree binfo;{  unsigned int d = (unsigned int)-1;  return get_vbase_1 (parent, binfo, &d);}/* Convert EXPR to a virtual base class of type TYPE.  We know that   EXPR is a non-null POINTER_TYPE to RECORD_TYPE.  We also know that   the type of what expr points to has a virtual base of type TYPE.  */static treeconvert_pointer_to_vbase (type, expr)     tree type;     tree expr;{  tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))));  return convert_pointer_to_real (vb, expr);}/* 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, rval,			     rval_private_ptr, new_binfo_ptr, parent, path_ptr,			     protect, via_virtual_ptr, via_virtual,			     current_scope_in_chain)     tree binfo;     int depth, is_private, rval;     int *rval_private_ptr;     tree *new_binfo_ptr, parent, *path_ptr;     int protect, *via_virtual_ptr, via_virtual;     int current_scope_in_chain;{  tree binfos;  int i, n_baselinks;  if (protect      && !current_scope_in_chain      && is_friend (BINFO_TYPE (binfo), current_scope ()))    current_scope_in_chain = 1;  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)		       && !(TREE_VIA_PROTECTED (base_binfo)			    && current_scope_in_chain)		       && !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,					      rval, rval_private_ptr,					      new_binfo_ptr, parent, path_ptr,					      protect, via_virtual_ptr,					      this_virtual,					      current_scope_in_chain);	  /* 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;  /* Should we be completing types here?  */  if (TREE_CODE (parent) != TREE_VEC)    parent = complete_type (TYPE_MAIN_VARIANT (parent));  else    complete_type (TREE_TYPE (parent));  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))    {      type = complete_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, -1,				      &rval_private, &new_binfo, parent,				      path_ptr, watch_access, &via_virtual, 0,				      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 /* GATHER_STATISTICS */  while (field)    {#ifdef GATHER_STATISTICS      n_fields_searched++;#endif /* GATHER_STATISTICS */      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_ptr 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_node means that the field can be accessed by the current lexical   scope.   access_protected_node means that the field cannot be accessed by the current   lexical scope because it is protected.   access_private_node 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_node#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node#else#define PUBLIC_RETURN return access_public_node#define PROTECTED_RETURN return access_protected_node#define PRIVATE_RETURN return access_private_node#endif#if 0/* Disabled with DECL_PUBLIC &c.  */static tree previous_scope = NULL_TREE;#endiftreecompute_access (basetype_path, field)     tree basetype_path, field;{  tree access;  tree types;  tree context;

⌨️ 快捷键说明

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