ObjC/ObjC++ revamp of @encoding patch

Nicola Pero nicola.pero@meta-innovation.com
Mon Sep 27 08:30:00 GMT 2010


This patch does a revamp of ObjC type encoding:

 * it merges changes from the apple/trunk branch on the FSF servers.  Unfortunately,
what Apple seems to have done on that branch is to introduce kludges to emulate the
buggy encoding strings emitted by GCC-3.3 (for ABI compatibility).  As the FSF has 
already shipped 4 or 5 versions of the compiler which emit correct encoding strings,
it seemed pointless to go back!  So, I imported Apple changes, but only activated them
for the NeXT runtime.  People compiling for the NeXT runtime will want them to be 
compatible with the Apple compilers/runtime, but everyone else just gets the current,
fixed version.

 * it adds lots of documentation on ObjC type encoding, both to doc/objc.texi 
and to objc/objc-act.c.

 * it fixes PR objc/45763, where a "BOOL *" was encoded as "*" instead of "^c" (GNU runtime
only, it was already working for the NeXT one)

 * it fixes PR objc/25450, where enums were always encoded as 'i' no matter what the
actual integer used for the enum.  I kept the NeXT runtime using a hardcoded 'i' 
to preserve compatibility when outputting code for the NeXT runtime, but I fixed the
GNU runtime to emit encodings that reflect the actual integer type.

 * it fixes PR objc/25464, where an incomplete array inside a struct was being encoded
as a pointer.  I had lots of thoughts about this, but in the end the right thing to do
was to encode them as zero-length arrays if inside a struct.  I implemented that, and
got the failing testcase to succeed. :-)

 * as a sideline to PR objc/25464, I added the missing check that instance variables 
of unknown size are not created by using a struct containing incomplete arrays.  I
added a testcase for this.

 * it partially fixes PR objc/25361, where vectors were not encoded.  I did fully
implement encoding vectors.  I used the _C_VECTOR ('!') code which had already been
allocated for vectors (and the NeXT runtime seems to include that #define as well), and pondered
a lot on how to implement it in a portable way.  libobjc/encoding.c is already full of
target hacks and I didn't want to add yet another layer for vectors.  So I decided to
have the compiler itself write the sizeof and alignof the vector inside the encode
string directly :-).  That means the runtime always knows the correct sizeof and alignof
of that vector on the platform, because the compiler has put it in there! ;-) For example,
on my machine the encoding for 'int __attribute__ ((vector_size (16)))' is ![16,16i].
The first 16 is the sizeof the type, the second 16 is the alignof the type, and 'i' is
the base type (int) (the brackets are there because a vector is a bit of a simple array).
This works great but still doesn't fix completely PR objc/25361, which actually requires 
the runtime being able to consistently determine the sizeof and alignof not only of vectors, 
but of structures containing vectors as well.  Fixing that isn't trivial at all as it does
require non-obvious knowledge of the target machine - even more hacks
in libobjc/encoding.c.  An idea I now have is, instead, to change the encoding to always
include the sizeof and alignof for all non-basic types.  Then no hacks are required by
the runtime to determine sizeof and alignof of types, as the compiler will have put 
that information in there when compiling!  I'm not sure how meaningful that is, but it
is an idea.  Of course, we can't change the encoding that dramatically unless we change 
the ABI, but we'll have to change the ABI to implement Objective-C 2.0.  So, when we get 
to implement a new ABI for Objective-C 2.0, we should consider changing the encodings 
as part of the ABI change to get encodings that work on all platforms without libobjc
having to include any tm.h and such like.  This is just an idea though.  I still have
to think about whether we need all that encoding.c stuff at all.  Anyway, vector encoding is
implemented and it does work for vectors that are not inside structs, which is much better
than before were vectors could simply never be used :-)

 * it changes the internal libobjc type qualifier used for _C_GCINVISIBLE which was '!', the same
as _C_VECTOR (a blatant conflict that never got noticed as _C_VECTOR was never used since vector
encoding had never been implemented).  I decided to change _C_GCINVISIBLE rather than _C_VECTOR 
because _C_GCINVISIBLE is currently private to libobjc, while _C_VECTOR isn't (and the Apple runtime 
seems to have a _C_VECTOR definition consistent with ours, so why change it).

 * it adds support for long doubles (D).  The idea was originally in a forgotten patch
by Alexander Malmberg where he got libobjc to use libffi for forwarding.  Anyway,
Apple seems to be using D for long doubles too, so I went on and added it in the same way
as everyone seems to be doing it (or wanting to do it).

 * it encodes 128-bit integers as T/t, and C++ references in the same way as pointers.  Again,
these are compatible with Apple.

 * it emits a warning when it's asked to encode an unrecognized type, and encodes it as '?'
(as per specs).  Before, it was silently failing to encode it. ;-)

No regressions, new testcases that succeed (and would previously fail) and 1 "unexpected success". :-)

Ok to apply to trunk ?

Thanks

PS: Apologies for bundling so many changes in a single patch.  I like small patches, but it would
have taken ages to get them all approved and committed one by one.  If there's anything specifically
dubious, I can take it out of the patch before committing. ;-)

++ gcc/objc/ChangeLog:

2010-09-25  Nicola Pero  <nicola.pero@meta-innovation.com>

        PR objc/45763
        PR objc/25450
        PR objc/25464
        * objc-act.c: Improved comments for encoding functions.
        (encode_aggregate_within): For the GNU runtime, rewritten some
        obsfuscated code to clarify the various cases.
        (encode_aggregate): Function removed.
        (encode_array): Generate an error if asked to encode an incomplete
        array as part of generating instance variables.  Else, when
        encoding an incomplete array inside a structure, encode it as an
        array of zero size.
        (encode_pointer): For the GNU runtime, fixed encoding 'BOOL *' as
        '^c' instead of '*'.
        (encode_gnu_bitfield): Encode enumerated types exactly in the same
        type as integer types instead of using a hardcoded 'i'.  If asked
        to encode a non-integer type as a bitfield, do not abort
        compilation immediately; instead generate an error, then skip the
        type.
        (encode_type): Use a 'switch' instead of a sequence of 'if's.
        Added a 'default' clause that gets executed if the type can not be
        matched, and that encodes it as '?' (unknown) and produces a
        warning.  For the GNU runtime, encode enumerated types exactly in
        the same way as integer types instead of using a hardcoded 'i'.
        Encode long double as 'D'.  Encode 128-bit integers as 'T' or 't'.
        Encode C++ reference types as pointers.  Call encode_vector to
        encode vectors.
        (encode_vector): New function.

2010-09-25  Nicola Pero  <nicola.pero@meta-innovation.com>

        Merge from 'apple/trunk' branch on FSF servers.  I modified the
        changes to be used only when compiling for the NeXT runtime.

        2005-10-10  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4301047

        * objc-act.c (encode_type): Remove the hack.

        2005-07-20  Ziemowit Laski  <zlaski@apple.com>

        Radar 4136935
        * objc-act.c (pointee_is_readonly): New function.
        (encode_pointer, encode_aggregate_within, encode_type):
        Attempt to emulate GCC 3.3 when generating type encodings.

++ gcc/testsuite/ChangeLog:

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        PR objc/25464
        * objc.dg/type-size-3.m: New test.

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        PR objc/45763
        * objc.dg/encode-1.m: Execute the test with the GNU runtime as
        well.

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        PR objc/25450
        * objc.dg/encode-3.m: Updated for fix of encoding of enums.
        * objc.dg/type-size-2.m: Same change.
        * obj-c++.dg/encode-5.mm: Same change.

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        Merge from 'apple/trunk' branch on FSF servers.  The original
        Changelogs are below.

        * objc.dg/encode-6.m: Execute the test only with the GNU runtime.
        * objc.dg/encode-6-next.m: New file (from encode-6.m in the
        branch).
        * objc.dg/encode-7-next.m: New file (from encode-7.m in the
        branch).
        * objc.dg/encode-7-next-64bit.m: New file (from encode-7-64bit.m
        in the branch).
        * objc.dg/proto-qual-1.m: Test the 3.3 ABI on NeXT (from
        proto-qual-1.m in the branch) and the normal ABI on GNU.
        * objc.dg/threedotthree-abi-1.m: New file (from the branch).  Run
        the test only with the NeXT runtime.
        * obj-c++/encode-1.mm: Execute the test only with the GNU runtime.
        * obj-c++/encode-1-next.mm: New file (from encode-1.mm in the
        branch).
        * obj-c++.dg/threedotthree-abi-1.mm: New file (from the branch).
        Run the test only with the NeXT runtime.

        2006-03-30 Fariborz Jahanian <fjahanian@apple.com>

        Radar 4492973
        * objc.dg/encode-7-64bit.m: New.
        * objc.dg/encode-7.m: Skip if -m64.

        2005-10-19  Fariborz Jahanian <fjahanian@apple.com>

        Radar 4301047
        * objc.dg/proto-qual-1.m: Fix test to match 3.3 ABI
        * obj-c++.dg/threedotthree-abi-1.mm: New
        * objc.dg/threedotthree-abi-1.m: New

        2005-07-20  Ziemowit Laski  <zlaski@apple.com>

        Radar 4136935
        * obj-c++.dg/encode-1.mm: Tweak encodings to match fix.
        * objc.dg/encode-6.m: Likewise.
        * objc.dg/encode-7.m: New test case.

++ gcc/ChangeLog:

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        * doc/objc.texi (Type encoding): Added the new 'long double' (D)
        code.  Added byref, which was missing in the list of codes.
        Explain that enumeration values are encoded as the integer type
        that the compiler uses to store them.  Explain and make examples
        of how 'const' interacts with pointers, and the complication of
        the encoding of 'const char *'.
        (Legacy type encoding): New subsection, explaining that GCC emits
        incorrect type encodings for the NeXT runtime for compatibility
        reasons.
        (@@encode): New subsection, explaining @encode and particularly
        that protocol qualifiers are not recognized inside an @encode()
        expression.
        (Method signatures): New subsection, explaining how method
        signatures are encoded.

++ libobjc/ChangeLog:

2010-09-26  Nicola Pero  <nicola.pero@meta-innovation.com>

        * encoding.c (objc_sizeof_type): Added support for vector type and
        for double long types.
        (objc_alignof_type): Same change.
        (objc_skip_typespec): Same change.
        * objc/encoding.h (_C_GCINVISIBLE): Use '|' for _C_GCINVISIBLE
        instead of '!' since '!' is already used for _C_VECTOR.
        * objc/objc-api.h (_C_LNG_DBL): Added.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch
Type: application/octet-stream
Size: 78353 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100927/97d3999c/attachment.obj>


More information about the Gcc-patches mailing list