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

📄 cp-search.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);  TREE_VIA_PUBLIC (basetype_chain) = 1;  search_stack = push_search_level (search_stack, &search_obstack);  BINFO_VIA_PUBLIC (basetype_path) = 1;  BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;  binfo = basetype_path;  while (1)    {      tree binfos = BINFO_BASETYPES (binfo);      int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;      /* Process and/or queue base types.  */      for (i = 0; i < n_baselinks; i++)	{	  tree base_binfo = TREE_VEC_ELT (binfos, i);	  if (BINFO_FIELDS_MARKED (base_binfo) == 0)	    {	      tree btypes;	      SET_BINFO_FIELDS_MARKED (base_binfo);	      btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);	      TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);	      TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);	      TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);	      obstack_ptr_grow (&search_obstack, btypes);	      tail += 1;	      if (tail >= search_stack->limit)		my_friendly_abort (98);	    }	}      /* Process head of queue, if one exists.  */      if (head >= tail)	break;      basetype_chain = search_stack->first[head++];      basetype_path = TREE_VALUE (basetype_chain);      if (TREE_CHAIN (basetype_chain))	BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));      else	BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;      binfo = basetype_path;      type = BINFO_TYPE (binfo);      /* See if we can find NAME in TYPE.  If RVAL is nonzero,	 and we do find NAME in TYPE, verify that such a second	 sighting is in fact legal.  */      if (rval)	{	  tree context = DECL_FIELD_CONTEXT (rval);	  /* Just another way of finding the same member.  */	  if (TYPE_BINFO (context) == binfo)	    {	      enum visibility_type new_v		= compute_visibility (basetype_path, rval);	      if (this_v != new_v)		errstr = "conflicting visibilities to member `%s'";	    }	  /* Same baseclass, maybe different places in the lattice.  */	  else if (context == type)	    {	      errstr = "member `%s' belongs to distinct base classes `%s'";	      protect = 2;	    }	  else	    {	      tree nval = lookup_field_1 (type, name);	      if (nval && TREE_CODE (nval) != TYPE_DECL && want_type)		nval = NULL_TREE;	      if (nval		  && binfo != get_binfo (type, DECL_FIELD_CONTEXT (rval), 0))		{		  /* We found it in other than a baseclass of RVAL's.  */		  errstr = "request for member `%s' is ambiguous";		  protect = 2;		}	    }	  if (errstr && entry)	    {	      tree error_string = my_build_string (errstr);	      TREE_TYPE (entry) = error_string;	    }	  if (errstr && protect)	    break;	}      else	{	  rval = lookup_field_1 (type, name);	  if (rval && TREE_CODE (rval) != TYPE_DECL && want_type)	    rval = NULL_TREE;	  if (rval)	    {	      if (entry || protect)		this_v = compute_visibility (basetype_path, rval);	      if (entry)		TREE_VALUE (entry) = rval;	      /* These may look ambiguous, but they really are not.  */	      if (vbase_name_p)		break;	    }	}    }  {    tree *tp = search_stack->first;    tree *search_tail = tp + tail;    /* If this FIELD_DECL defines its own visibility, deal with that.  */    if (rval && errstr == 0	&& ((protect&1) || entry)	&& DECL_LANG_SPECIFIC (rval)	&& DECL_VISIBILITY (rval))      {	while (tp < search_tail)	  {	    /* If is possible for one of the derived types on the	       path to have defined special visibility for this	       field.  Look for such declarations and report an	       error if a conflict is found.  */	    enum visibility_type new_v;	    if (this_v != visibility_default)	      new_v = compute_visibility (TREE_VALUE (*tp), rval);	    if (this_v != visibility_default && new_v != this_v)	      {		errstr = "conflicting visibilities to member `%s'";		this_v = visibility_default;	      }	    own_visibility = new_v;	    CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (*tp));	    tp += 1;	  }      }    else      {	while (tp < search_tail)	  {	    CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (*tp));	    tp += 1;	  }      }  }  search_stack = pop_search_level (search_stack);  if (errstr == 0)    {      if (own_visibility == visibility_private)	errstr = "member `%s' declared private";      else if (own_visibility == visibility_protected)	errstr = "member `%s' declared protected";      else if (this_v == visibility_private)	errstr = TREE_PRIVATE (rval)	  ? "member `%s' is private"	    : "member `%s' is from private base class";      else if (this_v == visibility_protected)	errstr = TREE_PROTECTED (rval)	  ? "member `%s' is protected"	    : "member `%s' is from protected base class";    }  if (entry)    {      if (errstr)	{	  tree error_string = my_build_string (errstr);	  /* Save error message with entry.  */	  TREE_TYPE (entry) = error_string;	}      else	{	  /* Mark entry as having no error string.  */	  TREE_TYPE (entry) = NULL_TREE;	}    }  if (errstr && protect)    {      error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));      rval = error_mark_node;    }  return rval;}/* Try to find NAME inside a nested class.  */treelookup_nested_field (name)     tree name;{  register tree t;  tree id = NULL_TREE;  if (TREE_CHAIN (current_class_type))    {      /* Climb our way up the nested ladder, seeing if we're trying to	 modify a field in an enclosing class.  If so, we should only	 be able to modify if it's static.  */      for (t = TREE_CHAIN (current_class_type);	   t && DECL_CONTEXT (t);	   t = TREE_CHAIN (DECL_CONTEXT (t)))	{	  if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)	    break;	  /* N.B.: lookup_field will do the visibility checking for us */	  id = lookup_field (DECL_CONTEXT (t), name, 1, 0);	  if (id == error_mark_node)	    continue;	  if (id != NULL_TREE)	    {	      if (TREE_CODE (id) == FIELD_DECL		  && ! TREE_STATIC (id)		  && TREE_TYPE (id) != error_mark_node)		{		  error ("assignment to non-static member `%s' of enclosing class `%s'",			 lang_printable_name (id),			 IDENTIFIER_POINTER (TYPE_IDENTIFIER					     (DECL_CONTEXT (t))));		  /* Mark this for do_identifier().  It would otherwise		     claim that the variable was undeclared.  */		  TREE_TYPE (id) = error_mark_node;		}	      break;	    }	}    }  return id;}/* TYPE is a class type. Return the index of the fields within   the method vector with name NAME, or -1 is no such field exists.  */static intlookup_fnfields_1 (type, name)     tree type, name;{  register tree method_vec = CLASSTYPE_METHOD_VEC (type);  if (method_vec != 0)    {      register tree *methods = &TREE_VEC_ELT (method_vec, 0);      register tree *end = TREE_VEC_END (method_vec);#ifdef GATHER_STATISTICS      n_calls_lookup_fnfields_1++;#endif      if (*methods && name == constructor_name (type))	return 0;      while (++methods != end)	{#ifdef GATHER_STATISTICS	  n_outer_fields_searched++;#endif	  if (DECL_NAME (*methods) == name)	    break;	}      if (methods != end)	return methods - &TREE_VEC_ELT (method_vec, 0);    }  return -1;}/* Starting from BASETYPE, return a TREE_BASELINK-like object   which gives the following information (in a list):   TREE_TYPE: list of basetypes needed to get to...   TREE_VALUE: list of all functions in of given type   which have name NAME.   No visibility information is computed by this function,   other then to adorn the list of basetypes with   TREE_VIA_PUBLIC.   If FIND_AMBIGUOUS is non-zero, then if we find two ways to get   to the same member function, both those ways are found,   and the caller must know what to do about this.  */treelookup_fnfields (basetype_path, name, find_ambiguous)     tree basetype_path, name;     int find_ambiguous;{  int head = 0, tail = 0;  tree type, rval, rvals = NULL_TREE;  tree entry, binfo, basetype_chain;  /* For now, don't try this.  */  int protect = find_ambiguous;  /* 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);  binfo = basetype_path;  type = BINFO_TYPE (basetype_path);  if (CLASSTYPE_MTABLE_ENTRY (type))    {      tree tem = MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);      while (tem && TREE_PURPOSE (tem) != name)	{	  memoized_fields_searched[1]++;	  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_CLASS_CONTEXT (TREE_VALUE (TREE_VALUE (tem)))));	      return error_mark_node;	    }	  if (TREE_VALUE (tem) == NULL_TREE)	    {	      memoized_fast_rejects[1] += 1;	      return NULL_TREE;	    }	  else	    {	      /* Want to return this, but we must make sure		 that visibility information is consistent.  */	      tree baselink = TREE_VALUE (tem);	      tree memoized_basetypes = TREE_PURPOSE (baselink);	      tree these_basetypes = basetype_path;	      while (memoized_basetypes && these_basetypes)		{		  memoized_fields_searched[1]++;		  if (TREE_VALUE (memoized_basetypes) != these_basetypes)		    break;		  memoized_basetypes = TREE_CHAIN (memoized_basetypes);		  these_basetypes = BINFO_INHERITANCE_CHAIN (these_basetypes);		}	      /* The following statement is true only when both are NULL.  */	      if (memoized_basetypes == these_basetypes)		{		  memoized_fast_finds[1] += 1;		  return TREE_VALUE (tem);		}	      /* else, we must re-find this field by hand.  */	      baselink = tree_cons (basetype_path, TREE_VALUE (baselink), TREE_CHAIN (baselink));	      return baselink;	    }	}    }#ifdef GATHER_STATISTICS  n_calls_lookup_fnfields++;#endif  if (protect && flag_memoize_lookups && ! global_bindings_p ())    entry = make_memoized_table_entry (type, name, 1);  else    entry = 0;  index = lookup_fnfields_1 (type, name);  if (index >= 0)    {      rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);      rvals = my_tree_cons (basetype_path, rval, NULL_TREE);      if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type))	TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);      if (entry)	{	  TREE_VALUE (entry) = rvals;	  TREE_TYPE (entry) = NULL_TREE;	}      if (errstr && protect)	{	  error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));	  return error_mark_node;	}      return rvals;    }  rval = NULL_TREE;  basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);  TREE_VIA_PUBLIC (basetype_chain) = 1;  search_stack = push_search_level (search_stack, &search_obstack);  BINFO_VIA_PUBLIC (basetype_path) = 1;  BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;  binfo = basetype_path;  while (1)    {      tree binfos = BINFO_BASETYPES (binfo);      int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;      /* Process and/or queue base types.  */      for (i = 0; i < n_baselinks; i++)	{	  tree base_binfo = TREE_VEC_ELT (binfos, i);	  if (BINFO_FIELDS_MARKED (base_binfo) == 0)	    {	      tree btypes;	      SET_BINFO_FIELDS_MARKED (base_binfo);	      btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);	      TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);	      TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);	      TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);	      obstack_ptr_grow (&search_obstack, btypes);	      tail += 1;	      if (tail >= search_stack->limit)		my_friendly_abort (99);	    }	}      /* Process head of queue, if one exists.  */      if (head >= tail)	break;      basetype_chain = search_stack->first[head++];      basetype_path = TREE_VALUE (basetype_chain);      if (TREE_CHAIN (basetype_chain))	BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));      else	BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;      binfo = basetype_path;      type = BINFO_TYPE (binfo);      /* See if we can find NAME in TYPE.  If RVAL is nonzero,	 and we do find NAME in TYPE, verify that such a second	 sighting is in fact legal.  */      if (rval)	{	  tree context = DECL_CLASS_CONTEXT (rval);	  /* Just another way of finding the same member.  */	  if (TYPE_BINFO (context) == binfo)	    ;	  /* Same baseclass, maybe different places in the lattice.  */	  else if (context == type)	    {	      if (TREE_VIA_VIRTUAL (TREE_PURPOSE (rvals)))		if (TREE_VIA_VIRTUAL (binfo))		  ;		else		  errstr = "member `%s' belongs to virtual and non-virtual baseclasses `%s'";

⌨️ 快捷键说明

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