xref: /illumos-gate/usr/src/uts/common/sys/va_impl.h (revision ed22c710)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved	*/
24 
25 
26 /*
27  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #ifndef	_SYS_VA_IMPL_H
32 #define	_SYS_VA_IMPL_H
33 
34 /*
35  * An application should not include this header directly.  Instead it
36  * should be included only through the inclusion of other Sun headers,
37  * specifically <stdarg.h> and <varargs.h>.
38  *
39  * This header serves two purposes.
40  *
41  * First, it provides a common set of definitions that implementations
42  * of the various standards for variable argument lists may use.  These
43  * various standards are implemented in <varargs.h>, <stdarg.h>,
44  * <iso/stdarg_iso.h>, <iso/stdarg_c99.h>, and <sys/varargs.h>.
45  *
46  * Second, it provides varying implementations of the common definitions,
47  * depending upon the compiler.
48  */
49 
50 /*
51  * The common definitions exported by this header or compilers using
52  * this header are:
53  *
54  * the macro __va_start(list, name) starting the list iteration
55  * the macro __va_arg(list, type) getting the current arg and iterating
56  * the macro __va_copy(to, from) to bookmark the list iteration
57  * the macro __va_end(list) to end the iteration
58  *
59  * In addition, the following are exported via inclusion of <sys/va_list.h>:
60  *
61  * the identifier __builtin_va_alist for the variable list pseudo parameter
62  * the type __va_alist_type for the variable list pseudo parameter
63  * the type __va_list defining the type of the variable list iterator
64  */
65 
66 /*
67  * This header uses feature macros (e.g. __BUILTIN_VA_ARG_INCR and
68  * __BUILTIN_VA_STRUCT), compiler macros (e.g. __GNUC__), and processor
69  * macros (e.g. __sparc) to determine the protocol appropriate to the
70  * current compilation.  It is intended that the compilation system
71  * define the feature, processor, and compiler macros, not the user of
72  * the system.
73  */
74 
75 /*
76  * Many compilation systems depend upon the use of special functions
77  * built into the the compilation system to handle variable argument
78  * lists.  These built-in symbols may include one or more of the
79  * following:
80  *
81  *      __builtin_va_alist
82  *      __builtin_va_start
83  *      __builtin_va_arg_incr
84  *      __builtin_stdarg_start
85  *      __builtin_va_end
86  *      __builtin_va_arg
87  *      __builtin_va_copy
88  */
89 
90 /*
91  * The following are defined in <sys/va_list.h>:
92  *
93  *      __va_alist_type
94  *      __va_void()
95  *      __va_ptr_base
96  *      ISA definitions via inclusion of <sys/isa_defs.h>
97  *
98  * Inclusion of this header also makes visible the symbols in <sys/va_list.h>.
99  * This header is included in <varargs.h>, <sys/varargs.h> and in <stdarg.h>
100  * via inclusion of <iso/stdarg_iso.h>.
101  */
102 
103 #include <sys/va_list.h>
104 
105 #ifdef	__cplusplus
106 extern "C" {
107 #endif
108 
109 #if defined(__lint)	/* ---------------------------------------- protocol */
110 
111 #define	__va_start(list, name)	((list) = (__va_list)&name)
112 #define	__va_arg(list, type)	((type *)(list))[0]
113 #define	__va_copy(to, from)	__va_void(((to) = (from)))
114 /*ARGSUSED*/
115 static void __va_end(__va_list list) { __va_end(list); }
116 
117 #elif defined(__BUILTIN_VA_STRUCT)	/* ------------------------ protocol */
118 
119 /* ISA __va_list structures defined in <sys/va_list.h> */
120 
121 #if defined(__STDC__)	/* source language is ISO C or C++ */
122 
123 void __builtin_va_start(__va_list, ...);
124 void *__builtin_va_arg_incr(__va_list, ...);
125 
126 #else	/* source language is K&R C */
127 
128 int __builtin_va_start();
129 char *__builtin_va_arg_incr();
130 
131 #endif	/* source language */
132 
133 #define	__va_start(list, name)	__builtin_va_start(list, 0)
134 #define	__va_arg(list, type)	\
135 	((type *)__builtin_va_arg_incr(list, (type *)0))[0]
136 #define	__va_copy(to, from)	__va_void(((to)[0] = (from)[0]))
137 #define	__va_end(list)		__va_void(0)
138 
139 #elif defined(__BUILTIN_VA_ARG_INCR)	/* ------------------------ protocol */
140 
141 #define	__va_start(list, name)	\
142 	__va_void(((list) = (__va_list)&__builtin_va_alist))
143 #define	__va_arg(list, type)	\
144 	((type *)__builtin_va_arg_incr((type *)(list)))[0]
145 #define	__va_copy(to, from)	__va_void(((to) = (from)))
146 #define	__va_end(list)		__va_void(0)
147 
148 #elif defined(__GNUC__)	&& ((__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || \
149 	(__GNUC__ >= 3))		/* ------------------------ protocol */
150 #if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3))
151 #define	__va_start(list, name)	__builtin_stdarg_start(list, name)
152 #else
153 #define	__va_start(list, name)	__builtin_va_start(list, name)
154 #endif
155 
156 #define	__va_arg(list, type)	__builtin_va_arg(list, type)
157 #define	__va_end(list)		__builtin_va_end(list)
158 #define	__va_copy(to, from)	__builtin_va_copy(to, from)
159 
160 #else					/* ----------------------- protocol */
161 
162 /*
163  * Because we can not predict the compiler protocol for unknown compilers, we
164  * force an error in order to avoid unpredictable behavior. For versions of
165  * gcc 2.95 and earlier, variable argument lists are handled in gcc specific
166  * stdarg.h and varargs.h headers created via the gcc fixincl utility. In
167  * those cases, the gcc headers would override this header.
168  */
169 
170 #error("Unrecognized compiler protocol for variable argument lists")
171 
172 #endif  /* -------------------------------------------------------- protocol */
173 
174 #ifdef	__cplusplus
175 }
176 #endif
177 
178 #endif	/* _SYS_VA_IMPL_H */
179