added visibility flag for types.
authorGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Wed, 15 Jun 2005 07:50:36 +0000 (07:50 +0000)
committerGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Wed, 15 Jun 2005 07:50:36 +0000 (07:50 +0000)
[r6008]

ir/tr/entity.c
ir/tr/entity.h
ir/tr/entity_t.h
ir/tr/type.c
ir/tr/type.h
ir/tr/type_t.h

index c391793..c791c24 100644 (file)
@@ -348,13 +348,13 @@ const char *get_allocation_name(ent_allocation all)
 }
 
 
-ent_visibility
+visibility
 (get_entity_visibility)(const entity *ent) {
   return _get_entity_visibility(ent);
 }
 
 void
-set_entity_visibility (entity *ent, ent_visibility vis) {
+set_entity_visibility (entity *ent, visibility vis) {
   assert(ent && ent->kind == k_entity);
   if (vis != visibility_local)
     assert((ent->allocation == allocation_static) ||
@@ -365,7 +365,7 @@ set_entity_visibility (entity *ent, ent_visibility vis) {
 }
 
 /* return the name of the visibility */
-const char *get_visibility_name(ent_visibility vis)
+const char *get_visibility_name(visibility vis)
 {
 #define X(a)    case a: return #a
   switch (vis) {
index e42a11d..227269d 100644 (file)
@@ -154,6 +154,11 @@ entity     *new_d_entity (type *owner, ident *name, type *tp, dbg_info *db);
  *
  * Automatically inserts the new entity as a member of owner.
  * Resets the overwrites/overwritten_by fields.
+ * Keeps the old atomic value.
+ *   @@@ Maybe we should change this.  If peculiarity of a method
+ *       is existent, we should add a new SymConst that points to
+ *       itself and not to the origin.  Right now we have to change
+ *       the peculiarity and then set a new atomic value by hand.
  */
 entity     *copy_entity_own (entity *old, type *new_owner);
 
@@ -163,6 +168,7 @@ entity     *copy_entity_own (entity *old, type *new_owner);
  *
  * Automatically inserts the new entity as a member of owner.
  * The mangled name ld_name is set to NULL.
+ * Overwrites relation is copied from old.
  */
 entity     *copy_entity_name (entity *old, ident *new_name);
 
@@ -233,6 +239,7 @@ void           set_entity_allocation (entity *ent, ent_allocation al);
 /** Return the name of the allocation type. */
 const char *get_allocation_name(ent_allocation vis);
 
+#if 0   // moved to type.h
 /**
  * This enumeration flags the visibility of entities.  This is necessary
  * for partial compilation.
@@ -246,16 +253,17 @@ typedef enum {
                           must not allocate memory for this entity. The entity must
                               be static_allocated.  This can also be an external defined
                           method. */
-} ent_visibility;
+} visibility;
+#endif
 
 /** Returns the visibility of an entity. */
-ent_visibility get_entity_visibility (const entity *ent);
+visibility get_entity_visibility (const entity *ent);
 
 /** Sets the visibility of an entity. */
-void           set_entity_visibility (entity *ent, ent_visibility vis);
+void       set_entity_visibility (entity *ent, visibility vis);
 
 /** Return the name of the visibility */
-const char *get_visibility_name(ent_visibility vis);
+const char *get_visibility_name(visibility vis);
 
 /** This enumeration flags the variability of entities. */
 typedef enum {
index c407ff6..181950b 100644 (file)
@@ -73,7 +73,7 @@ struct entity {
   type *owner;          /**< The compound type (e.g. class type) this entity belongs to. */
   ent_allocation allocation;  /**< Distinguishes static and dynamically allocated
                  entities and some further cases. */
-  ent_visibility visibility;  /**< Specifies visibility to external program
+  visibility visibility;  /**< Specifies visibility to external program
                  fragments */
   ent_variability variability;  /**< Specifies variability of entities content */
   ent_volatility volatility;    /**< Specifies volatility of entities content */
@@ -189,7 +189,7 @@ _set_entity_allocation(entity *ent, ent_allocation al) {
   ent->allocation = al;
 }
 
-static INLINE ent_visibility
+static INLINE visibility
 _get_entity_visibility(const entity *ent) {
   assert(ent && ent->kind == k_entity);
   return ent->visibility;
index 01c50ed..42511dd 100644 (file)
@@ -116,17 +116,18 @@ new_type(tp_op *type_op, ir_mode *mode, ident* name) {
   memset(res, 0, node_size);
   add_irp_type(res);   /* Remember the new type global. */
 
-  res->kind    = k_type;
-  res->type_op = type_op;
-  res->mode    = mode;
-  res->name    = name;
-  res->state   = layout_undefined;
-  res->size    = -1;
-  res->align   = -1;
-  res->visit   = 0;
-  res -> link  = NULL;
+  res->kind       = k_type;
+  res->type_op    = type_op;
+  res->mode       = mode;
+  res->name       = name;
+  res->visibility = visibility_external_allocated;
+  res->state      = layout_undefined;
+  res->size       = -1;
+  res->align      = -1;
+  res->visit      = 0;
+  res -> link     = NULL;
 #ifdef DEBUG_libfirm
-  res->nr      = get_irp_new_node_nr();
+  res->nr         = get_irp_new_node_nr();
 #endif /* defined DEBUG_libfirm */
 
   return res;
@@ -274,6 +275,57 @@ int (get_type_size_bits)(const type *tp) {
   return _get_type_size_bits(tp);
 }
 
+
+visibility get_type_visibility (const type *tp) {
+#if 0
+  visibility res =  visibility_local;
+  if (is_compound_type(tp)) {
+
+    if (is_Array_type(tp)) {
+      entity *mem = get_array_element_entity(tp);
+      if (get_entity_visibility(mem) != visibility_local)
+       res = visibility_external_visible;
+    } else {
+      int i, n_mems = get_compound_n_members(tp);
+      for (i = 0; i < n_mems; ++i) {
+       entity *mem = get_compound_member(tp, i);
+       if (get_entity_visibility(mem) != visibility_local)
+         res = visibility_external_visible;
+      }
+    }
+  }
+  return res;
+#endif
+  assert(is_type(tp));
+  return tp->visibility;
+}
+
+void       set_type_visibility (type *tp, visibility v) {
+  assert(is_type(tp));
+#if 0
+  /* check for correctness */
+  if (v != visibility_external_allocated) {
+    visibility res =  visibility_local;
+    if (is_compound_type(tp)) {
+      if (is_Array_type(tp)) {
+       entity *mem = get_array_element_entity(tp);
+       if (get_entity_visibility(mem) >  res)
+         res = get_entity_visibility(mem);
+      } else {
+       int i, n_mems = get_compound_n_members(tp);
+       for (i = 0; i < n_mems; ++i) {
+         entity *mem = get_compound_member(tp, i);
+         if (get_entity_visibility(mem) > res)
+           res = get_entity_visibility(mem);
+       }
+      }
+    }
+    assert(res < v);
+  }
+#endif
+  tp->visibility = v;
+}
+
 void
 set_type_size_bits(type *tp, int size) {
   assert(tp && tp->kind == k_type);
index 1be0a49..464944c 100644 (file)
@@ -149,6 +149,73 @@ ident*      get_type_ident(const type *tp);
 void        set_type_ident(type *tp, ident* id);
 const char* get_type_name(const type *tp);
 
+/** This enumeration flags the visibility of entities and types.
+ *
+ * This is necessary for partial compilation.
+ * We rely on the ordering of the flags.
+ */
+typedef enum {
+  visibility_local,              /**< The entity is only visible locally.  This is the default for
+                                     entities.
+                                     The type is only visible locally.  All instances are allocated
+                                     locally, and no pointer to entities of this type are passed
+                                     out of this compilation unit. */
+  visibility_external_visible,   /**< The entity is visible to other external program parts, but
+                                     it is defined here.  It may not be optimized away.  The entity must
+                                     be static_allocated.
+                                     For types:  entities of this type can be accessed externaly.  No
+                                     instances of this type are allocated externally.  */
+  visibility_external_allocated  /**< The entity is defined and allocated externally.  This compilation
+                                     must not allocate memory for this entity. The entity must
+                                     be static_allocated.  This can also be an external defined
+                                     method.
+                                     For types:  entities of this type are allocated and accessed from
+                                     external code.  Default for types.  */
+} visibility;
+
+/** The visibility of a type.
+ *
+ *  The visibility of a type indicates, whether entities of this type
+ *  are accessed or allocated in external code.
+ *
+ *  An entity of a type is allocated in external code, if the external
+ *  code declares a variable of this type, or dynamically allocates
+ *  an entity of this type.  If the external code declares a (compound)
+ *  type, that contains entities of this type, the visibility also
+ *  must be external_allocated.
+ *
+ *  The visibility must be higher than that of all entities, if the
+ *  type is a compound.  Here it is questionable, what happens with
+ *  static entities.  If these are accessed external by direct reference,
+ *  (a static call to a method, that is also in the dispatch table)
+ *  it should not affect the visibility of the type.
+ *
+ *
+ * @@@ Do we need a visibility for types?
+ * I change the layout of types radically when doing type splitting.
+ * I need to know, which fields of classes are accessed in the rts,
+ * e.g., [_length.  I may not move [_length to the split part.
+ * The layout though, is a property of the type.
+ *
+ * One could also think of changing the mode of a type ...
+ *
+ * But, we could also output macros to access the fields, e.g.,
+ *  ACCESS_[_length (X)   X->length              // conventional
+ *  ACCESS_[_length (X)   X->_split_ref->length  // with type splitting
+ *
+ * For now I implement this function, that returns the visibility
+ * based on the visibility of the entities of a compound ...
+ *
+ * This function returns visibility_external_visible if one or more
+ * entities of a compound type have visibility_external_visible.
+ * Entities of types are never visibility_external_allocated (right?).
+ * Else returns visibility_local.
+ */
+visibility get_type_visibility (const type *tp);
+void       set_type_visibility (type *tp, visibility v);
+
+
+
 /** The state of the type layout. */
 typedef enum {
   layout_undefined,    /**< The layout of this type is not defined.
index 3f8a1d9..489a24a 100644 (file)
@@ -115,11 +115,12 @@ struct 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 */
+  visibility visibility;   /**< Visibility of entities of this type. */
   type_state state;        /**< Represents the types state: layout undefined or
-                  fixed. */
+                             fixed. */
   int size;                /**< Size of an entity of this type. This is determined
-                  when fixing the layout of this class.  Size must be
-                  given in bits. */
+                             when fixing the layout of this class.  Size must be
+                             given in bits. */
   int align;               /**< Alignment of an 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().