X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftype.c;h=6f66c9b393b179fd445574a205b7e825f62481dd;hb=1312195fd166a8ace88a3ea9671dbb7dfc11b39e;hp=10640e56198571f3634b2e6d5358719db6c2ed07;hpb=760356ab155a0d884324c867a1f9a78a79c0b5a3;p=libfirm diff --git a/ir/tr/type.c b/ir/tr/type.c index 10640e561..6f66c9b39 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -1,9 +1,21 @@ +/* + * Project: libFIRM + * File name: ir/tr/type.c + * Purpose: Representation of types. + * Author: Goetz Lindenmaier + * Modified by: + * Created: + * CVS-ID: $Id$ + * Copyright: (c) 2001-2003 Universität Karlsruhe + * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + */ + /** * * file type.c - implementation of the datastructure to hold * type information. * (C) 2001 by Universitaet Karlsruhe - * Martin Trapp, Christian Schaefer, Goetz Lindenmaier + * Goetz Lindenmaier * * This module supplies a datastructure to represent all types * known in the compiled program. This includes types specified @@ -23,7 +35,6 @@ * @see type_t.h type tpop */ -/* $Id$ */ #ifdef HAVE_CONFIG_H # include #endif @@ -35,7 +46,7 @@ # include "type_t.h" # include "tpop_t.h" # include "irprog_t.h" -# include "typegmod_t.h" +# include "typegmod.h" # include "array.h" # include "irprog.h" # include "mangle.h" @@ -46,6 +57,10 @@ /** TYPE **/ /*******************************************************************/ +type *none_type; type *get_none_type(void) { return none_type; } +type *unknown_type; type *get_unknown_type(void) { return unknown_type; } + + #ifdef DEBUG_libfirm /** Returns a new, unique number to number nodes or the like. */ int get_irp_new_node_nr(void); @@ -56,8 +71,18 @@ static ident *value_params_suffix = NULL; static ident *value_ress_suffix = NULL; void init_type(void) { - value_params_suffix = id_from_str(VALUE_PARAMS_SUFFIX, strlen(VALUE_PARAMS_SUFFIX)); - value_ress_suffix = id_from_str(VALUE_RESS_SUFFIX, strlen(VALUE_RESS_SUFFIX)); + value_params_suffix = new_id_from_str(VALUE_PARAMS_SUFFIX); + value_ress_suffix = new_id_from_str(VALUE_RESS_SUFFIX); + + /* construct none and unknown type. */ + none_type = new_type(tpop_none, mode_BAD, new_id_from_str("type_none")); + set_type_size (none_type, 0); + set_type_state (none_type, layout_fixed); + remove_irp_type(none_type); + unknown_type = new_type(tpop_unknown, mode_ANY, new_id_from_str("type_unknown")); + set_type_size (unknown_type, 0); + set_type_state (unknown_type, layout_fixed); + remove_irp_type(unknown_type); } unsigned long type_visited; @@ -66,6 +91,8 @@ INLINE unsigned long get_master_type_visited() { return type_visited; } INLINE void inc_master_type_visited() { type_visited++; } void free_type(type *tp) { + if ((get_type_tpop(tp) == tpop_none) || (get_type_tpop(tp) == tpop_unknown)) + return; /* Remove from list of all types */ remove_irp_type(tp); /* Free the attributes of the type. */ @@ -74,6 +101,7 @@ void free_type(type *tp) { if (is_array_type(tp)) free_entity(get_array_element_entity(tp)); /* And now the type itself... */ + tp->kind = k_BAD; free(tp); } @@ -143,7 +171,7 @@ ident* get_type_tpop_nameid(type *tp) { const char* get_type_tpop_name(type *tp) { assert(tp && tp->kind == k_type); - return id_to_str(tp->type_op->name); + return get_id_str(tp->type_op->name); } tp_opcode get_type_tpop_code(type *tp) { @@ -159,12 +187,16 @@ ir_mode* get_type_mode(type *tp) { void set_type_mode(type *tp, ir_mode* m) { assert(tp && tp->kind == k_type); - assert(((tp->type_op != type_primitive) || mode_is_data(m)) && + assert(((tp->type_op != type_primitive) || mode_is_data(m)) && /* Modes of primitives must be data */ - ((tp->type_op != type_enumeration) || mode_is_int(m))); + ((tp->type_op != type_enumeration) || mode_is_int(m)) && /* Modes of enumerations must be integers */ + ((tp->type_op != type_pointer) || mode_is_reference(m)) ); + /* Modes of pointers must be references. */ - if ((tp->type_op == type_primitive) || (tp->type_op == type_enumeration)) { + if ((tp->type_op == type_primitive) || + (tp->type_op == type_enumeration) || + (tp->type_op == type_pointer) ) { /* For pointer, primitive and enumeration size depends on the mode. */ assert((get_mode_size_bytes(m) != -1) && "unorthodox modes not implemented"); tp->size = get_mode_size_bytes(m); @@ -189,13 +221,13 @@ get_type_nr(type *tp) { #ifdef DEBUG_libfirm return tp->nr; #else - return 0; + return (long)tp; #endif } const char* get_type_name(type *tp) { assert(tp && tp->kind == k_type); - return (id_to_str(tp->name)); + return (get_id_str(tp->name)); } int get_type_size(type *tp) { @@ -240,7 +272,7 @@ set_type_state(type *tp, type_state state) { { DDMT(tp); DDME(get_class_member(tp, i)); } assert(get_entity_offset(get_class_member(tp, i)) > -1); assert(is_method_type(get_entity_type(get_class_member(tp, i))) || - (get_entity_allocation(get_class_member(tp, i)) == automatic_allocated)); + (get_entity_allocation(get_class_member(tp, i)) == allocation_automatic)); } } break; case tpo_struct: @@ -248,7 +280,7 @@ set_type_state(type *tp, type_state state) { assert(get_type_size(tp) > -1); for (i = 0; i < get_struct_n_members(tp); i++) { assert(get_entity_offset(get_struct_member(tp, i)) > -1); - assert((get_entity_allocation(get_struct_member(tp, i)) == automatic_allocated)); + assert((get_entity_allocation(get_struct_member(tp, i)) == allocation_automatic)); } } break; case tpo_union: @@ -561,11 +593,11 @@ INLINE type *new_type_class (ident *name) { res = new_type(type_class, NULL, name); - res->attr.ca.members = NEW_ARR_F (entity *, 1); - res->attr.ca.subtypes = NEW_ARR_F (type *, 1); - res->attr.ca.supertypes = NEW_ARR_F (type *, 1); - res->attr.ca.peculiarity = existent; - res->attr.ca.dfn = 0; + res->attr.ca.members = NEW_ARR_F (entity *, 1); + res->attr.ca.subtypes = NEW_ARR_F (type *, 1); + res->attr.ca.supertypes = NEW_ARR_F (type *, 1); + res->attr.ca.peculiarity = peculiarity_existent; + res->attr.ca.dfn = 0; return res; } @@ -713,13 +745,21 @@ void remove_class_supertype(type *clss, type *supertype) { } } +char *get_peculiarity_string(peculiarity p) { + if (p == peculiarity_description) + return "peculiarity_description"; + if (p == peculiarity_inherited) + return "peculiarity_inherited"; + return "peculiarity_existent"; +} + INLINE peculiarity get_class_peculiarity (type *clss) { assert(clss && (clss->type_op == type_class)); return clss->attr.ca.peculiarity; } INLINE void set_class_peculiarity (type *clss, peculiarity pec) { assert(clss && (clss->type_op == type_class)); - assert(pec != inherited); /* There is no inheritance of types in libFirm. */ + assert(pec != peculiarity_inherited); /* There is no inheritance of types in libFirm. */ clss->attr.ca.peculiarity = pec; } @@ -847,7 +887,7 @@ INLINE type *new_type_method (ident *name, int n_param, int n_res) { res->attr.ma.n_res = n_res; res->attr.ma.res_type = (type **) xmalloc (sizeof (type *) * n_res); res->attr.ma.value_ress = NULL; - res->attr.ma.variadicity = non_variadic; + res->attr.ma.variadicity = variadicity_non_variadic; return res; } @@ -893,11 +933,18 @@ entity *get_method_value_param_ent(type *method, int pos) { method->attr.ma.value_params = build_value_type(mangle_u(get_type_ident(method), value_params_suffix), get_method_n_params(method), method->attr.ma.param_type); - assert((get_entity_type(get_struct_member(method->attr.ma.value_params, pos)) != method->attr.ma.value_params) + assert((get_entity_type(get_struct_member(method->attr.ma.value_params, pos)) + != method->attr.ma.value_params) && "param type not yet set"); return get_struct_member(method->attr.ma.value_params, pos); } +type *get_method_value_res_type(type *method) { + assert(method && (method->type_op == type_method)); + return method->attr.ma.value_params; +} + + int get_method_n_ress (type *method) { assert(method && (method->type_op == type_method)); return method->attr.ma.n_res; @@ -932,6 +979,19 @@ entity *get_method_value_res_ent(type *method, int pos) { return get_struct_member(method->attr.ma.value_ress, pos); } +/* Returns the null-terminated name of this variadicity. */ +const char *get_variadicity_name(variadicity vari) +{ +#define X(a) case a: return #a + switch (vari) { + X(variadicity_non_variadic); + X(variadicity_variadic); + default: + return "BAD VALUE"; + } +#undef X +} + variadicity get_method_variadicity(type *method) { assert(method && (method->type_op == type_method)); @@ -996,7 +1056,7 @@ ident *get_union_delim_nameid (type *uni, int pos) { const char *get_union_delim_name (type *uni, int pos) { assert(uni && (uni->type_op == type_union)); assert(pos >= 0 && pos < get_union_n_types(uni)); - return id_to_str(uni->attr.ua.delim_names[pos]); + return get_id_str(uni->attr.ua.delim_names[pos]); } void set_union_delim_nameid (type *uni, int pos, ident *id) { assert(uni && (uni->type_op == type_union)); @@ -1248,7 +1308,7 @@ ident *get_enumeration_nameid (type *enumeration, int pos) { const char *get_enumeration_name(type *enumeration, int pos) { assert(enumeration && (enumeration->type_op == type_enumeration)); assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration)); - return id_to_str(enumeration->attr.ea.enum_nameid[pos]); + return get_id_str(enumeration->attr.ea.enum_nameid[pos]); } /* typecheck */ @@ -1296,6 +1356,20 @@ bool is_pointer_type (type *pointer) { if (pointer->type_op == type_pointer) return 1; else return 0; } +/* Returns the first pointer type that has as points_to tp. + * Not efficient: O(#types). + * If not found returns unknown_type. */ +type *find_pointer_type_to_type (type *tp) { + int i; + for (i = 0; i < get_irp_n_types(); ++i) { + type *found = get_irp_type(i); + if (is_pointer_type(found) && get_pointer_points_to_type(found) == tp) + return (found); + } + return unknown_type; +} + + /*******************************************************************/ /** TYPE_PRIMITIVE **/