Matt Turner | 976464c | 2014-09-21 18:14:01 -0700 | [diff] [blame] | 1 | # =========================================================================== |
| 2 | # http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html |
| 3 | # =========================================================================== |
| 4 | # |
| 5 | # SYNOPSIS |
| 6 | # |
| 7 | # AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) |
| 8 | # |
| 9 | # DESCRIPTION |
| 10 | # |
| 11 | # This macro checks if the compiler supports one of GCC's function |
| 12 | # attributes; many other compilers also provide function attributes with |
| 13 | # the same syntax. Compiler warnings are used to detect supported |
| 14 | # attributes as unsupported ones are ignored by default so quieting |
| 15 | # warnings when using this macro will yield false positives. |
| 16 | # |
| 17 | # The ATTRIBUTE parameter holds the name of the attribute to be checked. |
| 18 | # |
| 19 | # If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>. |
| 20 | # |
| 21 | # The macro caches its result in the ax_cv_have_func_attribute_<attribute> |
| 22 | # variable. |
| 23 | # |
| 24 | # The macro currently supports the following function attributes: |
| 25 | # |
| 26 | # alias |
| 27 | # aligned |
| 28 | # alloc_size |
| 29 | # always_inline |
| 30 | # artificial |
| 31 | # cold |
| 32 | # const |
| 33 | # constructor |
| 34 | # deprecated |
| 35 | # destructor |
| 36 | # dllexport |
| 37 | # dllimport |
| 38 | # error |
| 39 | # externally_visible |
| 40 | # flatten |
| 41 | # format |
| 42 | # format_arg |
| 43 | # gnu_inline |
| 44 | # hot |
| 45 | # ifunc |
| 46 | # leaf |
| 47 | # malloc |
| 48 | # noclone |
| 49 | # noinline |
| 50 | # nonnull |
| 51 | # noreturn |
| 52 | # nothrow |
| 53 | # optimize |
| 54 | # packed |
| 55 | # pure |
| 56 | # unused |
| 57 | # used |
| 58 | # visibility |
| 59 | # warning |
| 60 | # warn_unused_result |
| 61 | # weak |
| 62 | # weakref |
| 63 | # |
| 64 | # Unsuppored function attributes will be tested with a prototype returning |
| 65 | # an int and not accepting any arguments and the result of the check might |
| 66 | # be wrong or meaningless so use with care. |
| 67 | # |
| 68 | # LICENSE |
| 69 | # |
| 70 | # Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com> |
| 71 | # |
| 72 | # Copying and distribution of this file, with or without modification, are |
| 73 | # permitted in any medium without royalty provided the copyright notice |
| 74 | # and this notice are preserved. This file is offered as-is, without any |
| 75 | # warranty. |
| 76 | |
| 77 | #serial 2 |
| 78 | |
| 79 | AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ |
| 80 | AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) |
| 81 | |
| 82 | AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ |
| 83 | AC_LINK_IFELSE([AC_LANG_PROGRAM([ |
| 84 | m4_case([$1], |
| 85 | [alias], [ |
| 86 | int foo( void ) { return 0; } |
| 87 | int bar( void ) __attribute__(($1("foo"))); |
| 88 | ], |
| 89 | [aligned], [ |
| 90 | int foo( void ) __attribute__(($1(32))); |
| 91 | ], |
| 92 | [alloc_size], [ |
| 93 | void *foo(int a) __attribute__(($1(1))); |
| 94 | ], |
| 95 | [always_inline], [ |
| 96 | inline __attribute__(($1)) int foo( void ) { return 0; } |
| 97 | ], |
| 98 | [artificial], [ |
| 99 | inline __attribute__(($1)) int foo( void ) { return 0; } |
| 100 | ], |
| 101 | [cold], [ |
| 102 | int foo( void ) __attribute__(($1)); |
| 103 | ], |
| 104 | [const], [ |
| 105 | int foo( void ) __attribute__(($1)); |
| 106 | ], |
| 107 | [constructor], [ |
| 108 | int foo( void ) __attribute__(($1)); |
| 109 | ], |
| 110 | [deprecated], [ |
| 111 | int foo( void ) __attribute__(($1(""))); |
| 112 | ], |
| 113 | [destructor], [ |
| 114 | int foo( void ) __attribute__(($1)); |
| 115 | ], |
| 116 | [dllexport], [ |
| 117 | __attribute__(($1)) int foo( void ) { return 0; } |
| 118 | ], |
| 119 | [dllimport], [ |
| 120 | int foo( void ) __attribute__(($1)); |
| 121 | ], |
| 122 | [error], [ |
| 123 | int foo( void ) __attribute__(($1(""))); |
| 124 | ], |
| 125 | [externally_visible], [ |
| 126 | int foo( void ) __attribute__(($1)); |
| 127 | ], |
| 128 | [flatten], [ |
| 129 | int foo( void ) __attribute__(($1)); |
| 130 | ], |
| 131 | [format], [ |
| 132 | int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); |
| 133 | ], |
| 134 | [format_arg], [ |
| 135 | char *foo(const char *p) __attribute__(($1(1))); |
| 136 | ], |
| 137 | [gnu_inline], [ |
| 138 | inline __attribute__(($1)) int foo( void ) { return 0; } |
| 139 | ], |
| 140 | [hot], [ |
| 141 | int foo( void ) __attribute__(($1)); |
| 142 | ], |
| 143 | [ifunc], [ |
| 144 | int my_foo( void ) { return 0; } |
| 145 | static int (*resolve_foo(void))(void) { return my_foo; } |
| 146 | int foo( void ) __attribute__(($1("resolve_foo"))); |
| 147 | ], |
| 148 | [leaf], [ |
| 149 | __attribute__(($1)) int foo( void ) { return 0; } |
| 150 | ], |
| 151 | [malloc], [ |
| 152 | void *foo( void ) __attribute__(($1)); |
| 153 | ], |
| 154 | [noclone], [ |
| 155 | int foo( void ) __attribute__(($1)); |
| 156 | ], |
| 157 | [noinline], [ |
| 158 | __attribute__(($1)) int foo( void ) { return 0; } |
| 159 | ], |
| 160 | [nonnull], [ |
| 161 | int foo(char *p) __attribute__(($1(1))); |
| 162 | ], |
| 163 | [noreturn], [ |
| 164 | void foo( void ) __attribute__(($1)); |
| 165 | ], |
| 166 | [nothrow], [ |
| 167 | int foo( void ) __attribute__(($1)); |
| 168 | ], |
| 169 | [optimize], [ |
| 170 | __attribute__(($1(3))) int foo( void ) { return 0; } |
| 171 | ], |
| 172 | [packed], [ |
| 173 | struct __attribute__(($1)) foo { int bar; }; |
| 174 | ], |
| 175 | [pure], [ |
| 176 | int foo( void ) __attribute__(($1)); |
| 177 | ], |
| 178 | [unused], [ |
| 179 | int foo( void ) __attribute__(($1)); |
| 180 | ], |
| 181 | [used], [ |
| 182 | int foo( void ) __attribute__(($1)); |
| 183 | ], |
| 184 | [visibility], [ |
| 185 | int foo_def( void ) __attribute__(($1("default"))); |
| 186 | int foo_hid( void ) __attribute__(($1("hidden"))); |
| 187 | int foo_int( void ) __attribute__(($1("internal"))); |
| 188 | int foo_pro( void ) __attribute__(($1("protected"))); |
| 189 | ], |
| 190 | [warning], [ |
| 191 | int foo( void ) __attribute__(($1(""))); |
| 192 | ], |
| 193 | [warn_unused_result], [ |
| 194 | int foo( void ) __attribute__(($1)); |
| 195 | ], |
| 196 | [weak], [ |
| 197 | int foo( void ) __attribute__(($1)); |
| 198 | ], |
| 199 | [weakref], [ |
| 200 | static int foo( void ) { return 0; } |
| 201 | static int bar( void ) __attribute__(($1("foo"))); |
| 202 | ], |
| 203 | [ |
| 204 | m4_warn([syntax], [Unsupported attribute $1, the test may fail]) |
| 205 | int foo( void ) __attribute__(($1)); |
| 206 | ] |
| 207 | )], []) |
| 208 | ], |
| 209 | dnl GCC doesn't exit with an error if an unknown attribute is |
| 210 | dnl provided but only outputs a warning, so accept the attribute |
| 211 | dnl only if no warning were issued. |
| 212 | [AS_IF([test -s conftest.err], |
| 213 | [AS_VAR_SET([ac_var], [no])], |
| 214 | [AS_VAR_SET([ac_var], [yes])])], |
| 215 | [AS_VAR_SET([ac_var], [no])]) |
| 216 | ]) |
| 217 | |
| 218 | AS_IF([test yes = AS_VAR_GET([ac_var])], |
| 219 | [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, |
| 220 | [Define to 1 if the system has the `$1' function attribute])], []) |
| 221 | |
| 222 | AS_VAR_POPDEF([ac_var]) |
| 223 | ]) |