/*
- * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
*/
/**
- * @file type.c
+ * @file
* @brief Representation of types -- private header.
* @author Goetz Lindenmaier, Michael Beck
* @version $Id$
+ * @see type.h tpop_t.h tpop.h
*/
#ifndef FIRM_TR_TYPE_T_H
#define FIRM_TR_TYPE_T_H
#include "firm_config.h"
-#include "type.h"
+#include "typerep.h"
#include "tpop_t.h"
#include "irgraph.h"
+#include "firm_common.h"
#include "array.h"
-/**
- * @file type_t.h
- * This file contains the datatypes hidden in type.h.
- *
- * @author Goetz Lindenmaier
- * @see type.h tpop_t.h tpop.h
- */
-
/** Class flags. */
enum class_flags {
cf_none = 0, /**< No flags. */
ir_type *points_to; /**< The type of the ir_entity the pointer points to. */
} ptr_attr;
-/*
-typedef struct { * No private attr yet! *
-} pri_attr; */
+/** Primitive type attributes. */
+typedef struct {
+ ir_type *base_type; /**< For bitfield types: The base primitive type, NULL else. */
+} pri_attr;
/*
arr_attr aa; /**< Attributes of an array type */
enm_attr ea; /**< Attributes of an enumeration type */
ptr_attr pa; /**< Attributes of a pointer type */
+ pri_attr ba; /**< Attributes of a primitive bitfield type */
} tp_attr;
/** Additional type flags. */
tf_tls_type = 32, /**< Set only for the tls type */
};
-/** The structure of a type. */
+/**
+ * An abstract data type to represent types.
+ *
+ * This is the abstract data type with which any type known in the
+ * compiled program can be represented. 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.
+ *
+ * There exist several kinds of types, arranged by the structure of
+ * the type. These are distinguished by a type opcode.
+ * 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.
+ *
+ * The following describes the common attributes. They can only be
+ * accessed by the functions given below.
+ *
+ * The common fields are:
+ *
+ * - firm_kind: A firm_kind tag containing k_type. This is useful
+ * for dynamically checking whether a node is a type node.
+ * - type_op: A tp_op specifying the kind of the type.
+ * - name: An identifier specifying the name of the type. To be
+ * set by the frontend.
+ * - visibility: The visibility of this type.
+ * - size: The size of the type, i.e. an entity of this type will
+ * occupy size bits in memory. In several cases this is
+ * determined when fixing the layout of this type (class,
+ * struct, union, array, enumeration).
+ * - alignment The alignment of the type, i.e. an entity of this type will
+ * be allocated an an address in memory with this alignment.
+ * In several cases this is determined when fixing the layout
+ * of this type (class, struct, union, array)
+ * - mode: The mode to be used to represent the type on a machine.
+ * - state: The state of the type. The state represents whether the
+ * layout of the type is undefined or fixed (values: layout_undefined
+ * or layout_fixed). Compound types can have an undefined
+ * layout. The layout of the basic types primitive and pointer
+ * is always layout_fixed. If the layout of
+ * compound types is fixed all entities must have an offset
+ * and the size of the type must be set.
+ * A fixed layout for enumeration types means that each enumeration
+ * is associated with an implementation value.
+ * - assoc_type: The associated lowered/upper type.
+ * - visit: A counter for walks of the type information.
+ * - link: A void* to associate some additional information with the type.
+ *
+ * These fields can only be accessed via access functions.
+ *
+ * Depending on the value of @c type_op, i.e., depending on the kind of the
+ * type the adt contains further attributes. These are documented below.
+ *
+ * @see
+ *
+ * @link class_type class @endlink, @link struct_type struct @endlink,
+ * @link method_type method @endlink, @link union_type union @endlink,
+ * @link array_type array @endlink, @link enumeration_type enumeration @endlink,
+ * @link pointer_type pointer @endlink, @link primitive_type primitive @endlink
+ *
+ * @todo
+ * mode maybe not global field??
+ */
struct ir_type {
firm_kind kind; /**< the firm kind, must be k_type */
const tp_op *type_op; /**< the type operation of the type */
ident *name; /**< The name of the type */
ir_visibility visibility;/**< Visibility of entities of this type. */
unsigned flags; /**< Type flags, a bitmask of enum type_flags. */
- int size; /**< Size of an ir_entity of this type. This is determined
+ unsigned size; /**< Size of an ir_entity of this type. This is determined
when fixing the layout of this class. Size must be
- given in bits. */
- int align; /**< Alignment of an ir_entity of this type. This should be
+ given in bytes. */
+ unsigned align; /**< Alignment of an ir_entity of this type. This should be
set according to the source language needs. If not set it's
calculated automatically by get_type_alignment().
- Alignment must be given in bits. */
+ Alignment must be given in bytes. */
ir_mode *mode; /**< The mode for atomic types */
- unsigned long visit; /**< visited counter for walks of the type information */
+ ir_visited_t visit; /**< visited counter for walks of the type information */
void *link; /**< holds temporary data - like in irnode_t.h */
struct dbg_info *dbi; /**< A pointer to information for debug support. */
ir_type *assoc_type; /**< The associated lowered/unlowered type */
void set_primitive_mode(ir_type *tp, ir_mode *mode);
void set_enumeration_mode(ir_type *tp, ir_mode *mode);
-void set_class_size_bits(ir_type *tp, int bits);
-void set_struct_size_bits(ir_type *tp, int bits);
-void set_union_size_bits(ir_type *tp, int bits);
-void set_array_size_bits(ir_type *tp, int size);
-void set_default_size_bits(ir_type *tp, int size);
+void set_class_size(ir_type *tp, unsigned bytes);
+void set_struct_size(ir_type *tp, unsigned bytes);
+void set_union_size(ir_type *tp, unsigned bytes);
+void set_array_size(ir_type *tp, unsigned bytes);
+void set_default_size(ir_type *tp, unsigned bytes);
/**
* Initialize the type module.
* inline functions *
* ------------------- */
-extern unsigned long firm_type_visited;
+extern ir_visited_t firm_type_visited;
-static INLINE void _set_master_type_visited(unsigned long val) { firm_type_visited = val; }
-static INLINE unsigned long _get_master_type_visited(void) { return firm_type_visited; }
-static INLINE void _inc_master_type_visited(void) { ++firm_type_visited; }
+static INLINE void _set_master_type_visited(ir_visited_t val) { firm_type_visited = val; }
+static INLINE ir_visited_t _get_master_type_visited(void) { return firm_type_visited; }
+static INLINE void _inc_master_type_visited(void) { ++firm_type_visited; }
static INLINE void *
_get_type_link(const ir_type *tp) {
tp->name = id;
}
-static INLINE int
-_get_type_size_bits(const ir_type *tp) {
+static INLINE unsigned
+_get_type_size_bytes(const ir_type *tp) {
assert(tp && tp->kind == k_type);
return tp->size;
}
-static INLINE int
-_get_type_size_bytes(const ir_type *tp) {
- int size = _get_type_size_bits(tp);
- if (size < 0)
- return -1;
- if ((size & 7) != 0) {
- assert(0 && "cannot take byte size of this type");
- return -1;
- }
- return size >> 3;
-}
-
-static INLINE type_state
+static INLINE ir_type_state
_get_type_state(const ir_type *tp) {
assert(tp && tp->kind == k_type);
return tp->flags & tf_layout_fixed ? layout_fixed : layout_undefined;
}
-static INLINE unsigned long
+static INLINE ir_visited_t
_get_type_visited(const ir_type *tp) {
assert(tp && tp->kind == k_type);
return tp->visit;
}
static INLINE void
-_set_type_visited(ir_type *tp, unsigned long num) {
+_set_type_visited(ir_type *tp, ir_visited_t num) {
assert(tp && tp->kind == k_type);
tp->visit = num;
}
return tp->visit < firm_type_visited;
}
+static INLINE dbg_info *
+_get_type_dbg_info(const ir_type *tp) {
+ return tp->dbi;
+}
+
+static INLINE void
+_set_type_dbg_info(ir_type *tp, dbg_info *db) {
+ tp->dbi = db;
+}
+
static INLINE int
_is_type(const void *thing) {
return (get_kind(thing) == k_type);
method->attr.ma.irg_calling_conv = cc_mask;
}
+
#define set_master_type_visited(val) _set_master_type_visited(val)
#define get_master_type_visited() _get_master_type_visited()
#define inc_master_type_visited() _inc_master_type_visited()
#define get_type_mode(tp) _get_type_mode(tp)
#define get_type_ident(tp) _get_type_ident(tp)
#define set_type_ident(tp, id) _set_type_ident(tp, id)
-#define get_type_size_bits(tp) _get_type_size_bits(tp)
#define get_type_size_bytes(tp) _get_type_size_bytes(tp)
#define get_type_state(tp) _get_type_state(tp)
#define get_type_visited(tp) _get_type_visited(tp)
#define mark_type_visited(tp) _mark_type_visited(tp)
#define type_visited(tp) _type_visited(tp)
#define type_not_visited(tp) _type_not_visited(tp)
+#define get_type_dbg_info(tp) _get_type_dbg_info(tp)
+#define set_type_dbg_info(tp, db) _set_type_dbg_info(tp, db)
#define is_type(thing) _is_type(thing)
#define is_Class_type(clss) _is_class_type(clss)
#define get_class_n_members(clss) _get_class_n_members(clss)