objc data structures

Ziemowit Laski zlaski@apple.com
Fri Oct 8 07:34:00 GMT 2004


On 7 Oct 2004, at 12.39, Geoffrey Keating wrote:

>
> On 07/10/2004, at 12:03 PM, Ziemowit Laski wrote:
>
>>>>>>> - Is it ever necessary to have this information as well as the 
>>>>>>> information that C or C++ stores in the lang_specific field?
>>>>>>
>>>>>> No idea.
>>>>>
>>>>> Could you please find out?  This information is essential to the 
>>>>> design.
>>>>
>>>> How do you suggest I do that?  You're asking me to establish 
>>>> constraints on the use of a local data structure by other 
>>>> front-ends.
>>>
>>> Is it necessary in the current compilers, to which you have source?
>>
>> Even if the "current compilers" were set in stone, I still fail to 
>> see how you'd compute this predicate.
>>
>>> More generally, given what the current compilers have in the 
>>> lang_type structures, is it necessary to have both that data and the 
>>> data that objc needs?
>>>
>>> Or, to phrase it another way, could we just decide that lang_type 
>>> can be a union that can point to either the data that objc needs or 
>>> the data that the C or C++ frontend needs?
>>
>> You're asking me
>>   (1) the exact conditions under which C or C++ might decide to store 
>> lang_specific information in a type node; and
>>   (2) the exact conditions under which ObjC/ObjC++ needs to store 
>> lang_specific information (for now, protocols) in a type node; and
>>   (3) whether (1) and (2) are guaranteed to be mutually exclusive.
>>
>> The only one of these I could even _begin_ to answer is (2).
>
> *sigh*.
>
> You do it very simply.  You look at the actual source code of the C 
> and C++ frontends, and determine (1).  Then, you look at the actual 
> source code of the objc/objc++ frontend and determine (2).  Then, you 
> determine what the overlap is.
>
> I will give you an worked example, from the C frontend.  Looking at 
> the C frontend, we see that 'struct lang_type' looks like:
>
> struct lang_type GTY(())
> {
>   /* In a RECORD_TYPE, a sorted array of the fields of the type.  */
>   struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) 
> s;
>   /* In an ENUMERAL_TYPE, the min and max values.  */
>   tree enum_min;
>   tree enum_max;
> };
>
> Now, from the information you gave earlier, we are concerned with 
> record types.  The 'struct lang_type' has a field that looks like it's 
> used for record types.  Searching for TYPE_LANG_SPECIFIC indicates 
> that it's used in 'lookup_field' in c-typeck.c, and maybe other 
> places.  So, it seems like the answer for the C part of (1) is "any 
> record type".

"Looks like it's used?" :-)  "Maybe other places?" :-)  Clearly you and 
I have very different notions of what "determining" something means.  
Thankfully, the issue is moot here; Since ObjC protocols attach to 
RECORD_TYPEs (and also POINTER_TYPEs), we must hang on to the 's' field 
even in the ObjC case.

However, it does appear from perusal of the sources that enum_min and 
enum_max are used strictly for ENUMERAL_TYPEs, as advertised.  So we 
could overlay the ObjC protocol list (with one word to spare) on top of 
that.

> Now, following my example, please answer (1) for C++, and (2) for ObjC 
> and ObjC++.  If you get stuck, let me know.

In C++, we have

struct lang_type GTY(())
{
   union lang_type_u
   {
     struct lang_type_header GTY((skip (""))) h;
     struct lang_type_class  GTY((tag ("1"))) c;
     struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
   } GTY((desc ("%h.h.is_lang_type_class"))) u;
};

Since we're concerned with RECORD_TYPEs, we drop down to 
lang_type_class.  (ObjC protocols can also be attached to 
POINTER_TYPEs; however, I believe that either (a) allocate a 
lang_type_class for those ObjC pointers that have protocols or (b) 
tweak ObjC itself so that the protocols are attached to the 
RECORD_TYPEs that the POINTER_TYPEs point to instead.)

struct lang_type_class GTY(())
{
   struct lang_type_header h;

   unsigned char align;

   unsigned has_mutable : 1;
   unsigned com_interface : 1;
   unsigned non_pod_class : 1;
   unsigned nearly_empty_p : 1;
   unsigned user_align : 1;
   unsigned has_assign_ref : 1;
   unsigned has_new : 1;
   unsigned has_array_new : 1;

   unsigned gets_delete : 2;
   unsigned interface_only : 1;
   unsigned interface_unknown : 1;
   unsigned contains_empty_class_p : 1;
   unsigned anon_aggr : 1;
   unsigned non_zero_init : 1;
   unsigned empty_p : 1;

   unsigned vec_new_uses_cookie : 1;
   unsigned declared_class : 1;
   unsigned diamond_shaped : 1;
   unsigned repeated_base : 1;
   unsigned being_defined : 1;
   unsigned redefined : 1;
   unsigned debug_requested : 1;
   unsigned fields_readonly : 1;

   unsigned use_template : 2;
   unsigned ptrmemfunc_flag : 1;
   unsigned was_anonymous : 1;
   unsigned lazy_default_ctor : 1;
   unsigned lazy_copy_ctor : 1;
   unsigned lazy_assignment_op : 1;
   unsigned has_const_init_ref : 1;

   unsigned has_complex_init_ref : 1;
   unsigned has_complex_assign_ref : 1;
   unsigned non_aggregate : 1;
   unsigned java_interface : 1;

   /* When adding a flag here, consider whether or not it ought to
      apply to a template instance if it applies to the template.  If
      so, make sure to copy it in instantiate_class_template!  */

   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
   unsigned dummy : 12;

   tree primary_base;
   VEC (tree_pair_s) *vcall_indices;
   tree vtables;
   tree typeinfo_var;
   VEC (tree) *vbases;
   binding_table nested_udts;
   tree as_base;
   VEC (tree) *pure_virtuals;
   tree friend_classes;
   VEC (tree) * GTY((reorder ("resort_type_method_vec"))) methods;
   tree key_method;
   tree decl_list;
   tree template_info;
   tree befriending_classes;
};

Here, the two fields which jump out at me as probably not needing to be 
used for ObjC classes are 'pure_virtuals' and 'template_info', so we 
could overlay our protocol info there.  In this case, we would also 
need to steal 1 bit to mark ObjC-ness.  And, of course, we would need 
to cross our fingers that the C++ front-end will never touch 
'pure_virtuals' and 'template_info' for classes without pure virtuals 
or template parameters.

Good software engineering this ain't, though perhaps you had something 
else in mind...

--Zem

--------------------------------------------------------------
Ziemowit Laski                 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group        Cupertino, CA USA  95014-2083
Apple Computer, Inc.           +1.408.974.6229  Fax .5477



More information about the Gcc mailing list