xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/member-function-pointers.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix CODE-LP64 %s
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix CODE-LP32 %s
3*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix GLOBAL-LP64 %s
4*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix GLOBAL-LP32 %s
5*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix GLOBAL-ARM %s
6*f4a2713aSLionel Sambuc 
7*f4a2713aSLionel Sambuc // PNaCl uses the same representation of method pointers as ARM.
8*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o - -triple=le32-unknown-nacl | FileCheck -check-prefix GLOBAL-ARM %s
9*f4a2713aSLionel Sambuc 
10*f4a2713aSLionel Sambuc struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
11*f4a2713aSLionel Sambuc struct B { int b; virtual void g(); };
12*f4a2713aSLionel Sambuc struct C : B, A { };
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc void (A::*pa)();
15*f4a2713aSLionel Sambuc void (A::*volatile vpa)();
16*f4a2713aSLionel Sambuc void (B::*pb)();
17*f4a2713aSLionel Sambuc void (C::*pc)();
18*f4a2713aSLionel Sambuc 
19*f4a2713aSLionel Sambuc // GLOBAL-LP64: @pa2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
20*f4a2713aSLionel Sambuc void (A::*pa2)() = &A::f;
21*f4a2713aSLionel Sambuc 
22*f4a2713aSLionel Sambuc // GLOBAL-LP64: @pa3 = global { i64, i64 } { i64 1, i64 0 }, align 8
23*f4a2713aSLionel Sambuc // GLOBAL-LP32: @pa3 = global { i32, i32 } { i32 1, i32 0 }, align 4
24*f4a2713aSLionel Sambuc void (A::*pa3)() = &A::vf1;
25*f4a2713aSLionel Sambuc 
26*f4a2713aSLionel Sambuc // GLOBAL-LP64: @pa4 = global { i64, i64 } { i64 9, i64 0 }, align 8
27*f4a2713aSLionel Sambuc // GLOBAL-LP32: @pa4 = global { i32, i32 } { i32 5, i32 0 }, align 4
28*f4a2713aSLionel Sambuc void (A::*pa4)() = &A::vf2;
29*f4a2713aSLionel Sambuc 
30*f4a2713aSLionel Sambuc // GLOBAL-LP64: @pc2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
31*f4a2713aSLionel Sambuc void (C::*pc2)() = &C::f;
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc // GLOBAL-LP64: @pc3 = global { i64, i64 } { i64 1, i64 0 }, align 8
34*f4a2713aSLionel Sambuc void (A::*pc3)() = &A::vf1;
35*f4a2713aSLionel Sambuc 
36*f4a2713aSLionel Sambuc void f() {
37*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } zeroinitializer, { i64, i64 }* @pa
38*f4a2713aSLionel Sambuc   pa = 0;
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc   // Is this okay?  What are LLVM's volatile semantics for structs?
41*f4a2713aSLionel Sambuc   // CODE-LP64: store volatile { i64, i64 } zeroinitializer, { i64, i64 }* @vpa
42*f4a2713aSLionel Sambuc   vpa = 0;
43*f4a2713aSLionel Sambuc 
44*f4a2713aSLionel Sambuc   // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pa, align 8
45*f4a2713aSLionel Sambuc   // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
46*f4a2713aSLionel Sambuc   // CODE-LP64: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16
47*f4a2713aSLionel Sambuc   // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
48*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pc, align 8
49*f4a2713aSLionel Sambuc   pc = pa;
50*f4a2713aSLionel Sambuc 
51*f4a2713aSLionel Sambuc   // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pc, align 8
52*f4a2713aSLionel Sambuc   // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
53*f4a2713aSLionel Sambuc   // CODE-LP64: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16
54*f4a2713aSLionel Sambuc   // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
55*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pa, align 8
56*f4a2713aSLionel Sambuc   pa = static_cast<void (A::*)()>(pc);
57*f4a2713aSLionel Sambuc }
58*f4a2713aSLionel Sambuc 
59*f4a2713aSLionel Sambuc void f2() {
60*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
61*f4a2713aSLionel Sambuc   void (A::*pa2)() = &A::f;
62*f4a2713aSLionel Sambuc 
63*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } { i64 1, i64 0 }
64*f4a2713aSLionel Sambuc   // CODE-LP32: store { i32, i32 } { i32 1, i32 0 }
65*f4a2713aSLionel Sambuc   void (A::*pa3)() = &A::vf1;
66*f4a2713aSLionel Sambuc 
67*f4a2713aSLionel Sambuc   // CODE-LP64: store { i64, i64 } { i64 9, i64 0 }
68*f4a2713aSLionel Sambuc   // CODE-LP32: store { i32, i32 } { i32 5, i32 0 }
69*f4a2713aSLionel Sambuc   void (A::*pa4)() = &A::vf2;
70*f4a2713aSLionel Sambuc }
71*f4a2713aSLionel Sambuc 
72*f4a2713aSLionel Sambuc void f3(A *a, A &ar) {
73*f4a2713aSLionel Sambuc   (a->*pa)();
74*f4a2713aSLionel Sambuc   (ar.*pa)();
75*f4a2713aSLionel Sambuc }
76*f4a2713aSLionel Sambuc 
77*f4a2713aSLionel Sambuc bool f4() {
78*f4a2713aSLionel Sambuc   return pa;
79*f4a2713aSLionel Sambuc }
80*f4a2713aSLionel Sambuc 
81*f4a2713aSLionel Sambuc // PR5177
82*f4a2713aSLionel Sambuc namespace PR5177 {
83*f4a2713aSLionel Sambuc   struct A {
84*f4a2713aSLionel Sambuc    bool foo(int*) const;
85*f4a2713aSLionel Sambuc   } a;
86*f4a2713aSLionel Sambuc 
87*f4a2713aSLionel Sambuc   struct B1 {
88*f4a2713aSLionel Sambuc    bool (A::*pmf)(int*) const;
89*f4a2713aSLionel Sambuc    const A* pa;
90*f4a2713aSLionel Sambuc 
91*f4a2713aSLionel Sambuc    B1() : pmf(&A::foo), pa(&a) {}
92*f4a2713aSLionel Sambuc    bool operator()() const { return (pa->*pmf)(new int); }
93*f4a2713aSLionel Sambuc   };
94*f4a2713aSLionel Sambuc 
95*f4a2713aSLionel Sambuc   void bar(B1 b2) { while (b2()) ; }
96*f4a2713aSLionel Sambuc }
97*f4a2713aSLionel Sambuc 
98*f4a2713aSLionel Sambuc // PR5138
99*f4a2713aSLionel Sambuc namespace PR5138 {
100*f4a2713aSLionel Sambuc   struct foo {
101*f4a2713aSLionel Sambuc       virtual void bar(foo *);
102*f4a2713aSLionel Sambuc   };
103*f4a2713aSLionel Sambuc 
104*f4a2713aSLionel Sambuc   extern "C" {
105*f4a2713aSLionel Sambuc     void baz(foo *);
106*f4a2713aSLionel Sambuc   }
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc   void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
109*f4a2713aSLionel Sambuc   void (*ptr2)(void *) = (void (*)(void *))&baz;
110*f4a2713aSLionel Sambuc 
111*f4a2713aSLionel Sambuc   void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
112*f4a2713aSLionel Sambuc }
113*f4a2713aSLionel Sambuc 
114*f4a2713aSLionel Sambuc // PR5593
115*f4a2713aSLionel Sambuc namespace PR5593 {
116*f4a2713aSLionel Sambuc   struct A { };
117*f4a2713aSLionel Sambuc 
118*f4a2713aSLionel Sambuc   bool f(void (A::*f)()) {
119*f4a2713aSLionel Sambuc     return f && f;
120*f4a2713aSLionel Sambuc   }
121*f4a2713aSLionel Sambuc }
122*f4a2713aSLionel Sambuc 
123*f4a2713aSLionel Sambuc namespace PR5718 {
124*f4a2713aSLionel Sambuc   struct A { };
125*f4a2713aSLionel Sambuc 
126*f4a2713aSLionel Sambuc   bool f(void (A::*f)(), void (A::*g)()) {
127*f4a2713aSLionel Sambuc     return f == g;
128*f4a2713aSLionel Sambuc   }
129*f4a2713aSLionel Sambuc }
130*f4a2713aSLionel Sambuc 
131*f4a2713aSLionel Sambuc namespace BoolMemberPointer {
132*f4a2713aSLionel Sambuc   struct A { };
133*f4a2713aSLionel Sambuc 
134*f4a2713aSLionel Sambuc   bool f(void (A::*f)()) {
135*f4a2713aSLionel Sambuc     return !f;
136*f4a2713aSLionel Sambuc   }
137*f4a2713aSLionel Sambuc 
138*f4a2713aSLionel Sambuc   bool g(void (A::*f)()) {
139*f4a2713aSLionel Sambuc     if (!!f)
140*f4a2713aSLionel Sambuc       return true;
141*f4a2713aSLionel Sambuc     return false;
142*f4a2713aSLionel Sambuc   }
143*f4a2713aSLionel Sambuc }
144*f4a2713aSLionel Sambuc 
145*f4a2713aSLionel Sambuc // PR5940
146*f4a2713aSLionel Sambuc namespace PR5940 {
147*f4a2713aSLionel Sambuc   class foo {
148*f4a2713aSLionel Sambuc   public:
149*f4a2713aSLionel Sambuc     virtual void baz(void);
150*f4a2713aSLionel Sambuc   };
151*f4a2713aSLionel Sambuc 
152*f4a2713aSLionel Sambuc   void foo::baz(void) {
153*f4a2713aSLionel Sambuc        void (foo::*ptr)(void) = &foo::baz;
154*f4a2713aSLionel Sambuc   }
155*f4a2713aSLionel Sambuc }
156*f4a2713aSLionel Sambuc 
157*f4a2713aSLionel Sambuc namespace MemberPointerImpCast {
158*f4a2713aSLionel Sambuc   struct A {
159*f4a2713aSLionel Sambuc     int x;
160*f4a2713aSLionel Sambuc   };
161*f4a2713aSLionel Sambuc   struct B : public A {
162*f4a2713aSLionel Sambuc   };
163*f4a2713aSLionel Sambuc   void f(B* obj, void (A::*method)()) {
164*f4a2713aSLionel Sambuc     (obj->*method)();
165*f4a2713aSLionel Sambuc   }
166*f4a2713aSLionel Sambuc }
167*f4a2713aSLionel Sambuc 
168*f4a2713aSLionel Sambuc // PR6258
169*f4a2713aSLionel Sambuc namespace PR6258 {
170*f4a2713aSLionel Sambuc 
171*f4a2713aSLionel Sambuc   struct A {
172*f4a2713aSLionel Sambuc     void f(bool);
173*f4a2713aSLionel Sambuc   };
174*f4a2713aSLionel Sambuc 
175*f4a2713aSLionel Sambuc   void (A::*pf)(bool) = &A::f;
176*f4a2713aSLionel Sambuc 
177*f4a2713aSLionel Sambuc   void f() {
178*f4a2713aSLionel Sambuc     void (A::*pf)(bool) = &A::f;
179*f4a2713aSLionel Sambuc   }
180*f4a2713aSLionel Sambuc }
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc // PR7027
183*f4a2713aSLionel Sambuc namespace PR7027 {
184*f4a2713aSLionel Sambuc   struct X { void test( ); };
185*f4a2713aSLionel Sambuc   void testX() { &X::test; }
186*f4a2713aSLionel Sambuc }
187*f4a2713aSLionel Sambuc 
188*f4a2713aSLionel Sambuc namespace test7 {
189*f4a2713aSLionel Sambuc   struct A { void foo(); virtual void vfoo(); };
190*f4a2713aSLionel Sambuc   struct B { void foo(); virtual void vfoo(); };
191*f4a2713aSLionel Sambuc   struct C : A, B { void foo(); virtual void vfoo(); };
192*f4a2713aSLionel Sambuc 
193*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 }
194*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 }
195*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 }
196*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 }
197*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 }
198*f4a2713aSLionel Sambuc   // GLOBAL-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 }
199*f4a2713aSLionel Sambuc   void (C::*ptr0)() = &A::foo;
200*f4a2713aSLionel Sambuc   void (C::*ptr1)() = &B::foo;
201*f4a2713aSLionel Sambuc   void (C::*ptr2)() = &C::foo;
202*f4a2713aSLionel Sambuc   void (C::*ptr3)() = &A::vfoo;
203*f4a2713aSLionel Sambuc   void (C::*ptr4)() = &B::vfoo;
204*f4a2713aSLionel Sambuc   void (C::*ptr5)() = &C::vfoo;
205*f4a2713aSLionel Sambuc }
206*f4a2713aSLionel Sambuc 
207*f4a2713aSLionel Sambuc namespace test8 {
208*f4a2713aSLionel Sambuc   struct X { };
209*f4a2713aSLionel Sambuc   typedef int (X::*pmf)(int);
210*f4a2713aSLionel Sambuc 
211*f4a2713aSLionel Sambuc   // CHECK: {{define.*_ZN5test81fEv}}
212*f4a2713aSLionel Sambuc   pmf f() {
213*f4a2713aSLionel Sambuc     // CHECK: {{ret.*zeroinitializer}}
214*f4a2713aSLionel Sambuc     return pmf();
215*f4a2713aSLionel Sambuc   }
216*f4a2713aSLionel Sambuc }
217*f4a2713aSLionel Sambuc 
218*f4a2713aSLionel Sambuc namespace test9 {
219*f4a2713aSLionel Sambuc   struct A {
220*f4a2713aSLionel Sambuc     void foo();
221*f4a2713aSLionel Sambuc   };
222*f4a2713aSLionel Sambuc   struct B : A {
223*f4a2713aSLionel Sambuc     void foo();
224*f4a2713aSLionel Sambuc   };
225*f4a2713aSLionel Sambuc 
226*f4a2713aSLionel Sambuc   typedef void (A::*fooptr)();
227*f4a2713aSLionel Sambuc 
228*f4a2713aSLionel Sambuc   struct S {
229*f4a2713aSLionel Sambuc     fooptr p;
230*f4a2713aSLionel Sambuc   };
231*f4a2713aSLionel Sambuc 
232*f4a2713aSLionel Sambuc   // CODE-LP64-LABEL:    define void @_ZN5test94testEv(
233*f4a2713aSLionel Sambuc   // CODE-LP64:      alloca i32
234*f4a2713aSLionel Sambuc   // CODE-LP64-NEXT: ret void
235*f4a2713aSLionel Sambuc   void test() {
236*f4a2713aSLionel Sambuc     int x;
237*f4a2713aSLionel Sambuc     static S array[] = { (fooptr) &B::foo };
238*f4a2713aSLionel Sambuc   }
239*f4a2713aSLionel Sambuc }
240*f4a2713aSLionel Sambuc 
241*f4a2713aSLionel Sambuc // rdar://problem/10815683 - Verify that we can emit reinterprets of
242*f4a2713aSLionel Sambuc // member pointers as constant initializers.  For added trickiness,
243*f4a2713aSLionel Sambuc // we also add some non-trivial adjustments.
244*f4a2713aSLionel Sambuc namespace test10 {
245*f4a2713aSLionel Sambuc   struct A {
246*f4a2713aSLionel Sambuc     int nonEmpty;
247*f4a2713aSLionel Sambuc     void foo();
248*f4a2713aSLionel Sambuc   };
249*f4a2713aSLionel Sambuc   struct B : public A {
250*f4a2713aSLionel Sambuc     virtual void requireNonZeroAdjustment();
251*f4a2713aSLionel Sambuc   };
252*f4a2713aSLionel Sambuc   struct C {
253*f4a2713aSLionel Sambuc     int nonEmpty;
254*f4a2713aSLionel Sambuc   };
255*f4a2713aSLionel Sambuc   struct D : public C {
256*f4a2713aSLionel Sambuc     virtual void requireNonZeroAdjustment();
257*f4a2713aSLionel Sambuc   };
258*f4a2713aSLionel Sambuc 
259*f4a2713aSLionel Sambuc 
260*f4a2713aSLionel Sambuc // It's not that the offsets are doubled on ARM, it's that they're left-shifted by 1.
261*f4a2713aSLionel Sambuc 
262*f4a2713aSLionel Sambuc // GLOBAL-LP64: @_ZN6test101aE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 0 }, align 8
263*f4a2713aSLionel Sambuc // GLOBAL-LP32: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
264*f4a2713aSLionel Sambuc // GLOBAL-ARM:  @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
265*f4a2713aSLionel Sambuc   void (A::*a)() = &A::foo;
266*f4a2713aSLionel Sambuc 
267*f4a2713aSLionel Sambuc // GLOBAL-LP64: @_ZN6test101bE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
268*f4a2713aSLionel Sambuc // GLOBAL-LP32: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
269*f4a2713aSLionel Sambuc // GLOBAL-ARM:  @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
270*f4a2713aSLionel Sambuc   void (B::*b)() = (void (B::*)()) &A::foo;
271*f4a2713aSLionel Sambuc 
272*f4a2713aSLionel Sambuc // GLOBAL-LP64: @_ZN6test101cE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
273*f4a2713aSLionel Sambuc // GLOBAL-LP32: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
274*f4a2713aSLionel Sambuc // GLOBAL-ARM:  @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
275*f4a2713aSLionel Sambuc   void (C::*c)() = (void (C::*)()) (void (B::*)()) &A::foo;
276*f4a2713aSLionel Sambuc 
277*f4a2713aSLionel Sambuc // GLOBAL-LP64: @_ZN6test101dE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 16 }, align 8
278*f4a2713aSLionel Sambuc // GLOBAL-LP32: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
279*f4a2713aSLionel Sambuc // GLOBAL-ARM:  @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 16 }, align 4
280*f4a2713aSLionel Sambuc   void (D::*d)() = (void (C::*)()) (void (B::*)()) &A::foo;
281*f4a2713aSLionel Sambuc }
282*f4a2713aSLionel Sambuc 
283*f4a2713aSLionel Sambuc namespace test11 {
284*f4a2713aSLionel Sambuc   struct A { virtual void a(); };
285*f4a2713aSLionel Sambuc   struct B : A {};
286*f4a2713aSLionel Sambuc   struct C : B { virtual void a(); };
287*f4a2713aSLionel Sambuc   void (C::*x)() = &C::a;
288*f4a2713aSLionel Sambuc 
289*f4a2713aSLionel Sambuc   // GLOBAL-LP64: @_ZN6test111xE = global { i64, i64 } { i64 1, i64 0 }
290*f4a2713aSLionel Sambuc   // GLOBAL-LP32: @_ZN6test111xE = global { i32, i32 } { i32 1, i32 0 }
291*f4a2713aSLionel Sambuc   // GLOBAL-ARM:  @_ZN6test111xE = global { i32, i32 } { i32 0, i32 1 }
292*f4a2713aSLionel Sambuc }
293