ir_node *new_rd_SymConst_size (dbg_info *db, ir_graph *irg, ir_type *symbol, ir_type *tp) {
symconst_symbol sym = {symbol};
- return new_rd_SymConst_type(db, irg, get_irg_start_block(irg), sym, symconst_size, tp);
+ return new_rd_SymConst_type(db, irg, get_irg_start_block(irg), sym, symconst_type_size, tp);
+}
+
+ir_node *new_rd_SymConst_align (dbg_info *db, ir_graph *irg, ir_type *symbol, ir_type *tp) {
+ symconst_symbol sym = {symbol};
+ return new_rd_SymConst_type(db, irg, get_irg_start_block(irg), sym, symconst_type_align, tp);
}
ir_node *
* ---------------------------------------------------------------------------
*
* There are three kinds of symbolic constants:
- * symconst_type_tag The symbolic constant represents a type tag.
- * symconst_size The symbolic constant represents the size of a class.
- * symconst_addr_name Information for the linker, e.g. the name of a global
- * variable.
+ * symconst_type_tag The symbolic constant represents a type tag.
+ * symconst_type_size The symbolic constant represents the size of a type.
+ * symconst_type_align The symbolic constant represents the alignment of a type.
+ * symconst_addr_name Information for the linker, e.g. the name of a global
+ * variable.
+ * symconst_addr_name The symbolic constant represents the address of an entity.
+ *
* To represent a pointer to an entity that is represented by an entity
* datastructure don't use
* new_SymConst((type_or_id*)get_entity_ld_ident(ent), symconst_addr_name);.
* Use a real const instead:
- * new_SymConst(mode_P_mach, tarval_p_from_entity(ent));
+ * new_SymConst(ent, symconst_addr_ent);
* This makes the Constant independent of name changes of the entity due to
* mangling.
*
* Attributes:
* attr.i.num The symconst_addr_ent, i.e. one of
* -symconst_type_tag
- * -symconst_size
- * - symconst_addr_name
- * If the attr.i.num is symconst_type_tag or symconst_size, the node contains an attribute
+ * -symconst_type_size
+ * -symconst_type_align
+ * -symconst_addr_name
+ *
+ * If the attr.i.num is symconst_type_tag, symconst_type_size or symconst_type_align,
+ * the node contains an attribute:
+ *
* attr.i.*type, a pointer to a type_class. The mode of the node is mode_Is.
* if it is linkage_ptr_info it contains
* attr.i.*ptrinfo, an ident holding information for the linker. The mode
*
* This is the constructor for a symbolic constant.
* There are four kinds of symbolic constants:
- * - type_tag The symbolic constant represents a type tag. The type the
- * tag stands for is given explicitly.
- * - size The symbolic constant represents the size of a type. The
- * type of which the constant represents the size is given
- * explicitly.
- * - addr_name The symbolic constant represents the address of an entity
- * (variable or method). The variable is indicated by a name
- * that is valid for linking.
+ * - type_tag The symbolic constant represents a type tag. The type the
+ * tag stands for is given explicitly.
+ * - type_size The symbolic constant represents the size of a type. The
+ * type of which the constant represents the size is given
+ * explicitly.
+ * - type_align The symbolic constant represents the alignment of a type. The
+ * type of which the constant represents the size is given
+ * explicitly.
+ * - addr_name The symbolic constant represents the address of an entity
+ * (variable or method). The variable is indicated by a name
+ * that is valid for linking.
* - addr_ent The symbolic constant represents the address of an entity
- * (variable or method). The variable is given explicitly by
- * a firm entity.
+ * (variable or method). The variable is given explicitly by
+ * a firm entity.
*
* Inputs to the node:
* No inputs except the block it belongs to.
/** Constructor for a SymConst size node.
*
* Same as new_rd_SymConst_type, except that the constructor is tailored for
- * symconst_addr_ent.
+ * symconst_type_size.
* Adds the SymConst to the start block of irg. */
ir_node *new_rd_SymConst_size (dbg_info *db, ir_graph *irg, ir_type *symbol, ir_type *tp);
+/** Constructor for a SymConst size node.
+ *
+ * Same as new_rd_SymConst_type, except that the constructor is tailored for
+ * symconst_type_align.
+ * Adds the SymConst to the start block of irg. */
+ir_node *new_rd_SymConst_align (dbg_info *db, ir_graph *irg, ir_type *symbol, ir_type *tp);
+
/** Constructor for a simpleSel node.
*
* This is a shortcut for the new_rd_Sel() constructor. To be used for
*
* @param *db A pointer for debug information.
* @param value A type, entity or ident depending on the SymConst kind.
- * @param kind The kind of the symbolic constant: symconst_type_tag, symconst_size
- * or symconst_addr_name.
+ * @param kind The kind of the symbolic constant: symconst_type_tag, symconst_type_size,
+ * symconst_type_align, symconst_addr_name or symconst_addr_ent.
* @param tp The source type of the constant.
*/
ir_node *new_d_SymConst_type (dbg_info *db, union symconst_symbol value, symconst_kind kind, ir_type *tp);
* An unsigned integer (I_u) or a pointer (P).
*
* @param value A type or a ident depending on the SymConst kind.
- * @param kind The kind of the symbolic constant: symconst_type_tag, symconst_size or symconst_addr_name.
+ * @param kind The kind of the symbolic constant: symconst_type_tag, symconst_type_size
+ * symconst_type_align, symconst_addr_name or symconst_addr_ent.
*/
ir_node *new_SymConst (union symconst_symbol value, symconst_kind kind);
/* @@@ some consts have an entity */
break;
case iro_SymConst:
- if ( (get_SymConst_kind(n) ==symconst_type_tag)
- || (get_SymConst_kind(n) ==symconst_size))
- {
- print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
- }
+ if (SYMCONST_HAS_TYPE(get_SymConst_kind(n)))
+ print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
break;
case iro_Sel: {
print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
fprintf(F, " type: ");
dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames);
break;
- case symconst_size:
+ case symconst_type_size:
fprintf(F, " kind: size\n");
fprintf(F, " type: ");
dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames);
break;
+ case symconst_type_align:
+ fprintf(F, " kind: alignment\n");
+ fprintf(F, " type: ");
+ dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames);
+ break;
}
fprintf(F, " type of value: %s \n", get_type_name_ex(get_SymConst_value_type(n), &bad));
} break;
ir_type *
get_SymConst_type (ir_node *node) {
- assert ( (node->op == op_SymConst)
- && ( get_SymConst_kind(node) == symconst_type_tag
- || get_SymConst_kind(node) == symconst_size));
+ assert( (node->op == op_SymConst)
+ && (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
return node->attr.i.sym.type_p = skip_tid(node->attr.i.sym.type_p);
}
void
set_SymConst_type (ir_node *node, ir_type *tp) {
- assert ( (node->op == op_SymConst)
- && ( get_SymConst_kind(node) == symconst_type_tag
- || get_SymConst_kind(node) == symconst_size));
+ assert( (node->op == op_SymConst)
+ && (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
node->attr.i.sym.type_p = tp;
}
/** Return the attribute type of a SymConst node if exists */
static ir_type *get_SymConst_attr_type(ir_node *self) {
symconst_kind kind = get_SymConst_kind(self);
- if (kind == symconst_type_tag || kind == symconst_size)
+ if (SYMCONST_HAS_TYPE(kind))
return get_SymConst_type(self);
return NULL;
}
/** Return the attribute entity of a SymConst node if exists */
static entity *get_SymConst_attr_entity(ir_node *self) {
symconst_kind kind = get_SymConst_kind(self);
- if (kind == symconst_addr_ent)
+ if (SYMCONST_HAS_ENT(kind))
return get_SymConst_entity(self);
return NULL;
}
this flag. */
typedef enum {
symconst_type_tag, /**< The SymConst is a type tag for the given type.
- Type_or_id_p is type *. */
- symconst_size, /**< The SymConst is the size of the given type.
- Type_or_id_p is type *. */
+ symconst_symbol is type *. */
+ symconst_type_size, /**< The SymConst is the size of the given type.
+ symconst_symbol is type *. */
+ symconst_type_align, /**< The SymConst is the alignment of the given type.
+ symconst_symbol is type *. */
symconst_addr_name, /**< The SymConst is a symbolic pointer to be filled in
by the linker. The pointer is represented by a string.
- Type_or_id_p is ident *. */
+ symconst_symbol is ident *. */
symconst_addr_ent /**< The SymConst is a symbolic pointer to be filled in
by the linker. The pointer is represented by an entity.
- Type_or_id_p is entity *. */
+ symconst_symbol is entity *. */
} symconst_kind;
+/** Returns non-zero if s symconst kind has a type attribute */
+#define SYMCONST_HAS_TYPE(kind) ((kind) <= symconst_type_align)
+
+/** Returns non-zero if s symconst kind has an ident attribute */
+#define SYMCONST_HAS_ID(kind) ((kind) == symconst_addr_name)
+
+/** Returns non-zero if s symconst kind has an entity attribute */
+#define SYMCONST_HAS_ENT(kind) ((kind) == symconst_addr_ent)
+
/** SymConst attribute.
*
* This union contains the symbolic information represented by the node. */
-union symconst_symbol {
+typedef union symconst_symbol {
ir_type *type_p;
ident *ident_p;
entity *entity_p;
-};
-
-typedef union symconst_symbol symconst_symbol;
-
+} symconst_symbol;
/** Get the kind of the SymConst. */
symconst_kind get_SymConst_kind (const ir_node *node);
*/
static tarval *computed_value_SymConst(ir_node *n)
{
- if ((get_SymConst_kind(n) == symconst_size) &&
- (get_type_state(get_SymConst_type(n))) == layout_fixed)
- return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(n)), get_irn_mode(n));
+ ir_type *type;
+
+ switch (get_SymConst_kind(n)) {
+ case symconst_type_size:
+ type = get_SymConst_type(n);
+ if (get_type_state(type) == layout_fixed)
+ return new_tarval_from_long(get_type_size_bytes(type), get_irn_mode(n));
+ break;
+ case symconst_type_align:
+ type = get_SymConst_type(n);
+ if (get_type_state(type) == layout_fixed)
+ return new_tarval_from_long(get_type_alignment_bytes(type), get_irn_mode(n));
+ break;
+ default:
+ break;
+ }
return tarval_bad;
}
case symconst_type_tag: /* type tag */
snprintf(tv_buf, sizeof(tv_buf), "<ID:%s>", get_type_name(get_SymConst_type(X)));
break;
- case symconst_size: /* type size */
+ case symconst_type_size: /* type size */
snprintf(tv_buf, sizeof(tv_buf), "<SIZE:%s>", get_type_name(get_SymConst_type(X)));
break;
+ case symconst_type_align: /* type alignment */
+ snprintf(tv_buf, sizeof(tv_buf), "<ALIGN:%s>", get_type_name(get_SymConst_type(X)));
+ break;
case symconst_addr_name: /* linker name */
snprintf(tv_buf, sizeof(tv_buf), "<EXT:%s>", get_id_str(get_SymConst_name(X)));
break;