added phase reinit data per irn
[libfirm] / ir / tr / type.c
index 3288048..3eaedfa 100644 (file)
@@ -6,7 +6,7 @@
  * Modified by: Michael Beck
  * Created:
  * CVS-ID:      $Id$
- * Copyright:   (c) 2001-2003 Universität Karlsruhe
+ * Copyright:   (c) 2001-2006 Universität Karlsruhe
  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
  */
 
@@ -255,7 +255,7 @@ int (get_type_size_bits)(const ir_type *tp) {
 }
 
 
-visibility get_type_visibility (const ir_type *tp) {
+ir_visibility get_type_visibility (const ir_type *tp) {
 #if 0
   visibility res =  visibility_local;
   if (is_compound_type(tp)) {
@@ -279,7 +279,7 @@ visibility get_type_visibility (const ir_type *tp) {
   return tp->visibility;
 }
 
-void       set_type_visibility (ir_type *tp, visibility v) {
+void       set_type_visibility (ir_type *tp, ir_visibility v) {
   assert(is_type(tp));
 #if 0
   /* check for correctness */
@@ -406,50 +406,50 @@ set_type_state(ir_type *tp, type_state state) {
     int i;
     switch (get_type_tpop_code(tp)) {
     case tpo_class:
-      {
-    assert(get_type_size_bits(tp) > -1);
-    if (tp != get_glob_type()) {
-      int n_mem = get_class_n_members(tp);
-      for (i = 0; i < n_mem; i++) {
-        if (get_entity_offset_bits(get_class_member(tp, i)) <= -1)
-          { DDMT(tp); DDME(get_class_member(tp, i)); }
-        assert(get_entity_offset_bits(get_class_member(tp, i)) > -1);
-            /* TR ??
-        assert(is_Method_type(get_entity_type(get_class_member(tp, i))) ||
-           (get_entity_allocation(get_class_member(tp, i)) == allocation_automatic));
-                   */
+      assert(get_type_size_bits(tp) > -1);
+      if (tp != get_glob_type()) {
+        int n_mem = get_class_n_members(tp);
+        for (i = 0; i < n_mem; i++) {
+          if (get_entity_offset_bits(get_class_member(tp, i)) <= -1)
+            { DDMT(tp); DDME(get_class_member(tp, i)); }
+          assert(get_entity_offset_bits(get_class_member(tp, i)) > -1);
+              /* TR ??
+          assert(is_Method_type(get_entity_type(get_class_member(tp, i))) ||
+             (get_entity_allocation(get_class_member(tp, i)) == allocation_automatic));
+                     */
+        }
       }
-    }
-      } break;
+      break;
     case tpo_struct:
-      {
-        assert(get_type_size_bits(tp) > -1);
-        for (i = 0; i < get_struct_n_members(tp); i++) {
-          assert(get_entity_offset_bits(get_struct_member(tp, i)) > -1);
-          assert((get_entity_allocation(get_struct_member(tp, i)) == allocation_automatic));
-        }
-      } break;
+      assert(get_type_size_bits(tp) > -1);
+      for (i = 0; i < get_struct_n_members(tp); i++) {
+        assert(get_entity_offset_bits(get_struct_member(tp, i)) > -1);
+        assert((get_entity_allocation(get_struct_member(tp, i)) == allocation_automatic));
+      }
+      break;
     case tpo_union:
-      /* ?? */
-      break;
+      /* ?? */
+      break;
     case tpo_array:
-      /* ??
+      /* ??
          Check order?
          Assure that only innermost dimension is dynamic? */
-      break;
+      break;
     case tpo_enumeration:
-      {
-        assert(get_type_mode != NULL);
-        for (i = 0; i < get_enumeration_n_enums(tp); i++)
-          assert(get_enumeration_enum(tp, i) != NULL);
-      } break;
+      assert(get_type_mode != NULL);
+      for (i = get_enumeration_n_enums(tp) - 1; i >= 0; --i) {
+        ir_enum_const *ec = get_enumeration_const(tp, i);
+        tarval        *tv = get_enumeration_value(ec);
+        assert(tv != NULL && tv != tarval_bad);
+      }
+      break;
     default: break;
     } /* switch (tp) */
   }
   if (state == layout_fixed)
     tp->flags |= tf_layout_fixed;
   else
-    tp->flags &= tf_layout_fixed;
+    tp->flags &= ~tf_layout_fixed;
 }
 
 unsigned long (get_type_visited)(const ir_type *tp) {
@@ -770,7 +770,8 @@ ir_type *new_d_type_class (ident *name, dbg_info *db) {
   res->attr.ca.supertypes  = NEW_ARR_F (ir_type *, 0);
   res->attr.ca.peculiarity = peculiarity_existent;
   res->attr.ca.type_info   = NULL;
-  res->attr.ca.final       = 0;
+  res->attr.ca.vtable_size = 0;
+  res->attr.ca.clss_flags  = cf_none;
   res->attr.ca.dfn         = 0;
   hook_new_type(res);
   return res;
@@ -954,7 +955,7 @@ void set_class_type_info(ir_type *clss, entity *ent) {
   clss->attr.ca.type_info = ent;
 }
 
-const char *get_peculiarity_string(peculiarity p) {
+const char *get_peculiarity_name(ir_peculiarity p) {
 #define X(a)    case a: return #a
   switch (p) {
     X(peculiarity_description);
@@ -965,23 +966,55 @@ const char *get_peculiarity_string(peculiarity p) {
   return "invalid peculiarity";
 }
 
-peculiarity get_class_peculiarity (const ir_type *clss) {
+ir_peculiarity get_class_peculiarity (const ir_type *clss) {
   assert(clss && (clss->type_op == type_class));
   return clss->attr.ca.peculiarity;
 }
 
-void        set_class_peculiarity (ir_type *clss, peculiarity pec) {
+void        set_class_peculiarity (ir_type *clss, ir_peculiarity pec) {
   assert(clss && (clss->type_op == type_class));
   assert(pec != peculiarity_inherited);  /* There is no inheritance of types in libFirm. */
   clss->attr.ca.peculiarity = pec;
 }
 
+/* Returns the size of the virtual function table. */
+unsigned (get_class_vtable_size)(const ir_type *clss) {
+  return _get_class_vtable_size(clss);
+}
+
+/* Sets a new size of the virtual function table. */
+void (set_class_vtable_size)(ir_type *clss, unsigned size) {
+  _set_class_vtable_size(clss, size);
+}
+
+/* Returns non-zero if a class is final. */
 int (is_class_final)(const ir_type *clss) {
   return _is_class_final(clss);
 }
 
-void (set_class_final)(ir_type *clss, int final) {
-  _set_class_final(clss, final);
+/* Sets if a class is final. */
+void (set_class_final)(ir_type *clss, int flag) {
+  _set_class_final(clss, flag);
+}
+
+/* Returns non-zero if a class is an interface. */
+int (is_class_interface)(const ir_type *clss) {
+  return _is_class_interface(clss);
+}
+
+/* Sets the class interface flag. */
+void (set_class_interface)(ir_type *clss, int flag) {
+  _set_class_interface(clss, flag);
+}
+
+/* Returns non-zero if a class is abstract. */
+int (is_class_abstract)(const ir_type *clss) {
+  return _is_class_abstract(clss);
+}
+
+/* Sets the class abstract flag. */
+void (set_class_abstract)(ir_type *clss, int final) {
+  _set_class_abstract(clss, final);
 }
 
 void set_class_dfn (ir_type *clss, int dfn) {
@@ -1120,13 +1153,20 @@ static INLINE ir_type *
 build_value_type(ident *name, int len, tp_ent_pair *tps) {
   int i;
   ir_type *res = new_type_struct(name);
+  res->flags |= tf_value_param_type;
   /* Remove type from type list.  Must be treated differently than other types. */
   remove_irp_type(res);
   for (i = 0; i < len; i++) {
+    ident *id = tps[i].param_name;
+
     /* use res as default if corresponding type is not yet set. */
     ir_type *elt_type = tps[i].tp ? tps[i].tp : res;
 
-    tps[i].ent = new_entity(res, mangle_u(name, get_type_ident(elt_type)), elt_type);
+    /* use the parameter name if specified */
+    if (! id)
+      id = mangle_u(name, get_type_ident(elt_type));
+    tps[i].ent = new_entity(res, id, elt_type);
+    set_entity_allocation(tps[i].ent, allocation_parameter);
   }
   return res;
 }
@@ -1141,7 +1181,7 @@ ir_type *new_d_type_method(ident *name, int n_param, int n_res, dbg_info *db) {
   res->flags                       |= tf_layout_fixed;
   res->size                         = get_mode_size_bits(mode_P_code);
   res->attr.ma.n_params             = n_param;
-  res->attr.ma.param_type           = xcalloc(n_param, sizeof(res->attr.ma.param_type[0]));
+  res->attr.ma.params               = xcalloc(n_param, sizeof(res->attr.ma.params[0]));
   res->attr.ma.value_params         = NULL;
   res->attr.ma.n_res                = n_res;
   res->attr.ma.res_type             = xcalloc(n_res, sizeof(res->attr.ma.res_type[0]));
@@ -1165,7 +1205,7 @@ void free_method_entities(ir_type *method) {
 /* Attention: also frees entities in value parameter subtypes! */
 void free_method_attrs(ir_type *method) {
   assert(method && (method->type_op == type_method));
-  free(method->attr.ma.param_type);
+  free(method->attr.ma.params);
   free(method->attr.ma.res_type);
   if (method->attr.ma.value_params) {
     free_type_entities(method->attr.ma.value_params);
@@ -1182,19 +1222,20 @@ int (get_method_n_params)(const ir_type *method) {
   return _get_method_n_params(method);
 }
 
+/* Returns the type of the parameter at position pos of a method. */
 ir_type *get_method_param_type(ir_type *method, int pos) {
   ir_type *res;
   assert(method && (method->type_op == type_method));
   assert(pos >= 0 && pos < get_method_n_params(method));
-  res = method->attr.ma.param_type[pos].tp;
+  res = method->attr.ma.params[pos].tp;
   assert(res != NULL && "empty method param type");
-  return method->attr.ma.param_type[pos].tp = skip_tid(res);
+  return method->attr.ma.params[pos].tp = skip_tid(res);
 }
 
 void  set_method_param_type(ir_type *method, int pos, ir_type *tp) {
   assert(method && (method->type_op == type_method));
   assert(pos >= 0 && pos < get_method_n_params(method));
-  method->attr.ma.param_type[pos].tp = tp;
+  method->attr.ma.params[pos].tp = tp;
   /* If information constructed set pass-by-value representation. */
   if (method->attr.ma.value_params) {
     assert(get_method_n_params(method) == get_struct_n_members(method->attr.ma.value_params));
@@ -1202,6 +1243,28 @@ void  set_method_param_type(ir_type *method, int pos, ir_type *tp) {
   }
 }
 
+/* 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) {
+  assert(method && (method->type_op == type_method));
+  assert(pos >= 0 && pos < get_method_n_params(method));
+  return method->attr.ma.params[pos].param_name;
+}
+
+/* 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) {
+  ident *id = get_method_param_ident(method, pos);
+  return id ? get_id_str(id) : NULL;
+}
+
+/* Sets an ident representing the parameters name. For debug support only. */
+void set_method_param_ident(ir_type *method, int pos, ident *id) {
+  assert(method && (method->type_op == type_method));
+  assert(pos >= 0 && pos < get_method_n_params(method));
+  method->attr.ma.params[pos].param_name = id;
+}
+
 /* Returns an entity that represents the copied value argument.  Only necessary
    for compounds passed by value. */
 entity *get_method_value_param_ent(ir_type *method, int pos) {
@@ -1212,15 +1275,15 @@ entity *get_method_value_param_ent(ir_type *method, int pos) {
     /* parameter value type not created yet, build */
     method->attr.ma.value_params
       = build_value_type(mangle_u(get_type_ident(method), value_params_suffix),
-             get_method_n_params(method), method->attr.ma.param_type);
+             get_method_n_params(method), method->attr.ma.params);
   }
   /*
    * build_value_type() sets the method->attr.ma.value_params type as default if
    * no type is set!
    */
-  assert((get_entity_type(method->attr.ma.param_type[pos].ent) != method->attr.ma.value_params)
+  assert((get_entity_type(method->attr.ma.params[pos].ent) != method->attr.ma.value_params)
      && "param type not yet set");
-  return method->attr.ma.param_type[pos].ent;
+  return method->attr.ma.params[pos].ent;
 }
 
 /*
@@ -1663,11 +1726,11 @@ void set_array_size_bits(ir_type *tp, int size) {
 
 /* create a new type enumeration -- set the enumerators independently */
 ir_type *new_d_type_enumeration(ident *name, int n_enums, dbg_info *db) {
-  ir_type *res = new_type(type_enumeration, NULL, name, db);
+  ir_type *res;
 
-  res->attr.ea.n_enums     = n_enums;
-  res->attr.ea.enumer      = xcalloc(n_enums, sizeof(res->attr.ea.enumer[0]));
-  res->attr.ea.enum_nameid = xcalloc(n_enums, sizeof(res->attr.ea.enum_nameid[0]));
+  assert(n_enums >= 0);
+  res = new_type(type_enumeration, NULL, name, db);
+  res->attr.ea.enumer = NEW_ARR_F(ir_enum_const, n_enums);
   hook_new_type(res);
   return res;
 }
@@ -1681,39 +1744,46 @@ void free_enumeration_entities(ir_type *enumeration) {
 }
 void free_enumeration_attrs(ir_type *enumeration) {
   assert(enumeration && (enumeration->type_op == type_enumeration));
-  free(enumeration->attr.ea.enumer);
-  free(enumeration->attr.ea.enum_nameid);
+  DEL_ARR_F(enumeration->attr.ea.enumer);
 }
 
 /* manipulate fields of enumeration type. */
-int     get_enumeration_n_enums (const ir_type *enumeration) {
+int     get_enumeration_n_enums(const ir_type *enumeration) {
   assert(enumeration && (enumeration->type_op == type_enumeration));
-  return enumeration->attr.ea.n_enums;
+  return ARR_LEN(enumeration->attr.ea.enumer);
 }
-void    set_enumeration_enum    (ir_type *enumeration, int pos, tarval *con) {
-  assert(enumeration && (enumeration->type_op == type_enumeration));
-  assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration));
-  enumeration->attr.ea.enumer[pos] = con;
+
+/* create a new constant */
+void set_enumeration_const(ir_type *enumeration, int pos, ident *nameid, tarval *con) {
+  assert(0 <= pos && pos < ARR_LEN(enumeration->attr.ea.enumer));
+  enumeration->attr.ea.enumer[pos].nameid = nameid;
+  enumeration->attr.ea.enumer[pos].value  = con;
+  enumeration->attr.ea.enumer[pos].owner  = enumeration;
 }
-tarval *get_enumeration_enum    (const ir_type *enumeration, int pos) {
+
+ir_enum_const *get_enumeration_const(const ir_type *enumeration, int pos) {
   assert(enumeration && (enumeration->type_op == type_enumeration));
   assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration));
-  return enumeration->attr.ea.enumer[pos];
+  return &enumeration->attr.ea.enumer[pos];
 }
-void    set_enumeration_nameid  (ir_type *enumeration, int pos, ident *id) {
-  assert(enumeration && (enumeration->type_op == type_enumeration));
-  assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration));
-  enumeration->attr.ea.enum_nameid[pos] = id;
+
+ir_type *get_enumeration_owner(const ir_enum_const *enum_cnst) {
+  return enum_cnst->owner;
 }
-ident  *get_enumeration_nameid  (const ir_type *enumeration, int pos) {
-  assert(enumeration && (enumeration->type_op == type_enumeration));
-  assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration));
-  return enumeration->attr.ea.enum_nameid[pos];
+void    set_enumeration_value(ir_enum_const *enum_cnst, tarval *con) {
+  enum_cnst->value = con;
 }
-const char *get_enumeration_name(const ir_type *enumeration, int pos) {
-  assert(enumeration && (enumeration->type_op == type_enumeration));
-  assert(pos >= 0 && pos < get_enumeration_n_enums(enumeration));
-  return get_id_str(enumeration->attr.ea.enum_nameid[pos]);
+tarval *get_enumeration_value(const ir_enum_const *enum_cnst) {
+  return enum_cnst->value;
+}
+void    set_enumeration_nameid(ir_enum_const *enum_cnst, ident *id) {
+  enum_cnst->nameid = id;
+}
+ident  *get_enumeration_nameid(const ir_enum_const *enum_cnst) {
+  return enum_cnst->nameid;
+}
+const char *get_enumeration_name(const ir_enum_const *enum_cnst) {
+  return get_id_str(enum_cnst->nameid);
 }
 
 /* typecheck */
@@ -1893,12 +1963,17 @@ int is_compound_type(const ir_type *tp) {
   return tp->type_op->flags & TP_OP_FLAG_COMPOUND;
 }
 
-/* Checks, whether a type is a frame ir_type */
+/* Checks, whether a type is a frame type */
 int is_frame_type(const ir_type *tp) {
   return tp->flags & tf_frame_type;
 }
 
-/* Checks, whether a type is a lowered ir_type */
+/* Checks, whether a type is a value parameter type */
+int is_value_param_type(const ir_type *tp) {
+  return tp->flags & tf_value_param_type;
+}
+
+/* Checks, whether a type is a lowered type */
 int is_lowered_type(const ir_type *tp) {
   return tp->flags & tf_lowered_type;
 }
@@ -1942,7 +2017,7 @@ void set_default_size_bits(ir_type *tp, int size) {
  * at the start or the end of a frame type.
  * The frame type must have already an fixed layout.
  */
-entity *frame_alloc_area(type *frame_type, int size, int alignment, int at_start)
+entity *frame_alloc_area(ir_type *frame_type, int size, int alignment, int at_start)
 {
   entity *area;
   ir_type *tp;
@@ -1991,5 +2066,7 @@ entity *frame_alloc_area(type *frame_type, int size, int alignment, int at_start
   set_entity_offset_bytes(area, offset);
   set_type_size_bytes(frame_type, frame_size);
 
+  /* mark this entity as compiler generated */
+  set_entity_compiler_generated(area, 1);
   return area;
 }