/* This is just like the default gvarargs.h
   except for differences described below.  */

/* Define __gnuc_va_list.  */

#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
#if ! defined (__svr4__) && ! defined (__linux__) && ! defined (__arch64__)
/* This has to be a char * to be compatible with Sun.
   i.e., we have to pass a `va_list' to vsprintf.  */
typedef char * __gnuc_va_list;
#else
/* This has to be a void * to be compatible with Sun svr4.
   i.e., we have to pass a `va_list' to vsprintf.  */
typedef void * __gnuc_va_list;
#endif
#endif /* not __GNUC_VA_LIST */

/* If this is for internal libc use, don't define anything but
   __gnuc_va_list.  */
#if defined (_STDARG_H) || defined (_VARARGS_H)

#define __va_ellipsis ...

#ifdef _STDARG_H
#define va_start(AP, LASTARG) \
 (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
#else
#define va_alist __builtin_va_alist
#define va_dcl int __builtin_va_alist; __va_ellipsis
#define va_start(AP)  AP=(char *) &__builtin_va_alist
#endif

#ifndef va_end
void va_end (__gnuc_va_list);		/* Defined in libgcc.a */

/* Values returned by __builtin_classify_type.  */

enum __va_type_classes {
  __no_type_class = -1,
  __void_type_class,
  __integer_type_class,
  __char_type_class,
  __enumeral_type_class,
  __boolean_type_class,
  __pointer_type_class,
  __reference_type_class,
  __offset_type_class,
  __real_type_class,
  __complex_type_class,
  __function_type_class,
  __method_type_class,
  __record_type_class,
  __union_type_class,
  __array_type_class,
  __string_type_class,
  __set_type_class,
  __file_type_class,
  __lang_type_class
};

#endif
#define va_end(pvar)	((void)0)

/* Avoid errors if compiling GCC v2 with GCC v1.  */
#if __GNUC__ == 1
#define __extension__
#endif

/* Returns 1 if the type is a pointer to something.  */
#define __va_pointer_p(TYPE) \
((__builtin_classify_type(*(TYPE*) 0) >= __pointer_type_class \
  && __builtin_classify_type(*(TYPE*) 0) <= __offset_type_class) || \
 (__builtin_classify_type(*(TYPE*) 0) >= __function_type_class \
  && __builtin_classify_type(*(TYPE*) 0) <= __method_type_class))

#define __va_rounded_size(TYPE)						\
(__va_pointer_p(TYPE) ? (sizeof(TYPE)) : \
  (((sizeof (int) == 2)) ? (((sizeof (TYPE) + 1) / 2) * 2) : \
   (((sizeof (TYPE) + 3) / 4) * 4)))

#define __va_rounded_aggregate_size(TYPE)				\
(((sizeof (TYPE) + 1) / 2) * 2)

#define __va_aggregate_p(TYPE)	(__builtin_classify_type(*(TYPE *)0) >= 12)


#define va_arg(AP,TYPE)							   \
__extension__ (*({							   \
  register TYPE *__ptr;							   \
									   \
  /* Aggregates are passed on the stack.  */				   \
  if (__va_aggregate_p (TYPE))						   \
    {									   \
      __ptr = (TYPE*) (AP);						   \
      (AP) = (__gnuc_va_list) ((char *) (AP)				   \
	     + __va_rounded_aggregate_size (TYPE));			   \
    }									   \
									   \
  /* Only integrals remaining.  */					   \
  else if (sizeof (TYPE) == __va_rounded_size (TYPE))			   \
    {									   \
      __ptr = (TYPE*) (AP);						   \
      (AP) = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE));  \
    }									   \
  else									   \
    {									   \
      (AP) = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE));  \
      __ptr = (TYPE *) ((void *) ((char *) (AP)  			   \
		       - ((sizeof (TYPE) < __va_rounded_size (char)	   \
			   ? sizeof (TYPE) : __va_rounded_size (TYPE))))); \
    }									   \
  __ptr;								   \
}))

/* Copy __gnuc_va_list into another variable of this type.  */
#define __va_copy(dest, src) (dest) = (src)

#endif
