📄 util.cc
字号:
static boolean warned = FALSE; mistake(&warned, tn, "integer type with size that does not match any target " "integer types"); use_intnum = TRUE; } if (use_intnum) { basetype->append("int"); basetype->append_int(tn->size()); } append_type_comments(tn, basetype, 1, 0); return; } case TYPE_FLOAT: { enum C_types the_c_type = c_float_type(tn); if (the_c_type == C_float) { basetype->append("float"); } else if (the_c_type == C_double) { basetype->append("double"); } else if (the_c_type == C_longdouble) { basetype->append("long double"); } else { static boolean warned = FALSE; mistake(&warned, tn, "floating point type with size that does not match any " "target floating point types"); basetype->append("float"); basetype->append_int(tn->size()); } append_type_comments(tn, basetype, 1, 0); return; } case TYPE_VOID: basetype->append("void"); append_type_comments(tn, basetype, 1, 0); return; case TYPE_PTR: { ptr_type *ptn = (ptr_type *)tn; pretype->prepend("*"); append_type_comments(tn, pretype, 1, 1); make_c_type_helper(ptn->ref_type(), basetype, pretype, posttype); return; } case TYPE_ARRAY: { array_type *atn = (array_type *) tn; if ((pretype->value()[0] != 0) || (posttype->value()[0] != 0)) { pretype->prepend("("); posttype->append(")"); } posttype->append("["); if (atn->size() != 0) posttype->append_int(atn->size() / atn->elem_type()->size()); posttype->append("]"); /* * From Fortran we can get types which are arrays of arrays where the * size of the second-level array is not known at compile time. In * terms of C, we want to consider such things a single flat array of * unknown size of the ultimate element type with known size. */ type_node *elem_type = atn->elem_type(); while (elem_type->unqual()->is_array() && (elem_type->size() == 0)) { array_type *elem_array = (array_type *)(elem_type->unqual()); elem_type = elem_array->elem_type(); } append_type_comments(tn, posttype, 1, 0); make_c_type_helper(elem_type, basetype, pretype, posttype); return; } case TYPE_ENUM: { enum_type *etn = (enum_type *) tn; basetype->append("enum "); basetype->append(etn->name()); append_type_comments(tn, basetype, 1, 0); return; } case TYPE_GROUP: case TYPE_STRUCT: case TYPE_UNION: { struct_type *stn = (struct_type *) tn; basetype->append(struct_is_union(stn) ? (char *)"union " : (char *)"struct "); basetype->append(stn->name()); append_type_comments(tn, basetype, 1, 0); return; } case TYPE_FUNC: { func_type *ftn = (func_type *) tn; if ((pretype->value()[0] != 0) || (posttype->value()[0] != 0)) { pretype->prepend("("); posttype->append(")"); } posttype->append("("); if (ftn->args_known()) { unsigned num_args = ftn->num_args(); if (num_args == 0) { if (ftn->has_varargs()) { static boolean warned = FALSE; mistake(&warned, ftn, "function with no specified arguments may not " "have varargs"); posttype->append("..."); } else { posttype->append("void"); } } else { for (unsigned arg_num = 0; arg_num < num_args; ++arg_num) { if (arg_num != 0) posttype->append(", "); auto_string *arg_basetype = new auto_string; auto_string *arg_pretype = new auto_string; auto_string *arg_posttype = new auto_string; make_c_type_helper(ftn->arg_type(arg_num), arg_basetype, arg_pretype, arg_posttype); posttype->append(arg_basetype->value()); if ((arg_pretype->value()[0] != 0) || (arg_posttype->value()[0] != 0)) { posttype->append(" "); posttype->append(arg_pretype->value()); posttype->append(arg_posttype->value()); } delete arg_basetype; delete arg_pretype; delete arg_posttype; } if (ftn->has_varargs()) posttype->append(", ..."); } } posttype->append(")"); check_function_type(ftn); append_type_comments(tn, posttype, 1, 0); make_c_type_helper(ftn->return_type(), basetype, pretype, posttype); return; } default: assert_msg(FALSE, ("make_c_type_helper - unknown type")); return; }}static void append_type_comments(type_node *the_type, auto_string *the_string, int prefix_space, int suffix_space) { immed_list *comment_list = (immed_list *)(the_type->peek_annote(k_s2c_comments)); if ((comment_list == NULL) || (comment_list->is_empty())) return; int space_count; for (space_count = 0; space_count < prefix_space; ++space_count) the_string->append(" "); 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); } the_string->append("/*"); the_string->append(this_immed.string()); the_string->append("*/"); if (!comment_iter.is_empty()) the_string->append(" "); } for (space_count = 0; space_count < suffix_space; ++space_count) the_string->append(" "); }static auto_string ct_bfr, ct_basetype, ct_pretype, ct_posttype;char *make_c_type(type_node *tn){ ct_basetype.set(""); ct_pretype.set(""); ct_posttype.set(""); make_c_type_helper(tn, &ct_basetype, &ct_pretype, &ct_posttype); ct_bfr.set(ct_basetype.value()); if ((ct_pretype.value()[0] != 0) || (ct_posttype.value()[0] != 0)) { ct_bfr.append(" "); ct_bfr.append(ct_pretype.value()); ct_bfr.append(ct_posttype.value()); } return ct_bfr.value();}char *make_c_sym_type(var_sym *sym){ ct_bfr.set(""); ct_basetype.set(""); ct_pretype.set(""); ct_posttype.set(""); make_c_type_helper(sym->type(), &ct_basetype, &ct_pretype, &ct_posttype); ct_bfr.append(ct_basetype.value()); ct_bfr.append(" "); ct_bfr.append(ct_pretype.value()); ct_bfr.append(sym->name()); ct_bfr.append(ct_posttype.value()); return ct_bfr.value();}char *make_c_proc_type(proc_sym *sym, char **posttype){ ct_bfr.set(""); ct_basetype.set(""); ct_pretype.set(""); ct_posttype.set(""); if (sym->is_private()) ct_bfr.append("static "); else if (c_style.extern_on_func_decl) ct_bfr.append("extern "); check_function_type(sym->type()); make_c_type_helper(sym->type()->return_type(), &ct_basetype, &ct_pretype, &ct_posttype); ct_bfr.append(ct_basetype.value()); ct_bfr.append(" "); ct_bfr.append(ct_pretype.value()); ct_bfr.append(sym->name()); *posttype = ct_posttype.value(); return ct_bfr.value();}extern char *make_c_proc_prototype(proc_sym *psym) { ct_bfr.set(""); ct_basetype.set(""); ct_pretype.set(""); ct_posttype.set(""); if (psym->is_private()) ct_bfr.append("static "); else if (c_style.extern_on_func_decl) ct_bfr.append("extern "); make_c_type_helper(psym->type(), &ct_basetype, &ct_pretype, &ct_posttype); ct_bfr.append(ct_basetype.value()); ct_bfr.append(" "); ct_bfr.append(ct_pretype.value()); ct_bfr.append(psym->name()); ct_bfr.append(ct_posttype.value()); return ct_bfr.value(); }char *make_c_agg_type(type_node *t, char *nm){ ct_bfr.set(""); ct_basetype.set(""); ct_pretype.set(""); ct_posttype.set(""); make_c_type_helper(t, &ct_basetype, &ct_pretype, &ct_posttype); ct_bfr.append(ct_basetype.value()); ct_bfr.append(" "); ct_bfr.append(ct_pretype.value()); ct_bfr.append(nm); ct_bfr.append(ct_posttype.value()); return ct_bfr.value();}extern void print_float(io_class *out, immed float_value) { /* * When printing a floating point constant, we want to use a compact * notation so it's easy to read (i.e. use exponential form iff it is * really needed). The printf() "%g" option would be perfect except * that if everything after the decimal point is zero it elinates the * decimal point. So it prints 5.0 as just 5. That turns the * floating point constant into an integer constant when it is parsed * back in as C code. So we need to explicitly add the ``.0'' in * this case. */ static char buffer[sizeof(double) * 10]; static char format[100]; char *string; if (float_value.is_flt()) { sprintf(format, "%%.%lulg", (unsigned long)(sizeof(double) * 3)); sprintf(buffer, format, float_value.flt()); string = buffer; } else if (float_value.is_ext_flt()) { string = float_value.ext_flt(); } else { assert(FALSE); } out->printf("%s", string); if ((strchr(string, '.') == NULL) && (strchr(string, 'e') == NULL) && (strchr(string, 'E') == NULL)) { out->printf(".0"); } return; }extern boolean array_flattening_needed(in_array *the_array, array_type *base_array_type) { if (!the_array->offset_op().is_null()) { immed result; eval_status status = evaluate_const_expr(the_array->offset_op(), &result); if ((status != EVAL_OK) || (result != immed(0))) return TRUE; } type_node *current_type = base_array_type; unsigned num_dims = the_array->dims(); for (unsigned dim_num = 0; dim_num < num_dims; ++dim_num) { if (!current_type->unqual()->is_array()) { error_line(1, the_array->parent(), "array type mismatches array reference instruction"); } array_type *this_array = (array_type *)(current_type->unqual()); if (dim_num == 0) { current_type = this_array->elem_type(); continue; } if ((!this_array->lower_bound().is_constant()) || (!this_array->upper_bound().is_constant())) { return TRUE; } operand this_bound = the_array->bound(dim_num); if (!this_bound.is_expr()) return TRUE; if (this_bound.instr()->opcode() != io_ldc) return TRUE; in_ldc *this_ldc = (in_ldc *)(this_bound.instr()); if (!this_ldc->value().is_integer()) return TRUE; int int_bound = this_ldc->value().integer(); if ((this_array->lower_bound().constant() != 0) || (this_array->upper_bound().constant() != int_bound - 1)) { return TRUE; } current_type = this_array->elem_type(); if (current_type->size() == 0) return TRUE; } if (((unsigned)current_type->size()) != the_array->elem_size()) return TRUE; return FALSE; }/* * This function makes sure a ctree gives a particular type by putting in a * convert only when necessary (really, it always puts in a convert but marks * it as removable and later it is optimized away if not needed). */extern ctree *force_type(ctree *the_ctree, type_node *the_type) { ctree *conv_tree = new ctree(ctree_conv, TRUE, the_type); conv_tree->addchild(the_ctree); return conv_tree; }extern void mistake(boolean *warned_var, suif_object *location, char *message, ...) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -