Commit 177b48f9 by Nicola Pero Committed by Nicola Pero

In gcc/: 2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/:
2010-09-27  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.

In gcc/objc/:
2010-09-27  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-27  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.

In gcc/testsuite/:
2010-09-27  Nicola Pero  <nicola.pero@meta-innovation.com>

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

2010-09-27  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-27  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-27  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.

In libobjc/:
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.

From-SVN: r164659
parent 16562d86
2010-09-27 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.
2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
Merge from 'apple/trunk' branch on FSF servers. Removed small
change in build_conditional_expr that had been added when fixing
PR objc/27377 and which did the same check in a less complete way.
......@@ -170,9 +170,13 @@ above apply to classes defined in bundle.
@node Type encoding
@section Type encoding
The Objective-C compiler generates type encodings for all the
types. These type encodings are used at runtime to find out information
about selectors and methods and about objects and classes.
This is an advanced section. Type encodings are used extensively by
the compiler and by the runtime, but you generally do not need to know
about them to use Objective-C.
The Objective-C compiler generates type encodings for all the types.
These type encodings are used at runtime to find out information about
selectors and methods and about objects and classes.
The types are encoded in the following way:
......@@ -205,6 +209,8 @@ The types are encoded in the following way:
@tab @code{f}
@item @code{double}
@tab @code{d}
@item @code{long double}
@tab @code{D}
@item @code{void}
@tab @code{v}
@item @code{id}
......@@ -215,6 +221,9 @@ The types are encoded in the following way:
@tab @code{:}
@item @code{char*}
@tab @code{*}
@item @code{enum}
@tab an @code{enum} is encoded exactly as the integer type that the compiler uses for it, which depends on the enumeration
values. Often the compiler users @code{unsigned int}, which is then encoded as @code{I}.
@item unknown type
@tab @code{?}
@item Complex types
......@@ -225,15 +234,16 @@ The types are encoded in the following way:
@c @sp 1
The encoding of bit-fields has changed to allow bit-fields to be properly
handled by the runtime functions that compute sizes and alignments of
types that contain bit-fields. The previous encoding contained only the
size of the bit-field. Using only this information it is not possible to
reliably compute the size occupied by the bit-field. This is very
important in the presence of the Boehm's garbage collector because the
objects are allocated using the typed memory facility available in this
collector. The typed memory allocation requires information about where
the pointers are located inside the object.
The encoding of bit-fields has changed to allow bit-fields to be
properly handled by the runtime functions that compute sizes and
alignments of types that contain bit-fields. The previous encoding
contained only the size of the bit-field. Using only this information
it is not possible to reliably compute the size occupied by the
bit-field. This is very important in the presence of the Boehm's
garbage collector because the objects are allocated using the typed
memory facility available in this collector. The typed memory
allocation requires information about where the pointers are located
inside the object.
The position in the bit-field is the position, counting in bits, of the
bit closest to the beginning of the structure.
......@@ -251,6 +261,8 @@ The non-atomic types are encoded as follows:
@tab @samp{@{} followed by the name of the structure (or @samp{?} if the structure is unnamed), the @samp{=} sign, the type of the members and by @samp{@}}
@item unions
@tab @samp{(} followed by the name of the structure (or @samp{?} if the union is unnamed), the @samp{=} sign, the type of the members followed by @samp{)}
@item vectors
@tab @samp{![} followed by the vector_size (the number of bytes composing the vector) followed by a comma, followed by the alignment (in bytes) of the vector, followed by the type of the elements followed by @samp{]}
@end multitable
Here are some types and their encodings, as they are generated by the
......@@ -277,6 +289,11 @@ struct @{
@}
@end smallexample
@tab @code{@{?=i[3f]b128i3b131i2c@}}
@item
@smallexample
int a __attribute__ ((vector_size (16)));
@end smallexample
@tab @code{![16,16i]} (alignment would depend on the machine)
@end multitable
@sp 1
......@@ -300,6 +317,8 @@ Objective-C type specifiers:
@tab @code{o}
@item @code{bycopy}
@tab @code{O}
@item @code{byref}
@tab @code{R}
@item @code{oneway}
@tab @code{V}
@end multitable
......@@ -310,6 +329,145 @@ The type specifiers are encoded just before the type. Unlike types
however, the type specifiers are only encoded when they appear in method
argument types.
Note how @code{const} interacts with pointers:
@sp 1
@multitable @columnfractions .25 .75
@item Objective-C type
@tab Compiler encoding
@item
@smallexample
const int
@end smallexample
@tab @code{ri}
@item
@smallexample
const int*
@end smallexample
@tab @code{^ri}
@item
@smallexample
int *const
@end smallexample
@tab @code{r^i}
@end multitable
@sp 1
@code{const int*} is a pointer to a @code{const int}, and so is
encoded as @code{^ri}. @code{int* const}, instead, is a @code{const}
pointer to an @code{int}, and so is encoded as @code{r^i}.
Finally, there is a complication when encoding @code{const char *}
versus @code{char * const}. Because @code{char *} is encoded as
@code{*} and not as @code{^c}, there is no way to express the fact
that @code{r} applies to the pointer or to the pointee.
Hence, it is assumed as a convention that @code{r*} means @code{const
char *} (since it is what is most often meant), and there is no way to
encode @code{char *const}. @code{char *const} would simply be encoded
as @code{*}, and the @code{const} is lost.
@menu
* Legacy type encoding::
* @@encode::
* Method signatures::
@end menu
@node Legacy type encoding
@subsection Legacy type encoding
Unfortunately, historically GCC used to have a number of bugs in its
encoding code. The NeXT runtime expects GCC to emit type encodings in
this historical format (compatible with GCC-3.3), so when using the
NeXT runtime, GCC will introduce on purpose a number of incorrect
encodings:
@itemize @bullet
@item
the read-only qualifier of the pointee gets emitted before the '^'.
The read-only qualifier of the pointer itself gets ignored, unless it
is a typedef. Also, the 'r' is only emitted for the outermost type.
@item
32-bit longs are encoded as 'l' or 'L', but not always. For typedefs,
the compiler uses 'i' or 'I' instead if encoding a struct field or a
pointer.
@item
@code{enum}s are always encoded as 'i' (int) even if they are actually
unsigned or long.
@end itemize
In addition to that, the NeXT runtime uses a different encoding for
bitfields. It encodes them as @code{b} followed by the size, without
a bit offset or the underlying field type.
@node @@encode
@subsection @@encode
GNU Objective-C supports the @code{@@encode} syntax that allows you to
create a type encoding from a C/Objective-C type. For example,
@code{@@encode(int)} is compiled by the compiler into @code{"i"}.
@code{@@encode} does not support type qualifiers other than
@code{const}. For example, @code{@@encode(const char*)} is valid and
is compiled into @code{"r*"}, while @code{@@encode(bycopy char *)} is
invalid and will cause a compilation error.
@node Method signatures
@subsection Method signatures
This section documents the encoding of method types, which is rarely
needed to use Objective-C. You should skip it at a first reading; the
runtime provides functions that will work on methods and can walk
through the list of parameters and interpret them for you. These
functions are part of the public ``API'' and are the preferred way to
interact with method signatures from user code.
But if you need to debug a problem with method signatures and need to
know how they are implemented (ie, the ``ABI''), read on.
Methods have their ``signature'' encoded and made available to the
runtime. The ``signature'' encodes all the information required to
dynamically build invocations of the method at runtime: return type
and arguments.
The ``signature'' is a null-terminated string, composed of the following:
@itemize @bullet
@item
The return type, including type qualifiers. For example, a method
returning @code{int} would have @code{i} here.
@item
The total size (in bytes) required to pass all the parameters. This
includes the two hidden parameters (the object @code{self} and the
method selector @code{_cmd}).
@item
Each argument, with the type encoding, followed by the offset (in
bytes) of the argument in the list of parameters.
@end itemize
For example, a method with no arguments and returning @code{int} would
have the signature @code{i8@@0:4} if the size of a pointer is 4. The
signature is interpreted as follows: the @code{i} is the return type
(an @code{int}), the @code{8} is the total size of the parameters in
bytes (two pointers each of size 4), the @code{@@0} is the first
parameter (an object at byte offset @code{0}) and @code{:4} is the
second parameter (a @code{SEL} at byte offset @code{4}).
You can easily find more examples by running the ``strings'' program
on an Objective-C object file compiled by GCC. You'll see a lot of
strings that look very much like @code{i8@@0:4}. They are signatures
of Objective-C methods.
@node Garbage Collection
@section Garbage Collection
......
2010-09-27 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-27 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.
2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
Merge from 'apple/trunk' branch on FSF servers.
2005-12-15 Fariborz Jahanian <fjahanian@apple.com>
......
2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
PR objc/25464
* objc.dg/type-size-3.m: New test.
2010-09-27 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-27 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-27 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.
2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
Merge from 'apple/trunk' branch on FSF servers. Renamed
const-str-12.m to constr-str-12b.m to avoid conflicts.
......
/* This file tests that things are encoded using the gcc-3.3 ABI which is only
used by the NeXT runtime. */
/* Test for graceful encoding of const-qualified fields and parameters. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
struct Cxx {
const struct Cxx *next;
};
@interface ObjC {
const struct Cxx *obj;
}
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d;
@end
@implementation ObjC
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d {
obj = d;
return self;
}
@end
/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+\\^{Cxx=\\^{Cxx}}\[0-9\]+r\\^{Cxx=\\^{Cxx}}" } } */
......@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
struct Cxx {
const struct Cxx *next;
......
......@@ -70,7 +70,21 @@ int main(void) {
CHECK_IF(offs3 == offs2 + sizeof(XXRect) && offs4 == offs3 + sizeof(int));
CHECK_IF(totsize == offs4 + sizeof(int));
meth = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u");
/* Here we have the complication that 'enum Enum' could be encoded
as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
runtime. So we get the @encode(enum Enum), then put it into the
string in place of the traditional 'i'.
*/
/* scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u"); */
{
char pattern[1024];
sprintf (pattern, "^%s%%u@%%u:%%u^{?=ff(__XXAngle=II)}%%u%s%%uc%%u",
@encode(enum Enum), @encode(enum Enum));
scan_initial(pattern);
}
CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
meth = [proto descriptionForClassMethod: @selector(getBool:)];
......
/* This file tests that things are encoded using the gcc-3.3 ABI which is only
used by the NeXT runtime. */
/* { dg-do run { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
#include <stdio.h>
#include <string.h>
#include "../objc-obj-c++-shared/Protocol1.h"
#ifndef __NEXT_RUNTIME__
#include <objc/objc-api.h>
#endif
extern "C" void abort();
@protocol CommonProtocol
-(oneway void)methodCall_On:(in bycopy id)someValue_On;
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO;
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo;
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO;
-(oneway void)methodCall_rn:(in const id)someValue_rn;
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn;
@end
@interface ObjCClass <CommonProtocol>
{
}
@end
@implementation ObjCClass
-(oneway void)methodCall_On:(in bycopy id)someValue_On { }
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO { }
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo { }
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO { }
-(oneway void)methodCall_rn:(in const id)someValue_rn { }
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn { }
@end
Protocol *proto = @protocol(CommonProtocol);
struct objc_method_description *meth;
int main()
{
meth = [proto descriptionForInstanceMethod: @selector(methodCall_On:)];
if (strcmp (meth->types, "Vv12@0:4On@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_nO:)];
if (strcmp (meth->types, "Vv12@0:4nO@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_Oo:)];
if (strcmp (meth->types, "Vv12@0:4Oo@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_oO:)];
if (strcmp (meth->types, "Vv12@0:4oO@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_rn:)];
if (strcmp (meth->types, "Vv12@0:4rn@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_oOn:)];
if (strcmp (meth->types, "Vv12@0:4oOn@8"))
abort();
return 0;
}
......@@ -4,7 +4,6 @@
where we have 'typedef char BOOL'. */
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do run } */
/* { dg-options "-fnext-runtime" } */
#include <string.h>
#include <stdlib.h>
#include <objc/objc.h>
......
......@@ -44,7 +44,7 @@ unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
static void scan_initial(const char *pattern) {
totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
&offs4, &offs5, &offs6, &offs7);
&offs4, &offs5, &offs6, &offs7);
CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
}
......@@ -65,7 +65,21 @@ int main(void) {
CHECK_IF(offs3 == offs2 + sizeof(XXRect) && offs4 == offs3 + sizeof(int));
CHECK_IF(totsize == offs4 + sizeof(int));
meth = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u");
/* Here we have the complication that 'enum Enum' could be encoded
as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
runtime. So we get the @encode(enum Enum), then put it into the
string in place of the traditional 'i'.
*/
/* scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u"); */
{
char pattern[1024];
sprintf (pattern, "^%s%%u@%%u:%%u^{?=ff(__XXAngle=II)}%%u%s%%uc%%u",
@encode(enum Enum), @encode(enum Enum));
scan_initial(pattern);
}
CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
meth = [proto descriptionForClassMethod: @selector(getBool:)];
......
/* Test for graceful encoding of const-qualified fields and parameters. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
struct Cxx {
const struct Cxx *next;
};
@interface ObjC {
const struct Cxx *obj;
}
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d;
@end
@implementation ObjC
- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d {
obj = d;
return self;
}
@end
/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+\\^{Cxx=\\^{Cxx}}\[0-9\]+r\\^{Cxx=\\^{Cxx}}" } } */
/* Test for graceful encoding of const-qualified fields and parameters. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
struct Cxx {
const struct Cxx *next;
......
......@@ -44,10 +44,20 @@ static void scan_initial(const char *pattern) {
int main(void) {
meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
#ifndef __NEXT_RUNTIME__
scan_initial("O@%u@%u:%uRN@%uo^^S%u");
#else
/* The NEXT runtime tries to be compatible with gcc-3.3 */
scan_initial("O@%u@%u:%uNR@%uo^^S%u");
#endif
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned));
meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
#ifndef __NEXT_RUNTIME__
scan_initial("Vv%u@%u:%uoO@%un^*%u");
#else
/* The NEXT runtime tries to be compatible with gcc-3.3 */
scan_initial("Vv%u@%u:%uOo@%un^*%u");
#endif
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **));
return 0;
}
/* This file tests that things are encoded using the gcc-3.3 ABI which is only
used by the NeXT runtime. */
/* { dg-do run { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
#include <stdio.h>
#include <string.h>
#include "../objc-obj-c++-shared/Protocol1.h"
extern void abort();
@protocol CommonProtocol
-(oneway void)methodCall_On:(in bycopy id)someValue_On;
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO;
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo;
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO;
-(oneway void)methodCall_rn:(in const id)someValue_rn;
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn;
@end
@interface ObjCClass <CommonProtocol>
{
}
@end
@implementation ObjCClass
-(oneway void)methodCall_On:(in bycopy id)someValue_On { }
-(oneway void)methodCall_nO:(bycopy in id)someValue_nO { }
-(oneway void)methodCall_Oo:(out bycopy id)someValue_Oo { }
-(oneway void)methodCall_oO:(bycopy out id)someValue_oO { }
-(oneway void)methodCall_rn:(in const id)someValue_rn { }
-(oneway void)methodCall_oOn:(in bycopy out id)someValue_oOn { }
@end
Protocol *proto = @protocol(CommonProtocol);
struct objc_method_description *meth;
int main()
{
meth = [proto descriptionForInstanceMethod: @selector(methodCall_On:)];
if (strcmp (meth->types, "Vv12@0:4On@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_nO:)];
if (strcmp (meth->types, "Vv12@0:4nO@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_Oo:)];
if (strcmp (meth->types, "Vv12@0:4Oo@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_oO:)];
if (strcmp (meth->types, "Vv12@0:4oO@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_rn:)];
if (strcmp (meth->types, "Vv12@0:4rn@8"))
abort();
meth = [proto descriptionForInstanceMethod: @selector(methodCall_oOn:)];
if (strcmp (meth->types, "Vv12@0:4oOn@8"))
abort();
return 0;
}
......@@ -48,7 +48,20 @@ int main(void) {
cls = objc_get_class("ArrayTest");
meth = class_get_instance_method(cls, @selector(str:with:and:));
scan_initial("r*%u@%u:%u*%u*%u[4i]%u");
/* Here we have the complication that 'enum Enum' could be encoded
as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
runtime. So we get the @encode(enum Enum), then put it into the
string in place of the traditional 'i'.
*/
/* scan_initial("r*%u@%u:%u*%u*%u[4i]%u"); */
{
char pattern[1024];
sprintf (pattern, "r*%%u@%%u:%%u*%%u*%%u[4%s]%%u", @encode(enum Enum));
scan_initial(pattern);
}
CHECK_IF(offs3 == offs2 + sizeof(signed char *) && offs4 == offs3 + sizeof(unsigned char *));
CHECK_IF(totsize == offs4 + sizeof(enum Enum *));
meth = class_get_instance_method(cls, @selector(meth1:with:with:));
......
/* Reject ivars with an unknown size. */
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
/* { dg-do compile } */
typedef struct
{
unsigned long int a;
double b[];
} test_type;
@interface Test
{
test_type c;
}
@end
@implementation Test
@end /* { dg-error "instance variable has unknown size" } */
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.
2010-09-26 Nicola Pero <nicola.pero@meta-innovation.com>
* libobjc_entry.c: File removed.
2010-09-26 Kai Tietz <kai.tietz@onevision.com>
......
......@@ -148,6 +148,8 @@ objc_sizeof_type (const char *type)
/* Skip the variable name if any */
if (*type == '"')
{
/* FIXME: How do we know we won't read beyond the end of the
string. Here and in the rest of the file! */
for (type++; *type++ != '"';)
/* do nothing */;
}
......@@ -217,6 +219,10 @@ objc_sizeof_type (const char *type)
return sizeof (double);
break;
case _C_LNG_DBL:
return sizeof (long double);
break;
case _C_VOID:
return sizeof (void);
break;
......@@ -236,6 +242,19 @@ objc_sizeof_type (const char *type)
}
break;
case _C_VECTOR:
{
/* Skip the '!'. */
type++;
/* Skip the '['. */
type++;
/* The size in bytes is the following number. */
int size = atoi (type);
return size;
}
break;
case _C_BFLD:
{
/* The new encoding of bitfields is: b 'position' 'type' 'size' */
......@@ -318,6 +337,10 @@ objc_sizeof_type (const char *type)
case _C_DBL:
return sizeof (_Complex double);
break;
case _C_LNG_DBL:
return sizeof (_Complex long double);
break;
default:
{
......@@ -418,6 +441,10 @@ objc_alignof_type (const char *type)
return __alignof__ (double);
break;
case _C_LNG_DBL:
return __alignof__ (long double);
break;
case _C_PTR:
case _C_ATOM:
case _C_CHARPTR:
......@@ -429,6 +456,23 @@ objc_alignof_type (const char *type)
/* do nothing */;
return objc_alignof_type (type);
case _C_VECTOR:
{
/* Skip the '!'. */
type++;
/* Skip the '['. */
type++;
/* Skip the size. */
while (isdigit ((unsigned char)*type))
type++;
/* Skip the ','. */
type++;
/* The alignment in bytes is the following number. */
return atoi (type);
}
case _C_STRUCT_B:
case _C_UNION_B:
{
......@@ -496,6 +540,10 @@ objc_alignof_type (const char *type)
case _C_DBL:
return __alignof__ (_Complex double);
break;
case _C_LNG_DBL:
return __alignof__ (_Complex long double);
break;
default:
{
......@@ -631,6 +679,7 @@ objc_skip_typespec (const char *type)
case _C_ULNG_LNG:
case _C_FLT:
case _C_DBL:
case _C_LNG_DBL:
case _C_VOID:
case _C_UNDEF:
return ++type;
......@@ -642,7 +691,6 @@ objc_skip_typespec (const char *type)
case _C_ARY_B:
/* skip digits, typespec and closing ']' */
while (isdigit ((unsigned char)*++type))
;
type = objc_skip_typespec (type);
......@@ -654,6 +702,30 @@ objc_skip_typespec (const char *type)
return 0;
}
case _C_VECTOR:
/* Skip '!' */
type++;
/* Skip '[' */
type++;
/* Skip digits (size) */
while (isdigit ((unsigned char)*type))
type++;
/* Skip ',' */
type++;
/* Skip digits (alignment) */
while (isdigit ((unsigned char)*type))
type++;
/* Skip typespec. */
type = objc_skip_typespec (type);
/* Skip closing ']'. */
if (*type == _C_ARY_E)
return ++type;
else
{
_objc_abort ("bad vector type %s\n", type);
return 0;
}
case _C_BFLD:
/* The new encoding of bitfields is: b 'position' 'type' 'size' */
while (isdigit ((unsigned char)*++type))
......@@ -700,6 +772,8 @@ objc_skip_typespec (const char *type)
/*
Skip an offset as part of a method encoding. This is prepended by a
'+' if the argument is passed in registers.
FIXME: The compiler never generates '+'.
*/
const char *
objc_skip_offset (const char *type)
......@@ -883,7 +957,7 @@ objc_get_type_qualifiers (const char *type)
the presence of bitfields inside the structure. */
void
objc_layout_structure (const char *type,
struct objc_struct_layout *layout)
struct objc_struct_layout *layout)
{
const char *ntype;
......@@ -979,6 +1053,7 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
bfld_field_size = atoi (objc_skip_typespec (bfld_type));
}
/* The following won't work for vectors. */
#ifdef BIGGEST_FIELD_ALIGNMENT
desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
#endif
......
......@@ -42,7 +42,7 @@ extern "C" {
#define _C_BYCOPY 'O'
#define _C_BYREF 'R'
#define _C_ONEWAY 'V'
#define _C_GCINVISIBLE '!'
#define _C_GCINVISIBLE '|'
#define _F_CONST 0x01
#define _F_IN 0x01
......
......@@ -68,13 +68,13 @@ struct objc_method_description
#define _C_ULNG_LNG 'Q'
#define _C_FLT 'f'
#define _C_DBL 'd'
#define _C_LNG_DBL 'D'
#define _C_BFLD 'b'
#define _C_BOOL 'B'
#define _C_BOOL 'B'
#define _C_VOID 'v'
#define _C_UNDEF '?'
#define _C_PTR '^'
#define _C_CHARPTR '*'
#define _C_ATOM '%'
#define _C_ARY_B '['
#define _C_ARY_E ']'
#define _C_UNION_B '('
......@@ -82,7 +82,13 @@ struct objc_method_description
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
#define _C_VECTOR '!'
#define _C_COMPLEX 'j'
#define _C_COMPLEX 'j'
/* The following one is never generated by the compiler. You can
treat it as equivalent to "*".
*/
#define _C_ATOM '%'
#include "deprecated/objc_error.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment