There are several significant differences between the mingw32 (gcc 4.3.0 based) compiler and the GCC 4.4 and later compilers.
Mingw32 requires that types int, long, long long, unsigned { int, long, long long}, float, and double be the only types passed to va_arg(). This requires the programmer to ensure that va_arg is called with type int for arguments of any type with a size less-than or equal-to int. GCC 4.4 and later does not require this and performs the appropriate promotions for you.
Mingw32 uses 32-bit long in both ia32 and x64 mode. GCC 4.4 makes long a 64-bit value when in x64 mode.
Signed-off-by: darylm503
Reviewed-by: jcarsey
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12258
6f19259b-4bc3-4df7-8a09-
765794883524
#define __POINTER_BIT 64\r
\r
#if defined(__GNUC__)\r
-#define __LONG_BIT 64\r
-/** minimum value for an object of type long int **/\r
-#define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 1)\r
+#if __GNUC_PREREQ__(4,4)\r
+ #define __LONG_BIT 64\r
\r
-/** maximum value for an object of type long int **/\r
-#define __LONG_MAX +9223372036854775807LL // 2^63 - 1\r
+ /** minimum value for an object of type long int **/\r
+ #define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 2)\r
\r
-/** maximum value for an object of type unsigned long int **/\r
-#define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1\r
+ /** maximum value for an object of type long int **/\r
+ #define __LONG_MAX (9223372036854775807LL) // 2^63 - 1\r
+\r
+ /** maximum value for an object of type unsigned long int **/\r
+ #define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1\r
#else\r
+ #define __LONG_BIT 32\r
+ /** minimum value for an object of type long int **/\r
+ #define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1)\r
+\r
+ /** maximum value for an object of type long int **/\r
+ #define __LONG_MAX 2147483647L // 2^31 - 1\r
+\r
+ /** maximum value for an object of type unsigned long int **/\r
+ #define __ULONG_MAX 0xffffffff // 2^32 - 1\r
+#endif\r
+\r
+\r
+#else /* NOT defined(__GNUC__) */\r
#define __LONG_BIT 32\r
/** minimum value for an object of type long int **/\r
#define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1)\r
\r
/** maximum value for an object of type long int **/\r
-#define __LONG_MAX +2147483647L // 2^31 - 1\r
+#define __LONG_MAX 2147483647L // 2^31 - 1\r
\r
/** maximum value for an object of type unsigned long int **/\r
#define __ULONG_MAX 0xffffffff // 2^32 - 1\r
/** @file\r
Machine dependent type definitions.\r
\r
- Portions Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available\r
- under the terms and conditions of the BSD License that accompanies this\r
- distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
#include <sys/EfiCdefs.h>\r
#include <machine/int_types.h>\r
\r
-/* Handle the long and unsigned long data types which EFI doesn't directly support. */\r
-//typedef long int LONGN; // 32-bit\r
-//typedef long unsigned int ULONGN; // 32-bit\r
-\r
typedef PHYSICAL_ADDRESS paddr_t;\r
typedef UINT64 psize_t;\r
typedef PHYSICAL_ADDRESS vaddr_t;\r
//#define _EFI_WINT_MIN (0)\r
//#define _EFI_WINT_MAX (0xFFFF)\r
#define _EFI_PTRDIFF_T_ __PTRDIFF_TYPE__ /* ptr1 - ptr2 --- Must be same size as size_t */\r
+\r
#else\r
#define _EFI_SIZE_T_ UINTN /* sizeof() */\r
#define _EFI_WCHAR_T UINT16\r
#define _DIAGASSERT(e)\r
\r
// Types used to replace long so that it will have constant length regardless of compiler.\r
-typedef INT32 EFI_LONG_T; // Equivalent to long in VS200?\r
-typedef UINT32 EFI_ULONG_T; // Equivalent to unsigned long in VS200?\r
-typedef INTN LONGN;\r
-typedef UINTN ULONGN;\r
-typedef INT32 LONG32;\r
+typedef INT32 LONG32;\r
typedef UINT32 ULONG32;\r
typedef INT64 LONG64;\r
typedef UINT64 ULONG64;\r
\r
+typedef INT32 EFI_LONG_T;\r
+typedef UINT32 EFI_ULONG_T;\r
+\r
+/* These types reflect the compiler's size for long */\r
+#if defined(__GNUC__)\r
+ #if __GNUC_PREREQ__(4,4)\r
+ /* GCC 4.4 or later */\r
+ typedef INT64 LONGN;\r
+ typedef UINT64 ULONGN;\r
+ #else\r
+ /* minGW gcc variant */\r
+ typedef INT32 LONGN;\r
+ typedef UINT32 ULONGN;\r
+ #endif /* __GNUC_PREREQ__(4,4) */\r
+#else /* NOT GCC */\r
+ /* Microsoft or Intel compilers */\r
+ typedef INT32 LONGN;\r
+ typedef UINT32 ULONGN;\r
+#endif /* defined(__GNUC__) */\r
+\r
#endif /* _EFI_CDEFS_H */\r
\r
mbs = initial;\r
mbseqlen = wcrtomb(buf,\r
- (wchar_t)GETARG(wint_t), &mbs);\r
+ /* The compiler "knows" that wint_t may be smaller than an int so\r
+ it warns about it when used as the type argument to va_arg().\r
+ Since any type of parameter smaller than an int is promoted to an int on a\r
+ function call, we must call GETARG with type int instead of wint_t.\r
+ */\r
+ (wchar_t)GETARG(int), &mbs);\r
if (mbseqlen == (size_t)-1) {\r
fp->_flags |= __SERR;\r
goto error;\r
}\r
#else\r
if (flags & LONGINT)\r
- *buf = (wchar_t)GETARG(wint_t);\r
+ *buf = (wchar_t)GETARG(int);\r
else\r
*buf = (wchar_t)btowc(GETARG(int));\r
size = 1;\r
(*argtable) [n].pvoidarg = va_arg (ap, void *);\r
break;\r
case T_WINT:\r
- (*argtable) [n].wintarg = va_arg (ap, wint_t);\r
+ (*argtable) [n].wintarg = va_arg (ap, int);\r
break;\r
case TP_WCHAR:\r
(*argtable) [n].pwchararg = va_arg (ap, wchar_t *);\r