📄 cp-tree.c
字号:
voidset_fnaddr_from_vtable_entry (entry, value) tree entry, value;{ 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); tree name2 = TYPE_NAME (type2); if (TREE_CODE (name1) == TYPE_DECL) name1 = DECL_NAME (name1); if (TREE_CODE (name2) == TYPE_DECL) name2 = DECL_NAME (name2); (*pfn) (s, IDENTIFIER_POINTER (name1), IDENTIFIER_POINTER (name2));}#define PRINT_RING_SIZE 4char *lang_printable_name (decl) tree decl;{ static tree decl_ring[PRINT_RING_SIZE]; static char *print_ring[PRINT_RING_SIZE]; static int ring_counter; int i; if (TREE_CODE (decl) != FUNCTION_DECL || DECL_LANG_SPECIFIC (decl) == 0) { if (DECL_NAME (decl)) { if (THIS_NAME_P (DECL_NAME (decl))) return "this"; return IDENTIFIER_POINTER (DECL_NAME (decl)); } return "((anonymous))"; } /* 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]); { int print_ret_type_p = (!DECL_CONSTRUCTOR_P (decl) && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))); char *name = (char *)fndecl_as_string (0, decl, print_ret_type_p); print_ring[ring_counter] = (char *)malloc (strlen (name) + 1); strcpy (print_ring[ring_counter], name); decl_ring[ring_counter] = decl; } return print_ring[ring_counter];}/* Comparison function for sorting identifiers in RAISES lists. Note that because IDENTIFIER_NODEs are unique, we can sort them by address, saving an indirection. */static intid_cmp (p1, p2) tree *p1, *p2;{ return (HOST_WIDE_INT)TREE_VALUE (*p1) - (HOST_WIDE_INT)TREE_VALUE (*p2);}/* Build the FUNCTION_TYPE or METHOD_TYPE which may raise exceptions listed in RAISES. */treebuild_exception_variant (ctype, type, raises) tree ctype, type; tree raises;{ int i; tree v = TYPE_MAIN_VARIANT (type); tree t, t2, cname; tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree)); int constp = TYPE_READONLY (type); int volatilep = TYPE_VOLATILE (type); if (raises && TREE_CHAIN (raises)) { for (i = 0, t = raises; t; t = TREE_CHAIN (t), i++) a[i] = t; /* NULL terminator for list. */ a[i] = NULL_TREE; qsort (a, i, sizeof (tree), id_cmp); while (i--) TREE_CHAIN (a[i]) = a[i+1]; raises = a[0]; } else if (raises) /* do nothing. */; else return build_type_variant (v, constp, volatilep); if (ctype) { cname = TYPE_NAME (ctype); if (TREE_CODE (cname) == TYPE_DECL) cname = DECL_NAME (cname); } else cname = NULL_TREE; for (t = raises; t; t = TREE_CHAIN (t)) { /* See that all the exceptions we are thinking about raising have been declared. */ tree this_cname = lookup_exception_cname (ctype, cname, t); tree decl = lookup_exception_object (this_cname, TREE_VALUE (t), 1); if (decl == NULL_TREE) decl = lookup_exception_object (this_cname, TREE_VALUE (t), 0); /* Place canonical exception decl into TREE_TYPE of RAISES list. */ TREE_TYPE (t) = decl; } for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v)) { if (TYPE_READONLY (v) != constp || TYPE_VOLATILE (v) != volatilep) continue; t = raises; t2 = TYPE_RAISES_EXCEPTIONS (v); while (t && t2) { if (TREE_TYPE (t) == TREE_TYPE (t2)) { t = TREE_CHAIN (t); t2 = TREE_CHAIN (t2); } else break; } if (t || t2) continue; /* 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 = copy_node (type); TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type); TYPE_NEXT_VARIANT (type) = v; 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. */static treemake_deep_copy (t) tree t;{ enum tree_code code; if (t == NULL_TREE || TREE_PERMANENT (t)) return t; switch (code = 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) = make_deep_copy (chain); TREE_TYPE (t) = make_deep_copy (TREE_TYPE (t)); DECL_INITIAL (t) = make_deep_copy (DECL_INITIAL (t)); DECL_SIZE (t) = make_deep_copy (DECL_SIZE (t)); return t; } case TREE_LIST: { tree chain = TREE_CHAIN (t); t = copy_node (t); TREE_PURPOSE (t) = make_deep_copy (TREE_PURPOSE (t)); TREE_VALUE (t) = make_deep_copy (TREE_VALUE (t)); TREE_CHAIN (t) = make_deep_copy (chain); return t; } case TREE_VEC: { int len = TREE_VEC_LENGTH (t); t = copy_node (t); while (len--) TREE_VEC_ELT (t, len) = make_deep_copy (TREE_VEC_ELT (t, len)); 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) = make_deep_copy (TREE_OPERAND (t, 0)); TREE_OPERAND (t, 1) = make_deep_copy (TREE_OPERAND (t, 1)); TREE_OPERAND (t, 2) = make_deep_copy (TREE_OPERAND (t, 2)); return t; case SAVE_EXPR: t = copy_node (t); TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0)); 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 CALL_EXPR: t = copy_node (t); TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0)); TREE_OPERAND (t, 1) = make_deep_copy (TREE_OPERAND (t, 1)); 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) = make_deep_copy (TREE_OPERAND (t, 0)); return t; /* This list is incomplete, but should suffice for now. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */ default: sorry ("initializer contains unrecognized tree code"); return error_mark_node; } my_friendly_abort (107); /* NOTREACHED */ return NULL_TREE;}/* Assuming T is a node built bottom-up, make it all exist on permanent obstack, if it is not permanent already. */treecopy_to_permanent (t) tree t;{ register struct obstack *ambient_obstack = current_obstack; register struct obstack *ambient_saveable_obstack = saveable_obstack; if (t == NULL_TREE || TREE_PERMANENT (t)) return t; saveable_obstack = &permanent_obstack; current_obstack = saveable_obstack; t = make_deep_copy (t); current_obstack = ambient_obstack; saveable_obstack = ambient_saveable_obstack; return t;}voidprint_lang_statistics (){ extern struct obstack maybepermanent_obstack; print_obstack_statistics ("class_obstack", &class_obstack); print_obstack_statistics ("permanent_obstack", &permanent_obstack); print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack); print_search_statistics (); print_class_statistics ();}/* This is used by the `assert' macro. It is provided in libgcc.a, which `cc' doesn't know how to link. Note that the C++ front-end no longer actually uses the `assert' macro (instead, it calls my_friendly_assert). But all of the back-end files still need this. */void__eprintf (string, expression, line, filename)#ifdef __STDC__ const char *string; const char *expression; unsigned line; const char *filename;#else char *string; char *expression; unsigned line; char *filename;#endif{ fprintf (stderr, string, expression, line, filename); fflush (stderr); abort ();}/* Return, as an INTEGER_CST node, the number of elements for TYPE (which is an ARRAY_TYPE). This counts only elements of the top array. */treearray_type_nelts_top (type) tree type;{ return fold (build (PLUS_EXPR, integer_type_node, array_type_nelts (type), integer_one_node));}/* Return, as an INTEGER_CST node, the number of elements for TYPE (which is an ARRAY_TYPE). This one is a recursive count of all ARRAY_TYPEs that are clumped together. */treearray_type_nelts_total (type) tree type;{ tree sz = array_type_nelts_top (type); type = TREE_TYPE (type); while (TREE_CODE (type) == ARRAY_TYPE) { tree n = array_type_nelts_top (type); sz = fold (build (MULT_EXPR, integer_type_node, sz, n)); type = TREE_TYPE (type); } return sz;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -