1 /* -*- coding: utf-8 -*- 2 * ---------------------------------------------------------------------- 3 * Copyright © 2011, RedJack, LLC. 4 * All rights reserved. 5 * 6 * Please see the COPYING file in this distribution for license 7 * details. 8 * ---------------------------------------------------------------------- 9 */ 10 11 #ifndef LIBCORK_CORE_ATTRIBUTES_H 12 #define LIBCORK_CORE_ATTRIBUTES_H 13 14 #include <libcork/config.h> 15 16 17 /* 18 * Declare a “const” function. 19 * 20 * A const function is one whose return value depends only on its 21 * parameters. This is slightly more strict than a “pure” function; a 22 * const function is not allowed to read from global variables, whereas 23 * a pure function is. 24 * 25 * int square(int x) CORK_ATTR_CONST; 26 */ 27 28 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 29 #define CORK_ATTR_CONST __attribute__((const)) 30 #else 31 #define CORK_ATTR_CONST 32 #endif 33 34 35 /* 36 * Declare a “pure” function. 37 * 38 * A pure function is one whose return value depends only on its 39 * parameters, and global variables. 40 * 41 * int square(int x) CORK_ATTR_PURE; 42 */ 43 44 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 45 #define CORK_ATTR_PURE __attribute__((pure)) 46 #else 47 #define CORK_ATTR_PURE 48 #endif 49 50 51 /* 52 * Declare that a function returns a newly allocated pointer. 53 * 54 * The compiler can use this information to generate more accurate 55 * aliasing information, since it can infer that the result of the 56 * function cannot alias any other existing pointer. 57 */ 58 59 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 60 #define CORK_ATTR_MALLOC __attribute__((malloc)) 61 #else 62 #define CORK_ATTR_MALLOC 63 #endif 64 65 66 /* 67 * Declare that a function shouldn't be inlined. 68 */ 69 70 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 71 #define CORK_ATTR_NOINLINE __attribute__((noinline)) 72 #else 73 #define CORK_ATTR_NOINLINE 74 #endif 75 76 77 /* 78 * Declare an entity that isn't used. 79 * 80 * This lets you keep -Wall activated in several cases where you're 81 * obligated to define something that you don't intend to use. 82 */ 83 84 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 85 #define CORK_ATTR_UNUSED __attribute__((unused)) 86 #else 87 #define CORK_ATTR_UNUSED 88 #endif 89 90 91 /* 92 * Declare a function that takes in printf-like parameters. 93 * 94 * When the compiler supports this attribute, it will check the format 95 * string, and the following arguments, to make sure that they match. 96 * format_index and args_index are 1-based. 97 */ 98 99 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 100 #define CORK_ATTR_PRINTF(format_index, args_index) \ 101 __attribute__((format(printf, format_index, args_index))) 102 #else 103 #define CORK_ATTR_PRINTF(format_index, args_index) 104 #endif 105 106 107 /* 108 * Declare a var-arg function whose last parameter must be a NULL 109 * sentinel value. 110 * 111 * When the compiler supports this attribute, it will check the actual 112 * parameters whenever this function is called, and ensure that the last 113 * parameter is a @c NULL. 114 */ 115 116 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 117 #define CORK_ATTR_SENTINEL __attribute__((sentinel)) 118 #else 119 #define CORK_ATTR_SENTINEL 120 #endif 121 122 123 /* 124 * Declare that a boolean expression is likely to be true or false. 125 */ 126 127 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 128 #define CORK_LIKELY(expr) __builtin_expect((expr), 1) 129 #define CORK_UNLIKELY(expr) __builtin_expect((expr), 0) 130 #else 131 #define CORK_LIKELY(expr) (expr) 132 #define CORK_UNLIKELY(expr) (expr) 133 #endif 134 135 /* 136 * Declare that a function is part of the current library's public API, or that 137 * it's internal to the current library. 138 */ 139 140 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES && !defined(__CYGWIN__) && !defined(__MINGW32__) 141 #define CORK_EXPORT __attribute__((visibility("default"))) 142 #define CORK_IMPORT __attribute__((visibility("default"))) 143 #define CORK_LOCAL __attribute__((visibility("hidden"))) 144 #else 145 #define CORK_EXPORT 146 #define CORK_IMPORT 147 #define CORK_LOCAL 148 #endif 149 150 151 /* 152 * Declare a static function that should automatically be called at program 153 * startup. 154 */ 155 156 /* TODO: When we implement a full Windows port, [1] describes how best to 157 * implement an initialization function under Visual Studio. 158 * 159 * [1] http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc 160 */ 161 162 #if CORK_CONFIG_HAVE_GCC_ATTRIBUTES 163 #define CORK_INITIALIZER(name) \ 164 __attribute__((constructor)) \ 165 static void \ 166 name(void) 167 #else 168 #error "Don't know how to implement initialization functions of this platform" 169 #endif 170 171 172 #endif /* LIBCORK_CORE_ATTRIBUTES_H */ 173