diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk/inline_api.h | 12 | ||||
-rw-r--r-- | include/asterisk/utils.h | 29 |
2 files changed, 34 insertions, 7 deletions
diff --git a/include/asterisk/inline_api.h b/include/asterisk/inline_api.h index 5f6911d36..d76dfa0a5 100644 --- a/include/asterisk/inline_api.h +++ b/include/asterisk/inline_api.h @@ -25,12 +25,14 @@ Small API functions that are candidates for inlining need to be specially declared and defined, to ensure that the 'right thing' always happens. For example: - - there must _always_ be a non-inlined version of the function + - there must _always_ be a non-inlined version of the function available for modules compiled out of the tree to link to - references to a function that cannot be inlined (for any reason that the compiler deems proper) must devolve into an 'extern' reference, instead of 'static', so that multiple - copies of the function body are not built in different modules + copies of the function body are not built in different modules. + However, since this doesn't work for clang, we go with 'static' + anyway and hope for the best! - when LOW_MEMORY is defined, inlining should be disabled completely, even if the compiler is configured to support it @@ -46,8 +48,12 @@ #if !defined(LOW_MEMORY) && !defined(DISABLE_INLINE) #if !defined(AST_API_MODULE) +#if defined(__clang__) +#define AST_INLINE_API(hdr, body) static hdr; static inline hdr body +#else /* if defined(__clang__) */ #define AST_INLINE_API(hdr, body) hdr; extern inline hdr body -#else +#endif +#else /* if !defined(AST_API_MODULE) */ #define AST_INLINE_API(hdr, body) hdr; hdr body #endif diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index a0e7cb6bf..1dc351d0a 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -1005,12 +1005,33 @@ char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size); * } * \endcode */ -#define RAII_VAR(vartype, varname, initval, dtor) \ - /* Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774 */ \ - auto void _dtor_ ## varname (vartype * v); \ - void _dtor_ ## varname (vartype * v) { dtor(*v); } \ + +#if defined(__clang__) + +#if defined(__has_feature) && __has_feature(blocks) +typedef void (^_raii_cleanup_block_t)(void); +static inline void _raii_cleanup_block(_raii_cleanup_block_t *b) { (*b)(); } + +#define RAII_VAR(vartype, varname, initval, dtor) \ + _raii_cleanup_block_t _raii_cleanup_ ## varname __attribute__((cleanup(_raii_cleanup_block),unused)) = NULL; \ + vartype varname = initval; \ + _raii_cleanup_ ## varname = ^{ dtor(varname); } + +#else + #error "CLANG must support the 'blocks' feature to compile Asterisk." +#endif /* #if defined(__has_feature) && __has_feature(blocks) */ + +#elif defined(__GNUC__) + +#define RAII_VAR(vartype, varname, initval, dtor) \ + auto void _dtor_ ## varname (vartype * v); \ + void _dtor_ ## varname (vartype * v) { dtor(*v); } \ vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval) +#else + #error "Cannot compile Asterisk: unknown and unsupported compiler." +#endif /* #if __GNUC__ */ + /*! * \brief Asterisk wrapper around crypt(3). * |