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

📄 cp-tree.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
  TREE_VIA_VIRTUAL (t) = via_virtual;  hashcode = list_hash (t);  t = list_hash_canon (hashcode, t);  current_obstack = ambient_obstack;  return t;}/* Constructor for hashed lists.  */treehash_tree_chain (value, chain)     tree value, chain;{  struct obstack *ambient_obstack = current_obstack;  tree t;  int hashcode;  current_obstack = &class_obstack;  t = tree_cons (NULL_TREE, value, chain);  hashcode = list_hash (t);  t = list_hash_canon (hashcode, t);  current_obstack = ambient_obstack;  return t;}/* Similar, but used for concatenating two lists.  */treehash_chainon (list1, list2)     tree list1, list2;{  if (list2 == 0)    return list1;  if (list1 == 0)    return list2;  if (TREE_CHAIN (list1) == NULL_TREE)    return hash_tree_chain (TREE_VALUE (list1), list2);  return hash_tree_chain (TREE_VALUE (list1),			  hash_chainon (TREE_CHAIN (list1), list2));}treeget_decl_list (value)     tree value;{  tree list = NULL_TREE;  if (TREE_CODE (value) == IDENTIFIER_NODE)    {      list = IDENTIFIER_AS_LIST (value);      if (list != NULL_TREE	  && (TREE_CODE (list) != TREE_LIST	      || TREE_VALUE (list) != value))	list = NULL_TREE;      else if (IDENTIFIER_HAS_TYPE_VALUE (value)	       && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE)	{	  tree type = IDENTIFIER_TYPE_VALUE (value);	  if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE)	    CLASSTYPE_ID_AS_LIST (type) = perm_tree_cons (NULL_TREE, value, NULL_TREE);	  list = CLASSTYPE_ID_AS_LIST (type);	}    }  else if (TREE_CODE (value) == RECORD_TYPE	   && TYPE_LANG_SPECIFIC (value))    list = CLASSTYPE_AS_LIST (value);  if (list != NULL_TREE)    {      my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 301);      return list;    }  return build_decl_list (NULL_TREE, value);}/* Look in the type hash table for a type isomorphic to   `build_tree_list (NULL_TREE, VALUE)'.   If one is found, return it.  Otherwise return 0.  */treelist_hash_lookup_or_cons (value)     tree value;{  register int hashcode = TYPE_HASH (value);  register struct list_hash *h;  struct obstack *ambient_obstack;  tree list = NULL_TREE;  if (TREE_CODE (value) == IDENTIFIER_NODE)    {      list = IDENTIFIER_AS_LIST (value);      if (list != NULL_TREE	  && (TREE_CODE (list) != TREE_LIST	      || TREE_VALUE (list) != value))	list = NULL_TREE;      else if (IDENTIFIER_HAS_TYPE_VALUE (value)	       && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE)	{	  /* If the type name and constructor name are different, don't	     write constructor name into type.  */	  extern tree constructor_name ();	  if (IDENTIFIER_TYPEDECL_VALUE (value)	      && IDENTIFIER_TYPEDECL_VALUE (value) != constructor_name (value))	    list = tree_cons (NULL_TREE, value, NULL_TREE);	  else	    {	      tree type = IDENTIFIER_TYPE_VALUE (value);	      if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE)		CLASSTYPE_ID_AS_LIST (type) = perm_tree_cons (NULL_TREE, value,							      NULL_TREE);	      list = CLASSTYPE_ID_AS_LIST (type);	    }	}    }  else if (TREE_CODE (value) == TYPE_DECL	   && TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE	   && TYPE_LANG_SPECIFIC (TREE_TYPE (value)))    list = CLASSTYPE_ID_AS_LIST (TREE_TYPE (value));  else if (TREE_CODE (value) == RECORD_TYPE	   && TYPE_LANG_SPECIFIC (value))    list = CLASSTYPE_AS_LIST (value);  if (list != NULL_TREE)    {      my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 302);      return list;    }  if (debug_no_list_hash)    return hash_tree_chain (value, NULL_TREE);  for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)    if (h->hashcode == hashcode	&& TREE_VIA_VIRTUAL (h->list) == 0	&& TREE_VIA_PUBLIC (h->list) == 0	&& TREE_VIA_PROTECTED (h->list) == 0	&& TREE_PURPOSE (h->list) == 0	&& TREE_VALUE (h->list) == value)      {	my_friendly_assert (TREE_TYPE (h->list) == 0, 303);	my_friendly_assert (TREE_CHAIN (h->list) == 0, 304);	return h->list;      }  ambient_obstack = current_obstack;  current_obstack = &class_obstack;  list = build_tree_list (NULL_TREE, value);  list_hash_add (hashcode, list);  current_obstack = ambient_obstack;  return list;}/* Build an association between TYPE and some parameters:   OFFSET is the offset added to `this' to convert it to a pointer   of type `TYPE *'   VTABLE is the virtual function table with which to initialize   sub-objects of type TYPE.   VIRTUALS are the virtual functions sitting in VTABLE.   CHAIN are more associations we must retain.  */treemake_binfo (offset, type, vtable, virtuals, chain)     tree offset, type;     tree vtable, virtuals;     tree chain;{  tree binfo = make_tree_vec (6);  tree old_binfo = TYPE_BINFO (type);  tree last;  TREE_CHAIN (binfo) = chain;  if (chain)    TREE_USED (binfo) = TREE_USED (chain);  TREE_TYPE (binfo) = TYPE_MAIN_VARIANT (type);  BINFO_OFFSET (binfo) = offset;  BINFO_VTABLE (binfo) = vtable;  BINFO_VIRTUALS (binfo) = virtuals;  BINFO_VPTR_FIELD (binfo) = NULL_TREE;  last = binfo;  if (old_binfo != NULL_TREE      && BINFO_BASETYPES (old_binfo) != NULL_TREE)    {      int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (type);      tree binfos = TYPE_BINFO_BASETYPES (type);      BINFO_BASETYPES (binfo) = make_tree_vec (n_baseclasses);      for (i = 0; i < n_baseclasses; i++)	{	  tree base_binfo = TREE_VEC_ELT (binfos, i);	  tree old_base_binfo = old_binfo ? BINFO_BASETYPE (old_binfo, i) : 0;	  BINFO_BASETYPE (binfo, i) = base_binfo;	  if (old_binfo)	    {	      TREE_VIA_PUBLIC (base_binfo) = TREE_VIA_PUBLIC (old_base_binfo);	      TREE_VIA_PROTECTED (base_binfo) = TREE_VIA_PROTECTED (old_base_binfo);	      TREE_VIA_VIRTUAL (base_binfo) = TREE_VIA_VIRTUAL (old_base_binfo);	    }	}    }  return binfo;}treecopy_binfo (list)     tree list;{  tree binfo = copy_list (list);  tree rval = binfo;  while (binfo)    {      TREE_USED (binfo) = 0;      if (BINFO_BASETYPES (binfo))	BINFO_BASETYPES (binfo) = copy_node (BINFO_BASETYPES (binfo));      binfo = TREE_CHAIN (binfo);    }  return rval;}/* Return the binfo value for ELEM in TYPE.  Due to structure   sharing, we may find ELEM only in the association list   belonging to a basetype of TYPE.   COPYING is 0 if we just want an binfo value without needing   to modify it.   COPYING is 1 if we want the binfo value in order to modify it.   In this case, if we don't find ELEM immediately in the binfo   values of TYPE, we return a copy.   COPYING is -1 if we are called recursively and need a copy.   In this case we return a copy of ELEM at the point we find it.  */treebinfo_value (elem, type, copying)     tree elem;     tree type;     int copying;{  tree binfo = TYPE_BINFO (type);  tree last;  tree rval = NULL_TREE;  /* Dispose quickly of degenerate case.  */  if (elem == type)    return copying < 0 ? copy_binfo (binfo) : binfo;  /* Look for ELEM in two passes.  First pass checks the entire binfo list.     Second pass recursively searches the binfo lists of binfos.  */  while (binfo)    {      if (elem == BINFO_TYPE (binfo))	/* If we find it on the main spine, then	   there can be no ambiguity.  */	return copying < 0 ? copy_binfo (binfo) : binfo;      last = binfo;      binfo = TREE_CHAIN (binfo);    }  for (binfo = TYPE_BINFO (type);       binfo != TREE_CHAIN (last);       binfo = TREE_CHAIN (binfo))    {      /* ??? Should this condition instead test	 BINFO_TYPE (binfo) != TYPE_MAIN_VARIANT (type) ???  */      if (BINFO_TYPE (binfo) != TYPE_MAIN_VARIANT (type))	{	  tree nval = binfo_value (elem, BINFO_TYPE (binfo), copying ? -1 : 0);	  if (nval)	    {	      if (copying && rval == NULL_TREE)		chainon (TYPE_BINFO (type), nval);	      if (rval && BINFO_TYPE (rval) != BINFO_TYPE (nval))		/* If we find it underneath, we must make sure that		   there are no two ways to do it.  */		compiler_error ("base class `%s' ambiguous in binfo_value",				TYPE_NAME_STRING (elem));	      else		rval = nval;	    }	}    }  return rval;}treereverse_path (path)     tree path;{  register tree prev = 0, tmp, next;  for (tmp = path; tmp; tmp = next)    {      next = BINFO_INHERITANCE_CHAIN (tmp);      BINFO_INHERITANCE_CHAIN (tmp) = prev;      prev = tmp;    }  return prev;}treevirtual_member (elem, list)     tree elem;     tree list;{  tree t;  tree rval, nval;  for (t = list; t; t = TREE_CHAIN (t))    if (elem == BINFO_TYPE (t))      return t;  rval = 0;  for (t = list; t; t = TREE_CHAIN (t))    {      tree binfos = BINFO_BASETYPES (t);      int i;      if (binfos != NULL_TREE)	for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)	  {	    nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0);	    if (nval)	      {		if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))		  my_friendly_abort (104);		rval = nval;	      }	  }    }  return rval;}/* Return the offset (as an INTEGER_CST) for ELEM in LIST.   INITIAL_OFFSET is the value to add to the offset that ELEM's   binfo entry in LIST provides.   Returns NULL if ELEM does not have an binfo value in LIST.  */treevirtual_offset (elem, list, initial_offset)     tree elem;     tree list;     tree initial_offset;{  tree vb, offset;  tree rval, nval;  for (vb = list; vb; vb = TREE_CHAIN (vb))    if (elem == BINFO_TYPE (vb))      return size_binop (PLUS_EXPR, initial_offset, BINFO_OFFSET (vb));  rval = 0;  for (vb = list; vb; vb = TREE_CHAIN (vb))    {      tree binfos = BINFO_BASETYPES (vb);      int i;      if (binfos == NULL_TREE)	continue;      for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)	{	  nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0);	  if (nval)	    {	      if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))		my_friendly_abort (105);	      offset = BINFO_OFFSET (vb);	      rval = nval;	    }	}    }  if (rval == NULL_TREE)    return rval;  return size_binop (PLUS_EXPR, offset, BINFO_OFFSET (rval));}voiddebug_binfo (elem)     tree elem;{  int i;  tree virtuals;  fprintf (stderr, "type \"%s\"; offset = %d\n",	   TYPE_NAME_STRING (BINFO_TYPE (elem)),	   TREE_INT_CST_LOW (BINFO_OFFSET (elem)));  fprintf (stderr, "vtable type:\n");  debug_tree (BINFO_TYPE (elem));  if (BINFO_VTABLE (elem))    fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem))));  else    fprintf (stderr, "no vtable decl yet\n");  fprintf (stderr, "virtuals:\n");  virtuals = BINFO_VIRTUALS (elem);  if (virtuals != 0)    {      virtuals = TREE_CHAIN (virtuals);      if (flag_dossier)	virtuals = TREE_CHAIN (virtuals);    }  i = 1;  while (virtuals)    {      tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);      fprintf (stderr, "%s [%d =? %d]\n",	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)),	       i, TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));      virtuals = TREE_CHAIN (virtuals);      i += 1;    }}/* Return the length of a chain of nodes chained through DECL_CHAIN.   We expect a null pointer to mark the end of the chain.   This is the Lisp primitive `length'.  */intdecl_list_length (t)     tree t;{  register tree tail;  register int len = 0;  my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL, 300);  for (tail = t; tail; tail = DECL_CHAIN (tail))    len++;  return len;}treefnaddr_from_vtable_entry (entry)     tree entry;{  return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));}

⌨️ 快捷键说明

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