[PATCH] gmp-h.in: allow build with llvm/clang 2.6: be more C99 friendly
Yann Droneaud
yann at droneaud.fr
Thu Dec 3 18:22:48 CET 2009
# HG changeset patch
# User Yann Droneaud <yann at droneaud.fr>
# Date 1259860889 18000
# Node ID 967d3addb104eda049225b18a7a536e61a7c9ac1
# Parent de804711a76fee0a8c23a647e9fde8e4bb9e5230
gmp-h.in: allow build with llvm/clang 2.6: be more C99 friendly
clang pretend to be GCC 4.2.1 but don't behave like it regarding
inline in C99 mode. It really sticks to the standard.
See: http://www.greenend.org.uk/rjk/2003/03/inline.html
In this example, one of the declarations does not mention inline:
// a declaration mentioning extern and inline
int max(int a, int b);
// a definition mentioning inline
inline int max(int a, int b) {
return a > b ? a : b;
}
In either example, the function will be callable from other files.
Having an inline definition plus a prototype make clang exporting
the function in each object built.
This patch try to handle C99 as a generic as possible, and it works
for gcc 4.4 and llvm/clang 2.6.
But this patch could be a problem for others compilers.
So it must be carefully reviewed, and problably not applied asis.
diff -r de804711a76f -r 967d3addb104 gmp-h.in
--- a/gmp-h.in Thu Dec 03 11:15:09 2009 -0500
+++ b/gmp-h.in Thu Dec 03 12:21:29 2009 -0500
@@ -415,19 +415,26 @@
inline" would be an acceptable substitute if the compiler (or linker)
discards unused statics. */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+# define __GMP_EXTERN_INLINE inline
+# ifndef __GMP_INLINE_PROTOTYPES
+# undef __GMP_INLINE_PROTOTYPES
+# endif
+#else
+
/* gcc has __inline__ in all modes, including strict ansi. Give a prototype
for an inline too, so as to correctly specify "dllimport" on windows, in
case the function is called rather than inlined.
GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
inline semantics, unless -fgnu89-inline is used. */
-#ifdef __GNUC__
-#if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2)
-#define __GMP_EXTERN_INLINE extern __inline__ __attribute__ ((__gnu_inline__))
-#else
-#define __GMP_EXTERN_INLINE extern __inline__
-#endif
-#define __GMP_INLINE_PROTOTYPES 1
-#endif
+# ifdef __GNUC__
+# if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2)
+# define __GMP_EXTERN_INLINE extern __inline__ __attribute__ ((__gnu_inline__))
+# else
+# define __GMP_EXTERN_INLINE extern __inline__
+# endif
+# define __GMP_INLINE_PROTOTYPES 1
+# endif
/* DEC C (eg. version 5.9) supports "static __inline foo()", even in -std1
strict ANSI mode. Inlining is done even when not optimizing (ie. -O0
@@ -437,9 +444,9 @@
but which is inlined within its file. Don't know if all old versions of
DEC C supported __inline, but as a start let's do the right thing for
current versions. */
-#ifdef __DECC
-#define __GMP_EXTERN_INLINE static __inline
-#endif
+# ifdef __DECC
+# define __GMP_EXTERN_INLINE static __inline
+# endif
/* SCO OpenUNIX 8 cc supports "static inline foo()" but not in -Xc strict
ANSI mode (__STDC__ is 1 in that mode). Inlining only actually takes
@@ -448,30 +455,31 @@
"extern" is apparently ignored, so foo is inlined if possible but also
emitted as a global, which causes multiple definition errors when
building a shared libgmp. */
-#ifdef __SCO_VERSION__
-#if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \
- && ! defined (__GMP_EXTERN_INLINE)
-#define __GMP_EXTERN_INLINE static inline
-#endif
-#endif
+# ifdef __SCO_VERSION__
+# if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \
+ && ! defined (__GMP_EXTERN_INLINE)
+# define __GMP_EXTERN_INLINE static inline
+# endif
+# endif
/* Microsoft's C compiler accepts __inline */
-#ifdef _MSC_VER
-#define __GMP_EXTERN_INLINE __inline
-#endif
+# ifdef _MSC_VER
+# define __GMP_EXTERN_INLINE __inline
+# endif
/* Recent enough Sun C compilers accept "extern inline" */
-#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560 \
- && ! defined (__GMP_EXTERN_INLINE)
-#define __GMP_EXTERN_INLINE extern inline
-#endif
+# if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560 \
+ && ! defined (__GMP_EXTERN_INLINE)
+# define __GMP_EXTERN_INLINE extern inline
+# endif
/* Somewhat older Sun C compilers accept "static inline" */
-#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540 \
- && ! defined (__GMP_EXTERN_INLINE)
-#define __GMP_EXTERN_INLINE static inline
-#endif
+# if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540 \
+ && ! defined (__GMP_EXTERN_INLINE)
+# define __GMP_EXTERN_INLINE static inline
+# endif
+#endif /* __STDC_VERSION__ */
/* C++ always has "inline" and since it's a normal feature the linker should
discard duplicate non-inlined copies, or if it doesn't then that's a
More information about the gmp-devel
mailing list