summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/inline_api.h12
-rw-r--r--include/asterisk/utils.h29
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).
*