8
8
#include < stdint .h >
9
9
#include < stdio .h >
10
10
11
- {%- for header in self .headers + %}
11
+ {%- for header in self .headers .keys () + %}
12
+ {%- for define in self .headers [header ] + %}
12
13
14
+ #define {{ define }}
15
+ {%- endfor + %}
13
16
#include <{{ header }}>
17
+ {%- for define in self .headers [header ] + %}
18
+ #undef {{ define }}
19
+ {%- endfor + %}
14
20
{%- endfor + %}
15
21
22
+ #if defined(__cplusplus )
23
+ #define CTEST_ALIGNOF (T ) alignof(T)
24
+ #else
25
+ #define CTEST_ALIGNOF (T ) _Alignof(T)
26
+ #endif
27
+
16
28
typedef void (* ctest_void_func )(void );
17
29
18
30
{%- for const_cstr in ctx .const_cstr_tests + %}
@@ -21,7 +33,7 @@ static char *ctest_const_{{ const_cstr.id }}_val_static = {{ const_cstr.c_val }}
21
33
22
34
// Define a function that returns a pointer to the value of the constant to test.
23
35
// This will later be called on the Rust side via FFI.
24
- char * ctest_const_cstr__ {{ const_cstr .id }}(void ) {
36
+ {{ self . linkage }} char * ctest_const_cstr__ {{ const_cstr .id }}(void ) {
25
37
return ctest_const_ {{ const_cstr .id }}_val_static ;
26
38
}
27
39
{%- endfor + %}
@@ -32,25 +44,25 @@ static {{ constant.c_ty }} ctest_const_{{ constant.id }}_val_static = {{ constan
32
44
33
45
// Define a function that returns a pointer to the value of the constant to test.
34
46
// This will later be called on the Rust side via FFI.
35
- {{ constant .c_ty }} * ctest_const__ {{ constant .id }}(void ) {
47
+ {{ self . linkage }}{{ constant .c_ty }} * ctest_const__ {{ constant .id }}(void ) {
36
48
return & ctest_const_ {{ constant .id }}_val_static ;
37
49
}
38
50
{%- endfor + %}
39
51
40
52
{%- for item in ctx .size_align_tests + %}
41
53
42
54
// Return the size of a type.
43
- uint64_t ctest_size_of__ {{ item .id }}(void ) { return sizeof ({{ item .c_ty }}); }
55
+ {{ self . linkage }} uint64_t ctest_size_of__ {{ item .id }}(void ) { return sizeof ({{ item .c_ty }}); }
44
56
45
57
// Return the alignment of a type.
46
- uint64_t ctest_align_of__ {{ item .id }}(void ) { return _Alignof ({{ item .c_ty }}); }
58
+ {{ self . linkage }} uint64_t ctest_align_of__ {{ item .id }}(void ) { return CTEST_ALIGNOF ({{ item .c_ty }}); }
47
59
{%- endfor + %}
48
60
49
61
{%- for alias in ctx .signededness_tests + %}
50
62
51
63
// Return `1` if the type is signed, otherwise return `0`.
52
64
// Casting -1 to the aliased type if signed evaluates to `-1 < 0`, if unsigned to `MAX_VALUE < 0`
53
- uint32_t ctest_signededness_of__ {{ alias .id }}(void ) {
65
+ {{ self . linkage }} uint32_t ctest_signededness_of__ {{ alias .id }}(void ) {
54
66
{{ alias .c_ty }} all_ones = ({{ alias .c_ty }}) - 1 ;
55
67
return all_ones < 0 ;
56
68
}
@@ -59,12 +71,12 @@ uint32_t ctest_signededness_of__{{ alias.id }}(void) {
59
71
{%- for item in ctx .field_size_offset_tests + %}
60
72
61
73
// Return the offset of a struct/union field.
62
- uint64_t ctest_offset_of__ {{ item .id }}__ {{ item .field .ident () }}(void ) {
74
+ {{ self . linkage }} uint64_t ctest_offset_of__ {{ item .id }}__ {{ item .field .ident () }}(void ) {
63
75
return offsetof({{ item .c_ty }}, {{ item .c_field }});
64
76
}
65
77
66
78
// Return the size of a struct/union field.
67
- uint64_t ctest_size_of__ {{ item .id }}__ {{ item .field .ident () }}(void ) {
79
+ {{ self . linkage }} uint64_t ctest_size_of__ {{ item .id }}__ {{ item .field .ident () }}(void ) {
68
80
return sizeof ((({{ item .c_ty }}){}).{{ item .c_field }});
69
81
}
70
82
{%- endfor + %}
@@ -75,7 +87,7 @@ uint64_t ctest_size_of__{{ item.id }}__{{ item.field.ident() }}(void) {
75
87
// This field can have a normal data type, or it could be a function pointer or an array, which
76
88
// have different syntax. A typedef is used for convenience, but the syntax must be precomputed.
77
89
typedef {{ item .volatile_keyword }}{{ item .field_return_type }};
78
- ctest_field_ty__ {{ item .id }}__ {{ item .field .ident () }}
90
+ {{ self . linkage }} ctest_field_ty__ {{ item .id }}__ {{ item .field .ident () }}
79
91
ctest_field_ptr__ {{ item .id }}__ {{ item .field .ident () }}({{ item .c_ty }} * b ) {
80
92
return & b -> {{ item .c_field }};
81
93
}
@@ -92,7 +104,7 @@ ctest_field_ptr__{{ item.id }}__{{ item.field.ident() }}({{ item.c_ty }} *b) {
92
104
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
93
105
// remains unchanged.
94
106
// It checks if the size is the same as well as if the padding bytes are all in the correct place.
95
- {{ item .c_ty }} ctest_roundtrip__ {{ item .id }}(
107
+ {{ self . linkage }}{{ item .c_ty }} ctest_roundtrip__ {{ item .id }}(
96
108
{{ item .c_ty }} value ,
97
109
const uint8_t is_padding_byte [sizeof ({{ item .c_ty }})],
98
110
uint8_t value_bytes [sizeof ({{ item .c_ty }})]
@@ -130,7 +142,8 @@ ctest_field_ptr__{{ item.id }}__{{ item.field.ident() }}({{ item.c_ty }} *b) {
130
142
131
143
{%- for item in ctx .foreign_fn_tests + %}
132
144
133
- ctest_void_func ctest_foreign_fn__ {{ item .id }}(void ) {
145
+ // Return a function pointer.
146
+ {{ self .linkage }}ctest_void_func ctest_foreign_fn__ {{ item .id }}(void ) {
134
147
return (ctest_void_func ){{ item .c_val }};
135
148
}
136
149
{%- endfor + %}
@@ -142,7 +155,7 @@ ctest_void_func ctest_foreign_fn__{{ item.id }}(void) {
142
155
{%- for static_ in ctx .foreign_static_tests + %}
143
156
144
157
// Return a pointer to the static variable content.
145
- void * ctest_static__ {{ static_ .id }}(void ) {
158
+ {{ self . linkage }} void * ctest_static__ {{ static_ .id }}(void ) {
146
159
// FIXME(ctest): Not correct due to casting the function to a data pointer.
147
160
return (void * )& {{ static_ .c_val }};
148
161
}
0 commit comments