X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=include%2Flibfirm%2Ftyperep.h;h=bc13f240803145f57b746e417efe8fbe4b7df20f;hb=d217f68a9e53ec6e800ae31ca3af8ed8b6f9ece9;hp=efe353e7fa3eb8d539c8927fec2a5d555ad348a2;hpb=901bb930a86871ff22dd4aa1c34424a3083ef5fa;p=libfirm diff --git a/include/libfirm/typerep.h b/include/libfirm/typerep.h index efe353e7f..bc13f2408 100644 --- a/include/libfirm/typerep.h +++ b/include/libfirm/typerep.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -16,13 +16,21 @@ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. */ + +/** + * @file + * @brief Declarations for functions and datastructures to represent types + */ #ifndef FIRM_TYPEREP_H #define FIRM_TYPEREP_H +#include #include "firm_types.h" +#include "begin.h" + /** - * @page entity Entity representation + * @defgroup ir_entity Entities * * An entity is the representation of program known objects in Firm. * The primary concept of entities is to represent members of complex @@ -46,15 +54,8 @@ * * - owner: A compound type this entity is a part of. * - type: The type of this entity. - * - name: The string that represents this entity in the source program. - * - allocation: A flag saying whether the entity is dynamically or statically - * allocated (values: dynamic_allocated, static_allocated, - * automatic_allocated). - * - visibility: A flag indicating the visibility of this entity (values: local, - * external_visible, external_allocated) - * - variability: A flag indicating the variability of this entity (values: - * uninitialized, initialized, part_constant, constant) - * - volatility: @@@ + * - name: The string that represents this entity in the source program + * - linkage: A flag indicating how the linker treats a symbol * - offset: The offset of the entity within the compound object in bytes. Only set * if the owner in the state "layout_fixed". * - offset_bits_remainder: The offset bit remainder of a bitfield entity (in a compound) @@ -68,59 +69,123 @@ * - link: A void* to associate some additional information with the entity. * - irg: If the entity is a method this is the ir graph that represents the * code of the method. - * - peculiarity: The peculiarity of the entity. If the entity is a method this - * indicates whether the entity represents - * a real method or whether it only exists to describe an interface. - * In that case there nowhere exists code for this entity and this entity - * is never dynamically used in the code. - * Values: description, existent. Default: existent. * - visited: visited flag. Master flag is type_visited. * * These fields can only be accessed via access functions. * - * @see ir_type, ir_entity + * Overwrites is a field that specifies that an access to the overwritten + * entity in the supertype must use this entity. It's a list as with + * multiple inheritance several entities can be overwritten. This field + * is mostly useful for method entities. + * If a Sel node selects an entity that is overwritten by other entities it + * must return a pointer to the entity of the dynamic type of the pointer + * that is passed to it. Lowering of the Sel node must assure this. + * Overwrittenby is the inverse of overwrites. Both add routines add + * both relations, they only differ in the order of arguments. + * + * @{ */ -/** This enumeration flags the visibility of entities and types. - * - * This is necessary for partial compilation. - * We rely on the ordering of the flags. +/** + * Visibility classed for entities. */ 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. */ + /** + * The entity is visible outside the compilation unit, but it is defined + * here. + */ + ir_visibility_default, + /** + * The entity is local to the compilation unit. + * A local entity is not visible in other compilation units. + * Note that the entity might still be accessed indirectly from other units + * through pointers. + */ + ir_visibility_local, + /** + * The entity is defined outside the compilation unit but potentially used + * here. + */ + ir_visibility_external, + /** + * This has the same semantic as visibility_local. Additionally the symbol is + * completely hidden from the linker (it only appears in the assembly). + * While visibility_local is probably still visible to debuggers, + * visibility_private symbols aren't and probably won't appear in the object + * files + */ + ir_visibility_private } ir_visibility; -/** This enumeration flags the peculiarity of entities and types. */ -typedef enum { - peculiarity_description, /**< Represents only a description. The entity/type is never - allocated, no code/data exists for this entity/type. - @@@ eventually rename to descriptive (adjective as the others!)*/ - peculiarity_inherited, /**< Describes explicitly that other entities are - inherited to the owner of this entity. - Overwrites must refer to at least one other - entity. If this is a method entity there exists - no irg for this entity, only for one of the - overwritten ones. - Only for entity. */ - peculiarity_existent /**< The entity/type (can) exist. - @@@ eventually rename to 'real' i.e., 'echt' - This serves better as opposition to description _and_ inherited.*/ -} ir_peculiarity; +/** + * linkage specifies how the linker treats symbols + */ +typedef enum ir_linkage { + IR_LINKAGE_DEFAULT = 0, + /** + * A symbol whose definition won't change in a program. + * Optimisation might replace loads from this entity with constants. + * Also most linkers put such data in a constant segment which is shared + * between multiple running instances of the same application. + */ + IR_LINKAGE_CONSTANT = 1 << 0, + /** + * The entity is a weak symbol. + * A weak symbol is overridden by a non-weak symbol if one exists. + * Most linkers only support the IR_LINKAGE_WEAK in combination with + * IR_LINKAGE_MERGE. + */ + IR_LINKAGE_WEAK = 1 << 1, + /** + * The entity may be removed when it isn't referenced anywhere in the + * compilation unit even if it is exported (non-local). + * Typically used for C++ instantiated template code (,,COMDAT'' section). + */ + IR_LINKAGE_GARBAGE_COLLECT = 1 << 2, + /** + * The linker will try to merge entities with same name from different + * compilation units. This is the usual behaviour for global variables + * without explicit initialisation in C (``COMMON'' symbols). It's also + * typically used in C++ for instantiated template code (,,COMDAT'' section) + */ + IR_LINKAGE_MERGE = 1 << 3, + /** + * Some entity uses are potentially hidden from the compiler. + * (For example because they happen in an asm("") statement. This flag + * should be set for __attribute__((used)) in C code). + * Setting this flag prohibits that the compiler making assumptions about + * read/write behaviour to global variables or changing calling conventions + * from cdecl to fastcall. + */ + IR_LINKAGE_HIDDEN_USER = 1 << 4 +} ir_linkage; +ENUM_BITSET(ir_linkage) + +/** + * Returns the visibility class of an entity + */ +FIRM_API ir_visibility get_entity_visibility(const ir_entity *entity); + +/** + * Sets visibility class of an entity + */ +FIRM_API void set_entity_visibility(ir_entity *entity, ir_visibility visibility); + +/** + * Returns 1 if the entity is visible outside the current compilation unit + * or to unknown callers (like asm statements). + * (The entity might still be accessible indirectly through pointers) + * This is a convenience function and does the same as + * get_entity_visibility(entity) != ir_visibility_local || + * (get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) + */ +FIRM_API int entity_is_externally_visible(const ir_entity *entity); + +/** + * Returns 1 if the entity has a definition (initializer) in the current + * compilation unit + */ +FIRM_API int entity_has_definition(const ir_entity *entity); /** * Creates a new entity. @@ -131,7 +196,7 @@ typedef enum { * value is a pointer to the method. * Visibility is local, offset -1, and it is not volatile. */ -ir_entity *new_entity(ir_type *owner, ident *name, ir_type *tp); +FIRM_API ir_entity *new_entity(ir_type *owner, ident *name, ir_type *tp); /** * Creates a new entity. @@ -142,7 +207,31 @@ ir_entity *new_entity(ir_type *owner, ident *name, ir_type *tp); * value is a pointer to the method. * Visibility is local, offset -1, and it is not volatile. */ -ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *tp, dbg_info *db); +FIRM_API ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *tp, + dbg_info *db); + +/** + * Creates a new entity corresponding to a function parameter. + * This must be created on an irgs frame_type + */ +FIRM_API ir_entity *new_parameter_entity(ir_type *owner, size_t pos, + ir_type *type); + +/** + * Like new_parameter_entity() but with debug information. + */ +FIRM_API ir_entity *new_d_parameter_entity(ir_type *owner, size_t pos, + ir_type *type, dbg_info *dbgi); + +/** + * Check an entity. Currently, we check only if initialized constants + * are build on the const irg graph. + * + * @return + * 0 if no error encountered + * != 0 a trverify_error_codes code + */ +FIRM_API int check_entity(ir_entity *ent); /** * Copies the entity if the new_owner is different from the @@ -151,12 +240,8 @@ ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *tp, dbg_info *db); * Automatically inserts the new entity as a member of owner. * Resets the overwrites/overwritten_by fields. * Keeps the old atomic value. - * @@@ Maybe we should change this. If peculiarity of a method - * is existent, we should add a new SymConst that points to - * itself and not to the origin. Right now we have to change - * the peculiarity and then set a new atomic value by hand. */ -ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner); +FIRM_API ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner); /** * Copies the entity if the new_name is different from the @@ -166,7 +251,7 @@ ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner); * The mangled name ld_name is set to NULL. * Overwrites relation is copied from old. */ -ir_entity *copy_entity_name(ir_entity *old, ident *new_name); +FIRM_API ir_entity *copy_entity_name(ir_entity *old, ident *new_name); /** * Frees the entity. @@ -174,16 +259,16 @@ ir_entity *copy_entity_name(ir_entity *old, ident *new_name); * The owner will still contain the pointer to this * entity, as well as all other references! */ -void free_entity(ir_entity *ent); +FIRM_API void free_entity(ir_entity *ent); /** Returns the name of an entity. */ -const char *get_entity_name(const ir_entity *ent); +FIRM_API const char *get_entity_name(const ir_entity *ent); /** Returns the ident of an entity. */ -ident *get_entity_ident(const ir_entity *ent); +FIRM_API ident *get_entity_ident(const ir_entity *ent); /** Sets the ident of the entity. */ -void set_entity_ident(ir_entity *ent, ident *id); +FIRM_API void set_entity_ident(ir_entity *ent, ident *id); /** Returns the mangled name of the entity. * @@ -191,186 +276,128 @@ void set_entity_ident(ir_entity *ent, ident *id); * Else it generates a name with mangle_entity() * and remembers this new name internally. */ -ident *get_entity_ld_ident(ir_entity *ent); +FIRM_API ident *get_entity_ld_ident(const ir_entity *ent); /** Sets the mangled name of the entity. */ -void set_entity_ld_ident(ir_entity *ent, ident *ld_ident); +FIRM_API void set_entity_ld_ident(ir_entity *ent, ident *ld_ident); /** Returns the mangled name of the entity as a string. */ -const char *get_entity_ld_name(ir_entity *ent); +FIRM_API const char *get_entity_ld_name(const ir_entity *ent); + +/** returns 1 if the entity has an ld_ident set explicitely */ +FIRM_API int entity_has_ld_ident(const ir_entity *entity); /** Returns the owner of the entity. */ -ir_type *get_entity_owner(ir_entity *ent); +FIRM_API ir_type *get_entity_owner(const ir_entity *ent); -/** Sets the owner field in entity to owner. Don't forget to add - ent to owner!! */ -void set_entity_owner(ir_entity *ent, ir_type *owner); +/** + * Sets the owner field in entity to owner. + * Automatically removes entity from old owner type and adds it to the new + * one. + */ +FIRM_API void set_entity_owner(ir_entity *ent, ir_type *owner); /** Returns the type of an entity. */ -ir_type *get_entity_type(ir_entity *ent); +FIRM_API ir_type *get_entity_type(const ir_entity *ent); /** Sets the type of an entity. */ -void set_entity_type(ir_entity *ent, ir_type *tp); - -/** The allocation type. */ -typedef enum { - allocation_automatic, /**< The entity is allocated during runtime, implicitly - as component of a compound type. This is the default. */ - allocation_parameter, /**< The entity is a parameter. It is also automatic allocated. - We distinguish the allocation of parameters from the allocation - of local variables as their placement depends on the calling - conventions. */ - allocation_dynamic, /**< The entity is allocated during runtime, explicitly - by an Alloc node. */ - allocation_static /**< The entity is allocated statically. We can use a - Const as address of the entity. This is the default for methods. */ -} ir_allocation; - -/** Returns the allocation type of an entity. */ -ir_allocation get_entity_allocation(const ir_entity *ent); - -/** Sets the allocation type of an entity. */ -void set_entity_allocation(ir_entity *ent, ir_allocation al); - -/** Return the name of the allocation type. */ -const char *get_allocation_name(ir_allocation al); +FIRM_API void set_entity_type(ir_entity *ent, ir_type *tp); -/** Returns the visibility of an entity. */ -ir_visibility get_entity_visibility(const ir_entity *ent); +/** Returns the linkage of an entity. */ +FIRM_API ir_linkage get_entity_linkage(const ir_entity *entity); -/** Sets the visibility of an entity. */ -void set_entity_visibility(ir_entity *ent, ir_visibility vis); +/** Sets the linkage flags of entity @p entity to @p linkage. */ +FIRM_API void set_entity_linkage(ir_entity *entity, ir_linkage linkage); +/** Adds linkage flags @p linkage to entity @p entity. */ +FIRM_API void add_entity_linkage(ir_entity *entity, ir_linkage linkage); +/** Remove linkage flags @p linkage from entity @p entity. */ +FIRM_API void remove_entity_linkage(ir_entity *entity, ir_linkage linkage); -/** Return the name of the visibility */ -const char *get_visibility_name(ir_visibility vis); - -/** This enumeration flags the variability of entities. */ -typedef enum { - variability_uninitialized, /**< The content of the entity is completely unknown. Default. */ - variability_initialized, /**< After allocation the entity is initialized with the - value given somewhere in the entity. */ - variability_part_constant, /**< For entities of compound types. - The members of the entity are mixed constant, - initialized or uninitialized. */ - variability_constant /**< The entity is constant. */ -} ir_variability; - -/** Returns the variability of an entity. */ -ir_variability get_entity_variability(const ir_entity *ent); - -/** Sets the variability of an entity. */ -void set_entity_variability(ir_entity *ent, ir_variability var); - -/** Return the name of the variability. */ -const char *get_variability_name(ir_variability var); - -/** This enumeration flags the volatility of entities and Loads/Stores. */ -typedef enum { - volatility_non_volatile, /**< The entity is not volatile. Default. */ - volatility_is_volatile /**< The entity is volatile. */ -} ir_volatility; - -/** Returns the volatility of an entity. */ -ir_volatility get_entity_volatility(const ir_entity *ent); +/** + * Returns the volatility of an entity. + * @deprecated + */ +FIRM_API ir_volatility get_entity_volatility(const ir_entity *ent); -/** Sets the volatility of an entity. */ -void set_entity_volatility(ir_entity *ent, ir_volatility vol); +/** + * Sets the volatility of an entity. + * @deprecated + */ +FIRM_API void set_entity_volatility(ir_entity *ent, ir_volatility vol); -/** Return the name of the volatility. */ -const char *get_volatility_name(ir_volatility var); +/** Returns the name of the volatility. */ +FIRM_API const char *get_volatility_name(ir_volatility var); /** Returns alignment of entity in bytes */ -unsigned get_entity_alignment(const ir_entity *entity); - -/** Sets alignment for entity in bytes */ -void set_entity_alignment(ir_entity *entity, unsigned alignment); - -/** This enumeration flags the align of Loads/Stores. */ -typedef enum { - align_non_aligned, /**< The entity is not aligned. */ - align_is_aligned /**< The entity is aligned. Default */ -} ir_align; - -/** Returns indication wether entity is aligned in memory. */ -ir_align get_entity_aligned(const ir_entity *ent); - -/** Sets indication wether entity is aligned in memory */ -void set_entity_aligned(ir_entity *ent, ir_align a); +FIRM_API unsigned get_entity_alignment(const ir_entity *entity); -/** Return the name of the alignment. */ -const char *get_align_name(ir_align a); +/** Allows you to override the type alignment for an entity. + * @param entity the entity + * @param alignment alignment in bytes + */ +FIRM_API void set_entity_alignment(ir_entity *entity, unsigned alignment); -/** This enumeration flags the stickyness of an entity. */ -typedef enum { - stickyness_unsticky, /**< The entity can be removed from - the program, unless contraindicated - by other attributes. Default. */ - stickyness_sticky /**< The entity must remain in the - program in any case. There might be external - callers. */ -} ir_stickyness; +/** + * Returns indication whether entity is aligned in memory. + * @deprecated + */ +FIRM_API ir_align get_entity_aligned(const ir_entity *ent); -/** Get the entity's stickyness. */ -ir_stickyness get_entity_stickyness(const ir_entity *ent); +/** + * Sets indication whether entity is aligned in memory + * @deprecated + */ +FIRM_API void set_entity_aligned(ir_entity *ent, ir_align a); -/** Set the entity's stickyness. */ -void set_entity_stickyness(ir_entity *ent, ir_stickyness stickyness); +/** Returns the name of the alignment. */ +FIRM_API const char *get_align_name(ir_align a); -/** Returns the offset of an entity (in a compound) in bytes. Only set if layout = fixed. */ -int get_entity_offset(const ir_entity *ent); +/** Returns the offset of an entity (in a compound) in bytes. Only set if + * layout = fixed. */ +FIRM_API int get_entity_offset(const ir_entity *ent); /** Sets the offset of an entity (in a compound) in bytes. */ -void set_entity_offset(ir_entity *ent, int offset); +FIRM_API void set_entity_offset(ir_entity *ent, int offset); -/** Returns the offset bit remainder of a bitfield entity (in a compound) in bits. Only set if layout = fixed. */ -unsigned char get_entity_offset_bits_remainder(const ir_entity *ent); +/** Returns the offset bit remainder of a bitfield entity (in a compound) in + * bits. Only set if layout = fixed. */ +FIRM_API unsigned char get_entity_offset_bits_remainder(const ir_entity *ent); /** Sets the offset bit remainder of a bitfield entity (in a compound) in bits. */ -void set_entity_offset_bits_remainder(ir_entity *ent, unsigned char offset); +FIRM_API void set_entity_offset_bits_remainder(ir_entity *ent, + unsigned char offset); /** Returns the stored intermediate information. */ -void *get_entity_link(const ir_entity *ent); +FIRM_API void *get_entity_link(const ir_entity *ent); /** Stores new intermediate information. */ -void set_entity_link(ir_entity *ent, void *l); - -/* -- Fields of method entities -- */ -/** The entity knows the corresponding irg if the entity is a method. - This allows to get from a Call to the called irg. - Only entities of peculiarity "existent" can have a corresponding irg, - else the field is fixed to NULL. (Get returns NULL, set asserts.) */ -ir_graph *get_entity_irg(const ir_entity *ent); -void set_entity_irg(ir_entity *ent, ir_graph *irg); - -/** Gets the entity vtable number. */ -unsigned get_entity_vtable_number(const ir_entity *ent); +FIRM_API void set_entity_link(ir_entity *ent, void *l); -/** Sets the entity vtable number. */ -void set_entity_vtable_number(ir_entity *ent, unsigned vtable_number); +/** + * The entity knows the corresponding irg if the entity is a method. + * This allows to get from a Call to the called irg. + */ +FIRM_API ir_graph *get_entity_irg(const ir_entity *ent); -/** Return the peculiarity of an entity. */ -ir_peculiarity get_entity_peculiarity(const ir_entity *ent); +/** A reserved value for "not yet set". */ +#define IR_VTABLE_NUM_NOT_SET ((unsigned)(-1)) -/** Sets the peculiarity of an entity. */ -void set_entity_peculiarity(ir_entity *ent, ir_peculiarity pec); +/** Returns the entity vtable number. */ +FIRM_API unsigned get_entity_vtable_number(const ir_entity *ent); -/** Checks if an entity cannot be overridden anymore. */ -int is_entity_final(const ir_entity *ent); +/** Sets the entity vtable number. */ +FIRM_API void set_entity_vtable_number(ir_entity *ent, unsigned vtable_number); -/** Sets/resets the final flag of an entity. */ -void set_entity_final(ir_entity *ent, int final); +/** Sets label number of an entity with code type */ +FIRM_API void set_entity_label(ir_entity *ent, ir_label_t label); +/** Returns label number of an entity with code type */ +FIRM_API ir_label_t get_entity_label(const ir_entity *ent); /** Checks if an entity is compiler generated. */ -int is_entity_compiler_generated(const ir_entity *ent); +FIRM_API int is_entity_compiler_generated(const ir_entity *ent); /** Sets/resets the compiler generated flag. */ -void set_entity_compiler_generated(ir_entity *ent, int flag); - -/** Checks if an entity is marked by the backend. */ -int is_entity_backend_marked(const ir_entity *ent); - -/** Sets/resets the backend marker flag. */ -void set_entity_backend_marked(ir_entity *ent, int flag); +FIRM_API void set_entity_compiler_generated(ir_entity *ent, int flag); /** * Bitfield type indicating the way an entity is used. @@ -388,18 +415,18 @@ typedef enum { | ir_usage_reinterpret_cast } ir_entity_usage; -/** Return the entity usage */ -ir_entity_usage get_entity_usage(const ir_entity *ent); +/** Returns the entity usage */ +FIRM_API ir_entity_usage get_entity_usage(const ir_entity *ent); /** Sets/resets the state of the address taken flag of an entity. */ -void set_entity_usage(ir_entity *ent, ir_entity_usage flag); +FIRM_API void set_entity_usage(ir_entity *ent, ir_entity_usage flag); /** * Returns the debug information of an entity. * * @param ent The entity. */ -dbg_info *get_entity_dbg_info(const ir_entity *ent); +FIRM_API dbg_info *get_entity_dbg_info(const ir_entity *ent); /** * Sets the debug information of an entity. @@ -407,9 +434,34 @@ dbg_info *get_entity_dbg_info(const ir_entity *ent); * @param ent The entity. * @param db The debug info. */ -void set_entity_dbg_info(ir_entity *ent, dbg_info *db); +FIRM_API void set_entity_dbg_info(ir_entity *ent, dbg_info *db); + +/** + * Sepcial parameter number which can be used for parameter entities to + * indicate the first non-declared parameter in a procedure with variable + * arguments. + * We assumes that all additional parameters for variable parameters are on the + * stack. Starting from this address you can walk the stack to find all other + * parameters. + */ +#define IR_VA_START_PARAMETER_NUMBER ((size_t)-1) + +/** + * returns true if a given entity is a parameter_entity representing the + * address of a function parameter + */ +FIRM_API int is_parameter_entity(const ir_entity *entity); + +/** + * returns number of parameter a parameter entitiy represents + */ +FIRM_API size_t get_entity_parameter_number(const ir_entity *entity); + +/** + * set number of parameter an entity represents + */ +FIRM_API void set_entity_parameter_number(ir_entity *entity, size_t n); -/* -- Representation of constant values of entities -- */ /** * Returns true if the the node is representable as code on * const_code_irg. @@ -417,23 +469,27 @@ void set_entity_dbg_info(ir_entity *ent, dbg_info *db); * @deprecated This function is not used by libFirm and stays here * only as a helper for the old Jack frontend. */ -int is_irn_const_expression(ir_node *n); +FIRM_API int is_irn_const_expression(ir_node *n); /** * Copies a Firm subgraph that complies to the restrictions for - * constant expressions to current_block in current_ir_graph. - * - * @param dbg debug info for all newly created nodes - * @param n the node + * constant expressions to block. * - * Set current_ir_graph to get_const_code_irg() to generate a constant - * expression. + * @param dbg debug info for all newly created nodes + * @param n the node + * @param to_block block to copy to */ -ir_node *copy_const_value(dbg_info *dbg, ir_node *n); +FIRM_API ir_node *copy_const_value(dbg_info *dbg, ir_node *n, ir_node *to_block); -/* Set has no effect for existent entities of type method. */ -ir_node *get_atomic_ent_value(ir_entity *ent); -void set_atomic_ent_value(ir_entity *ent, ir_node *val); +/** Returns initial value of entity with atomic type @p ent. */ +FIRM_API ir_node *get_atomic_ent_value(ir_entity *ent); +/** Sets initial value of entity with atomic type @p ent to node @p val. + * @note @p val must be a node in the const_code graph */ +FIRM_API void set_atomic_ent_value(ir_entity *ent, ir_node *val); + +/** @defgroup ir_initializer Entity Initializers + * @{ + */ /** the kind (type) of an initializer */ typedef enum ir_initializer_kind_t { @@ -447,173 +503,89 @@ typedef enum ir_initializer_kind_t { IR_INITIALIZER_COMPOUND } ir_initializer_kind_t; -/** returns kind of an initializer */ -ir_initializer_kind_t get_initializer_kind(const ir_initializer_t *initializer); +/** Returns kind of an initializer */ +FIRM_API ir_initializer_kind_t get_initializer_kind(const ir_initializer_t *initializer); -/** Return the name of the initializer kind. */ -const char *get_initializer_kind_name(ir_initializer_kind_t ini); +/** Returns the name of the initializer kind. */ +FIRM_API const char *get_initializer_kind_name(ir_initializer_kind_t ini); /** - * returns the null initializer (there's only one instance of it in a program ) + * Returns the null initializer (there's only one instance of it in a program ) */ -ir_initializer_t *get_initializer_null(void); +FIRM_API ir_initializer_t *get_initializer_null(void); /** - * creates an initializer containing a reference to a node on the const-code + * Creates an initializer containing a reference to a node on the const-code * irg. */ -ir_initializer_t *create_initializer_const(ir_node *value); - -/** creates an initializer containing a single tarval value */ -ir_initializer_t *create_initializer_tarval(tarval *tv); - -/** return value contained in a const initializer */ -ir_node *get_initializer_const_value(const ir_initializer_t *initializer); - -/** return value contained in a tarval initializer */ -tarval *get_initializer_tarval_value(const ir_initializer_t *initialzier); - -/** creates a compound initializer which holds @p n_entries entries */ -ir_initializer_t *create_initializer_compound(unsigned n_entries); - -/** returns the number of entries in a compound initializer */ -unsigned get_initializer_compound_n_entries(const ir_initializer_t *initializer); - -/** sets entry with index @p index to the initializer @p value */ -void set_initializer_compound_value(ir_initializer_t *initializer, - unsigned index, ir_initializer_t *value); - -/** returns the value with index @p index of a compound initializer */ -ir_initializer_t *get_initializer_compound_value( - const ir_initializer_t *initializer, unsigned index); - -/** Creates a new compound graph path of given length. */ -compound_graph_path *new_compound_graph_path(ir_type *tp, int length); +FIRM_API ir_initializer_t *create_initializer_const(ir_node *value); -/** Returns non-zero if an object is a compound graph path */ -int is_compound_graph_path(const void *thing); +/** Creates an initializer containing a single tarval value */ +FIRM_API ir_initializer_t *create_initializer_tarval(ir_tarval *tv); -/** Frees a graph path object */ -void free_compound_graph_path(compound_graph_path *gr); +/** Returns value contained in a const initializer */ +FIRM_API ir_node *get_initializer_const_value(const ir_initializer_t *initializer); -/** Returns the length of a graph path */ -int get_compound_graph_path_length(const compound_graph_path *gr); +/** Returns value contained in a tarval initializer */ +FIRM_API ir_tarval *get_initializer_tarval_value(const ir_initializer_t *initialzier); -/** Get the entity node of an compound graph path at position pos. */ -ir_entity *get_compound_graph_path_node(const compound_graph_path *gr, int pos); -/** Set the entity node of an compound graph path at position pos. */ -void set_compound_graph_path_node(compound_graph_path *gr, int pos, ir_entity *node); -/** Get the index of an compound graph path at position pos. */ -int get_compound_graph_path_array_index(const compound_graph_path *gr, int pos); -/** Set the index of an compound graph path at position pos. */ -void set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index); -/** Get the type of an compound graph path. */ -ir_type *get_compound_graph_path_type(const compound_graph_path *gr); +/** Creates a compound initializer which holds @p n_entries entries */ +FIRM_API ir_initializer_t *create_initializer_compound(size_t n_entries); -/** Checks whether the path up to pos is correct. If the path contains a NULL, - * assumes the path is not complete and returns non-zero. */ -int is_proper_compound_graph_path(compound_graph_path *gr, int pos); +/** Returns the number of entries in a compound initializer */ +FIRM_API size_t get_initializer_compound_n_entries(const ir_initializer_t *initializer); -/* A value of a compound entity is a pair of a value and the description of the - corresponding access path to the member of the compound. */ -void add_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path); -void set_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path, int pos); +/** Sets entry with index @p index to the initializer @p value */ +FIRM_API void set_initializer_compound_value(ir_initializer_t *initializer, + size_t index, + ir_initializer_t *value); -/** Returns the number of constant values needed to initialize the entity. - * - * Asserts if the entity has variability_uninitialized. - * */ -int get_compound_ent_n_values(ir_entity *ent); -/** Returns a constant value given the position. */ -ir_node *get_compound_ent_value(ir_entity *ent, int pos); -/** Returns the access path for value at position pos. */ -compound_graph_path *get_compound_ent_value_path(ir_entity *ent, int pos); -/** Returns a constant value given the access path. - * The path must contain array indices for all array element entities. */ -ir_node *get_compound_ent_value_by_path(ir_entity *ent, compound_graph_path *path); - -/** Removes all constant entries where the path ends at value_ent. Does not - free the memory of the paths. (The same path might be used for several - constant entities. */ -void remove_compound_ent_value(ir_entity *ent, ir_entity *value_ent); - -/* Some languages support only trivial access paths, i.e., the member is a - direct, atomic member of the constant entities type. In this case the - corresponding entity can be accessed directly. The following functions - allow direct access. */ +/** Returns the value with index @p index of a compound initializer */ +FIRM_API ir_initializer_t *get_initializer_compound_value( + const ir_initializer_t *initializer, size_t index); -/** Generates a Path with length 1. - Beware: Has a bad runtime for array elements (O(|array|) and should be - avoided there. Use add_compound_ent_value_w_path() instead and create - the path manually. */ -void add_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member); - -/** Returns the last member in the path */ -ir_entity *get_compound_ent_value_member(ir_entity *ent, int pos); - -/** Sets the path at pos 0 */ -void set_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member, int pos); +/** @} */ /** Sets the new style initializers of an entity. */ -void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer); +FIRM_API void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer); /** Returns true, if an entity has new style initializers. */ -int has_entity_initializer(const ir_entity *entity); - -/** Return the new style initializers of an entity. */ -ir_initializer_t *get_entity_initializer(const ir_entity *entity); - -/** Initializes the entity ent which must be of a one dimensional - array type with the values given in the values array. - The array must have a lower and an upper bound. Keeps the - order of values. Does not test whether the number of values - fits into the given array size. Does not test whether the - values have the proper mode for the array. */ -void set_array_entity_values(ir_entity *ent, tarval **values, int num_vals); - -/** - * Return the offset in bits from the last byte address. - * - * This requires that the layout of all concerned types is fixed. - * - * @param ent Any entity of compound type with at least pos initialization values. - * @param pos The position of the value for which the offset is requested. - */ -unsigned get_compound_ent_value_offset_bit_remainder(ir_entity *ent, int pos); - -/** Return the overall offset of value at position pos in bytes. - * - * This requires that the layout of all concerned types is fixed. - * Asserts if bit offset is not byte aligned. - * - * @param ent Any entity of compound type with at least pos initialization values. - * @param pos The position of the value for which the offset is requested. - */ -unsigned get_compound_ent_value_offset_bytes(ir_entity *ent, int pos); - -/* --- Fields of entities with a class type as owner --- */ -/* Overwrites is a field that specifies that an access to the overwritten - entity in the supertype must use this entity. It's a list as with - multiple inheritance several entities can be overwritten. This field - is mostly useful for method entities. - If a Sel node selects an entity that is overwritten by other entities it - must return a pointer to the entity of the dynamic type of the pointer - that is passed to it. Lowering of the Sel node must assure this. - Overwrittenby is the inverse of overwrites. Both add routines add - both relations, they only differ in the order of arguments. */ -void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten); -int get_entity_n_overwrites(ir_entity *ent); -int get_entity_overwrites_index(ir_entity *ent, ir_entity *overwritten); -ir_entity *get_entity_overwrites(ir_entity *ent, int pos); -void set_entity_overwrites(ir_entity *ent, int pos, ir_entity *overwritten); -void remove_entity_overwrites(ir_entity *ent, ir_entity *overwritten); - -void add_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites); -int get_entity_n_overwrittenby(ir_entity *ent); -int get_entity_overwrittenby_index(ir_entity *ent, ir_entity *overwrites); -ir_entity *get_entity_overwrittenby(ir_entity *ent, int pos); -void set_entity_overwrittenby(ir_entity *ent, int pos, ir_entity *overwrites); -void remove_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites); +FIRM_API int has_entity_initializer(const ir_entity *entity); + +/** Returns the new style initializers of an entity. */ +FIRM_API ir_initializer_t *get_entity_initializer(const ir_entity *entity); + +/** Adds entity @p ent to the list of entities that overwrite @p overwritten. */ +FIRM_API void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten); +/** Returns the number of entities in the list of entities that overwrite + * entity @p ent. */ +FIRM_API size_t get_entity_n_overwrites(const ir_entity *ent); +/** Returns index of @p overwritten in list of entities overwriting entity + * @p ent. */ +FIRM_API size_t get_entity_overwrites_index(const ir_entity *ent, + ir_entity *overwritten); +/** Returns entry @p pos in list of entities overwriting entity @p ent. */ +FIRM_API ir_entity *get_entity_overwrites(const ir_entity *ent, size_t pos); +/** Sets entry @p pos in list of entities overwriting entity @p ent. */ +FIRM_API void set_entity_overwrites(ir_entity *ent, size_t pos, + ir_entity *overwritten); +/** Remove @p overwritten from list of entities overwriting entity @p ent. */ +FIRM_API void remove_entity_overwrites(ir_entity *ent, ir_entity *overwritten); + +/** Returns number of entities overwritten by @p ent. */ +FIRM_API size_t get_entity_n_overwrittenby(const ir_entity *ent); +/** Returns index of @p overwrites in list of entities overwritten by entity + * @p ent. */ +FIRM_API size_t get_entity_overwrittenby_index(const ir_entity *ent, + ir_entity *overwrites); +/** Return entry @p pos in list of entities overwritten by entity @p ent. */ +FIRM_API ir_entity *get_entity_overwrittenby(const ir_entity *ent, size_t pos); +/** Sets entry @p pos in list of entities overwritten by entity @p ent. */ +FIRM_API void set_entity_overwrittenby(ir_entity *ent, size_t pos, + ir_entity *overwrites); +/** Removes entry @p overwrites in list of entities overwritten by @p ent. */ +FIRM_API void remove_entity_overwrittenby(ir_entity *ent, + ir_entity *overwrites); /** * Checks whether a pointer points to an entity. @@ -623,47 +595,45 @@ void remove_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites); * @return * true if the thing is an entity, else false */ -int is_entity(const void *thing); +FIRM_API int is_entity(const void *thing); /** Returns true if the type of the entity is a primitive, pointer * enumeration or method type. * - * @Note This is a different classification than from is_primitive_type(). + * @note This is a different classification than from is_primitive_type(). */ -int is_atomic_entity(ir_entity *ent); +FIRM_API int is_atomic_entity(const ir_entity *ent); /** Returns true if the type of the entity is a class, structure, array or union type. */ -int is_compound_entity(ir_entity *ent); +FIRM_API int is_compound_entity(const ir_entity *ent); /** Returns true if the type of the entity is a Method type. */ -int is_method_entity(ir_entity *ent); - -/** Returns non-zero if ent1 and ent2 have are equal except for their owner. - Two entities are equal if - - they have the same type (the same C-struct) - - ...? -*/ -int equal_entity(ir_entity *ent1, ir_entity *ent2); +FIRM_API int is_method_entity(const ir_entity *ent); /** Outputs a unique number for this entity if libfirm is compiled for * debugging, (configure with --enable-debug) else returns the address * of the type cast to long. */ -long get_entity_nr(const ir_entity *ent); +FIRM_API long get_entity_nr(const ir_entity *ent); -/** Returns the entities visited count. */ -ir_visited_t get_entity_visited(ir_entity *ent); +/** Returns the entities visited counter. + * @see @ref visited_counters */ +FIRM_API ir_visited_t get_entity_visited(const ir_entity *ent); -/** Sets the entities visited count. */ -void set_entity_visited(ir_entity *ent, ir_visited_t num); +/** Sets the entities visited counter. + * @see @ref visited_counters */ +FIRM_API void set_entity_visited(ir_entity *ent, ir_visited_t num); -/** Sets visited field in entity to entity_visited. */ -void mark_entity_visited(ir_entity *ent); +/** Marks entity as visited. + * @see @ref visited_counters */ +FIRM_API void mark_entity_visited(ir_entity *ent); -/** Returns true if this entity was visited. */ -int entity_visited(ir_entity *ent); +/** Returns true if this entity was visited. + * @see @ref visited_counters */ +FIRM_API int entity_visited(const ir_entity *ent); -/** Returns true if this entity was not visited. */ -int entity_not_visited(ir_entity *ent); +/** Returns true if this entity was not visited. + * @see @ref visited_counters */ +FIRM_API int entity_not_visited(const ir_entity *ent); /** * Returns the mask of the additional entity properties. @@ -672,17 +642,19 @@ int entity_not_visited(ir_entity *ent); * set_entity_additional_properties() or * set_entity_additional_property(). */ -unsigned get_entity_additional_properties(ir_entity *ent); +FIRM_API mtp_additional_properties get_entity_additional_properties(const ir_entity *ent); /** Sets the mask of the additional graph properties. */ -void set_entity_additional_properties(ir_entity *ent, unsigned property_mask); +FIRM_API void set_entity_additional_properties(ir_entity *ent, + mtp_additional_properties prop); -/** Sets one additional graph property. */ -void set_entity_additional_property(ir_entity *ent, mtp_additional_property flag); +/** Sets additional graph properties. */ +FIRM_API void add_entity_additional_properties(ir_entity *ent, + mtp_additional_properties flag); /** Returns the class type that this type info entity represents or NULL if ent is no type info entity. */ -ir_type *get_entity_repr_class(const ir_entity *ent); +FIRM_API ir_type *get_entity_repr_class(const ir_entity *ent); /** * @page unknown_entity The Unknown entity @@ -704,14 +676,10 @@ ir_type *get_entity_repr_class(const ir_entity *ent); * - ld_name = "unknown_entity" * - owner = unknown_type * - type = unknown_type - * - allocation = allocation_automatic - * - visibility = visibility_external_allocated * - offset = -1 - * - variability = variability_uninitialized * - value = SymConst(unknown_entity) * - values = NULL * - val_paths = NULL - * - peculiarity = peculiarity_existent * - volatility = volatility_non_volatile * - stickyness = stickyness_unsticky * - ld_name = NULL @@ -720,14 +688,50 @@ ir_type *get_entity_repr_class(const ir_entity *ent); * - irg = NULL * - link = NULL */ -/* A variable that contains the only unknown entity. */ -extern ir_entity *unknown_entity; + +/** A variable that contains the only unknown entity. */ +FIRM_API ir_entity *unknown_entity; /** Returns the @link unknown_entity unknown entity @endlink. */ -ir_entity *get_unknown_entity(void); +FIRM_API ir_entity *get_unknown_entity(void); + +/** @deprecated */ +typedef enum { + allocation_automatic, + allocation_parameter, + allocation_dynamic, + allocation_static +} ir_allocation; +/** @deprecated */ +FIRM_API ir_allocation get_entity_allocation(const ir_entity *ent); +/** @deprecated */ +FIRM_API void set_entity_allocation(ir_entity *ent, ir_allocation al); + +/** @deprecated */ +typedef enum { + peculiarity_existent, + peculiarity_description, + peculiarity_inherited +} ir_peculiarity; +/** @deprecated */ +FIRM_API ir_peculiarity get_entity_peculiarity(const ir_entity *ent); +/** @deprecated */ +FIRM_API void set_entity_peculiarity(ir_entity *ent, ir_peculiarity pec); + +/** @deprecated */ +FIRM_API int is_entity_final(const ir_entity *ent); +/** @deprecated */ +FIRM_API void set_entity_final(ir_entity *ent, int final); + +/** @deprecated */ +FIRM_API ir_peculiarity get_class_peculiarity(const ir_type *clss); +/** @deprecated */ +FIRM_API void set_class_peculiarity(ir_type *clss, ir_peculiarity pec); + +/** @} */ /** Encodes how a pointer parameter is accessed. */ -typedef enum acc_bits { +typedef enum ptr_access_kind { ptr_access_none = 0, /**< no access */ ptr_access_read = 1, /**< read access */ ptr_access_write = 2, /**< write access */ @@ -735,13 +739,33 @@ typedef enum acc_bits { ptr_access_store = 4, /**< the pointer is stored */ ptr_access_all = ptr_access_rw|ptr_access_store /**< all possible access */ } ptr_access_kind; +ENUM_BITSET(ptr_access_kind) -#define IS_READ(a) ((a) & ptr_access_read) -#define IS_WRITTEN(a) ((a) & ptr_access_write) -#define IS_STORED(a) ((a) & ptr_access_store) +/** + * @defgroup ir_type Type System + * + * Datastructure to hold type information. + * + * This module supplies a datastructure to represent all types + * known in the compiled program. This includes types specified + * in the program as well as types defined by the language. In the + * view of the intermediate representation there is no difference + * between these types. Finally it specifies some auxiliary types. + * + * There exist several kinds of types, arranged by the structure of + * the type. A type is described by a set of attributes. Some of + * these attributes are common to all types, others depend on the + * kind of the type. + * + * Types are different from the modes defined in irmode: Types are + * on the level of the programming language, modes at the level of + * the target processor. + * + * @{ + */ /** - * @page tyop type operations + * @defgroup tp_op Type Opcodes * This module specifies the kinds of types available in firm. * * They are called type opcodes. These include classes, structs, methods, unions, @@ -749,7 +773,7 @@ typedef enum acc_bits { * Special types with own opcodes are the id type, a type representing an unknown * type and a type used to specify that something has no type. * - * @see type.h + * @{ */ /** @@ -766,10 +790,10 @@ typedef enum { tpo_enumeration, /**< An enumeration type. */ tpo_pointer, /**< A pointer type. */ tpo_primitive, /**< A primitive type. */ - tpo_id, /**< Special Id tag used for type replacement. */ + tpo_code, /**< a piece of code (a basic block) */ tpo_none, /**< Special type for the None type. */ tpo_unknown, /**< Special code for the Unknown type. */ - tpo_max /* not a type opcode */ + tpo_last = tpo_unknown /* not a type opcode */ } tp_opcode; /** @@ -778,7 +802,7 @@ typedef enum { * this is only the kind name, an enum for case-switching and some * internal values. * - * @see get_tpop_name(), get_tpop_code(), get_tpop_ident() + * @see get_tpop_name(), get_tpop_code() */ typedef struct tp_op tp_op; @@ -787,9 +811,9 @@ typedef struct tp_op tp_op; * Returns the string for the type opcode. * * @param op The type opcode to get the string from. - * @return a string. (@todo Null terminated?) + * @return a string. */ -const char *get_tpop_name(const tp_op *op); +FIRM_API const char *get_tpop_name(const tp_op *op); /** * Returns an enum for the type opcode. @@ -797,149 +821,9 @@ const char *get_tpop_name(const tp_op *op); * @param op The type opcode to get the enum from. * @return the enum. */ -tp_opcode get_tpop_code(const tp_op *op); - -/** - * Returns the ident for the type opcode. - * - * @param op The type opcode to get the ident from. - * @return The ident. - */ -ident *get_tpop_ident(const tp_op *op); - -/** - * This type opcode marks that the corresponding type is a class type. - * - * Consequently the type refers to supertypes, subtypes and entities. - * Entities can be any fields, but also methods. - * @@@ value class or not??? - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_class; -tp_op *get_tpop_class(void); - -/** - * This type opcode marks that the corresponding type is a compound type - * as a struct in C. - * - * Consequently the type refers to a list of entities - * which may not be methods (but pointers to methods). - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_struct; -tp_op *get_tpop_struct(void); - -/** - * This type opcode marks that the corresponding type is a method type. - * - * Consequently it refers to a list of arguments and results. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_method; -tp_op *get_tpop_method(void); - -/** - * This type opcode marks that the corresponding type is a union type. - * - * Consequently it refers to a list of unioned types. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_union; -tp_op *get_tpop_union(void); - -/** - * This type opcode marks that the corresponding type is an array type. - * - * Consequently it contains a list of dimensions (lower and upper bounds) - * and an element type. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_array; -tp_op *get_tpop_array(void); - -/** - * This type opcode marks that the corresponding type is an enumeration type. - * - * Consequently it contains a list of idents for the enumeration identifiers - * and a list of target values that are the constants used to implement - * the enumerators. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_enumeration; -tp_op *get_tpop_enumeration(void); +FIRM_API tp_opcode get_tpop_code(const tp_op *op); -/** - * This type opcode marks that the corresponding type is a pointer type. - * - * It contains a reference to the type the pointer points to. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_pointer; -tp_op *get_tpop_pointer(void); - -/** - * This type opcode marks that the corresponding type is a primitive type. - * - * Primitive types are types that are directly mapped to target machine - * modes. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_primitive; -tp_op *get_tpop_primitive(void); - -/** - * This type opcode is an auxiliary opcode dedicated to support transformations - * of the type structure. - * - * If a type is changed to another type with another - * opcode the new type will be allocated with new memory. All nodes refering - * to the old type need to be changed to refer to the new one. This is simplified - * by turning the old type into an id type that merely forwards to the new type - * that now replaces the old one. - * type_ids should never be visible out of the type module. All access routines - * should automatically check for type_id and eventually follow the forward in - * type_id. Two types are exchanged by a call to exchange_types. - * If a type_id is visible externally report this as bug. If it is assured that - * this never happens this extern variable can be moved to tpop_t.h. - * This struct is dynamically allocated but constant for the lifetime - * of the library. - */ -extern tp_op *type_id; -tp_op *get_tpop_id(void); - -/** - * This type opcode is an auxiliary opcode dedicated to support type analyses. - * - * Types with this opcode represents that there is no type. - * The type can be used to initialize fields of the type* that actually can not - * contain a type or that are initialized for an analysis. There exists exactly - * one type with this opcode. - */ -extern tp_op *tpop_none; -tp_op *get_tpop_none(void); - -/** - * This type opcode is an auxiliary opcode dedicated to support type analyses. - * - * Types with this opcode represents that there could be a type, but it is not - * known. This type can be used to initialize fields before an analysis (not known - * yet) or to represent the top of a lattice (could not be determined). There exists - * exactly one type with this opcode. - */ -extern tp_op *tpop_unknown; -tp_op *get_tpop_unknown(void); - -/* ----------------------------------------------------------------------- */ -/* Classify pairs of types/entities in the inheritance relations. */ -/* ----------------------------------------------------------------------- */ +/** @} */ /** Returns true if low is subclass of high. * @@ -947,7 +831,7 @@ tp_op *get_tpop_unknown(void); * a subclass of high. I.e, we search in all subtypes of high for low. * @@@ this can be implemented more efficient if we know the set of all * subclasses of high. */ -int is_SubClass_of(ir_type *low, ir_type *high); +FIRM_API int is_SubClass_of(ir_type *low, ir_type *high); /** Subclass check for pointers to classes. * @@ -955,7 +839,7 @@ int is_SubClass_of(ir_type *low, ir_type *high); * many as possible). If the remaining types are both class types * and subclasses, returns true, else false. Can also be called with * two class types. */ -int is_SubClass_ptr_of(ir_type *low, ir_type *high); +FIRM_API int is_SubClass_ptr_of(ir_type *low, ir_type *high); /** Returns true if high is superclass of low. * @@ -976,24 +860,22 @@ int is_SubClass_ptr_of(ir_type *low, ir_type *high); /** Returns true if high is (transitive) overwritten by low. * * Returns false if high == low. */ -int is_overwritten_by(ir_entity *high, ir_entity *low); +FIRM_API int is_overwritten_by(ir_entity *high, ir_entity *low); /** Resolve polymorphism in the inheritance relation. * * Returns the dynamically referenced entity if the static entity and the * dynamic type are given. * Searches downwards in overwritten tree. */ -ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity* static_ent); - -/* ----------------------------------------------------------------------- */ -/* Resolve implicit inheritance. */ -/* ----------------------------------------------------------------------- */ +FIRM_API ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, + ir_entity* static_ent); /** Default name mangling for inherited entities. * * Returns an ident that consists of the name of type followed by an * underscore and the name (not ld_name) of the entity. */ -ident *default_mangle_inherited_name(ir_entity *ent, ir_type *clss); +FIRM_API ident *default_mangle_inherited_name(const ir_entity *ent, + const ir_type *clss); /** Type of argument functions for inheritance resolver. * @@ -1002,7 +884,8 @@ ident *default_mangle_inherited_name(ir_entity *ent, ir_type *clss); * used. * @param clss The class type in which the new entity will be placed. */ -typedef ident *mangle_inherited_name_func(ir_entity *ent, ir_type *clss); +typedef ident *mangle_inherited_name_func(const ir_entity *ent, + const ir_type *clss); /** Resolve implicit inheritance. * @@ -1017,10 +900,8 @@ typedef ident *mangle_inherited_name_func(ir_entity *ent, ir_type *clss); * The name of the new entity is generated with the function passed. * If the function is NULL, the default_mangle_inherited_name() is * used. - * - * This function was moved here from firmlower 3/2005. */ -void resolve_inheritance(mangle_inherited_name_func *mfunc); +FIRM_API void resolve_inheritance(mangle_inherited_name_func *mfunc); /* ----------------------------------------------------------------------- */ @@ -1038,10 +919,9 @@ void resolve_inheritance(mangle_inherited_name_func *mfunc); /* Do the sets contain the node itself? I assume NOT! */ /* ----------------------------------------------------------------------- */ -/** The state of the transitive closure. - * - * @todo: we could manage the state for each relation separately. Invalidating - * the entity relations does not mean invalidating the class relation. */ +/** + * The state of the transitive closure. + */ typedef enum { inh_transitive_closure_none, /**< Closure is not computed, can not be accessed. */ inh_transitive_closure_valid, /**< Closure computed and valid. */ @@ -1049,49 +929,66 @@ typedef enum { inh_transitive_closure_max /**< Invalid value. */ } inh_transitive_closure_state; -void set_irp_inh_transitive_closure_state(inh_transitive_closure_state s); -void invalidate_irp_inh_transitive_closure_state(void); -inh_transitive_closure_state get_irp_inh_transitive_closure_state(void); - +/** Sets the transitive closure of sub/superclass state for the + * whole program. */ +FIRM_API void set_irp_inh_transitive_closure_state(inh_transitive_closure_state s); +/** Sets the transitive closure of sub/superclass state for the + * whole program to #inh_transitive_closure_invalid */ +FIRM_API void invalidate_irp_inh_transitive_closure_state(void); +/** Returns the transitive closure of sub/superclass state for the + * whole program. */ +FIRM_API inh_transitive_closure_state get_irp_inh_transitive_closure_state(void); /** Compute transitive closure of the subclass/superclass and * overwrites/overwrittenby relation. * - * This function walks over the ir (O(#types+#entities)) to compute the + * This function walks over the ir (O(\#types+\#entities)) to compute the * transitive closure. */ -void compute_inh_transitive_closure(void); +FIRM_API void compute_inh_transitive_closure(void); /** Free memory occupied by the transitive closure information. */ -void free_inh_transitive_closure(void); - - -/* - subtype ------------------------------------------------------------- */ - -/** Iterate over all transitive subtypes. */ -ir_type *get_class_trans_subtype_first(const ir_type *tp); -ir_type *get_class_trans_subtype_next(const ir_type *tp); -int is_class_trans_subtype(const ir_type *tp, const ir_type *subtp); - -/* - supertype ----------------------------------------------------------- */ +FIRM_API void free_inh_transitive_closure(void); -/** Iterate over all transitive supertypes. */ -ir_type *get_class_trans_supertype_first(const ir_type *tp); -ir_type *get_class_trans_supertype_next(const ir_type *tp); - -/* - overwrittenby ------------------------------------------------------- */ +/** Start iteration over all transitive subtypes of @p tp */ +FIRM_API ir_type *get_class_trans_subtype_first(const ir_type *tp); +/** + * Returns next type in a subtype iteration started by + * get_class_trans_subtype_first() + */ +FIRM_API ir_type *get_class_trans_subtype_next(const ir_type *tp); +/** + * Check if @p subtp is a subtype of @p tp. This function checks the full + * transitive closure of the subtype relation and not just direct subtyping. + * @return 1 if it is a subtype, 0 otherwise + */ +FIRM_API int is_class_trans_subtype(const ir_type *tp, const ir_type *subtp); -/** Iterate over all entities that transitive overwrite this entities. */ -ir_entity *get_entity_trans_overwrittenby_first(const ir_entity *ent); -ir_entity *get_entity_trans_overwrittenby_next(const ir_entity *ent); +/** Start iteration over all transitive supertypes of @p tp */ +FIRM_API ir_type *get_class_trans_supertype_first(const ir_type *tp); +/** + * Returns next type in a supertype iteration started by + * get_class_trans_supertype_first() + */ +FIRM_API ir_type *get_class_trans_supertype_next(const ir_type *tp); -/* - overwrites ---------------------------------------------------------- */ +/** Start iteration over all entities that transitive overwrite entity @p ent.*/ +FIRM_API ir_entity *get_entity_trans_overwrittenby_first(const ir_entity *ent); +/** + * Returns next entity in a overwrittenby iteration started by + * get_entity_trans_overwrittenby_first() + */ +FIRM_API ir_entity *get_entity_trans_overwrittenby_next(const ir_entity *ent); -/** Iterate over all transitive overwritten entities. */ -ir_entity *get_entity_trans_overwrites_first(const ir_entity *ent); -ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent); +/** Start iteration over all transitive overwritten entities, overwritten by + * entity @p ent */ +FIRM_API ir_entity *get_entity_trans_overwrites_first(const ir_entity *ent); +/** + * Returns next entity in a overwrites iteration started by + * get_entity_trans_overwrites_first() + */ +FIRM_API ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent); -/* ----------------------------------------------------------------------- */ /** The state of Cast operations that cast class types or pointers to class * types. * @@ -1110,11 +1007,7 @@ ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent); * any: Cast operations do not conform with the transitive inheritance * relation. Example: (B2)(new B1()) * - * @see: tropt.h - */ -/* ----------------------------------------------------------------------- */ - -/** Flags for class cast state. + * Flags for class cast state. * * The state in irp is always smaller or equal to the state of any * irg. @@ -1127,24 +1020,21 @@ typedef enum { ir_class_casts_normalized = 2, /**< Class casts conform to inheritance edges. */ ir_class_casts_state_max } ir_class_cast_state; -char *get_class_cast_state_string(ir_class_cast_state s); -void set_irg_class_cast_state(ir_graph *irg, ir_class_cast_state s); -ir_class_cast_state get_irg_class_cast_state(ir_graph *irg); -void set_irp_class_cast_state(ir_class_cast_state s); -ir_class_cast_state get_irp_class_cast_state(void); - -/** Verify the class cast state of an irg. - * - * Asserts if state is to high, outputs warning if state is to low - * and firm verbosity is set. - */ -void verify_irg_class_cast_state(ir_graph *irg); +/** Sets class cast state for graph @p irg to @p state. */ +FIRM_API void set_irg_class_cast_state(ir_graph *irg, + ir_class_cast_state state); +/** Returns class cast state for graph @p irg. */ +FIRM_API ir_class_cast_state get_irg_class_cast_state(const ir_graph *irg); +/** Sets class cast state for the whole program to @p state. */ +FIRM_API void set_irp_class_cast_state(ir_class_cast_state state); +/** Returns class cast state for the whole program. */ +FIRM_API ir_class_cast_state get_irp_class_cast_state(void); /** - * possible trvrfy() error codes + * possible trverify() error codes */ -enum trvrfy_error_codes { +enum trverify_error_codes { no_error = 0, /**< no error */ error_ent_not_cont, /**< overwritten entity not in superclass */ error_null_mem, /**< compound contains NULL member */ @@ -1163,17 +1053,7 @@ enum trvrfy_error_codes { * @return * 0 if no error encountered */ -int check_type(ir_type *tp); - -/** - * Check an entity. Currently, we check only if initialized constants - * are build on the const irg graph. - * - * @return - * 0 if no error encountered - * != 0 a trvrfy_error_codes code - */ -int check_entity(ir_entity *ent); +FIRM_API int check_type(ir_type *tp); /** * Walks the type information and performs a set of sanity checks. @@ -1187,79 +1067,13 @@ int check_entity(ir_entity *ent); * 0 if graph is correct * else error code. */ -int tr_vrfy(void); - -/** - * If NDEBUG is defined performs nothing, else calls the tr_vrfy() function. - */ -#ifdef NDEBUG -#define TR_VRFY() 0 -#else -#define TR_VRFY() tr_vrfy() -#endif - -/** - * - * @file typegmod.h - * This module supplies routines that support changing the type graph. - */ - -/** Replaces one type by the other. - * - * Old type is replaced by new_type. All references to old_type - * now point to new_type. The memory for the old type is destroyed, - * but still used. Therefore it is not freed. - * All referenced to this memory will be lost after a certain while. - * An exception is the list of types in irp (irprog.h). - * In the future there might be a routine to recover the memory, but - * this will be at considerable runtime cost. - * - * @param old_type - The old type that shall be replaced by the new type. - * @param new_type - The new type that will replace old_type. - * - */ -void exchange_types(ir_type *old_type, ir_type *new_type); - -/** Skip id types until a useful type is reached. - * - * @param tp - A type of arbitrary kind. - * - * @return - * tp if it is not an id type. - * If tp is an id type returns the real type it stands for. - */ -ir_type *skip_tid(ir_type *tp); - -/** - * @page type representation of types - * - * Datastructure to hold type information. - * - * This module supplies a datastructure to represent all types - * known in the compiled program. This includes types specified - * in the program as well as types defined by the language. In the - * view of the intermediate representation there is no difference - * between these types. Finally it specifies some auxiliary types. - * - * There exist several kinds of types, arranged by the structure of - * the type. A type is described by a set of attributes. Some of - * these attributes are common to all types, others depend on the - * kind of the type. - * - * Types are different from the modes defined in irmode: Types are - * on the level of the programming language, modes at the level of - * the target processor. - * - * @see tpop.h - */ - -#include "typerep.h" +FIRM_API int tr_verify(void); /** Frees all entities associated with a type. * Does not free the array entity. * Warning: ensure these entities are not referenced anywhere else. */ -void free_type_entities(ir_type *tp); +FIRM_API void free_type_entities(ir_type *tp); /** Frees the memory used by the type. * @@ -1268,60 +1082,30 @@ void free_type_entities(ir_type *tp); * not free if tp is "none" or "unknown". Frees entities in value * param subtypes of method types!!! Make sure these are not * referenced any more. Further make sure there is no pointer type - * that refers to this type. */ -void free_type(ir_type *tp); - -const tp_op *get_type_tpop(const ir_type *tp); -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); - -/** 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. + * that refers to this type. */ -ir_visibility get_type_visibility(const ir_type *tp); -void set_type_visibility(ir_type *tp, ir_visibility v); +FIRM_API void free_type(ir_type *tp); +/** Returns type opcode of type @p tp */ +FIRM_API const tp_op *get_type_tpop(const ir_type *tp); +/** Returns name identifier of type opcode of type @p tp */ +FIRM_API ident *get_type_tpop_nameid(const ir_type *tp); +/** Returns name of type opcode of type @p tp */ +FIRM_API const char *get_type_tpop_name(const ir_type *tp); +/** Returns opcode of type opcode of type @p tp */ +FIRM_API tp_opcode get_type_tpop_code(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. + */ +FIRM_API void ir_print_type(char *buffer, size_t buffer_size, + const ir_type *tp); /** The state of the type layout. */ typedef enum { @@ -1339,44 +1123,44 @@ typedef enum { } ir_type_state; /** Returns a human readable string for the enum entry. */ -const char *get_type_state_name(ir_type_state s); +FIRM_API const char *get_type_state_name(ir_type_state s); /** Returns the type layout state of a type. */ -ir_type_state get_type_state(const ir_type *tp); +FIRM_API ir_type_state get_type_state(const ir_type *tp); /** Sets the type layout state of a type. * * For primitives, pointer and method types the layout is always fixed. * This call is legal but has no effect. */ -void set_type_state(ir_type *tp, ir_type_state state); +FIRM_API void set_type_state(ir_type *tp, ir_type_state state); /** Returns the mode of a type. * * Returns NULL for all non atomic types. */ -ir_mode *get_type_mode(const ir_type *tp); +FIRM_API ir_mode *get_type_mode(const ir_type *tp); /** Sets the mode of a type. * * Only has an effect on primitive, enumeration and pointer types. */ -void set_type_mode(ir_type *tp, ir_mode* m); +FIRM_API void set_type_mode(ir_type *tp, ir_mode* m); /** Returns the size of a type in bytes. */ -unsigned get_type_size_bytes(const ir_type *tp); +FIRM_API unsigned get_type_size_bytes(const ir_type *tp); /** Sets the size of a type in bytes. * * For primitive, enumeration, pointer and method types the size * is always fixed. This call is legal but has no effect. */ -void set_type_size_bytes(ir_type *tp, unsigned size); +FIRM_API void set_type_size_bytes(ir_type *tp, unsigned size); /** Returns the alignment of a type in bytes. */ -unsigned get_type_alignment_bytes(ir_type *tp); +FIRM_API unsigned get_type_alignment_bytes(ir_type *tp); -/** Returns the alignment of a type in bits. +/** Sets the alignment of a type in bytes. * * If the alignment of a type is * not set, it is calculated here according to the following rules: @@ -1386,39 +1170,38 @@ unsigned get_type_alignment_bytes(ir_type *tp); * -#.) method types return 0 here. * -#.) all other types return 1 here (i.e. aligned at byte). */ -void set_type_alignment_bytes(ir_type *tp, unsigned align); - -/** Returns the visited count of a type. */ -ir_visited_t get_type_visited(const ir_type *tp); -/** Sets the visited count of a type to num. */ -void set_type_visited(ir_type *tp, ir_visited_t num); -/** Sets visited field in type to type_visited. */ -void mark_type_visited(ir_type *tp); -/** Returns non-zero if the type is already visited */ -int type_visited(const ir_type *tp); -/** Returns non-zero if the type is not yet visited */ -int type_not_visited(const ir_type *tp); +FIRM_API void set_type_alignment_bytes(ir_type *tp, unsigned align); + +/** Returns the visited counter of a type. + * @see @ref visited_counters */ +FIRM_API ir_visited_t get_type_visited(const ir_type *tp); +/** Sets the visited counter of a type to num. + * @see @ref visited_counters */ +FIRM_API void set_type_visited(ir_type *tp, ir_visited_t num); +/** Sets visited field in type to type_visited. + * @see @ref visited_counters */ +FIRM_API void mark_type_visited(ir_type *tp); +/** Returns non-zero if the type is already visited + * @see @ref visited_counters */ +FIRM_API int type_visited(const ir_type *tp); +/** Returns non-zero if the type is not yet visited + * @see @ref visited_counters */ +FIRM_API int type_not_visited(const ir_type *tp); /** Returns the associated link field of a type. */ -void *get_type_link(const ir_type *tp); +FIRM_API void *get_type_link(const ir_type *tp); /** Sets the associated link field of a type. */ -void set_type_link(ir_type *tp, void *l); +FIRM_API void set_type_link(ir_type *tp, void *l); -/** - * Visited flag to traverse the type information. - * - * Increase this flag by one before traversing the type information - * using inc_master_type_visited(). - * Mark type nodes as visited by mark_type_visited(ir_type). - * Check whether node was already visited by type_visited(ir_type) - * and type_not_visited(ir_type). - * Or use the function to walk all types. - * - * @see typewalk - */ -void set_master_type_visited(ir_visited_t val); -ir_visited_t get_master_type_visited(void); -void inc_master_type_visited(void); +/** Increments type visited reference counter by one. + * @see @ref visited_counters, mark_type_visited(), type_visited() */ +FIRM_API void inc_master_type_visited(void); +/** Sets type visited reference counter. + * @see @ref visited_counters */ +FIRM_API void set_master_type_visited(ir_visited_t val); +/** Returns type visited reference counter. + * @see @ref visited_counters */ +FIRM_API ir_visited_t get_master_type_visited(void); /** * Sets the debug information of a type. @@ -1426,14 +1209,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); +FIRM_API 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); +FIRM_API type_dbg_info *get_type_dbg_info(const ir_type *tp); /** * Checks whether a pointer points to a type. @@ -1443,7 +1226,14 @@ dbg_info *get_type_dbg_info(const ir_type *tp); * @return * true if the thing is a type, else false */ -int is_type(const void *thing); +FIRM_API int is_type(const void *thing); + +/** + * Outputs a unique number for this type if libfirm is compiled for + * debugging, (configure with --enable-debug) else returns the address + * of the type cast to long. + */ +FIRM_API long get_type_nr(const ir_type *tp); /** * Checks whether two types are structurally equal. @@ -1464,7 +1254,6 @@ int is_type(const void *thing); * - the same supertypes -- the C-pointers are compared --> no recursive call. * - the same number of subtypes. Subtypes are not compared, * as this could cause a cyclic test. - * - the same peculiarity * - they are structure types and have the same members * - they are method types and have * - the same parameter types @@ -1477,11 +1266,11 @@ int is_type(const void *thing); * - the same element type * - 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. + * (i.e., the same C-struct to represent the type. * This is to avoid endless recursions; with pointer types cyclic * type graphs are possible.) */ -int equal_type(ir_type *typ1, ir_type *typ2); +FIRM_API int equal_type(ir_type *typ1, ir_type *typ2); /** * Checks whether two types are structural comparable. @@ -1518,10 +1307,11 @@ int equal_type(ir_type *typ1, ir_type *typ2); * @return smaller than the points_to type of lt. * */ -int smaller_type(ir_type *st, ir_type *lt); +FIRM_API int smaller_type(ir_type *st, ir_type *lt); /** - * @page class_type Representation of a class type + * @ingroup compound_type + * @defgroup class_type Class * * If the type opcode is set to type_class the type represents class * types. A list of fields and methods is associated with a class. @@ -1540,15 +1330,6 @@ int smaller_type(ir_type *st, ir_type *lt); * * - supertypes: A list of direct superclasses. * - * - peculiarity: The peculiarity of this class. If the class is of peculiarity - * "description" it only is a description of requirements to a class, - * as, e.g., a Java interface. The class will never be allocated. - * Peculiarity inherited is only possible for entities. An entity - * is of peculiarity inherited if the compiler generated the entity - * to explicitly resolve inheritance. An inherited method entity has - * no value for irg. - * Values: description, existent, inherited. Default: existent. - * * - type_info: An entity representing the type information of this class. * This entity can be of arbitrari type, Firm did not use it yet. * It allows to express the coupling of a type with an entity @@ -1573,168 +1354,143 @@ int smaller_type(ir_type *st, ir_type *lt); * between interfaces, abstract classes and other classes that all may * have the peculiarity peculiarity_description. Depending on this flag * the lowering might do different actions. Default: false + * @{ */ /** Creates a new class type. */ -ir_type *new_type_class(ident *name); +FIRM_API 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); +FIRM_API ir_type *new_d_type_class(ident *name, type_dbg_info *db); -/* --- manipulate private fields of class type --- */ +/** Returns identifier of the class type */ +FIRM_API ident *get_class_ident(const ir_type *clss); -/** Adds the entity as member of the class. */ -void add_class_member(ir_type *clss, ir_entity *member); +/** Returns identifier of the class type */ +FIRM_API const char *get_class_name(const ir_type *clss); /** Returns the number of members of this class. */ -int get_class_n_members(const ir_type *clss); +FIRM_API size_t get_class_n_members(const ir_type *clss); /** Returns the member at position pos, 0 <= pos < n_member */ -ir_entity *get_class_member(const ir_type *clss, int pos); - -/** Returns index of mem in clss, -1 if not contained. */ -int get_class_member_index(const ir_type *clss, ir_entity *mem); +FIRM_API ir_entity *get_class_member(const ir_type *clss, size_t pos); -/** Finds the member with name 'name'. If several members with the same - * name returns one of them. Returns NULL if no member found. */ -ir_entity *get_class_member_by_name(ir_type *clss, ident *name); - -/** Overwrites the member at position pos, 0 <= pos < n_member with - * the passed entity. */ -void set_class_member(ir_type *clss, ir_entity *member, int pos); - -/** Replaces complete member list in class type by the list passed. - * - * Copies the list passed. This function is necessary to reduce the number of members. - * members is an array of entities, num the size of this array. Sets all - * owners of the members passed to clss. */ -void set_class_members(ir_type *clss, ir_entity *members[], int arity); +/** + * Special index returned when get_class_member_index() cannot find a member. + * This index is never used for actual members. + */ +#define INVALID_MEMBER_INDEX ((size_t)-1) -/** Finds member in the list of members and removes it. - * - * Shrinks the member list, so iterate from the end!!! - * Does not deallocate the entity. */ -void remove_class_member(ir_type *clss, ir_entity *member); +/** Returns index of mem in clss, INVALID_MEMBER_INDEX if not contained. */ +FIRM_API size_t get_class_member_index(const ir_type *clss, ir_entity *mem); +/** Finds the member with name 'name'. If several members with the same + * name returns one of them. Returns NULL if no member found. */ +FIRM_API ir_entity *get_class_member_by_name(ir_type *clss, ident *name); /** Adds subtype as subtype to clss. * * Checks whether clss is a supertype of subtype. If not * adds also clss as supertype to subtype. */ -void add_class_subtype(ir_type *clss, ir_type *subtype); +FIRM_API void add_class_subtype(ir_type *clss, ir_type *subtype); /** Returns the number of subtypes */ -int get_class_n_subtypes(const ir_type *clss); +FIRM_API size_t get_class_n_subtypes(const ir_type *clss); -/** Gets the subtype at position pos, 0 <= pos < n_subtype. */ -ir_type *get_class_subtype(ir_type *clss, int pos); +/** Returns the subtype at position pos, 0 <= pos < n_subtype. */ +FIRM_API ir_type *get_class_subtype(ir_type *clss, size_t 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(ir_type *clss, const ir_type *subclass); +FIRM_API size_t get_class_subtype_index(ir_type *clss, const ir_type *subclass); /** Sets the subtype at position pos, 0 <= pos < n_subtype. * * Does not set the corresponding supertype relation for subtype: this might * be a different position! */ -void set_class_subtype(ir_type *clss, ir_type *subtype, int pos); +FIRM_API void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos); /** Finds subtype in the list of subtypes and removes it */ -void remove_class_subtype(ir_type *clss, ir_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) +FIRM_API void remove_class_subtype(ir_type *clss, ir_type *subtype); /** Adds supertype as supertype to class. * * Checks whether clss is a subtype of supertype. If not * adds also clss as subtype to supertype. */ -void add_class_supertype(ir_type *clss, ir_type *supertype); +FIRM_API void add_class_supertype(ir_type *clss, ir_type *supertype); /** Returns the number of supertypes */ -int get_class_n_supertypes(const ir_type *clss); +FIRM_API size_t get_class_n_supertypes(const ir_type *clss); /** 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(ir_type *clss, ir_type *super_clss); +FIRM_API size_t get_class_supertype_index(ir_type *clss, ir_type *super_clss); -/** Gets the supertype at position pos, 0 <= pos < n_supertype. */ -ir_type *get_class_supertype(ir_type *clss, int pos); +/** Returns the supertype at position pos, 0 <= pos < n_supertype. */ +FIRM_API ir_type *get_class_supertype(ir_type *clss, size_t pos); /** Sets the supertype at position pos, 0 <= pos < n_supertype. * * Does not set the corresponding subtype relation for supertype: this might * be at a different position! */ -void set_class_supertype(ir_type *clss, ir_type *supertype, int pos); +FIRM_API void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos); /** Finds supertype in the list of supertypes and removes it */ -void remove_class_supertype(ir_type *clss, ir_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) - -/** Returns a human readable string for a peculiarity. */ -const char *get_peculiarity_name(ir_peculiarity p); - -/** Returns the peculiarity of the class. */ -ir_peculiarity get_class_peculiarity(const ir_type *clss); -/** Sets the peculiarity of the class. */ -void set_class_peculiarity(ir_type *clss, ir_peculiarity pec); +FIRM_API void remove_class_supertype(ir_type *clss, ir_type *supertype); /** Returns the type info entity of a class. */ -ir_entity *get_class_type_info(const ir_type *clss); +FIRM_API ir_entity *get_class_type_info(const ir_type *clss); -/** Set a type info entity for the class. */ -void set_class_type_info(ir_type *clss, ir_entity *ent); +/** Sets a type info entity for the class. */ +FIRM_API void set_class_type_info(ir_type *clss, ir_entity *ent); /** Returns the size of the virtual function table. */ -unsigned get_class_vtable_size(const ir_type *clss); +FIRM_API unsigned get_class_vtable_size(const ir_type *clss); /** Sets a new size of the virtual function table. */ -void set_class_vtable_size(ir_type *clss, unsigned size); +FIRM_API void set_class_vtable_size(ir_type *clss, unsigned size); /** Returns non-zero if a class is final. */ -int is_class_final(const ir_type *clss); +FIRM_API int is_class_final(const ir_type *clss); /** Sets the class final flag. */ -void set_class_final(ir_type *clss, int flag); +FIRM_API void set_class_final(ir_type *clss, int flag); -/** Return non-zero if a class is an interface */ -int is_class_interface(const ir_type *clss); +/** Returns non-zero if a class is an interface */ +FIRM_API int is_class_interface(const ir_type *clss); /** Sets the class interface flag. */ -void set_class_interface(ir_type *clss, int flag); +FIRM_API void set_class_interface(ir_type *clss, int flag); -/** Return non-zero if a class is an abstract class. */ -int is_class_abstract(const ir_type *clss); +/** Returns non-zero if a class is an abstract class. */ +FIRM_API int is_class_abstract(const ir_type *clss); /** Sets the class abstract flag. */ -void set_class_abstract(ir_type *clss, int flag); - -/** Set and get a class' dfn -- - @todo This is an undocumented field, subject to change! */ -void set_class_dfn(ir_type *clss, int dfn); -int get_class_dfn(const ir_type *clss); +FIRM_API void set_class_abstract(ir_type *clss, int flag); /** Returns true if a type is a class type. */ -int is_Class_type(const ir_type *clss); +FIRM_API int is_Class_type(const ir_type *clss); /** - * @page struct_type Representation of a struct type + * This type opcode marks that the corresponding type is a class type. + * + * Consequently the type refers to supertypes, subtypes and entities. + * Entities can be any fields, but also methods. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_class; +/** Returns type opcode for class type. @see type_class */ +FIRM_API const tp_op *get_tpop_class(void); + +/** @} */ + +/** @ingroup compound_type + * @defgroup struct_type Struct * * A struct type represents aggregate types that consist of a list * of fields. @@ -1748,38 +1504,101 @@ int is_Class_type(const ir_type *clss); * but not shrinked. * This is a dynamic list that can be grown with an "add_" function, * but not shrinked. + * @{ */ + /** Creates a new type struct */ -ir_type *new_type_struct(ident *name); +FIRM_API 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); +FIRM_API ir_type *new_d_type_struct(ident *name, type_dbg_info* db); -/* --- manipulate private fields of struct --- */ +/** Returns struct identifier */ +FIRM_API ident *get_struct_ident(const ir_type *strct); -/** Adds the entity as member of the struct. */ -void add_struct_member(ir_type *strct, ir_entity *member); +/** Returns struct identifier as c-string*/ +FIRM_API const char *get_struct_name(const ir_type *strct); /** Returns the number of members of this struct. */ -int get_struct_n_members(const ir_type *strct); +FIRM_API size_t get_struct_n_members(const ir_type *strct); -/** Returns the member at position pos, 0 <= pos < n_member */ -ir_entity *get_struct_member(const ir_type *strct, int pos); +/** Returns the member at position pos, pos < n_member */ +FIRM_API ir_entity *get_struct_member(const ir_type *strct, size_t pos); /** Returns index of member in strct, -1 if not contained. */ -int get_struct_member_index(const ir_type *strct, ir_entity *member); +FIRM_API size_t get_struct_member_index(const ir_type *strct, ir_entity *member); -/** Overwrites the member at position pos, 0 <= pos < n_member with - the passed entity. */ -void set_struct_member(ir_type *strct, int pos, ir_entity *member); +/** Returns true if a type is a struct type. */ +FIRM_API int is_Struct_type(const ir_type *strct); -/** Finds member in the list of members and removes it. */ -void remove_struct_member(ir_type *strct, ir_entity *member); +/** + * This type opcode marks that the corresponding type is a compound type + * as a struct in C. + * + * Consequently the type refers to a list of entities + * which may not be methods (but pointers to methods). + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_struct; +/** Returns type opcode for struct type. @see type_struct */ +FIRM_API const tp_op *get_tpop_struct(void); -/** Returns true if a type is a struct type. */ -int is_Struct_type(const ir_type *strct); +/** @} */ /** - * @page method_type Representation of a method type + * @ingroup compound_type + * @defgroup union_type Union + * + * The union type represents union types. Note that this representation + * resembles the C union type. For tagged variant types like in Pascal or + * Modula a combination of a struct and a union type must be used. + * + * - n_types: Number of unioned types. + * - members: Entities for unioned types. Fixed length array. + * This is a dynamic list that can be grown with an "add_" + * function, but not shrinked. + * @{ + */ +/** Creates a new type union. */ +FIRM_API ir_type *new_type_union(ident *name); + +/** Creates a new type union with debug information. */ +FIRM_API ir_type *new_d_type_union(ident *name, type_dbg_info* db); + + +/** Returns union identifier */ +FIRM_API ident *get_union_ident(const ir_type *uni); + +/** Returns union identifier as c-string */ +FIRM_API const char *get_union_name(const ir_type *uni); + +/** Returns the number of unioned types of this union */ +FIRM_API size_t get_union_n_members(const ir_type *uni); + +/** Returns the entity at position pos of a union */ +FIRM_API ir_entity *get_union_member(const ir_type *uni, size_t pos); + +/** Returns index of member in uni, -1 if not contained. */ +FIRM_API size_t get_union_member_index(const ir_type *uni, ir_entity *member); + +/** Returns true if a type is a union type. */ +FIRM_API int is_Union_type(const ir_type *uni); + +/** + * This type opcode marks that the corresponding type is a union type. + * + * Consequently it refers to a list of unioned types. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_union; +/** Returns type opcode for union type. @see type_union */ +FIRM_API const tp_op *get_tpop_union(void); + +/** @} */ + +/** + * @defgroup method_type Method * * A method type represents a method, function or procedure type. * It contains a list of the parameter and result types, as these @@ -1806,31 +1625,21 @@ int is_Struct_type(const ir_type *strct); * - res_type: A list with the types of parameters. This list is ordered. * The nth type in this list corresponds to the nth input to * Return nodes. (See ircons.h for more information.) - * - * - value_res_ents - * A list of entities (whose owner is a struct private to the - * method type) that represent results passed by value. + * @{ */ -/* These macros define the suffixes for the types and entities used - to represent value parameters / results. */ -#define VALUE_PARAMS_SUFFIX "val_param" -#define VALUE_RESS_SUFFIX "val_res" - /** Create a new method type. * - * @param name the name (ident) of this type * @param n_param the number of parameters * @param n_res the number of results * * 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); +FIRM_API ir_type *new_type_method(size_t n_param, size_t n_res); /** Create a new method type with debug information. * - * @param name the name (ident) of this type * @param n_param the number of parameters * @param n_res the number of results * @param db user defined debug information @@ -1838,66 +1647,24 @@ 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); - -/* -- manipulate private fields of method. -- */ +FIRM_API ir_type *new_d_type_method(size_t n_param, size_t n_res, + type_dbg_info *db); /** Returns the number of parameters of this method. */ -int get_method_n_params(const ir_type *method); +FIRM_API size_t get_method_n_params(const ir_type *method); /** Returns the type of the parameter at position pos of a method. */ -ir_type *get_method_param_type(ir_type *method, int pos); +FIRM_API ir_type *get_method_param_type(const ir_type *method, size_t pos); /** Sets the type of the parameter at position pos of a method. - Also changes the type in the pass-by-value representation by just - changing the type of the corresponding entity if the representation is constructed. */ -void set_method_param_type(ir_type *method, int pos, ir_type *tp); -/** Returns an entity that represents the copied value argument. Only necessary - for compounds passed by value. This information is constructed only on demand. */ -ir_entity *get_method_value_param_ent(ir_type *method, int pos); -/** - * Sets the type that represents the copied value arguments. - */ -void set_method_value_param_type(ir_type *method, ir_type *tp); -/** - * Returns a type that represents the copied value arguments if one - * was allocated, else NULL. - */ -ir_type *get_method_value_param_type(const ir_type *method); -/** Returns an ident representing the parameters name. Returns NULL if not set. - For debug support only. */ -ident *get_method_param_ident(ir_type *method, int pos); -/** Returns a string representing the parameters name. Returns NULL if not set. - For debug support only. */ -const char *get_method_param_name(ir_type *method, int pos); -/** Sets an ident representing the parameters name. For debug support only. */ -void set_method_param_ident(ir_type *method, int pos, ident *id); - + * Note: does not change the corresponding parameter entities (if there are any) + */ +FIRM_API void set_method_param_type(ir_type *method, size_t pos, ir_type *tp); /** Returns the number of results of a method type. */ -int get_method_n_ress(const ir_type *method); +FIRM_API size_t get_method_n_ress(const ir_type *method); /** Returns the return type of a method type at position pos. */ -ir_type *get_method_res_type(ir_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 - changing the type of the corresponding entity if the representation is constructed. */ -void set_method_res_type(ir_type *method, int pos, ir_type *tp); -/** Returns an entity that represents the copied value result. Only necessary - for compounds passed by value. This information is constructed only on demand. */ -ir_entity *get_method_value_res_ent(ir_type *method, int pos); - -/** - * Returns a type that represents the copied value results. - */ -ir_type *get_method_value_res_type(const ir_type *method); +FIRM_API ir_type *get_method_res_type(const ir_type *method, size_t pos); +/** Sets the type of the result at position pos of a method. */ +FIRM_API void set_method_res_type(ir_type *method, size_t pos, ir_type *tp); /** * This enum flags the variadicity of methods (methods with a @@ -1910,38 +1677,24 @@ typedef enum ir_variadicity { } ir_variadicity; /** Returns the null-terminated name of this variadicity. */ -const char *get_variadicity_name(ir_variadicity vari); +FIRM_API const char *get_variadicity_name(ir_variadicity vari); /** Returns the variadicity of a method. */ -ir_variadicity get_method_variadicity(const ir_type *method); +FIRM_API ir_variadicity get_method_variadicity(const ir_type *method); /** Sets the variadicity of a method. */ -void set_method_variadicity(ir_type *method, ir_variadicity vari); - -/** - * Returns the first variadic parameter index of a type. - * If this index was NOT set, the index of the last parameter - * of the method type plus one is returned for variadic functions. - * Non-variadic function types always return -1 here. - */ -int get_method_first_variadic_param_index(const ir_type *method); - -/** - * Sets the first variadic parameter index. This allows to specify - * a complete call type (containing the type of all parameters) - * but still have the knowledge, which parameter must be passed as - * variadic one. - */ -void set_method_first_variadic_param_index(ir_type *method, int index); +FIRM_API void set_method_variadicity(ir_type *method, ir_variadicity vari); /** Returns the mask of the additional graph properties. */ -unsigned get_method_additional_properties(const ir_type *method); +FIRM_API mtp_additional_properties get_method_additional_properties(const ir_type *method); /** Sets the mask of the additional graph properties. */ -void set_method_additional_properties(ir_type *method, unsigned property_mask); +FIRM_API void set_method_additional_properties(ir_type *method, + mtp_additional_properties property_mask); /** Sets one additional graph property. */ -void set_method_additional_property(ir_type *method, mtp_additional_property flag); +FIRM_API void add_method_additional_properties(ir_type *method, + mtp_additional_properties flag); /** * Calling conventions: lower 24 bits are the number of register parameters, @@ -1966,9 +1719,6 @@ typedef enum { cc_bits = (0xFF << 24)/**< The calling convention bits. */ } calling_convention; -/* some often used cases: made as defines because firmjni cannot handle two - equal enum values. */ - /** cdecl calling convention */ #define cc_cdecl_set (0) /** stdcall calling convention */ @@ -1976,9 +1726,6 @@ typedef enum { /** fastcall calling convention */ #define cc_fastcall_set (cc_reg_param|cc_callee_clear_stk) -/** Returns the default calling convention for method types. */ -unsigned get_default_cc_mask(void); - /** * check for the CDECL calling convention */ @@ -2000,7 +1747,7 @@ unsigned get_default_cc_mask(void); #define SET_CDECL(cc_mask) (((cc_mask) & ~cc_bits) | cc_cdecl_set) /** - * Set. the STDCALL convention bits. + * Sets the STDCALL convention bits. */ #define SET_STDCALL(cc_mask) (((cc_mask) & ~cc_bits) | cc_stdcall_set) @@ -2010,63 +1757,35 @@ unsigned get_default_cc_mask(void); #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 ir_type *method); +FIRM_API unsigned get_method_calling_convention(const ir_type *method); /** Sets the calling convention of an entities graph. */ -void set_method_calling_convention(ir_type *method, unsigned cc_mask); +FIRM_API void set_method_calling_convention(ir_type *method, unsigned cc_mask); /** Returns the number of registers parameters, 0 means default. */ -unsigned get_method_n_regparams(ir_type *method); +FIRM_API unsigned get_method_n_regparams(ir_type *method); /** Sets the number of registers parameters, 0 means default. */ -void set_method_n_regparams(ir_type *method, unsigned n_regs); +FIRM_API void set_method_n_regparams(ir_type *method, unsigned n_regs); /** Returns true if a type is a method type. */ -int is_Method_type(const ir_type *method); +FIRM_API int is_Method_type(const ir_type *method); /** - * @page union_type Representation of a union (variant) type. - * - * The union type represents union types. Note that this representation - * resembles the C union type. For tagged variant types like in Pascal or Modula - * a combination of a struct and a union type must be used. + * This type opcode marks that the corresponding type is a method type. * - * - n_types: Number of unioned types. - * - members: Entities for unioned types. Fixed length array. - * This is a dynamic list that can be grown with an "add_" function, - * but not shrinked. + * Consequently it refers to a list of arguments and results. + * This struct is dynamically allocated but constant for the lifetime + * of the library. */ -/** Creates a new type union. */ -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); - -/* --- manipulate private fields of struct --- */ +FIRM_API const tp_op *type_method; +/** Returns type opcode for method type @see type_method */ +FIRM_API const tp_op *get_tpop_method(void); -/** Returns the number of unioned types of this union */ -int get_union_n_members(const ir_type *uni); - -/** Adds a new entity to a union type */ -void add_union_member(ir_type *uni, ir_entity *member); - -/** Returns the entity at position pos of a union */ -ir_entity *get_union_member(const ir_type *uni, int pos); - -/** Returns index of member in uni, -1 if not contained. */ -int get_union_member_index(const ir_type *uni, ir_entity *member); - -/** Overwrites a entity at position pos in a union type. */ -void set_union_member(ir_type *uni, int pos, ir_entity *member); - -/** Finds member in the list of members and removes it. */ -void remove_union_member(ir_type *uni, ir_entity *member); - -/** Returns true if a type is a union type. */ -int is_Union_type(const ir_type *uni); +/** @} */ /** - * @page array_type Representation of an array type + * @defgroup array_type Array * * The array type represents rectangular multi dimensional arrays. * The constants representing the bounds must be allocated to @@ -2078,10 +1797,7 @@ int is_Union_type(const ir_type *uni); * - *element_type: The type of the array elements. * - *element_ent: An entity for the array elements to be used for * element selection with Sel. - * @todo - * Do we need several entities? One might want - * to select a dimension and not a single element in case of multi - * dimensional arrays. + * @{ */ /** Create a new type array. @@ -2089,90 +1805,108 @@ int is_Union_type(const ir_type *uni); * Sets n_dimension to dimension and all dimension entries to NULL. * Initializes order to the order of the dimensions. * The entity for array elements is built automatically. - * Set dimension sizes after call to constructor with set_* routines. + * Sets dimension sizes after call to constructor with set_* routines. */ -ir_type *new_type_array(ident *name, int n_dims, ir_type *element_type); +FIRM_API ir_type *new_type_array(size_t n_dims, ir_type *element_type); /** Create a new type array with debug information. * * Sets n_dimension to dimension and all dimension entries to NULL. * Initializes order to the order of the dimensions. * The entity for array elements is built automatically. - * Set dimension sizes after call to constructor with set_* routines. + * Sets 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); +FIRM_API ir_type *new_d_type_array(size_t n_dims, ir_type *element_type, + type_dbg_info* db); -/* --- manipulate private fields of array type --- */ /** Returns the number of array dimensions of this type. */ -int get_array_n_dimensions(const ir_type *array); +FIRM_API size_t get_array_n_dimensions(const ir_type *array); /** * Allocates Const nodes of mode_Is for one array dimension. * Upper bound in Firm is the element next to the last, i.e. [lower,upper[ */ -void set_array_bounds_int(ir_type *array, int dimension, int lower_bound, - int upper_bound); +FIRM_API void set_array_bounds_int(ir_type *array, size_t 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, i.e. [lower,upper[ */ -void set_array_bounds(ir_type *array, int dimension, ir_node *lower_bound, - ir_node *upper_bound); +FIRM_API void set_array_bounds(ir_type *array, size_t dimension, + ir_node *lower_bound, ir_node *upper_bound); /** Sets the lower bound for one array dimension, i.e. [lower,upper[ */ -void set_array_lower_bound(ir_type *array, int dimension, ir_node *lower_bound); +FIRM_API void set_array_lower_bound(ir_type *array, size_t dimension, + ir_node *lower_bound); /** Allocates Const nodes of mode_Is for the lower bound of an array dimension, i.e. [lower,upper[ */ -void set_array_lower_bound_int(ir_type *array, int dimension, int lower_bound); +FIRM_API void set_array_lower_bound_int(ir_type *array, size_t dimension, + int lower_bound); /** Sets the upper bound for one array dimension, i.e. [lower,upper[ */ -void set_array_upper_bound(ir_type *array, int dimension, ir_node *upper_bound); +FIRM_API void set_array_upper_bound(ir_type *array, size_t dimension, + ir_node *upper_bound); /** Allocates Const nodes of mode_Is for the upper bound of an array dimension, i.e. [lower,upper[. */ -void set_array_upper_bound_int(ir_type *array, int dimension, int upper_bound); +FIRM_API void set_array_upper_bound_int(ir_type *array, size_t dimension, + int upper_bound); /** Returns true if lower bound != Unknown. */ -int has_array_lower_bound(const ir_type *array, int dimension); +FIRM_API int has_array_lower_bound(const ir_type *array, size_t dimension); /** Returns the lower bound of an array. */ -ir_node *get_array_lower_bound(const ir_type *array, int dimension); +FIRM_API ir_node *get_array_lower_bound(const ir_type *array, size_t dimension); /** Works only if bound is Const node with tarval that can be converted to long. */ -long get_array_lower_bound_int(const ir_type *array, int dimension); +FIRM_API long get_array_lower_bound_int(const ir_type *array, size_t dimension); /** returns true if lower bound != Unknown */ -int has_array_upper_bound(const ir_type *array, int dimension); +FIRM_API int has_array_upper_bound(const ir_type *array, size_t dimension); /** Returns the upper bound of an array. */ -ir_node *get_array_upper_bound(const ir_type *array, int dimension); +FIRM_API ir_node *get_array_upper_bound(const ir_type *array, size_t dimension); /** Works only if bound is Const node with tarval that can be converted to long. */ -long get_array_upper_bound_int(const ir_type *array, int dimension); +FIRM_API long get_array_upper_bound_int(const ir_type *array, size_t dimension); /** Sets an array dimension to a specific order. */ -void set_array_order(ir_type *array, int dimension, int order); +FIRM_API void set_array_order(ir_type *array, size_t dimension, size_t order); /** Returns the order of an array dimension. */ -int get_array_order(const ir_type *array, int dimension); +FIRM_API size_t get_array_order(const ir_type *array, size_t dimension); /** Find the array dimension that is placed at order order. */ -int find_array_dimension(const ir_type *array, int order); +FIRM_API size_t find_array_dimension(const ir_type *array, size_t order); /** Sets the array element type. */ -void set_array_element_type(ir_type *array, ir_type* tp); +FIRM_API 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); +/** Returns the array element type. */ +FIRM_API 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); +FIRM_API void set_array_element_entity(ir_type *array, ir_entity *ent); -/** Get the array element entity. */ -ir_entity *get_array_element_entity(const ir_type *array); +/** Returns the array element entity. */ +FIRM_API ir_entity *get_array_element_entity(const ir_type *array); /** Returns true if a type is an array type. */ -int is_Array_type(const ir_type *array); +FIRM_API int is_Array_type(const ir_type *array); + +/** + * This type opcode marks that the corresponding type is an array type. + * + * Consequently it contains a list of dimensions (lower and upper bounds) + * and an element type. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_array; +/** Returns type opcode for array type. @see type_array */ +FIRM_API const tp_op *get_tpop_array(void); + +/** @} */ /** - * @page enumeration_type Representation of an enumeration type + * @defgroup enumeration_type Enumeration * * Enumeration types need not necessarily be represented explicitly * by Firm types, as the frontend can lower them to integer constants as @@ -2182,101 +1916,151 @@ int is_Array_type(const ir_type *array); * * - *const: The target values representing the constants used to * represent individual enumerations. + * @{ */ /** Create a new type enumeration -- set the enumerators independently. */ -ir_type *new_type_enumeration(ident *name, int n_enums); +FIRM_API ir_type *new_type_enumeration(ident *name, size_t 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); +FIRM_API ir_type *new_d_type_enumeration(ident *name, size_t n_enums, + type_dbg_info *db); -/* --- manipulate fields of enumeration type. --- */ -/** 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); +/** Returns enumeration identifier */ +FIRM_API ident *get_enumeration_ident(const ir_type *enumeration); + +/** Returns enumeration identifier as c-string */ +FIRM_API const char *get_enumeration_name(const ir_type *enumeration); + +/** Sets an enumeration constant to a enumeration type at a given position. */ +FIRM_API void set_enumeration_const(ir_type *enumeration, size_t pos, + ident *nameid, ir_tarval *con); /** Returns the number of enumeration values of this enumeration */ -int get_enumeration_n_enums(const ir_type *enumeration); +FIRM_API size_t get_enumeration_n_enums(const ir_type *enumeration); /** Returns the enumeration constant at a given position. */ -ir_enum_const *get_enumeration_const(const ir_type *enumeration, int pos); +FIRM_API ir_enum_const *get_enumeration_const(const ir_type *enumeration, + size_t pos); /** Returns the enumeration type owner of an enumeration constant. */ -ir_type *get_enumeration_owner(const ir_enum_const *enum_cnst); +FIRM_API ir_type *get_enumeration_owner(const ir_enum_const *enum_cnst); /** Sets the enumeration constant value. */ -void set_enumeration_value(ir_enum_const *enum_cnst, tarval *con); +FIRM_API void set_enumeration_value(ir_enum_const *enum_cnst, ir_tarval *con); /** Returns the enumeration constant value. */ -tarval *get_enumeration_value(const ir_enum_const *enum_cnst); +FIRM_API ir_tarval *get_enumeration_value(const ir_enum_const *enum_cnst); /** Assign an ident to an enumeration constant. */ -void set_enumeration_nameid(ir_enum_const *enum_cnst, ident *id); +FIRM_API 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); +FIRM_API 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); +FIRM_API 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); +FIRM_API int is_Enumeration_type(const ir_type *enumeration); /** - * @page pointer_type Representation of a pointer type + * This type opcode marks that the corresponding type is an enumeration type. * - * The mode of the pointer type must be a reference mode. + * Consequently it contains a list of idents for the enumeration identifiers + * and a list of target values that are the constants used to implement + * the enumerators. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_enumeration; +/** Returns type opcode for enumeration type. @see type_enumeration */ +FIRM_API const tp_op *get_tpop_enumeration(void); + +/** @} */ + +/** + * @defgroup pointer_type Pointer * * Pointer types: - * - points_to: The type of the entity this pointer points to. + * - points_to: The type this pointer points to. + * @{ */ /** Creates a new type pointer. */ -ir_type *new_type_pointer(ident *name, ir_type *points_to, ir_mode *ptr_mode); +FIRM_API 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); +FIRM_API 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); +FIRM_API 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); +FIRM_API 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); +FIRM_API int is_Pointer_type(const ir_type *pointer); /** Returns the first pointer type that has as points_to tp. - * Not efficient: O(#types). + * Not efficient: O(\#types). * If not found returns firm_unknown_type. */ -ir_type *find_pointer_type_to_type(ir_type *tp); +FIRM_API ir_type *find_pointer_type_to_type(ir_type *tp); /** - * @page primitive_type Representation of a primitive type + * This type opcode marks that the corresponding type is a pointer type. + * + * It contains a reference to the type the pointer points to. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_pointer; +/** Returns type opcode for pointer type. @see type_pointer */ +FIRM_API const tp_op *get_tpop_pointer(void); + +/** @} */ + +/** + * @defgroup primitive_type Primitive * * Primitive types are types that represent atomic data values that * map directly to modes. They don't have private attributes. The * 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); +FIRM_API 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); +FIRM_API 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); +FIRM_API 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); +/** Returns the base type of a primitive (bitfield) type or NULL if none. */ +FIRM_API 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); +FIRM_API void set_primitive_base_type(ir_type *tp, ir_type *base_tp); + +/** + * This type opcode marks that the corresponding type is a primitive type. + * + * Primitive types are types that are directly mapped to target machine + * modes. + * This struct is dynamically allocated but constant for the lifetime + * of the library. + */ +FIRM_API const tp_op *type_primitive; +/** Returns type opcode for primitive type. @see type_primitive */ +FIRM_API const tp_op *get_tpop_primitive(void); + +/** @} */ /** - * @page none_type The None type + * @defgroup none_type None * * This type is an auxiliary type dedicated to support type analyses. * @@ -2291,15 +2075,46 @@ void set_primitive_base_type(ir_type *tp, ir_type *base_tp); * - name: "type_none" * - state: layout_fixed * - size: 0 + * @{ */ /** A variable that contains the only none type. */ -extern ir_type *firm_none_type; - +FIRM_API ir_type *firm_none_type; /** Returns the none type. */ -ir_type *get_none_type(void); +FIRM_API ir_type *get_none_type(void); +/** + * This type opcode is an auxiliary opcode dedicated to support type analyses. + * + * Types with this opcode represents that there is no type. + * The type can be used to initialize fields of the type* that actually can not + * contain a type or that are initialized for an analysis. There exists exactly + * one type with this opcode. + */ +FIRM_API const tp_op *tpop_none; +/** Returns type opcode for none type. @see tpop_none */ +FIRM_API const tp_op *get_tpop_none(void); +/** @} */ + +/** @defgroup code_type Code + * @{ + */ +/** A variable that contains the only code type. */ +FIRM_API ir_type *firm_code_type; +/** Returns the code type. */ +FIRM_API ir_type *get_code_type(void); +/** + * Checks whether a type is a code type. + */ +FIRM_API int is_code_type(const ir_type *tp); +/** + * The code type is used to mark pieces of code (basic blocks) + */ +FIRM_API const tp_op *tpop_code; +/** Returns type opcode for code type. @see tpop_code */ +FIRM_API const tp_op *get_tpop_code_type(void); +/** @} */ /** - * @page unknown_type The Unknown type + * @defgroup unknown_type Unknown * * This type is an auxiliary type dedicated to support type analyses. * @@ -2314,25 +2129,48 @@ ir_type *get_none_type(void); * - name: "type_unknown" * - state: layout_fixed * - size: 0 + * @{ */ /** A variable that contains the only unknown type. */ -extern ir_type *firm_unknown_type; - +FIRM_API ir_type *firm_unknown_type; /** Returns the unknown type. */ -ir_type *get_unknown_type(void); - +FIRM_API ir_type *get_unknown_type(void); +/** + * This type opcode is an auxiliary opcode dedicated to support type analyses. + * + * Types with this opcode represents that there could be a type, but it is not + * known. This type can be used to initialize fields before an analysis (not known + * yet) or to represent the top of a lattice (could not be determined). There exists + * exactly one type with this opcode. + */ +FIRM_API const tp_op *tpop_unknown; +/** Returns type opcode for unknown type. @see tpop_unknown */ +FIRM_API const tp_op *get_tpop_unknown(void); +/** @} */ /** * Checks whether a type is atomic. * @param tp any type * @return true if type is primitive, pointer or enumeration */ -int is_atomic_type(const ir_type *tp); +FIRM_API int is_atomic_type(const ir_type *tp); + +/** + * @defgroup compound_type Compound + * + * @{ + */ -/* --- Support for compound types --- */ +/** + * Returns the identifier of a compound type + */ +FIRM_API ident *get_compound_ident(const ir_type *tp); + +/** Returns compound identifier as c-string */ +FIRM_API const char *get_compound_name(const ir_type *tp); /** - * Gets the number of elements in a Firm compound type. + * Returns the number of elements in a Firm compound type. * * This is just a comfortability function, because structs and * classes can often be treated be the same code, but they have @@ -2342,22 +2180,28 @@ int is_atomic_type(const ir_type *tp); * * @return Number of members in the compound type. */ -int get_compound_n_members(const ir_type *tp); +FIRM_API size_t get_compound_n_members(const ir_type *tp); /** - * Gets the member of a Firm compound type at position pos. + * Returns the member of a Firm compound type at position pos. * * @param tp The type (must be struct, union or class). * @param pos The number of the member. * * @return The member entity at position pos. - * - * @see get_compound_n_members() for justification of existence. */ -ir_entity *get_compound_member(const ir_type *tp, int pos); +FIRM_API ir_entity *get_compound_member(const ir_type *tp, size_t pos); /** Returns index of member in tp, -1 if not contained. */ -int get_compound_member_index(const ir_type *tp, ir_entity *member); +FIRM_API size_t get_compound_member_index(const ir_type *tp, ir_entity *member); + +/** Remove a member from a compound type. */ +FIRM_API void remove_compound_member(ir_type *compound, ir_entity *entity); + +/** + * layout members of a struct/union or class type in a default way. + */ +FIRM_API void default_layout_compound_type(ir_type *tp); /** * Checks whether a type is a compound type. @@ -2366,55 +2210,32 @@ int get_compound_member_index(const ir_type *tp, ir_entity *member); * * @return true if the type is class, structure, union or array type. */ -int is_compound_type(const ir_type *tp); +FIRM_API int is_compound_type(const ir_type *tp); -/** - * Checks, whether a type is a frame type. - */ -int is_frame_type(const ir_type *tp); - -/** - * Checks, whether a type is a value parameter type. - */ -int is_value_param_type(const ir_type *tp); - -/** - * Checks, whether a type is a lowered type. - */ -int is_lowered_type(const ir_type *tp); +/** @} */ -/** - * Makes a new value type. Value types are struct types, - * so all struct access functions work. - * Value types are not in the global list of types. +/** @defgroup frame_type Frame + * @{ */ -ir_type *new_type_value(ident *name); /** * 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); - -/** - * Makes a clone of a frame type. - * Sets entity links from old frame entities to new onces and - * vice versa. - */ -ir_type *clone_frame_type(ir_type *type); +FIRM_API ir_type *new_type_frame(void); /** - * Sets a lowered type for a type. This sets both associations - * and marks lowered_type as a "lowered" one. + * Checks, whether a type is a frame type. */ -void set_lowered_type(ir_type *tp, ir_type *lowered_type); +FIRM_API int is_frame_type(const ir_type *tp); /** - * Gets the lowered/unlowered type of a type or NULL if this type - * has no lowered/unlowered one. + * Makes a clone of a frame type. + * Sets entity links from old frame entities to new onces and + * vice versa. */ -ir_type *get_associated_type(const ir_type *tp); +FIRM_API ir_type *clone_frame_type(ir_type *type); /** * Allocate an area of size bytes aligned at alignment @@ -2428,20 +2249,15 @@ ir_type *get_associated_type(const ir_type *tp); * * @return the entity representing the area */ -ir_entity *frame_alloc_area(ir_type *frame_type, int size, unsigned alignment, int at_start); +FIRM_API ir_entity *frame_alloc_area(ir_type *frame_type, int size, + unsigned alignment, int at_start); -/*-----------------------------------------------------------------*/ -/** Debug aides **/ -/*-----------------------------------------------------------------*/ +/** @} */ /** - * Outputs a unique number for this type if libfirm is compiled for - * debugging, (configure with --enable-debug) else returns the address - * of the type cast to long. + * @defgroup trwalk Traversing + * @{ */ -long get_type_nr(const ir_type *tp); - -/* ------------------------------------------------------------------------ */ /** Type for a function that compares two types. * @@ -2450,106 +2266,6 @@ long get_type_nr(const ir_type *tp); */ typedef int (compare_types_func_t)(const void *tp1, const void *tp2); -/** Compares two types by their name. - * - * Compares the opcode and the name of the types. If these are - * equal returns 0, else non-zero. - */ -int compare_names(const void *tp1, const void *tp2); - -/** Compares two types strict. - * - * returns 0 if tp1 == tp2, else non-zero - */ -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. - */ -int firm_hash_name(ir_type *tp); - -/* ------------------------------------------------------------------------ */ - -/** Finalize type construction. - * - * Indicate that a type is so far completed that it can be - * distinguished from other types. Mature_type hashes the type into a - * table. It uses the function in compare_types_func to compare the - * types. - * - * If it finds a type identical to tp it returns this type. It turns - * tp into the Id type. All places formerly pointing to tp will now - * point to the found type. All entities of tp now refer to the found - * type as their owner, but they are not a member of this type. This - * is invalid firm -- the entities must be replaced by entities of the - * found type. The Id type will be removed from the representation - * automatically, but within an unknown time span. It occupies memory - * for this time. - * - * @param tp The type to mature. - */ -ir_type *mature_type(ir_type *tp); - -/** Finalize type construction. - * - * Indicate that a type is so far completed that it can be - * distinguished from other types. mature_type() hashes the type into a - * table. It uses the function in compare_types_func to compare the - * types. - * - * If it finds a type identical to tp it returns this type. It frees - * type tp and all its entities. - * - * @param tp The type to mature. - */ -ir_type *mature_type_free(ir_type *tp); - -/** Finalize type construction. - * - * Indicate that a type is so far completed that it can be - * distinguished from other types. Mature_type hashes the type into a - * table. It uses the function in compare_types_func to compare the - * types. - * - * If it find a type identical to tp it returns this type. It frees - * the entities and turns the type into an Id type. All places - * formerly pointing to tp will now point to the found type. The Id - * type will be removed from the representation automatically, but - * within an unknown time span. It occupies memory for this time. - * - * @param tp The type to mature. - */ -ir_type *mature_type_free_entities(ir_type *tp); - -/** - * The interface type for the type identify module; - */ -struct type_identify_if_t { - compare_types_func_t *cmp; /**< The function that should be used to compare two types. - If NULL, compare_strict() will be used. */ - hash_types_func_t *hash; /**< The function that should be used to calculate a hash - value of a type. If NULL, hash_name() will be used. */ -}; - -/** - * Initialise the type identifier module. - * - * @param ti_if The interface functions for this module. - * - * If the parameter ti_if is NULL, the default functions compare_strict() and - * firm_hash_name() will be used. - */ -void init_type_identify(type_identify_if_t *ti_if); - /** A data type to treat types and entities as the same. */ typedef union { ir_type *typ; /**< points to a type */ @@ -2574,32 +2290,27 @@ typedef void class_walk_func(ir_type *clss, void *env); * types/entities are created during the traversal these will * be visited, too. * Does not touch frame types or types for value params ... */ -void type_walk(type_walk_func *pre, type_walk_func *post, void *env); - -/** Touches every type, entity, frame type, and value param type in - * unspecified order (also all segment types). */ -void type_walk_prog(type_walk_func *pre, type_walk_func *post, void *env); +FIRM_API void type_walk(type_walk_func *pre, type_walk_func *post, void *env); /** Walks over all type information reachable from an ir graph. * * Walks over all type information reachable from irg, i.e., starts a * type walk at the irgs entity, the irgs frame type and all types and * entities that are attributes to firm nodes. */ -void type_walk_irg(ir_graph *irg, type_walk_func *pre, type_walk_func *post, - void *env); +FIRM_API void type_walk_irg(ir_graph *irg, type_walk_func *pre, + type_walk_func *post, void *env); /** - Touches every class in specified order: - - first the super class - - second the class itself - - third the sub classes. If new classes are created - during the traversal these will be visited, too. - - @todo should be named class-walk - - @deprecated will be removed? -*/ -void type_walk_super2sub(type_walk_func *pre, type_walk_func *post, void *env); + * Touches every class in specified order: + * - first the super class + * - second the class itself + * - third the sub classes. If new classes are created + * during the traversal these will be visited, too. + * + * @deprecated will be removed? + */ +FIRM_API void type_walk_super2sub(type_walk_func *pre, type_walk_func *post, + void *env); /** Walker for class types in inheritance order. * @@ -2613,7 +2324,8 @@ void type_walk_super2sub(type_walk_func *pre, type_walk_func *post, void *env); * visiting all superclasses. * * The arguments pre, post, env may be NULL. */ -void type_walk_super(type_walk_func *pre, type_walk_func *post, void *env); +FIRM_API void type_walk_super(type_walk_func *pre, type_walk_func *post, + void *env); /** Same as type_walk_super2sub, but visits only class types. Executes pre for a class if all superclasses have been visited. @@ -2621,8 +2333,8 @@ void type_walk_super(type_walk_func *pre, type_walk_func *post, void *env); subclass. Does not visit global type, frame types. */ -void class_walk_super2sub(class_walk_func *pre, class_walk_func *post, - void *env); +FIRM_API void class_walk_super2sub(class_walk_func *pre, class_walk_func *post, + void *env); /** * the entity walk function. A function type for entity walkers. @@ -2639,7 +2351,8 @@ typedef void entity_walk_func(ir_entity *ent, void *env); * @param doit the entity walker function * @param env environment, will be passed to the walker function */ -void walk_types_entities(ir_type *tp, entity_walk_func *doit, void *env); +FIRM_API void walk_types_entities(ir_type *tp, entity_walk_func *doit, + void *env); /** * If we have the closed world assumption, we can calculate the @@ -2647,6 +2360,17 @@ void walk_types_entities(ir_type *tp, entity_walk_func *doit, void *env); * After this is done, all classes and entities that are not overridden * anymore have the final property set. */ -void types_calc_finalization(void); +FIRM_API void types_calc_finalization(void); + +/** @deprecated */ +FIRM_API ir_visibility get_type_visibility(const ir_type *tp); +/** @deprecated */ +FIRM_API void set_type_visibility(ir_type *tp, ir_visibility v); + +/** @} */ + +/** @} */ + +#include "end.h" #endif