-static void normalize_irn_class_cast(ir_node *n, void *env) {
- if (get_irn_op(n) != op_Cast) return;
-
-
- type *fromtype = get_irn_typeinfo_type(get_Cast_op(n));
- type *totype = get_Cast_type(n);
- int ref_depth = 0;
-
- if (totype == fromtype) return; /* Case for optimization! */
-
- while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
- totype = get_pointer_points_to_type(totype);
- fromtype = get_pointer_points_to_type(fromtype);
- ref_depth++;
- }
-
- if (!is_Class_type(totype)) return;
- if (!is_Class_type(fromtype)) return;
-
- if ((get_class_supertype_index(totype, fromtype) != -1) ||
- (get_class_supertype_index(fromtype, totype) != -1) ) {
- /* It's just what we want ... */
- return;
- }
-
- set_cur_block(get_nodes_block(n));
-
- if (is_subclass_of(totype, fromtype)) {
- /* downcast */
- while (get_class_subtype_index(fromtype, totype) == -1) {
- /* Insert a cast to a subtype of fromtype. */
- type *new_type = NULL;
- ir_node *new_cast;
- int i, n_subtypes = get_class_n_subtypes(fromtype);
- for (i = 0; i < n_subtypes && !new_type; ++i) {
- type *new_sub = get_class_subtype(fromtype, i);
- if (is_superclass_of(new_sub, totype))
- new_type = new_sub;
- }
- assert(new_type);
- fromtype = new_type;
- new_type = pointerize_type(new_type, ref_depth);
- new_cast = new_Cast(get_Cast_op(n), new_type);
- n_casts_normalized ++;
- set_irn_typeinfo_type(new_cast, new_type); /* keep type information up to date. */
- set_Cast_op(n, new_cast);
- if (get_trouts_state() != outs_none) add_type_cast(new_type, new_cast);
- }
- }
- else {
- assert(is_superclass_of(totype, fromtype));
- /* upcast */
- while (get_class_supertype_index(fromtype, totype) == -1) {
- /* Insert a cast to a supertype of fromtype. */
- type *new_type = NULL;
- ir_node *new_cast;
- int i, n_supertypes = get_class_n_supertypes(fromtype);
- for (i = 0; i < n_supertypes && !new_type; ++i) {
- type *new_super = get_class_supertype(fromtype, i);
- if (is_subclass_of(new_super, totype))
- new_type = new_super;
- }
- assert(new_type);
- fromtype = new_type;
- new_type = pointerize_type(new_type, ref_depth);
- new_cast = new_Cast(get_Cast_op(n), new_type);
- n_casts_normalized ++;
- set_irn_typeinfo_type(new_cast, new_type); /* keep type information up to date. */
- if (get_trouts_state() != outs_none) add_type_cast(new_type, new_cast);
- set_Cast_op(n, new_cast);
- }
- }
+/**
+ * Post-Walker.
+ */
+static void normalize_irn_class_cast(ir_node *n, void *env)
+{
+ ir_node *res;
+ (void) env;
+ if (is_Cast(n)) {
+ ir_node *pred = get_Cast_op(n);
+ ir_type *totype = get_Cast_type(n);
+ res = normalize_values_type(totype, pred);
+ set_Cast_op(n, res);
+ } else if (is_Call(n)) {
+ size_t n_params = get_Call_n_params(n);
+ size_t i;
+ ir_type *tp = get_Call_type(n);
+ for (i = 0; i < n_params; ++i) {
+ res = normalize_values_type(get_method_param_type(tp, i), get_Call_param(n, i));
+ set_Call_param(n, i, res);
+ }
+ }