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

📄 types.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
/*  Implementation of High-Level Types *//*  Copyright (c) 1994 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>#define _MODULE_ "libsuif.a"#pragma implementation "types.h"#define RCS_BASE_FILE types_cc#include "suif1.h"#include "suif_internal.h"RCS_BASE(    "$Id: types.cc,v 1.2 1999/08/25 03:29:19 brm Exp $")/*  predefined types */type_node *type_error = NULL;type_node *type_v0 = NULL;type_node *type_s8 = NULL;type_node *type_s16 = NULL;type_node *type_s32 = NULL;type_node *type_s64 = NULL;type_node *type_u8 = NULL;type_node *type_u16 = NULL;type_node *type_u32 = NULL;type_node *type_u64 = NULL;type_node *type_f32 = NULL;type_node *type_f64 = NULL;type_node *type_f128 = NULL;/*  portable types */type_node *type_void = NULL;type_node *type_ptr = NULL;type_node *type_char = NULL;type_node *type_signed_char = NULL;type_node *type_unsigned_char = NULL;type_node *type_signed_short = NULL;type_node *type_unsigned_short = NULL;type_node *type_signed = NULL; /* int */type_node *type_unsigned = NULL; /* int */type_node *type_signed_long = NULL;type_node *type_unsigned_long = NULL;type_node *type_signed_longlong = NULL;type_node *type_unsigned_longlong = NULL;type_node *type_ptr_diff = NULL;type_node *type_float = NULL;type_node *type_double = NULL;type_node *type_longdouble = NULL;type_node::type_node ()    : oper(TYPE_VOID), table(0), id(0){}voidtype_node::clear_type_id (){    if (parent() != NULL)        parent()->register_type_id_change(this, 0);    set_type_id(0);}/* *  Check if a type is a group, a structure, a union, or an enumeration. *  These are all of the named type classes. */booleantype_node::is_named (){    if (op() == TYPE_GROUP) return TRUE;    if (op() == TYPE_STRUCT) return TRUE;    if (op() == TYPE_UNION) return TRUE;    if (op() == TYPE_ENUM) return TRUE;    return FALSE;}/* *  Check if a type is scalar.  This rules out everything except integers, *  floats, pointers, and enumerations. */booleantype_node::is_scalar (){    type_node *t = unqual();    if ((t->op() == TYPE_INT) ||	(t->op() == TYPE_FLOAT) ||	(t->op() == TYPE_PTR) ||	(t->op() == TYPE_ENUM)) {	return TRUE;    }    return FALSE;}/* *  Compare the base class fields for two type_nodes.  This is not called *  directly by users but may be used in the derived "is_same" methods. */booleantype_node::is_same (type_node *t){    if (!t) return FALSE;    if (op() != t->op()) return FALSE;    if (!is_same_annotes(t)) return FALSE;    return TRUE;}/* *  Check if another type node has the same annotations.  Structured  *  annotations are automatically flattened so they can be compared. *  Unregistered annotations are ignored.  Note that this method assumes *  that the annotation order is significant. */booleantype_node::is_same_annotes (type_node *t){    /* compare the annotations */    if (are_annotations() != t->are_annotations()) return FALSE;    if (!are_annotations()) return TRUE;    if (annotes()->count() != t->annotes()->count()) return FALSE;    annote_list_iter anli(annotes());    annote_list_iter t_anli(t->annotes());    while (!anli.is_empty()) {	assert(!t_anli.is_empty());	annote *an = anli.step();	annote *t_an = t_anli.step();	/* compare the annotation names */	if (an->name() != t_an->name()) return FALSE;	immed_list *iml = an->immeds();	immed_list *t_iml = t_an->immeds();	/* ignore unregistered annotations */	if (!iml) continue;	boolean no_diff = TRUE;	/* check if the immed lists are the same length */	if (iml->count() != t_iml->count()) {	    no_diff = FALSE;	} else {	    /* compare the immeds */	    immed_list_iter imli(iml);	    immed_list_iter t_imli(t_iml);	    while (!imli.is_empty()) {		assert(!t_imli.is_empty());		if (imli.step() != t_imli.step()) {		    no_diff = FALSE;		    break;		}	    }	}	if (an->is_structured()) {	    delete iml;	    delete t_iml;	}	if (!no_diff) return FALSE;    }    return TRUE;}/* *  Try to find the specified modifier type.  Return NULL if it does *  not exist. */modifier_type *type_node::find_modifier (type_ops mod){    if (!is_modifier()) return NULL;    modifier_type *mt = (modifier_type *)this;    if (op() == mod) return mt;    return mt->base()->find_modifier(mod);}/* *  Return a type which is a pointer to this type.  If this type is *  installed, the pointer type will be installed in the same place. *  If this type is not installed, the pointer type will not be *  installed. */ptr_type *type_node::ptr_to(void){    ptr_type *result = new ptr_type(this);    if (parent() != NULL)        result = (ptr_type *)(parent()->install_type(result));    return result;}/* *  Print a type (short version) -- just use the type ID number. */voidtype_node::print (FILE *f){    fputs("t:", f);    print_id_number(f, type_id());}/* *  Print the type id, operator, and size.  This abbreviated form is used *  when printing the result_types of instructions. */voidtype_node::print_abbrev (FILE *f){    /* print the type_id number */    print(f);    fputs(" (", f);    switch (unqual()->op()) {	case TYPE_INT: {	    base_type *bt = (base_type *)unqual();	    if (bt->is_signed()) {		putc('i', f);	    } else {		putc('u', f);	    }	    break;	}	case TYPE_FLOAT:	{ putc('f', f); break; }	case TYPE_VOID:		{ putc('v', f); break; }	case TYPE_PTR:		{ putc('p', f); break; }	case TYPE_ARRAY:	{ putc('a', f); break; }	case TYPE_FUNC:		{ putc('n', f); break; }	case TYPE_GROUP:	{ putc('g', f); break; }	case TYPE_STRUCT:	{ putc('s', f); break; }	case TYPE_UNION:	{ putc('n', f); break; }	case TYPE_ENUM:		{ putc('e', f); break; }	default: {	    assert_msg(FALSE, ("type_node::print_abbrev - invalid operator"));	}    }    fprintf(f, ".%d)", size());}/* *  Print all of the type information.  This method is used for printing *  symtabs.  This handles the fields shared by all type_nodes and the *  print_helper virtual function is used to print fields specific to the *  derived classes. */voidtype_node::print_full (FILE *f, int depth){    suif_indent(f, depth);    /* print the ID number */    print(f);    switch (op()) {	case TYPE_INT:		{ fputs(": int ", f); break; }	case TYPE_FLOAT:	{ fputs(": float ", f); break; }	case TYPE_VOID:		{ fputs(": void ", f); break; }	case TYPE_PTR:		{ fputs(": ptr ", f); break; }	case TYPE_ARRAY:	{ fputs(": array ", f); break; }	case TYPE_FUNC:		{ fputs(": function ", f); break; }	case TYPE_GROUP:	{ fputs(": group ", f); break; }	case TYPE_STRUCT:	{ fputs(": struct ", f); break; }	case TYPE_UNION:	{ fputs(": union ", f); break; }	case TYPE_ENUM:		{ fputs(": enum ", f); break; }	case TYPE_CONST:	{ fputs(": const ", f); break; }	case TYPE_VOLATILE:	{ fputs(": volatile ", f); break; }	case TYPE_CALL_BY_REF:	{ fputs(": call-by-ref ", f); break; }	case TYPE_NULL:		{ fputs(": null ", f); break; }	default: {	    assert_msg(FALSE, ("type_node::print - invalid operator"));	}    }    /* print any fields specific to the type kind */    print_helper(f, depth);    print_annotes(f, depth+1);    putc('\n', f);}/* *  Read a type_node from an input stream.  The type_node must have already *  been created in the symtab or one of its ancestors. */type_node *type_node::read (in_stream *is, base_symtab *symtab){    unsigned i = is->read_int();    type_node *result = symtab->lookup_type_id(i);    assert_msg(result, ("type_node::read - type ID %u not found", i));    return result;}/* *  Write a type_node to an output stream.  The type_node must have a *  non-zero ID number assigned before it can be written out. */voidtype_node::write (out_stream *os){    write_check();    os->write_int(id);}voidtype_node::write_check (void){    assert(write_scope != NULL);    assert_msg(type_id() != 0,               ("attempt to write reference to type with no type_id"));    assert_msg(write_scope->is_visible(this),               ("attempt to write reference to type #%u used outside its "                "scope", id));}/* *  Create a type_node from an annotation created by type_node::cvt_to_annote. *  This function calls the appropriate constructor based on the name *  of the annotation.  This function only creates the type_nodes; it *  doesn't read the details of the types (except the ID numbers) from *  the annotations because there may be references to type_nodes that *  haven't yet been created. */type_node *type_node::scan_from_annote (annote *an){    type_node *result = NULL;    if (an->name() == k_int_type) {	result = new base_type;	result->set_op(TYPE_INT);    } else if (an->name() == k_float_type) {	result = new base_type;	result->set_op(TYPE_FLOAT);    } else if (an->name() == k_void_type) {	result = new base_type;	result->set_op(TYPE_VOID);    } else if (an->name() == k_ptr_type) {	result = new ptr_type;	result->set_op(TYPE_PTR);    } else if (an->name() == k_array_type) {	result = new array_type;	result->set_op(TYPE_ARRAY);    } else if (an->name() == k_func_type) {	result = new func_type;	result->set_op(TYPE_FUNC);    } else if (an->name() == k_group_type) {	result = new struct_type;	result->set_op(TYPE_GROUP);    } else if (an->name() == k_struct_type) {	result = new struct_type;	result->set_op(TYPE_STRUCT);    } else if (an->name() == k_union_type) {	result = new struct_type;	result->set_op(TYPE_UNION);    } else if (an->name() == k_enum_type) {	result = new enum_type;	result->set_op(TYPE_ENUM);    } else if (an->name() == k_const_type) {	result = new modifier_type;	result->set_op(TYPE_CONST);    } else if (an->name() == k_volatile_type) {	result = new modifier_type;	result->set_op(TYPE_VOLATILE);    } else if (an->name() == k_call_by_ref_type) {	result = new modifier_type;	result->set_op(TYPE_CALL_BY_REF);    } else if (an->name() == k_null_type) {	result = new modifier_type;	result->set_op(TYPE_NULL);    }    assert_msg(result, ("type_node::scan_from_annote: unknown type kind"));    /* get the ID number */    result->id = (*an->immeds())[0].unsigned_int();    return result;}/* *  Read the shared type_node fields from an annotation.  This function is *  called by the cvt_from_annote functions in the derived classes.  Since *  the ID number has already been read by scan_from_annote, it is just *  checked here. */voidtype_node::cvt_from_annote (annote *an, base_symtab *){    assert(id == an->immeds()->pop().unsigned_int());}/* *  Write the shared type_node fields onto an annotation.  This function is *  called by the cvt_to_annote functions to append to the annotation the *  fields shared by all type_nodes. */voidtype_node::cvt_to_annote_base (annote *an){    an->immeds()->append(immed(id));}/* *  Check if a type_node has been cloned, and if so, return its replacement. *  Otherwise, just return this type_node. */type_node *type_node::clone_helper (replacements *r){    /* check if this type has been replaced */    type_node_list_iter old_tnli(&r->oldtypes);    type_node_list_iter new_tnli(&r->newtypes);    while (!old_tnli.is_empty()) {	assert(!new_tnli.is_empty());	type_node *old_tn = old_tnli.step();	type_node *new_tn = new_tnli.step();	/* return the replacement */	if (old_tn == this) return new_tn;    }    return this;}/*****************************************************************************//* *  Create a modifier type. */modifier_type::modifier_type (type_ops o, type_node *t)    : type_node(), typ(t){    assert_msg((o == TYPE_CONST) ||	       (o == TYPE_VOLATILE) ||	       (o == TYPE_CALL_BY_REF) ||	       (o == TYPE_NULL),	       ("attempt to create modifier_type with invalid operator"));    set_op(o);}/* *  Return the type size.  Modifiers have no effect on the size. */intmodifier_type::size (){    if (!base()) return 0;    return base()->size();}/* *  Unqualify a type (remove the modifiers).  Since we know this is a *  modifier, we can just skip to the base type. */type_node *modifier_type::unqual (){    if (!base()) return NULL;    return base()->unqual();}/* *  Virtual methods to check for the various modifiers.  The default return *  value for these methods is FALSE. */booleanmodifier_type::is_const (){    if (op() == TYPE_CONST) return TRUE;    if (base()) return base()->is_const();    return FALSE;}booleanmodifier_type::is_volatile (){    if (op() == TYPE_VOLATILE) return TRUE;    if (base()) return base()->is_volatile();    return FALSE;}booleanmodifier_type::is_call_by_ref (){    if (op() == TYPE_CALL_BY_REF) return TRUE;    if (base()) return base()->is_call_by_ref();    return FALSE;}type_node *modifier_type::ref_type (unsigned num){    assert(num == 0);    return base();}voidmodifier_type::set_ref_type (unsigned num, type_node *new_type){    assert(num == 0);    set_base(new_type);}/* *  Help print a modifier type.  Just print the base type. */voidmodifier_type::print_helper (FILE *f, int /* depth */){    assert_msg(base(), ("modifier_type::print_helper - missing base type"));    base()->print(f);}/* *  Make a copy of a modifier_type.  (This isn't very useful!) */type_node *modifier_type::copy (){    modifier_type *result = new modifier_type(op(), base());    return result;}modifier_type *modifier_type::clone(void){    modifier_type *result = new modifier_type(op(), base()->clone());    copy_annotes(result);    return result;}/* *  Check if this type is the same as another type_node.  The modifiers *  may be in any order, so the "is_same_helper" method is used to check

⌨️ 快捷键说明

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