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

📄 tree.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 4 页
字号:
  list_hash_table[hashcode % TYPE_HASH_SIZE] = h;}/* Given TYPE, and HASHCODE its hash code, return the canonical   object for an identical list if one already exists.   Otherwise, return TYPE, and record it as the canonical object   if it is a permanent object.   To use this function, first create a list of the sort you want.   Then compute its hash code from the fields of the list that   make it different from other similar lists.   Then call this function and use the value.   This function frees the list you pass in if it is a duplicate.  *//* Set to 1 to debug without canonicalization.  Never set by program.  */static int debug_no_list_hash = 0;treelist_hash_canon (hashcode, list)     int hashcode;     tree list;{  tree t1;  if (debug_no_list_hash)    return list;  t1 = list_hash_lookup (hashcode, list);  if (t1 != 0)    {      obstack_free (&class_obstack, list);      return t1;    }  /* If this is a new list, record it for later reuse.  */  list_hash_add (hashcode, list);  return list;}treehash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)     int via_public, via_virtual, via_protected;     tree purpose, value, chain;{  struct obstack *ambient_obstack = current_obstack;  tree t;  int hashcode;  current_obstack = &class_obstack;  t = tree_cons (purpose, value, chain);  TREE_VIA_PUBLIC (t) = via_public;  TREE_VIA_PROTECTED (t) = via_protected;  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));}static treeget_identifier_list (value)     tree value;{  tree 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	   && IDENTIFIER_TYPE_VALUE (value)	      == TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (value)))    {      tree type = IDENTIFIER_TYPE_VALUE (value);      if (TYPE_PTRMEMFUNC_P (type))	list = NULL_TREE;      else if (type == current_class_type)	/* Don't mess up the constructor name.  */	list = tree_cons (NULL_TREE, value, NULL_TREE);      else	{	  register tree id;	  /* This will return the correct thing for regular types,	     nested types, and templates.  Yay! */	  if (TYPE_NESTED_NAME (type))	    id = TYPE_NESTED_NAME (type);	  else	    id = TYPE_IDENTIFIER (type);	  if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE)	    CLASSTYPE_ID_AS_LIST (type)	      = perm_tree_cons (NULL_TREE, id, NULL_TREE);	  list = CLASSTYPE_ID_AS_LIST (type);	}    }  return list;}treeget_decl_list (value)     tree value;{  tree list = NULL_TREE;  if (TREE_CODE (value) == IDENTIFIER_NODE)    list = get_identifier_list (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, 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 = get_identifier_list (value);  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 *'   BINFO is the base binfo to use, if we are deriving from one.  This   is necessary, as we want specialized parent binfos from base   classes, so that the VTABLE_NAMEs of bases are for the most derived   type, instead of of the simple 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, binfo, vtable, virtuals, chain)     tree offset, binfo;     tree vtable, virtuals;     tree chain;{  tree new_binfo = make_tree_vec (6);  tree type;  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else    {      type = binfo;      binfo = TYPE_BINFO (binfo);    }  TREE_CHAIN (new_binfo) = chain;  if (chain)    TREE_USED (new_binfo) = TREE_USED (chain);  TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);  BINFO_OFFSET (new_binfo) = offset;  BINFO_VTABLE (new_binfo) = vtable;  BINFO_VIRTUALS (new_binfo) = virtuals;  BINFO_VPTR_FIELD (new_binfo) = NULL_TREE;  if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)    BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));        return new_binfo;}/* Return the binfo value for ELEM in TYPE.  */treebinfo_value (elem, type)     tree elem;     tree type;{  if (get_base_distance (elem, type, 0, (tree *)0) == -2)    compiler_error ("base class `%s' ambiguous in binfo_value",		    TYPE_NAME_STRING (elem));  if (elem == type)    return TYPE_BINFO (type);  if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type)    return type;  return get_binfo (elem, type, 0);}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)));	    if (nval)	      {		if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))		  my_friendly_abort (104);		rval = nval;	      }	  }    }  return rval;}voiddebug_binfo (elem)     tree elem;{  unsigned HOST_WIDE_INT n;  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);  n = skip_rtti_stuff (&virtuals);  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)),	       n, TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));      ++n;      virtuals = TREE_CHAIN (virtuals);    }}/* 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		      || TREE_CODE (t) == TEMPLATE_DECL, 300);  for (tail = t; tail; tail = DECL_CHAIN (tail))    len++;  return len;}intcount_functions (t)     tree t;{  if (TREE_CODE (t) == FUNCTION_DECL)    return 1;  else if (TREE_CODE (t) == TREE_LIST)    return decl_list_length (TREE_VALUE (t));  my_friendly_abort (359);  return 0;}/* Like value_member, but for DECL_CHAINs.  */treedecl_value_member (elem, list)     tree elem, list;{  while (list)    {      if (elem == list)	return list;      list = DECL_CHAIN (list);    }  return NULL_TREE;}intis_overloaded_fn (x)     tree x;{  if (TREE_CODE (x) == FUNCTION_DECL)    return 1;  if (TREE_CODE (x) == TREE_LIST      && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL	  || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))    return 1;  return 0;}intreally_overloaded_fn (x)     tree x;{       if (TREE_CODE (x) == TREE_LIST      && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL	  || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))    return 1;  return 0;}treeget_first_fn (from)     tree from;{  if (TREE_CODE (from) == FUNCTION_DECL)    return from;  my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9);    return TREE_VALUE (from);}treefnaddr_from_vtable_entry (entry)     tree entry;{  if (flag_vtable_thunks)    {      tree func = entry;      if (TREE_CODE (func) == ADDR_EXPR)	func = TREE_OPERAND (func, 0);      if (TREE_CODE (func) == THUNK_DECL)	return DECL_INITIAL (func);      else	return entry;    }  else    return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));}voidset_fnaddr_from_vtable_entry (entry, value)     tree entry, value;{  if (flag_vtable_thunks)    abort ();  else  TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry)))) = value;}treefunction_arg_chain (t)     tree t;{  return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t)));}intpromotes_to_aggr_type (t, code)     tree t;     enum tree_code code;{  if (TREE_CODE (t) == code)    t = TREE_TYPE (t);  return IS_AGGR_TYPE (t);}intis_aggr_type_2 (t1, t2)     tree t1, t2;{  if (TREE_CODE (t1) != TREE_CODE (t2))    return 0;  return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);}/* Give message using types TYPE1 and TYPE2 as arguments.   PFN is the function which will print the message;   S is the format string for PFN to use.  */voidmessage_2_types (pfn, s, type1, type2)     void (*pfn) ();     char *s;     tree type1, type2;{  tree name1 = TYPE_NAME (type1);

⌨️ 快捷键说明

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