📄 tree.c
字号:
hash_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 { if (! CLASSTYPE_ID_AS_LIST (type)) CLASSTYPE_ID_AS_LIST (type) = perm_tree_cons (NULL_TREE, TYPE_IDENTIFIER (type), 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) && value == TYPE_MAIN_VARIANT (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);}/* 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;}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;}intis_overloaded_fn (x) tree x;{ if (TREE_CODE (x) == FUNCTION_DECL) return 1; if (TREE_CODE (x) == TEMPLATE_ID_EXPR) 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) == TEMPLATE_ID_EXPR) return 1; if (TREE_CODE (x) == TREE_LIST && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x)))) return 1; return 0;}treeget_first_fn (from) tree from;{ if (TREE_CODE (from) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (from)) return from; my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9); return TREE_VALUE (from);}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);}#define PRINT_RING_SIZE 4char *lang_printable_name (decl, v) tree decl; int v;{ static tree decl_ring[PRINT_RING_SIZE]; static char *print_ring[PRINT_RING_SIZE]; static int ring_counter; int i; /* Only cache functions. */ if (v < 2 || TREE_CODE (decl) != FUNCTION_DECL || DECL_LANG_SPECIFIC (decl) == 0) return lang_decl_name (decl, v); /* See if this print name is lying around. */ for (i = 0; i < PRINT_RING_SIZE; i++) if (decl_ring[i] == decl) /* yes, so return it. */ return print_ring[i]; if (++ring_counter == PRINT_RING_SIZE) ring_counter = 0; if (current_function_decl != NULL_TREE) { if (decl_ring[ring_counter] == current_function_decl) ring_counter += 1; if (ring_counter == PRINT_RING_SIZE) ring_counter = 0; if (decl_ring[ring_counter] == current_function_decl) my_friendly_abort (106); } if (print_ring[ring_counter]) free (print_ring[ring_counter]); print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v)); decl_ring[ring_counter] = decl; return print_ring[ring_counter];}/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions listed in RAISES. */treebuild_exception_variant (type, raises) tree type; tree raises;{ tree v = TYPE_MAIN_VARIANT (type); int constp = TYPE_READONLY (type); int volatilep = TYPE_VOLATILE (type); for (; v; v = TYPE_NEXT_VARIANT (v)) { if (TYPE_READONLY (v) != constp || TYPE_VOLATILE (v) != volatilep) continue; /* @@ This should do set equality, not exact match. */ if (simple_cst_list_equal (TYPE_RAISES_EXCEPTIONS (v), raises)) /* List of exceptions raised matches previously found list. @@ Nice to free up storage used in consing up the @@ list of exceptions raised. */ return v; } /* Need to build a new variant. */ v = build_type_copy (type); if (raises && ! TREE_PERMANENT (raises)) { push_obstacks_nochange (); end_temporary_allocation (); raises = copy_list (raises); pop_obstacks (); } TYPE_RAISES_EXCEPTIONS (v) = raises; return v;}/* Subroutine of copy_to_permanent Assuming T is a node build bottom-up, make it all exist on permanent obstack, if it is not permanent already. */treemapcar (t, func) tree t; tree (*func) PROTO((tree));{ tree tmp; if (t == NULL_TREE) return t; if (tmp = func (t), tmp != NULL_TREE) return tmp; switch (TREE_CODE (t)) { case ERROR_MARK: return error_mark_node; case VAR_DECL: case FUNCTION_DECL: case CONST_DECL: break; case PARM_DECL: { tree chain = TREE_CHAIN (t); t = copy_node (t); TREE_CHAIN (t) = mapcar (chain, func); TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); DECL_INITIAL (t) = mapcar (DECL_INITIAL (t), func); DECL_SIZE (t) = mapcar (DECL_SIZE (t), func); return t; } case TREE_LIST: { tree chain = TREE_CHAIN (t); t = copy_node (t); TREE_PURPOSE (t) = mapcar (TREE_PURPOSE (t), func); TREE_VALUE (t) = mapcar (TREE_VALUE (t), func); TREE_CHAIN (t) = mapcar (chain, func); return t; } case TREE_VEC: { int len = TREE_VEC_LENGTH (t); t = copy_node (t); while (len--) TREE_VEC_ELT (t, len) = mapcar (TREE_VEC_ELT (t, len), func); return t; } case INTEGER_CST: case REAL_CST: case STRING_CST: return copy_node (t); case COND_EXPR: case TARGET_EXPR: case NEW_EXPR: t = copy_node (t); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); return t; case SAVE_EXPR: t = copy_node (t); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); return t; case MODIFY_EXPR: case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR: case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: case MIN_EXPR: case MAX_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case BIT_AND_EXPR: case BIT_ANDTC_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case LT_EXPR: case LE_EXPR: case GT_EXPR: case GE_EXPR: case EQ_EXPR: case NE_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case CEIL_MOD_EXPR: case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: case COMPOUND_EXPR: case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: case ARRAY_REF: case SCOPE_REF: t = copy_node (t); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); return t; case CALL_EXPR: t = copy_node (t); TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); /* tree.def says that operand two is RTL, but build_call_declarator puts trees in there. */ if (TREE_OPERAND (t, 2) && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST) TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); else TREE_OPERAND (t, 2) = NULL_TREE; return t; case CONVERT_EXPR: case ADDR_EXPR: case INDIRECT_REF: case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: case NOP_EXPR: case COMPONENT_REF: t = copy_node (t); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); return t; case POINTER_TYPE: tmp = build_pointer_type (mapcar (TREE_TYPE (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case REFERENCE_TYPE: tmp = build_reference_type (mapcar (TREE_TYPE (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case FUNCTION_TYPE: tmp = build_function_type (mapcar (TREE_TYPE (t), func), mapcar (TYPE_ARG_TYPES (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case ARRAY_TYPE: tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func), mapcar (TYPE_DOMAIN (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case INTEGER_TYPE: tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case OFFSET_TYPE: tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func), mapcar (TREE_TYPE (t), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case METHOD_TYPE: tmp = build_cplus_method_type (mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func), mapcar (TREE_TYPE (t), func), mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func)); return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case COMPLEX_CST: t = copy_node (t); TREE_REALPART (t) = mapcar (TREE_REALPART (t), func); TREE_IMAGPART (t) = mapcar (TREE_REALPART (t), func);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -