ChangeLog fix
[bpt/emacs.git] / src / lisp.h
index c4b3655..2c53282 100644 (file)
@@ -1,6 +1,7 @@
 /* Fundamental definitions for GNU Emacs Lisp interpreter.
 
-Copyright (C) 1985-1987, 1993-1995, 1997-2013 Free Software Foundation, Inc.
+Copyright (C) 1985-1987, 1993-1995, 1997-2014 Free Software Foundation,
+Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,7 +24,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 #include <stdalign.h>
 #include <stdarg.h>
-#include <stdbool.h>
 #include <stddef.h>
 #include <float.h>
 #include <inttypes.h>
@@ -36,14 +36,30 @@ INLINE_HEADER_BEGIN
 
 /* Define a TYPE constant ID as an externally visible name.  Use like this:
 
+      #define ID_val (some integer preprocessor expression)
+      #if ENUMABLE (ID_val)
+      DEFINE_GDB_SYMBOL_ENUM (ID)
+      #else
       DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID)
-      #define ID something
+      # define ID ID_val
       DEFINE_GDB_SYMBOL_END (ID)
+      #endif
 
    This hack is for the benefit of compilers that do not make macro
    definitions visible to the debugger.  It's used for symbols that
    .gdbinit needs, symbols whose values may not fit in 'int' (where an
-   enum would suffice).  */
+   enum would suffice).
+
+   Some GCC versions before GCC 4.2 omit enums in debugging output;
+   see GCC bug 23336.  So don't use enums with older GCC.  */
+
+#if !defined __GNUC__ || 4 < __GNUC__ + (2 <= __GNUC_MINOR__)
+# define ENUMABLE(val) (INT_MIN <= (val) && (val) <= INT_MAX)
+#else
+# define ENUMABLE(val) 0
+#endif
+
+#define DEFINE_GDB_SYMBOL_ENUM(id) enum { id = id##_val };
 #if defined MAIN_PROGRAM
 # define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE
 # define DEFINE_GDB_SYMBOL_END(id) = id;
@@ -58,26 +74,52 @@ INLINE_HEADER_BEGIN
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
+/* Number of elements in an array.  */
+#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0])
+
+/* Number of bits in a Lisp_Object tag.  */
+DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS)
+#define GCTYPEBITS 3
+DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
+
+/* The number of bits needed in an EMACS_INT over and above the number
+   of bits in a pointer.  This is 0 on systems where:
+   1.  We can specify multiple-of-8 alignment on static variables.
+   2.  We know malloc returns a multiple of 8.  */
+#if (defined alignas \
+     && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
+        || defined DARWIN_OS || defined __sun || defined __MINGW32__))
+# define NONPOINTER_BITS 0
+#else
+# define NONPOINTER_BITS GCTYPEBITS
+#endif
+
 /* EMACS_INT - signed integer wide enough to hold an Emacs value
    EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if
    pI - printf length modifier for EMACS_INT
    EMACS_UINT - unsigned variant of EMACS_INT */
 #ifndef EMACS_INT_MAX
-# if LONG_MAX < LLONG_MAX && defined WIDE_EMACS_INT
-typedef long long int EMACS_INT;
-typedef unsigned long long int EMACS_UINT;
-#  define EMACS_INT_MAX LLONG_MAX
-#  define pI "ll"
-# elif INT_MAX < LONG_MAX
+# if INTPTR_MAX <= 0
+#  error "INTPTR_MAX misconfigured"
+# elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT
+typedef int EMACS_INT;
+typedef unsigned int EMACS_UINT;
+#  define EMACS_INT_MAX INT_MAX
+#  define pI ""
+# elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT
 typedef long int EMACS_INT;
 typedef unsigned long EMACS_UINT;
 #  define EMACS_INT_MAX LONG_MAX
 #  define pI "l"
+/* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS.
+   In theory this is not safe, but in practice it seems to be OK.  */
+# elif INTPTR_MAX <= LLONG_MAX
+typedef long long int EMACS_INT;
+typedef unsigned long long int EMACS_UINT;
+#  define EMACS_INT_MAX LLONG_MAX
+#  define pI "ll"
 # else
-typedef int EMACS_INT;
-typedef unsigned int EMACS_UINT;
-#  define EMACS_INT_MAX INT_MAX
-#  define pI ""
+#  error "INTPTR_MAX too large"
 # endif
 #endif
 
@@ -89,7 +131,7 @@ enum {  BOOL_VECTOR_BITS_PER_CHAR =
 };
 
 /* An unsigned integer type representing a fixed-length bit sequence,
-   suitable for words in a Lisp bool vector.  Normally it is size_t
+   suitable for bool vector words, GC mark bits, etc.  Normally it is size_t
    for speed, but it is unsigned char on weird platforms.  */
 #if BOOL_VECTOR_BITS_PER_CHAR == CHAR_BIT
 typedef size_t bits_word;
@@ -107,7 +149,6 @@ enum
   {
     BITS_PER_CHAR      = CHAR_BIT,
     BITS_PER_SHORT     = CHAR_BIT * sizeof (short),
-    BITS_PER_INT       = CHAR_BIT * sizeof (int),
     BITS_PER_LONG      = CHAR_BIT * sizeof (long int),
     BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
   };
@@ -170,7 +211,7 @@ typedef EMACS_UINT uprintmax_t;
    for COND to call external functions or access volatile storage.  */
 
 #ifndef ENABLE_CHECKING
-# define eassert(cond) ((void) (0 && (cond))) /* Check that COND compiles.  */
+# define eassert(cond) ((void) (false && (cond))) /* Check COND compiles.  */
 # define eassume(cond) assume (cond)
 #else /* ENABLE_CHECKING */
 
@@ -211,12 +252,6 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
 
 enum Lisp_Bits
   {
-    /* Number of bits in a Lisp_Object tag.  This can be used in #if,
-       and for GDB's sake also as a regular symbol.  */
-    GCTYPEBITS =
-#define GCTYPEBITS 3
-       GCTYPEBITS,
-
     /* 2**GCTYPEBITS.  This must be a macro that expands to a literal
        integer constant, for MSVC.  */
 #define GCALIGNMENT 8
@@ -240,31 +275,19 @@ enum Lisp_Bits
    This can be used in #if, e.g., '#if VAL_MAX < UINTPTR_MAX' below.  */
 #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1))
 
-/* Unless otherwise specified, use USE_LSB_TAG on systems where:  */
-#ifndef USE_LSB_TAG
-/* 1.  We know malloc returns a multiple of 8.  */
-# if (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
-      || defined DARWIN_OS || defined __sun)
-/* 2.  We can specify multiple-of-8 alignment on static variables.  */
-#  ifdef alignas
-/* 3.  Pointers-as-ints exceed VAL_MAX.
+/* Whether the least-significant bits of an EMACS_INT contain the tag.
    On hosts where pointers-as-ints do not exceed VAL_MAX, USE_LSB_TAG is:
     a. unnecessary, because the top bits of an EMACS_INT are unused, and
     b. slower, because it typically requires extra masking.
-   So, default USE_LSB_TAG to 1 only on hosts where it might be useful.  */
-#   if VAL_MAX < UINTPTR_MAX
-#    define USE_LSB_TAG 1
-#   endif
-#  endif
-# endif
-#endif
-#ifdef USE_LSB_TAG
-# undef USE_LSB_TAG
-enum enum_USE_LSB_TAG { USE_LSB_TAG = 1 };
-# define USE_LSB_TAG 1
-#else
-enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
-# define USE_LSB_TAG 0
+   So, USE_LSB_TAG is true only on hosts where it might be useful.  */
+DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG)
+#define USE_LSB_TAG (EMACS_INT_MAX >> GCTYPEBITS < INTPTR_MAX)
+DEFINE_GDB_SYMBOL_END (USE_LSB_TAG)
+
+#if !USE_LSB_TAG && !defined WIDE_EMACS_INT
+# error "USE_LSB_TAG not supported on this platform; please report this." \
+       "Try 'configure --with-wide-int' to work around the problem."
+error !;
 #endif
 
 #ifndef alignas
@@ -318,8 +341,8 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
 #define lisp_h_CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y)
 #define lisp_h_CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x)
 #define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x)
-#define lisp_h_CHECK_TYPE(ok, Qxxxp, x) \
-   ((ok) ? (void) 0 : (void) wrong_type_argument (Qxxxp, x))
+#define lisp_h_CHECK_TYPE(ok, predicate, x) \
+   ((ok) ? (void) 0 : (void) wrong_type_argument (predicate, x))
 #define lisp_h_CONSP(x) (XTYPE (x) == Lisp_Cons)
 #define lisp_h_EQ(x, y) (XLI (x) == XLI (y))
 #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float)
@@ -339,15 +362,15 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
 #define lisp_h_XCONS(a) \
    (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
 #define lisp_h_XHASH(a) XUINT (a)
-#define lisp_h_XPNTR(a) \
-   ((void *) (intptr_t) ((XLI (a) & VALMASK) | DATA_SEG_BITS))
+#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK))
 #define lisp_h_XSYMBOL(a) \
    (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
 #if USE_LSB_TAG
-# define lisp_h_make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS)
+# define lisp_h_make_number(n) \
+    XIL ((EMACS_INT) ((EMACS_UINT) (n) << INTTYPEBITS))
 # define lisp_h_XFASTINT(a) XINT (a)
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
@@ -356,7 +379,7 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
 
 /* When compiling via gcc -O0, define the key operations as macros, as
    Emacs is too slow otherwise.  To disable this optimization, compile
-   with -DINLINING=0.  */
+   with -DINLINING=false.  */
 #if (defined __NO_INLINE__ \
      && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \
      && ! (defined INLINING && ! INLINING))
@@ -365,7 +388,7 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
 # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y)
 # define CHECK_NUMBER(x) lisp_h_CHECK_NUMBER (x)
 # define CHECK_SYMBOL(x) lisp_h_CHECK_SYMBOL (x)
-# define CHECK_TYPE(ok, Qxxxp, x) lisp_h_CHECK_TYPE (ok, Qxxxp, x)
+# define CHECK_TYPE(ok, predicate, x) lisp_h_CHECK_TYPE (ok, predicate, x)
 # define CONSP(x) lisp_h_CONSP (x)
 # define EQ(x, y) lisp_h_EQ (x, y)
 # define FLOATP(x) lisp_h_FLOATP (x)
@@ -550,14 +573,14 @@ typedef struct { EMACS_INT i; } Lisp_Object;
 #define LISP_INITIALLY_ZERO {0}
 
 #undef CHECK_LISP_OBJECT_TYPE
-enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 };
+enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true };
 #else /* CHECK_LISP_OBJECT_TYPE */
 
 /* If a struct type is not wanted, define Lisp_Object as just a number.  */
 
 typedef EMACS_INT Lisp_Object;
 #define LISP_INITIALLY_ZERO 0
-enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 };
+enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
 #endif /* CHECK_LISP_OBJECT_TYPE */
 
 /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
@@ -567,15 +590,25 @@ LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i))
 
 /* In the size word of a vector, this bit means the vector has been marked.  */
 
+#define ARRAY_MARK_FLAG_val PTRDIFF_MIN
+#if ENUMABLE (ARRAY_MARK_FLAG_val)
+DEFINE_GDB_SYMBOL_ENUM (ARRAY_MARK_FLAG)
+#else
 DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
-#define ARRAY_MARK_FLAG PTRDIFF_MIN
+# define ARRAY_MARK_FLAG ARRAY_MARK_FLAG_val
 DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
+#endif
 
 /* In the size word of a struct Lisp_Vector, this bit means it's really
    some other vector-like object.  */
+#define PSEUDOVECTOR_FLAG_val (PTRDIFF_MAX - PTRDIFF_MAX / 2)
+#if ENUMABLE (PSEUDOVECTOR_FLAG_val)
+DEFINE_GDB_SYMBOL_ENUM (PSEUDOVECTOR_FLAG)
+#else
 DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
-#define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
+# define PSEUDOVECTOR_FLAG PSEUDOVECTOR_FLAG_val
 DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
+#endif
 
 /* In a pseudovector, the size field actually contains a word with one
    PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
@@ -601,18 +634,8 @@ enum pvec_type
   PVEC_FONT /* Should be last because it's used for range checking.  */
 };
 
-/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
-   which were stored in a Lisp_Object.  */
-#ifndef DATA_SEG_BITS
-# define DATA_SEG_BITS 0
-#endif
-enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS };
-#undef DATA_SEG_BITS
-
 enum More_Lisp_Bits
   {
-    DATA_SEG_BITS = gdb_DATA_SEG_BITS,
-
     /* For convenience, we also store the number of elements in these bits.
        Note that this size is not necessarily the memory-footprint size, but
        only the number of Lisp_Object fields (that need to be traced by GC).
@@ -629,7 +652,7 @@ enum More_Lisp_Bits
 
     /* Used to extract pseudovector subtype information.  */
     PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
-    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS,
+    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
   };
 \f
 /* These functions extract various sorts of values from a Lisp_Object.
@@ -637,9 +660,15 @@ enum More_Lisp_Bits
    XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
    that cons.  */
 
+/* Mask for the value (as opposed to the type bits) of a Lisp object.  */
+#define VALMASK_val (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
+#if ENUMABLE (VALMASK_val)
+DEFINE_GDB_SYMBOL_ENUM (VALMASK)
+#else
 DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
-#define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
+# define VALMASK VALMASK_val
 DEFINE_GDB_SYMBOL_END (VALMASK)
+#endif
 
 /* Largest and smallest representable fixnum values.  These are the C
    values.  They are macros for use in static initializers.  */
@@ -668,7 +697,14 @@ LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
 INLINE Lisp_Object
 make_number (EMACS_INT n)
 {
-  return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK);
+  if (USE_LSB_TAG)
+    {
+      EMACS_UINT u = n;
+      n = u << INTTYPEBITS;
+    }
+  else
+    n &= INTMASK;
+  return XIL (n);
 }
 
 /* Extract A's value as a signed integer.  */
@@ -676,7 +712,12 @@ INLINE EMACS_INT
 XINT (Lisp_Object a)
 {
   EMACS_INT i = XLI (a);
-  return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS;
+  if (! USE_LSB_TAG)
+    {
+      EMACS_UINT u = i;
+      i = u << INTTYPEBITS;
+    }
+  return i >> INTTYPEBITS;
 }
 
 /* Like XINT (A), but may be faster.  A must be nonnegative.
@@ -736,7 +777,7 @@ make_natnum (EMACS_INT n)
 /* Return true if X and Y are the same object.  */
 LISP_MACRO_DEFUN (EQ, bool, (Lisp_Object x, Lisp_Object y), (x, y))
 
-/* Value is non-zero if I doesn't fit into a Lisp fixnum.  It is
+/* Value is true if I doesn't fit into a Lisp fixnum.  It is
    written this way so that it also works if I is of unsigned
    type or if I is a NaN.  */
 
@@ -791,10 +832,12 @@ extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qt, Qvectorp;
 extern Lisp_Object Qbool_vector_p;
 extern Lisp_Object Qvector_or_char_table_p, Qwholenump;
 extern Lisp_Object Qwindow;
-extern Lisp_Object Ffboundp (Lisp_Object);
 extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
 
 /* Defined in emacs.c.  */
+extern bool might_dump;
+/* True means Emacs has already been initialized.
+   Used during startup to detect startup of dumped Emacs.  */
 extern bool initialized;
 
 /* Defined in eval.c.  */
@@ -960,8 +1003,9 @@ make_lisp_proc (struct Lisp_Process *p)
 
 /* Type checking.  */
 
-LISP_MACRO_DEFUN_VOID (CHECK_TYPE, (int ok, Lisp_Object Qxxxp, Lisp_Object x),
-                      (ok, Qxxxp, x))
+LISP_MACRO_DEFUN_VOID (CHECK_TYPE,
+                      (int ok, Lisp_Object predicate, Lisp_Object x),
+                      (ok, predicate, x))
 
 /* Deprecated and will be removed soon.  */
 
@@ -1085,17 +1129,23 @@ STRING_MULTIBYTE (Lisp_Object str)
   ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1))
 
 /* Mark STR as a unibyte string.  */
-#define STRING_SET_UNIBYTE(STR)  \
-  do { if (EQ (STR, empty_multibyte_string))  \
-      (STR) = empty_unibyte_string;  \
-    else XSTRING (STR)->size_byte = -1; } while (0)
+#define STRING_SET_UNIBYTE(STR)                                \
+  do {                                                 \
+    if (EQ (STR, empty_multibyte_string))              \
+      (STR) = empty_unibyte_string;                    \
+    else                                               \
+      XSTRING (STR)->size_byte = -1;                   \
+  } while (false)
 
 /* Mark STR as a multibyte string.  Assure that STR contains only
    ASCII characters in advance.  */
-#define STRING_SET_MULTIBYTE(STR)  \
-  do { if (EQ (STR, empty_unibyte_string))  \
-      (STR) = empty_multibyte_string;  \
-    else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0)
+#define STRING_SET_MULTIBYTE(STR)                      \
+  do {                                                 \
+    if (EQ (STR, empty_unibyte_string))                        \
+      (STR) = empty_multibyte_string;                  \
+    else                                               \
+      XSTRING (STR)->size_byte = XSTRING (STR)->size;  \
+  } while (false)
 
 /* Convenience functions for dealing with Lisp strings.  */
 
@@ -1149,12 +1199,6 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
 {
   XSTRING (string)->size = newsize;
 }
-INLINE void
-STRING_COPYIN (Lisp_Object string, ptrdiff_t index, char const *new,
-              ptrdiff_t count)
-{
-  memcpy (SDATA (string) + index, new, count);
-}
 
 /* Header of vector-like objects.  This documents the layout constraints on
    vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
@@ -1348,14 +1392,14 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
 /* Compute A OP B, using the unsigned comparison operator OP.  A and B
    should be integer expressions.  This is not the same as
    mathematical comparison; for example, UNSIGNED_CMP (0, <, -1)
-   returns 1.  For efficiency, prefer plain unsigned comparison if A
+   returns true.  For efficiency, prefer plain unsigned comparison if A
    and B's sizes both fit (after integer promotion).  */
 #define UNSIGNED_CMP(a, op, b)                                         \
   (max (sizeof ((a) + 0), sizeof ((b) + 0)) <= sizeof (unsigned)       \
    ? ((a) + (unsigned) 0) op ((b) + (unsigned) 0)                      \
    : ((a) + (uintmax_t) 0) op ((b) + (uintmax_t) 0))
 
-/* Nonzero iff C is an ASCII character.  */
+/* True iff C is an ASCII character.  */
 #define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80)
 
 /* A char-table is a kind of vectorlike, with contents are like a
@@ -1536,7 +1580,7 @@ enum symbol_redirect
 
 struct Lisp_Symbol
 {
-  unsigned gcmarkbit : 1;
+  bool_bf gcmarkbit : 1;
 
   /* Indicates where the value can be found:
      0 : it's a plain var, the value is in the `value' field.
@@ -1554,9 +1598,12 @@ struct Lisp_Symbol
      enum symbol_interned.  */
   unsigned interned : 2;
 
-  /* Non-zero means that this variable has been explicitly declared
+  /* True means that this variable has been explicitly declared
      special (with `defvar' etc), and shouldn't be lexically bound.  */
-  unsigned declared_special : 1;
+  bool_bf declared_special : 1;
+
+  /* True if pointed to from purespace and hence can't be GC'd.  */
+  bool_bf pinned : 1;
 
   /* The symbol's name, as a Lisp string.  */
   Lisp_Object name;
@@ -1654,7 +1701,7 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
 LISP_MACRO_DEFUN (SYMBOL_CONSTANT_P, int, (Lisp_Object sym), (sym))
 
 #define DEFSYM(sym, name)                                              \
-  do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0)
+  do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (false)
 
 \f
 /***********************************************************************
@@ -1699,8 +1746,8 @@ struct Lisp_Hash_Table
      ratio, a float.  */
   Lisp_Object rehash_threshold;
 
-  /* Vector of hash codes.. If hash[I] is nil, this means that that
-     entry I is unused.  */
+  /* Vector of hash codes.  If hash[I] is nil, this means that the
+     I-th entry is unused.  */
   Lisp_Object hash;
 
   /* Vector used to chain entries.  If entry I is free, next[I] is the
@@ -1832,22 +1879,22 @@ SXHASH_REDUCE (EMACS_UINT x)
 struct Lisp_Misc_Any           /* Supertype of all Misc types.  */
 {
   ENUM_BF (Lisp_Misc_Type) type : 16;          /* = Lisp_Misc_??? */
-  unsigned gcmarkbit : 1;
+  bool_bf gcmarkbit : 1;
   unsigned spacer : 15;
 };
 
 struct Lisp_Marker
 {
   ENUM_BF (Lisp_Misc_Type) type : 16;          /* = Lisp_Misc_Marker */
-  unsigned gcmarkbit : 1;
+  bool_bf gcmarkbit : 1;
   unsigned spacer : 13;
   /* This flag is temporarily used in the functions
      decode/encode_coding_object to record that the marker position
      must be adjusted after the conversion.  */
-  unsigned int need_adjustment : 1;
-  /* 1 means normal insertion at the marker's position
+  bool_bf need_adjustment : 1;
+  /* True means normal insertion at the marker's position
      leaves the marker after the inserted text.  */
-  unsigned int insertion_type : 1;
+  bool_bf insertion_type : 1;
   /* This is the buffer that the marker points into, or 0 if it points nowhere.
      Note: a chain of markers can contain markers pointing into different
      buffers (the chain is per buffer_text rather than per buffer, so it's
@@ -1893,7 +1940,7 @@ struct Lisp_Overlay
 */
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Overlay */
-    unsigned gcmarkbit : 1;
+    bool_bf gcmarkbit : 1;
     unsigned spacer : 15;
     struct Lisp_Overlay *next;
     Lisp_Object start;
@@ -1971,7 +2018,7 @@ typedef void (*voidfuncptr) (void);
 struct Lisp_Save_Value
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Save_Value */
-    unsigned gcmarkbit : 1;
+    bool_bf gcmarkbit : 1;
     unsigned spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
 
     /* V->data may hold up to SAVE_VALUE_SLOTS entries.  The type of
@@ -2047,7 +2094,7 @@ XSAVE_OBJECT (Lisp_Object obj, int n)
 struct Lisp_Free
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Free */
-    unsigned gcmarkbit : 1;
+    bool_bf gcmarkbit : 1;
     unsigned spacer : 15;
     union Lisp_Misc *chain;
   };
@@ -2116,8 +2163,8 @@ struct Lisp_Intfwd
 
 /* Boolean forwarding pointer to an int variable.
    This is like Lisp_Intfwd except that the ostensible
-   "value" of the symbol is t if the int variable is nonzero,
-   nil if it is zero.  */
+   "value" of the symbol is t if the bool variable is true,
+   nil if it is false.  */
 struct Lisp_Boolfwd
   {
     enum Lisp_Fwd_Type type;   /* = Lisp_Fwd_Bool */
@@ -2170,15 +2217,15 @@ struct Lisp_Buffer_Objfwd
 
 struct Lisp_Buffer_Local_Value
   {
-    /* 1 means that merely setting the variable creates a local
+    /* True means that merely setting the variable creates a local
        binding for the current buffer.  */
-    unsigned int local_if_set : 1;
-    /* 1 means this variable can have frame-local bindings, otherwise, it is
+    bool_bf local_if_set : 1;
+    /* True means this variable can have frame-local bindings, otherwise, it is
        can have buffer-local bindings.  The two cannot be combined.  */
-    unsigned int frame_local : 1;
-    /* 1 means that the binding now loaded was found.
+    bool_bf frame_local : 1;
+    /* True means that the binding now loaded was found.
        Presumably equivalent to (defcell!=valcell).  */
-    unsigned int found : 1;
+    bool_bf found : 1;
     /* If non-NULL, a forwarding to the C var where it should also be set.  */
     union Lisp_Fwd *fwd;       /* Should never be (Buffer|Kboard)_Objfwd.  */
     /* The buffer or frame for which the loaded binding was found.  */
@@ -2373,7 +2420,7 @@ INLINE bool
 PSEUDOVECTORP (Lisp_Object a, int code)
 {
   if (! VECTORLIKEP (a))
-    return 0;
+    return false;
   else
     {
       /* Converting to struct vectorlike_header * avoids aliasing issues.  */
@@ -2506,9 +2553,9 @@ CHECK_VECTOR_OR_STRING (Lisp_Object x)
   CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x);
 }
 INLINE void
-CHECK_ARRAY (Lisp_Object x, Lisp_Object Qxxxp)
+CHECK_ARRAY (Lisp_Object x, Lisp_Object predicate)
 {
-  CHECK_TYPE (ARRAYP (x), Qxxxp, x);
+  CHECK_TYPE (ARRAYP (x), predicate, x);
 }
 INLINE void
 CHECK_BUFFER (Lisp_Object x)
@@ -2520,11 +2567,13 @@ CHECK_WINDOW (Lisp_Object x)
 {
   CHECK_TYPE (WINDOWP (x), Qwindowp, x);
 }
+#ifdef subprocesses
 INLINE void
 CHECK_PROCESS (Lisp_Object x)
 {
   CHECK_TYPE (PROCESSP (x), Qprocessp, x);
 }
+#endif
 INLINE void
 CHECK_NATNUM (Lisp_Object x)
 {
@@ -2541,18 +2590,22 @@ CHECK_NATNUM (Lisp_Object x)
                      ? MOST_NEGATIVE_FIXNUM                            \
                      : (lo)),                                          \
         make_number (min (hi, MOST_POSITIVE_FIXNUM)));                 \
-  } while (0)
+  } while (false)
 #define CHECK_TYPE_RANGED_INTEGER(type, x) \
   do {                                                                 \
     if (TYPE_SIGNED (type))                                            \
       CHECK_RANGED_INTEGER (x, TYPE_MINIMUM (type), TYPE_MAXIMUM (type)); \
     else                                                               \
       CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type));                        \
-  } while (0)
+  } while (false)
 
-#define CHECK_NUMBER_COERCE_MARKER(x) \
-  do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \
-    else CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x); } while (0)
+#define CHECK_NUMBER_COERCE_MARKER(x)                                  \
+  do {                                                                 \
+    if (MARKERP ((x)))                                                 \
+      XSETFASTINT (x, marker_position (x));                            \
+    else                                                               \
+      CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x);              \
+  } while (false)
 
 INLINE double
 XFLOATINT (Lisp_Object n)
@@ -2566,9 +2619,13 @@ CHECK_NUMBER_OR_FLOAT (Lisp_Object x)
   CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x);
 }
 
-#define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x) \
-  do { if (MARKERP (x)) XSETFASTINT (x, marker_position (x)); \
-    else CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); } while (0)
+#define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x)                         \
+  do {                                                                 \
+    if (MARKERP (x))                                                   \
+      XSETFASTINT (x, marker_position (x));                            \
+    else                                                               \
+      CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); \
+  } while (false)
 
 /* Since we can't assign directly to the CAR or CDR fields of a cons
    cell, use these when checking that those fields contain numbers.  */
@@ -2625,16 +2682,10 @@ CHECK_NUMBER_CDR (Lisp_Object x)
        minargs, maxargs, lname, intspec, 0};                           \
    Lisp_Object fnname
 #else  /* not _MSC_VER */
-# if __STDC_VERSION__ < 199901
-#  define DEFUN_FUNCTION_INIT(fnname, maxargs) (Lisp_Object (*) (void)) fnname
-# else
-#  define DEFUN_FUNCTION_INIT(fnname, maxargs) .a ## maxargs = fnname
-# endif
 #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc)    \
-   Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;                         \
    static struct Lisp_Subr alignas (GCALIGNMENT) sname =               \
      { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },                                \
-       { DEFUN_FUNCTION_INIT (fnname, maxargs) },                      \
+       { .a ## maxargs = fnname },                                     \
        minargs, maxargs, lname, intspec, 0};                           \
    Lisp_Object fnname
 #endif
@@ -2701,34 +2752,34 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
   do {                                         \
     static struct Lisp_Objfwd o_fwd;           \
     defvar_lisp (&o_fwd, lname, &globals.f_ ## vname);         \
-  } while (0)
+  } while (false)
 #define DEFVAR_LISP_NOPRO(lname, vname, doc)   \
   do {                                         \
     static struct Lisp_Objfwd o_fwd;           \
     defvar_lisp_nopro (&o_fwd, lname, &globals.f_ ## vname);   \
-  } while (0)
+  } while (false)
 #define DEFVAR_BOOL(lname, vname, doc)         \
   do {                                         \
     static struct Lisp_Boolfwd b_fwd;          \
     defvar_bool (&b_fwd, lname, &globals.f_ ## vname);         \
-  } while (0)
+  } while (false)
 #define DEFVAR_INT(lname, vname, doc)          \
   do {                                         \
     static struct Lisp_Intfwd i_fwd;           \
     defvar_int (&i_fwd, lname, &globals.f_ ## vname);          \
-  } while (0)
+  } while (false)
 
 #define DEFVAR_BUFFER_DEFAULTS(lname, vname, doc)              \
   do {                                                         \
     static struct Lisp_Objfwd o_fwd;                           \
     defvar_lisp_nopro (&o_fwd, lname, &BVAR (&buffer_defaults, vname));        \
-  } while (0)
+  } while (false)
 
 #define DEFVAR_KBOARD(lname, vname, doc)                       \
   do {                                                         \
     static struct Lisp_Kboard_Objfwd ko_fwd;                   \
     defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \
-  } while (0)
+  } while (false)
 \f
 /* Save and restore the instruction and environment pointers,
    without affecting the signal mask.  */
@@ -2812,7 +2863,7 @@ union specbinding
     } let;
     struct {
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
-      unsigned debug_on_exit : 1;
+      bool_bf debug_on_exit : 1;
       Lisp_Object function;
       Lisp_Object *args;
       ptrdiff_t nargs;
@@ -2869,7 +2920,7 @@ struct handler
 
   /* Most global vars are reset to their value via the specpdl mechanism,
      but a few others are handled by storing their value here.  */
-#if 1 /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but they're defined later.  */
+#if true /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but defined later.  */
   struct gcpro *gcpro;
 #endif
   sys_jmp_buf jmp;
@@ -2917,7 +2968,7 @@ extern char *stack_bottom;
    Unless that is impossible, of course.
    But it is very desirable to avoid creating loops where QUIT is impossible.
 
-   Exception: if you set immediate_quit to nonzero,
+   Exception: if you set immediate_quit to true,
    then the handler that responds to the C-g does the quit itself.
    This is a good thing to do around a loop that has no side effects
    and (in particular) cannot call arbitrary Lisp code.
@@ -2935,10 +2986,10 @@ extern void process_quit_flag (void);
       process_quit_flag ();                            \
     else if (pending_signals)                          \
       process_pending_signals ();                      \
-  } while (0)
+  } while (false)
 
 
-/* Nonzero if ought to quit now.  */
+/* True if ought to quit now.  */
 
 #define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
 \f
@@ -3019,6 +3070,7 @@ struct gcpro
 #define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \
   ((void) gcpro6, (void) gcpro5, (void) gcpro4, (void) gcpro3, (void) gcpro2, \
    (void) gcpro1)
+#define GCPRO7(a, b, c, d, e, f, g) (GCPRO6 (a, b, c, d, e, f), (void) gcpro7)
 #define UNGCPRO ((void) 0)
 
 #else /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
@@ -3064,6 +3116,16 @@ struct gcpro
   gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \
   gcprolist = &gcpro6; }
 
+#define GCPRO7(a, b, c, d, e, f, g)                            \
+ {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;        \
+  gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;  \
+  gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;  \
+  gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;  \
+  gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;  \
+  gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;  \
+  gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1;  \
+  gcprolist = &gcpro7; }
+
 #define UNGCPRO (gcprolist = gcpro1.next)
 
 #else
@@ -3120,10 +3182,22 @@ extern int gcpro_level;
   gcpro6.level = gcpro_level++; \
   gcprolist = &gcpro6; }
 
+#define GCPRO7(a, b, c, d, e, f, g)                                    \
+ {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;                \
+  gcpro1.level = gcpro_level;                                          \
+  gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;          \
+  gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;          \
+  gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;          \
+  gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;          \
+  gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;          \
+  gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1;          \
+  gcpro7.level = gcpro_level++;                                                \
+  gcprolist = &gcpro7; }
+
 #define UNGCPRO                                        \
((--gcpro_level != gcpro1.level)              \
-  ? (emacs_abort (), 0)                                \
-  : ((gcprolist = gcpro1.next), 0))
 (--gcpro_level != gcpro1.level               \
+   ? emacs_abort ()                            \
+   : (void) (gcprolist = gcpro1.next))
 
 #endif /* DEBUG_GCPRO */
 #endif /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
@@ -3131,14 +3205,14 @@ extern int gcpro_level;
 
 /* Evaluate expr, UNGCPRO, and then return the value of expr.  */
 #define RETURN_UNGCPRO(expr)                   \
-do                                             \
+  do                                           \
     {                                          \
       Lisp_Object ret_ungc_val;                        \
       ret_ungc_val = (expr);                   \
       UNGCPRO;                                 \
       return ret_ungc_val;                     \
     }                                          \
-while (0)
+  while (false)
 
 /* Call staticpro (&var) to protect static variable `var'.  */
 
@@ -3271,7 +3345,7 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val)
 }
 
 /* Defined in data.c.  */
-extern Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
+extern Lisp_Object Qquote, Qunbound;
 extern Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
 extern Lisp_Object Qerror, Qquit, Qargs_out_of_range;
 extern Lisp_Object Qvoid_variable, Qvoid_function;
@@ -3282,26 +3356,18 @@ extern Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
 extern Lisp_Object Qtext_read_only;
 extern Lisp_Object Qinteractive_form;
 extern Lisp_Object Qcircular_list;
-extern Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp;
-extern Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
-extern Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
-extern Lisp_Object Qbuffer_or_string_p;
+extern Lisp_Object Qsequencep;
+extern Lisp_Object Qchar_or_string_p, Qinteger_or_marker_p;
 extern Lisp_Object Qfboundp;
-extern Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
 
 extern Lisp_Object Qcdr;
 
 extern Lisp_Object Qrange_error, Qoverflow_error;
 
-extern Lisp_Object Qfloatp;
-extern Lisp_Object Qnumberp, Qnumber_or_marker_p;
+extern Lisp_Object Qnumber_or_marker_p;
 
 extern Lisp_Object Qbuffer, Qinteger, Qsymbol;
 
-extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
-
-EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST;
-
 /* Defined in data.c.  */
 extern Lisp_Object indirect_function (Lisp_Object);
 extern Lisp_Object find_symbol_value (Lisp_Object);
@@ -3348,7 +3414,6 @@ extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
 extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object);
 extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object,
                                           Lisp_Object);
-extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
 extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
 extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool);
 extern void syms_of_data (void);
@@ -3367,11 +3432,8 @@ extern void init_coding_once (void);
 extern void syms_of_coding (void);
 
 /* Defined in character.c.  */
-EXFUN (Fmax_char, 0) ATTRIBUTE_CONST;
 extern ptrdiff_t chars_in_text (const unsigned char *, ptrdiff_t);
 extern ptrdiff_t multibyte_chars_in_text (const unsigned char *, ptrdiff_t);
-extern int multibyte_char_to_unibyte (int) ATTRIBUTE_CONST;
-extern int multibyte_char_to_unibyte_safe (int) ATTRIBUTE_CONST;
 extern void syms_of_character (void);
 
 /* Defined in charset.c.  */
@@ -3381,9 +3443,6 @@ extern void syms_of_charset (void);
 /* Structure forward declarations.  */
 struct charset;
 
-/* Defined in composite.c.  */
-extern void syms_of_composite (void);
-
 /* Defined in syntax.c.  */
 extern void init_syntax_once (void);
 extern void syms_of_syntax (void);
@@ -3391,7 +3450,6 @@ extern void syms_of_syntax (void);
 /* Defined in fns.c.  */
 extern Lisp_Object QCrehash_size, QCrehash_threshold;
 enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
-EXFUN (Fidentity, 1) ATTRIBUTE_CONST;
 extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST;
 extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
 extern void sweep_weak_hash_tables (void);
@@ -3424,7 +3482,6 @@ extern Lisp_Object string_make_unibyte (Lisp_Object);
 extern void syms_of_fns (void);
 
 /* Defined in floatfns.c.  */
-extern double extract_float (Lisp_Object);
 extern void syms_of_floatfns (void);
 extern Lisp_Object fmod_float (Lisp_Object x, Lisp_Object y);
 
@@ -3445,6 +3502,7 @@ extern void syms_of_image (void);
 
 /* Defined in insdel.c.  */
 extern Lisp_Object Qinhibit_modification_hooks;
+extern Lisp_Object Qregion_extract_function;
 extern void move_gap_both (ptrdiff_t, ptrdiff_t);
 extern _Noreturn void buffer_overflow (void);
 extern void make_gap (ptrdiff_t);
@@ -3497,18 +3555,16 @@ _Noreturn void __executable_start (void);
 #endif
 extern Lisp_Object Vwindow_system;
 extern Lisp_Object sit_for (Lisp_Object, bool, int);
-extern void init_display (void);
-extern void syms_of_display (void);
 
 /* Defined in xdisp.c.  */
 extern Lisp_Object Qinhibit_point_motion_hooks;
-extern Lisp_Object Qinhibit_redisplay, Qdisplay;
+extern Lisp_Object Qinhibit_redisplay;
 extern Lisp_Object Qmenu_bar_update_hook;
 extern Lisp_Object Qwindow_scroll_functions;
 extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-extern Lisp_Object Qimage, Qtext, Qboth, Qboth_horiz, Qtext_image_horiz;
+extern Lisp_Object Qtext, Qboth, Qboth_horiz, Qtext_image_horiz;
 extern Lisp_Object Qspace, Qcenter, QCalign_to;
-extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
+extern Lisp_Object Qbar, Qhbar, Qhollow;
 extern Lisp_Object Qleft_margin, Qright_margin;
 extern Lisp_Object QCdata, QCfile;
 extern Lisp_Object QCmap;
@@ -3535,7 +3591,6 @@ extern void message_log_maybe_newline (void);
 extern void update_echo_area (void);
 extern void truncate_echo_area (ptrdiff_t);
 extern void redisplay (void);
-extern void redisplay_preserve_echo_area (int);
 
 void set_frame_cursor_types (struct frame *, Lisp_Object);
 extern void syms_of_xdisp (void);
@@ -3700,6 +3755,7 @@ extern void init_alloc (void);
 extern void syms_of_alloc (void);
 extern struct buffer * allocate_buffer (void);
 extern int valid_lisp_object_p (Lisp_Object);
+extern int relocatable_string_data_p (const char *);
 #ifdef GC_CHECK_CONS_LIST
 extern void check_cons_list (void);
 #else
@@ -3708,21 +3764,18 @@ INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); }
 
 #ifdef REL_ALLOC
 /* Defined in ralloc.c.  */
-extern void *r_alloc (void **, size_t);
+extern void *r_alloc (void **, size_t) ATTRIBUTE_ALLOC_SIZE ((2));
 extern void r_alloc_free (void **);
-extern void *r_re_alloc (void **, size_t);
+extern void *r_re_alloc (void **, size_t) ATTRIBUTE_ALLOC_SIZE ((2));
 extern void r_alloc_reset_variable (void **, void **);
 extern void r_alloc_inhibit_buffer_relocation (int);
 #endif
 
 /* Defined in chartab.c.  */
 extern Lisp_Object copy_char_table (Lisp_Object);
-extern Lisp_Object char_table_ref (Lisp_Object, int);
 extern Lisp_Object char_table_ref_and_range (Lisp_Object, int,
                                              int *, int *);
-extern void char_table_set (Lisp_Object, int, Lisp_Object);
 extern void char_table_set_range (Lisp_Object, int, int, Lisp_Object);
-extern int char_table_translate (Lisp_Object, int);
 extern void map_char_table (void (*) (Lisp_Object, Lisp_Object,
                             Lisp_Object),
                             Lisp_Object, Lisp_Object, Lisp_Object);
@@ -3746,7 +3799,7 @@ extern void print_error_message (Lisp_Object, Lisp_Object, const char *,
                                 Lisp_Object);
 extern Lisp_Object internal_with_output_to_temp_buffer
         (const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object);
-enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 };
+#define FLOAT_TO_STRING_BUFSIZE 350
 extern int float_to_string (char *, double);
 extern void init_print_once (void);
 extern void syms_of_print (void);
@@ -3778,7 +3831,7 @@ LOADHIST_ATTACH (Lisp_Object x)
     Vcurrent_load_list = Fcons (x, Vcurrent_load_list);
 }
 extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
-                  Lisp_Object *, Lisp_Object);
+                  Lisp_Object *, Lisp_Object, bool);
 extern Lisp_Object string_to_number (char const *, int, bool);
 extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
                          Lisp_Object);
@@ -3800,7 +3853,7 @@ intern_c_string (const char *str)
 }
 
 /* Defined in eval.c.  */
-extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qmacro;
+extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro;
 extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure;
 extern Lisp_Object Qand_rest;
 extern Lisp_Object Vautoload_queue;
@@ -3904,7 +3957,7 @@ extern bool overlay_touches_p (ptrdiff_t);
 extern Lisp_Object other_buffer_safely (Lisp_Object);
 extern Lisp_Object get_truename_buffer (Lisp_Object);
 extern void init_buffer_once (void);
-extern void init_buffer (void);
+extern void init_buffer (int);
 extern void syms_of_buffer (void);
 extern void keys_of_buffer (void);
 
@@ -3935,7 +3988,6 @@ extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
 extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
                                 Lisp_Object, Lisp_Object, Lisp_Object,
                                 Lisp_Object, int);
-EXFUN (Fread_file_name, 6);     /* Not a normal DEFUN.  */
 extern void close_file_unwind (int);
 extern void fclose_unwind (void *);
 extern void restore_point_unwind (Lisp_Object);
@@ -3987,6 +4039,7 @@ extern void syms_of_minibuf (void);
 /* Defined in callint.c.  */
 
 extern Lisp_Object Qminus, Qplus;
+extern Lisp_Object Qprogn;
 extern Lisp_Object Qwhen;
 extern Lisp_Object Qmouse_leave_buffer_hook;
 extern void syms_of_callint (void);
@@ -4008,8 +4061,7 @@ extern Lisp_Object echo_message_buffer;
 extern struct kboard *echo_kboard;
 extern void cancel_echoing (void);
 extern Lisp_Object Qdisabled, QCfilter;
-extern Lisp_Object Qup, Qdown, Qbottom;
-extern Lisp_Object Qtop;
+extern Lisp_Object Qup, Qdown;
 extern Lisp_Object last_undo_boundary;
 extern bool input_pending;
 extern Lisp_Object menu_bar_items (Lisp_Object);
@@ -4041,14 +4093,11 @@ extern void syms_of_indent (void);
 
 /* Defined in frame.c.  */
 extern Lisp_Object Qonly, Qnone;
-extern Lisp_Object Qvisible;
 extern void set_frame_param (struct frame *, Lisp_Object, Lisp_Object);
 extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
 extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
 extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
-#if HAVE_NS || HAVE_NTGUI
 extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
-#endif
 extern void frames_discard_buffer (Lisp_Object);
 extern void syms_of_frame (void);
 
@@ -4098,12 +4147,9 @@ extern bool running_asynch_code;
 
 /* Defined in process.c.  */
 extern Lisp_Object QCtype, Qlocal;
-extern Lisp_Object Qprocessp;
 extern void kill_buffer_processes (Lisp_Object);
-extern bool wait_reading_process_output (intmax_t, int, int, bool,
-                                        Lisp_Object,
-                                        struct Lisp_Process *,
-                                        int);
+extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object,
+                                       struct Lisp_Process *, int);
 /* Max value for the first argument of wait_reading_process_output.  */
 #if __GNUC__ == 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 5)
 /* Work around a bug in GCC 3.4.2, known to be fixed in GCC 4.6.3.
@@ -4157,9 +4203,8 @@ extern void syms_of_macros (void);
 extern Lisp_Object Qapply;
 extern Lisp_Object Qinhibit_read_only;
 extern void truncate_undo_list (struct buffer *);
-extern void record_marker_adjustment (Lisp_Object, ptrdiff_t);
 extern void record_insert (ptrdiff_t, ptrdiff_t);
-extern void record_delete (ptrdiff_t, Lisp_Object);
+extern void record_delete (ptrdiff_t, Lisp_Object, bool);
 extern void record_first_change (void);
 extern void record_change (ptrdiff_t, ptrdiff_t);
 extern void record_property_change (ptrdiff_t, ptrdiff_t,
@@ -4167,9 +4212,8 @@ extern void record_property_change (ptrdiff_t, ptrdiff_t,
                                     Lisp_Object);
 extern void syms_of_undo (void);
 /* Defined in textprop.c.  */
-extern Lisp_Object Qfont, Qmouse_face;
+extern Lisp_Object Qmouse_face;
 extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks;
-extern Lisp_Object Qfront_sticky, Qrear_nonsticky;
 extern Lisp_Object Qminibuffer_prompt;
 
 extern void report_interval_modification (Lisp_Object, Lisp_Object);
@@ -4192,12 +4236,9 @@ extern char *get_current_dir_name (void);
 #endif
 extern void stuff_char (char c);
 extern void init_foreground_group (void);
-extern void init_sigio (int);
 extern void sys_subshell (void);
 extern void sys_suspend (void);
 extern void discard_tty_input (void);
-extern void block_tty_out_signal (void);
-extern void unblock_tty_out_signal (void);
 extern void init_sys_modes (struct tty_display_info *);
 extern void reset_sys_modes (struct tty_display_info *);
 extern void init_all_sys_modes (void);
@@ -4279,8 +4320,8 @@ extern void syms_of_w32notify (void);
 #endif
 
 /* Defined in xfaces.c.  */
-extern Lisp_Object Qdefault, Qtool_bar, Qfringe;
-extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
+extern Lisp_Object Qdefault, Qfringe;
+extern Lisp_Object Qscroll_bar, Qcursor;
 extern Lisp_Object Qmode_line_inactive;
 extern Lisp_Object Qface;
 extern Lisp_Object Qnormal;
@@ -4339,24 +4380,22 @@ extern void syms_of_profiler (void);
 /* Defined in msdos.c, w32.c.  */
 extern char *emacs_root_dir (void);
 #endif /* DOS_NT */
-\f
-/* True means Emacs has already been initialized.
-   Used during startup to detect startup of dumped Emacs.  */
-extern bool initialized;
 
 /* True means ^G can quit instantly.  */
 extern bool immediate_quit;
 
-extern void *xmalloc (size_t);
-extern void *xzalloc (size_t);
-extern void *xrealloc (void *, size_t);
+extern void *xmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1));
+extern void *xzalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1));
+extern void *xrealloc (void *, size_t) ATTRIBUTE_ALLOC_SIZE ((2));
 extern void xfree (void *);
-extern void *xnmalloc (ptrdiff_t, ptrdiff_t);
-extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
+extern void *xnmalloc (ptrdiff_t, ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1,2));
+extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t)
+  ATTRIBUTE_ALLOC_SIZE ((2,3));
 extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
 
-extern char *xstrdup (const char *);
-extern char *xlispstrdup (Lisp_Object);
+extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
+extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC;
+extern void dupstring (char **, char const *);
 extern void xputenv (const char *);
 
 extern char *egetenv (const char *);
@@ -4387,16 +4426,16 @@ extern void init_system_name (void);
 
 enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
 
-extern void *record_xmalloc (size_t);
+extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
 
 #define USE_SAFE_ALLOCA                        \
-  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = 0
+  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
 
 /* SAFE_ALLOCA allocates a simple buffer.  */
 
 #define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \
                           ? alloca (size)      \
-                          : (sa_must_free = 1, record_xmalloc (size)))
+                          : (sa_must_free = true, record_xmalloc (size)))
 
 /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
    NITEMS items, each of the same type as *BUF.  MULTIPLIER must
@@ -4409,20 +4448,20 @@ extern void *record_xmalloc (size_t);
     else                                                        \
       {                                                                 \
        (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
-       sa_must_free = 1;                                        \
+       sa_must_free = true;                                     \
        record_unwind_protect_ptr (xfree, buf);                  \
       }                                                                 \
-  } while (0)
+  } while (false)
 
 /* SAFE_FREE frees xmalloced memory and enables GC as needed.  */
 
 #define SAFE_FREE()                    \
   do {                                 \
     if (sa_must_free) {                        \
-      sa_must_free = 0;                        \
+      sa_must_free = false;            \
       unbind_to (sa_count, Qnil);      \
     }                                  \
-  } while (0)
+  } while (false)
 
 
 /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects.  */
@@ -4430,39 +4469,40 @@ extern void *record_xmalloc (size_t);
 #define SAFE_ALLOCA_LISP(buf, nelt)                           \
   do {                                                        \
     if ((nelt) < MAX_ALLOCA / word_size)                      \
-      buf = alloca ((nelt) * word_size);                      \
+      (buf) = alloca ((nelt) * word_size);                    \
     else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
       {                                                               \
        Lisp_Object arg_;                                      \
-       buf = xmalloc ((nelt) * word_size);                    \
+       (buf) = xmalloc ((nelt) * word_size);                  \
        arg_ = make_save_memory (buf, nelt);                   \
-       sa_must_free = 1;                                      \
+       sa_must_free = true;                                   \
        record_unwind_protect (free_save_value, arg_);         \
       }                                                               \
     else                                                      \
       memory_full (SIZE_MAX);                                 \
-  } while (0)
+  } while (false)
 
 /* Loop over all tails of a list, checking for cycles.
    FIXME: Make tortoise and n internal declarations.
    FIXME: Unroll the loop body so we don't need `n'.  */
 #define FOR_EACH_TAIL(hare, list, tortoise, n) \
-  for (tortoise = hare = (list), n = true;                     \
+  for ((tortoise) = (hare) = (list), (n) = true;               \
        CONSP (hare);                                           \
-       (hare = XCDR (hare), n = !n,                            \
-       (n                                                      \
-        ? ((EQ (hare, tortoise)                                \
-            && (xsignal1 (Qcircular_list, (list)), 0)))        \
+       (hare = XCDR (hare), (n) = !(n),                                \
+       ((n)                                                    \
+        ? (EQ (hare, tortoise)                                 \
+           ? xsignal1 (Qcircular_list, list)                   \
+           : (void) 0)                                         \
         /* Move tortoise before the next iteration, in case */ \
         /* the next iteration does an Fsetcdr.  */             \
-        : (tortoise = XCDR (tortoise), 0))))
+        : (void) ((tortoise) = XCDR (tortoise)))))
 
 /* Do a `for' loop over alist values.  */
 
 #define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var)            \
-  for (list_var = head_var;                                            \
-       (CONSP (list_var) && (value_var = XCDR (XCAR (list_var)), 1));  \
-       list_var = XCDR (list_var))
+  for ((list_var) = (head_var);                                                \
+       (CONSP (list_var) && ((value_var) = XCDR (XCAR (list_var)), true)); \
+       (list_var) = XCDR (list_var))
 
 /* Check whether it's time for GC, and run it if so.  */
 
@@ -4498,14 +4538,14 @@ functionp (Lisp_Object object)
   if (SUBRP (object))
     return XSUBR (object)->max_args != UNEVALLED;
   else if (COMPILEDP (object))
-    return 1;
+    return true;
   else if (CONSP (object))
     {
       Lisp_Object car = XCAR (object);
       return EQ (car, Qlambda) || EQ (car, Qclosure);
     }
   else
-    return 0;
+    return false;
 }
 
 INLINE_HEADER_END