⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 types.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* *  Set the name of a particular field in a struct_type.  Make sure that it *  is entered in the lexicon.  The field number must be valid or an error *  will occur. */voidstruct_type::set_field_name (unsigned n, char *nm){    check_range(n);    names[n] = nm ? lexicon->enter(nm)->sp : NULL;}/* *  Set the type of a particular field in a struct_type.  The field number *  must be valid or an error will occur. */voidstruct_type::set_field_type (unsigned n, type_node *t){    check_range(n);    types[n] = t;}/* *  Set the offset of a particular field in a struct_type.  The field number *  must be valid or an error will occur. */voidstruct_type::set_offset (unsigned n, int o){    check_range(n);    offsets[n] = o;}/* *  Find a structure field from its offset.  This relies upon the convention *  that the fields are stored in order of increasing offsets.  If no fields *  match the offset exactly, the field containing the offset is returned and *  the number of bits from the start of that field is returned in the "left" *  parameter.  This function is useless for TYPE_UNIONs since the fields all *  have the same offset. */unsignedstruct_type::find_field_by_offset (int off, int& left){    unsigned closest_field = num_fields();    int distance = 0;    for (unsigned field_num = 0; field_num < num_fields(); ++field_num) {	if (offset(field_num) <= off) {	    if ((closest_field == num_fields()) ||		(distance > (off - offset(field_num)))) {		distance = off - offset(field_num);		closest_field = field_num;	    }	}    }    if (closest_field != num_fields())	left = distance;    return closest_field;}/* *  Find a group, structure, or union field by name.  Returns *  "(unsigned)-1" if the field is not found. */unsignedstruct_type::find_field_by_name (char *nm){    char *nn = nm ? lexicon->enter(nm)->sp : NULL;        for (unsigned i = 0; i < num_fields(); i++) {	if (nn == field_name(i)) return i;    }    return (unsigned)-1;}type_node *struct_type::ref_type (unsigned num){    return field_type(num);}voidstruct_type::set_ref_type (unsigned num, type_node *new_type){    set_field_type(num, new_type);}/* *  Write the struct_type fields onto an annotation. */annote *struct_type::cvt_to_annote (){    annote *an;    if (op() == TYPE_GROUP) {	an = new annote(k_group_type);    } else if (op() == TYPE_STRUCT) {	an = new annote(k_struct_type);    } else {	an = new annote(k_union_type);    }    cvt_to_annote_base(an);    an->immeds()->append(immed(name()));    an->immeds()->append(immed(size()));    an->immeds()->append(immed(num_fields()));        for (unsigned i = 0; i < num_fields(); i++) {	assert_msg(field_type(i), ("struct_type::cvt_to_annote - missing type "				   "for field %u", i));	if (write_scope != NULL)	    field_type(i)->write_check();	unsigned field_id = field_type(i)->type_id();	an->immeds()->append(immed(field_name(i)));	an->immeds()->append(immed(field_id));	an->immeds()->append(immed(offset(i)));    }    return an;}/* *  Read the struct_type fields from an annotation. */voidstruct_type::cvt_from_annote (annote *an, base_symtab *symtab){    type_node::cvt_from_annote(an, symtab);    my_name = an->immeds()->pop().string();    sz = an->immeds()->pop().integer();    ntypes = an->immeds()->pop().unsigned_int();    /* allocate storage for the aggregate's elements */    names = new char*[ntypes];    types = new type_node*[ntypes];    offsets = new int[ntypes];    for (unsigned i = 0; i < ntypes; i++) {	names[i] = an->immeds()->pop().string();	unsigned field_id = an->immeds()->pop().unsigned_int();	types[i] = symtab->lookup_type_id(field_id);	assert_msg(types[i], ("struct_type::cvt_from_annote - type ID %u not "			      "found", field_id));	offsets[i] = an->immeds()->pop().integer();    }}type_node *struct_type::clone_internal(void){    return clone();}/* *  Help print a struct_type.  This method includes all of the struct_type *  fields. */voidstruct_type::print_helper (FILE *f, int depth){    fprintf(f, "%s (%d) { ", name(), size());        for (unsigned i = 0; i < num_fields(); i++) {	putc('\n', f);	suif_indent(f, depth+1);	if(field_name(i)) {	    fprintf(f, "%s offset=%d ", field_name(i), offset(i));	    if(field_type(i)) {		field_type(i)->print(f);	    } else {		fprintf(f, "<<MISSING TYPE>>");	    }	} else {	    fprintf(f, "<<MISSING FIELD>>");	}    }    if (num_fields() > 0) {	putc('\n', f);	suif_indent(f, depth);    }    putc('}', f);}/* *  Make a copy of a struct_type.  The field types are not copied. */type_node *struct_type::copy (){    struct_type *result = new struct_type(op(), size(), name(), num_fields());    /* set the field names, types, and offsets */    for (unsigned n = 0; n < num_fields(); n++) {	result->set_field_name(n, field_name(n));	result->set_field_type(n, field_type(n));	result->set_offset(n, offset(n));    }    return result;}struct_type *struct_type::clone(void){    annote *clone_annote = annotes()->peek_annote(k_clone);    if (clone_annote != NULL) {        immed_list *clone_immeds = clone_annote->immeds();        assert((clone_immeds->count() == 1) && ((*clone_immeds)[0].is_type()));        type_node *result = (*clone_immeds)[0].type();        assert(result->is_struct());        return (struct_type *)result;    }    struct_type *result = new struct_type(op(), size(), name(), num_fields());    clone_annote = new annote(k_clone);    clone_annote->immeds()->append(immed(result));    annotes()->push(clone_annote);    for (unsigned n = 0; n < num_fields(); n++) {	result->set_field_name(n, field_name(n));	result->set_field_type(n, field_type(n)->clone());	result->set_offset(n, offset(n));    }    clone_annote = annotes()->get_annote(k_clone);    assert(clone_annote != NULL);    delete clone_annote;    copy_annotes(result);    return result;}/* * Modify the type of struct_type * No validation is done here */voidstruct_type::set_to_union() {  set_op(TYPE_UNION);}voidstruct_type::set_to_struct() {  set_op(TYPE_STRUCT);}voidstruct_type::set_to_group() {  set_op(TYPE_GROUP);}/* *  Check if this type is compatible with another type_node.  Struct types *  should never need to be compared but this method does something reasonable *  just in case. */booleanstruct_type::compatible (type_node *t){    if (!t) return FALSE;    return is_same(t->unqual());}/* *  Compare struct_types.  In SUIF, the types are the same only if *  their pointers match. */booleanstruct_type::is_same (type_node *t){    return (t == (type_node *)this);}/*****************************************************************************//* *  Create a new enum_type.  The member arrays are allocated and initialized, *  but the individual values must be set separately. */enum_type::enum_type (char *nm, int s, boolean b, unsigned n)    : base_type(TYPE_ENUM, s, b), my_name(0), nvals(n),      names(new char*[nvals]), vals(new int[nvals]){    set_name(nm);    /* initialize the members */    for (unsigned i = 0; i < nvals; i++) {	names[i] = NULL;	vals[i] = 0;    }}enum_type::~enum_type (){    if (names) delete[] names;    if (vals) delete[] vals;}/* *  Check if an enum_type member number is valid. */voidenum_type::check_range (unsigned n){    assert_msg(n < num_values(),	       ((num_values() > 0) ? (char *)                "enum_type: member number %u out of range 0 to %u" : (char *)                "enum_type: member number %u is invalid for enumerated "                "type with zero members",		n, num_values() - 1));}/* *  Change the number of members in an enum_type.  If the number is larger *  than before, the member arrays are reallocated. */voidenum_type::set_num_values (unsigned n){    if (n <= nvals) {	nvals = n;	return;    }    char **new_names = new char*[n];    int *new_vals = new int[n];    /* copy the old values (as much as possible) */    unsigned i;    for (i = 0; (i < nvals) && (i < n); i++) {	new_names[i] = names[i];	new_vals[i] = vals[i];    }    /* initialize any new values */    for (unsigned j = nvals; j < n; j++) {	new_names[i] = NULL;	new_vals[i] = 0;    }    nvals = n;    delete[] names;    delete[] vals;    names = new_names;    vals = new_vals;}/* *  Set the name of an enum_type.  Make sure it is entered in the lexicon. */voidenum_type::set_name (char *nm){    my_name = nm ? lexicon->enter(nm)->sp : NULL;}/* *  Set the name of a particular member of an enum_type.  Make sure it is *  entered in the lexicon.  The member number must be valid or an error will *  occur. */voidenum_type::set_member (unsigned n, char *nm){    check_range(n);    names[n] = nm ? lexicon->enter(nm)->sp : NULL;}/* *  Set the value of a particular member of an enum_type.  The member number *  must be valid or an error will occur. */voidenum_type::set_value (unsigned n, int v){    check_range(n);    assert_msg(is_signed() || (v >= 0),	       ("enum_type: negative member number not allowed in unsigned "		"enumeration"));    assert_msg((is_signed() && ((v >= 0) && ((v >> size() - 1) == 0)) ||			       ((v < 0) && (~v >> size() - 1) == 0)) ||	       (!is_signed() && ((v >> size()) == 0)),	       ("enum_type: member number doesn't fit in size allocated"));    vals[n] = v;}/* *  Search for a particular member of an enumerated type by either the *  value or the name.  If found, the index of the member is returned; *  otherwise, "(unsigned)-1" is returned. */unsignedenum_type::find_member_by_value (int v){    for (unsigned i = 0; i < num_values(); i++) {	if (value(i) == v) return i;    }    return (unsigned)-1;}unsignedenum_type::find_member_by_name (char *nm){    char *nn = nm ? lexicon->enter(nm)->sp : NULL;        for (unsigned i = 0; i < num_values(); i++) {	if (nn == member(i)) return i;    }    return (unsigned)-1;}/* *  Write the enum_type fields onto an annotation. */annote *enum_type::cvt_to_annote (){    annote *an = new annote(k_enum_type);    cvt_to_annote_base(an);    an->immeds()->append(immed(name()));    an->immeds()->append(immed(size()));    an->immeds()->append(immed((int)is_signed()));    an->immeds()->append(immed(num_values()));    for (unsigned n = 0; n < num_values(); n++) {	an->immeds()->append(immed(member(n)));	an->immeds()->append(immed(value(n)));    }    return an;}/* *  Read the enum_type fields from an annotation. */voidenum_type::cvt_from_annote (annote *an, base_symtab *symtab){    type_node::cvt_from_annote(an, symtab);    my_name = an->immeds()->pop().string();    set_size(an->immeds()->pop().integer());    set_signed((boolean)(an->immeds()->pop().integer()));    nvals = an->immeds()->pop().unsigned_int();    names = new char*[nvals];    vals = new int[nvals];    for (unsigned n = 0; n < nvals; n++) {	names[n] = an->immeds()->pop().string();	vals[n] = an->immeds()->pop().integer();    }}type_node *enum_type::clone_internal(void){    return clone();}/* *  Help print an enum_type.  This method includes all of the enum_type *  members. */voidenum_type::print_helper (FILE *f, int depth){    fputs(name(), f);    if (is_signed()) {	fputs(" signed", f);    } else {	fputs(" unsigned", f);    }    fprintf(f, " %d { ", size());        for (unsigned i = 0; i < num_values(); i++) {	putc('\n', f);	suif_indent(f, depth+1);	fprintf(f, "%s = %d, ", member(i), value(i));    }    if (num_values() > 0) {	putc('\n', f);	suif_indent(f, depth);    }    putc('}', f);}/* *  Make a copy of an enum_type. */type_node *enum_type::copy (){    enum_type *result =	new enum_type(name(), size(), is_signed(), num_values());    /* set the members and values */    for (unsigned n = 0; n < num_values(); n++) {	result->set_member(n, member(n));	result->set_value(n, value(n));    }    return result;}enum_type *enum_type::clone(void){    enum_type *result =            new enum_type(name(), size(), is_signed(), num_values());    for (unsigned n = 0; n < num_values(); n++) {	result->set_member(n, member(n));	result->set_value(n, value(n));    }    copy_annotes(result);    return result;}/* *  Check if this type is compatible with another type_node.  ENUM types *  are compatible with INTs and other ENUMs of the same size and "signed- *  ness". */booleanenum_type::compatible (type_node *t){    t = t->unqual();    if ((t->op() == TYPE_INT) || (t->op() == TYPE_ENUM)) {	base_type *bt = (base_type *)t;	if ((bt->is_signed() == is_signed()) &&	    (bt->size() == size())) {	    return TRUE;	}    }    return is_same(t);}/* *  Compare enum_types (using name equivalence). */booleanenum_type::is_same (type_node *t){    return (t == (type_node *)this);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -