This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: objc data structures
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