1 /*
2  * Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdnoreturn.h>
22 
23 #include "vacall-internal.h"
24 
25 /* Room for returning structs according to the Sun C non-reentrant struct return convention. */
26 typedef union { __vaword room[__VA_ALIST_WORDS]; double align; } __va_struct_buffer_t;
27 static __va_struct_buffer_t vacall_struct_buffer;
28 
29 static _Noreturn void
vacall_error_type_mismatch(enum __VAtype start_type,enum __VAtype return_type)30 vacall_error_type_mismatch (enum __VAtype start_type, enum __VAtype return_type)
31 {
32   /* If you see this, fix your code. */
33   fprintf (stderr, "vacall: va_start type %d and va_return type %d disagree.\n",
34                    (int)start_type, (int)return_type);
35   abort();
36 }
37 
38 static _Noreturn void
vacall_error_struct_too_large(unsigned int size)39 vacall_error_struct_too_large (unsigned int size)
40 {
41   /* If you see this, increase __VA_ALIST_WORDS: */
42   fprintf (stderr, "vacall: struct of size %u too large for Sun C struct return.\n",
43                    size);
44   abort();
45 }
46 
vacall_start(va_alist list,int rettype,int flags)47 void vacall_start (va_alist list, int rettype, int flags)
48 {
49   __va_start(list,rettype,flags);
50 }
51 
vacall_start_struct(va_alist list,size_t type_size,size_t type_align,int type_splittable,int flags)52 void vacall_start_struct (va_alist list, size_t type_size, size_t type_align, int type_splittable, int flags)
53 {
54   __va_start_struct(list,type_size,type_align,type_splittable,flags);
55 }
56 
vacall_arg_char(va_alist list)57 char vacall_arg_char (va_alist list)
58 {
59   return _va_arg_char(list);
60 }
61 
vacall_arg_schar(va_alist list)62 signed char vacall_arg_schar (va_alist list)
63 {
64   return _va_arg_schar(list);
65 }
66 
vacall_arg_uchar(va_alist list)67 unsigned char vacall_arg_uchar (va_alist list)
68 {
69   return _va_arg_uchar(list);
70 }
71 
vacall_arg_short(va_alist list)72 short vacall_arg_short (va_alist list)
73 {
74   return _va_arg_short(list);
75 }
76 
vacall_arg_ushort(va_alist list)77 unsigned short vacall_arg_ushort (va_alist list)
78 {
79   return _va_arg_ushort(list);
80 }
81 
vacall_arg_int(va_alist list)82 int vacall_arg_int (va_alist list)
83 {
84   return _va_arg_int(list);
85 }
86 
vacall_arg_uint(va_alist list)87 unsigned int vacall_arg_uint (va_alist list)
88 {
89   return _va_arg_uint(list);
90 }
91 
vacall_arg_long(va_alist list)92 long vacall_arg_long (va_alist list)
93 {
94   return _va_arg_long(list);
95 }
96 
vacall_arg_ulong(va_alist list)97 unsigned long vacall_arg_ulong (va_alist list)
98 {
99   return _va_arg_ulong(list);
100 }
101 
vacall_arg_longlong(va_alist list)102 long long vacall_arg_longlong (va_alist list)
103 {
104   return _va_arg_longlong(list);
105 }
106 
vacall_arg_ulonglong(va_alist list)107 unsigned long long vacall_arg_ulonglong (va_alist list)
108 {
109   return _va_arg_ulonglong(list);
110 }
111 
vacall_arg_float(va_alist list)112 float vacall_arg_float (va_alist list)
113 {
114   return _va_arg_float(list);
115 }
116 
vacall_arg_double(va_alist list)117 double vacall_arg_double (va_alist list)
118 {
119   return _va_arg_double(list);
120 }
121 
vacall_arg_ptr(va_alist list)122 void* vacall_arg_ptr (va_alist list)
123 {
124   return _va_arg_ptr(list);
125 }
126 
vacall_arg_struct(va_alist list,size_t type_size,size_t type_align)127 void* vacall_arg_struct (va_alist list, size_t type_size, size_t type_align)
128 {
129   return __va_arg_struct(list,type_size,type_align);
130 }
131 
vacall_return_void(va_alist list)132 void vacall_return_void (va_alist list)
133 {
134   _va_return_void(list);
135 }
136 
vacall_return_char(va_alist list,char val)137 void vacall_return_char (va_alist list, char val)
138 {
139   _va_return_char(list,val);
140 }
141 
vacall_return_schar(va_alist list,signed char val)142 void vacall_return_schar (va_alist list, signed char val)
143 {
144   _va_return_schar(list,val);
145 }
146 
vacall_return_uchar(va_alist list,unsigned char val)147 void vacall_return_uchar (va_alist list, unsigned char val)
148 {
149   _va_return_uchar(list,val);
150 }
151 
vacall_return_short(va_alist list,short val)152 void vacall_return_short (va_alist list, short val)
153 {
154   _va_return_short(list,val);
155 }
156 
vacall_return_ushort(va_alist list,unsigned short val)157 void vacall_return_ushort (va_alist list, unsigned short val)
158 {
159   _va_return_ushort(list,val);
160 }
161 
vacall_return_int(va_alist list,int val)162 void vacall_return_int (va_alist list, int val)
163 {
164   _va_return_int(list,val);
165 }
166 
vacall_return_uint(va_alist list,unsigned int val)167 void vacall_return_uint (va_alist list, unsigned int val)
168 {
169   _va_return_uint(list,val);
170 }
171 
vacall_return_long(va_alist list,long val)172 void vacall_return_long (va_alist list, long val)
173 {
174   _va_return_long(list,val);
175 }
176 
vacall_return_ulong(va_alist list,unsigned long val)177 void vacall_return_ulong (va_alist list, unsigned long val)
178 {
179   _va_return_ulong(list,val);
180 }
181 
vacall_return_longlong(va_alist list,long long val)182 void vacall_return_longlong (va_alist list, long long val)
183 {
184   _va_return_longlong(list,val);
185 }
186 
vacall_return_ulonglong(va_alist list,unsigned long long val)187 void vacall_return_ulonglong (va_alist list, unsigned long long val)
188 {
189   _va_return_ulonglong(list,val);
190 }
191 
vacall_return_float(va_alist list,float val)192 void vacall_return_float (va_alist list, float val)
193 {
194   _va_return_float(list,val);
195 }
196 
vacall_return_double(va_alist list,double val)197 void vacall_return_double (va_alist list, double val)
198 {
199   _va_return_double(list,val);
200 }
201 
vacall_return_ptr(va_alist list,void * val)202 void vacall_return_ptr (va_alist list, void* val)
203 {
204   _va_return_ptr(list,val);
205 }
206 
vacall_return_struct(va_alist list,size_t type_size,size_t type_align,const void * val_addr)207 void vacall_return_struct (va_alist list, size_t type_size, size_t type_align, const void* val_addr)
208 {
209   __va_return_struct(list,type_size,type_align,val_addr);
210 }
211