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

📄 search.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (rval && errstr == 0	&& ((protect&1) || entry)	&& DECL_LANG_SPECIFIC (rval)	&& DECL_ACCESS (rval))      {	while (tp < search_tail)	  {	    /* If is possible for one of the derived types on the path to	       have defined special access for this field.  Look for such	       declarations and report an error if a conflict is found.  */	    enum access_type new_v;	    if (this_v != access_default)	      new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);	    if (this_v != access_default && new_v != this_v)	      {		errstr = "conflicting access to member `%D'";		this_v = access_default;	      }	    own_access = new_v;	    CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));	    tp += 1;	  }      }    else      {	while (tp < search_tail)	  {	    CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));	    tp += 1;	  }      }  }  search_stack = pop_search_level (search_stack);  if (errstr == 0)    {      if (own_access == access_private)	errstr = "member `%D' declared private";      else if (own_access == access_protected)	errstr = "member `%D' declared protected";      else if (this_v == access_private)	errstr = TREE_PRIVATE (rval)	  ? "member `%D' is private"	    : "member `%D' is from private base class";      else if (this_v == access_protected)	errstr = TREE_PROTECTED (rval)	  ? "member `%D' is protected"	    : "member `%D' 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)    {      cp_error (errstr, name, type);      rval = error_mark_node;    }  return rval;}/* Try to find NAME inside a nested class.  */treelookup_nested_field (name, complain)     tree name;     int complain;{  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 access checking for us */	  id = lookup_field (DECL_CONTEXT (t), name, complain, 0);	  if (id == error_mark_node)	    {	      id = NULL_TREE;	      continue;	    }	  if (id != NULL_TREE)	    {	      if (TREE_CODE (id) == FIELD_DECL		  && ! TREE_STATIC (id)		  && TREE_TYPE (id) != error_mark_node)		{		  if (complain)		    {		      /* At parse time, we don't want to give this error, since			 we won't have enough state to make this kind of			 decision properly.  But there are times (e.g., with			 enums in nested classes) when we do need to call			 this fn at parse time.  So, in those cases, we pass			 complain as a 0 and just return a NULL_TREE.  */		      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;		    }		  else		    {		      id = NULL_TREE;		      continue;		    }		}	      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 access information is computed by this function,   other then to adorn the list of basetypes with   TREE_VIA_PUBLIC.   If there are two ways to find a name (two members), if COMPLAIN is   non-zero, then error_mark_node is returned, and an error message is   printed, otherwise, just an error_mark_node is returned.   As a special case, is COMPLAIN is -1, we don't complain, and we   don't return error_mark_node, but rather the complete list of   virtuals.  This is used by get_virtuals_named_this.  */treelookup_fnfields (basetype_path, name, complain)     tree basetype_path, name;     int complain;{  int head = 0, tail = 0;  tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE, rval_binfo_h;  tree entry, binfo, basetype_chain, binfo_h;  int find_all = 0;  /* rval_binfo is the binfo associated with the found member, note,     this can be set with useful information, even when rval is not     set, because it must deal with ALL members, not just function     members.  It is used for ambiguity checking and the hidden     checks.  Whereas rval is only set if a proper (not hidden)     function member is found.  */  /* rval_binfo_h and binfo_h are binfo values used when we perform the     hiding checks, as virtual base classes may not be shared.  The strategy     is we always go into the the binfo hierarchy owned by TYPE_BINFO of     virtual base classes, as we cross virtual base class lines.  This way     we know that binfo of a virtual base class will always == itself when     found along any line.  (mrs)  */  /* For now, don't try this.  */  int protect = complain;  char *errstr = 0;  /* Set this to nonzero if we don't know how to compute     accurate error messages for access control.  */  int index = MEMOIZED_HASH_FN (name);  if (complain == -1)    {      find_all = 1;      protect = complain = 0;    }  /* If we are looking for a constructor in a templated type, use the     unspecialized name, as that is how we store it.  */  if (IDENTIFIER_TEMPLATE (name))    name = constructor_name (name);  binfo = basetype_path;  binfo_h = binfo;  type = BINFO_TYPE (basetype_path);  /* The memoization code is in need of maintenance. */  if (!find_all && 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 access 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_here (type, name);  if (index >= 0 || lookup_field_1 (type, name))    {      rval_binfo = basetype_path;      rval_binfo_h = rval_binfo;    }  if (index >= 0)    {      rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);      rvals = my_tree_cons (basetype_path, rval, rvals);      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;	}      return rvals;    }  rval = NULL_TREE;  if (basetype_path == TYPE_BINFO (type))    {      basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);      TREE_VIA_PUBLIC (basetype_chain) = 1;      BINFO_VIA_PUBLIC (basetype_path) = 1;      BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;    }  else    {      basetype_chain = build_tree_list (NULL_TREE, basetype_path);      TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);      TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);      TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);    }  /* The ambiguity check relies upon breadth first searching. */  search_stack = push_search_level (search_stack, &search_obstack);  binfo = basetype_path;  binfo_h = binfo;  while (1)    {      tree binfos = BINFO_BASETYPES (binfo);      int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;      int index;      /* 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);	      if (TREE_VIA_VIRTUAL (base_binfo))		btypes = tree_cons (NULL_TREE,				    TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),				    btypes);	      else		btypes = tree_cons (NULL_TREE,				    TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),				    btypes);	      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++];      binfo_h = TREE_VALUE (basetype_chain);      basetype_chain = TREE_CHAIN (basetype_chain);      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 valid.  */      index = lookup_fnfields_here (type, name);      if (index >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all))	{	  if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h))	    {	      /* This is ok, the member found is in rval_binfo, not		 here (binfo). */	    }	  else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h))	    {	      /* This is ok, the member found is here (binfo), not in		 rval_binfo. */	      if (index >= 0)		{		  rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);		  /* Note, rvals can only be previously set if find_all is		     true.  */		  rvals = my_tree_cons (basetype_path, rval, rvals);		  if (TYPE_BINFO_BASETYPES (type)		      && CLASSTYPE_BASELINK_VEC (type))		    TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);		}	      else		{		  /* Undo finding it before, as something else hides it. */		  rval = NULL_TREE;		  rvals = NULL_TREE;		}	      rval_binfo = binfo;	      rval_binfo_h = binfo_h;	    }	  else	    {	      /* This is ambiguous. */	      errstr = "request for method `%D' is ambiguous";	      rvals = error_mark_node;	      break;	    }	}    }  {    tree *tp = search_stack->first;    tree *search_tail = tp + tail;    while (tp < search_tail)      {	CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));	tp += 1;      }  }  search_stack = pop_search_level (search_stack);  if (entry)    {      if (errstr)

⌨️ 快捷键说明

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