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

📄 types.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
 *  for each possible modifier. */booleanmodifier_type::is_same (type_node *t){    if (!t) return FALSE;    type_node *ut = unqual();    if (!ut || (!ut->is_same(t->unqual()))) return FALSE;    if (is_same_helper(TYPE_CONST, t) &&	is_same_helper(TYPE_VOLATILE, t) &&	is_same_helper(TYPE_CALL_BY_REF, t) &&	is_same_helper(TYPE_NULL, t)) {	return TRUE;    }    return FALSE;}booleanmodifier_type::is_same_helper (type_ops mod, type_node *t){    modifier_type *mt1 = find_modifier(mod);    modifier_type *mt2 = t->find_modifier(mod);    /* check if they are identical or both NULL */    if (mt1 == mt2) return TRUE;    /* check if both types have the same modifier with the same annotations */    if (mt1 && mt2 && mt1->is_same_annotes(mt2)) return TRUE;    return FALSE;}/* *  Check if this type is compatible with another type_node.  Modifiers *  do not affect compatibility so they are ignored here. */booleanmodifier_type::compatible (type_node *t){    if (!t) return FALSE;    type_node *ut = unqual();    if (!ut) return FALSE;    return ut->compatible(t);}/* *  Write the modifier_type fields onto an annotation. */annote *modifier_type::cvt_to_annote (){    annote *an;    /* determine the annotation name from the type operator */    switch (op()) {	case TYPE_CONST:	{ an = new annote(k_const_type); break; }	case TYPE_VOLATILE:	{ an = new annote(k_volatile_type);  break; }	case TYPE_CALL_BY_REF:	{ an = new annote(k_call_by_ref_type); break; }	case TYPE_NULL:		{ an = new annote(k_null_type); break; }	default:		{ break; }    }    assert_msg(an, ("modifier_type::cvt_to_annote - invalid type operator"));    cvt_to_annote_base(an);    assert_msg(base(), ("modifier_type::cvt_to_annote - missing base type"));    if (write_scope != NULL)	base()->write_check();    unsigned base_id = base()->type_id();    an->immeds()->append(immed(base_id));    return an;}/* *  Read the modifier_type fields from an annotation. */voidmodifier_type::cvt_from_annote (annote *an, base_symtab *symtab){    type_node::cvt_from_annote(an, symtab);    unsigned base_id = an->immeds()->pop().unsigned_int();    typ = symtab->lookup_type_id(base_id);    assert_msg(typ, ("modifier_type::cvt_from_annote - type ID %u not found",		     base_id));}type_node *modifier_type::clone_internal(void){    return clone();}/*****************************************************************************//* *  Create a base type. */base_type::base_type (type_ops o, int s, boolean b)    : sz(s), sgn(b){    assert_msg((o == TYPE_INT) ||	       (o == TYPE_FLOAT) ||	       (o == TYPE_VOID) ||	       (o == TYPE_ENUM),	       ("attempt to create base_type with non-base operator"));    set_op(o);    if ((o == TYPE_INT) || (o == TYPE_ENUM)) {	sgn = b;    } else if (o == TYPE_VOID) {	sgn = FALSE;    } else {	sgn = TRUE;    }}/* *  Write the base_type fields onto an annotation. */annote *base_type::cvt_to_annote (){    annote *an;    /* determine the annotation name from the type operator */    switch (op()) {	case TYPE_INT:		{ an = new annote(k_int_type); break; }	case TYPE_FLOAT:	{ an = new annote(k_float_type);  break;}	case TYPE_VOID:		{ an = new annote(k_void_type); break; }	default:		{ break; }    }    assert_msg(an, ("base_type::cvt_to_annote - invalid type operator"));    cvt_to_annote_base(an);    an->immeds()->append(immed(size()));    an->immeds()->append(immed((int)is_signed()));    return an;}/* *  Read the base_type fields from an annotation. */voidbase_type::cvt_from_annote (annote *an, base_symtab *symtab){    type_node::cvt_from_annote(an, symtab);    sz = an->immeds()->pop().integer();    sgn = (boolean)(an->immeds()->pop().integer());}type_node *base_type::clone_internal(void){    return clone();}/* *  Help print a base_type.  The only added fields to check are the *  "is_signed" flag and the size. */voidbase_type::print_helper (FILE *f, int /* depth */){    if (op() == TYPE_INT) {	if (is_signed()) {	    fputs("signed ", f);	} else {	    fputs("unsigned ", f);	}    }    fprintf(f, "%d", size());}/* *  Make a copy of a base_type. */type_node *base_type::copy (){    base_type *result = new base_type(op(), size(), is_signed());    return result;}base_type *base_type::clone(void){    base_type *result = new base_type(op(), size(), is_signed());    copy_annotes(result);    return result;}/* *  Check if this type is compatible with another type_node.  This is mostly *  like "is_same" except that ENUMs may be compatible with INTs. */booleanbase_type::compatible (type_node *t){    t = t->unqual();    /* enums and ints may be compatible */    if ((t->op() == TYPE_ENUM) && (op() == TYPE_INT)) {	enum_type *et = (enum_type *)t;	if ((et->is_signed() == is_signed()) &&	    (et->size() == size())) {	    return TRUE;	}    }    if (t->op() != op()) return FALSE;    base_type *bt = (base_type *)t;    if (bt->size() != size()) return FALSE;    if (bt->is_signed() != is_signed()) return FALSE;    return TRUE;}/* *  Check if this base_type is the same as another type_node. */booleanbase_type::is_same (type_node *t){    if (!type_node::is_same(t)) return FALSE;    base_type *bt = (base_type *)t;    if (bt->size() != size()) return FALSE;    if (bt->is_signed() != is_signed()) return FALSE;    return TRUE;}/*****************************************************************************//* *  Create a new ptr_type. */ptr_type::ptr_type (type_node *r)    : ref(r){    set_op(TYPE_PTR);}/* *  Write the ptr_type fields onto an annotation. */annote *ptr_type::cvt_to_annote (){    annote *an = new annote(k_ptr_type);    cvt_to_annote_base(an);    assert_msg(ref_type(), ("ptr_type::cvt_to_annote - missing ref type"));    if (write_scope != NULL)	ref_type()->write_check();    unsigned ref_id = ref_type()->type_id();    an->immeds()->append(immed(ref_id));    return an;}/* *  Read the ptr_type fields from an annotation. */voidptr_type::cvt_from_annote (annote *an, base_symtab *symtab){    type_node::cvt_from_annote(an, symtab);    unsigned ref_id = an->immeds()->pop().unsigned_int();    ref = symtab->lookup_type_id(ref_id);    assert_msg(ref, ("ptr_type::cvt_from_annote - type ID %u not found",		     ref_id));}type_node *ptr_type::clone_internal(void){    return clone();}/* *  Help print a ptr_type.  Just print the referent type. */voidptr_type::print_helper (FILE *f, int /* depth */){    fputs("to ", f);    assert_msg(ref_type(), ("ptr_type::print - missing ref type"));    ref_type()->print(f);}type_node *ptr_type::ref_type (unsigned num){    assert(num == 0);    return ref_type();}voidptr_type::set_ref_type (unsigned num, type_node *new_type){    assert(num == 0);    set_ref_type(new_type);}/* *  Make a copy of a ptr_type.  The referent type is not copied. */type_node *ptr_type::copy (){    ptr_type *result = new ptr_type(ref_type());    return result;}ptr_type *ptr_type::clone(void){    ptr_type *result = new ptr_type(ref_type()->clone());    copy_annotes(result);    return result;}/* *  Check if this type is compatible with another type_node.  All pointers *  are considered to be compatible with one another. */booleanptr_type::compatible (type_node *t){    if (!t || !(t = t->unqual())) return FALSE;    if (t->op() != op()) return FALSE;    return TRUE;}/* *  Check if a ptr_type is equivalent to another type_node. */booleanptr_type::is_same (type_node *t){    if (!type_node::is_same(t)) return FALSE;    ptr_type *pt = (ptr_type *)t;    if (!ref_type() ||	!ref_type()->is_same(pt->ref_type())) return FALSE;    return TRUE;}/*****************************************************************************//* *  Global variable used for unknown array bounds. */const array_bound unknown_bound;/* *  Retrieve a constant bound.  An error occurs if the bound is not *  a constant. */intarray_bound::constant () const{    assert_msg(is_constant(),	       ("array_bound::constant - bound is not constant"));    return u.cnst;}/* *  Retrieve a variable bound.  An error occurs if the bound is not *  a variable. */var_sym *array_bound::variable () const{    assert_msg(is_variable(),	       ("array_bound::variable - bound is not a variable"));    return u.var;}/* *  Print an array bound.  Variables include the full chain_name from the *  symbol table.  If the bound is unknown, it is printed as an asterisk. */voidarray_bound::print (FILE *f){    if (is_constant()) {	fprintf(f, "%d", constant());    } else if (is_variable()) {	variable()->print(f);    } else {	fputc('*', f);    }}/* *  Array bound operators.... */array_bound &array_bound::operator= (const array_bound &b){    is_cnst = b.is_cnst;    u = b.u;    return *this;}booleanarray_bound::operator== (const array_bound &b){    if (is_unknown() && b.is_unknown()) return TRUE;    if (is_constant() && b.is_constant()) return (constant() == b.constant());    if (is_variable() && b.is_variable()) return (variable() == b.variable());    return FALSE;}/* *  Grab an array bound from the list of immeds in an annotation. *  This is called by the array_type::cvt_from_annote function. */array_bound::array_bound (annote *an, base_symtab *symtab){    is_cnst = (boolean)(an->immeds()->pop().integer());    if (is_cnst) {	u.cnst = an->immeds()->pop().integer();    } else {	unsigned var_id = an->immeds()->pop().unsigned_int();	if (var_id == 0) {	    u.var = NULL;	} else {	    u.var = (var_sym *)symtab->lookup_sym_id(var_id);	    assert_msg(u.var && u.var->is_var(),		       ("array_bound - variable ID (%u) not found", var_id));	}    }}/* *  Put an array bound on the list of immeds of an annotation. *  This is called by the array_type::cvt_to_annote function. */voidarray_bound::add_to_annote (annote *an){    if (is_constant()) {	an->immeds()->append(immed((int)TRUE));	an->immeds()->append(immed(constant()));    } else if (is_variable()) {	an->immeds()->append(immed((int)FALSE));	if (write_scope != NULL)	    variable()->write_check();	an->immeds()->append(immed(variable()->sym_id()));    } else {	an->immeds()->append(immed((int)FALSE));	an->immeds()->append(immed(0u));    }}/*****************************************************************************//* *  Create a new array type.  By default, the bounds are unknown. */array_type::array_type (type_node *elem, array_bound lb, array_bound ub)    : elemt(elem), low(lb), uppr(ub){    set_op(TYPE_ARRAY);    /* make sure constant bounds are valid */    if (lb.is_constant() && ub.is_constant()) {	assert_msg(ub.constant() >= lb.constant(),		   ("array_type - upper bound smaller than lower bound"));    }}/* *  Check if the upper bound is unknown.  As a consistency check, this *  method also checks that if the upper bound is known, then the lower *  bound must also be known. */booleanarray_type::are_bounds_unknown (){    if (upper_bound().is_unknown()) return TRUE;    if (lower_bound().is_unknown()) {	assert_msg(upper_bound().is_unknown(),		   ("array_type::are_bounds_unknown - "		    "only upper bound is known"));    }    return FALSE;}/* *  Try to figure out the size (in bits) of an array.  If the array bounds *  are not constant, the result is zero. */intarray_type::size (){    if (!lower_bound().is_constant() ||	!upper_bound().is_constant() ||	!elem_type()) {	return 0;    }    int lb = lower_bound().constant();    int ub = upper_bound().constant();    assert_msg(ub >= lb, ("array_type::size - "			  "upper bound smaller than lower bound"));    return (ub - lb + 1) * elem_type()->size();}type_node *array_type::ref_type (unsigned num){    assert(num == 0);    return elem_type();}voidarray_type::set_ref_type (unsigned num, type_node *new_type){    assert(num == 0);    set_elem_type(new_type);}/* *  Write the array_type fields onto an annotation. */annote *array_type::cvt_to_annote (){    annote *an = new annote(k_array_type);    cvt_to_annote_base(an);    assert_msg(elem_type(),	       ("array_type::cvt_to_annote - missing element type"));    if (write_scope != NULL)	elem_type()->write_check();    unsigned elemt_id = elem_type()->type_id();    an->immeds()->append(immed(elemt_id));    lower_bound().add_to_annote(an);

⌨️ 快捷键说明

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