+} /* get_address_taken_state_name */
+
+/* Get the entity's stickyness */
+ir_stickyness
+(get_entity_stickyness)(const ir_entity *ent) {
+ return _get_entity_stickyness(ent);
+} /* get_entity_stickyness */
+
+/* Set the entity's stickyness */
+void
+(set_entity_stickyness)(ir_entity *ent, ir_stickyness stickyness) {
+ _set_entity_stickyness(ent, stickyness);
+} /* set_entity_stickyness */
+
+/* Set has no effect for existent entities of type method. */
+ir_node *
+get_atomic_ent_value(ir_entity *ent)
+{
+ assert(ent && is_atomic_entity(ent));
+ assert(ent->variability != variability_uninitialized);
+ return skip_Id(ent->value);
+} /* get_atomic_ent_value */
+
+void
+set_atomic_ent_value(ir_entity *ent, ir_node *val) {
+ assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
+ if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
+ return;
+ ent->value = val;
+} /* set_atomic_ent_value */
+
+/* Returns true if the the node is representable as code on
+ * const_code_irg. */
+int is_irn_const_expression(ir_node *n) {
+ ir_mode *m;
+
+ /* we are in danger iff an exception will arise. TODO: be more precisely,
+ * for instance Div. will NOT rise if divisor != 0
+ */
+ if (is_binop(n) && !is_fragile_op(n))
+ return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
+
+ m = get_irn_mode(n);
+ switch (get_irn_opcode(n)) {
+ case iro_Const:
+ case iro_SymConst:
+ case iro_Unknown:
+ return 1;
+ case iro_Conv:
+ case iro_Cast:
+ return is_irn_const_expression(get_irn_n(n, 0));
+ default:
+ break;
+ }
+ return 0;
+} /* is_irn_const_expression */
+
+/*
+ * Copies a firm subgraph that complies to the restrictions for
+ * constant expressions to current_block in current_ir_graph.
+ */
+ir_node *copy_const_value(dbg_info *dbg, ir_node *n) {
+ ir_node *nn;
+ ir_mode *m;
+
+ /* @@@ GL I think we should implement this using the routines from irgopt for
+ dead node elimination/inlineing. */
+
+ m = get_irn_mode(n);
+ switch (get_irn_opcode(n)) {
+ case iro_Const:
+ nn = new_d_Const_type(dbg, m, get_Const_tarval(n), get_Const_type(n));
+ break;
+ case iro_SymConst:
+ nn = new_d_SymConst_type(dbg, get_SymConst_symbol(n), get_SymConst_kind(n),
+ get_SymConst_value_type(n));
+ break;
+ case iro_Add:
+ nn = new_d_Add(dbg, copy_const_value(dbg, get_Add_left(n)),
+ copy_const_value(dbg, get_Add_right(n)), m); break;
+ case iro_Sub:
+ nn = new_d_Sub(dbg, copy_const_value(dbg, get_Sub_left(n)),
+ copy_const_value(dbg, get_Sub_right(n)), m); break;
+ case iro_Mul:
+ nn = new_d_Mul(dbg, copy_const_value(dbg, get_Mul_left(n)),
+ copy_const_value(dbg, get_Mul_right(n)), m); break;
+ case iro_And:
+ nn = new_d_And(dbg, copy_const_value(dbg, get_And_left(n)),
+ copy_const_value(dbg, get_And_right(n)), m); break;
+ case iro_Or:
+ nn = new_d_Or(dbg, copy_const_value(dbg, get_Or_left(n)),
+ copy_const_value(dbg, get_Or_right(n)), m); break;
+ case iro_Eor:
+ nn = new_d_Eor(dbg, copy_const_value(dbg, get_Eor_left(n)),
+ copy_const_value(dbg, get_Eor_right(n)), m); break;
+ case iro_Cast:
+ nn = new_d_Cast(dbg, copy_const_value(dbg, get_Cast_op(n)), get_Cast_type(n)); break;
+ case iro_Conv:
+ nn = new_d_Conv(dbg, copy_const_value(dbg, get_Conv_op(n)), m); break;
+ case iro_Unknown:
+ nn = new_d_Unknown(m); break;
+ default:
+ assert(0 && "opcode invalid or not implemented");
+ nn = NULL;
+ break;
+ }
+ return nn;
+} /* copy_const_value */
+
+/* Creates a new compound graph path. */
+compound_graph_path *
+new_compound_graph_path(ir_type *tp, int length) {
+ compound_graph_path *res;
+
+ assert(is_compound_type(tp));
+ assert(length > 0);
+
+ res = xmalloc(sizeof(*res) + (length-1) * sizeof(res->list[0]));
+ memset(res, 0, sizeof(*res) + (length-1) * sizeof(res->list[0]));
+ res->kind = k_ir_compound_graph_path;
+ res->tp = tp;
+ res->len = length;
+
+ return res;
+} /* new_compound_graph_path */
+
+/* Frees an graph path object */
+void free_compound_graph_path (compound_graph_path *gr) {
+ assert(gr && is_compound_graph_path(gr));
+ gr->kind = k_BAD;
+ free(gr);
+} /* free_compound_graph_path */
+
+/* Returns non-zero if an object is a compound graph path */
+int is_compound_graph_path(const void *thing) {
+ return (get_kind(thing) == k_ir_compound_graph_path);
+} /* is_compound_graph_path */
+
+/* Checks whether the path up to pos is correct. If the path contains a NULL,
+ * assumes the path is not complete and returns 'true'. */
+int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
+ int i;
+ ir_entity *node;
+ ir_type *owner = gr->tp;
+
+ for (i = 0; i <= pos; i++) {
+ node = get_compound_graph_path_node(gr, i);
+ if (node == NULL)
+ /* Path not yet complete. */
+ return 1;
+ if (get_entity_owner(node) != owner)
+ return 0;
+ owner = get_entity_type(node);
+ }
+ if (pos == get_compound_graph_path_length(gr))
+ if (!is_atomic_type(owner))
+ return 0;
+ return 1;
+} /* is_proper_compound_graph_path */
+
+/* Returns the length of a graph path */
+int get_compound_graph_path_length(const compound_graph_path *gr) {
+ assert(gr && is_compound_graph_path(gr));
+ return gr->len;
+} /* get_compound_graph_path_length */
+
+ir_entity *
+get_compound_graph_path_node(const compound_graph_path *gr, int pos) {
+ assert(gr && is_compound_graph_path(gr));
+ assert(pos >= 0 && pos < gr->len);
+ return gr->list[pos].node;
+} /* get_compound_graph_path_node */
+
+void
+set_compound_graph_path_node(compound_graph_path *gr, int pos, ir_entity *node) {
+ assert(gr && is_compound_graph_path(gr));
+ assert(pos >= 0 && pos < gr->len);
+ assert(is_entity(node));
+ gr->list[pos].node = node;
+ assert(is_proper_compound_graph_path(gr, pos));
+} /* set_compound_graph_path_node */
+
+int
+get_compound_graph_path_array_index(const compound_graph_path *gr, int pos) {
+ assert(gr && is_compound_graph_path(gr));
+ assert(pos >= 0 && pos < gr->len);
+ return gr->list[pos].index;
+} /* get_compound_graph_path_array_index */
+
+void
+set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
+ assert(gr && is_compound_graph_path(gr));
+ assert(pos >= 0 && pos < gr->len);
+ gr->list[pos].index = index;
+} /* set_compound_graph_path_array_index */
+
+/* A value of a compound entity is a pair of value and the corresponding path to a member of