Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add useful attributes supported by supported compilers #1784

Merged
merged 5 commits into from
Jun 3, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 215 additions & 7 deletions hal/api/toolchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,214 @@
#ifndef MBED_TOOLCHAIN_H
#define MBED_TOOLCHAIN_H


// Warning for unsupported compilers
#if !defined(__GNUC__) /* GCC */ \
&& !defined(__CC_ARM) /* ARMCC */ \
&& !defined(__clang__) /* LLVM/Clang */ \
&& !defined(__ICCARM__) /* IAR */
#warning "This compiler is not yet supported."
#endif


// Attributes

/** MBED_PACKED
* Pack a structure, preventing any padding from being added between fields.
*
* @code
* #include "toolchain.h"
*
* MBED_PACKED(struct) foo {
* char x;
* int y;
* };
* @endcode
*/
#ifndef MBED_PACKED
#if defined(__ICCARM__)
#define MBED_PACKED(struct) __packed struct
#else
#define MBED_PACKED(struct) struct __attribute__((packed))
#endif
#endif

/** MBED_ALIGN(N)
* Declare a variable to be aligned on an N-byte boundary.
*
* @code
* #include "toolchain.h"
*
* MBED_ALIGN(16) char a;
* @endcode
*/
#ifndef MBED_ALIGN
#if defined(__ICCARM__)
#define _MBED_ALIGN(N) _Pragma(#N)
#define MBED_ALIGN(N) _MBED_ALIGN(data_alignment=N)
#else
#define MBED_ALIGN(N) __attribute__((aligned(N)))
#endif
#endif

/** MBED_UNUSED
* Declare a function argument to be unused, suppressing compiler warnings
*
* @code
* #include "toolchain.h"
*
* void foo(MBED_UNUSED int arg) {
*
* }
* @endcode
*/
#ifndef MBED_UNUSED
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#define MBED_UNUSED __attribute__((__unused__))
#else
#define MBED_UNUSED
#endif
#endif

/** MBED_WEAK
* Mark a function as being weak.
*
* @note
* weak functions are not friendly to making code re-usable, as they can only
* be overridden once (and if they are multiply overridden the linker will emit
* no warning). You should not normally use weak symbols as part of the API to
* re-usable modules.
*
* @code
* #include "toolchain.h"
*
* MBED_WEAK void foo() {
* // a weak implementation of foo that can be overriden by a definition
* // without __weak
* }
* @endcode
*/
#ifndef MBED_WEAK
#if defined(__ICCARM__)
#define MBED_WEAK __weak
#else
#define MBED_WEAK __attribute__((weak))
#endif
#endif

/** MBED_PURE
* Hint to the compiler that a function depends only on parameters
*
* @code
* #include "toolchain.h"
*
* MBED_PURE int foo(int arg){
* // no access to global variables
* }
* @endcode
*/
#ifndef MBED_PURE
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#define MBED_PURE __attribute__((const))
#else
#define MBED_PURE
#endif
#endif

/** MBED_FORCEINLINE
* Declare a function that must always be inlined. Failure to inline
* such a function will result in an error.
*
* @code
* #include "toolchain.h"
*
* MBED_FORCEINLINE void foo() {
*
* }
* @endcode
*/
#ifndef MBED_FORCEINLINE
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#define MBED_FORCEINLINE static inline __attribute__((always_inline))
#elif defined(__ICCARM__)
#define MBED_FORCEINLINE _Pragma("inline=forced") static
#else
#define MBED_FORCEINLINE static inline
#endif
#endif

/** MBED_NORETURN
* Declare a function that will never return.
*
* @code
* #include "toolchain.h"
*
* MBED_NORETURN void foo() {
* // must never return
* while (1) {}
* }
* @endcode
*/
#ifndef MBED_NORETURN
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#define MBED_NORETURN __attribute__((noreturn))
#elif defined(__ICCARM__)
#define MBED_NORETURN __noreturn
#else
#define MBED_NORETURN
#endif
#endif

/** MBED_UNREACHABLE
* An unreachable statement. If the statement is reached,
* behaviour is undefined. Useful in situations where the compiler
* cannot deduce the unreachability of code.
*
* @code
* #include "toolchain.h"
*
* void foo(int arg) {
* switch (arg) {
* case 1: return 1;
* case 2: return 2;
* ...
* }
* MBED_UNREACHABLE;
* }
* @endcode
*/
#ifndef MBED_UNREACHABLE
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
#define MBED_UNREACHABLE __builtin_unreachable()
#else
#define MBED_UNREACHABLE while (1)
#endif
#endif

/** MBED_DEPRECATED("message string")
* Mark a function declaration as deprecated, if it used then a warning will be
* issued by the compiler possibly including the provided message. Note that not
* all compilers are able to display the message.
*
* @code
* #include "toolchain.h"
*
* MBED_DEPRECATED("don't foo any more, bar instead")
* void foo(int arg);
* @endcode
*/
#ifndef MBED_DEPRECATED
#if defined(__GNUC__) || defined(__clang__)
#define MBED_DEPRECATED(M) __attribute__((deprecated(M)))
#elif defined(__CC_ARM)
#define MBED_DEPRECATED(M) __attribute__((deprecated))
#else
#define MBED_DEPRECATED(M)
#endif
#endif


// FILEHANDLE declaration
#if defined(TOOLCHAIN_ARM)
#include <rt_sys.h>
#endif
Expand All @@ -24,15 +232,15 @@
typedef int FILEHANDLE;
#endif

#if defined (__ICCARM__)
# define WEAK __weak
# define PACKED __packed
#else
# define WEAK __attribute__((weak))
# define PACKED __attribute__((packed))
// Backwards compatibility
#ifndef WEAK
#define WEAK MBED_WEAK
#endif

#ifndef PACKED
#define PACKED MBED_PACKED()
#endif

// Backwards compatibility
#ifndef EXTERN
#define EXTERN extern
#endif
Expand Down