Commit 9d564d61 authored by Matthias Braun's avatar Matthias Braun
Browse files

Primitive, Pointer, Array and Method types are anonymous now

- There's a new type_dbg_info* that allows you to attach debug names to types
- get_type_name and get_type_ident are now more. The new ir_print_type
  and the usual ir_printf("%+F", type) help in most usage cases.
  But you should be aware that names are not guaranteed to be unique anymore
  (or positively said: You don't have no trouble anymore building unique names
   in code that creates types)
- No need to specify mode for new pointer types anymore (you can still do it
  with set_type_mode)

[r26909]
parent e2e929ea
......@@ -35,6 +35,7 @@
#ifndef FIRM_DEBUG_DBGINFO_H
#define FIRM_DEBUG_DBGINFO_H
#include <stdlib.h>
#include "firm_types.h"
#include "ident.h"
......@@ -162,9 +163,28 @@ typedef const char *(*retrieve_dbg_func)(const dbg_info *dbg, unsigned *line);
*/
void ir_set_debug_retrieve(retrieve_dbg_func func);
/**
* The type of the type debug info retrieve function.
* Prints a human readable source representation of a type to an obstack.
* (Used for generating debug info like stabs or dwarf)
*/
typedef void (*retrieve_type_dbg_func)(char *buffer, size_t buffer_size,
const type_dbg_info *tdbgi);
/**
* Set global print_type_dbg_info function in firm
*/
void ir_set_type_debug_retrieve(retrieve_type_dbg_func func);
/**
* Retrieve the debug info.
*/
const char *ir_retrieve_dbg_info(const dbg_info *dbg, unsigned *line);
/**
* Retrieve type debug info
*/
void ir_retrieve_type_dbg_info(char *buffer, size_t buffer_size,
const type_dbg_info *tdbgi);
#endif
......@@ -32,49 +32,49 @@
* libFirm initialization parameters.
*/
struct _firm_parameter_t {
/**
* The size of this structure. init_firm() will only initialize
* this amount of data. This allows to add more fields to this structure
* without breaking compatibility to older source.
*/
unsigned int size;
/**
* Statistic options. If statistic function where enabled, these
* flags configure it, see enum firmstat_options_t.
*/
unsigned enable_statistics;
/**
* This function is called, whenever a local variable is
* used before definition. The function should insert a default value,
* and/or raise a compiler error/warning. Note that returning
* an Unknown is allowed here.
*/
uninitialized_local_variable_func_t *initialize_local_func;
/**
* The interface functions for the type identification module.
* If not set, the default implementation with compare_strict() and
* firm_hash_name() will be used.
*/
type_identify_if_t *ti_if;
/**
* The interface for the ident module.
* If not set, the default libFirm ident module (using hash sets).
*/
ident_if_t *id_if;
/**
* The default calling convention.
*/
unsigned cc_mask;
/**
* The debug info that should be used for "builtin" objects.
*/
dbg_info *builtin_dbg;
/**
* The size of this structure. init_firm() will only initialize
* this amount of data. This allows to add more fields to this structure
* without breaking compatibility to older source.
*/
unsigned int size;
/**
* Statistic options. If statistic function where enabled, these
* flags configure it, see enum firmstat_options_t.
*/
unsigned enable_statistics;
/**
* This function is called, whenever a local variable is
* used before definition. The function should insert a default value,
* and/or raise a compiler error/warning. Note that returning
* an Unknown is allowed here.
*/
uninitialized_local_variable_func_t *initialize_local_func;
/**
* The interface functions for the type identification module.
* If not set, the default implementation with compare_strict() and
* firm_hash_name() will be used.
*/
type_identify_if_t *ti_if;
/**
* The interface for the ident module.
* If not set, the default libFirm ident module (using hash sets).
*/
ident_if_t *id_if;
/**
* The default calling convention.
*/
unsigned cc_mask;
/**
* dummy (here was dbg_info *builtin_dbg before)
*/
void *dummy;
};
typedef struct _firm_parameter_t firm_parameter_t;
......
......@@ -31,6 +31,7 @@ typedef unsigned long ir_exc_region_t;
typedef unsigned long ir_label_t;
typedef struct dbg_info dbg_info, *dbg_info_ptr;
typedef struct type_dbg_info type_dbg_info;
typedef const struct _ident ident, *ir_ident_ptr;
typedef struct ir_node ir_node, *ir_node_ptr;
typedef struct ir_op ir_op, *ir_op_ptr;
......
......@@ -478,4 +478,9 @@ void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode);
*/
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst);
/**
* Returns the primitive type matching the given mode
*/
ir_type *get_type_for_mode(const ir_mode *mode);
#endif
......@@ -63,7 +63,7 @@ typedef struct {
* A function returning a pointer type for a given type.
* If this pointer is NULL, a new pointer type is always created.
*/
ir_type *(*find_pointer_type)(ir_type *e_type, ir_mode *mode, int alignment);
ir_type *(*find_pointer_type)(ir_type *e_type, int alignment);
/**
* If the LF_SMALL_CMP_IN_REGS flag is set, this function will be called
......
......@@ -25,6 +25,7 @@
#define FIRM_TYPEREP_H
#include "firm_types.h"
#include <stdlib.h>
/**
* @page entity Entity representation
......@@ -1123,9 +1124,16 @@ ident *get_type_tpop_nameid(const ir_type *tp);
const char *get_type_tpop_name(const ir_type *tp);
tp_opcode get_type_tpop_code(const ir_type *tp);
ident *get_type_ident(const ir_type *tp);
void set_type_ident(ir_type *tp, ident* id);
const char *get_type_name(const ir_type *tp);
/**
* construct a string representing the type.
* This uses the info retrieved by the type_dbg_info if available.
* Otherwise it tries to create an approximate textual representation of the
* type.
* Keep in mind that this representation is not unique for each type,
* might abstract away some details. The main intention of this is creating
* human redable strings giving an idea of the type.
*/
void ir_print_type(char *buffer, size_t buffer_size, const ir_type *tp);
/** The visibility of a type.
*
......@@ -1273,14 +1281,14 @@ void inc_master_type_visited(void);
* @param tp The type.
* @param db The debug info.
*/
void set_type_dbg_info(ir_type *tp, dbg_info *db);
void set_type_dbg_info(ir_type *tp, type_dbg_info *db);
/**
* Returns the debug information of a type.
*
* @param tp The type.
*/
dbg_info *get_type_dbg_info(const ir_type *tp);
type_dbg_info *get_type_dbg_info(const ir_type *tp);
/**
* Checks whether a pointer points to a type.
......@@ -1426,10 +1434,16 @@ int smaller_type(ir_type *st, ir_type *lt);
ir_type *new_type_class(ident *name);
/** Creates a new class type with debug information. */
ir_type *new_d_type_class(ident *name, dbg_info *db);
ir_type *new_d_type_class(ident *name, type_dbg_info *db);
/* --- manipulate private fields of class type --- */
/** return identifier of the class type */
ident *get_class_ident(const ir_type *clss);
/** return identifier of the class type */
const char *get_class_name(const ir_type *clss);
/** Adds the entity as member of the class. */
void add_class_member(ir_type *clss, ir_entity *member);
......@@ -1599,10 +1613,16 @@ int is_Class_type(const ir_type *clss);
/** Creates a new type struct */
ir_type *new_type_struct(ident *name);
/** Creates a new type struct with debug information. */
ir_type *new_d_type_struct(ident *name, dbg_info* db);
ir_type *new_d_type_struct(ident *name, type_dbg_info* db);
/* --- manipulate private fields of struct --- */
/** return struct identifier */
ident *get_struct_ident(const ir_type *strct);
/** return struct identifier as c-string*/
const char *get_struct_name(const ir_type *strct);
/** Adds the entity as member of the struct. */
void add_struct_member(ir_type *strct, ir_entity *member);
......@@ -1673,7 +1693,7 @@ int is_Struct_type(const ir_type *strct);
* The arrays for the parameter and result types are not initialized by
* the constructor.
*/
ir_type *new_type_method(ident *name, int n_param, int n_res);
ir_type *new_type_method(int n_param, int n_res);
/** Create a new method type with debug information.
*
......@@ -1685,17 +1705,7 @@ ir_type *new_type_method(ident *name, int n_param, int n_res);
* The arrays for the parameter and result types are not initialized by
* the constructor.
*/
ir_type *new_d_type_method(ident *name, int n_param, int n_res, dbg_info *db);
/** Clone an existing method type.
*
* @param tp the method type to clone.
* @param prefix if non-null, will be the prefix for the name of
* the cloned type
*
* @return the cloned method type.
*/
ir_type *clone_type_method(ir_type *tp, ident *prefix);
ir_type *new_d_type_method(int n_param, int n_res, type_dbg_info *db);
/* -- manipulate private fields of method. -- */
......@@ -1887,10 +1897,16 @@ int is_Method_type(const ir_type *method);
ir_type *new_type_union(ident *name);
/** Creates a new type union with debug information. */
ir_type *new_d_type_union(ident *name, dbg_info* db);
ir_type *new_d_type_union(ident *name, type_dbg_info* db);
/* --- manipulate private fields of struct --- */
/** return union identifier */
ident *get_union_ident(const ir_type *uni);
/** return union identifier as c-string */
const char *get_union_name(const ir_type *uni);
/** Returns the number of unioned types of this union */
int get_union_n_members(const ir_type *uni);
......@@ -1938,7 +1954,7 @@ int is_Union_type(const ir_type *uni);
* The entity for array elements is built automatically.
* Set dimension sizes after call to constructor with set_* routines.
*/
ir_type *new_type_array(ident *name, int n_dims, ir_type *element_type);
ir_type *new_type_array(int n_dims, ir_type *element_type);
/** Create a new type array with debug information.
*
......@@ -1948,7 +1964,7 @@ ir_type *new_type_array(ident *name, int n_dims, ir_type *element_type);
* Set dimension sizes after call to constructor with set_* routines.
* A legal array type must have at least one dimension set.
*/
ir_type *new_d_type_array(ident *name, int n_dims, ir_type *element_type, dbg_info* db);
ir_type *new_d_type_array(int n_dims, ir_type *element_type, type_dbg_info* db);
/* --- manipulate private fields of array type --- */
......@@ -2007,7 +2023,7 @@ int find_array_dimension(const ir_type *array, int order);
void set_array_element_type(ir_type *array, ir_type* tp);
/** Gets the array element type. */
ir_type *get_array_element_type(ir_type *array);
ir_type *get_array_element_type(const ir_type *array);
/** Sets the array element entity. */
void set_array_element_entity(ir_type *array, ir_entity *ent);
......@@ -2035,10 +2051,16 @@ int is_Array_type(const ir_type *array);
ir_type *new_type_enumeration(ident *name, int n_enums);
/** Create a new type enumeration with debug information -- set the enumerators independently. */
ir_type *new_d_type_enumeration(ident *name, int n_enums, dbg_info *db);
ir_type *new_d_type_enumeration(ident *name, int n_enums, type_dbg_info *db);
/* --- manipulate fields of enumeration type. --- */
/** return enumeration identifier */
ident *get_enumeration_ident(const ir_type *enumeration);
/** return enumeration identifier as c-string */
const char *get_enumeration_name(const ir_type *enumeration);
/** Set an enumeration constant to a enumeration type at a given position. */
void set_enumeration_const(ir_type *enumeration, int pos, ident *nameid, tarval *con);
......@@ -2061,10 +2083,10 @@ tarval *get_enumeration_value(const ir_enum_const *enum_cnst);
void set_enumeration_nameid(ir_enum_const *enum_cnst, ident *id);
/** Returns the assigned ident of an enumeration constant. */
ident *get_enumeration_nameid(const ir_enum_const *enum_cnst);
ident *get_enumeration_const_nameid(const ir_enum_const *enum_cnst);
/** Returns the assigned name of an enumeration constant. */
const char *get_enumeration_name(const ir_enum_const *enum_cnst);
const char *get_enumeration_const_name(const ir_enum_const *enum_cnst);
/** Returns true if a type is a enumeration type. */
int is_Enumeration_type(const ir_type *enumeration);
......@@ -2072,25 +2094,23 @@ int is_Enumeration_type(const ir_type *enumeration);
/**
* @page pointer_type Representation of a pointer type
*
* The mode of the pointer type must be a reference mode.
*
* Pointer types:
* - points_to: The type of the entity this pointer points to.
*/
/** Creates a new type pointer. */
ir_type *new_type_pointer(ident *name, ir_type *points_to, ir_mode *ptr_mode);
ir_type *new_type_pointer(ir_type *points_to);
/** Creates a new type pointer with debug information. */
ir_type *new_d_type_pointer(ident *name, ir_type *points_to, ir_mode *ptr_mode, dbg_info* db);
ir_type *new_d_type_pointer(ir_type *points_to, type_dbg_info* db);
/* --- manipulate fields of type_pointer --- */
/** Sets the type to which a pointer points to. */
void set_pointer_points_to_type(ir_type *pointer, ir_type *tp);
void set_pointer_points_to_type(ir_type *pointer, ir_type *tp);
/** Returns the type to which a pointer points to. */
ir_type *get_pointer_points_to_type(ir_type *pointer);
ir_type *get_pointer_points_to_type(const ir_type *pointer);
/** Returns true if a type is a pointer type. */
int is_Pointer_type(const ir_type *pointer);
......@@ -2108,16 +2128,16 @@ ir_type *find_pointer_type_to_type(ir_type *tp);
* important information they carry is held in the common mode field.
*/
/** Creates a new primitive type. */
ir_type *new_type_primitive(ident *name, ir_mode *mode);
ir_type *new_type_primitive(ir_mode *mode);
/** Creates a new primitive type with debug information. */
ir_type *new_d_type_primitive(ident *name, ir_mode *mode, dbg_info* db);
ir_type *new_d_type_primitive(ir_mode *mode, type_dbg_info* db);
/** Returns true if a type is a primitive type. */
int is_Primitive_type(const ir_type *primitive);
/** Return the base type of a primitive (bitfield) type or NULL if none. */
ir_type *get_primitive_base_type(ir_type *tp);
ir_type *get_primitive_base_type(const ir_type *tp);
/** Sets the base type of a primitive (bitfield) type. */
void set_primitive_base_type(ir_type *tp, ir_type *base_tp);
......@@ -2183,6 +2203,14 @@ int is_atomic_type(const ir_type *tp);
/* --- Support for compound types --- */
/**
* Gets the identifier of a compound type
*/
ident *get_compound_ident(const ir_type *tp);
/** return compound identifier as c-string */
const char *get_compound_name(const ir_type *tp);
/**
* Gets the number of elements in a Firm compound type.
*
......@@ -2245,14 +2273,14 @@ int is_lowered_type(const ir_type *tp);
* so all struct access functions work.
* Value types are not in the global list of types.
*/
ir_type *new_type_value(ident *name);
ir_type *new_type_value(void);
/**
* Makes a new frame type. Frame types are class types,
* so all class access functions work.
* Frame types are not in the global list of types.
*/
ir_type *new_type_frame(ident *name);
ir_type *new_type_frame(void);
/**
* Makes a clone of a frame type.
......@@ -2322,12 +2350,6 @@ int compare_strict(const void *tp1, const void *tp2);
/* ------------------------------------------------------------------------ */
/** Type for a function that computes a hash value for a type.
*
* @param tp The type to compute a hash for.
*/
typedef int (hash_types_func_t)(ir_type *tp);
/** Computes a hash value by the type name.
*
* Uses the name of the type and the type opcode to compute the hash.
......
......@@ -1263,18 +1263,15 @@ static pmap *mtp_map;
*
* @param tp the type to clone
*/
static ir_type *clone_type_and_cache(ir_type *tp) {
static ident *prefix = NULL;
static ir_type *clone_type_and_cache(ir_type *tp)
{
ir_type *res;
pmap_entry *e = pmap_find(mtp_map, tp);
if (e)
return e->value;
if (prefix == NULL)
prefix = new_id_from_chars("C", 1);
res = clone_type_method(tp, prefix);
res = clone_type_method(tp);
pmap_insert(mtp_map, tp, res);
return res;
......
......@@ -280,8 +280,7 @@ static ir_type *find_type_for_node(ir_node *n) {
if (tp1 == tp2) { tp = tp1; break; }
DB((dbg, SET_LEVEL_2, "Phi %ld with two different types: %s, %s: unknown type.\n", get_irn_node_nr(n),
get_type_name(tp1), get_type_name(tp2)));
DB((dbg, SET_LEVEL_2, "Phi %ld with two different types: %+F, %+F: unknown type.\n", get_irn_node_nr(n), tp1, tp2));
tp = firm_unknown_type; /* Test for supertypes? */
break;
}
......@@ -381,8 +380,7 @@ default_code:
tp = phi_cycle_type;
break;
}
DB((dbg, SET_LEVEL_2, "Binop %ld with two different types: %s, %s: unknown type \n", get_irn_node_nr(n),
get_type_name(tp1), get_type_name(tp2)));
DB((dbg, SET_LEVEL_2, "Binop %ld with two different types: %+F, %+F: unknown type\n", get_irn_node_nr(n), tp1, tp2));
tp = firm_unknown_type;
break;
}
......
......@@ -307,8 +307,8 @@ static ir_type *TEMPLATE_get_between_type(void *self)
if(!between_type) {
ir_entity *ret_addr_ent;
ir_type *ret_addr_type = new_type_primitive(new_id_from_str("return_addr"), mode_P);
ir_type *old_bp_type = new_type_primitive(new_id_from_str("bp"), mode_P);
ir_type *ret_addr_type = new_type_primitive(mode_P);
ir_type *old_bp_type = new_type_primitive(mode_P);
between_type = new_type_class(new_id_from_str("TEMPLATE_between_type"));
old_bp_ent = new_entity(between_type, new_id_from_str("old_bp"), old_bp_type);
......
......@@ -436,7 +436,7 @@ static void handle_calls(ir_node *call, void *env)
n = i;
n_param = get_method_n_params(mtp) - n + idx;
n_res = get_method_n_ress(mtp);
new_mtd = new_d_type_method(get_type_ident(mtp), n_param, n_res, get_type_dbg_info(mtp));
new_mtd = new_d_type_method(n_param, n_res, get_type_dbg_info(mtp));
for (i = 0; i < idx; ++i)
set_method_param_type(new_mtd, i, new_tp[i]);
......@@ -505,7 +505,7 @@ static void *arm_cg_init(be_irg_t *birg) {
if (! int_tp) {
/* create an integer type with machine size */
int_tp = new_type_primitive(new_id_from_chars("int", 3), mode_Is);
int_tp = new_type_primitive(mode_Is);
}
cg = XMALLOC(arm_code_gen_t);
......@@ -543,14 +543,14 @@ static void arm_handle_intrinsics(void) {
#define ID(x) new_id_from_chars(x, sizeof(x)-1)
int_tp = new_type_primitive(ID("int"), mode_Is);
uint_tp = new_type_primitive(ID("uint"), mode_Iu);
int_tp = new_type_primitive(mode_Is);
uint_tp = new_type_primitive(mode_Iu);
/* ARM has neither a signed div instruction ... */
{
i_instr_record *map_Div = &records[n_records++].i_instr;
tp = new_type_method(ID("rt_iDiv"), 2, 1);
tp = new_type_method(2, 1);
set_method_param_type(tp, 0, int_tp);
set_method_param_type(tp, 1, int_tp);
set_method_res_type(tp, 0, int_tp);
......@@ -576,7 +576,7 @@ static void arm_handle_intrinsics(void) {
{
i_instr_record *map_Div = &records[n_records++].i_instr;
tp = new_type_method(ID("rt_uDiv"), 2, 1);
tp = new_type_method(2, 1);
set_method_param_type(tp, 0, uint_tp);
set_method_param_type(tp, 1, uint_tp);
set_method_res_type(tp, 0, uint_tp);
......@@ -602,7 +602,7 @@ static void arm_handle_intrinsics(void) {
{
i_instr_record *map_Mod = &records[n_records++].i_instr;
tp = new_type_method(ID("rt_iMod"), 2, 1);
tp = new_type_method(2, 1);
set_method_param_type(tp, 0, int_tp);
set_method_param_type(tp, 1, int_tp);
set_method_res_type(tp, 0, int_tp);
......@@ -628,7 +628,7 @@ static void arm_handle_intrinsics(void) {
{
i_instr_record *map_Mod = &records[n_records++].i_instr;
tp = new_type_method(ID("rt_uMod"), 2, 1);
tp = new_type_method(2, 1);
set_method_param_type(tp, 0, uint_tp);
set_method_param_type(tp, 1, uint_tp);
set_method_res_type(tp, 0, uint_tp);
......
......@@ -2134,7 +2134,7 @@ static ir_entity *create_pic_symbol(be_main_env_t *be, ir_entity *entity)
ident *old_id = get_entity_ld_ident(entity);
ident *id = id_mangle3("L", old_id, "$non_lazy_ptr");
ir_type *e_type = get_entity_type(entity);
ir_type *type = new_type_pointer(id, e_type, mode_P_data);
ir_type *type = new_type_pointer(e_type);
ir_type *parent = be->pic_symbols_type;
ir_entity *ent = new_entity(parent, old_id, type);
set_entity_ld_ident(ent, id);
......
......@@ -207,6 +207,13 @@ static void be_emit_tv_as_decimal(tarval *tv) {
set_tarval_mode_output_option(mode, old);
}
static void emit_type_name(const ir_type *type)
{
char buf[256];
ir_print_type(buf, sizeof(buf), type);
be_emit_string(buf);
}
/**
* Generates a primitive type.
*
......@@ -233,7 +240,9 @@ static void gen_primitive_type(stabs_handle *h, ir_type *tp) {
type_num = get_type_number(h, tp);
if (mode_is_int(mode)) {
be_emit_irprintf("\t.stabs\t\"%s:t%u=r%u;", get_type_name(tp), type_num, type_num);
be_emit_cstring("\t.stabs\t\"");
emit_type_name(tp);
be_emit_irprintf(":t%u=r%u;", type_num, type_num);
be_emit_tv_as_decimal(get_mode_min(mode));
be_emit_char(';');
be_emit_tv_as_decimal(get_mode_max(mode));
......@@ -241,7 +250,9 @@ static void gen_primitive_type(stabs_handle *h, ir_type *tp) {
be_emit_write_line();
} else if (mode_is_float(mode)) {
int size = get_type_size_bytes(tp);
be_emit_irprintf("\t.stabs\t\"%s:t%u=r1;%d;0;\",%d,0,0,0\n", get_type_name(tp), type_num, size, N_LSYM);
be_emit_cstring("\t.stabs\t\"");
emit_type_name(tp);
be_emit_irprintf(":t%u=r1;%d;0;\",%d,0,0,0\n", type_num, size, N_LSYM);
be_emit_write_line();
}
} /* gen_primitive_type */
......@@ -257,13 +268,15 @@ static void gen_enum_type(stabs_handle *h, ir_type *tp) {
int i, n;
SET_TYPE_READY(tp);
be_emit_irprintf("\t.stabs\t\"%s:T%u=e", get_type_name(tp), type_num);
be_emit_cstring("\t.stabs\t\"");
emit_type_name(tp);
be_emit_irprintf(":T%u=e", type_num);
for (i = 0, n = get_enumeration_n_enums(tp); i < n; ++i) {
ir_enum_const *ec = get_enumeration_const(tp, i);
char buf[64];
tarval_snprintf(buf, sizeof(buf), get_enumeration_value(ec));
be_emit_irprintf("%s:%s,", get_enumeration_name(ec), buf);
be_emit_irprintf("%s:%s,", get_enumeration_const_name(ec), buf);
}
be_emit_irprintf(";\",%d,0,0,0\n", N_LSYM);
be_emit_write_line();
......@@ -294,7 +307,9 @@ static void gen_pointer_type(wenv_t *env, ir_type *tp) {
if (! IS_TYPE_READY(el_tp))
waitq_put(env->wq, el_tp);
be_emit_irprintf("\t.stabs\t\"%s:t", get_type_name(tp));
be_emit_cstring("\t.stabs\t\"");