|
9 | 9 |
|
10 | 10 | typedef void (*ctest_void_func)(void);
|
11 | 11 |
|
12 |
| -static char *ctest_const_A_val_static = A; |
13 |
| - |
14 |
| -// Define a function that returns a pointer to the value of the constant to test. |
15 |
| -// This will later be called on the Rust side via FFI. |
16 |
| -char *ctest_const_cstr__A(void) { |
17 |
| - return ctest_const_A_val_static; |
18 |
| -} |
19 |
| - |
20 |
| -// Return the size of a type. |
21 |
| -uint64_t ctest_size_of__Byte(void) { return sizeof(Byte); } |
22 |
| - |
23 |
| -// Return the alignment of a type. |
24 |
| -uint64_t ctest_align_of__Byte(void) { return _Alignof(Byte); } |
25 |
| - |
26 |
| -// Return the size of a type. |
27 |
| -uint64_t ctest_size_of__Person(void) { return sizeof(struct Person); } |
28 |
| - |
29 |
| -// Return the alignment of a type. |
30 |
| -uint64_t ctest_align_of__Person(void) { return _Alignof(struct Person); } |
31 |
| - |
32 |
| -// Return the size of a type. |
33 |
| -uint64_t ctest_size_of__Word(void) { return sizeof(union Word); } |
34 |
| - |
35 |
| -// Return the alignment of a type. |
36 |
| -uint64_t ctest_align_of__Word(void) { return _Alignof(union Word); } |
37 |
| - |
38 |
| -// Return `1` if the type is signed, otherwise return `0`. |
39 |
| -// Casting -1 to the aliased type if signed evaluates to `-1 < 0`, if unsigned to `MAX_VALUE < 0` |
40 |
| -uint32_t ctest_signededness_of__Byte(void) { |
41 |
| - Byte all_ones = (Byte) -1; |
42 |
| - return all_ones < 0; |
43 |
| -} |
44 |
| - |
45 |
| -// Return the offset of a struct/union field. |
46 |
| -uint64_t ctest_offset_of__Person__name(void) { |
47 |
| - return offsetof(struct Person, name); |
48 |
| -} |
49 |
| - |
50 |
| -// Return the size of a struct/union field. |
51 |
| -uint64_t ctest_size_of__Person__name(void) { |
52 |
| - return sizeof(((struct Person){}).name); |
53 |
| -} |
54 |
| - |
55 |
| -// Return the offset of a struct/union field. |
56 |
| -uint64_t ctest_offset_of__Person__age(void) { |
57 |
| - return offsetof(struct Person, age); |
58 |
| -} |
59 |
| - |
60 |
| -// Return the size of a struct/union field. |
61 |
| -uint64_t ctest_size_of__Person__age(void) { |
62 |
| - return sizeof(((struct Person){}).age); |
63 |
| -} |
64 |
| - |
65 |
| -// Return the offset of a struct/union field. |
66 |
| -uint64_t ctest_offset_of__Person__job(void) { |
67 |
| - return offsetof(struct Person, job); |
68 |
| -} |
69 |
| - |
70 |
| -// Return the size of a struct/union field. |
71 |
| -uint64_t ctest_size_of__Person__job(void) { |
72 |
| - return sizeof(((struct Person){}).job); |
73 |
| -} |
74 |
| - |
75 |
| -// Return the offset of a struct/union field. |
76 |
| -uint64_t ctest_offset_of__Word__word(void) { |
77 |
| - return offsetof(union Word, word); |
78 |
| -} |
79 |
| - |
80 |
| -// Return the size of a struct/union field. |
81 |
| -uint64_t ctest_size_of__Word__word(void) { |
82 |
| - return sizeof(((union Word){}).word); |
83 |
| -} |
84 |
| - |
85 |
| -// Return the offset of a struct/union field. |
86 |
| -uint64_t ctest_offset_of__Word__byte(void) { |
87 |
| - return offsetof(union Word, byte); |
88 |
| -} |
89 |
| - |
90 |
| -// Return the size of a struct/union field. |
91 |
| -uint64_t ctest_size_of__Word__byte(void) { |
92 |
| - return sizeof(((union Word){}).byte); |
93 |
| -} |
94 |
| - |
95 |
| -// Return a pointer to a struct/union field. |
96 |
| -// This field can have a normal data type, or it could be a function pointer or an array, which |
97 |
| -// have different syntax. A typedef is used for convenience, but the syntax must be precomputed. |
98 |
| -typedef const char **ctest_field_ty__Person__name; |
99 |
| -ctest_field_ty__Person__name |
100 |
| -ctest_field_ptr__Person__name(struct Person *b) { |
101 |
| - return &b->name; |
102 |
| -} |
103 |
| - |
104 |
| -// Return a pointer to a struct/union field. |
105 |
| -// This field can have a normal data type, or it could be a function pointer or an array, which |
106 |
| -// have different syntax. A typedef is used for convenience, but the syntax must be precomputed. |
107 |
| -typedef uint8_t *ctest_field_ty__Person__age; |
108 |
| -ctest_field_ty__Person__age |
109 |
| -ctest_field_ptr__Person__age(struct Person *b) { |
110 |
| - return &b->age; |
111 |
| -} |
112 |
| - |
113 |
| -// Return a pointer to a struct/union field. |
114 |
| -// This field can have a normal data type, or it could be a function pointer or an array, which |
115 |
| -// have different syntax. A typedef is used for convenience, but the syntax must be precomputed. |
116 |
| -typedef void (**ctest_field_ty__Person__job)(uint8_t, const char *); |
117 |
| -ctest_field_ty__Person__job |
118 |
| -ctest_field_ptr__Person__job(struct Person *b) { |
119 |
| - return &b->job; |
120 |
| -} |
121 |
| - |
122 |
| -// Return a pointer to a struct/union field. |
123 |
| -// This field can have a normal data type, or it could be a function pointer or an array, which |
124 |
| -// have different syntax. A typedef is used for convenience, but the syntax must be precomputed. |
125 |
| -typedef uint16_t *ctest_field_ty__Word__word; |
126 |
| -ctest_field_ty__Word__word |
127 |
| -ctest_field_ptr__Word__word(union Word *b) { |
128 |
| - return &b->word; |
129 |
| -} |
130 |
| - |
131 |
| -// Return a pointer to a struct/union field. |
132 |
| -// This field can have a normal data type, or it could be a function pointer or an array, which |
133 |
| -// have different syntax. A typedef is used for convenience, but the syntax must be precomputed. |
134 |
| -typedef Byte (*ctest_field_ty__Word__byte)[2]; |
135 |
| -ctest_field_ty__Word__byte |
136 |
| -ctest_field_ptr__Word__byte(union Word *b) { |
137 |
| - return &b->byte; |
138 |
| -} |
139 |
| - |
140 | 12 | #ifdef _MSC_VER
|
141 | 13 | // Disable signed/unsigned conversion warnings on MSVC.
|
142 | 14 | // These trigger even if the conversion is explicit.
|
143 | 15 | # pragma warning(disable:4365)
|
144 | 16 | #endif
|
145 | 17 |
|
146 |
| -// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust |
147 |
| -// remains unchanged. |
148 |
| -// It checks if the size is the same as well as if the padding bytes are all in the correct place. |
149 |
| -Byte ctest_roundtrip__Byte( |
150 |
| - Byte value, |
151 |
| - const uint8_t is_padding_byte[sizeof(Byte)], |
152 |
| - uint8_t value_bytes[sizeof(Byte)] |
153 |
| -) { |
154 |
| - int size = (int)sizeof(Byte); |
155 |
| - // Mark `p` as volatile so that the C compiler does not optimize away the pattern we create. |
156 |
| - // Otherwise the Rust side would not be able to see it. |
157 |
| - volatile uint8_t* p = (volatile uint8_t*)&value; |
158 |
| - int i = 0; |
159 |
| - for (i = 0; i < size; ++i) { |
160 |
| - // We skip padding bytes in both Rust and C because writing to it is undefined. |
161 |
| - // Instead we just make sure the the placement of the padding bytes remains the same. |
162 |
| - if (is_padding_byte[i]) { continue; } |
163 |
| - value_bytes[i] = p[i]; |
164 |
| - // After we check that the pattern remained unchanged from Rust to C, we invert the pattern |
165 |
| - // and send it back to Rust to make sure that it remains unchanged from C to Rust. |
166 |
| - uint8_t d = (uint8_t)(255) - (uint8_t)(i % 256); |
167 |
| - d = d == 0 ? 42: d; |
168 |
| - p[i] = d; |
169 |
| - } |
170 |
| - return value; |
171 |
| -} |
172 |
| - |
173 |
| -// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust |
174 |
| -// remains unchanged. |
175 |
| -// It checks if the size is the same as well as if the padding bytes are all in the correct place. |
176 |
| -struct Person ctest_roundtrip__Person( |
177 |
| - struct Person value, |
178 |
| - const uint8_t is_padding_byte[sizeof(struct Person)], |
179 |
| - uint8_t value_bytes[sizeof(struct Person)] |
180 |
| -) { |
181 |
| - int size = (int)sizeof(struct Person); |
182 |
| - // Mark `p` as volatile so that the C compiler does not optimize away the pattern we create. |
183 |
| - // Otherwise the Rust side would not be able to see it. |
184 |
| - volatile uint8_t* p = (volatile uint8_t*)&value; |
185 |
| - int i = 0; |
186 |
| - for (i = 0; i < size; ++i) { |
187 |
| - // We skip padding bytes in both Rust and C because writing to it is undefined. |
188 |
| - // Instead we just make sure the the placement of the padding bytes remains the same. |
189 |
| - if (is_padding_byte[i]) { continue; } |
190 |
| - value_bytes[i] = p[i]; |
191 |
| - // After we check that the pattern remained unchanged from Rust to C, we invert the pattern |
192 |
| - // and send it back to Rust to make sure that it remains unchanged from C to Rust. |
193 |
| - uint8_t d = (uint8_t)(255) - (uint8_t)(i % 256); |
194 |
| - d = d == 0 ? 42: d; |
195 |
| - p[i] = d; |
196 |
| - } |
197 |
| - return value; |
198 |
| -} |
199 |
| - |
200 |
| -// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust |
201 |
| -// remains unchanged. |
202 |
| -// It checks if the size is the same as well as if the padding bytes are all in the correct place. |
203 |
| -union Word ctest_roundtrip__Word( |
204 |
| - union Word value, |
205 |
| - const uint8_t is_padding_byte[sizeof(union Word)], |
206 |
| - uint8_t value_bytes[sizeof(union Word)] |
207 |
| -) { |
208 |
| - int size = (int)sizeof(union Word); |
209 |
| - // Mark `p` as volatile so that the C compiler does not optimize away the pattern we create. |
210 |
| - // Otherwise the Rust side would not be able to see it. |
211 |
| - volatile uint8_t* p = (volatile uint8_t*)&value; |
212 |
| - int i = 0; |
213 |
| - for (i = 0; i < size; ++i) { |
214 |
| - // We skip padding bytes in both Rust and C because writing to it is undefined. |
215 |
| - // Instead we just make sure the the placement of the padding bytes remains the same. |
216 |
| - if (is_padding_byte[i]) { continue; } |
217 |
| - value_bytes[i] = p[i]; |
218 |
| - // After we check that the pattern remained unchanged from Rust to C, we invert the pattern |
219 |
| - // and send it back to Rust to make sure that it remains unchanged from C to Rust. |
220 |
| - uint8_t d = (uint8_t)(255) - (uint8_t)(i % 256); |
221 |
| - d = d == 0 ? 42: d; |
222 |
| - p[i] = d; |
223 |
| - } |
224 |
| - return value; |
225 |
| -} |
226 |
| - |
227 | 18 | #ifdef _MSC_VER
|
228 | 19 | # pragma warning(default:4365)
|
229 | 20 | #endif
|
|
0 commit comments