📄 tree.c
字号:
TREE_TYPE (t) = build_complex_type (TREE_TYPE (real)); TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag); TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (real) | TREE_CONSTANT_OVERFLOW (imag); return t;}/* Build a newly constructed TREE_VEC node of length LEN. */treemake_tree_vec (len) int len;{ register tree t; register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec); register struct obstack *obstack = current_obstack; register int i;#ifdef GATHER_STATISTICS tree_node_counts[(int)vec_kind]++; tree_node_sizes[(int)vec_kind] += length;#endif t = (tree) obstack_alloc (obstack, length); for (i = (length / sizeof (int)) - 1; i >= 0; i--) ((int *) t)[i] = 0; TREE_SET_CODE (t, TREE_VEC); TREE_VEC_LENGTH (t) = len; if (obstack == &permanent_obstack) TREE_PERMANENT (t) = 1; return t;}/* Return 1 if EXPR is the integer constant zero or a complex constant of zero. */intinteger_zerop (expr) tree expr;{ STRIP_NOPS (expr); return ((TREE_CODE (expr) == INTEGER_CST && TREE_INT_CST_LOW (expr) == 0 && TREE_INT_CST_HIGH (expr) == 0) || (TREE_CODE (expr) == COMPLEX_CST && integer_zerop (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))));}/* Return 1 if EXPR is the integer constant one or the corresponding complex constant. */intinteger_onep (expr) tree expr;{ STRIP_NOPS (expr); return ((TREE_CODE (expr) == INTEGER_CST && TREE_INT_CST_LOW (expr) == 1 && TREE_INT_CST_HIGH (expr) == 0) || (TREE_CODE (expr) == COMPLEX_CST && integer_onep (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))));}/* Return 1 if EXPR is an integer containing all 1's in as much precision as it contains. Likewise for the corresponding complex constant. */intinteger_all_onesp (expr) tree expr;{ register int prec; register int uns; STRIP_NOPS (expr); if (TREE_CODE (expr) == COMPLEX_CST && integer_all_onesp (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))) return 1; else if (TREE_CODE (expr) != INTEGER_CST) return 0; uns = TREE_UNSIGNED (TREE_TYPE (expr)); if (!uns) return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == -1; /* Note that using TYPE_PRECISION here is wrong. We care about the actual bits, not the (arbitrary) range of the type. */ prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))); if (prec >= HOST_BITS_PER_WIDE_INT) { int high_value, shift_amount; shift_amount = prec - HOST_BITS_PER_WIDE_INT; if (shift_amount > HOST_BITS_PER_WIDE_INT) /* Can not handle precisions greater than twice the host int size. */ abort (); else if (shift_amount == HOST_BITS_PER_WIDE_INT) /* Shifting by the host word size is undefined according to the ANSI standard, so we must handle this as a special case. */ high_value = -1; else high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1; return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == high_value; } else return TREE_INT_CST_LOW (expr) == ((HOST_WIDE_INT) 1 << prec) - 1;}/* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only one bit on). */intinteger_pow2p (expr) tree expr;{ HOST_WIDE_INT high, low; STRIP_NOPS (expr); if (TREE_CODE (expr) == COMPLEX_CST && integer_pow2p (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))) return 1; if (TREE_CODE (expr) != INTEGER_CST) return 0; high = TREE_INT_CST_HIGH (expr); low = TREE_INT_CST_LOW (expr); if (high == 0 && low == 0) return 0; return ((high == 0 && (low & (low - 1)) == 0) || (low == 0 && (high & (high - 1)) == 0));}/* Return 1 if EXPR is the real constant zero. */intreal_zerop (expr) tree expr;{ STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)) || (TREE_CODE (expr) == COMPLEX_CST && real_zerop (TREE_REALPART (expr)) && real_zerop (TREE_IMAGPART (expr))));}/* Return 1 if EXPR is the real constant one in real or complex form. */intreal_onep (expr) tree expr;{ STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)) || (TREE_CODE (expr) == COMPLEX_CST && real_onep (TREE_REALPART (expr)) && real_zerop (TREE_IMAGPART (expr))));}/* Return 1 if EXPR is the real constant two. */intreal_twop (expr) tree expr;{ STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)) || (TREE_CODE (expr) == COMPLEX_CST && real_twop (TREE_REALPART (expr)) && real_zerop (TREE_IMAGPART (expr))));}/* Nonzero if EXP is a constant or a cast of a constant. */ intreally_constant_p (exp) tree exp;{ /* This is not quite the same as STRIP_NOPS. It does more. */ while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR || TREE_CODE (exp) == NON_LVALUE_EXPR) exp = TREE_OPERAND (exp, 0); return TREE_CONSTANT (exp);}/* Return first list element whose TREE_VALUE is ELEM. Return 0 if ELEM is not in LIST. */treevalue_member (elem, list) tree elem, list;{ while (list) { if (elem == TREE_VALUE (list)) return list; list = TREE_CHAIN (list); } return NULL_TREE;}/* Return first list element whose TREE_PURPOSE is ELEM. Return 0 if ELEM is not in LIST. */treepurpose_member (elem, list) tree elem, list;{ while (list) { if (elem == TREE_PURPOSE (list)) return list; list = TREE_CHAIN (list); } return NULL_TREE;}/* Return first list element whose BINFO_TYPE is ELEM. Return 0 if ELEM is not in LIST. */treebinfo_member (elem, list) tree elem, list;{ while (list) { if (elem == BINFO_TYPE (list)) return list; list = TREE_CHAIN (list); } return NULL_TREE;}/* Return nonzero if ELEM is part of the chain CHAIN. */intchain_member (elem, chain) tree elem, chain;{ while (chain) { if (elem == chain) return 1; chain = TREE_CHAIN (chain); } return 0;}/* Return nonzero if ELEM is equal to TREE_VALUE (CHAIN) for any piece of chain CHAIN. *//* ??? This function was added for machine specific attributes but is no longer used. It could be deleted if we could confirm all front ends don't use it. */intchain_member_value (elem, chain) tree elem, chain;{ while (chain) { if (elem == TREE_VALUE (chain)) return 1; chain = TREE_CHAIN (chain); } return 0;}/* Return nonzero if ELEM is equal to TREE_PURPOSE (CHAIN) for any piece of chain CHAIN. *//* ??? This function was added for machine specific attributes but is no longer used. It could be deleted if we could confirm all front ends don't use it. */intchain_member_purpose (elem, chain) tree elem, chain;{ while (chain) { if (elem == TREE_PURPOSE (chain)) return 1; chain = TREE_CHAIN (chain); } return 0;}/* Return the length of a chain of nodes chained through TREE_CHAIN. We expect a null pointer to mark the end of the chain. This is the Lisp primitive `length'. */intlist_length (t) tree t;{ register tree tail; register int len = 0; for (tail = t; tail; tail = TREE_CHAIN (tail)) len++; return len;}/* Concatenate two chains of nodes (chained through TREE_CHAIN) by modifying the last node in chain 1 to point to chain 2. This is the Lisp primitive `nconc'. */treechainon (op1, op2) tree op1, op2;{ if (op1) { register tree t1; register tree t2; for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1)) ; TREE_CHAIN (t1) = op2; for (t2 = op2; t2; t2 = TREE_CHAIN (t2)) if (t2 == t1) abort (); /* Circularity created. */ return op1; } else return op2;}/* Return the last node in a chain of nodes (chained through TREE_CHAIN). */treetree_last (chain) register tree chain;{ register tree next; if (chain) while (next = TREE_CHAIN (chain)) chain = next; return chain;}/* Reverse the order of elements in the chain T, and return the new head of the chain (old last element). */treenreverse (t) tree t;{ register tree prev = 0, decl, next; for (decl = t; decl; decl = next) { next = TREE_CHAIN (decl); TREE_CHAIN (decl) = prev; prev = decl; } return prev;}/* Given a chain CHAIN of tree nodes, construct and return a list of those nodes. */treelistify (chain) tree chain;{ tree result = NULL_TREE; tree in_tail = chain; tree out_tail = NULL_TREE; while (in_tail) { tree next = tree_cons (NULL_TREE, in_tail, NULL_TREE); if (out_tail) TREE_CHAIN (out_tail) = next; else result = next; out_tail = next; in_tail = TREE_CHAIN (in_tail); } return result;}/* Return a newly created TREE_LIST node whose purpose and value fields are PARM and VALUE. */treebuild_tree_list (parm, value) tree parm, value;{ register tree t = make_node (TREE_LIST); TREE_PURPOSE (t) = parm; TREE_VALUE (t) = value; return t;}/* Similar, but build on the temp_decl_obstack. */treebuild_decl_list (parm, value) tree parm, value;{ register tree node; register struct obstack *ambient_obstack = current_obstack; current_obstack = &temp_decl_obstack; node = build_tree_list (parm, value); current_obstack = ambient_obstack; return node;}/* Return a newly created TREE_LIST node whose purpose and value fields are PARM and VALUE and whose TREE_CHAIN is CHAIN. */treetree_cons (purpose, value, chain) tree purpose, value, chain;{#if 0 register tree node = make_node (TREE_LIST);#else register int i; register tree node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));#ifdef GATHER_STATISTICS tree_node_counts[(int)x_kind]++; tree_node_sizes[(int)x_kind] += sizeof (struct tree_list);#endif for (i = (sizeof (struct tree_common) / sizeof (int)) - 1; i >= 0; i--) ((int *) node)[i] = 0; TREE_SET_CODE (node, TREE_LIST); if (current_obstack == &permanent_obstack) TREE_PERMANENT (node) = 1;#endif TREE_CHAIN (node) = chain; TREE_PURPOSE (node) = purpose; TREE_VALUE (node) = value; return node;}/* Similar, but build on the temp_decl_obstack. */treedecl_tree_cons (purpose, value, chain) tree purpose, value, chain;{ register tree node; register struct obstack *ambient_obstack = current_obstack; current_obstack = &temp_decl_obstack; node = tree_cons (purpose, value, chain); current_obstack = ambient_obstack; return node;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -