]>
Commit | Line | Data |
---|---|---|
f3db20a3 | 1 | /* This is just like the default gvarargs.h |
6dc42e49 | 2 | except for differences described below. */ |
f3db20a3 RS |
3 | |
4 | /* Make this a macro rather than a typedef, so we can undef any other defn. */ | |
5 | #define va_list __va___list | |
69d6c854 | 6 | #ifndef __svr4__ |
f3db20a3 RS |
7 | /* This has to be a char * to be compatible with Sun. |
8 | i.e., we have to pass a `va_list' to vsprintf. */ | |
9 | typedef char * __va___list; | |
69d6c854 RS |
10 | #else |
11 | /* This has to be a void * to be compatible with Sun svr4. | |
12 | i.e., we have to pass a `va_list' to vsprintf. */ | |
13 | typedef void * __va___list; | |
14 | #endif | |
f3db20a3 RS |
15 | |
16 | /* In GCC version 2, we want an ellipsis at the end of the declaration | |
17 | of the argument list. GCC version 1 can't parse it. */ | |
18 | ||
19 | #if __GNUC__ > 1 | |
20 | #define __va_ellipsis ... | |
21 | #else | |
22 | #define __va_ellipsis | |
23 | #endif | |
24 | ||
5840cf94 JW |
25 | #ifdef _STDARG_H |
26 | #define va_start(AP, LASTARG) \ | |
27 | (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ())) | |
28 | #else | |
168c4006 RS |
29 | #define va_alist __builtin_va_alist |
30 | /* The ... causes current_function_varargs to be set in cc1. */ | |
31 | #define va_dcl int __builtin_va_alist; __va_ellipsis | |
32 | ||
f3db20a3 RS |
33 | #define va_start(AP) \ |
34 | (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist)) | |
5840cf94 JW |
35 | #endif |
36 | ||
f3db20a3 RS |
37 | #define va_end(pvar) |
38 | ||
39 | #define __va_rounded_size(TYPE) \ | |
40 | (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) | |
41 | ||
cc8995d5 RS |
42 | /* Avoid errors if compiling GCC v2 with GCC v1. */ |
43 | #if __GNUC__ == 1 | |
44 | #define __extension__ | |
45 | #endif | |
46 | ||
f3db20a3 RS |
47 | /* RECORD_TYPE args passed using the C calling convention are |
48 | passed by invisible reference. ??? RECORD_TYPE args passed | |
49 | in the stack are made to be word-aligned; for an aggregate that is | |
50 | not word-aligned, we advance the pointer to the first non-reg slot. */ | |
5c96a037 RS |
51 | /* We don't declare the union member `d' to have type TYPE |
52 | because that would lose in C++ if TYPE has a constructor. */ | |
f3db20a3 | 53 | #define va_arg(pvar,TYPE) \ |
e13d81d0 | 54 | __extension__ \ |
f3db20a3 RS |
55 | ({ TYPE __va_temp; \ |
56 | ((__builtin_classify_type (__va_temp) >= 12) \ | |
57 | ? ((pvar) += __va_rounded_size (TYPE *), \ | |
5840cf94 | 58 | **(TYPE **) ((pvar) - __va_rounded_size (TYPE *))) \ |
81359be5 | 59 | : __va_rounded_size (TYPE) == 8 \ |
5c96a037 RS |
60 | ? ({ union {char __d[sizeof (TYPE)]; int __i[2];} __u; \ |
61 | __u.__i[0] = ((int *) (pvar))[0]; \ | |
62 | __u.__i[1] = ((int *) (pvar))[1]; \ | |
81359be5 | 63 | (pvar) += 8; \ |
5c96a037 | 64 | *(TYPE *)__u.__d; }) \ |
5840cf94 | 65 | : ((pvar) += __va_rounded_size (TYPE), \ |
f3db20a3 | 66 | *((TYPE *) ((pvar) - __va_rounded_size (TYPE)))));}) |