summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/va_impl.h
blob: d11a65640bc475cdef94de833e931c05ca4b59b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved	*/


/*
 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
 *
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_VA_IMPL_H
#define	_SYS_VA_IMPL_H

/*
 * An application should not include this header directly.  Instead it
 * should be included only through the inclusion of other Sun headers,
 * specifically <stdarg.h> and <varargs.h>.
 *
 * This header serves two purposes.
 *
 * First, it provides a common set of definitions that implementations
 * of the various standards for variable argument lists may use.  These
 * various standards are implemented in <varargs.h>, <stdarg.h>,
 * <iso/stdarg_iso.h>, <iso/stdarg_c99.h>, and <sys/varargs.h>.
 *
 * Second, it provides varying implementations of the common definitions,
 * depending upon the compiler.
 */

/*
 * The common definitions exported by this header or compilers using
 * this header are:
 *
 * the macro __va_start(list, name) starting the list iteration
 * the macro __va_arg(list, type) getting the current arg and iterating
 * the macro __va_copy(to, from) to bookmark the list iteration
 * the macro __va_end(list) to end the iteration
 *
 * In addition, the following are exported via inclusion of <sys/va_list.h>:
 *
 * the identifier __builtin_va_alist for the variable list pseudo parameter
 * the type __va_alist_type for the variable list pseudo parameter
 * the type __va_list defining the type of the variable list iterator
 */

/*
 * This header uses feature macros (e.g. __BUILTIN_VA_ARG_INCR and
 * __BUILTIN_VA_STRUCT), compiler macros (e.g. __GNUC__), and processor
 * macros (e.g. __sparc) to determine the protocol appropriate to the
 * current compilation.  It is intended that the compilation system
 * define the feature, processor, and compiler macros, not the user of
 * the system.
 */

/*
 * Many compilation systems depend upon the use of special functions
 * built into the the compilation system to handle variable argument
 * lists.  These built-in symbols may include one or more of the
 * following:
 *
 *      __builtin_va_alist
 *      __builtin_va_start
 *      __builtin_va_arg_incr
 *      __builtin_stdarg_start
 *      __builtin_va_end
 *      __builtin_va_arg
 *      __builtin_va_copy
 */

/*
 * The following are defined in <sys/va_list.h>:
 *
 *      __va_alist_type
 *      __va_void()
 *      __va_ptr_base
 *      ISA definitions via inclusion of <sys/isa_defs.h>
 *
 * Inclusion of this header also makes visible the symbols in <sys/va_list.h>.
 * This header is included in <varargs.h>, <sys/varargs.h> and in <stdarg.h>
 * via inclusion of <iso/stdarg_iso.h>.
 */

#include <sys/va_list.h>

#ifdef	__cplusplus
extern "C" {
#endif

#if defined(__lint)	/* ---------------------------------------- protocol */

#define	__va_start(list, name)	((list) = (__va_list)&name)
#define	__va_arg(list, type)	((type *)(list))[0]
#define	__va_copy(to, from)	__va_void(((to) = (from)))
/*ARGSUSED*/
static void __va_end(__va_list list) { __va_end(list); }

#elif defined(__BUILTIN_VA_STRUCT)	/* ------------------------ protocol */

/* ISA __va_list structures defined in <sys/va_list.h> */

void __builtin_va_start(__va_list, ...);
void *__builtin_va_arg_incr(__va_list, ...);

#define	__va_start(list, name)	__builtin_va_start(list, 0)
#define	__va_arg(list, type)	\
	((type *)__builtin_va_arg_incr(list, (type *)0))[0]
#define	__va_copy(to, from)	__va_void(((to)[0] = (from)[0]))
#define	__va_end(list)		__va_void(0)

#elif defined(__BUILTIN_VA_ARG_INCR)	/* ------------------------ protocol */

#define	__va_start(list, name)	\
	__va_void(((list) = (__va_list)&__builtin_va_alist))
#define	__va_arg(list, type)	\
	((type *)__builtin_va_arg_incr((type *)(list)))[0]
#define	__va_copy(to, from)	__va_void(((to) = (from)))
#define	__va_end(list)		__va_void(0)

#elif defined(__GNUC__)	&& ((__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || \
	(__GNUC__ >= 3))		/* ------------------------ protocol */
#if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3))
#define	__va_start(list, name)	__builtin_stdarg_start(list, name)
#else
#define	__va_start(list, name)	__builtin_va_start(list, name)
#endif

#define	__va_arg(list, type)	__builtin_va_arg(list, type)
#define	__va_end(list)		__builtin_va_end(list)
#define	__va_copy(to, from)	__builtin_va_copy(to, from)

#else					/* ----------------------- protocol */

/*
 * Because we can not predict the compiler protocol for unknown compilers, we
 * force an error in order to avoid unpredictable behavior. For versions of
 * gcc 2.95 and earlier, variable argument lists are handled in gcc specific
 * stdarg.h and varargs.h headers created via the gcc fixincl utility. In
 * those cases, the gcc headers would override this header.
 */

#error("Unrecognized compiler protocol for variable argument lists")

#endif  /* -------------------------------------------------------- protocol */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_VA_IMPL_H */