1
0
mirror of git://jb55.com/damus synced 2024-09-16 10:13:45 +00:00
damus/damus-c/compiler.h
William Casarin dbe1260b54 damus-c: add bolt11 parser from CLN
We'll need this for our lightning invoice view

Signed-off-by: William Casarin <jb55@jb55.com>
2022-10-19 07:45:06 -07:00

318 lines
8.0 KiB
C

/* CC0 (Public domain) - see LICENSE file for details */
#ifndef CCAN_COMPILER_H
#define CCAN_COMPILER_H
#include "config.h"
#ifndef COLD
#if HAVE_ATTRIBUTE_COLD
/**
* COLD - a function is unlikely to be called.
*
* Used to mark an unlikely code path and optimize appropriately.
* It is usually used on logging or error routines.
*
* Example:
* static void COLD moan(const char *reason)
* {
* fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
* }
*/
#define COLD __attribute__((__cold__))
#else
#define COLD
#endif
#endif
#ifndef NORETURN
#if HAVE_ATTRIBUTE_NORETURN
/**
* NORETURN - a function does not return
*
* Used to mark a function which exits; useful for suppressing warnings.
*
* Example:
* static void NORETURN fail(const char *reason)
* {
* fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
* exit(1);
* }
*/
#define NORETURN __attribute__((__noreturn__))
#else
#define NORETURN
#endif
#endif
#ifndef PRINTF_FMT
#if HAVE_ATTRIBUTE_PRINTF
/**
* PRINTF_FMT - a function takes printf-style arguments
* @nfmt: the 1-based number of the function's format argument.
* @narg: the 1-based number of the function's first variable argument.
*
* This allows the compiler to check your parameters as it does for printf().
*
* Example:
* void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...);
*/
#define PRINTF_FMT(nfmt, narg) \
__attribute__((format(__printf__, nfmt, narg)))
#else
#define PRINTF_FMT(nfmt, narg)
#endif
#endif
#ifndef CONST_FUNCTION
#if HAVE_ATTRIBUTE_CONST
/**
* CONST_FUNCTION - a function's return depends only on its argument
*
* This allows the compiler to assume that the function will return the exact
* same value for the exact same arguments. This implies that the function
* must not use global variables, or dereference pointer arguments.
*/
#define CONST_FUNCTION __attribute__((__const__))
#else
#define CONST_FUNCTION
#endif
#ifndef PURE_FUNCTION
#if HAVE_ATTRIBUTE_PURE
/**
* PURE_FUNCTION - a function is pure
*
* A pure function is one that has no side effects other than it's return value
* and uses no inputs other than it's arguments and global variables.
*/
#define PURE_FUNCTION __attribute__((__pure__))
#else
#define PURE_FUNCTION
#endif
#endif
#endif
#if HAVE_ATTRIBUTE_UNUSED
#ifndef UNNEEDED
/**
* UNNEEDED - a variable/function may not be needed
*
* This suppresses warnings about unused variables or functions, but tells
* the compiler that if it is unused it need not emit it into the source code.
*
* Example:
* // With some preprocessor options, this is unnecessary.
* static UNNEEDED int counter;
*
* // With some preprocessor options, this is unnecessary.
* static UNNEEDED void add_to_counter(int add)
* {
* counter += add;
* }
*/
#define UNNEEDED __attribute__((__unused__))
#endif
#ifndef NEEDED
#if HAVE_ATTRIBUTE_USED
/**
* NEEDED - a variable/function is needed
*
* This suppresses warnings about unused variables or functions, but tells
* the compiler that it must exist even if it (seems) unused.
*
* Example:
* // Even if this is unused, these are vital for debugging.
* static NEEDED int counter;
* static NEEDED void dump_counter(void)
* {
* printf("Counter is %i\n", counter);
* }
*/
#define NEEDED __attribute__((__used__))
#else
/* Before used, unused functions and vars were always emitted. */
#define NEEDED __attribute__((__unused__))
#endif
#endif
#ifndef UNUSED
/**
* UNUSED - a parameter is unused
*
* Some compilers (eg. gcc with -W or -Wunused) warn about unused
* function parameters. This suppresses such warnings and indicates
* to the reader that it's deliberate.
*
* Example:
* // This is used as a callback, so needs to have this prototype.
* static int some_callback(void *unused UNUSED)
* {
* return 0;
* }
*/
#define UNUSED __attribute__((__unused__))
#endif
#else
#ifndef UNNEEDED
#define UNNEEDED
#endif
#ifndef NEEDED
#define NEEDED
#endif
#ifndef UNUSED
#define UNUSED
#endif
#endif
#ifndef IS_COMPILE_CONSTANT
#if HAVE_BUILTIN_CONSTANT_P
/**
* IS_COMPILE_CONSTANT - does the compiler know the value of this expression?
* @expr: the expression to evaluate
*
* When an expression manipulation is complicated, it is usually better to
* implement it in a function. However, if the expression being manipulated is
* known at compile time, it is better to have the compiler see the entire
* expression so it can simply substitute the result.
*
* This can be done using the IS_COMPILE_CONSTANT() macro.
*
* Example:
* enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON };
*
* // Out-of-line version.
* const char *greek_name(enum greek greek);
*
* // Inline version.
* static inline const char *_greek_name(enum greek greek)
* {
* switch (greek) {
* case ALPHA: return "alpha";
* case BETA: return "beta";
* case GAMMA: return "gamma";
* case DELTA: return "delta";
* case EPSILON: return "epsilon";
* default: return "**INVALID**";
* }
* }
*
* // Use inline if compiler knows answer. Otherwise call function
* // to avoid copies of the same code everywhere.
* #define greek_name(g) \
* (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g))
*/
#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr)
#else
/* If we don't know, assume it's not. */
#define IS_COMPILE_CONSTANT(expr) 0
#endif
#endif
#ifndef WARN_UNUSED_RESULT
#if HAVE_WARN_UNUSED_RESULT
/**
* WARN_UNUSED_RESULT - warn if a function return value is unused.
*
* Used to mark a function where it is extremely unlikely that the caller
* can ignore the result, eg realloc().
*
* Example:
* // buf param may be freed by this; need return value!
* static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size)
* {
* return realloc(buf, (*size) *= 2);
* }
*/
#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else
#define WARN_UNUSED_RESULT
#endif
#endif
#if HAVE_ATTRIBUTE_DEPRECATED
/**
* WARN_DEPRECATED - warn that a function/type/variable is deprecated when used.
*
* Used to mark a function, type or variable should not be used.
*
* Example:
* WARN_DEPRECATED char *oldfunc(char *buf);
*/
#define WARN_DEPRECATED __attribute__((__deprecated__))
#else
#define WARN_DEPRECATED
#endif
#if HAVE_ATTRIBUTE_NONNULL
/**
* NO_NULL_ARGS - specify that no arguments to this function can be NULL.
*
* The compiler will warn if any pointer args are NULL.
*
* Example:
* NO_NULL_ARGS char *my_copy(char *buf);
*/
#define NO_NULL_ARGS __attribute__((__nonnull__))
/**
* NON_NULL_ARGS - specify that some arguments to this function can't be NULL.
* @...: 1-based argument numbers for which args can't be NULL.
*
* The compiler will warn if any of the specified pointer args are NULL.
*
* Example:
* char *my_copy2(char *buf, char *maybenull) NON_NULL_ARGS(1);
*/
#define NON_NULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__)))
#else
#define NO_NULL_ARGS
#define NON_NULL_ARGS(...)
#endif
#if HAVE_ATTRIBUTE_RETURNS_NONNULL
/**
* RETURNS_NONNULL - specify that this function cannot return NULL.
*
* Mainly an optimization opportunity, but can also suppress warnings.
*
* Example:
* RETURNS_NONNULL char *my_copy(char *buf);
*/
#define RETURNS_NONNULL __attribute__((__returns_nonnull__))
#else
#define RETURNS_NONNULL
#endif
#if HAVE_ATTRIBUTE_SENTINEL
/**
* LAST_ARG_NULL - specify the last argument of a variadic function must be NULL.
*
* The compiler will warn if the last argument isn't NULL.
*
* Example:
* char *join_string(char *buf, ...) LAST_ARG_NULL;
*/
#define LAST_ARG_NULL __attribute__((__sentinel__))
#else
#define LAST_ARG_NULL
#endif
#if HAVE_BUILTIN_CPU_SUPPORTS
/**
* cpu_supports - test if current CPU supports the named feature.
*
* This takes a literal string, and currently only works on glibc platforms.
*
* Example:
* if (cpu_supports("mmx"))
* printf("MMX support engaged!\n");
*/
#define cpu_supports(x) __builtin_cpu_supports(x)
#else
#define cpu_supports(x) 0
#endif /* HAVE_BUILTIN_CPU_SUPPORTS */
#endif /* CCAN_COMPILER_H */