[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