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

📄 search.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	      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++];      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.  */      nval = lookup_field_1 (type, name);      if (nval || lookup_fnfields_here (type, name)>=0)	{	  if (nval && nval == rval && SHARED_MEMBER_P (nval))	    {	      /* This is ok, the member found is the same [class.ambig] */	    }	  else if (rval_binfo && 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 || hides (binfo_h, rval_binfo_h))	    {	      /* This is ok, the member found is here (binfo), not in		 rval_binfo.  */	      if (nval)		{		  rval = nval;		  if (entry || protect)		    this_v = compute_access (basetype_path, rval);		  /* These may look ambiguous, but they really are not.  */		  if (vbase_name_p)		    break;		}	      else		{		  /* Undo finding it before, as something else hides it.  */		  rval = NULL_TREE;		}	      rval_binfo = binfo;	      rval_binfo_h = binfo_h;	    }	  else	    {	      /* This is ambiguous.  */	      errstr = "request for member `%D' is ambiguous";	      protect += 2;	      break;	    }	}    }  {    tree *tp = search_stack->first;    tree *search_tail = tp + tail;    if (entry)      TREE_VALUE (entry) = rval;    if (rval_binfo)      {	type = BINFO_TYPE (rval_binfo);	if (rval)	  {	    if (want_type)	      {		if (TREE_CODE (rval) != TYPE_DECL)		  {		    rval = purpose_member (name, CLASSTYPE_TAGS (type));		    if (rval)		      rval = TYPE_MAIN_DECL (TREE_VALUE (rval));		  }	      }	    else	      {		if (TREE_CODE (rval) == TYPE_DECL		    && lookup_fnfields_here (type, name) >= 0)		  rval = NULL_TREE;	      }	  }      }    if (rval == NULL_TREE)      errstr = 0;    /* If this FIELD_DECL defines its own access level, deal with that.  */    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.  */	    tree new_v;	    if (this_v != access_default_node)	      new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);	    if (this_v != access_default_node && new_v != this_v)	      {		errstr = "conflicting access to member `%D'";		this_v = access_default_node;	      }	    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_node)	errstr = "member `%D' declared private";      else if (own_access == access_protected_node)	errstr = "member `%D' declared protected";      else if (this_v == access_private_node)	errstr = TREE_PRIVATE (rval)	  ? "member `%D' is private"	    : "member `%D' is from private base class";      else if (this_v == access_protected_node)	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 (protect == 2)    {      /* If we are not interested in ambiguities, don't report them,	 just return NULL_TREE.  */      rval = NULL_TREE;      protect = 0;    }  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.  */		      cp_error ("assignment to non-static member `%D' of enclosing class `%T'",				id, 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 /* GATHER_STATISTICS */      /* Constructors are first...  */      if (*methods && name == ctor_identifier)	return 0;      /* and destructors are second.  */      if (*++methods && name == dtor_identifier)	return 1;      while (++methods != end)	{#ifdef GATHER_STATISTICS	  n_outer_fields_searched++;#endif /* GATHER_STATISTICS */	  if (DECL_NAME (*methods) == name)	    break;	}      /* If we didn't find it, it might have been a template	 conversion operator.  (Note that we don't look for this case	 above so that we will always find specializations first.)  */      if (methods == end 	  && IDENTIFIER_TYPENAME_P (name)) 	{	  methods = &TREE_VEC_ELT (method_vec, 0) + 1;	  	  while (++methods != end)	    {	      if (TREE_CODE (*methods) == TEMPLATE_DECL 		  && IDENTIFIER_TYPENAME_P (DECL_NAME (*methods)))		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 a 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 idx = MEMOIZED_HASH_FN (name);  if (complain == -1)    {      find_all = 1;      protect = complain = 0;    }#if 0  /* We cannot search for constructor/destructor names like this.  */  /* This can't go here, but where should it go?  */  /* 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);#endif  binfo = basetype_path;  binfo_h = binfo;  type = complete_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), idx);      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 /* GATHER_STATISTICS */  if (protect && flag_memoize_lookups && ! global_bindings_p ())    entry = make_memoized_table_entry (type, name, 1);  else    entry = 0;  idx = lookup_fnfields_here (type, name);  if (idx >= 0 || lookup_field_1 (type, name))    {      rval_binfo = basetype_path;      rval_binfo_h = rval_binfo;    }  if (idx >= 0)    {      rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);      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), idx);      if (entry)

⌨️ 快捷键说明

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