📄 ctree.cc
字号:
if (comment_space == 0) comment_space = 1; char **new_comments = new char *[comment_space * 2]; int space_num = 0; if (comments != NULL) { for (; space_num + 1 < comment_space; ++space_num) new_comments[space_num] = comments[space_num]; delete[] comments; } comments = new_comments; comments[space_num] = comment; comments[space_num + 1] = NULL; comment_space *= 2; }void ctree::add_object_comments(suif_object *the_object) { immed_list *comment_list = (immed_list *)(the_object->peek_annote(k_s2c_comments)); if ((comment_list == NULL) || (comment_list->is_empty())) return; immed_list_iter comment_iter(comment_list); while (!comment_iter.is_empty()) { immed this_immed = comment_iter.step(); if (!this_immed.is_string()) { error_line(1, NULL, "non-string in \"%s\" annotation", k_s2c_comments); } add_comment(this_immed.string()); } }void ctree::copy_comments_from(ctree *other_ctree) { if (other_ctree->comments == NULL) return; int space_num = 0; while (other_ctree->comments[space_num] != NULL) { add_comment(other_ctree->comments[space_num]); ++space_num; } }/* * Compare two ctrees. */boolean ctree::operator==(ctree &c){ if (op != c.op || type != c.type || ((op == ctree_intconst || op == ctree_case) && integer_val() != c.integer_val()) || (op == ctree_floatconst && float_val() != c.float_val()) || ((op == ctree_strconst || op == ctree_enumconst) && leafval.s != c.leafval.s) || ((op == ctree_symconst || op == ctree_vardecl || op == ctree_vardef || op == ctree_funcdecl || op == ctree_funcdef || op == ctree_goto || op == ctree_label) && leafval.y != c.leafval.y) || (op == ctree_typedecl && leafval.t != c.leafval.t) || (op == ctree_typeforward && leafval.t != c.leafval.t)) return FALSE; if (N() != c.N()) return FALSE; for (int i=0; i<N(); i++) if (*child(i) != *c.child(i)) return FALSE; return TRUE;}void ctree::swap(ctree *other) { static char swapspace[sizeof(ctree)]; memcpy(swapspace, this, sizeof(ctree)); memcpy(this, other, sizeof(ctree)); memcpy(other, swapspace, sizeof(ctree)); } boolean ctree::is_int_const(i_integer *value) { if (op == ctree_intconst) { *value = integer_val(); return TRUE; } else { return FALSE; } }/* * Return the type of a C expression. */type_node *ctree::expr_type(void) { switch (op) { case ctree_intconst: case ctree_floatconst: return type; case ctree_charconst: case ctree_enumconst: return type_signed; case ctree_strconst: { array_type *new_array = new array_type(type_char, array_bound(0), array_bound(strlen(leafval.s) + 1)); return type_char->parent()->install_type(new_array); } case ctree_symconst: if (leafval.y->is_var()) { var_sym *the_var = (var_sym *)(leafval.y); return the_var->type(); } else if (leafval.y->is_proc()) { proc_sym *the_proc = (proc_sym *)(leafval.y); return the_proc->type(); } else { assert(FALSE); return NULL; } case ctree_strptr: case ctree_strsel: { assert(N() == 1); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type); if (op == ctree_strptr) { this_type = this_type->unqual(); assert(this_type->is_ptr()); ptr_type *the_ptr_type = (ptr_type *)this_type; this_type = the_ptr_type->ref_type(); } assert(this_type->unqual()->is_struct()); struct_type *the_struct_type = (struct_type *)(this_type->unqual()); char *field_name = leafval.s; if ((the_struct_type->op() == TYPE_GROUP) && struct_is_union(the_struct_type)) { field_name = strchr(field_name, '.'); assert(field_name != NULL); ++field_name; } unsigned field_num = the_struct_type->find_field_by_name(field_name); assert(field_num < the_struct_type->num_fields()); type_node *field_type = the_struct_type->field_type(field_num); if (this_type->is_const() && !field_type->is_const()) { type_node *new_type = new modifier_type(TYPE_CONST, field_type); field_type = field_type->parent()->install_type(new_type); } if (this_type->is_volatile() && !field_type->is_volatile()) { type_node *new_type = new modifier_type(TYPE_VOLATILE, field_type); field_type = field_type->parent()->install_type(new_type); } return field_type; } case ctree_subscr: { assert(N() > 0); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); assert(this_type->is_ptr()); ptr_type *this_ptr = (ptr_type *)this_type; for (int child_num = 2; child_num < N(); ++child_num) { this_type = this_ptr->ref_type(); this_type = op_type_conv(this_type->unqual()); assert(this_type->is_ptr()); this_ptr = (ptr_type *)this_type; } return this_ptr->ref_type(); } case ctree_funcall: { assert(N() > 0); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); assert(this_type->is_ptr()); ptr_type *this_ptr = (ptr_type *)this_type; this_type = this_ptr->ref_type()->unqual(); assert(this_type->is_func()); func_type *this_func = (func_type *)this_type; return this_func->return_type(); } case ctree_macro: { if (type != NULL) return type; if (N() == 0) return type_signed; assert(N() > 0); type_node *type_1 = child(0)->expr_type(); type_1 = op_type_conv(type_1->unqual()); type_node *type_2; if (N() == 1) { type_2 = type_1; } else { type_2 = child(1)->expr_type(); type_2 = op_type_conv(type_2->unqual()); } return usual_arith_conv(type_1, type_2); } case ctree_postinc: case ctree_postdec: assert(N() == 1); return op_type_conv(child(0)->expr_type()->unqual()); case ctree_preinc: case ctree_predec: { assert(N() == 1); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); if (this_type->is_ptr()) return this_type; return usual_arith_conv(this_type, type_signed); } case ctree_compl: case ctree_neg: { assert(N() == 1); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); return integral_promotions(this_type); } case ctree_not: case ctree_lt: case ctree_lte: case ctree_gt: case ctree_gte: case ctree_eq: case ctree_neq: case ctree_logand: case ctree_logor: return type_signed; case ctree_addrof: { assert(N() == 1); return child(0)->expr_type()->ptr_to(); } case ctree_deref: { assert(N() == 1); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); assert(this_type->is_ptr()); ptr_type *this_ptr = (ptr_type *)this_type; return this_ptr->ref_type(); } case ctree_conv: return type; case ctree_mult: case ctree_div: case ctree_mod: case ctree_bitand: case ctree_bitxor: case ctree_bitor: { assert(N() > 0); type_node *this_type = child(0)->expr_type(); if (N() == 1) return this_type; this_type = op_type_conv(this_type->unqual()); for (int child_num = 1; child_num < N(); ++child_num) { type_node *op_type = child(child_num)->expr_type(); op_type = op_type_conv(op_type->unqual()); this_type = usual_arith_conv(this_type, op_type); } return this_type; } case ctree_add: case ctree_sub: { assert(N() > 0); type_node *this_type = child(0)->expr_type(); if (N() == 1) return this_type; this_type = op_type_conv(this_type->unqual()); for (int child_num = 1; child_num < N(); ++child_num) { type_node *op_type = child(child_num)->expr_type(); op_type = op_type_conv(op_type->unqual()); if (this_type->is_ptr() && op_type->is_ptr()) this_type = type_ptr_diff; else if (op_type->is_ptr()) this_type = op_type; else if (!this_type->is_ptr()) this_type = usual_arith_conv(this_type, op_type); } return this_type; } case ctree_lshift: case ctree_rshift: { assert(N() > 0); type_node *this_type = child(0)->expr_type(); this_type = op_type_conv(this_type->unqual()); return integral_promotions(this_type); } case ctree_ternary: { assert(N() == 3); type_node *type_1 = child(1)->expr_type(); type_1 = op_type_conv(type_1->unqual()); type_node *type_2 = child(2)->expr_type(); type_2 = op_type_conv(type_2->unqual()); if (((type_1->op() == TYPE_INT) || (type_1->op() == TYPE_FLOAT)) && ((type_2->op() == TYPE_INT) || (type_2->op() == TYPE_FLOAT))) { return usual_arith_conv(type_1, type_2); } if (type_1 == type_2) return type_1; assert(type_1->is_ptr() && type_2->is_ptr()); ptr_type *ptr_1 = (ptr_type *)type_1; ptr_type *ptr_2 = (ptr_type *)type_2; type_node *result; if (ptr_1->ref_type()->unqual()->op() == TYPE_VOID) { result = ptr_2->ref_type()->unqual(); } else if (ptr_2->ref_type()->unqual()->op() == TYPE_VOID) { result = ptr_1->ref_type()->unqual(); } else { result = composite(ptr_1->ref_type()->unqual(), ptr_2->ref_type()->unqual()); assert(result != NULL); } if (ptr_1->ref_type()->is_const() || ptr_2->ref_type()->is_const()) { type_node *new_type = new modifier_type(TYPE_CONST, result); result = result->parent()->install_type(new_type); } if (ptr_1->ref_type()->is_volatile() || ptr_2->ref_type()->is_volatile()) { type_node *new_type = new modifier_type(TYPE_VOLATILE, result); result = result->parent()->install_type(new_type); } return result->ptr_to(); } case ctree_assign: case ctree_addassign: case ctree_subassign: { assert(N() == 2); type_node *this_type = child(0)->expr_type(); return op_type_conv(this_type->unqual()); } case ctree_comma: { assert(N() > 0); type_node *this_type = child(N() - 1)->expr_type(); return op_type_conv(this_type->unqual()); } case ctree_funcdef: case ctree_funcdecl: case ctree_vardecl: case ctree_vardef: case ctree_typedecl: case ctree_typeforward: case ctree_goto: case ctree_break: case ctree_continue: case ctree_return: case ctree_label: case ctree_case: case ctree_default: case ctree_for: case ctree_if: case ctree_do: case ctree_switch: case ctree_block: case ctree_semi: case ctree_blank_line: case ctree_pound_line: case ctree_type_ref: assert_msg(FALSE, ("ctree::expr_type() called on non-expression")); return NULL; } return NULL; }/* * Print a ctree in list form. */void ctree::print(FILE *out, int nindent){ file_io the_io(out); switch (op) { case ctree_intconst: integer_val().print(out); return; case ctree_charconst: { fprintf(out, "'"); print_c_char(&the_io, integer_val());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -