📄 ctree.cc
字号:
out->printf("ull"); } if (comments != NULL) in_line_output_comments(out, 1, 1); return; } case ctree_charconst: { out->printf("'"); print_c_char(out, integer_val()); out->printf("'"); if (comments != NULL) in_line_output_comments(out, 1, 1); return; } case ctree_floatconst: { immed float_value = float_val(); boolean is_negative; if (float_value.is_flt()) is_negative = (float_value.flt() < 0); else if (float_value.is_ext_flt()) is_negative = (*(float_value.ext_flt()) == '-'); else assert(FALSE); if (is_negative) out->printf("("); assert(type->op() == TYPE_FLOAT); enum C_types the_c_type = c_float_type(type); print_float(out, float_value); if (the_c_type == C_float) out->printf("F"); else if (the_c_type == C_longdouble) out->printf("L"); else assert(the_c_type == C_double); if (is_negative) out->printf(")"); if (comments != NULL) in_line_output_comments(out, 1, 1); return; } case ctree_enumconst: out->printf("%s", leafval.s); if (comments != NULL) in_line_output_comments(out, 1, 1); return; case ctree_strconst: out->printf("\"%s\"", leafval.s); if (comments != NULL) in_line_output_comments(out, 1, 1); return; case ctree_symconst: out->printf("%s", leafval.y->name()); if (comments != NULL) in_line_output_comments(out, 1, 1); return; case ctree_blank_line: if (comments != NULL) full_line_output_comments(out, nindent); else out->printf("\n"); return; case ctree_pound_line: out->printf("#%s", leafval.s); if (comments != NULL) in_line_output_comments(out, 1, 0); out->printf("\n"); return; case ctree_type_ref: assert(N() == 0); out->printf("%s", make_c_type(type)); if (comments != NULL) in_line_output_comments(out, 1, 1); return; }}/*********************************************************************** * * Tree rewriting routines, used to turn the C tree into legal, * readable C. * ***********************************************************************//* * Do some nice cleanup on the tree, like collapsing *& into nothing. */void ctree::do_basic_folding(){ for (int i=0; i<N(); i++) child(i)->do_basic_folding(); for (;;) { if ((op == ctree_addrof) && (N() == 1) && (child(0)->op == ctree_deref)) { assert(child(0)->N() == 1); ctree *old_child = child(0); ctree *replacement = old_child->child(0); old_child->reset_children(); swap(replacement); copy_comments_from(old_child); copy_comments_from(replacement); delete replacement; continue; } if ((op == ctree_deref) && (N() == 1) && (child(0)->op == ctree_addrof)) { assert(child(0)->N() == 1); ctree *old_child = child(0); ctree *replacement = old_child->child(0); old_child->reset_children(); swap(replacement); copy_comments_from(old_child); copy_comments_from(replacement); delete replacement; continue; } if ((op == ctree_strsel) && (N() == 1) && (child(0)->op == ctree_deref)) { assert(child(0)->N() == 1); ctree *old_child = child(0); replace_child(0, old_child->child(0)); old_child->children = new ctree_list; old_child->flush_child_cache(); copy_comments_from(old_child); delete old_child; op = ctree_strptr; continue; } if ((op == ctree_strptr) && (N() == 1) && (child(0)->op == ctree_addrof)) { assert(child(0)->N() == 1); ctree *old_child = child(0); replace_child(0, old_child->child(0)); old_child->children = new ctree_list; old_child->flush_child_cache(); copy_comments_from(old_child); delete old_child; op = ctree_strsel; continue; } if ((op == ctree_addrof) && (N() == 1) && (child(0)->op == ctree_subscr) && (child(0)->N() == 2) && (child(0)->child(1)->op == ctree_intconst) && (child(0)->child(1)->integer_val() == 0)) { ctree *old_child = child(0); ctree *replacement = old_child->child(0); copy_comments_from(old_child->child(1)); delete old_child->child(1); old_child->reset_children(); swap(replacement); copy_comments_from(old_child); copy_comments_from(replacement); delete replacement; continue; } if ((op == ctree_not) && (N() == 1) && (child(0)->op == ctree_not)) { assert(child(0)->N() == 1); ctree *old_child = child(0); ctree *replacement = old_child->child(0); old_child->reset_children(); swap(replacement); copy_comments_from(old_child); copy_comments_from(replacement); delete replacement; continue; } return; }}/* * Get rid of unnecessary type casts. */void ctree::fold_converts(void) { for (int child_num = 0; child_num < N(); ++child_num) { child(child_num)->fold_converts(); boolean do_not_repeat = FALSE; if ((child(child_num)->op == ctree_conv) && child(child_num)->foldable) { assert(child(child_num)->N() == 1); type_node *implicit_type = child(child_num)->child(0)->expr_type(); if ((op != ctree_addrof) && (op != ctree_postinc) && (op != ctree_preinc) && (op != ctree_postdec) && (op != ctree_predec) && (op != ctree_strsel) && (((op != ctree_assign) && (op != ctree_addassign) && (op != ctree_subassign)) || (child_num != 0))) { implicit_type = implicit_type->unqual(); } if (op != ctree_addrof) implicit_type = op_type_conv(implicit_type); boolean do_fold = FALSE; type_node *child_type = child(child_num)->type; if (implicit_type->is_same(child_type)) { do_fold = TRUE; } else if (write_pseudo) { do_fold = FALSE; } else if ((op == ctree_vardef) || (((op == ctree_assign) || (op == ctree_addassign) || (op == ctree_subassign)) && (child_num != 0))) { do_fold = assign_convert_implicit(child_type, implicit_type); do_not_repeat = TRUE; } else if ((op == ctree_funcall) && (child_num != 0)) { type_node *func_base = child(0)->expr_type()->unqual(); if (func_base->is_ptr()) { ptr_type *func_ptr = (ptr_type *)func_base; func_base = func_ptr->ref_type()->unqual(); } assert(func_base->is_func()); func_type *the_func_type = (func_type *)func_base; if (the_func_type->args_known()) { do_fold = assign_convert_implicit(child_type, implicit_type); do_not_repeat = TRUE; } else { do_fold = call_convert_implicit(child_type, implicit_type); } } else if ((op == ctree_compl) || (op == ctree_neg) || (op == ctree_lshift) || (op == ctree_rshift)) { do_fold = (integral_promotions(implicit_type)->is_same( child_type)); } else if (op == ctree_conv) { if (type->unqual()->is_ptr() && child_type->unqual()->is_ptr()) { do_fold = TRUE; } else if ((type->unqual()->op() == TYPE_FLOAT) && (child_type->unqual()->op() == TYPE_FLOAT) && (implicit_type->unqual()->op() == TYPE_FLOAT)) { if (child_type->size() >= implicit_type->size()) do_fold = TRUE; } else if ((type->unqual()->op() == TYPE_INT) && (child_type->unqual()->op() == TYPE_INT) && (implicit_type->unqual()->op() == TYPE_INT)) { base_type *base_0 = (base_type *)(type->unqual()); base_type *base_1 = (base_type *)(child_type->unqual()); base_type *base_2 = (base_type *)(implicit_type->unqual()); boolean is_signed_0 = base_0->is_signed(); boolean is_signed_1 = base_1->is_signed(); boolean is_signed_2 = base_2->is_signed(); if (is_signed_1 == is_signed_2) { if (child_type->size() >= implicit_type->size()) do_fold = TRUE; } else if ((is_signed_0 == is_signed_2) && is_signed_1) { if (child_type->size() > implicit_type->size()) do_fold = TRUE; } } } if (do_fold) { ctree *this_child = child(child_num); replace_child(child_num, this_child->child(0)); this_child->reset_children(); copy_comments_from(this_child); delete this_child; if (!do_not_repeat) { /* now look at this child again */ --child_num; } } } } }/* * Find initialized symbols in vardefs and break out the data into * children of the vardef. */void ctree::extract_data(){ if (op == ctree_vardef) { var_sym *vs = (var_sym*)leafval.y; if (vs->has_var_def() && vs->definition()->are_annotations()) { base_init_struct_list *init_list = read_init_data(vs->definition()); ctree *init_tree = build_initializers(vs->type(), init_list); deallocate_init_data(init_list); if (init_tree != NULL) addchild(init_tree); } } else { for (int i=0; i<N(); i++) child(i)->extract_data(); }}void ctree::full_line_output_comments(io_class *out, int nindent){ assert(comments != NULL); char **follow = comments; assert(*follow != NULL); while (TRUE) { ctree_indent(out, nindent); output_a_comment(out, *follow); out->printf("\n"); ++follow; if (*follow == NULL) break; }}void ctree::in_line_output_comments(io_class *out, int prefix_space, int suffix_space){ assert(comments != NULL); int ind_i; for (ind_i = 0; ind_i < prefix_space; ++ind_i) out->printf(" "); char **follow = comments; assert(*follow != NULL); while (TRUE) { output_a_comment(out, *follow); ++follow; if (*follow == NULL) break; out->printf(" "); } for (ind_i = 0; ind_i < suffix_space; ++ind_i) out->printf(" ");}void ctree::output_a_comment(io_class *out, char *comment) { if (in_comment) out->printf("/ *"); else out->printf("/*"); out->printf("%s", comment); if (in_comment) out->printf("* /"); else out->printf("*/"); }/* * Truncate all strings with trailing zeros. This is called by * ctree::truncate_zeros_in_static_inits() only on static initializer * trees. It is legal in static initializers because the size is * already determined by the definition and all parts not explicitly * initialized are implicitly initialized to zero. It is not legal * in general for string literals in executable expressions, because * it shortens the length of the memory area reserved for the string. */void ctree::truncate_all_zeros(void) { if (getop() == ctree_strconst) { char *old_string = leafval.s; char *new_end = old_string; char *follow = new_end; while (*follow != 0) { if (*follow == '\\') { if ((follow[1] == '0') && (follow[2] == '0') && (follow[3] == '0')) { follow += 4; } else { follow += 2; new_end = follow; } } else { ++follow; new_end = follow; } } if (follow != new_end) { char *temp_string = new char[(new_end - old_string) + 1]; strncpy(temp_string, old_string, (new_end - old_string)); temp_string[new_end - old_string] = 0; leafval.s = lexicon->enter(temp_string)->sp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -