* polluting the namespace with lots of stuff...
*
*
- * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/c.h
#define WIN32
#endif
-#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */
+#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */
#include "pg_config_os.h" /* must be before any system header files */
#endif
#include "pg_config_os.h"
#endif
+/*
+ * Force disable inlining if PG_FORCE_DISABLE_INLINE is defined. This is used
+ * to work around compiler bugs and might also be useful for investigatory
+ * purposes by defining the symbol in the platform's header..
+ *
+ * This is done early (in slightly the wrong section) as functionality later
+ * in this file might want to rely on inline functions.
+ */
+#ifdef PG_FORCE_DISABLE_INLINE
+#undef inline
+#define inline
+#endif
+
/* Must be before gettext() games below */
#include <locale.h>
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
+ * CppAsString2
+ * Convert the argument to a string, after one round of macro expansion.
* CppConcat
* Concatenate two arguments together, using the C preprocessor.
*
* backward compatibility with existing PostgreSQL code.
*/
#define CppAsString(identifier) #identifier
+#define CppAsString2(x) CppAsString(x)
#define CppConcat(x, y) x##y
/*
#define dummyret char
#endif
-#ifndef __GNUC__
-#define __attribute__(_arg_)
+/* Which __func__ symbol do we have, if any? */
+#ifdef HAVE_FUNCNAME__FUNC
+#define PG_FUNCNAME_MACRO __func__
+#else
+#ifdef HAVE_FUNCNAME__FUNCTION
+#define PG_FUNCNAME_MACRO __FUNCTION__
+#else
+#define PG_FUNCNAME_MACRO NULL
+#endif
#endif
/* ----------------------------------------------------------------
#ifndef false
#define false ((bool) 0)
#endif
-#endif /* not C++ */
+#endif /* not C++ */
typedef bool *BoolPtr;
typedef signed char int8; /* == 8 bits */
typedef signed short int16; /* == 16 bits */
typedef signed int int32; /* == 32 bits */
-#endif /* not HAVE_INT8 */
+#endif /* not HAVE_INT8 */
/*
* uintN
typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* == 32 bits */
-#endif /* not HAVE_UINT8 */
+#endif /* not HAVE_UINT8 */
/*
* bitsN
#define INT64_FORMAT "%" INT64_MODIFIER "d"
#define UINT64_FORMAT "%" INT64_MODIFIER "u"
-/* Select timestamp representation (float8 or int64) */
-#ifdef USE_INTEGER_DATETIMES
-#define HAVE_INT64_TIMESTAMP
+/*
+ * 128-bit signed and unsigned integers
+ * There currently is only a limited support for the type. E.g. 128bit
+ * literals and snprintf are not supported; but math is.
+ */
+#if defined(PG_INT128_TYPE)
+#define HAVE_INT128
+typedef PG_INT128_TYPE int128;
+typedef unsigned PG_INT128_TYPE uint128;
#endif
-/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
-#ifndef HAVE_SIG_ATOMIC_T
-typedef int sig_atomic_t;
-#endif
+/*
+ * stdint.h limits aren't guaranteed to be present and aren't guaranteed to
+ * have compatible types with our fixed width types. So just define our own.
+ */
+#define PG_INT8_MIN (-0x7F-1)
+#define PG_INT8_MAX (0x7F)
+#define PG_UINT8_MAX (0xFF)
+#define PG_INT16_MIN (-0x7FFF-1)
+#define PG_INT16_MAX (0x7FFF)
+#define PG_UINT16_MAX (0xFFFF)
+#define PG_INT32_MIN (-0x7FFFFFFF-1)
+#define PG_INT32_MAX (0x7FFFFFFF)
+#define PG_UINT32_MAX (0xFFFFFFFF)
+#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
+#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
+#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF)
+
+/*
+ * We now always use int64 timestamps, but keep this symbol defined for the
+ * benefit of external code that might test it.
+ */
+#define HAVE_INT64_TIMESTAMP
/*
* Size
typedef struct
{
int indx[MAXDIM];
-} IntArray;
+} IntArray;
/* ----------------
* Variable-length datatypes all share the 'struct varlena' header.
* may be compressed or moved out-of-line. However datatype-specific routines
* are mostly content to deal with de-TOASTed values only, and of course
* client-side routines should never see a TOASTed value. But even in a
- * de-TOASTed value, beware of touching vl_len_ directly, as its representation
- * is no longer convenient. It's recommended that code always use the VARDATA,
- * VARSIZE, and SET_VARSIZE macros instead of relying on direct mentions of
- * the struct fields. See postgres.h for details of the TOASTed form.
+ * de-TOASTed value, beware of touching vl_len_ directly, as its
+ * representation is no longer convenient. It's recommended that code always
+ * use macros VARDATA_ANY, VARSIZE_ANY, VARSIZE_ANY_EXHDR, VARDATA, VARSIZE,
+ * and SET_VARSIZE instead of relying on direct mentions of the struct fields.
+ * See postgres.h for details of the TOASTed form.
* ----------------
*/
struct varlena
{
char vl_len_[4]; /* Do not touch this field directly! */
- char vl_dat[1];
+ char vl_dat[FLEXIBLE_ARRAY_MEMBER]; /* Data content is here */
};
#define VARHDRSZ ((int32) sizeof(int32))
/*
* These widely-used datatypes are just a varlena header and the data bytes.
* There is no terminating null or anything like that --- the data length is
- * always VARSIZE(ptr) - VARHDRSZ.
+ * always VARSIZE_ANY_EXHDR(ptr).
*/
typedef struct varlena bytea;
typedef struct varlena text;
#define PointerIsAligned(pointer, type) \
(((uintptr_t)(pointer) % (sizeof (type))) == 0)
+#define OffsetToPointer(base, offset) \
+ ((void *)((char *) base + offset))
+
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
#define RegProcedureIsValid(p) OidIsValid(p)
*/
#ifndef offsetof
#define offsetof(type, field) ((long) &((type *)0)->field)
-#endif /* offsetof */
+#endif /* offsetof */
/*
* lengthof
/* we don't currently need wider versions of the other ALIGN macros */
#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN))
+/* ----------------
+ * Attribute macros
+ *
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
+ * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/function_attributes.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/type_attrib.html
+ * ----------------
+ */
+
+/* only GCC supports the unused attribute */
+#ifdef __GNUC__
+#define pg_attribute_unused() __attribute__((unused))
+#else
+#define pg_attribute_unused()
+#endif
+
+/* GCC and XLC support format attributes */
+#if defined(__GNUC__) || defined(__IBMC__)
+#define pg_attribute_format_arg(a) __attribute__((format_arg(a)))
+#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a)))
+#else
+#define pg_attribute_format_arg(a)
+#define pg_attribute_printf(f,a)
+#endif
+
+/* GCC, Sunpro and XLC support aligned, packed and noreturn */
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
+#define pg_attribute_aligned(a) __attribute__((aligned(a)))
+#define pg_attribute_noreturn() __attribute__((noreturn))
+#define pg_attribute_packed() __attribute__((packed))
+#define HAVE_PG_ATTRIBUTE_NORETURN 1
+#else
+/*
+ * NB: aligned and packed are not given default definitions because they
+ * affect code functionality; they *must* be implemented by the compiler
+ * if they are to be used.
+ */
+#define pg_attribute_noreturn()
+#endif
+
/* ----------------------------------------------------------------
* Section 6: assertions
* ----------------------------------------------------------------
Trap(TYPEALIGN(bndr, (uintptr_t)(ptr)) != (uintptr_t)(ptr), \
"UnalignedPointer")
-#endif /* USE_ASSERT_CHECKING && !FRONTEND */
+#endif /* USE_ASSERT_CHECKING && !FRONTEND */
/*
* Macros to support compile-time assertion checks.
((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
#define StaticAssertExpr(condition, errmessage) \
StaticAssertStmt(condition, errmessage)
-#endif /* HAVE__STATIC_ASSERT */
+#endif /* HAVE__STATIC_ASSERT */
/*
#define AssertVariableIsOfTypeMacro(varname, typename) \
((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \
CppAsString(varname) " does not have type " CppAsString(typename)))
-#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
+#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
/* ----------------------------------------------------------------
/*
- * Function inlining support -- Allow modules to define functions that may be
- * inlined, if the compiler supports it.
+ * Hints to the compiler about the likelihood of a branch. Both likely() and
+ * unlikely() return the boolean value of the contained expression.
*
- * The function bodies must be defined in the module header prefixed by
- * STATIC_IF_INLINE, protected by a cpp symbol that the module's .c file must
- * define. If the compiler doesn't support inline functions, the function
- * definitions are pulled in by the .c file as regular (not inline) symbols.
- *
- * The header must also declare the functions' prototypes, protected by
- * !PG_USE_INLINE.
+ * These should only be used sparingly, in very hot code paths. It's very easy
+ * to mis-estimate likelihoods.
*/
-
-/* declarations which are only visible when not inlining and in the .c file */
-#ifdef PG_USE_INLINE
-#define STATIC_IF_INLINE static inline
+#if __GNUC__ >= 3
+#define likely(x) __builtin_expect((x) != 0, 1)
+#define unlikely(x) __builtin_expect((x) != 0, 0)
#else
-#define STATIC_IF_INLINE
-#endif /* PG_USE_INLINE */
-
-/* declarations which are marked inline when inlining, extern otherwise */
-#ifdef PG_USE_INLINE
-#define STATIC_IF_INLINE_DECLARE static inline
-#else
-#define STATIC_IF_INLINE_DECLARE extern
-#endif /* PG_USE_INLINE */
+#define likely(x) ((x) != 0)
+#define unlikely(x) ((x) != 0)
+#endif
/* ----------------------------------------------------------------
#ifdef USE_ASSERT_CHECKING
#define PG_USED_FOR_ASSERTS_ONLY
#else
-#define PG_USED_FOR_ASSERTS_ONLY __attribute__((unused))
+#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused()
#endif
/* gettext domain name mangling */
/*
- * To better support parallel installations of major PostgeSQL
+ * To better support parallel installations of major PostgreSQL
* versions as well as parallel installations of major library soname
* versions, we mangle the gettext domain name by appending those
- * version numbers. The coding rule ought to be that whereever the
+ * version numbers. The coding rule ought to be that wherever the
* domain name is mentioned as a literal, it must be wrapped into
* PG_TEXTDOMAIN(). The macros below do not work on non-literals; but
* that is somewhat intentional because it avoids having to worry
*
* Make sure this matches the installation rules in nls-global.mk.
*/
-
-/* need a second indirection because we want to stringize the macro value, not the name */
-#define CppAsString2(x) CppAsString(x)
-
#ifdef SO_MAJOR_VERSION
#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION)
#else
*/
#if !HAVE_DECL_SNPRINTF
-extern int
-snprintf(char *str, size_t count, const char *fmt,...)
-/* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+extern int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4);
#endif
#if !HAVE_DECL_VSNPRINTF
/*
* When there is no sigsetjmp, its functionality is provided by plain
* setjmp. Incidentally, nothing provides setjmp's functionality in
- * that case.
+ * that case. We now support the case only on Windows.
*/
-#ifndef HAVE_SIGSETJMP
+#ifdef WIN32
#define sigjmp_buf jmp_buf
#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
/* /port compatibility functions */
#include "port.h"
-#endif /* C_H */
+#endif /* C_H */