Commit | Line | Data |
---|---|---|
b48daf6d C |
1 | /* This is just like the default gvarargs.h |
2 | except for differences described below. */ | |
3 | ||
4 | /* Define __gnuc_va_list. */ | |
5 | ||
6 | #ifndef __GNUC_VA_LIST | |
7 | #define __GNUC_VA_LIST | |
8 | ||
9 | #ifndef __svr4__ | |
10 | /* This has to be a char * to be compatible with Sun. | |
11 | i.e., we have to pass a `va_list' to vsprintf. */ | |
12 | typedef char * __gnuc_va_list; | |
13 | #else | |
14 | /* This has to be a void * to be compatible with Sun svr4. | |
15 | i.e., we have to pass a `va_list' to vsprintf. */ | |
16 | typedef void * __gnuc_va_list; | |
17 | #endif | |
18 | #endif /* not __GNUC_VA_LIST */ | |
19 | ||
20 | /* If this is for internal libc use, don't define anything but | |
21 | __gnuc_va_list. */ | |
22 | #if defined (_STDARG_H) || defined (_VARARGS_H) | |
23 | ||
24 | /* In GCC version 2, we want an ellipsis at the end of the declaration | |
25 | of the argument list. GCC version 1 can't parse it. */ | |
26 | ||
27 | #if __GNUC__ > 1 | |
28 | #define __va_ellipsis ... | |
29 | #else | |
30 | #define __va_ellipsis | |
31 | #endif | |
32 | ||
33 | #ifdef _STDARG_H | |
34 | #define va_start(AP, LASTARG) \ | |
35 | (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ())) | |
36 | #else | |
37 | #define va_alist __builtin_va_alist | |
38 | /* The ... causes current_function_varargs to be set in cc1. */ | |
39 | #define va_dcl int __builtin_va_alist; __va_ellipsis | |
40 | ||
41 | #define va_start(AP) \ | |
42 | (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist)) | |
43 | #endif | |
44 | ||
45 | #ifndef va_end | |
46 | void va_end (__gnuc_va_list); /* Defined in libgcc.a */ | |
47 | #endif | |
48 | #define va_end(pvar) | |
49 | ||
50 | #define __va_rounded_size(TYPE) \ | |
51 | (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) | |
52 | ||
53 | /* Avoid errors if compiling GCC v2 with GCC v1. */ | |
54 | #if __GNUC__ == 1 | |
55 | #define __extension__ | |
56 | #endif | |
57 | ||
58 | /* RECORD_TYPE args passed using the C calling convention are | |
59 | passed by invisible reference. ??? RECORD_TYPE args passed | |
60 | in the stack are made to be word-aligned; for an aggregate that is | |
61 | not word-aligned, we advance the pointer to the first non-reg slot. */ | |
62 | /* We don't declare the union member `d' to have type TYPE | |
63 | because that would lose in C++ if TYPE has a constructor. */ | |
64 | /* We cast to void * and then to TYPE * because this avoids | |
65 | a warning about increasing the alignment requirement. */ | |
66 | #define va_arg(pvar,TYPE) \ | |
67 | __extension__ \ | |
68 | ({ TYPE __va_temp; \ | |
69 | ((__builtin_classify_type (__va_temp) >= 12) \ | |
70 | ? ((pvar) += __va_rounded_size (TYPE *), \ | |
71 | **(TYPE **) (void *) ((pvar) - __va_rounded_size (TYPE *))) \ | |
72 | : __va_rounded_size (TYPE) == 8 \ | |
73 | ? ({ union {char __d[sizeof (TYPE)]; int __i[2];} __u; \ | |
74 | __u.__i[0] = ((int *) (void *) (pvar))[0]; \ | |
75 | __u.__i[1] = ((int *) (void *) (pvar))[1]; \ | |
76 | (pvar) += 8; \ | |
77 | *(TYPE *) (void *) __u.__d; }) \ | |
78 | : ((pvar) += __va_rounded_size (TYPE), \ | |
79 | *((TYPE *) (void *) ((pvar) - __va_rounded_size (TYPE)))));}) | |
80 | ||
81 | #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ | |
82 |