X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftype.h;h=98989dd751bedf8455a7342272025453628b1590;hb=b07ec8c98f79e2f8404c47f769cddf4062fc18a5;hp=16c1713a041d6f36d896576c3ca6d0d79e9349eb;hpb=e18eba3e4511208f4eaccc1501ead35ba8c555b8;p=libfirm diff --git a/ir/tr/type.h b/ir/tr/type.h index 16c1713a0..98989dd75 100644 --- a/ir/tr/type.h +++ b/ir/tr/type.h @@ -1,5 +1,4 @@ /** - * * @file type.h * * Project: libFIRM
@@ -36,25 +35,12 @@ # ifndef _TYPE_H_ # define _TYPE_H_ -#include - +# include "firm_types.h" # include "tpop.h" # include "firm_common.h" # include "ident.h" # include "irmode.h" # include "dbginfo.h" - -/* to resolve recursion between entity.h and type.h */ -#ifndef _ENTITY_TYPEDEF_ -#define _ENTITY_TYPEDEF_ -typedef struct entity entity; -#endif - -#ifndef _IR_NODE_TYPEDEF_ -#define _IR_NODE_TYPEDEF_ -typedef struct ir_node ir_node; -#endif - # include "tr_inheritance.h" /** @@ -119,7 +105,7 @@ typedef struct ir_node ir_node; */ #ifndef _TYPE_TYPEDEF_ #define _TYPE_TYPEDEF_ -typedef struct type type; +typedef struct ir_type type; #endif # include "type_or_entity.h" @@ -149,6 +135,73 @@ ident* get_type_ident(const type *tp); void set_type_ident(type *tp, ident* id); const char* get_type_name(const type *tp); +/** This enumeration flags the visibility of entities and types. + * + * This is necessary for partial compilation. + * We rely on the ordering of the flags. + */ +typedef enum { + visibility_local, /**< The entity is only visible locally. This is the default for + entities. + The type is only visible locally. All instances are allocated + locally, and no pointer to entities of this type are passed + out of this compilation unit. */ + visibility_external_visible, /**< The entity is visible to other external program parts, but + it is defined here. It may not be optimized away. The entity must + be static_allocated. + For types: entities of this type can be accessed externally. No + instances of this type are allocated externally. */ + visibility_external_allocated /**< The entity is defined and allocated externally. This compilation + must not allocate memory for this entity. The entity must + be static_allocated. This can also be an external defined + method. + For types: entities of this type are allocated and accessed from + external code. Default for types. */ +} visibility; + +/** The visibility of a type. + * + * The visibility of a type indicates, whether entities of this type + * are accessed or allocated in external code. + * + * An entity of a type is allocated in external code, if the external + * code declares a variable of this type, or dynamically allocates + * an entity of this type. If the external code declares a (compound) + * type, that contains entities of this type, the visibility also + * must be external_allocated. + * + * The visibility must be higher than that of all entities, if the + * type is a compound. Here it is questionable, what happens with + * static entities. If these are accessed external by direct reference, + * (a static call to a method, that is also in the dispatch table) + * it should not affect the visibility of the type. + * + * + * @@@ Do we need a visibility for types? + * I change the layout of types radically when doing type splitting. + * I need to know, which fields of classes are accessed in the RTS, + * e.g., [_length. I may not move [_length to the split part. + * The layout though, is a property of the type. + * + * One could also think of changing the mode of a type ... + * + * But, we could also output macros to access the fields, e.g., + * ACCESS_[_length (X) X->length // conventional + * ACCESS_[_length (X) X->_split_ref->length // with type splitting + * + * For now I implement this function, that returns the visibility + * based on the visibility of the entities of a compound ... + * + * This function returns visibility_external_visible if one or more + * entities of a compound type have visibility_external_visible. + * Entities of types are never visibility_external_allocated (right?). + * Else returns visibility_local. + */ +visibility get_type_visibility (const type *tp); +void set_type_visibility (type *tp, visibility v); + + + /** The state of the type layout. */ typedef enum { layout_undefined, /**< The layout of this type is not defined. @@ -189,7 +242,7 @@ ir_mode* get_type_mode(const type *tp); void set_type_mode(type *tp, ir_mode* m); /** Returns the size of a type in bytes, returns -1 if the size is NOT - * a byte size, ie not dividable by 8. */ + * a byte size, i.e. not dividable by 8. */ int get_type_size_bytes(const type *tp); /** Returns the size of a type in bits. */ @@ -219,11 +272,11 @@ int get_type_alignment_bytes(type *tp); * * If the alignment of a type is * not set, it is calculated here according to the following rules: - * 1.) if a type has a mode, the alignment is the mode size. - * 2.) compound types have the alignment of it's biggest member. - * 3.) array types have the alignment of its element type. - * 4.) method types return 0 here. - * 5.) all other types return 8 here (i.e. aligned at byte). + * -#.) if a type has a mode, the alignment is the mode size. + * -#.) compound types have the alignment of there biggest member. + * -#.) array types have the alignment of there element type. + * -#.) method types return 0 here. + * -#.) all other types return 8 here (i.e. aligned at byte). */ int get_type_alignment_bits(type *tp); @@ -241,24 +294,26 @@ unsigned long get_type_visited(const type *tp); void set_type_visited(type *tp, unsigned long num); /* Sets visited field in type to type_visited. */ void mark_type_visited(type *tp); -/* @@@ name clash!! int type_visited(const type *tp); */ +int type_visited(const type *tp); int type_not_visited(const type *tp); +/** Returns the associated link field of a type. */ void* get_type_link(const type *tp); +/** Sets the associated link field of a type. */ void set_type_link(type *tp, void *l); /** * Visited flag to traverse the type information. * - * Increase this flag by one before traversing the type information. - * Mark type nodes as visited by set_type_visited(type, type_visited). - * Check whether node was already visited by comparing get_type_visited(type) - * and type_visited. + * Increase this flag by one before traversing the type information + * using inc_master_type_visited(). + * Mark type nodes as visited by mark_type_visited(type). + * Check whether node was already visited by type_visited(type) + * and type_not_visited(type). * Or use the function to walk all types. * * @see typewalk */ -extern unsigned long type_visited; void set_master_type_visited(unsigned long val); unsigned long get_master_type_visited(void); void inc_master_type_visited(void); @@ -276,17 +331,18 @@ int is_type (const void *thing); /** * Checks whether two types are structurally equal. * - * @param st pointer type - * @param lt pointer type + * @param typ1 the first type + * @param typ2 the second type * * @return * true if the types are equal, else false. - * Types are equal if : + * + * Types are equal if : * - they are the same type kind * - they have the same name * - they have the same mode (if applicable) * - they have the same type_state and, ev., the same size - * - they are class types and have + * - they are class types and have: * - the same members (see same_entity in entity.h) * - the same supertypes -- the C-pointers are compared --> no recursive call. * - the same number of subtypes. Subtypes are not compared, @@ -305,10 +361,10 @@ int is_type (const void *thing); * - they are enumeration types and have the same enumerator names * - they are pointer types and have the identical points_to type * (i.e., the same C-struct to represent the type, type_id is skipped. - * This is to avoid endless recursions; with pointer types circlic + * This is to avoid endless recursions; with pointer types cyclic * type graphs are possible.) */ -int equal_type(type *tpy1, type *typ2); +int equal_type(type *typ1, type *typ2); /** * Checks whether two types are structural comparable. @@ -355,7 +411,7 @@ int smaller_type (type *st, type *lt); * Further a class can inherit from and bequest to other classes. * @@@ value class??? * The following attributes are private to this type kind: - * - member: All entities belonging to this class. This are methode entities + * - member: All entities belonging to this class. This are method entities * which have type_method or fields that can have any of the * following type kinds: type_class, type_struct, type_union, * type_array, type_enumeration, type_pointer, type_primitive. @@ -432,6 +488,12 @@ int get_class_n_subtypes (const type *clss); /** Gets the subtype at position pos, 0 <= pos < n_subtype. */ type *get_class_subtype (type *clss, int pos); +/** Returns the index to access subclass as subtype of class. + * + * If subclass is no direct subtype of class returns -1. + */ +int get_class_subtype_index(type *clss, const type *subclass); + /** Sets the subtype at position pos, 0 <= pos < n_subtype. * * Does not set the corresponding supertype relation for subtype: this might @@ -441,6 +503,13 @@ void set_class_subtype (type *clss, type *subtype, int pos); /** Finds subtype in the list of subtypes and removes it */ void remove_class_subtype(type *clss, type *subtype); +/* Convenience macros */ +#define add_class_derived_type(clss, drvtype) add_class_subtype(clss, drvtype) +#define get_class_n_derived_types(clss) get_class_n_subtypes(clss) +#define get_class_derived_type(clss, pos) get_class_subtype(clss, pos) +#define get_class_derived_type_index(clss, drvtype) get_class_subtype_index(clss, drvtype) +#define set_class_derived_type(clss, drvtype, pos) set_class_subtype(clss, drvtype, pos) +#define remove_class_derived_type(clss, drvtype) remove_class_subtype(clss, drvtype) /** Adds supertype as supertype to class. * @@ -451,7 +520,10 @@ void add_class_supertype (type *clss, type *supertype); /** Returns the number of supertypes */ int get_class_n_supertypes (const type *clss); -/** Returns the index of an supertype in a type. */ +/** Returns the index to access superclass as supertype of class. + * + * If superclass is no direct supertype of class returns -1. + */ int get_class_supertype_index(type *clss, type *super_clss); /** Gets the supertype at position pos, 0 <= pos < n_supertype. */ @@ -466,6 +538,22 @@ void set_class_supertype (type *clss, type *supertype, int pos); /** Finds supertype in the list of supertypes and removes it */ void remove_class_supertype(type *clss, type *supertype); +/** Convenience macro */ +#define add_class_base_type(clss, basetype) add_class_supertype(clss, basetype) +#define get_class_n_base_types(clss) get_class_n_supertypes(clss) +#define get_class_base_type_index(clss, base_clss) get_class_supertype_index(clss, base_clss) +#define get_class_base_type(clss, pos) get_class_supertype(clss, pos) +#define set_class_base_type(clss, basetype, pos) set_class_supertype(clss, basetype, pos) +#define remove_class_base_type(clss, basetype) remove_class_supertype(clss, basetype) + +/** Convenience macro */ +#define add_class_base_type(clss, basetype) add_class_supertype(clss, basetype) +#define get_class_n_base_types(clss) get_class_n_supertypes(clss) +#define get_class_base_type_index(clss, base_clss) get_class_supertype_index(clss, base_clss) +#define get_class_base_type(clss, pos) get_class_supertype(clss, pos) +#define set_class_base_type(clss, basetype, pos) set_class_supertype(clss, basetype, pos) +#define remove_class_base_type(clss, basetype) remove_class_supertype(clss, basetype) + /** This enumeration flags the peculiarity of entities and types. */ typedef enum peculiarity { peculiarity_description, /**< Represents only a description. The entity/type is never @@ -484,9 +572,9 @@ typedef enum peculiarity { } peculiarity; const char *get_peculiarity_string(peculiarity p); -/* The peculiarity of the class. The enumeration peculiarity is defined - in entity.h */ +/** Returns the peculiarity of the class. */ peculiarity get_class_peculiarity (const type *clss); +/** Sets the peculiarity of the class. */ void set_class_peculiarity (type *clss, peculiarity pec); /* Set and get a class' dfn -- @@ -622,7 +710,9 @@ entity *get_method_value_param_ent(type *method, int pos); */ type *get_method_value_param_type(const type *method); +/** Returns the number of results of a method type. */ int get_method_n_ress (const type *method); +/** Returns the return type of a method type at position pos. */ type *get_method_res_type(type *method, int pos); /** Sets the type of the result at position pos of a method. Also changes the type in the pass-by-value representation by just @@ -638,7 +728,7 @@ entity *get_method_value_res_ent(type *method, int pos); type *get_method_value_res_type(const type *method); /** - * this enum flags the variadicity of methods (methods with a + * This enum flags the variadicity of methods (methods with a * variable amount of arguments (e.g. C's printf). Default is * non_variadic. */ @@ -672,11 +762,116 @@ int get_method_first_variadic_param_index(const type *method); */ void set_method_first_variadic_param_index(type *method, int index); +/** + * additional method type properties: + * Tell about special properties of a method type. Some + * of these may be discovered by analyses. + */ +typedef enum { + mtp_no_property = 0x00000000, /**< no additional properties, default */ + mtp_property_const = 0x00000001, /**< This method did not access memory and calculates + its return values solely from its parameters. + GCC: __attribute__((const)). */ + mtp_property_pure = 0x00000002, /**< This method did NOT write to memory and calculates + its return values solely form its parameters and + the memory they points to (or global vars). + GCC: __attribute__((pure)). */ + mtp_property_noreturn = 0x00000004, /**< This method did not return due to an aborting system + call. + GCC: __attribute__((noreturn)). */ + mtp_property_nothrow = 0x00000008, /**< This method cannot throw an exception. + GCC: __attribute__((nothrow)). */ + mtp_property_naked = 0x00000010, /**< This method is naked. + GCC: __attribute__((naked)). */ + mtp_property_malloc = 0x00000020, /**< This method returns newly allocate memory. + GCC: __attribute__((malloc)). */ + mtp_property_inherited = 0x40000000 /**< used only in irg's, means property is inherited + from type. */ +} mtp_additional_property; + +/** Returns the mask of the additional graph properties. */ +unsigned get_method_additional_properties(const type *method); + +/** Sets the mask of the additional graph properties. */ +void set_method_additional_properties(type *method, unsigned property_mask); + +/** Sets one additional graph property. */ +void set_method_additional_property(type *method, mtp_additional_property flag); + +/** + * calling conventions: lower 24 bits are the number of register parameters, + * upper 8 encode the calling conventions + */ +typedef enum { + cc_reg_param = 0x01000000, /**< Transmit parameters in registers, else the stack is used. + This flag may be set as default on some architectures. */ + cc_last_on_top = 0x02000000, /**< The last non-register parameter is transmitted on top of + the stack. This is equivalent to the stdcall or pascal + calling convention. If this flag is not set, the first + non-register parameter is used (cdecl calling convention) */ + cc_callee_clear_stk = 0x04000000, /**< The callee clears the stack. This forbids variadic + function calls (stdcall). */ + cc_this_call = 0x08000000, /**< The first parameter is a this pointer and is transmitted + in a special way. */ + + /* some often used cases */ + cc_cdecl_set = 0, /**< cdecl calling convention */ + cc_stdcall_set = cc_callee_clear_stk, /**< stdcall calling convention */ + cc_fastcall_set = cc_reg_param|cc_callee_clear_stk, /**< fastcall calling convention */ + + cc_bits = (0xFF << 24) /**< the calling convention bits */ +} calling_convention; + +/** return the default calling convention for method types */ +unsigned get_default_cc_mask(void); + +/** + * check for the CDECL calling convention + */ +#define IS_CDECL(cc_mask) (((cc_mask) & cc_bits) == cc_cdecl_set) + +/** + * check for the STDCALL calling convention + */ +#define IS_STDCALL(cc_mask) (((cc_mask) & cc_bits) == cc_stdcall_set) + +/** + * check for the FASTCALL calling convention + */ +#define IS_FASTCALL(cc_mask) (((cc_mask) & cc_bits) == cc_fastcall_set) + +/** + * set the CDECL convention bits + */ +#define SET_CDECL(cc_mask) (((cc_mask) & ~cc_bits) | cc_cdecl_set) + +/** + * set the STDCALL convention bits + */ +#define SET_STDCALL(cc_mask) (((cc_mask) & ~cc_bits) | cc_stdcall_set) + +/** + * set the FASTCALL convention bits + */ +#define SET_FASTCALL(cc_mask) (((cc_mask) & ~cc_bits) | cc_fastcall_set) + +/** Returns the calling convention of an entities graph. */ +unsigned get_method_calling_convention(const type *method); + +/** Sets the calling convention of an entities graph. */ +void set_method_calling_convention(type *method, unsigned cc_mask); + +/** Returns the number of registers parameters, 0 means default. */ +unsigned get_method_n_regparams(type *method); + +/** Sets the number of registers parameters, 0 means default. */ +void set_method_n_regparams(type *method, unsigned n_regs); + /** Returns true if a type is a method type. */ int is_Method_type (const type *method); /** - * @page union_type Representation of a union type. + * @page union_type Representation of a union (variant) type. * * The union type represents union types. * - n_types: Number of unioned types. @@ -757,48 +952,62 @@ int get_array_n_dimensions (const type *array); /** * Allocates Const nodes of mode_I for one array dimension. - * Upper bound in Firm is the element next to the last, ie [lower,upper[ + * Upper bound in Firm is the element next to the last, i.e. [lower,upper[ */ void set_array_bounds_int (type *array, int dimension, int lower_bound, int upper_bound); /** * Sets the bounds for one array dimension. - * Upper bound in Firm is the element next to the last, ie [lower,upper[ + * Upper bound in Firm is the element next to the last, i.e. [lower,upper[ */ void set_array_bounds (type *array, int dimension, ir_node *lower_bound, ir_node *upper_bound); -/** Sets the lower bound for one array dimension, ie [lower,upper[ */ +/** Sets the lower bound for one array dimension, i.e. [lower,upper[ */ void set_array_lower_bound (type *array, int dimension, ir_node *lower_bound); /** Allocates Const nodes of mode_I for the lower bound of an array - dimension, ie [lower,upper[ */ + dimension, i.e. [lower,upper[ */ void set_array_lower_bound_int (type *array, int dimension, int lower_bound); -/** Sets the upper bound for one array dimension, ie [lower,upper[ */ +/** Sets the upper bound for one array dimension, i.e. [lower,upper[ */ void set_array_upper_bound (type *array, int dimension, ir_node *upper_bound); /** Allocates Const nodes of mode_I for the upper bound of an array - dimension, ie [lower,upper[ */ + dimension, i.e. [lower,upper[. */ void set_array_upper_bound_int (type *array, int dimension, int upper_bound); -/** returns true if lower bound != Unknown */ +/** Returns true if lower bound != Unknown. */ int has_array_lower_bound (const type *array, int dimension); +/** Returns the lower bound of an array. */ ir_node * get_array_lower_bound (const type *array, int dimension); /** Works only if bound is Const node with tarval that can be converted to long. */ long get_array_lower_bound_int (const type *array, int dimension); /** returns true if lower bound != Unknown */ int has_array_upper_bound (const type *array, int dimension); +/** Returns the upper bound of an array. */ ir_node * get_array_upper_bound (const type *array, int dimension); /** Works only if bound is Const node with tarval that can be converted to long. */ long get_array_upper_bound_int (const type *array, int dimension); +/** Sets an array dimension to a specific order. */ void set_array_order (type *array, int dimension, int order); + +/** Returns the order of an array dimension. */ int get_array_order (const type *array, int dimension); +/** Find the array dimension that is placed at order ord. */ +int find_array_dimension(const type *array, int order); + +/** Sets the array element type. */ void set_array_element_type (type *array, type *tp); + +/** Gets the array element type. */ type *get_array_element_type (type *array); +/** Sets the array element entity. */ void set_array_element_entity (type *array, entity *ent); + +/** Get the array element entity. */ entity *get_array_element_entity (const type *array); /** Returns true if a type is an array type. */ @@ -848,19 +1057,16 @@ int is_Enumeration_type (const type *enumeration); /** * @page pointer_type Representation of a pointer type * - * The mode of the pointer type must be a mode_reference. + * 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 with mode mode_p. */ -#define new_type_pointer(N, P) new_type_pointer_mode(N, P, mode_P_mach) +/** Creates a new type pointer. */ +type *new_type_pointer (ident *name, type *points_to, ir_mode *ptr_mode); -/** Creates a new type pointer with given pointer mode. */ -type *new_type_pointer_mode (ident *name, type *points_to, ir_mode *ptr_mode); - -/** Creates a new type pointer given pointer mode and with debug information. */ +/** Creates a new type pointer with debug information. */ type *new_d_type_pointer (ident *name, type *points_to, ir_mode *ptr_mode, dbg_info* db); /* --- manipulate fields of type_pointer --- */ @@ -908,14 +1114,14 @@ int is_Primitive_type (const type *primitive); * allocated when initializing the type module. * * The following values are set: - * mode: mode_BAD - * name: "type_none" - * state: layout_fixed - * size: 0 + * - mode: mode_BAD + * - name: "type_none" + * - state: layout_fixed + * - size: 0 */ -/* A variable that contains the only none type. */ +/** A variable that contains the only none type. */ extern type *firm_none_type; -/* Returns the none type */ +/** Returns the none type */ type *get_none_type(void); /** @@ -930,20 +1136,20 @@ type *get_none_type(void); * allocated when initializing the type module. * * The following values are set: - * mode: mode_ANY - * name: "type_unknown" - * state: layout_fixed - * size: 0 + * - mode: mode_ANY + * - name: "type_unknown" + * - state: layout_fixed + * - size: 0 */ -/* A variable that contains the only unknown type. */ +/** A variable that contains the only unknown type. */ extern type *firm_unknown_type; -/* Returns the unknown type */ +/** Returns the unknown type */ type *get_unknown_type(void); /** * Checks whether a type is atomic. - * @param tp - any type + * @param tp any type * @return true if type is primitive, pointer or enumeration */ int is_atomic_type(const type *tp); @@ -971,19 +1177,34 @@ int get_compound_n_members(const type *tp); * * @return The member entity at position pos. * - * @see get_compound_n_members() for justifaction of existence. + * @see get_compound_n_members() for justification of existence. */ entity *get_compound_member(const type *tp, int pos); /** - * Checks whether a type is compound. + * Checks whether a type is compound. * - * @param tp - any type + * @param tp - any type * - * @return true if the type is class, structure, union or array type. + * @return true if the type is class, structure, union or array type. */ int is_compound_type(const type *tp); +/** + * Checks, whether a type is a frame type + */ +int is_frame_type(const type *tp); + +/** + * 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. + */ +type *new_type_frame(ident *name); + +/*-----------------------------------------------------------------*/ +/** Debug aides **/ +/*-----------------------------------------------------------------*/ /** * Outputs a unique number for this type if libfirm is compiled for @@ -992,11 +1213,5 @@ int is_compound_type(const type *tp); */ long get_type_nr(const type *tp); -/*******************************************************************/ -/** Debug aides **/ -/*******************************************************************/ - - - # endif /* _TYPE_H_ */