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 2014 Garrett D'Amore <garrett@damore.org>
  28  *
  29  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  30  * Use is subject to license terms.
  31  */
  32 
  33 #ifndef _SYS_VA_IMPL_H
  34 #define _SYS_VA_IMPL_H
  35 
  36 /*
  37  * An application should not include this header directly.  Instead it
  38  * should be included only through the inclusion of other Sun headers,
  39  * specifically <stdarg.h> and <varargs.h>.
  40  *
  41  * This header serves two purposes.
  42  *
  43  * First, it provides a common set of definitions that implementations
  44  * of the various standards for variable argument lists may use.  These
  45  * various standards are implemented in <varargs.h>, <stdarg.h>,
  46  * <iso/stdarg_iso.h>, <iso/stdarg_c99.h>, and <sys/varargs.h>.
  47  *
  48  * Second, it provides varying implementations of the common definitions,
  49  * depending upon the compiler.
  50  */
  51 
  52 /*
  53  * The common definitions exported by this header or compilers using
  54  * this header are:
  55  *
  56  * the macro __va_start(list, name) starting the list iteration
  57  * the macro __va_arg(list, type) getting the current arg and iterating
  58  * the macro __va_copy(to, from) to bookmark the list iteration
  59  * the macro __va_end(list) to end the iteration
  60  *
  61  * In addition, the following are exported via inclusion of <sys/va_list.h>:
  62  *
  63  * the identifier __builtin_va_alist for the variable list pseudo parameter
  64  * the type __va_alist_type for the variable list pseudo parameter
  65  * the type __va_list defining the type of the variable list iterator
  66  */
  67 
  68 /*
  69  * This header uses feature macros (e.g. __BUILTIN_VA_ARG_INCR and
  70  * __BUILTIN_VA_STRUCT), compiler macros (e.g. __GNUC__), and processor
  71  * macros (e.g. __sparc) to determine the protocol appropriate to the
  72  * current compilation.  It is intended that the compilation system
  73  * define the feature, processor, and compiler macros, not the user of
  74  * the system.
  75  */
  76 
  77 /*
  78  * Many compilation systems depend upon the use of special functions
  79  * built into the the compilation system to handle variable argument
  80  * lists.  These built-in symbols may include one or more of the
  81  * following:
  82  *
  83  *      __builtin_va_alist
  84  *      __builtin_va_start
  85  *      __builtin_va_arg_incr
  86  *      __builtin_stdarg_start
  87  *      __builtin_va_end
  88  *      __builtin_va_arg
  89  *      __builtin_va_copy
  90  */
  91 
  92 /*
  93  * The following are defined in <sys/va_list.h>:
  94  *
  95  *      __va_alist_type
  96  *      __va_void()
  97  *      __va_ptr_base
  98  *      ISA definitions via inclusion of <sys/isa_defs.h>
  99  *
 100  * Inclusion of this header also makes visible the symbols in <sys/va_list.h>.
 101  * This header is included in <varargs.h>, <sys/varargs.h> and in <stdarg.h>
 102  * via inclusion of <iso/stdarg_iso.h>.
 103  */
 104 
 105 #include <sys/va_list.h>
 106 
 107 #ifdef  __cplusplus
 108 extern "C" {
 109 #endif
 110 
 111 #if defined(__lint)     /* ---------------------------------------- protocol */
 112 
 113 #define __va_start(list, name)  ((list) = (__va_list)&name)
 114 #define __va_arg(list, type)    ((type *)(list))[0]
 115 #define __va_copy(to, from)     __va_void(((to) = (from)))
 116 /*ARGSUSED*/
 117 static void __va_end(__va_list list) { __va_end(list); }
 118 
 119 #elif defined(__BUILTIN_VA_STRUCT)      /* ------------------------ protocol */
 120 
 121 /* ISA __va_list structures defined in <sys/va_list.h> */
 122 
 123 void __builtin_va_start(__va_list, ...);
 124 void *__builtin_va_arg_incr(__va_list, ...);
 125 
 126 #define __va_start(list, name)  __builtin_va_start(list, 0)
 127 #define __va_arg(list, type)    \
 128         ((type *)__builtin_va_arg_incr(list, (type *)0))[0]
 129 #define __va_copy(to, from)     __va_void(((to)[0] = (from)[0]))
 130 #define __va_end(list)          __va_void(0)
 131 
 132 #elif defined(__BUILTIN_VA_ARG_INCR)    /* ------------------------ protocol */
 133 
 134 #define __va_start(list, name)  \
 135         __va_void(((list) = (__va_list)&__builtin_va_alist))
 136 #define __va_arg(list, type)    \
 137         ((type *)__builtin_va_arg_incr((type *)(list)))[0]
 138 #define __va_copy(to, from)     __va_void(((to) = (from)))
 139 #define __va_end(list)          __va_void(0)
 140 
 141 #elif defined(__GNUC__) && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || \
 142         (__GNUC__ >= 3))             /* ------------------------ protocol */
 143 #if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3))
 144 #define __va_start(list, name)  __builtin_stdarg_start(list, name)
 145 #else
 146 #define __va_start(list, name)  __builtin_va_start(list, name)
 147 #endif
 148 
 149 #define __va_arg(list, type)    __builtin_va_arg(list, type)
 150 #define __va_end(list)          __builtin_va_end(list)
 151 #define __va_copy(to, from)     __builtin_va_copy(to, from)
 152 
 153 #else                                   /* ----------------------- protocol */
 154 
 155 /*
 156  * Because we can not predict the compiler protocol for unknown compilers, we
 157  * force an error in order to avoid unpredictable behavior. For versions of
 158  * gcc 2.95 and earlier, variable argument lists are handled in gcc specific
 159  * stdarg.h and varargs.h headers created via the gcc fixincl utility. In
 160  * those cases, the gcc headers would override this header.
 161  */
 162 
 163 #error("Unrecognized compiler protocol for variable argument lists")
 164 
 165 #endif  /* -------------------------------------------------------- protocol */
 166 
 167 #ifdef  __cplusplus
 168 }
 169 #endif
 170 
 171 #endif  /* _SYS_VA_IMPL_H */