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

📄 tree.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* All BLOCK nodes are put where we can preserve them if nec.  */      if (obstack != &permanent_obstack)	obstack = saveable_obstack;      break;    case 's':  /* an expression with side effects */#ifdef GATHER_STATISTICS      kind = s_kind;      goto usual_kind;#endif    case 'r':  /* a reference */#ifdef GATHER_STATISTICS      kind = r_kind;      goto usual_kind;#endif    case 'e':  /* an expression */    case '<':  /* a comparison expression */    case '1':  /* a unary arithmetic expression */    case '2':  /* a binary arithmetic expression */#ifdef GATHER_STATISTICS      kind = e_kind;    usual_kind:#endif      obstack = expression_obstack;      /* All BIND_EXPR nodes are put where we can preserve them if nec.  */      if (code == BIND_EXPR && obstack != &permanent_obstack)	obstack = saveable_obstack;      length = sizeof (struct tree_exp)	+ (tree_code_length[(int) code] - 1) * sizeof (char *);      break;    case 'c':  /* a constant */#ifdef GATHER_STATISTICS      kind = c_kind;#endif      obstack = expression_obstack;      /* We can't use tree_code_length for INTEGER_CST, since the number of	 words is machine-dependent due to varying length of HOST_WIDE_INT,	 which might be wider than a pointer (e.g., long long).  Similarly	 for REAL_CST, since the number of words is machine-dependent due	 to varying size and alignment of `double'.  */      if (code == INTEGER_CST)	length = sizeof (struct tree_int_cst);      else if (code == REAL_CST)	length = sizeof (struct tree_real_cst);      else	length = sizeof (struct tree_common)	  + tree_code_length[(int) code] * sizeof (char *);      break;    case 'x':  /* something random, like an identifier.  */#ifdef GATHER_STATISTICS      if (code == IDENTIFIER_NODE)	kind = id_kind;      else if (code == OP_IDENTIFIER)	kind = op_id_kind;      else if (code == TREE_VEC)	kind = vec_kind;      else	kind = x_kind;#endif      length = sizeof (struct tree_common)	+ tree_code_length[(int) code] * sizeof (char *);      /* Identifier nodes are always permanent since they are	 unique in a compiler run.  */      if (code == IDENTIFIER_NODE) obstack = &permanent_obstack;      break;    default:      abort ();    }  t = (tree) obstack_alloc (obstack, length);#ifdef GATHER_STATISTICS  tree_node_counts[(int)kind]++;  tree_node_sizes[(int)kind] += length;#endif  /* Clear a word at a time.  */  for (i = (length / sizeof (int)) - 1; i >= 0; i--)    ((int *) t)[i] = 0;  /* Clear any extra bytes.  */  for (i = length / sizeof (int) * sizeof (int); i < length; i++)    ((char *) t)[i] = 0;  TREE_SET_CODE (t, code);  if (obstack == &permanent_obstack)    TREE_PERMANENT (t) = 1;  switch (type)    {    case 's':      TREE_SIDE_EFFECTS (t) = 1;      TREE_TYPE (t) = void_type_node;      break;    case 'd':      if (code != FUNCTION_DECL)	DECL_ALIGN (t) = 1;      DECL_IN_SYSTEM_HEADER (t)	= in_system_header && (obstack == &permanent_obstack);      DECL_SOURCE_LINE (t) = lineno;      DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";      DECL_UID (t) = next_decl_uid++;      break;    case 't':      TYPE_UID (t) = next_type_uid++;      TYPE_ALIGN (t) = 1;      TYPE_MAIN_VARIANT (t) = t;      TYPE_OBSTACK (t) = obstack;      TYPE_ATTRIBUTES (t) = NULL_TREE;#ifdef SET_DEFAULT_TYPE_ATTRIBUTES      SET_DEFAULT_TYPE_ATTRIBUTES (t);#endif      break;    case 'c':      TREE_CONSTANT (t) = 1;      break;    }  return t;}/* Return a new node with the same contents as NODE   except that its TREE_CHAIN is zero and it has a fresh uid.  */treecopy_node (node)     tree node;{  register tree t;  register enum tree_code code = TREE_CODE (node);  register int length;  register int i;  switch (TREE_CODE_CLASS (code))    {    case 'd':  /* A decl node */      length = sizeof (struct tree_decl);      break;    case 't':  /* a type node */      length = sizeof (struct tree_type);      break;    case 'b':  /* a lexical block node */      length = sizeof (struct tree_block);      break;    case 'r':  /* a reference */    case 'e':  /* an expression */    case 's':  /* an expression with side effects */    case '<':  /* a comparison expression */    case '1':  /* a unary arithmetic expression */    case '2':  /* a binary arithmetic expression */      length = sizeof (struct tree_exp)	+ (tree_code_length[(int) code] - 1) * sizeof (char *);      break;    case 'c':  /* a constant */      /* We can't use tree_code_length for INTEGER_CST, since the number of	 words is machine-dependent due to varying length of HOST_WIDE_INT,	 which might be wider than a pointer (e.g., long long).  Similarly	 for REAL_CST, since the number of words is machine-dependent due	 to varying size and alignment of `double'.  */      if (code == INTEGER_CST)        {          length = sizeof (struct tree_int_cst);          break;        }      else if (code == REAL_CST)	{	  length = sizeof (struct tree_real_cst);	  break;	}    case 'x':  /* something random, like an identifier.  */      length = sizeof (struct tree_common)	+ tree_code_length[(int) code] * sizeof (char *);      if (code == TREE_VEC)	length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);    }  t = (tree) obstack_alloc (current_obstack, length);  for (i = (length / sizeof (int)) - 1; i >= 0; i--)    ((int *) t)[i] = ((int *) node)[i];  /* Clear any extra bytes.  */  for (i = length / sizeof (int) * sizeof (int); i < length; i++)    ((char *) t)[i] = ((char *) node)[i];  TREE_CHAIN (t) = 0;  if (TREE_CODE_CLASS (code) == 'd')    DECL_UID (t) = next_decl_uid++;  else if (TREE_CODE_CLASS (code) == 't')    {      TYPE_UID (t) = next_type_uid++;      TYPE_OBSTACK (t) = current_obstack;    }  TREE_PERMANENT (t) = (current_obstack == &permanent_obstack);  return t;}/* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.   For example, this can copy a list made of TREE_LIST nodes.  */treecopy_list (list)     tree list;{  tree head;  register tree prev, next;  if (list == 0)    return 0;  head = prev = copy_node (list);  next = TREE_CHAIN (list);  while (next)    {      TREE_CHAIN (prev) = copy_node (next);      prev = TREE_CHAIN (prev);      next = TREE_CHAIN (next);    }  return head;}#define HASHBITS 30/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).   If an identifier with that name has previously been referred to,   the same node is returned this time.  */treeget_identifier (text)     register char *text;{  register int hi;  register int i;  register tree idp;  register int len, hash_len;  /* Compute length of text in len.  */  for (len = 0; text[len]; len++);  /* Decide how much of that length to hash on */  hash_len = len;  if (warn_id_clash && len > id_clash_len)    hash_len = id_clash_len;  /* Compute hash code */  hi = hash_len * 613 + (unsigned)text[0];  for (i = 1; i < hash_len; i += 2)    hi = ((hi * 613) + (unsigned)(text[i]));  hi &= (1 << HASHBITS) - 1;  hi %= MAX_HASH_TABLE;    /* Search table for identifier */  for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))    if (IDENTIFIER_LENGTH (idp) == len	&& IDENTIFIER_POINTER (idp)[0] == text[0]	&& !bcmp (IDENTIFIER_POINTER (idp), text, len))      return idp;		/* <-- return if found */  /* Not found; optionally warn about a similar identifier */  if (warn_id_clash && do_identifier_warnings && len >= id_clash_len)    for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))      if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))	{	  warning ("`%s' and `%s' identical in first %d characters",		   IDENTIFIER_POINTER (idp), text, id_clash_len);	  break;	}  if (tree_code_length[(int) IDENTIFIER_NODE] < 0)    abort ();			/* set_identifier_size hasn't been called.  */  /* Not found, create one, add to chain */  idp = make_node (IDENTIFIER_NODE);  IDENTIFIER_LENGTH (idp) = len;#ifdef GATHER_STATISTICS  id_string_size += len;#endif  IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len);  TREE_CHAIN (idp) = hash_table[hi];  hash_table[hi] = idp;  return idp;			/* <-- return if created */}/* Enable warnings on similar identifiers (if requested).   Done after the built-in identifiers are created.  */voidstart_identifier_warnings (){  do_identifier_warnings = 1;}/* Record the size of an identifier node for the language in use.   SIZE is the total size in bytes.   This is called by the language-specific files.  This must be   called before allocating any identifiers.  */voidset_identifier_size (size)     int size;{  tree_code_length[(int) IDENTIFIER_NODE]    = (size - sizeof (struct tree_common)) / sizeof (tree);}/* Return a newly constructed INTEGER_CST node whose constant value   is specified by the two ints LOW and HI.   The TREE_TYPE is set to `int'.    This function should be used via the `build_int_2' macro.  */treebuild_int_2_wide (low, hi)     HOST_WIDE_INT low, hi;{  register tree t = make_node (INTEGER_CST);  TREE_INT_CST_LOW (t) = low;  TREE_INT_CST_HIGH (t) = hi;  TREE_TYPE (t) = integer_type_node;  return t;}/* Return a new REAL_CST node whose type is TYPE and value is D.  */treebuild_real (type, d)     tree type;     REAL_VALUE_TYPE d;{  tree v;  int overflow = 0;  /* Check for valid float value for this type on this target machine;     if not, can print error message and store a valid value in D.  */#ifdef CHECK_FLOAT_VALUE  CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);#endif  v = make_node (REAL_CST);  TREE_TYPE (v) = type;  TREE_REAL_CST (v) = d;  TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow;  return v;}/* Return a new REAL_CST node whose type is TYPE   and whose value is the integer value of the INTEGER_CST node I.  */#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)REAL_VALUE_TYPEreal_value_from_int_cst (i)     tree i;{  REAL_VALUE_TYPE d;  REAL_VALUE_TYPE e;  /* Some 386 compilers mishandle unsigned int to float conversions,     so introduce a temporary variable E to avoid those bugs.  */#ifdef REAL_ARITHMETIC  if (! TREE_UNSIGNED (TREE_TYPE (i)))    REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));  else    REAL_VALUE_FROM_UNSIGNED_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));#else /* not REAL_ARITHMETIC */  if (TREE_INT_CST_HIGH (i) < 0 && ! TREE_UNSIGNED (TREE_TYPE (i)))    {      d = (double) (~ TREE_INT_CST_HIGH (i));      e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))	    * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));      d *= e;      e = (double) (unsigned HOST_WIDE_INT) (~ TREE_INT_CST_LOW (i));      d += e;      d = (- d - 1.0);    }  else    {      d = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (i);      e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))	    * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));      d *= e;      e = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (i);      d += e;    }#endif /* not REAL_ARITHMETIC */  return d;}/* This function can't be implemented if we can't do arithmetic   on the float representation.  */treebuild_real_from_int_cst (type, i)     tree type;     tree i;{  tree v;  int overflow = TREE_OVERFLOW (i);  REAL_VALUE_TYPE d;  jmp_buf float_error;  v = make_node (REAL_CST);  TREE_TYPE (v) = type;  if (setjmp (float_error))    {      d = dconst0;      overflow = 1;      goto got_it;    }  set_float_handler (float_error);  d = REAL_VALUE_TRUNCATE (TYPE_MODE (type), real_value_from_int_cst (i));  /* Check for valid float value for this type on this target machine.  */ got_it:  set_float_handler (NULL_PTR);#ifdef CHECK_FLOAT_VALUE  CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);#endif  TREE_REAL_CST (v) = d;  TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow;  return v;}#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC *//* Return a newly constructed STRING_CST node whose value is   the LEN characters at STR.   The TREE_TYPE is not initialized.  */treebuild_string (len, str)     int len;     char *str;{  /* Put the string in saveable_obstack since it will be placed in the RTL     for an "asm" statement and will also be kept around a while if     deferring constant output in varasm.c.  */  register tree s = make_node (STRING_CST);  TREE_STRING_LENGTH (s) = len;  TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);  return s;}/* Return a newly constructed COMPLEX_CST node whose value is   specified by the real and imaginary parts REAL and IMAG.   Both REAL and IMAG should be constant nodes.   The TREE_TYPE is not initialized.  */treebuild_complex (real, imag)     tree real, imag;{  register tree t = make_node (COMPLEX_CST);  TREE_REALPART (t) = real;  TREE_IMAGPART (t) = imag;

⌨️ 快捷键说明

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