1/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, March 2011.  */
2/* Test encoding properties.  */
3/* { dg-do run } */
4/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
5
6#include <objc/runtime.h>
7#include <stdlib.h>
8#include <stdio.h>
9#include <string.h>
10
11@interface MyRootClass
12{ Class isa; }
13+ alloc;
14- init;
15+ initialize;
16@end
17
18@implementation MyRootClass
19+ alloc { return class_createInstance (self, 0); }
20- init  { return self; }
21+ initialize { return self; }
22@end
23
24@interface MySubClass : MyRootClass
25{
26  char char_property;
27  short short_property;
28  int int_property;
29  long long_property;
30  float float_property;
31  double double_property;
32  int *int_pointer_property;
33
34  id propertyA;
35  id propertyB;
36  id propertyC;
37  id propertyD;
38  int propertyE;
39  id propertyF;
40
41  id other_variable;
42}
43@property char char_property;
44@property short short_property;
45@property int int_property;
46@property long long_property;
47@property float float_property;
48@property double double_property;
49@property int *int_pointer_property;
50
51@property (assign, getter=getP, setter=setP:) id propertyA;
52@property (assign) id propertyB;
53@property (copy) id propertyC;
54@property (retain) id propertyD;
55@property (nonatomic) int propertyE;
56@property (nonatomic, readonly, copy) id propertyF;
57
58@property (assign) id propertyG;
59@property (assign, readonly, getter=X) id propertyH;
60@end
61
62@implementation MySubClass
63@synthesize char_property;
64@synthesize short_property;
65@synthesize int_property;
66@synthesize long_property;
67@synthesize float_property;
68@synthesize double_property;
69@synthesize int_pointer_property;
70
71@synthesize propertyA;
72@synthesize propertyB;
73@synthesize propertyC;
74@synthesize propertyD;
75@synthesize propertyE;
76@synthesize propertyF;
77
78@synthesize propertyG = other_variable;
79@dynamic propertyH;
80@end
81
82#ifdef __OBJC2__
83void error (objc_property_t p)
84{
85  printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n",
86	  property_getName (p),
87	  property_getAttributes (p));
88  abort ();
89}
90
91/* Concatenate 3 strings and return the result.  */
92char *concat (const char *a, const char *b, const char *c)
93{
94  /* We happily leak memory here.  This is a test.  */
95  char *x = (char *)malloc (sizeof (char) * 128);
96  snprintf (x, 128, "%s%s%s", a, b, c);
97  return x;
98}
99
100#endif
101
102int main (void)
103{
104#ifdef __OBJC2__
105  Class c = objc_getClass ("MySubClass");
106  objc_property_t p;
107
108  p = class_getProperty (c, "char_property");
109  /* Usually we expect "Tc,Vchar_property", but if a char is of
110     different size, it may be encoded differently than "c".  */
111  if (strcmp (concat ("T", @encode (char), ",Vchar_property"),
112	      property_getAttributes (p)) != 0)
113    error (p);
114
115  p = class_getProperty (c, "short_property");
116  if (strcmp (concat ("T", @encode (short), ",Vshort_property"),
117	      property_getAttributes (p)) != 0)
118    error (p);
119
120  p = class_getProperty (c, "int_property");
121  if (strcmp (concat ("T", @encode (int), ",Vint_property"),
122	      property_getAttributes (p)) != 0)
123    error (p);
124
125  p = class_getProperty (c, "long_property");
126  if (strcmp (concat ("T", @encode (long), ",Vlong_property"),
127	      property_getAttributes (p)) != 0)
128    error (p);
129
130  p = class_getProperty (c, "float_property");
131  if (strcmp (concat ("T", @encode (float), ",Vfloat_property"),
132	      property_getAttributes (p)) != 0)
133    error (p);
134
135  p = class_getProperty (c, "double_property");
136  if (strcmp (concat ("T", @encode (double), ",Vdouble_property"),
137	      property_getAttributes (p)) != 0)
138    error (p);
139
140  p = class_getProperty (c, "int_pointer_property");
141  if (strcmp (concat ("T", @encode (int *), ",Vint_pointer_property"),
142	      property_getAttributes (p)) != 0)
143    error (p);
144
145  /* Objects are always encoded as '@' hence the string does not
146     depend on the architecture.  */
147  p = class_getProperty (c, "propertyA");
148  if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0)
149    error (p);
150
151  p = class_getProperty (c, "propertyB");
152  if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0)
153    error (p);
154
155  p = class_getProperty (c, "propertyC");
156  if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0)
157    error (p);
158
159  p = class_getProperty (c, "propertyD");
160  if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0)
161    error (p);
162
163  p = class_getProperty (c, "propertyE");
164  if (strcmp (concat ("T", @encode (int), ",N,VpropertyE"),
165	      property_getAttributes (p)) != 0)
166    error (p);
167
168  p = class_getProperty (c, "propertyF");
169  if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0)
170    error (p);
171
172  p = class_getProperty (c, "propertyG");
173  if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0)
174    error (p);
175
176  p = class_getProperty (c, "propertyH");
177  if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0)
178    error (p);
179#endif
180
181  return 0;
182}
183