emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] xwidget cc7cb20 1/2: merge master, fix conflicts


From: Joakim Verona
Subject: [Emacs-diffs] xwidget cc7cb20 1/2: merge master, fix conflicts
Date: Sun, 11 Jan 2015 19:22:21 +0000

branch: xwidget
commit cc7cb20d6abc0f862e5513b24831bba0eaecaa5f
Merge: d972b50 9a57bda
Author: Joakim Verona <address@hidden>
Commit: Joakim Verona <address@hidden>

    merge master, fix conflicts
---
 ChangeLog                                 |   19 +
 INSTALL                                   |    7 +-
 admin/ChangeLog                           |    4 +
 admin/authors.el                          |    1 +
 configure.ac                              |    4 +-
 doc/lispref/display.texi                  |   27 +-
 etc/ChangeLog                             |    9 +
 etc/NEWS                                  |   24 +-
 etc/NEWS.24                               |    3 +
 lib-src/ChangeLog                         |   38 +
 lib-src/make-docfile.c                    |  289 ++++--
 lib/stdio.in.h                            |    7 +-
 lisp/ChangeLog                            |  355 ++++++-
 lisp/cedet/ChangeLog                      |   49 +
 lisp/cedet/ede.el                         |   10 +-
 lisp/cedet/ede/base.el                    |   21 +-
 lisp/cedet/ede/custom.el                  |    4 +-
 lisp/cedet/ede/proj.el                    |    2 +-
 lisp/cedet/ede/project-am.el              |    8 +-
 lisp/cedet/ede/speedbar.el                |    8 +-
 lisp/cedet/semantic.el                    |   87 +-
 lisp/cedet/semantic/bovine/make.el        |    5 +-
 lisp/cedet/semantic/complete.el           |    4 +-
 lisp/cedet/semantic/db-ebrowse.el         |    2 +-
 lisp/cedet/semantic/db-el.el              |    2 +-
 lisp/cedet/semantic/db-file.el            |    3 +-
 lisp/cedet/semantic/db-find.el            |    6 +-
 lisp/cedet/semantic/db-typecache.el       |    2 +-
 lisp/cedet/semantic/db.el                 |    4 +
 lisp/cedet/semantic/ede-grammar.el        |    2 +-
 lisp/cedet/semantic/fw.el                 |   19 +-
 lisp/cedet/semantic/grammar.el            |    9 +-
 lisp/cedet/semantic/scope.el              |    4 +-
 lisp/cedet/srecode/compile.el             |    8 +-
 lisp/cedet/srecode/fields.el              |    2 +-
 lisp/cedet/srecode/insert.el              |   10 +-
 lisp/cedet/srecode/map.el                 |    2 +-
 lisp/emacs-lisp/chart.el                  |   10 +-
 lisp/emacs-lisp/eieio-base.el             |  123 ++-
 lisp/emacs-lisp/eieio-core.el             | 1797 ++++++++---------------------
 lisp/emacs-lisp/eieio-custom.el           |   50 +-
 lisp/emacs-lisp/eieio-datadebug.el        |   14 +-
 lisp/emacs-lisp/eieio-generic.el          |  904 +++++++++++++++
 lisp/emacs-lisp/eieio-opt.el              |  175 +--
 lisp/emacs-lisp/eieio-speedbar.el         |   10 +-
 lisp/emacs-lisp/eieio.el                  |  498 +++++----
 lisp/files.el                             |   32 -
 lisp/gnus/ChangeLog                       |   14 +-
 lisp/gnus/gnus-group.el                   |   42 +-
 lisp/gnus/registry.el                     |    2 +-
 lisp/international/ccl.el                 |   49 +-
 lisp/minibuffer.el                        |   29 +-
 lisp/net/eww.el                           |   15 +-
 lisp/net/shr.el                           |    7 +-
 lisp/progmodes/js.el                      |    5 +-
 lisp/progmodes/xref.el                    |    3 +-
 lisp/shell.el                             |    9 +-
 lisp/simple.el                            |   12 +-
 lisp/subr.el                              |    1 +
 lisp/vc/vc-hooks.el                       |    2 +-
 m4/stdio_h.m4                             |   20 +-
 src/.gdbinit                              |   18 +-
 src/ChangeLog                             |  247 ++++
 src/alloc.c                               |  147 ++-
 src/bidi.c                                |    1 -
 src/buffer.c                              |   41 +-
 src/buffer.h                              |    6 -
 src/bytecode.c                            |    1 -
 src/callint.c                             |   14 +-
 src/casefiddle.c                          |    2 -
 src/casetab.c                             |    1 -
 src/category.c                            |    2 -
 src/ccl.c                                 |   24 +-
 src/ccl.h                                 |    2 -
 src/character.c                           |    6 -
 src/character.h                           |    1 -
 src/charset.c                             |   20 +-
 src/charset.h                             |    3 -
 src/chartab.c                             |    4 +-
 src/cmds.c                                |   13 +-
 src/coding.c                              |   51 +-
 src/coding.h                              |   19 -
 src/composite.c                           |    4 -
 src/composite.h                           |    1 -
 src/conf_post.h                           |    4 +-
 src/data.c                                |   56 -
 src/dbusbind.c                            |   39 +-
 src/decompress.c                          |    2 -
 src/dired.c                               |    8 -
 src/dispextern.h                          |   28 +-
 src/dispnew.c                             |   12 +-
 src/disptab.h                             |    3 -
 src/doc.c                                 |    2 -
 src/dosfns.c                              |    2 -
 src/editfns.c                             |   24 +-
 src/emacs.c                               |    9 +-
 src/eval.c                                |   38 +-
 src/fileio.c                              |   99 +--
 src/fns.c                                 |   22 -
 src/font.c                                |   70 +-
 src/font.h                                |   18 +-
 src/fontset.c                             |    5 -
 src/fontset.h                             |    1 -
 src/frame.c                               |  192 ++--
 src/frame.h                               |   51 -
 src/fringe.c                              |    4 -
 src/ftfont.c                              |    9 +-
 src/ftxfont.c                             |    2 -
 src/gfilenotify.c                         |   56 +-
 src/gnutls.c                              |   23 +-
 src/image.c                               |  109 +--
 src/inotify.c                             |   81 +-
 src/insdel.c                              |    6 +-
 src/intervals.h                           |   16 +-
 src/keyboard.c                            |  257 ++---
 src/keyboard.h                            |   31 -
 src/keymap.c                              |   19 +-
 src/keymap.h                              |    3 -
 src/lisp.h                                |  434 ++++----
 src/lread.c                               |  101 +-
 src/macfont.m                             |   24 +-
 src/macros.c                              |    5 +-
 src/menu.h                                |    4 -
 src/minibuf.c                             |   36 +-
 src/nsfns.m                               |   29 -
 src/nsfont.m                              |    7 +-
 src/nsimage.m                             |    2 -
 src/nsmenu.m                              |    6 -
 src/nsselect.m                            |    2 -
 src/nsterm.h                              |    1 -
 src/nsterm.m                              |   17 +-
 src/print.c                               |   12 +-
 src/process.c                             |   32 +-
 src/process.h                             |    9 -
 src/profiler.c                            |    1 -
 src/search.c                              |    9 +-
 src/sound.c                               |    6 -
 src/syntax.c                              |    8 -
 src/term.c                                |    9 -
 src/terminal.c                            |    4 -
 src/textprop.c                            |   22 +-
 src/undo.c                                |    8 +-
 src/w32.c                                 |    2 -
 src/w32.h                                 |    1 -
 src/w32fns.c                              |   21 +-
 src/w32font.c                             |   47 +-
 src/w32inevt.c                            |    3 +-
 src/w32menu.c                             |    2 -
 src/w32notify.c                           |   10 +-
 src/w32proc.c                             |    2 -
 src/w32select.c                           |    8 +-
 src/w32term.c                             |    9 +-
 src/w32uniscribe.c                        |    4 -
 src/window.c                              |   27 +-
 src/window.h                              |    1 -
 src/xdisp.c                               |  274 ++---
 src/xfaces.c                              |  111 +--
 src/xfns.c                                |   10 +-
 src/xftfont.c                             |    3 -
 src/xmenu.c                               |    3 +-
 src/xml.c                                 |    2 -
 src/xselect.c                             |   16 +-
 src/xsettings.c                           |    2 -
 src/xterm.c                               |    8 -
 src/xterm.h                               |    3 -
 test/ChangeLog                            |   71 +-
 test/automated/eieio-test-methodinvoke.el |   58 +-
 test/automated/eieio-test-persist.el      |   17 +-
 test/automated/eieio-tests.el             |  124 +-
 169 files changed, 4079 insertions(+), 4360 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 36edfe6..cca9100 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2015-01-11  Paul Eggert  <address@hidden>
+
+       Default to 'configure --enable-silent-rules'
+       This greatly shortens the 'make' output, making it more readable
+       and useful.  For example, on my platform it shortens a
+       4125-character line "gcc -std=gnu99 -c -Demacs -I. -I. -I../lib
+       ... emacs.c" -- a line so long that it's hard to see what's going
+       on or where the diagnostics are -- to just "CC emacs.o".
+       * INSTALL: Document this.
+       * configure.ac: Add AM_SILENT_RULES([yes]).
+       (AM_DEFAULT_VERBOSITY): Remove now-unnecessary initialization.
+       Fixes: bug#19501
+
+2015-01-06  Paul Eggert  <address@hidden>
+
+       Merge from gnulib
+       * lib/stdio.in.h, m4/stdio_h.m4: Update from gnulib, incorporating:
+       2015-01-05 stdio: fix use of PRIdMAX on modern mingw
+
 2015-01-04  Paul Eggert  <address@hidden>
 
        * INSTALL: Mention 'make WERROR_CFLAGS='.
diff --git a/INSTALL b/INSTALL
index 1ed2698..5532020 100644
--- a/INSTALL
+++ b/INSTALL
@@ -316,10 +316,9 @@ generated warnings may still be useful, though you may 
prefer building
 with 'make WERROR_CFLAGS=' so that the warnings are not treated as
 errors.
 
-Use --enable-silent-rules to cause 'make' to chatter less.  This is
-helpful when combined with options like --enable-gcc-warnings that
-generate long shell-command lines.  'make V=0' also suppresses the
-chatter.
+Use --disable-silent-rules to cause 'make' to give more details about
+the commands it executes.  This can be helpful when debugging a build
+that goes awry.  'make V=1' also enables the extra chatter.
 
 Use --enable-link-time-optimization to enable link-time optimizer.  If
 you're using GNU compiler, this feature is supported since version 4.5.0.
diff --git a/admin/ChangeLog b/admin/ChangeLog
index 8c0c975..dc029a0 100644
--- a/admin/ChangeLog
+++ b/admin/ChangeLog
@@ -1,3 +1,7 @@
+2015-01-08  Glenn Morris  <address@hidden>
+
+       * authors.el (authors-aliases): Add an entry to ignore.
+
 2015-01-04  Paul Eggert  <address@hidden>
 
        Less 'make' chatter for admin/grammars
diff --git a/admin/authors.el b/admin/authors.el
index 1249806..afab6f0 100644
--- a/admin/authors.el
+++ b/admin/authors.el
@@ -40,6 +40,7 @@ files.")
 
 (defconst authors-aliases
   '(
+    (nil "A\\. N\\. Other")  ; unknown author 2014-12-03, later removed
     ("Aaron S. Hawley" "Aaron Hawley")
     ("Alexandru Harsanyi" "Alex Harsanyi")
     ("Andrew Csillag" "Drew Csillag")
diff --git a/configure.ac b/configure.ac
index 3e2a600..1b2dd3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1013,9 +1013,11 @@ if test "${enableval}" != "no"; then
    fi
 fi)
 
+dnl Prefer silent make output.  For verbose output, use
+dnl 'configure --disable-silent-rules' or 'make V=1' .
+AM_SILENT_RULES([yes])
 dnl Port to Automake 1.11.
 dnl This section can be removed once we assume Automake 1.14 or later.
-: ${AM_DEFAULT_VERBOSITY=1}
 : ${AM_V=$AM_DEFAULT_VERBOSITY}
 : ${AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY}
 AC_SUBST([AM_V])
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index ffe6d7d..1b7f21d 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -87,10 +87,7 @@ waiting for input.
 @defun redisplay &optional force
 This function tries immediately to redisplay.  The optional argument
 @var{force}, if address@hidden, forces the redisplay to be performed,
-instead of being preempted, even if input is pending and the variable
address@hidden is @code{nil} (see below).  If
address@hidden is address@hidden (the default), this
-function redisplays in any case, i.e., @var{force} does nothing.
+instead of being preempted if input is pending.
 
 The function returns @code{t} if it actually tried to redisplay, and
 @code{nil} otherwise.  A value of @code{t} does not mean that
@@ -98,28 +95,6 @@ redisplay proceeded to completion; it could have been 
preempted by
 newly arriving input.
 @end defun
 
address@hidden redisplay-dont-pause
-If this variable is @code{nil}, arriving input events preempt
-redisplay; Emacs avoids starting a redisplay, and stops any redisplay
-that is in progress, until the input has been processed.  In
-particular, @code{(redisplay)} returns @code{nil} without actually
-redisplaying, if there is pending input.
-
-The default value is @code{t}, which means that pending input does not
-preempt redisplay.
address@hidden defvar
-
address@hidden redisplay-preemption-period
-If @code{redisplay-dont-pause} is @code{nil}, this variable specifies
-how many seconds Emacs waits between checks for new input during
-redisplay; if input arrives during this interval, redisplay stops and
-the input is processed.  The default value is 0.1; if the value is
address@hidden, Emacs does not check for input during redisplay.
-
-This variable has no effect when @code{redisplay-dont-pause} is
address@hidden (the default).
address@hidden defvar
-
 @defvar pre-redisplay-function
 A function run just before redisplay.  It is called with one argument,
 the set of windows to redisplay.
diff --git a/etc/ChangeLog b/etc/ChangeLog
index c72c560..20f88bd 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,12 @@
+2015-01-11  Paul Eggert  <address@hidden>
+
+       Default to 'configure --enable-silent-rules'
+       * NEWS: Document this.
+
+2015-01-10  Daniel Colascione  <address@hidden>
+
+       * NEWS: Fix typo
+
 2015-01-04  Paul Eggert  <address@hidden>
 
        batch write-region no longer says "Wrote FOO"
diff --git a/etc/NEWS b/etc/NEWS
index ac42a9f..b3267e1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -40,8 +40,10 @@ or by sticking with Emacs 24.4.
 ** The configure option `--with-pkg-config-prog' has been removed.
 Use './configure PKG_CONFIG=/full/name/of/pkg-config' if you need to.
 
-** The configure option '--enable-silent-rules' and the command
-'make V=0' now do a better job of suppressing chatter.
+** The configure option '--enable-silent-rules' is now the default,
+and silent rules are now quieter.  To get the old behavior where
+'make' chatters a lot, configure with '--disable-silent-rules' or
+build with 'make V=1'.
 
 ---
 ** The `grep-changelog' script (and its manual page) are no longer included.
@@ -141,10 +143,6 @@ this has no effect.
 ** A new text property `inhibit-read-only' can be used in read-only
 buffers to allow certain parts of the text to be writable.
 
-** A new function `file-tree-walk' allows to apply a certain action
-to all the files and subdirectories of a directory, similarly to the C
-library function `ftw'.
-
 ** A new function `directory-files-recursively' returns all matching
 files (recursively) under a directory.
 
@@ -166,6 +164,8 @@ characters, which can be used for geometry-related 
calculations.
 
 * Editing Changes in Emacs 25.1
 
+** Unicode names entered via C-x 8 RET now use substring completion by default.
+
 ** New minor mode global-eldoc-mode is enabled by default.
 
 ** Emacs now supports "bracketed paste mode" when running on a terminal
@@ -191,10 +191,16 @@ Unicode standards.
 
 When you invoke `shell' interactively, the *shell* buffer will now
 display in a new window.  However, you can customize this behavior via
-the new `shell-display-buffer-actions' variable.  For example, to get
+the `display-buffer-alist' variable.  For example, to get
 the old behavior -- *shell* buffer displays in current window -- use
-(setq shell-display-buffer-actions '(display-buffer-same-window)).
+(add-to-list 'display-buffer-alist
+     '("^\\*shell\\*$" . (display-buffer-same-window))).
+
 
+** EIEIO
+*** The <class>-list-p and <class>-child-p functions are declared obsolete.
+*** The <class> variables are declared obsolete.
+*** The <initarg> variables are declared obsolete.
 ** ido
 *** New command `ido-bury-buffer-at-head' bound to C-S-b
 Bury the buffer at the head of `ido-matches', analogous to how C-k
@@ -607,7 +613,7 @@ Horizontal scroll bars are turned off by default.
     `scroll-bar-height'.
 
 +++
-** The height of a frame's menu and tool bar are no more counted in the
+** The height of a frame's menu and tool bar are no longer counted in the
 frame's text height.  This means that the text height stands only for
 the height of the frame's root window plus that of the echo area (if
 present).  This was already the behavior for frames with external tool
diff --git a/etc/NEWS.24 b/etc/NEWS.24
index c33b337..ae0d402 100644
--- a/etc/NEWS.24
+++ b/etc/NEWS.24
@@ -27,6 +27,9 @@ otherwise leave it unmarked.
 ---
 ** The default value of `history-length' has increased to 100.
 
++++
+** `redisplay-dont-pause' is declared as obsolete.
+
 
 * Changes in Specialized Modes and Packages in Emacs 24.5
 
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index acbbd3a..7403596 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,41 @@
+2015-01-10  Paul Eggert  <address@hidden>
+
+       Port to 32-bit --with-wide-int
+       * make-docfile.c (write_globals): Define and use symbols like
+       iQnil (a small integer, like 0) rather than aQnil (an address
+       constant).
+
+       Port to 32-bit Sun C 5.12 sparc
+       * make-docfile.c (close_emacs_globals): Align lispsym to GCALIGNMENT.
+       The alignment is required on all platforms; it just happens to have
+       been properly aligned on the previous platforms we tested.
+
+2015-01-05  Paul Eggert  <address@hidden>
+
+       Use 0 for Qnil
+       * make-docfile.c (compare_globals): Consider 'nil' to be the least.
+
+       Compute C decls for DEFSYMs automatically
+       Fixes Bug#15880.
+       * make-docfile.c: Revamp to generate table of symbols, too.
+       Include <stdbool.h>.
+       (xstrdup): New function.
+       (main): Don't process the same file twice.
+       (SYMBOL): New constant in enum global_type.
+       (struct symbol): Turn 'value' member into a union, either v.value
+       for int or v.svalue for string.  All uses changed.
+       (add_global): New arg svalue, which overrides value, so that globals
+       can have a string value.
+       (close_emacs_global): New arg num_symbols; all uses changed.
+       Output lispsym decl.
+       (write_globals): Output symbol globals too.  Output more
+       ATTRIBUTE_CONST, now that Qnil etc. are C constants.
+       Output defsym_name table.
+       (scan_c_file): Move most of guts into ...
+       (scan_c_stream): ... new function.  Scan for DEFSYMs and
+       record symbols found.  Don't read past EOF if file doesn't
+       end in newline.
+
 2015-01-04  Paul Eggert  <address@hidden>
 
        'temacs -nw' should not call missing functions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index f74b3d5..bc5420e 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -36,6 +36,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>   /* config.h unconditionally includes this anyway */
 
@@ -63,6 +64,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 static int scan_file (char *filename);
 static int scan_lisp_file (const char *filename, const char *mode);
 static int scan_c_file (char *filename, const char *mode);
+static int scan_c_stream (FILE *infile);
 static void start_globals (void);
 static void write_globals (void);
 
@@ -106,6 +108,17 @@ xmalloc (unsigned int size)
   return result;
 }
 
+/* Like strdup, but get fatal error if memory is exhausted.  */
+
+static char *
+xstrdup (char *s)
+{
+  char *result = strdup (s);
+  if (! result)
+    fatal ("virtual memory exhausted", 0);
+  return result;
+}
+
 /* Like realloc but get fatal error if memory is exhausted.  */
 
 static void *
@@ -123,7 +136,6 @@ main (int argc, char **argv)
 {
   int i;
   int err_count = 0;
-  int first_infile;
 
   progname = argv[0];
 
@@ -167,16 +179,21 @@ main (int argc, char **argv)
   if (generate_globals)
     start_globals ();
 
-  first_infile = i;
-  for (; i < argc; i++)
+  if (argc <= i)
+    scan_c_stream (stdin);
+  else
     {
-      int j;
-      /* Don't process one file twice.  */
-      for (j = first_infile; j < i; j++)
-       if (! strcmp (argv[i], argv[j]))
-         break;
-      if (j == i)
-       err_count += scan_file (argv[i]);
+      int first_infile = i;
+      for (; i < argc; i++)
+       {
+         int j;
+         /* Don't process one file twice.  */
+         for (j = first_infile; j < i; j++)
+           if (strcmp (argv[i], argv[j]) == 0)
+             break;
+         if (j == i)
+           err_count += scan_file (argv[i]);
+       }
     }
 
   if (err_count == 0 && generate_globals)
@@ -528,13 +545,15 @@ write_c_args (char *func, char *buf, int minargs, int 
maxargs)
 }
 
 /* The types of globals.  These are sorted roughly in decreasing alignment
-   order to avoid allocation gaps, except that functions are last.  */
+   order to avoid allocation gaps, except that symbols and functions
+   are last.  */
 enum global_type
 {
   INVALID,
   LISP_OBJECT,
   EMACS_INTEGER,
   BOOLEAN,
+  SYMBOL,
   FUNCTION
 };
 
@@ -543,7 +562,11 @@ struct global
 {
   enum global_type type;
   char *name;
-  int value;
+  union
+  {
+    int value;
+    char const *svalue;
+  } v;
 };
 
 /* All the variable names we saw while scanning C sources in `-g'
@@ -553,7 +576,7 @@ int num_globals_allocated;
 struct global *globals;
 
 static void
-add_global (enum global_type type, char *name, int value)
+add_global (enum global_type type, char *name, int value, char const *svalue)
 {
   /* Ignore the one non-symbol that can occur.  */
   if (strcmp (name, "..."))
@@ -574,7 +597,10 @@ add_global (enum global_type type, char *name, int value)
 
       globals[num_globals - 1].type = type;
       globals[num_globals - 1].name = name;
-      globals[num_globals - 1].value = value;
+      if (svalue)
+       globals[num_globals - 1].v.svalue = svalue;
+      else
+       globals[num_globals - 1].v.value = value;
     }
 }
 
@@ -587,21 +613,58 @@ compare_globals (const void *a, const void *b)
   if (ga->type != gb->type)
     return ga->type - gb->type;
 
+  /* Consider "nil" to be the least, so that iQnil is zero.  That
+     way, Qnil's internal representation is zero, which is a bit faster.  */
+  if (ga->type == SYMBOL)
+    {
+      bool a_nil = strcmp (ga->name, "Qnil") == 0;
+      bool b_nil = strcmp (gb->name, "Qnil") == 0;
+      if (a_nil | b_nil)
+       return b_nil - a_nil;
+    }
+
   return strcmp (ga->name, gb->name);
 }
 
 static void
-close_emacs_globals (void)
+close_emacs_globals (int num_symbols)
 {
-  puts ("};");
-  puts ("extern struct emacs_globals globals;");
+  printf (("};\n"
+          "extern struct emacs_globals globals;\n"
+          "\n"
+          "#ifndef DEFINE_SYMBOLS\n"
+          "extern\n"
+          "#endif\n"
+          "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%d];\n"),
+         num_symbols);
 }
 
 static void
 write_globals (void)
 {
-  int i, seen_defun = 0;
+  int i, j;
+  bool seen_defun = false;
+  int symnum = 0;
+  int num_symbols = 0;
   qsort (globals, num_globals, sizeof (struct global), compare_globals);
+
+  j = 0;
+  for (i = 0; i < num_globals; i++)
+    {
+      while (i + 1 < num_globals
+            && strcmp (globals[i].name, globals[i + 1].name) == 0)
+       {
+         if (globals[i].type == FUNCTION
+             && globals[i].v.value != globals[i + 1].v.value)
+           error ("function '%s' defined twice with differing signatures",
+                  globals[i].name);
+         i++;
+       }
+      num_symbols += globals[i].type == SYMBOL;
+      globals[j++] = globals[i];
+    }
+  num_globals = j;
+
   for (i = 0; i < num_globals; ++i)
     {
       char const *type = 0;
@@ -617,12 +680,13 @@ write_globals (void)
        case LISP_OBJECT:
          type = "Lisp_Object";
          break;
+       case SYMBOL:
        case FUNCTION:
          if (!seen_defun)
            {
-             close_emacs_globals ();
+             close_emacs_globals (num_symbols);
              putchar ('\n');
-             seen_defun = 1;
+             seen_defun = true;
            }
          break;
        default:
@@ -635,6 +699,13 @@ write_globals (void)
          printf ("#define %s globals.f_%s\n",
                  globals[i].name, globals[i].name);
        }
+      else if (globals[i].type == SYMBOL)
+       printf (("DEFINE_LISP_SYMBOL_BEGIN (%s)\n"
+                "#define i%s %d\n"
+                "#define %s builtin_lisp_symbol (i%s)\n"
+                "DEFINE_LISP_SYMBOL_END (%s)\n\n"),
+               globals[i].name, globals[i].name, symnum++,
+               globals[i].name, globals[i].name, globals[i].name);
       else
        {
          /* It would be nice to have a cleaner way to deal with these
@@ -647,39 +718,65 @@ write_globals (void)
            fputs ("_Noreturn ", stdout);
 
          printf ("EXFUN (%s, ", globals[i].name);
-         if (globals[i].value == -1)
+         if (globals[i].v.value == -1)
            fputs ("MANY", stdout);
-         else if (globals[i].value == -2)
+         else if (globals[i].v.value == -2)
            fputs ("UNEVALLED", stdout);
          else
-           printf ("%d", globals[i].value);
+           printf ("%d", globals[i].v.value);
          putchar (')');
 
          /* It would be nice to have a cleaner way to deal with these
             special hacks, too.  */
-         if (strcmp (globals[i].name, "Fbyteorder") == 0
+         if (strcmp (globals[i].name, "Fatom") == 0
+             || strcmp (globals[i].name, "Fbyteorder") == 0
+             || strcmp (globals[i].name, "Fcharacterp") == 0
+             || strcmp (globals[i].name, "Fchar_or_string_p") == 0
+             || strcmp (globals[i].name, "Fconsp") == 0
+             || strcmp (globals[i].name, "Feq") == 0
+             || strcmp (globals[i].name, "Fface_attribute_relative_p") == 0
              || strcmp (globals[i].name, "Fframe_windows_min_size") == 0
+             || strcmp (globals[i].name, "Fgnutls_errorp") == 0
              || strcmp (globals[i].name, "Fidentity") == 0
+             || strcmp (globals[i].name, "Fintegerp") == 0
+             || strcmp (globals[i].name, "Finteractive") == 0
+             || strcmp (globals[i].name, "Ffloatp") == 0
+             || strcmp (globals[i].name, "Flistp") == 0
              || strcmp (globals[i].name, "Fmax_char") == 0
-             || strcmp (globals[i].name, "Ftool_bar_height") == 0)
+             || strcmp (globals[i].name, "Fnatnump") == 0
+             || strcmp (globals[i].name, "Fnlistp") == 0
+             || strcmp (globals[i].name, "Fnull") == 0
+             || strcmp (globals[i].name, "Fnumberp") == 0
+             || strcmp (globals[i].name, "Fstringp") == 0
+             || strcmp (globals[i].name, "Fsymbolp") == 0
+             || strcmp (globals[i].name, "Ftool_bar_height") == 0
+             || strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0
+#ifndef WINDOWSNT
+             || strcmp (globals[i].name, "Fgnutls_available_p") == 0
+             || strcmp (globals[i].name, "Fzlib_available_p") == 0
+#endif
+             || 0)
            fputs (" ATTRIBUTE_CONST", stdout);
 
          puts (";");
        }
-
-      while (i + 1 < num_globals
-            && !strcmp (globals[i].name, globals[i + 1].name))
-       {
-         if (globals[i].type == FUNCTION
-             && globals[i].value != globals[i + 1].value)
-           error ("function '%s' defined twice with differing signatures",
-                  globals[i].name);
-         ++i;
-       }
     }
 
   if (!seen_defun)
-    close_emacs_globals ();
+    close_emacs_globals (num_symbols);
+
+  puts ("#ifdef DEFINE_SYMBOLS");
+  puts ("static char const *const defsym_name[] = {");
+  for (int i = 0; i < num_globals; i++)
+    {
+      if (globals[i].type == SYMBOL)
+       printf ("\t\"%s\",\n", globals[i].v.svalue);
+      while (i + 1 < num_globals
+            && strcmp (globals[i].name, globals[i + 1].name) == 0)
+       i++;
+    }
+  puts ("};");
+  puts ("#endif");
 }
 
 
@@ -692,9 +789,6 @@ static int
 scan_c_file (char *filename, const char *mode)
 {
   FILE *infile;
-  register int c;
-  register int commas;
-  int minargs, maxargs;
   int extension = filename[strlen (filename) - 1];
 
   if (extension == 'o')
@@ -720,8 +814,15 @@ scan_c_file (char *filename, const char *mode)
 
   /* Reset extension to be able to detect duplicate files.  */
   filename[strlen (filename) - 1] = extension;
+  return scan_c_stream (infile);
+}
+
+static int
+scan_c_stream (FILE *infile)
+{
+  int commas, minargs, maxargs;
+  int c = '\n';
 
-  c = '\n';
   while (!feof (infile))
     {
       int doc_keyword = 0;
@@ -750,37 +851,53 @@ scan_c_file (char *filename, const char *mode)
          if (c != 'F')
            continue;
          c = getc (infile);
-         if (c != 'V')
-           continue;
-         c = getc (infile);
-         if (c != 'A')
-           continue;
-         c = getc (infile);
-         if (c != 'R')
-           continue;
-         c = getc (infile);
-         if (c != '_')
-           continue;
-
-         defvarflag = 1;
-
-         c = getc (infile);
-         defvarperbufferflag = (c == 'P');
-         if (generate_globals)
+         if (c == 'S')
            {
-             if (c == 'I')
-               type = EMACS_INTEGER;
-             else if (c == 'L')
-               type = LISP_OBJECT;
-             else if (c == 'B')
-               type = BOOLEAN;
+             c = getc (infile);
+             if (c != 'Y')
+               continue;
+             c = getc (infile);
+             if (c != 'M')
+               continue;
+             c = getc (infile);
+             if (c != ' ' && c != '\t' && c != '(')
+               continue;
+             type = SYMBOL;
            }
+         else if (c == 'V')
+           {
+             c = getc (infile);
+             if (c != 'A')
+               continue;
+             c = getc (infile);
+             if (c != 'R')
+               continue;
+             c = getc (infile);
+             if (c != '_')
+               continue;
 
-         c = getc (infile);
-         /* We need to distinguish between DEFVAR_BOOL and
-            DEFVAR_BUFFER_DEFAULTS.  */
-         if (generate_globals && type == BOOLEAN && c != 'O')
-           type = INVALID;
+             defvarflag = 1;
+
+             c = getc (infile);
+             defvarperbufferflag = (c == 'P');
+             if (generate_globals)
+               {
+                 if (c == 'I')
+                   type = EMACS_INTEGER;
+                 else if (c == 'L')
+                   type = LISP_OBJECT;
+                 else if (c == 'B')
+                   type = BOOLEAN;
+               }
+
+             c = getc (infile);
+             /* We need to distinguish between DEFVAR_BOOL and
+                DEFVAR_BUFFER_DEFAULTS.  */
+             if (generate_globals && type == BOOLEAN && c != 'O')
+               type = INVALID;
+           }
+         else
+           continue;
        }
       else if (c == 'D')
        {
@@ -797,7 +914,7 @@ scan_c_file (char *filename, const char *mode)
 
       if (generate_globals
          && (!defvarflag || defvarperbufferflag || type == INVALID)
-         && !defunflag)
+         && !defunflag && type != SYMBOL)
        continue;
 
       while (c != '(')
@@ -807,15 +924,19 @@ scan_c_file (char *filename, const char *mode)
          c = getc (infile);
        }
 
-      /* Lisp variable or function name.  */
-      c = getc (infile);
-      if (c != '"')
-       continue;
-      c = read_c_string_or_comment (infile, -1, 0, 0);
+      if (type != SYMBOL)
+       {
+         /* Lisp variable or function name.  */
+         c = getc (infile);
+         if (c != '"')
+           continue;
+         c = read_c_string_or_comment (infile, -1, 0, 0);
+       }
 
       if (generate_globals)
        {
          int i = 0;
+         char const *svalue = 0;
 
          /* Skip "," and whitespace.  */
          do
@@ -827,6 +948,8 @@ scan_c_file (char *filename, const char *mode)
          /* Read in the identifier.  */
          do
            {
+             if (c < 0)
+               goto eof;
              input_buffer[i++] = c;
              c = getc (infile);
            }
@@ -837,13 +960,27 @@ scan_c_file (char *filename, const char *mode)
          name = xmalloc (i + 1);
          memcpy (name, input_buffer, i + 1);
 
+         if (type == SYMBOL)
+           {
+             do
+               c = getc (infile);
+             while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+             if (c != '"')
+               continue;
+             c = read_c_string_or_comment (infile, -1, 0, 0);
+             svalue = xstrdup (input_buffer);
+           }
+
          if (!defunflag)
            {
-             add_global (type, name, 0);
+             add_global (type, name, 0, svalue);
              continue;
            }
        }
 
+      if (type == SYMBOL)
+       continue;
+
       /* DEFVAR_LISP ("name", addr, "doc")
         DEFVAR_LISP ("name", addr /\* doc *\/)
         DEFVAR_LISP ("name", addr, doc: /\* doc *\/)  */
@@ -896,7 +1033,7 @@ scan_c_file (char *filename, const char *mode)
 
       if (generate_globals)
        {
-         add_global (FUNCTION, name, maxargs);
+         add_global (FUNCTION, name, maxargs, 0);
          continue;
        }
 
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 2a639c4..759c94d 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -84,8 +84,13 @@
    except that it indicates to GCC that the supported format string directives
    are the ones of the system printf(), rather than the ones standardized by
    ISO C99 and POSIX.  */
-#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, 
first_argument) \
+#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU
+# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, 
first_argument) \
+  _GL_ATTRIBUTE_FORMAT_PRINTF (formatstring_parameter, first_argument)
+#else
+# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, 
first_argument) \
   _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument))
+#endif
 
 /* _GL_ATTRIBUTE_FORMAT_SCANF
    indicates to GCC that the function takes a format string and arguments,
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f413526..674b267 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,7 +1,319 @@
+2015-01-10  Lars Magne Ingebrigtsen  <address@hidden>
+
+       * net/shr.el (shr-urlify): Don't bother the user about
+       invalidly-encoded display strings.
+
+2015-01-10  Ivan Shmakov  <address@hidden>
+
+       * net/shr.el (shr-urlify): Decode URLs before using them as titles
+       (bug#19555).
+
+2015-01-10  Lars Magne Ingebrigtsen  <address@hidden>
+
+       * net/eww.el (eww): Always interpret URLs that start with https?:
+       as plain URLs, even if they have spaces in them (bug#19556).
+       (eww): Also interpret things like "en.wikipedia.org/wiki/Free
+       software" as an URL.
+       (eww): Don't interpret "org/foo" as an URL.
+       (eww): Clear the title when loading so that we don't display
+       misleading information.
+
+2015-01-10  Daniel Colascione  <address@hidden>
+
+       * vc/vc-hooks.el (vc-prefix-map): Bind vc-delete-file to C-x v x,
+       by analogy with dired.
+
+2015-01-09  Daniel Colascione  <address@hidden>
+
+       * progmodes/js.el (js--function-heading-1-re)
+       (js--function-prologue-beginning): Parse ES6 generator function
+       declarations.  (That is, "function* name()").
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio.el (defclass): Move from eieio-defclass all the code
+       that creates functions, and most of the sanity checks.
+       Mark as obsolete the <class>-child-p function.
+       * emacs-lisp/eieio-core.el (eieio--define-field-accessors): Remove.
+       (eieio--class, eieio--object): Use cl-defstruct.
+       (eieio--object-num-slots): Define manually.
+       (eieio-defclass-autoload): Use eieio--class-make.
+       (eieio-defclass-internal): Rename from eieio-defclass.  Move all the
+       `(lambda...) definitions and most of the sanity checks to `defclass'.
+       Mark as obsolete the <class>-list-p function, the <class> variable and
+       the <initarg> variables.  Use pcase-dolist.
+       (eieio-defclass): New compatibility function.
+       * emacs-lisp/eieio-opt.el (eieio-build-class-alist)
+       (eieio-class-speedbar): Don't use eieio-default-superclass var.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio-generic.el: New file.
+       * emacs-lisp/eieio-core.el: Move all generic function code to
+       eieio-generic.el.
+       (eieio--defmethod): Declare.
+
+       * emacs-lisp/eieio.el: Require eieio-generic.  Move all generic
+       function code to eieio-generic.el.
+       * emacs-lisp/eieio-opt.el (eieio-help-generic): Move to
+       eieio-generic.el.
+       * emacs-lisp/eieio-datadebug.el (eieio-debug-methodinvoke): Update call
+       to eieio--generic-call.
+       * emacs-lisp/eieio-base.el (eieio-instance-inheritor): Don't use
+       <class>-child type.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/chart.el (chart-add-sequence, chart-bar-quickie):
+       Don't use <class> as a variable.
+
+       * emacs-lisp/eieio.el (same-class-p): Accept class object as well.
+       (call-next-method): Simplify.
+       (clone): Obey eieio-backward-compatibility.
+
+       * emacs-lisp/eieio-opt.el (eieio-read-generic-p): Remove.
+       (eieio-read-generic): Use `generic-p' instead.
+
+       * emacs-lisp/eieio-core.el (eieio-backward-compatibility): New var.
+       (eieio-defclass-autoload): Obey it.
+       (eieio--class-object): Improve error behavior.
+       (eieio-class-children-fast, same-class-fast-p): Remove.  Inline at
+       every use site.
+       (eieio--defgeneric-form-primary-only): Rename from
+       eieio-defgeneric-form-primary-only; update all callers.
+       (eieio--defgeneric-form-primary-only-one): Rename from
+       eieio-defgeneric-form-primary-only-one; update all callers.
+       (eieio-defgeneric-reset-generic-form)
+       (eieio-defgeneric-reset-generic-form-primary-only)
+       (eieio-defgeneric-reset-generic-form-primary-only-one): Remove.
+       (eieio--method-optimize-primary): New function to replace them.
+       (eieio--defmethod, eieio-defmethod): Use it.
+       (eieio--perform-slot-validation): Rename from
+       eieio-perform-slot-validation; update all callers.
+       (eieio--validate-slot-value): Rename from eieio-validate-slot-value.
+       Change `class' to be a class object.  Update all callers.
+       (eieio--validate-class-slot-value): Rename from
+       eieio-validate-class-slot-value.  Change `class' to be a class object.
+       Update all callers.
+       (eieio-oset-default): Accept class object as well.
+       (eieio--generic-call-primary-only): Rename from
+       eieio-generic-call-primary-only.  Update all callers.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
+       Improve error messages.
+       (eieio-persistent-slot-type-is-class-p): Handle `list-of' types, as
+       well as user-defined types.  Emit errors for legacy types like
+       <class>-child and <class>-list, if not eieio-backward-compatibility.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio.el (eieio-class-parents): Accept class objects.
+       (eieio--class-slot-initarg): Rename from class-slot-initarg.
+       Change `class' arg to be a class object.  Update all callers.
+       (call-next-method): Adjust to new return value of `eieio-generic-form'.
+       (eieio-default-superclass): Set var to the class object.
+       (eieio-edebug-prin1-to-string): Fix recursive call for lists.
+       Change print behavior to affect class objects rather than
+       class symbols.
+
+       * emacs-lisp/eieio-core.el (eieio-class-object): New function.
+       (eieio-class-parents-fast): Remove macro.
+       (eieio--class-option-assoc): Rename from class-option-assoc.
+       Update all callers.
+       (eieio--class-option): Rename from class-option.  Change `class' arg to
+       be a class object.  Update all callers.
+       (eieio--class-method-invocation-order): Rename from
+       class-method-invocation-order.  Change `class' arg to be a class
+       object.  Update all callers.
+       (eieio-defclass-autoload, eieio-defclass): Set the `parent' field to
+       a list of class objects rather than names.
+       (eieio-defclass): Remove redundant quotes.  Use `eieio-oref-default'
+       for accessors to class allocated slots.
+       (eieio--perform-slot-validation-for-default): Rename from
+       eieio-perform-slot-validation-for-default.  Update all callers.
+       (eieio--add-new-slot): Rename from eieio-add-new-slot.
+       Update all callers.  Use push.
+       (eieio-copy-parents-into-subclass): Adjust to new content of
+       `parent' field.  Use dolist.
+       (eieio-oref): Remove support for providing a class rather than
+       an object.
+       (eieio-oref-default): Prefer class objects over class names.
+       (eieio--slot-originating-class-p): Rename from
+       eieio-slot-originating-class-p.  Update all callers.  Use `or'.
+       (eieio--slot-name-index): Turn check into assertion.
+       (eieio--class-slot-name-index): Rename from
+       eieio-class-slot-name-index.  Change `class' arg to be a class object.
+       Update all callers.
+       (eieio-attribute-to-initarg): Move to eieio-test-persist.el.
+       (eieio--c3-candidate): Rename from eieio-c3-candidate.
+       Update all callers.
+       (eieio--c3-merge-lists): Rename from eieio-c3-merge-lists.
+       Update all callers.
+       (eieio--class-precedence-c3): Rename from eieio-class-precedence-c3.
+       Update all callers.
+       (eieio--class-precedence-dfs): Rename from eieio-class-precedence-dfs.
+       Update all callers.
+       (eieio--class-precedence-bfs): Rename from eieio-class-precedence-bfs.
+       Update all callers.  Adjust to new `parent' content.
+       (eieio--class-precedence-list): Rename from -class-precedence-list.
+       Update all callers.
+       (eieio-generic-call): Use autoloadp and autoload-do-load.
+       Slight simplification.
+       (eieio-generic-call, eieio-generic-call-primary-only): Adjust to new
+       return value of `eieio-generic-form'.
+       (eieiomt-add): Index the hashtable with class objects rather than
+       class names.
+       (eieio-generic-form): Accept class objects as well.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-convert-list-to-object):
+       Adjust to new convention for eieio-persistent-validate/fix-slot-value.
+       (eieio-persistent-validate/fix-slot-value):
+       Change `class' arg to be a class object.  Update all callers.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio.el (child-of-class-p): Make it accept class objects
+       additionally to class names.
+
+       * emacs-lisp/eieio-core.el (eieio--with-scoped-class): Use let-binding.
+       (object): Remove first (constant) slot; rename second to `class-tag'.
+       (eieio--object-class-object, eieio--object-class-name): New funs
+       to replace eieio--object-class.
+       (eieio--class-object, eieio--class-p): New functions.
+       (same-class-fast-p): Make it a defsubst, change its implementation
+       to check the class objects rather than their names.
+       (eieio-object-p): Rewrite.
+       (eieio-defclass): Adjust the object initialization according to the new
+       object layout.
+       (eieio--scoped-class): Declare it returns a class object (not a class
+       name any more).  Adjust calls accordingly (along with calls to
+       eieio--with-scoped-class).
+       (eieio--slot-name-index): Rename from eieio-slot-name-index and change
+       its class arg to be a class object.  Adjust callers accordingly.
+       (eieio-slot-originating-class-p): Make its start-class arg a class
+       object.  Adjust all callers.
+       (eieio--initarg-to-attribute): Rename from eieio-initarg-to-attribute.
+       Make its `class' arg a class object.  Adjust all callers.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
+       Use eieio--slot-name-index rather than eieio-slot-name-index.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio.el (make-instance): Simplify by not adding an object
+       name argument.
+       (eieio-object-name): Use eieio-object-name-string.
+       (eieio--object-names): New const.
+       (eieio-object-name-string, eieio-object-set-name-string): Re-implement
+       using a hashtable rather than a built-in slot.
+       (eieio-constructor): Rename from `constructor'.  Remove `newname' arg.
+       (clone): Don't mess with the object's "name".
+
+       * emacs-lisp/eieio-custom.el (eieio-widget-test): Remove dummy arg.
+       (eieio-object-value-get): Use eieio-object-set-name-string.
+
+       * emacs-lisp/eieio-core.el (eieio--defalias): Follow aliases.
+       (eieio--object): Remove `name' field.
+       (eieio-defclass): Adjust to new convention where constructors don't
+       take an "object name" any more.
+       (eieio--defgeneric-init-form, eieio--defmethod): Follow aliases.
+       (eieio-validate-slot-value, eieio-oset-default)
+       (eieio-slot-name-index): Don't hardcode eieio--object-num-slots.
+       (eieio-generic-call-primary-only): Simplify.
+
+       * emacs-lisp/eieio-base.el (clone) <eieio-instance-inheritor>:
+       Use call-next-method.
+       (eieio-constructor): Rename from `constructor'.
+       (eieio-persistent-convert-list-to-object): Drop objname.
+       (eieio-persistent-validate/fix-slot-value): Don't hardcode
+       eieio--object-num-slots.
+       (eieio-named): Use a normal slot.
+       (slot-missing) <eieio-named>: Remove.
+       (eieio-object-name-string, eieio-object-set-name-string, clone)
+       <eieio-named>: New methods.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio-core.el (eieio--class-v): Rename from class-v.
+       (method-*): Add a "eieio--" prefix to those constants.
+
+       * emacs-lisp/eieio.el: Move edebug specs to the corresponding macro.
+
+       * emacs-lisp/eieio-speedbar.el: Use lexical-binding.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio.el (child-of-class-p): Fix case where `class' is
+       `eieio-default-superclass'.
+
+       * emacs-lisp/eieio-datadebug.el: Use lexical-binding.
+
+       * emacs-lisp/eieio-custom.el: Use lexical-binding.
+       (eieio-object-value-to-abstract): Simplify.
+
+       * emacs-lisp/eieio-opt.el (eieio-build-class-list): Use cl-mapcan.
+       (eieio-build-class-alist): Use dolist.
+       (eieio-all-generic-functions): Adjust to use of hashtables.
+
+       * emacs-lisp/eieio-core.el (class): Rename field symbol-obarray to
+       symbol-hashtable.  It contains a hashtable instead of an obarray.
+       (generic-p): Use symbol property `eieio-method-hashtable' instead of
+       `eieio-method-obarray'.
+       (generic-primary-only-p, generic-primary-only-one-p):
+       Slight optimization.
+       (eieio-defclass-autoload-map): Use a hashtable instead of an obarray.
+       (eieio-defclass-autoload, eieio-defclass): Adjust/simplify accordingly.
+       (eieio-class-un-autoload): Use autoload-do-load.
+       (eieio-defclass): Use dolist, cl-pushnew, cl-callf.
+       Use new cl-deftype-satisfies.  Adjust to use of hashtables.
+       Don't hardcode the value of eieio--object-num-slots.
+       (eieio-defgeneric-form-primary-only-one): Remove `doc-string' arg.
+       Use a closure rather than a backquoted lambda.
+       (eieio--defmethod): Adjust call accordingly.  Set doc-string via the
+       function-documentation property.
+       (eieio-slot-originating-class-p, eieio-slot-name-index)
+       (eieiomt--optimizing-hashtable, eieiomt-install, eieiomt-add)
+       (eieio-generic-form): Adjust to use of hashtables.
+       (eieiomt--sym-optimize): Rename from eieiomt-sym-optimize; take
+       additional class argument.
+       (eieio-generic-call-methodname): Remove, unused.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-slot-type-is-class-p):
+       Prefer \' to $.
+
+2015-01-08  Eli Zaretskii  <address@hidden>
+
+       * simple.el (line-move-visual): When converting X pixel coordinate
+       to temporary-goal-column, adjust the value for right-to-left
+       screen lines.  This fixes vertical-motion, next/prev-line, etc.
+
+2015-01-08  Glenn Morris  <address@hidden>
+
+       * files.el (file-tree-walk): Remove; of unknown authorship.  (Bug#19325)
+
+2015-01-07  K. Handa  <address@hidden>
+
+       * international/ccl.el (define-ccl-program): Improve the docstring.
+
+2015-01-06  Sam Steingold  <address@hidden>
+
+       * shell.el (shell-display-buffer-actions): Remove,
+       use `display-buffer-alist' instead.
+
+2015-01-05  Dmitry Gutov  <address@hidden>
+
+       * progmodes/xref.el (xref--insert-xrefs): Add `help-echo' property
+       to the references.
+
+2015-01-05  Stefan Monnier  <address@hidden>
+
+       * minibuffer.el (completion-category-defaults): New var.
+       Set unicode-name to use substring completion.
+       (completion-category-defaults): Set it to nil.
+
 2015-01-04  Dmitry Gutov  <address@hidden>
 
        Add mouse interaction to xref.
-
        * progmodes/xref.el (xref--button-map): New variable.
        (xref--mouse-2): New command.
        (xref--insert-xrefs): Add `mouse-face' and `keymap' properties to
@@ -30,7 +342,6 @@
 2015-01-04  Dmitry Gutov  <address@hidden>
 
        Unbreak `mouse-action' property in text buttons.
-
        * button.el (push-button): Fix regression from 2012-12-06.
 
 2015-01-03  Dmitry Gutov  <address@hidden>
@@ -144,11 +455,9 @@
 2014-12-29  Dmitry Gutov  <address@hidden>
 
        Unbreak jumping to an alias's definition.
-
        * emacs-lisp/find-func.el (find-function-library): Return a pair
        (ORIG-FUNCTION . LIBRARY) instead of just its second element.
        (find-function-noselect): Use it.
-
        * progmodes/elisp-mode.el (elisp--xref-identifier-file): Rename to
        `elisp--xref-identifier-location', incorporate logic from
        `elisp--xref-find-definitions', use the changed
@@ -217,7 +526,6 @@
 2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
 
        python.el: Native readline completion.
-
        * progmodes/python.el 
(python-shell-completion-native-disabled-interpreters)
        (python-shell-completion-native-enable)
        (python-shell-completion-native-output-timeout): New defcustoms.
@@ -236,9 +544,8 @@
 
        python.el: Enhance shell user interaction and deprecate
        python-shell-get-or-create-process.
-
-       * progmodes/python.el
-       (python-shell-get-process-or-error): New function.
+       * progmodes/python.el (python-shell-get-process-or-error):
+       New function.
        (python-shell-with-shell-buffer): Use it.
        (python-shell-send-string, python-shell-send-region)
        (python-shell-send-buffer, python-shell-send-defun)
@@ -266,22 +573,15 @@
 2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
 
        python.el: Fix message when sending region.
-
        * progmodes/python.el (python-shell-send-region): Rename argument
        send-main from nomain.  Fix message.
        (python-shell-send-buffer): Rename argument send-main from arg.
 
-2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
-
        python.el: Cleanup temp files even with eval errors.
-
        * progmodes/python.el (python-shell-send-file): Make file-name
        mandatory.  Fix temp file removal in the majority of cases.
 
-2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
-
        python.el: Handle file encoding for shell.
-
        * progmodes/python.el (python-rx-constituents): Add coding-cookie.
        (python-shell--save-temp-file): Write file with proper encoding.
        (python-shell-buffer-substring): Add coding cookie for detected
@@ -343,7 +643,7 @@
 
 2014-12-27  Stefan Monnier  <address@hidden>
 
-       * lisp/subr.el (redisplay-dont-pause): Mark as obsolete.
+       * subr.el (redisplay-dont-pause): Mark as obsolete.
 
 2014-12-27  Michael Albinus  <address@hidden>
 
@@ -416,7 +716,6 @@
 2014-12-26  Fabián Ezequiel Gallina  <address@hidden>
 
        python.el: Generate clearer shell buffer names.
-
        * progmodes/python.el (python-shell-get-process-name)
        (python-shell-internal-get-process-name): Use `buffer-name`.
        (python-shell-internal-get-or-create-process): Simplify.
@@ -539,7 +838,7 @@
 2014-12-19  Alan Mackenzie  <address@hidden>
 
        Make C++11 uniform init syntax work.
-       New keywords "final" and "override"
+       New keywords "final" and "override".
        * progmodes/cc-engine.el (c-back-over-member-initializer-braces):
        New function.
        (c-guess-basic-syntax): Set `containing-sex' and `lim' using the
@@ -575,8 +874,7 @@
 
 2014-12-18  Artur Malabarba  <address@hidden>
 
-       * let-alist.el (let-alist): Evaluate the `alist' argument only
-       once.
+       * let-alist.el (let-alist): Evaluate the `alist' argument only once.
 
 2014-12-18  Sam Steingold  <address@hidden>
 
@@ -590,13 +888,12 @@
        Add code for "preserving" window sizes.
        * dired.el (dired-pop-to-buffer): Call fit-window-to-buffer with
        `preserve-size' t.
-       (dired-mark-pop-up): Preserve size of window showing marked
-       files.
+       (dired-mark-pop-up): Preserve size of window showing marked files.
        * electric.el (Electric-pop-up-window):
        * help.el (resize-temp-buffer-window): Call fit-window-to-buffer
        with `preserve-size' t.
-       * minibuffer.el (minibuffer-completion-help): Use
-       `resize-temp-buffer-window' instead of `fit-window-to-buffer'
+       * minibuffer.el (minibuffer-completion-help):
+       Use `resize-temp-buffer-window' instead of `fit-window-to-buffer'
        (Bug#19355).  Preserve size of completions window.
        * register.el (register-preview): Preserve size of register
        preview window.
@@ -606,8 +903,7 @@
        `window-preserve-size'.
        (window-min-pixel-size, window--preservable-size)
        (window-preserve-size, window-preserved-size)
-       (window--preserve-size, window--min-size-ignore-p): New
-       functions.
+       (window--preserve-size, window--min-size-ignore-p): New functions.
        (window-min-size, window-min-delta, window--resizable)
        (window--resize-this-window, split-window-below)
        (split-window-right): Amend doc-string.
@@ -622,8 +918,7 @@
        window above or below.
        (window--state-put-2): Handle horizontal scroll bars.
        (window--display-buffer): Call `preserve-size' if asked for.
-       (display-buffer): Mention `preserve-size' alist member in
-       doc-string.
+       (display-buffer): Mention `preserve-size' alist member in doc-string.
        (fit-window-to-buffer): New argument PRESERVE-SIZE.
        * textmodes/ispell.el (ispell-command-loop): Suppress horizontal
        scroll bar on ispell's windows.  Don't count window lines and
@@ -711,7 +1006,7 @@
 
 2014-12-14  Alan Mackenzie  <address@hidden>
 
-       * lisp/cus-start.el (all): Add fast-but-imprecise-scrolling.
+       * cus-start.el (all): Add fast-but-imprecise-scrolling.
 
 2014-12-14  Artur Malabarba  <address@hidden>
 
@@ -1857,7 +2152,7 @@
 
 2014-11-19  Artur Malabarba  <address@hidden>
 
-       * lisp/ido.el (ido-bury-buffer-at-head): New command.
+       * ido.el (ido-bury-buffer-at-head): New command.
        (ido-buffer-completion-map): Bind it to C-S-b.
 
 2014-11-18  Juri Linkov  <address@hidden>
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog
index 367ed9f..5c95835 100644
--- a/lisp/cedet/ChangeLog
+++ b/lisp/cedet/ChangeLog
@@ -1,3 +1,52 @@
+2015-01-07  Stefan Monnier  <address@hidden>
+
+       Don't use <class> as a variable and don't assume that <class>-list-p is
+       automatically defined.
+
+       * ede/speedbar.el (ede-speedbar-compile-line)
+       (ede-speedbar-get-top-project-for-line):
+       * ede.el (ede-buffer-belongs-to-target-p)
+       (ede-buffer-belongs-to-project-p, ede-build-forms-menu)
+       (ede-add-project-to-global-list):
+       * semantic/db-typecache.el (semanticdb-get-typecache):
+       * semantic/db-file.el (semanticdb-load-database):
+       * semantic/db-el.el (semanticdb-elisp-sym->tag):
+       * semantic/db-ebrowse.el (semanticdb-ebrowse-load-helper):
+       * ede/project-am.el (project-am-preferred-target-type):
+       * ede/proj.el (ede-proj-load):
+       * ede/custom.el (ede-customize-current-target, ede-customize-target):
+       * semantic/ede-grammar.el ("semantic grammar"):
+       * semantic/scope.el (semantic-scope-reset-cache)
+       (semantic-calculate-scope):
+       * srecode/map.el (srecode-map-update-map):
+       * srecode/insert.el (srecode-insert-show-error-report)
+       (srecode-insert-method, srecode-insert-include-lookup)
+       (srecode-insert-method):
+       * srecode/fields.el (srecode-active-template-region):
+       * srecode/compile.el (srecode-flush-active-templates)
+       (srecode-compile-inserter): Don't use <class> as a variable.
+       Use `oref-default' for class slots.
+
+       * semantic/grammar.el (semantic-grammar-eldoc-last-data): New var.
+       (semantic-grammar-eldoc-get-macro-docstring): Use it instead of
+       eldoc-last-data.
+       * semantic/fw.el (semantic-exit-on-input): Use `declare'.
+       (semantic-throw-on-input): Use `with-current-buffer'.
+       * semantic/db.el (semanticdb-abstract-table-list): Define if not
+       pre-defined.
+       * semantic/db-find.el (semanticdb-find-tags-collector):
+       Use save-current-buffer.
+       (semanticdb-find-tags-collector): Don't use <class> as a variable.
+       * semantic/complete.el (semantic-complete-active-default)
+       (semantic-complete-current-matched-tag): Declare.
+       (semantic-complete-inline-custom-type): Don't use <class> as a variable.
+       * semantic/bovine/make.el (semantic-analyze-possible-completions):
+       Use with-current-buffer.
+       * semantic.el (semantic-parser-warnings): Declare.
+       * ede/base.el (ede-target-list): Define if not pre-defined.
+       (ede-with-projectfile): Prefer find-file-noselect over
+       save-window-excursion.
+
 2014-12-22  Stefan Monnier  <address@hidden>
 
        * srecode/srt-mode.el (srecode-macro-help): Use eieio-class-children.
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el
index edf87f6..87cfb85 100644
--- a/lisp/cedet/ede.el
+++ b/lisp/cedet/ede.el
@@ -248,12 +248,12 @@ Argument LIST-O-O is the list of objects to choose from."
   (let ((obj ede-object))
     (if (consp obj)
        (setq obj (car obj)))
-    (and obj (obj-of-class-p obj ede-target))))
+    (and obj (obj-of-class-p obj 'ede-target))))
 
 (defun ede-buffer-belongs-to-project-p ()
   "Return non-nil if this buffer belongs to at least one project."
   (if (or (null ede-object) (consp ede-object)) nil
-    (obj-of-class-p ede-object-project ede-project)))
+    (obj-of-class-p ede-object-project 'ede-project)))
 
 (defun ede-menu-obj-of-class-p (class)
   "Return non-nil if some member of `ede-object' is a child of CLASS."
@@ -281,7 +281,7 @@ Argument MENU-DEF is the menu definition to use."
        ;; First, collect the build items from the project
        (setq newmenu (append newmenu (ede-menu-items-build obj t)))
        ;; Second, declare the current target menu items
-       (if (and ede-obj (ede-menu-obj-of-class-p ede-target))
+       (if (and ede-obj (ede-menu-obj-of-class-p 'ede-target))
            (while ede-obj
              (setq newmenu (append newmenu
                                    (ede-menu-items-build (car ede-obj) t))
@@ -1078,7 +1078,7 @@ On success, return the added project."
     (error "No project created to add to master list"))
   (when (not (eieio-object-p proj))
     (error "Attempt to add non-object to master project list"))
-  (when (not (obj-of-class-p proj ede-project-placeholder))
+  (when (not (obj-of-class-p proj 'ede-project-placeholder))
     (error "Attempt to add a non-project to the ede projects list"))
   (add-to-list 'ede-projects proj)
   proj)
@@ -1099,6 +1099,8 @@ Flush the dead projects from the project cache."
       (ede-delete-project-from-global-list D))
     ))
 
+(defvar ede--disable-inode)             ;Defined in ede/files.el.
+
 (defun ede-global-list-sanity-check ()
   "Perform a sanity check to make sure there are no duplicate projects."
   (interactive)
diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el
index 9f4fa45..ce7857b 100644
--- a/lisp/cedet/ede/base.el
+++ b/lisp/cedet/ede/base.el
@@ -159,6 +159,9 @@ and querying them will cause the actual project to get 
loaded.")
 ;; Projects can also affect how EDE works, by changing what appears in
 ;; the EDE menu, or how some keys are bound.
 ;;
+(unless (fboundp 'ede-target-list-p)
+  (cl-deftype ede-target-list () '(list-of ede-target)))
+
 (defclass ede-project (ede-project-placeholder)
   ((subproj :initform nil
            :type list
@@ -287,16 +290,18 @@ All specific project types must derive from this project."
 ;;
 (defmacro ede-with-projectfile (obj &rest forms)
   "For the project in which OBJ resides, execute FORMS."
-  `(save-window-excursion
-     (let* ((pf (if (obj-of-class-p ,obj ede-target)
-                   (ede-target-parent ,obj)
-                 ,obj))
-           (dbka (get-file-buffer (oref pf file))))
-       (if (not dbka) (find-file (oref pf file))
-        (switch-to-buffer dbka))
+  (declare (indent 1))
+  (unless (symbolp obj)
+    (message "Beware! ede-with-projectfile's first arg is copied: %S" obj))
+  `(let* ((pf (if (obj-of-class-p ,obj 'ede-target)
+                  (ede-target-parent ,obj)
+                ,obj))
+          (dbka (get-file-buffer (oref pf file))))
+     (with-current-buffer
+         (if (not dbka) (find-file-noselect (oref pf file))
+           dbka)
        ,@forms
        (if (not dbka) (kill-buffer (current-buffer))))))
-(put 'ede-with-projectfile 'lisp-indent-function 1)
 
 ;;; The EDE persistent cache.
 ;;
diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el
index 3cc3a48..a39b488 100644
--- a/lisp/cedet/ede/custom.el
+++ b/lisp/cedet/ede/custom.el
@@ -61,7 +61,7 @@
   "Edit fields of the current target through EIEIO & Custom."
   (interactive)
   (require 'eieio-custom)
-  (if (not (obj-of-class-p ede-object ede-target))
+  (if (not (obj-of-class-p ede-object 'ede-target))
       (error "Current file is not part of a target"))
   (ede-customize-target ede-object))
 
@@ -72,7 +72,7 @@
   "Edit fields of the current target through EIEIO & Custom.
 OBJ is the target object to customize."
   (require 'eieio-custom)
-  (if (and obj (not (obj-of-class-p obj ede-target)))
+  (if (and obj (not (obj-of-class-p obj 'ede-target)))
       (error "No logical target to customize"))
   (ede-customize obj))
 
diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el
index 1ea1657..fd789b3 100644
--- a/lisp/cedet/ede/proj.el
+++ b/lisp/cedet/ede/proj.el
@@ -297,7 +297,7 @@ for the tree being read in.  If ROOTPROJ is nil, then 
assume that
 the PROJECT being read in is the root project."
   (save-excursion
     (let ((ret (eieio-persistent-read (concat project "Project.ede")
-                                     ede-proj-project))
+                                     'ede-proj-project))
          (subdirs (directory-files project nil "[^.].*" nil)))
       (if (not (object-of-class-p ret 'ede-proj-project))
          (error "Corrupt project file"))
diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el
index 75fd195..d0ca809 100644
--- a/lisp/cedet/ede/project-am.el
+++ b/lisp/cedet/ede/project-am.el
@@ -853,13 +853,13 @@ Argument FILE is the file to extract the end directory 
name from."
 (defun project-am-preferred-target-type (file)
   "For FILE, return the preferred type for that file."
   (cond ((string-match "\\.texi?\\(nfo\\)$" file)
-        project-am-texinfo)
+        'project-am-texinfo)
        ((string-match "\\.[0-9]$" file)
-        project-am-man)
+        'project-am-man)
        ((string-match "\\.el$" file)
-        project-am-lisp)
+        'project-am-lisp)
        (t
-        project-am-program)))
+        'project-am-program)))
 
 (defmethod ede-buffer-header-file((this project-am-objectcode) buffer)
   "There are no default header files."
diff --git a/lisp/cedet/ede/speedbar.el b/lisp/cedet/ede/speedbar.el
index fc26ec9..e08562a 100644
--- a/lisp/cedet/ede/speedbar.el
+++ b/lisp/cedet/ede/speedbar.el
@@ -121,9 +121,9 @@ Argument DIR is the directory from which to derive the list 
of objects."
   (let ((obj (eieio-speedbar-find-nearest-object)))
     (if (not (eieio-object-p obj))
        nil
-      (cond ((obj-of-class-p obj ede-project)
+      (cond ((obj-of-class-p obj 'ede-project)
             (project-compile-project obj))
-           ((obj-of-class-p obj ede-target)
+           ((obj-of-class-p obj 'ede-target)
             (project-compile-target obj))
            (t (error "Error in speedbar structure"))))))
 
@@ -133,9 +133,9 @@ Argument DIR is the directory from which to derive the list 
of objects."
   (let ((obj (eieio-speedbar-find-nearest-object)))
     (if (not (eieio-object-p obj))
        (error "Error in speedbar or ede structure")
-      (if (obj-of-class-p obj ede-target)
+      (if (obj-of-class-p obj 'ede-target)
          (setq obj (ede-target-parent obj)))
-      (if (obj-of-class-p obj ede-project)
+      (if (obj-of-class-p obj 'ede-project)
          obj
        (error "Error in speedbar or ede structure")))))
 
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 7afe67b..81a9788 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -573,6 +573,7 @@ string."
 ;; The best way to call the parser from programs is via
 ;; `semantic-fetch-tags'.  This, in turn, uses other internal
 ;; API functions which plug-in parsers can take advantage of.
+(defvar semantic-parser-warnings)
 
 (defun semantic-fetch-tags ()
   "Fetch semantic tags from the current buffer.
@@ -602,49 +603,49 @@ was marked unparseable, then do nothing, and return the 
cache."
      (garbage-collect)
      (cond
 
-;;;; Try the incremental parser to do a fast update.
-     ((semantic-parse-tree-needs-update-p)
-      (setq res (semantic-parse-changes))
-      (if (semantic-parse-tree-needs-rebuild-p)
-          ;; If the partial reparse fails, jump to a full reparse.
-          (semantic-fetch-tags)
-        ;; Clear the cache of unmatched syntax tokens
-        ;;
-        ;; NOTE TO SELF:
-        ;;
-        ;; Move this into the incremental parser.  This is a bug.
-        ;;
-        (semantic-clear-unmatched-syntax-cache)
-        (run-hook-with-args ;; Let hooks know the updated tags
-         'semantic-after-partial-cache-change-hook res))
-      (setq semantic--completion-cache nil))
-
-;;;; Parse the whole system.
-     ((semantic-parse-tree-needs-rebuild-p)
-      ;; Use Emacs's built-in progress-reporter (only interactive).
-      (if noninteractive
-         (setq res (semantic-parse-region (point-min) (point-max)))
-       (let ((semantic--progress-reporter
-              (and (>= (point-max) semantic-minimum-working-buffer-size)
-                   (eq semantic-working-type 'percent)
-                   (make-progress-reporter
-                    (semantic-parser-working-message (buffer-name))
-                    0 100))))
-         (setq res (semantic-parse-region (point-min) (point-max)))
-         (if semantic--progress-reporter
-             (progress-reporter-done semantic--progress-reporter))))
-
-      ;; Clear the caches when we see there were no errors.
-      ;; But preserve the unmatched syntax cache and warnings!
-      (let (semantic-unmatched-syntax-cache
-           semantic-unmatched-syntax-cache-check
-           semantic-parser-warnings)
-       (semantic-clear-toplevel-cache))
-      ;; Set up the new overlays
-      (semantic--tag-link-list-to-buffer res)
-      ;; Set up the cache with the new results
-      (semantic--set-buffer-cache res)
-      ))))
+      ;; Try the incremental parser to do a fast update.
+      ((semantic-parse-tree-needs-update-p)
+       (setq res (semantic-parse-changes))
+       (if (semantic-parse-tree-needs-rebuild-p)
+           ;; If the partial reparse fails, jump to a full reparse.
+           (semantic-fetch-tags)
+         ;; Clear the cache of unmatched syntax tokens
+         ;;
+         ;; NOTE TO SELF:
+         ;;
+         ;; Move this into the incremental parser.  This is a bug.
+         ;;
+         (semantic-clear-unmatched-syntax-cache)
+         (run-hook-with-args ;; Let hooks know the updated tags
+          'semantic-after-partial-cache-change-hook res))
+       (setq semantic--completion-cache nil))
+
+      ;; Parse the whole system.
+      ((semantic-parse-tree-needs-rebuild-p)
+       ;; Use Emacs's built-in progress-reporter (only interactive).
+       (if noninteractive
+           (setq res (semantic-parse-region (point-min) (point-max)))
+         (let ((semantic--progress-reporter
+                (and (>= (point-max) semantic-minimum-working-buffer-size)
+                     (eq semantic-working-type 'percent)
+                     (make-progress-reporter
+                      (semantic-parser-working-message (buffer-name))
+                      0 100))))
+           (setq res (semantic-parse-region (point-min) (point-max)))
+           (if semantic--progress-reporter
+               (progress-reporter-done semantic--progress-reporter))))
+
+       ;; Clear the caches when we see there were no errors.
+       ;; But preserve the unmatched syntax cache and warnings!
+       (let (semantic-unmatched-syntax-cache
+             semantic-unmatched-syntax-cache-check
+             semantic-parser-warnings)
+         (semantic-clear-toplevel-cache))
+       ;; Set up the new overlays
+       (semantic--tag-link-list-to-buffer res)
+       ;; Set up the cache with the new results
+       (semantic--set-buffer-cache res)
+       ))))
 
   ;; Always return the current parse tree.
   semantic--buffer-cache)
diff --git a/lisp/cedet/semantic/bovine/make.el 
b/lisp/cedet/semantic/bovine/make.el
index 6ba02ee..c001a4d 100644
--- a/lisp/cedet/semantic/bovine/make.el
+++ b/lisp/cedet/semantic/bovine/make.el
@@ -178,9 +178,8 @@ This is the same as a regular prototype."
   makefile-mode (context)
   "Return a list of possible completions in a Makefile.
 Uses default implementation, and also gets a list of filenames."
-  (save-excursion
-    (require 'semantic/analyze/complete)
-    (set-buffer (oref context buffer))
+  (require 'semantic/analyze/complete)
+  (with-current-buffer (oref context buffer)
     (let* ((normal (semantic-analyze-possible-completions-default context))
           (classes (oref context :prefixclass))
           (filetags nil))
diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el
index f1fbc75..3f726ee 100644
--- a/lisp/cedet/semantic/complete.el
+++ b/lisp/cedet/semantic/complete.el
@@ -188,6 +188,8 @@ Value should be a ... what?")
   "Default history variable for any unhistoried prompt.
 Keeps STRINGS only in the history.")
 
+(defvar semantic-complete-active-default)
+(defvar semantic-complete-current-matched-tag)
 
 (defun semantic-complete-read-tag-engine (collector displayor prompt
                                                    default-tag initial-input
@@ -1871,7 +1873,7 @@ completion text in ghost text."
               (list 'const
                     :tag doc1
                     C)))
-          (eieio-build-class-alist semantic-displayor-abstract t))
+          (eieio-build-class-alist 'semantic-displayor-abstract t))
          )
   "Possible options for inline completion displayors.
 Use this to enable custom editing.")
diff --git a/lisp/cedet/semantic/db-ebrowse.el 
b/lisp/cedet/semantic/db-ebrowse.el
index 6ed3cdb..2590dd1 100644
--- a/lisp/cedet/semantic/db-ebrowse.el
+++ b/lisp/cedet/semantic/db-ebrowse.el
@@ -192,7 +192,7 @@ is specified by `semanticdb-default-save-directory'."
 If DIRECTORY is found to be defunct, it won't load the DB, and will
 warn instead."
   (if (file-directory-p directory)
-      (semanticdb-create-database semanticdb-project-database-ebrowse
+      (semanticdb-create-database 'semanticdb-project-database-ebrowse
                                  directory)
     (let* ((BF (semanticdb-ebrowse-file-for-directory directory))
           (BFL (concat BF "-load.el"))
diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el
index 8b988be..be9ffe3 100644
--- a/lisp/cedet/semantic/db-el.el
+++ b/lisp/cedet/semantic/db-el.el
@@ -225,7 +225,7 @@ TOKTYPE is a hint to the type of tag desired."
            (semantic-elisp-desymbolify
              ;; FIXME: This only gives the instance slots and ignores the
              ;; class-allocated slots.
-            (eieio--class-public-a (find-class semanticdb-project-database))) 
;; slots ;FIXME: eieio--
+            (eieio--class-public-a (find-class 'semanticdb-project-database))) 
;; slots ;FIXME: eieio--
            (semantic-elisp-desymbolify (eieio-class-parents sym)) ;; parents
            ))
          ((not toktype)
diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el
index 5b76d85..0360e06 100644
--- a/lisp/cedet/semantic/db-file.el
+++ b/lisp/cedet/semantic/db-file.el
@@ -158,7 +158,8 @@ If DIRECTORY doesn't exist, create a new one."
 (defun semanticdb-load-database (filename)
   "Load the database FILENAME."
   (condition-case foo
-      (let* ((r (eieio-persistent-read filename 
semanticdb-project-database-file))
+      (let* ((r (eieio-persistent-read filename
+                                       'semanticdb-project-database-file))
             (c (semanticdb-get-database-tables r))
             (tv (oref r semantic-tag-version))
             (fv (oref r semanticdb-version))
diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el
index 08a22fb..dd36cc1 100644
--- a/lisp/cedet/semantic/db-find.el
+++ b/lisp/cedet/semantic/db-find.el
@@ -1114,7 +1114,7 @@ for backward compatibility.
 If optional argument BRUTISH is non-nil, then ignore include statements,
 and search all tables in this project tree."
   (let (found match)
-    (save-excursion
+    (save-current-buffer
       ;; If path is a buffer, set ourselves up in that buffer
       ;; so that the override methods work correctly.
       (when (bufferp path) (set-buffer path))
@@ -1127,7 +1127,7 @@ and search all tables in this project tree."
            ;; databases and not associated with a file.
            (unless (and find-file-match
                         (obj-of-class-p
-                         (car tableandtags) semanticdb-search-results-table))
+                         (car tableandtags) 'semanticdb-search-results-table))
              (when (setq match (funcall function
                                         (car tableandtags) (cdr tableandtags)))
                (when find-file-match
@@ -1144,7 +1144,7 @@ and search all tables in this project tree."
          ;; `semanticdb-search-results-table', since those are system
          ;; databases and not associated with a file.
          (unless (and find-file-match
-                      (obj-of-class-p table semanticdb-search-results-table))
+                      (obj-of-class-p table 'semanticdb-search-results-table))
            (when (and table (setq match (funcall function table nil)))
              (semanticdb-find-log-activity table match)
              (when find-file-match
diff --git a/lisp/cedet/semantic/db-typecache.el 
b/lisp/cedet/semantic/db-typecache.el
index eb00a57..723b7bd 100644
--- a/lisp/cedet/semantic/db-typecache.el
+++ b/lisp/cedet/semantic/db-typecache.el
@@ -180,7 +180,7 @@ If there is no table, create one, and fill it in."
 (defmethod semanticdb-get-typecache ((db semanticdb-project-database))
   "Retrieve the typecache from the semantic database DB.
 If there is no table, create one, and fill it in."
-  (semanticdb-cache-get db semanticdb-database-typecache)
+  (semanticdb-cache-get db 'semanticdb-database-typecache)
   )
 
 
diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el
index 43e5e5b..b2c1252 100644
--- a/lisp/cedet/semantic/db.el
+++ b/lisp/cedet/semantic/db.el
@@ -330,6 +330,10 @@ Adds the number of tags in this file to the object print 
name."
 
 ;;; DATABASE BASE CLASS
 ;;
+(unless (fboundp 'semanticdb-abstract-table-list-p)
+  (cl-deftype semanticdb-abstract-table-list ()
+    '(list-of semanticdb-abstract-table)))
+
 (defclass semanticdb-project-database (eieio-instance-tracker)
   ((tracking-symbol :initform semanticdb-database-list)
    (reference-directory :type string
diff --git a/lisp/cedet/semantic/ede-grammar.el 
b/lisp/cedet/semantic/ede-grammar.el
index dc3dfa7..67f0cfe 100644
--- a/lisp/cedet/semantic/ede-grammar.el
+++ b/lisp/cedet/semantic/ede-grammar.el
@@ -213,7 +213,7 @@ Argument THIS is the target that should insert stuff."
 ;;   "Target class for Emacs/Semantic grammar files." nil nil)
 
 (ede-proj-register-target "semantic grammar"
-                         semantic-ede-proj-target-grammar)
+                         'semantic-ede-proj-target-grammar)
 
 (provide 'semantic/ede-grammar)
 
diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el
index 56adf3a..a0c3694 100644
--- a/lisp/cedet/semantic/fw.el
+++ b/lisp/cedet/semantic/fw.el
@@ -378,11 +378,11 @@ If FORMS includes a call to `semantic-throw-on-input', 
then
 if a user presses any key during execution, this form macro
 will exit with the value passed to `semantic-throw-on-input'.
 If FORMS completes, then the return value is the same as `progn'."
+  (declare (indent 1))
   `(let ((semantic-current-input-throw-symbol ,symbol)
          (semantic--on-input-start-marker (point-marker)))
      (catch ,symbol
        ,@forms)))
-(put 'semantic-exit-on-input 'lisp-indent-function 1)
 
 (defmacro semantic-throw-on-input (from)
   "Exit with `throw' when in `semantic-exit-on-input' on user input.
@@ -391,15 +391,14 @@ to pass to `throw'.  It is recommended to use the name of 
the function
 calling this one."
   `(when (and semantic-current-input-throw-symbol
               (or (input-pending-p)
-                  (save-excursion
-                    ;; Timers might run during accept-process-output.
-                    ;; If they redisplay, point must be where the user
-                    ;; expects. (Bug#15045)
-                    (set-buffer (marker-buffer
-                                 semantic--on-input-start-marker))
-                    (goto-char (marker-position
-                                semantic--on-input-start-marker))
-                    (accept-process-output))))
+                  (with-current-buffer
+                      ;; Timers might run during accept-process-output.
+                      ;; If they redisplay, point must be where the user
+                      ;; expects. (Bug#15045)
+                      (marker-buffer semantic--on-input-start-marker)
+                    (save-excursion
+                      (goto-char semantic--on-input-start-marker)
+                      (accept-process-output)))))
      (throw semantic-current-input-throw-symbol ,from)))
 
 
diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el
index fc62b22..7a92a12 100644
--- a/lisp/cedet/semantic/grammar.el
+++ b/lisp/cedet/semantic/grammar.el
@@ -1665,13 +1665,14 @@ Select the buffer containing the tag's definition, and 
move point there."
 (declare-function eldoc-get-fnsym-args-string "eldoc")
 (declare-function eldoc-get-var-docstring "eldoc")
 
+(defvar semantic-grammar-eldoc-last-data (cons nil nil))
+
 (defun semantic-grammar-eldoc-get-macro-docstring (macro expander)
   "Return a one-line docstring for the given grammar MACRO.
 EXPANDER is the name of the function that expands MACRO."
   (require 'eldoc)
-  (if (and (eq expander (aref eldoc-last-data 0))
-           (eq 'function (aref eldoc-last-data 2)))
-      (aref eldoc-last-data 1)
+  (if (eq expander (car semantic-grammar-eldoc-last-data))
+      (cdr semantic-grammar-eldoc-last-data)
     (let ((doc (help-split-fundoc (documentation expander t) expander)))
       (cond
        (doc
@@ -1684,7 +1685,7 @@ EXPANDER is the name of the function that expands MACRO."
         (setq doc
              (eldoc-docstring-format-sym-doc
               macro (format "==> %s %s" expander doc) 'default))
-        (eldoc-last-data-store expander doc 'function))
+        (setq semantic-grammar-eldoc-last-data (cons expander doc)))
       doc)))
 
 (define-mode-local-override semantic-idle-summary-current-symbol-info
diff --git a/lisp/cedet/semantic/scope.el b/lisp/cedet/semantic/scope.el
index 2c0dea2..c56cbc3 100644
--- a/lisp/cedet/semantic/scope.el
+++ b/lisp/cedet/semantic/scope.el
@@ -134,7 +134,7 @@ Saves scoping information between runs of the analyzer.")
   "Get the current cached scope, and reset it."
   (when semanticdb-current-table
     (let ((co (semanticdb-cache-get semanticdb-current-table
-                                   semantic-scope-cache)))
+                                   'semantic-scope-cache)))
       (semantic-reset co))))
 
 (defmethod semantic-scope-set-typecache ((cache semantic-scope-cache)
@@ -706,7 +706,7 @@ The class returned from the scope calculation is variable
       (let* ((TAG  (semantic-current-tag))
             (scopecache
              (semanticdb-cache-get semanticdb-current-table
-                                   semantic-scope-cache))
+                                   'semantic-scope-cache))
             )
        (when (not (semantic-equivalent-tag-p TAG (oref scopecache tag)))
          (semantic-reset scopecache))
diff --git a/lisp/cedet/srecode/compile.el b/lisp/cedet/srecode/compile.el
index d899b42..782121e 100644
--- a/lisp/cedet/srecode/compile.el
+++ b/lisp/cedet/srecode/compile.el
@@ -87,10 +87,10 @@ for push, pop, and peek for the active template.")
 Useful if something goes wrong in SRecode, and the active template
 stack is broken."
   (interactive)
-  (if (oref srecode-template active)
+  (if (oref-default 'srecode-template active)
       (when (y-or-n-p (format "%d active templates.  Flush? "
-                             (length (oref srecode-template active))))
-       (oset-default srecode-template active nil))
+                             (length (oref-default 'srecode-template active))))
+       (oset-default 'srecode-template active nil))
     (message "No active templates to flush."))
   )
 
@@ -514,7 +514,7 @@ to the inserter constructor."
   ;;(message "Compile: %s %S" name props)
   (if (not key)
       (apply 'srecode-template-inserter-variable name props)
-    (let ((classes (eieio-class-children srecode-template-inserter))
+    (let ((classes (eieio-class-children 'srecode-template-inserter))
          (new nil))
       ;; Loop over the various subclasses and
       ;; create the correct inserter.
diff --git a/lisp/cedet/srecode/fields.el b/lisp/cedet/srecode/fields.el
index 20852f7..f473a0d 100644
--- a/lisp/cedet/srecode/fields.el
+++ b/lisp/cedet/srecode/fields.el
@@ -237,7 +237,7 @@ If SET-TO is a string, then replace the text of OLAID wit 
SET-TO."
 
 (defsubst srecode-active-template-region ()
   "Return the active region for template fields."
-  (oref srecode-template-inserted-region active-region))
+  (oref-default 'srecode-template-inserted-region active-region))
 
 (defun srecode-field-post-command ()
   "Srecode field handler in the post command hook."
diff --git a/lisp/cedet/srecode/insert.el b/lisp/cedet/srecode/insert.el
index f1f23bc..78ec165 100644
--- a/lisp/cedet/srecode/insert.el
+++ b/lisp/cedet/srecode/insert.el
@@ -211,7 +211,7 @@ insertions."
            (propertize " (most recent at bottom)" 'face '(:slant italic))
            ":\n")
     (data-debug-insert-stuff-list
-     (reverse (oref srecode-template active)) "> ")
+     (reverse (oref-default 'srecode-template active)) "> ")
     ;; Show the current dictionary.
     (insert (propertize "Dictionary" 'face '(:weight bold)) "\n")
     (data-debug-insert-thing dictionary "" "> ")
@@ -396,7 +396,7 @@ Specify the :blank argument to enable this inserter.")
        (pm (point-marker)))
     (when (and inbuff
               ;; Don't do this if we are not the active template.
-              (= (length (oref srecode-template active)) 1))
+              (= (length (oref-default 'srecode-template active)) 1))
 
       (when (and (eq i t) inbuff (not (eq (oref sti where) 'begin)))
        (indent-according-to-mode)
@@ -773,7 +773,7 @@ generalized marker will do something else.  See
   ;; valid. Compare this to the actual template nesting depth and
   ;; maybe use the override function which is stored in the cdr.
   (if (and srecode-template-inserter-point-override
-          (<= (length (oref srecode-template active))
+          (<= (length (oref-default 'srecode-template active))
               (car srecode-template-inserter-point-override)))
       ;; Disable the old override while we do this.
       (let ((over (cdr srecode-template-inserter-point-override))
@@ -943,7 +943,7 @@ this template instance."
     ;; Calculate and store the discovered template
     (let ((tmpl (srecode-template-get-table (srecode-table)
                                            templatenamepart))
-         (active (oref srecode-template active))
+         (active (oref-default 'srecode-template active))
          ctxt)
       (when (not tmpl)
        ;; If it isn't just available, scan back through
@@ -1053,7 +1053,7 @@ template where a ^ inserter occurs."
         (lexical-let ((inserter1 sti))
           (cons
            ;; DEPTH
-           (+ (length (oref srecode-template active)) 1)
+           (+ (length (oref-default 'srecode-template active)) 1)
            ;; FUNCTION
            (lambda (dict)
              (let ((srecode-template-inserter-point-override nil))
diff --git a/lisp/cedet/srecode/map.el b/lisp/cedet/srecode/map.el
index 7224d59..cc0c4ae 100644
--- a/lisp/cedet/srecode/map.el
+++ b/lisp/cedet/srecode/map.el
@@ -298,7 +298,7 @@ if that file is NEW, otherwise assume the mode has not 
changed."
     (when (not srecode-current-map)
       (condition-case nil
          (setq srecode-current-map
-               (eieio-persistent-read srecode-map-save-file srecode-map))
+               (eieio-persistent-read srecode-map-save-file 'srecode-map))
        (error
         ;; There was an error loading the old map.  Create a new one.
         (setq srecode-current-map
diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el
index 62b2b5c..851b3bf 100644
--- a/lisp/emacs-lisp/chart.el
+++ b/lisp/emacs-lisp/chart.el
@@ -422,7 +422,7 @@ or is created with the bounds of SEQ."
        (if (stringp (car (oref seq data)))
            (let ((labels (oref seq data)))
              (if (not axis)
-                 (setq axis (make-instance chart-axis-names
+                 (setq axis (make-instance 'chart-axis-names
                                            :name (oref seq name)
                                            :items labels
                                            :chart c))
@@ -430,7 +430,7 @@ or is created with the bounds of SEQ."
          (let ((range (cons 0 1))
                (l (oref seq data)))
            (if (not axis)
-               (setq axis (make-instance chart-axis-range
+               (setq axis (make-instance 'chart-axis-range
                                          :name (oref seq name)
                                          :chart c)))
            (while l
@@ -577,19 +577,19 @@ labeled NUMTITLE.
 Optional arguments:
 Set the chart's max element display to MAX, and sort lists with
 SORT-PRED if desired."
-  (let ((nc (make-instance chart-bar
+  (let ((nc (make-instance 'chart-bar
                           :title title
                           :key-label "8-m"  ; This is a text key pic
                           :direction dir
                           ))
        (iv (eq dir 'vertical)))
     (chart-add-sequence nc
-                       (make-instance chart-sequece
+                       (make-instance 'chart-sequece
                                       :data namelst
                                       :name nametitle)
                        (if iv 'x-axis 'y-axis))
     (chart-add-sequence nc
-                       (make-instance chart-sequece
+                       (make-instance 'chart-sequece
                                       :data numlst
                                       :name numtitle)
                        (if iv 'y-axis 'x-axis))
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index 7478908..9931fbd 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -40,7 +40,7 @@
 ;; error if a slot is unbound.
 (defclass eieio-instance-inheritor ()
   ((parent-instance :initarg :parent-instance
-                   :type eieio-instance-inheritor-child
+                   :type eieio-instance-inheritor
                    :documentation
                    "The parent of this instance.
 If a slot of this class is referenced, and is unbound, then the parent
@@ -63,25 +63,10 @@ SLOT-NAME is the offending slot.  FN is the function 
signaling the error."
     ;; Throw the regular signal.
     (call-next-method)))
 
-(defmethod clone ((obj eieio-instance-inheritor) &rest params)
+(defmethod clone ((obj eieio-instance-inheritor) &rest _params)
   "Clone OBJ, initializing `:parent' to OBJ.
 All slots are unbound, except those initialized with PARAMS."
-  (let ((nobj (make-vector (length obj) eieio-unbound))
-       (nm (eieio--object-name obj))
-       (passname (and params (stringp (car params))))
-       (num 1))
-    (aset nobj 0 'object)
-    (setf (eieio--object-class nobj) (eieio--object-class obj))
-    ;; The following was copied from the default clone.
-    (if (not passname)
-       (save-match-data
-         (if (string-match "-\\([0-9]+\\)" nm)
-             (setq num (1+ (string-to-number (match-string 1 nm)))
-                   nm (substring nm 0 (match-beginning 0))))
-         (setf (eieio--object-name nobj) (concat nm "-" (int-to-string num))))
-      (setf (eieio--object-name nobj) (car params)))
-    ;; Now initialize from params.
-    (if params (shared-initialize nobj (if passname (cdr params) params)))
+  (let ((nobj (call-next-method)))
     (oset nobj parent-instance obj)
     nobj))
 
@@ -155,7 +140,7 @@ Multiple calls to `make-instance' will return this 
object."))
 A singleton is a class which will only ever have one instance."
   :abstract t)
 
-(defmethod constructor :STATIC ((class eieio-singleton) _name &rest _slots)
+(defmethod eieio-constructor :STATIC ((class eieio-singleton) &rest _slots)
   "Constructor for singleton CLASS.
 NAME and SLOTS initialize the new object.
 This constructor guarantees that no matter how many you request,
@@ -270,7 +255,7 @@ malicious code.
 Note: This function recurses when a slot of :type of some object is
 identified, and needing more object creation."
   (let ((objclass (nth 0 inputlist))
-       (objname (nth 1 inputlist))
+       ;; (objname (nth 1 inputlist))
        (slots (nthcdr 2 inputlist))
        (createslots nil))
 
@@ -285,7 +270,7 @@ identified, and needing more object creation."
        ;; In addition, strip out quotes, list functions, and update
        ;; object constructors as needed.
        (setq value (eieio-persistent-validate/fix-slot-value
-                    objclass name value))
+                    (eieio--class-v objclass) name value))
 
        (push name createslots)
        (push value createslots)
@@ -293,7 +278,7 @@ identified, and needing more object creation."
 
       (setq slots (cdr (cdr slots))))
 
-    (apply 'make-instance objclass objname (nreverse createslots))
+    (apply #'make-instance objclass (nreverse createslots))
 
     ;;(eval inputlist)
     ))
@@ -305,11 +290,13 @@ constructor functions are considered valid.
 Second, any text properties will be stripped from strings."
   (cond ((consp proposed-value)
         ;; Lists with something in them need special treatment.
-        (let ((slot-idx (eieio-slot-name-index class nil slot))
+        (let ((slot-idx (eieio--slot-name-index class
+                                                 nil slot))
               (type nil)
               (classtype nil))
-          (setq slot-idx (- slot-idx 3))
-          (setq type (aref (eieio--class-public-type (class-v class))
+          (setq slot-idx (- slot-idx
+                             (eval-when-compile eieio--object-num-slots)))
+          (setq type (aref (eieio--class-public-type class)
                            slot-idx))
 
           (setq classtype (eieio-persistent-slot-type-is-class-p
@@ -346,8 +333,8 @@ Second, any text properties will be stripped from strings."
                  (unless (and
                           ;; Do we have a type?
                           (consp classtype) (class-p (car classtype)))
-                   (error "In save file, list of object constructors found, 
but no :type specified for slot %S"
-                          slot))
+                   (error "In save file, list of object constructors found, 
but no :type specified for slot %S of type %S"
+                          slot classtype))
 
                  ;; We have a predicate, but it doesn't satisfy the predicate?
                  (dolist (PV (cdr proposed-value))
@@ -375,31 +362,49 @@ Second, any text properties will be stripped from 
strings."
   )
 
 (defun eieio-persistent-slot-type-is-class-p (type)
-  "Return the class refered to in TYPE.
+  "Return the class referred to in TYPE.
 If no class is referenced there, then return nil."
   (cond ((class-p type)
         ;; If the type is a class, then return it.
         type)
-
-       ((and (symbolp type) (string-match "-child$" (symbol-name type))
+       ((and (eq 'list-of (car-safe type)) (class-p (cadr type)))
+        ;; If it is the type of a list of a class, then return that class and
+        ;; the type.
+        (cons (cadr type) type))
+
+        ((and (symbolp type) (get type 'cl-deftype-handler))
+         ;; Macro-expand the type according to cl-deftype definitions.
+         (eieio-persistent-slot-type-is-class-p
+          (funcall (get type 'cl-deftype-handler))))
+
+        ;; FIXME: foo-child should not be a valid type!
+       ((and (symbolp type) (string-match "-child\\'" (symbol-name type))
              (class-p (intern-soft (substring (symbol-name type) 0
                                               (match-beginning 0)))))
+         (unless eieio-backward-compatibility
+           (error "Use of bogus %S type instead of %S"
+                  type (intern-soft (substring (symbol-name type) 0
+                                              (match-beginning 0)))))
         ;; If it is the predicate ending with -child, then return
         ;; that class.  Unfortunately, in EIEIO, typep of just the
         ;; class is the same as if we used -child, so no further work needed.
         (intern-soft (substring (symbol-name type) 0
                                 (match-beginning 0))))
-
-       ((and (symbolp type) (string-match "-list$" (symbol-name type))
+        ;; FIXME: foo-list should not be a valid type!
+       ((and (symbolp type) (string-match "-list\\'" (symbol-name type))
              (class-p (intern-soft (substring (symbol-name type) 0
                                               (match-beginning 0)))))
+         (unless eieio-backward-compatibility
+           (error "Use of bogus %S type instead of (list-of %S)"
+                  type (intern-soft (substring (symbol-name type) 0
+                                              (match-beginning 0)))))
         ;; If it is the predicate ending with -list, then return
         ;; that class and the predicate to use.
         (cons (intern-soft (substring (symbol-name type) 0
                                       (match-beginning 0)))
               type))
 
-       ((and (consp type) (eq (car type) 'or))
+       ((eq (car-safe type) 'or)
         ;; If type is a list, and is an or, it is possibly something
         ;; like (or null myclass), so check for that.
         (let ((ans nil))
@@ -463,34 +468,38 @@ instance."
 
 
 ;;; Named object
-;;
-;; Named objects use the objects `name' as a slot, and that slot
-;; is accessed with the `object-name' symbol.
 
 (defclass eieio-named ()
-  ()
-  "Object with a name.
-Name storage already occurs in an object.  This object provides get/set
-access to it."
+  ((object-name :initarg :object-name :initform nil))
+  "Object with a name."
   :abstract t)
 
-(defmethod slot-missing ((obj eieio-named)
-                        slot-name operation &optional new-value)
-  "Called when a non-existent slot is accessed.
-For variable `eieio-named', provide an imaginary `object-name' slot.
-Argument OBJ is the named object.
-Argument SLOT-NAME is the slot that was attempted to be accessed.
-OPERATION is the type of access, such as `oref' or `oset'.
-NEW-VALUE is the value that was being set into SLOT if OPERATION were
-a set type."
-  (if (memq slot-name '(object-name :object-name))
-      (cond ((eq operation 'oset)
-            (if (not (stringp new-value))
-                (signal 'invalid-slot-type
-                        (list obj slot-name 'string new-value)))
-            (eieio-object-set-name-string obj new-value))
-           (t (eieio-object-name-string obj)))
-    (call-next-method)))
+(defmethod eieio-object-name-string ((obj eieio-named))
+  "Return a string which is OBJ's name."
+  (or (slot-value obj 'object-name)
+      (symbol-name (eieio-object-class obj))))
+
+(defmethod eieio-object-set-name-string ((obj eieio-named) name)
+  "Set the string which is OBJ's NAME."
+  (eieio--check-type stringp name)
+  (eieio-oset obj 'object-name name))
+
+(defmethod clone ((obj eieio-named) &rest params)
+  "Clone OBJ, initializing `:parent' to OBJ.
+All slots are unbound, except those initialized with PARAMS."
+  (let* ((newname (and (stringp (car params)) (pop params)))
+         (nobj (apply #'call-next-method obj params))
+         (nm (slot-value obj 'object-name)))
+    (eieio-oset obj 'object-name
+                (or newname
+                    (save-match-data
+                      (if (and nm (string-match "-\\([0-9]+\\)" nm))
+                          (let ((num (1+ (string-to-number
+                                          (match-string 1 nm)))))
+                            (concat (substring nm 0 (match-beginning 0))
+                                    "-" (int-to-string num)))
+                        (concat nm "-1")))))
+    nobj))
 
 (provide 'eieio-base)
 
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index 68b3765..dc2c873 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -32,6 +32,7 @@
 ;;; Code:
 
 (require 'cl-lib)
+(require 'pcase)
 
 (put 'eieio--defalias 'byte-hunk-handler
      #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
@@ -39,6 +40,9 @@
   "Like `defalias', but with less side-effects.
 More specifically, it has no side-effects at all when the new function
 definition is the same (`eq') as the old one."
+  (while (and (fboundp name) (symbolp (symbol-function name)))
+    ;; Follow aliases, so methods applied to obsolete aliases still work.
+    (setq name (symbol-function name)))
   (unless (and (fboundp name)
                (eq (symbol-function name) body))
     (defalias name body)))
@@ -74,6 +78,13 @@ default setting for optimization purposes.")
 (defvar eieio-initializing-object  nil
   "Set to non-nil while initializing an object.")
 
+(defvar eieio-backward-compatibility t
+  "If nil, drop support for some behaviors of older versions of EIEIO.
+Currently under control of this var:
+- Define every class as a var whose value is the class symbol.
+- Define <class>-child-p and <class>-list-p predicates.
+- Allow object names in constructors.")
+
 (defconst eieio-unbound
   (if (and (boundp 'eieio-unbound) (symbolp eieio-unbound))
       eieio-unbound
@@ -98,96 +109,87 @@ default setting for optimization purposes.")
   "A stack of the classes currently in scope during method invocation.")
 
 (defun eieio--scoped-class ()
-  "Return the class currently in scope, or nil."
+  "Return the class object currently in scope, or nil."
   (car-safe eieio--scoped-class-stack))
 
 (defmacro eieio--with-scoped-class (class &rest forms)
   "Set CLASS as the currently scoped class while executing FORMS."
   (declare (indent 1))
-  `(unwind-protect
-       (progn
-        (push ,class eieio--scoped-class-stack)
-        ,@forms)
-     (pop eieio--scoped-class-stack)))
+  `(let ((eieio--scoped-class-stack (cons ,class eieio--scoped-class-stack)))
+     ,@forms))
+
+(progn
+  ;; Arrange for field access not to bother checking if the access is indeed
+  ;; made to an eieio--class object.
+  (cl-declaim (optimize (safety 0)))
+(cl-defstruct (eieio--class
+               (:constructor nil)
+               (:constructor eieio--class-make (symbol &aux (tag 'defclass)))
+               (:type vector)
+               (:copier nil))
+  ;; We use an untagged cl-struct, with our own hand-made tag as first field
+  ;; (containing the symbol `defclass').  It would be better to use a normal
+  ;; cl-struct with its normal tag (e.g. so that cl-defstruct can define the
+  ;; predicate for us), but that breaks compatibility with .elc files compiled
+  ;; against older versions of EIEIO.
+  tag
+  symbol ;; symbol (self-referencing)
+  parent children
+  symbol-hashtable ;; hashtable permitting fast access to variable position 
indexes
+  ;; @todo
+  ;; the word "public" here is leftovers from the very first version.
+  ;; Get rid of it!
+  public-a                        ;; class attribute index
+  public-d                        ;; class attribute defaults index
+  public-doc                      ;; class documentation strings for attributes
+  public-type                     ;; class type for a slot
+  public-custom                   ;; class custom type for a slot
+  public-custom-label             ;; class custom group for a slot
+  public-custom-group             ;; class custom group for a slot
+  public-printer                  ;; printer for a slot
+  protection                      ;; protection for a slot
+  initarg-tuples                  ;; initarg tuples list
+  class-allocation-a              ;; class allocated attributes
+  class-allocation-doc            ;; class allocated documentation
+  class-allocation-type           ;; class allocated value type
+  class-allocation-custom         ;; class allocated custom descriptor
+  class-allocation-custom-label   ;; class allocated custom descriptor
+  class-allocation-custom-group   ;; class allocated custom group
+  class-allocation-printer        ;; class allocated printer for a slot
+  class-allocation-protection     ;; class allocated protection list
+  class-allocation-values         ;; class allocated value vector
+  default-object-cache ;; what a newly created object would look like.
+                       ; This will speed up instantiation time as
+                       ; only a `copy-sequence' will be needed, instead of
+                       ; looping over all the values and setting them from
+                       ; the default.
+  options ;; storage location of tagged class option
+          ; Stored outright without modifications or stripping
+  )
+  ;; Set it back to the default value.
+  (cl-declaim (optimize (safety 1))))
 
-;;;
-;; Field Accessors
-;;
-(defmacro eieio--define-field-accessors (prefix fields)
-  (declare (indent 1))
-  (let ((index 0)
-        (defs '()))
-    (dolist (field fields)
-      (let ((doc (if (listp field)
-                     (prog1 (cadr field) (setq field (car field))))))
-        (push `(defmacro ,(intern (format "eieio--%s-%s" prefix field)) (x)
-                 ,@(if doc (list (format (if (string-match "\n" doc)
-                                             "Return %s" "Return %s of a %s.")
-                                         doc prefix)))
-                 (list 'aref x ,index))
-              defs)
-        (setq index (1+ index))))
-    `(eval-and-compile
-       ,@(nreverse defs)
-       (defconst ,(intern (format "eieio--%s-num-slots" prefix)) ,index))))
-
-(eieio--define-field-accessors class
-  (-unused-0 ;;FIXME: not sure, but at least there was no accessor!
-   (symbol "symbol (self-referencing)")
-   parent children
-   (symbol-obarray "obarray permitting fast access to variable position 
indexes")
-   ;; @todo
-   ;; the word "public" here is leftovers from the very first version.
-   ;; Get rid of it!
-   (public-a "class attribute index")
-   (public-d "class attribute defaults index")
-   (public-doc "class documentation strings for attributes")
-   (public-type "class type for a slot")
-   (public-custom "class custom type for a slot")
-   (public-custom-label "class custom group for a slot")
-   (public-custom-group "class custom group for a slot")
-   (public-printer "printer for a slot")
-   (protection "protection for a slot")
-   (initarg-tuples "initarg tuples list")
-   (class-allocation-a "class allocated attributes")
-   (class-allocation-doc "class allocated documentation")
-   (class-allocation-type "class allocated value type")
-   (class-allocation-custom "class allocated custom descriptor")
-   (class-allocation-custom-label "class allocated custom descriptor")
-   (class-allocation-custom-group "class allocated custom group")
-   (class-allocation-printer "class allocated printer for a slot")
-   (class-allocation-protection "class allocated protection list")
-   (class-allocation-values "class allocated value vector")
-   (default-object-cache "what a newly created object would look like.
-This will speed up instantiation time as only a `copy-sequence' will
-be needed, instead of looping over all the values and setting them
-from the default.")
-   (options "storage location of tagged class options.
-Stored outright without modifications or stripping.")))
-
-(eieio--define-field-accessors object
-  (-unused-0 ;;FIXME: not sure, but at least there was no accessor!
-   (class "class struct defining OBJ")
-   name))
-
-;; FIXME: The constants below should have an `eieio-' prefix added!!
-
-(defconst method-static 0 "Index into :static tag on a method.")
-(defconst method-before 1 "Index into :before tag on a method.")
-(defconst method-primary 2 "Index into :primary tag on a method.")
-(defconst method-after 3 "Index into :after tag on a method.")
-(defconst method-num-lists 4 "Number of indexes into methods vector in which 
groups of functions are kept.")
-(defconst method-generic-before 4 "Index into generic :before tag on a 
method.")
-(defconst method-generic-primary 5 "Index into generic :primary tag on a 
method.")
-(defconst method-generic-after 6 "Index into generic :after tag on a method.")
-(defconst method-num-slots 7 "Number of indexes into a method's vector.")
-
-(defsubst eieio-specialized-key-to-generic-key (key)
-  "Convert a specialized KEY into a generic method key."
-  (cond ((eq key method-static) 0) ;; don't convert
-       ((< key method-num-lists) (+ key 3)) ;; The conversion
-       (t key) ;; already generic.. maybe.
-       ))
+
+(cl-defstruct (eieio--object
+               (:type vector)           ;We manage our own tagging system.
+               (:constructor nil)
+               (:copier nil))
+  ;; `class-tag' holds a symbol, which is not the class name, but is instead
+  ;; properly prefixed as an internal EIEIO thingy and which holds the class
+  ;; object/struct in its `symbol-value' slot.
+  class-tag)
+
+(eval-and-compile
+  (defconst eieio--object-num-slots
+    (length (get 'eieio--object 'cl-struct-slots))))
+
+(defsubst eieio--object-class-object (obj)
+  (symbol-value (eieio--object-class-tag obj)))
+
+(defsubst eieio--object-class-name (obj)
+  ;; FIXME: Most uses of this function should be changed to use
+  ;; eieio--object-class-object instead!
+  (eieio--class-symbol (eieio--object-class-object obj)))
 
 
 ;;; Important macros used internally in eieio.
@@ -201,114 +203,91 @@ Stored outright without modifications or stripping.")))
               (t `(,type ,obj))))
        (signal 'wrong-type-argument (list ',type ,obj))))
 
-(defmacro class-v (class)
+(defmacro eieio--class-v (class)        ;Use a macro, so it acts as a GV place.
   "Internal: Return the class vector from the CLASS symbol."
+  (declare (debug t))
   ;; No check: If eieio gets this far, it has probably been checked already.
   `(get ,class 'eieio-class-definition))
 
+(defsubst eieio--class-object (class)
+  "Return the class object."
+  (if (symbolp class)
+      ;; Keep the symbol if class-v is nil, for better error messages.
+      (or (eieio--class-v class) class)
+    class))
+
+(defsubst eieio--class-p (class)
+  "Return non-nil if CLASS is a valid class object."
+  (condition-case nil
+      (eq (aref class 0) 'defclass)
+    (error nil)))
+
+(defsubst eieio-class-object (class)
+  "Check that CLASS is a class and return the corresponding object."
+  (let ((c (eieio--class-object class)))
+    (eieio--check-type eieio--class-p c)
+    c))
+
 (defsubst class-p (class)
   "Return non-nil if CLASS is a valid class vector.
-CLASS is a symbol."
+CLASS is a symbol."                     ;FIXME: Is it a vector or a symbol?
   ;; this new method is faster since it doesn't waste time checking lots of
   ;; things.
   (condition-case nil
-      (eq (aref (class-v class) 0) 'defclass)
+      (eq (aref (eieio--class-v class) 0) 'defclass)
     (error nil)))
 
-(defun eieio-class-name (class) "Return a Lisp like symbol name for CLASS."
+(defun eieio-class-name (class)
+  "Return a Lisp like symbol name for CLASS."
+  ;; FIXME: What's a "Lisp like symbol name"?
+  ;; FIXME: CLOS returns a symbol, but the code returns a string.
+  (if (eieio--class-p class) (setq class (eieio--class-symbol class)))
   (eieio--check-type class-p class)
   ;; I think this is supposed to return a symbol, but to me CLASS is a symbol,
   ;; and I wanted a string.  Arg!
   (format "#<class %s>" (symbol-name class)))
 (define-obsolete-function-alias 'class-name #'eieio-class-name "24.4")
 
-(defmacro eieio-class-parents-fast (class)
-  "Return parent classes to CLASS with no check."
-  `(eieio--class-parent (class-v ,class)))
-
-(defmacro eieio-class-children-fast (class) "Return child classes to CLASS 
with no check."
-  `(eieio--class-children (class-v ,class)))
-
-(defmacro same-class-fast-p (obj class)
-  "Return t if OBJ is of class-type CLASS with no error checking."
-  `(eq (eieio--object-class ,obj) ,class))
-
 (defmacro class-constructor (class)
   "Return the symbol representing the constructor of CLASS."
-  `(eieio--class-symbol (class-v ,class)))
-
-(defsubst generic-p (method)
-  "Return non-nil if symbol METHOD is a generic function.
-Only methods have the symbol `eieio-method-obarray' as a property
-\(which contains a list of all bindings to that method type.)"
-  (and (fboundp method) (get method 'eieio-method-obarray)))
-
-(defun generic-primary-only-p (method)
-  "Return t if symbol METHOD is a generic function with only primary methods.
-Only methods have the symbol `eieio-method-obarray' as a property (which
-contains a list of all bindings to that method type.)
-Methods with only primary implementations are executed in an optimized way."
-  (and (generic-p method)
-       (let ((M (get method 'eieio-method-tree)))
-        (and (< 0 (length (aref M method-primary)))
-             (not (aref M method-static))
-             (not (aref M method-before))
-             (not (aref M method-after))
-             (not (aref M method-generic-before))
-             (not (aref M method-generic-primary))
-             (not (aref M method-generic-after))))
-       ))
-
-(defun generic-primary-only-one-p (method)
-  "Return t if symbol METHOD is a generic function with only primary methods.
-Only methods have the symbol `eieio-method-obarray' as a property (which
-contains a list of all bindings to that method type.)
-Methods with only primary implementations are executed in an optimized way."
-  (and (generic-p method)
-       (let ((M (get method 'eieio-method-tree)))
-        (and (= 1 (length (aref M method-primary)))
-             (not (aref M method-static))
-             (not (aref M method-before))
-             (not (aref M method-after))
-             (not (aref M method-generic-before))
-             (not (aref M method-generic-primary))
-             (not (aref M method-generic-after))))
-       ))
-
-(defmacro class-option-assoc (list option)
+  (declare (debug t))
+  `(eieio--class-symbol (eieio--class-v ,class)))
+
+(defmacro eieio--class-option-assoc (list option)
   "Return from LIST the found OPTION, or nil if it doesn't exist."
   `(car-safe (cdr (memq ,option ,list))))
 
-(defmacro class-option (class option)
+(defsubst eieio--class-option (class option)
   "Return the value stored for CLASS' OPTION.
 Return nil if that option doesn't exist."
-  `(class-option-assoc (eieio--class-options (class-v ,class)) ',option))
+  (eieio--class-option-assoc (eieio--class-options class) option))
 
 (defsubst eieio-object-p (obj)
   "Return non-nil if OBJ is an EIEIO object."
-  (condition-case nil
-      (and (eq (aref obj 0) 'object)
-           (class-p (eieio--object-class obj)))
-    (error nil)))
+  (and (arrayp obj)
+       (condition-case nil
+           (eq (aref (eieio--object-class-object obj) 0) 'defclass)
+         (error nil))))
+
 (defalias 'object-p 'eieio-object-p)
 
 (defsubst class-abstract-p (class)
   "Return non-nil if CLASS is abstract.
 Abstract classes cannot be instantiated."
-  (class-option class :abstract))
+  (eieio--class-option (eieio--class-v class) :abstract))
 
-(defmacro class-method-invocation-order (class)
+(defsubst eieio--class-method-invocation-order (class)
   "Return the invocation order of CLASS.
 Abstract classes cannot be instantiated."
-  `(or (class-option ,class :method-invocation-order)
-       :breadth-first))
+  (or (eieio--class-option class :method-invocation-order)
+      :breadth-first))
 
 
 
 ;;;
 ;; Class Creation
 
-(defvar eieio-defclass-autoload-map (make-vector 7 nil)
+(defvar eieio-defclass-autoload-map (make-hash-table)
   "Symbol map of superclasses we find in autoloads.")
 
 ;; We autoload this because it's used in `make-autoload'.
@@ -322,16 +301,12 @@ SUPERCLASSES as children.
 It creates an autoload function for CNAME's constructor."
   ;; Assume we've already debugged inputs.
 
-  (let* ((oldc (when (class-p cname) (class-v cname)))
-        (newc (make-vector eieio--class-num-slots nil))
+  (let* ((oldc (when (class-p cname) (eieio--class-v cname)))
+        (newc (eieio--class-make cname))
         )
     (if oldc
        nil ;; Do nothing if we already have this class.
 
-      ;; Create the class in NEWC, but don't fill anything else in.
-      (aset newc 0 'defclass)
-      (setf (eieio--class-symbol newc) cname)
-
       (let ((clear-parent nil))
        ;; No parents?
        (when (not superclasses)
@@ -348,34 +323,25 @@ It creates an autoload function for CNAME's constructor."
          ;;        map needs to be cleared!
 
 
-         ;; Does our parent exist?
-         (if (not (class-p SC))
-
-             ;; Create a symbol for this parent, and then store this
-             ;; parent on that symbol.
-             (let ((sym (intern (symbol-name SC) eieio-defclass-autoload-map)))
-               (if (not (boundp sym))
-                   (set sym (list cname))
-                 (add-to-list sym cname))
-               )
+          ;; Save the child in the parent.
+          (cl-pushnew cname (if (class-p SC)
+                                (eieio--class-children (eieio--class-v SC))
+                              ;; Parent doesn't exist yet.
+                              (gethash SC eieio-defclass-autoload-map)))
 
-           ;; We have a parent, save the child in there.
-           (when (not (member cname (eieio--class-children (class-v SC))))
-             (setf (eieio--class-children (class-v SC))
-                   (cons cname (eieio--class-children (class-v SC))))))
-
-         ;; save parent in child
-         (setf (eieio--class-parent newc) (cons SC (eieio--class-parent newc)))
-         )
+         ;; Save parent in child.
+          (push (eieio--class-v SC) (eieio--class-parent newc)))
 
        ;; turn this into a usable self-pointing symbol
-       (set cname cname)
+        (when eieio-backward-compatibility
+          (set cname cname)
+          (make-obsolete-variable cname (format "use '%s instead" cname) 
"25.1"))
 
        ;; Store the new class vector definition into the symbol.  We need to
        ;; do this first so that we can call defmethod for the accessor.
        ;; The vector will be updated by the following while loop and will not
        ;; need to be stored a second time.
-       (put cname 'eieio-class-definition newc)
+       (setf (eieio--class-v cname) newc)
 
        ;; Clear the parent
        (if clear-parent (setf (eieio--class-parent newc) nil))
@@ -390,8 +356,7 @@ It creates an autoload function for CNAME's constructor."
 
 (defsubst eieio-class-un-autoload (cname)
   "If class CNAME is in an autoload state, load its file."
-  (when (eq (car-safe (symbol-function cname)) 'autoload)
-    (load-library (car (cdr (symbol-function cname))))))
+  (autoload-do-load (symbol-function cname))) ; cname
 
 (cl-deftype list-of (elem-type)
   `(and list
@@ -399,11 +364,12 @@ It creates an autoload function for CNAME's constructor."
                      (cl-every (lambda (elem) (cl-typep elem ',elem-type))
                                list)))))
 
-(defun eieio-defclass (cname superclasses slots options-and-doc)
-  ;; FIXME: Most of this should be moved to the `defclass' macro.
+(declare-function eieio--defmethod "eieio-generic" (method kind argclass code))
+
+(defun eieio-defclass-internal (cname superclasses slots options)
   "Define CNAME as a new subclass of SUPERCLASSES.
-SLOTS are the slots residing in that class definition, and options or
-documentation OPTIONS-AND-DOC is the toplevel documentation for this class.
+SLOTS are the slots residing in that class definition, and OPTIONS
+holds the class options.
 See `defclass' for more information."
   ;; Run our eieio-hook each time, and clear it when we are done.
   ;; This way people can add hooks safely if they want to modify eieio
@@ -411,18 +377,12 @@ See `defclass' for more information."
   (run-hooks 'eieio-hook)
   (setq eieio-hook nil)
 
-  (eieio--check-type listp superclasses)
-
   (let* ((pname superclasses)
-        (newc (make-vector eieio--class-num-slots nil))
-        (oldc (when (class-p cname) (class-v cname)))
+        (newc (eieio--class-make cname))
+        (oldc (when (class-p cname) (eieio--class-v cname)))
         (groups nil) ;; list of groups id'd from slots
-        (options nil)
         (clearparent nil))
 
-    (aset newc 0 'defclass)
-    (setf (eieio--class-symbol newc) cname)
-
     ;; If this class already existed, and we are updating its structure,
     ;; make sure we keep the old child list.  This can cause bugs, but
     ;; if no new slots are created, it also saves time, and prevents
@@ -430,123 +390,68 @@ See `defclass' for more information."
     ;; byte compiling an EIEIO file.
     (if oldc
        (setf (eieio--class-children newc) (eieio--class-children oldc))
-      ;; If the old class did not exist, but did exist in the autoload map, 
then adopt those children.
-      ;; This is like the above, but deals with autoloads nicely.
-      (let ((sym (intern-soft (symbol-name cname) 
eieio-defclass-autoload-map)))
-       (when sym
-         (condition-case nil
-             (setf (eieio--class-children newc) (symbol-value sym))
-           (error nil))
-         (unintern (symbol-name cname) eieio-defclass-autoload-map)
-         ))
-      )
-
-    (cond ((and (stringp (car options-and-doc))
-               (/= 1 (% (length options-and-doc) 2)))
-          (error "Too many arguments to `defclass'"))
-         ((and (symbolp (car options-and-doc))
-               (/= 0 (% (length options-and-doc) 2)))
-          (error "Too many arguments to `defclass'"))
-         )
-
-    (setq options
-         (if (stringp (car options-and-doc))
-             (cons :documentation options-and-doc)
-           options-and-doc))
+      ;; If the old class did not exist, but did exist in the autoload map,
+      ;; then adopt those children.  This is like the above, but deals with
+      ;; autoloads nicely.
+      (let ((children (gethash cname eieio-defclass-autoload-map)))
+       (when children
+          (setf (eieio--class-children newc) children)
+         (remhash cname eieio-defclass-autoload-map))))
 
     (if pname
        (progn
-         (while pname
-           (if (and (car pname) (symbolp (car pname)))
-               (if (not (class-p (car pname)))
+         (dolist (p pname)
+           (if (and p (symbolp p))
+               (if (not (class-p p))
                    ;; bad class
-                   (error "Given parent class %s is not a class" (car pname))
+                   (error "Given parent class %S is not a class" p)
                  ;; good parent class...
                  ;; save new child in parent
-                 (when (not (member cname (eieio--class-children (class-v (car 
pname)))))
-                   (setf (eieio--class-children (class-v (car pname)))
-                         (cons cname (eieio--class-children (class-v (car 
pname))))))
+                  (cl-pushnew cname (eieio--class-children (eieio--class-v p)))
                  ;; Get custom groups, and store them into our local copy.
                  (mapc (lambda (g) (cl-pushnew g groups :test #'equal))
-                       (class-option (car pname) :custom-groups))
+                       (eieio--class-option (eieio--class-v p) :custom-groups))
                  ;; save parent in child
-                 (setf (eieio--class-parent newc) (cons (car pname) 
(eieio--class-parent newc))))
-             (error "Invalid parent class %s" pname))
-           (setq pname (cdr pname)))
+                  (push (eieio--class-v p) (eieio--class-parent newc)))
+             (error "Invalid parent class %S" p)))
          ;; Reverse the list of our parents so that they are prioritized in
          ;; the same order as specified in the code.
-         (setf (eieio--class-parent newc) (nreverse (eieio--class-parent 
newc))) )
+         (cl-callf nreverse (eieio--class-parent newc)))
       ;; If there is nothing to loop over, then inherit from the
       ;; default superclass.
       (unless (eq cname 'eieio-default-superclass)
        ;; adopt the default parent here, but clear it later...
        (setq clearparent t)
-       ;; save new child in parent
-       (if (not (member cname (eieio--class-children (class-v 
'eieio-default-superclass))))
-           (setf (eieio--class-children (class-v 'eieio-default-superclass))
-                 (cons cname (eieio--class-children (class-v 
'eieio-default-superclass)))))
-       ;; save parent in child
-       (setf (eieio--class-parent newc) (list eieio-default-superclass))))
-
-    ;; turn this into a usable self-pointing symbol
-    (set cname cname)
-
-    ;; These two tests must be created right away so we can have self-
-    ;; referencing classes.  ei, a class whose slot can contain only
-    ;; pointers to itself.
-
-    ;; Create the test function
-    (let ((csym (intern (concat (symbol-name cname) "-p"))))
-      (fset csym
-           (list 'lambda (list 'obj)
-                 (format "Test OBJ to see if it an object of type %s" cname)
-                 (list 'and '(eieio-object-p obj)
-                       (list 'same-class-p 'obj cname)))))
-
-    ;; Make sure the method invocation order  is a valid value.
-    (let ((io (class-option-assoc options :method-invocation-order)))
-      (when (and io (not (member io '(:depth-first :breadth-first :c3))))
-       (error "Method invocation order %s is not allowed" io)
-       ))
+        ;; save new child in parent
+        (cl-pushnew cname (eieio--class-children eieio-default-superclass))
+        ;; save parent in child
+        (setf (eieio--class-parent newc) (list eieio-default-superclass))))
 
-    ;; Create a handy child test too
-    (let ((csym (intern (concat (symbol-name cname) "-child-p"))))
-      (fset csym
-           `(lambda (obj)
-              ,(format
-                 "Test OBJ to see if it an object is a child of type %s"
-                 cname)
-              (and (eieio-object-p obj)
-                   (object-of-class-p obj ,cname))))
+    ;; turn this into a usable self-pointing symbol;  FIXME: Why?
+    (when eieio-backward-compatibility
+      (set cname cname)
+      (make-obsolete-variable cname (format "use '%s instead" cname) "25.1"))
 
     ;; Create a handy list of the class test too
-    (let ((csym (intern (concat (symbol-name cname) "-list-p"))))
-      (fset csym
-           `(lambda (obj)
-              ,(format
-                 "Test OBJ to see if it a list of objects which are a child of 
type %s"
-                 cname)
-              (when (listp obj)
-                (let ((ans t)) ;; nil is valid
-                  ;; Loop over all the elements of the input list, test
-                  ;; each to make sure it is a child of the desired object 
class.
-                  (while (and obj ans)
-                    (setq ans (and (eieio-object-p (car obj))
-                                   (object-of-class-p (car obj) ,cname)))
-                    (setq obj (cdr obj)))
-                  ans)))))
-
-      ;; When using typep, (typep OBJ 'myclass) returns t for objects which
-      ;; are subclasses of myclass.  For our predicates, however, it is
-      ;; important for EIEIO to be backwards compatible, where
-      ;; myobject-p, and myobject-child-p are different.
-      ;; "cl" uses this technique to specify symbols with specific typep
-      ;; test, so we can let typep have the CLOS documented behavior
-      ;; while keeping our above predicate clean.
-
-      ;; FIXME: It would be cleaner to use `cl-deftype' here.
-      (put cname 'cl-deftype-handler
-          (list 'lambda () `(list 'satisfies (quote ,csym)))))
+    (when eieio-backward-compatibility
+      (let ((csym (intern (concat (symbol-name cname) "-list-p"))))
+        (defalias csym
+              `(lambda (obj)
+                 ,(format
+                   "Test OBJ to see if it a list of objects which are a child 
of type %s"
+                   cname)
+                 (when (listp obj)
+                   (let ((ans t)) ;; nil is valid
+                     ;; Loop over all the elements of the input list, test
+                     ;; each to make sure it is a child of the desired object 
class.
+                     (while (and obj ans)
+                       (setq ans (and (eieio-object-p (car obj))
+                                      (object-of-class-p (car obj) ,cname)))
+                       (setq obj (cdr obj)))
+                     ans))))
+        (make-obsolete csym (format "use (cl-typep ... '(list-of %s)) instead"
+                                    cname)
+                       "25.1")))
 
     ;; Before adding new slots, let's add all the methods and classes
     ;; in from the parent class.
@@ -556,78 +461,45 @@ See `defclass' for more information."
     ;; do this first so that we can call defmethod for the accessor.
     ;; The vector will be updated by the following while loop and will not
     ;; need to be stored a second time.
-    (put cname 'eieio-class-definition newc)
+    (setf (eieio--class-v cname) newc)
 
     ;; Query each slot in the declaration list and mangle into the
     ;; class structure I have defined.
-    (while slots
-      (let* ((slot1  (car slots))
-            (name    (car slot1))
-            (slot   (cdr slot1))
-            (acces   (plist-get slot ':accessor))
-            (init    (or (plist-get slot ':initform)
-                         (if (member ':initform slot) nil
+    (pcase-dolist (`(,name . ,slot) slots)
+      (let* ((init    (or (plist-get slot :initform)
+                         (if (member :initform slot) nil
                            eieio-unbound)))
-            (initarg (plist-get slot ':initarg))
-            (docstr  (plist-get slot ':documentation))
-            (prot    (plist-get slot ':protection))
-            (reader  (plist-get slot ':reader))
-            (writer  (plist-get slot ':writer))
-            (alloc   (plist-get slot ':allocation))
-            (type    (plist-get slot ':type))
-            (custom  (plist-get slot ':custom))
-            (label   (plist-get slot ':label))
-            (customg (plist-get slot ':group))
-            (printer (plist-get slot ':printer))
-
-            (skip-nil (class-option-assoc options :allow-nil-initform))
+            (initarg (plist-get slot :initarg))
+            (docstr  (plist-get slot :documentation))
+            (prot    (plist-get slot :protection))
+            (alloc   (plist-get slot :allocation))
+            (type    (plist-get slot :type))
+            (custom  (plist-get slot :custom))
+            (label   (plist-get slot :label))
+            (customg (plist-get slot :group))
+            (printer (plist-get slot :printer))
+
+            (skip-nil (eieio--class-option-assoc options :allow-nil-initform))
             )
 
-       (if eieio-error-unsupported-class-tags
-           (let ((tmp slot))
-             (while tmp
-               (if (not (member (car tmp) '(:accessor
-                                            :initform
-                                            :initarg
-                                            :documentation
-                                            :protection
-                                            :reader
-                                            :writer
-                                            :allocation
-                                            :type
-                                            :custom
-                                            :label
-                                            :group
-                                            :printer
-                                            :allow-nil-initform
-                                            :custom-groups)))
-                   (signal 'invalid-slot-type (list (car tmp))))
-               (setq tmp (cdr (cdr tmp))))))
-
        ;; Clean up the meaning of protection.
-       (cond ((or (eq prot 'public) (eq prot :public)) (setq prot nil))
-             ((or (eq prot 'protected) (eq prot :protected)) (setq prot 
'protected))
-             ((or (eq prot 'private) (eq prot :private)) (setq prot 'private))
-             ((eq prot nil) nil)
-             (t (signal 'invalid-slot-type (list ':protection prot))))
-
-       ;; Make sure the :allocation parameter has a valid value.
-       (if (not (or (not alloc) (eq alloc :class) (eq alloc :instance)))
-           (signal 'invalid-slot-type (list ':allocation alloc)))
+        (setq prot
+              (pcase prot
+                ((or 'nil 'public ':public) nil)
+                ((or 'protected ':protected) 'protected)
+                ((or 'private ':private) 'private)
+                (_ (signal 'invalid-slot-type (list :protection prot)))))
 
        ;; The default type specifier is supposed to be t, meaning anything.
        (if (not type) (setq type t))
 
-       ;; Label is nil, or a string
-       (if (not (or (null label) (stringp label)))
-           (signal 'invalid-slot-type (list ':label label)))
-
-       ;; Is there an initarg, but allocation of class?
-       (if (and initarg (eq alloc :class))
-           (message "Class allocated slots do not need :initarg"))
-
        ;; intern the symbol so we can use it blankly
-       (if initarg (set initarg initarg))
+        (if eieio-backward-compatibility
+            (and initarg (not (keywordp initarg))
+                 (progn
+                   (set initarg initarg)
+                   (make-obsolete-variable
+                    initarg (format "use '%s instead" initarg) "25.1"))))
 
        ;; The customgroup should be a list of symbols
        (cond ((null customg)
@@ -637,131 +509,60 @@ See `defclass' for more information."
        ;; The customgroup better be a symbol, or list of symbols.
        (mapc (lambda (cg)
                (if (not (symbolp cg))
-                   (signal 'invalid-slot-type (list ':group cg))))
+                   (signal 'invalid-slot-type (list :group cg))))
                customg)
 
        ;; First up, add this slot into our new class.
-       (eieio-add-new-slot newc name init docstr type custom label customg 
printer
+       (eieio--add-new-slot newc name init docstr type custom label customg 
printer
                             prot initarg alloc 'defaultoverride skip-nil)
 
        ;; We need to id the group, and store them in a group list attribute.
-       (mapc (lambda (cg) (cl-pushnew cg groups :test 'equal)) customg)
-
-       ;; Anyone can have an accessor function.  This creates a function
-       ;; of the specified name, and also performs a `defsetf' if applicable
-       ;; so that users can `setf' the space returned by this function.
-       (if acces
-           (progn
-             (eieio--defmethod
-               acces (if (eq alloc :class) :static :primary) cname
-               `(lambda (this)
-                  ,(format
-                      "Retrieves the slot `%s' from an object of class `%s'"
-                      name cname)
-                  (if (slot-boundp this ',name)
-                      (eieio-oref this ',name)
-                           ;; Else - Some error?  nil?
-                           nil)))
-
-              ;; FIXME: We should move more of eieio-defclass into the
-              ;; defclass macro so we don't have to use `eval' and require
-              ;; `gv' at run-time.
-              (eval `(gv-define-setter ,acces (eieio--store eieio--object)
-                       (list 'eieio-oset eieio--object '',name
-                             eieio--store)))))
-
-       ;; If a writer is defined, then create a generic method of that
-       ;; name whose purpose is to set the value of the slot.
-       (if writer
-            (eieio--defmethod
-             writer nil cname
-             `(lambda (this value)
-                ,(format "Set the slot `%s' of an object of class `%s'"
-                             name cname)
-                (setf (slot-value this ',name) value))))
-       ;; If a reader is defined, then create a generic method
-       ;; of that name whose purpose is to access this slot value.
-       (if reader
-            (eieio--defmethod
-             reader nil cname
-             `(lambda (this)
-                ,(format "Access the slot `%s' from object of class `%s'"
-                             name cname)
-                (slot-value this ',name))))
-       )
-      (setq slots (cdr slots)))
+       (dolist (cg customg)
+          (cl-pushnew cg groups :test 'equal))
+       ))
 
     ;; Now that everything has been loaded up, all our lists are backwards!
     ;; Fix that up now.
-    (setf (eieio--class-public-a newc) (nreverse (eieio--class-public-a newc)))
-    (setf (eieio--class-public-d newc) (nreverse (eieio--class-public-d newc)))
-    (setf (eieio--class-public-doc newc) (nreverse (eieio--class-public-doc 
newc)))
-    (setf (eieio--class-public-type newc)
-         (apply #'vector (nreverse (eieio--class-public-type newc))))
-    (setf (eieio--class-public-custom newc) (nreverse 
(eieio--class-public-custom newc)))
-    (setf (eieio--class-public-custom-label newc) (nreverse 
(eieio--class-public-custom-label newc)))
-    (setf (eieio--class-public-custom-group newc) (nreverse 
(eieio--class-public-custom-group newc)))
-    (setf (eieio--class-public-printer newc) (nreverse 
(eieio--class-public-printer newc)))
-    (setf (eieio--class-protection newc) (nreverse (eieio--class-protection 
newc)))
-    (setf (eieio--class-initarg-tuples newc) (nreverse 
(eieio--class-initarg-tuples newc)))
+    (cl-callf nreverse (eieio--class-public-a newc))
+    (cl-callf nreverse (eieio--class-public-d newc))
+    (cl-callf nreverse (eieio--class-public-doc newc))
+    (cl-callf (lambda (types) (apply #'vector (nreverse types)))
+        (eieio--class-public-type newc))
+    (cl-callf nreverse (eieio--class-public-custom newc))
+    (cl-callf nreverse (eieio--class-public-custom-label newc))
+    (cl-callf nreverse (eieio--class-public-custom-group newc))
+    (cl-callf nreverse (eieio--class-public-printer newc))
+    (cl-callf nreverse (eieio--class-protection newc))
+    (cl-callf nreverse (eieio--class-initarg-tuples newc))
 
     ;; The storage for class-class-allocation-type needs to be turned into
     ;; a vector now.
-    (setf (eieio--class-class-allocation-type newc)
-         (apply #'vector (eieio--class-class-allocation-type newc)))
+    (cl-callf (lambda (cat) (apply #'vector cat))
+        (eieio--class-class-allocation-type newc))
 
     ;; Also, take class allocated values, and vectorize them for speed.
-    (setf (eieio--class-class-allocation-values newc)
-         (apply #'vector (eieio--class-class-allocation-values newc)))
-
-    ;; Attach slot symbols into an obarray, and store the index of
-    ;; this slot as the variable slot in this new symbol.  We need to
-    ;; know about primes, because obarrays are best set in vectors of
-    ;; prime number length, and we also need to make our vector small
-    ;; to save space, and also optimal for the number of items we have.
+    (cl-callf (lambda (cavs) (apply #'vector cavs))
+        (eieio--class-class-allocation-values newc))
+
+    ;; Attach slot symbols into a hashtable, and store the index of
+    ;; this slot as the value this table.
     (let* ((cnt 0)
           (pubsyms (eieio--class-public-a newc))
           (prots (eieio--class-protection newc))
-          (l (length pubsyms))
-          (vl (let ((primes '( 3 5 7 11 13 17 19 23 29 31 37 41 43 47
-                                 53 59 61 67 71 73 79 83 89 97 101 )))
-                (while (and primes (< (car primes) l))
-                  (setq primes (cdr primes)))
-                (car primes)))
-          (oa (make-vector vl 0))
-          (newsym))
+          (oa (make-hash-table :test #'eq)))
       (while pubsyms
-       (setq newsym (intern (symbol-name (car pubsyms)) oa))
-       (set newsym cnt)
-       (setq cnt (1+ cnt))
-       (if (car prots) (put newsym 'protection (car prots)))
+       (let ((newsym (list cnt)))
+          (setf (gethash (car pubsyms) oa) newsym)
+          (setq cnt (1+ cnt))
+          (if (car prots) (setcdr newsym (car prots))))
        (setq pubsyms (cdr pubsyms)
              prots (cdr prots)))
-      (setf (eieio--class-symbol-obarray newc) oa)
-      )
-
-    ;; Create the constructor function
-    (if (class-option-assoc options :abstract)
-       ;; Abstract classes cannot be instantiated.  Say so.
-       (let ((abs (class-option-assoc options :abstract)))
-         (if (not (stringp abs))
-             (setq abs (format "Class %s is abstract" cname)))
-         (fset cname
-               `(lambda (&rest stuff)
-                  ,(format "You cannot create a new object of type %s" cname)
-                  (error ,abs))))
-
-      ;; Non-abstract classes need a constructor.
-      (fset cname
-           `(lambda (newname &rest slots)
-              ,(format "Create a new object with name NAME of class type %s" 
cname)
-              (apply #'constructor ,cname newname slots)))
-      )
+      (setf (eieio--class-symbol-hashtable newc) oa))
 
     ;; Set up a specialized doc string.
     ;; Use stored value since it is calculated in a non-trivial way
     (put cname 'variable-documentation
-        (class-option-assoc options :documentation))
+        (eieio--class-option-assoc options :documentation))
 
     ;; Save the file location where this class is defined.
     (let ((fname (if load-in-progress
@@ -773,7 +574,7 @@ See `defclass' for more information."
        (put cname 'class-location fname)))
 
     ;; We have a list of custom groups.  Store them into the options.
-    (let ((g (class-option-assoc options :custom-groups)))
+    (let ((g (eieio--class-option-assoc options :custom-groups)))
       (mapc (lambda (cg) (cl-pushnew cg g :test 'equal)) groups)
       (if (memq :custom-groups options)
          (setcar (cdr (memq :custom-groups options)) g)
@@ -787,11 +588,17 @@ See `defclass' for more information."
     (if clearparent (setf (eieio--class-parent newc) nil))
 
     ;; Create the cached default object.
-    (let ((cache (make-vector (+ (length (eieio--class-public-a newc)) 3)
-                              nil)))
-      (aset cache 0 'object)
-      (setf (eieio--object-class cache) cname)
-      (setf (eieio--object-name cache) 'default-cache-object)
+    (let ((cache (make-vector (+ (length (eieio--class-public-a newc))
+                                 (eval-when-compile eieio--object-num-slots))
+                              nil))
+          ;; We don't strictly speaking need to use a symbol, but the old
+          ;; code used the class's name rather than the class's object, so
+          ;; we follow this preference for using a symbol, which is probably
+          ;; convenient to keep the printed representation of such Elisp
+          ;; objects readable.
+          (tag (intern (format "eieio-class-tag--%s" cname))))
+      (set tag newc)
+      (setf (eieio--object-class-tag cache) tag)
       (let ((eieio-skip-typecheck t))
        ;; All type-checking has been done to our satisfaction
        ;; before this call.  Don't waste our time in this call..
@@ -807,16 +614,16 @@ See `defclass' for more information."
   "Whether the default value VAL should be evaluated for use."
   (and (consp val) (symbolp (car val)) (fboundp (car val))))
 
-(defun eieio-perform-slot-validation-for-default (slot spec value skipnil)
+(defun eieio--perform-slot-validation-for-default (slot spec value skipnil)
   "For SLOT, signal if SPEC does not match VALUE.
 If SKIPNIL is non-nil, then if VALUE is nil return t instead."
-  (if (and (not (eieio-eval-default-p value))
-          (not eieio-skip-typecheck)
-          (not (and skipnil (null value)))
-          (not (eieio-perform-slot-validation spec value)))
+  (if (not (or (eieio-eval-default-p value) ;FIXME: Why?
+               eieio-skip-typecheck
+               (and skipnil (null value))
+               (eieio--perform-slot-validation spec value)))
       (signal 'invalid-slot-type (list slot spec value))))
 
-(defun eieio-add-new-slot (newc a d doc type cust label custg print prot init 
alloc
+(defun eieio--add-new-slot (newc a d doc type cust label custg print prot init 
alloc
                                 &optional defaultoverride skipnil)
   "Add into NEWC attribute A.
 If A already exists in NEWC, then do nothing.  If it doesn't exist,
@@ -837,9 +644,9 @@ if default value is nil."
 
   ;; To prevent override information w/out specification of storage,
   ;; we need to do this little hack.
-  (if (member a (eieio--class-class-allocation-a newc)) (setq alloc ':class))
+  (if (member a (eieio--class-class-allocation-a newc)) (setq alloc :class))
 
-  (if (or (not alloc) (and (symbolp alloc) (eq alloc ':instance)))
+  (if (or (not alloc) (and (symbolp alloc) (eq alloc :instance)))
       ;; In this case, we modify the INSTANCE version of a given slot.
 
       (progn
@@ -847,16 +654,16 @@ if default value is nil."
        ;; Only add this element if it is so-far unique
        (if (not (member a (eieio--class-public-a newc)))
            (progn
-             (eieio-perform-slot-validation-for-default a type d skipnil)
-             (setf (eieio--class-public-a newc) (cons a (eieio--class-public-a 
newc)))
-             (setf (eieio--class-public-d newc) (cons d (eieio--class-public-d 
newc)))
-             (setf (eieio--class-public-doc newc) (cons doc 
(eieio--class-public-doc newc)))
-             (setf (eieio--class-public-type newc) (cons type 
(eieio--class-public-type newc)))
-             (setf (eieio--class-public-custom newc) (cons cust 
(eieio--class-public-custom newc)))
-             (setf (eieio--class-public-custom-label newc) (cons label 
(eieio--class-public-custom-label newc)))
-             (setf (eieio--class-public-custom-group newc) (cons custg 
(eieio--class-public-custom-group newc)))
-             (setf (eieio--class-public-printer newc) (cons print 
(eieio--class-public-printer newc)))
-             (setf (eieio--class-protection newc) (cons prot 
(eieio--class-protection newc)))
+             (eieio--perform-slot-validation-for-default a type d skipnil)
+             (push a (eieio--class-public-a newc))
+             (push d (eieio--class-public-d newc))
+             (push doc (eieio--class-public-doc newc))
+             (push type (eieio--class-public-type newc))
+             (push cust (eieio--class-public-custom newc))
+             (push label (eieio--class-public-custom-label newc))
+             (push custg (eieio--class-public-custom-group newc))
+             (push print (eieio--class-public-printer newc))
+             (push prot (eieio--class-protection newc))
              (setf (eieio--class-initarg-tuples newc) (cons (cons init a) 
(eieio--class-initarg-tuples newc)))
              )
          ;; When defaultoverride is true, we are usually adding new local
@@ -882,7 +689,7 @@ if default value is nil."
                         type tp a)))
                ;; If we have a repeat, only update the initarg...
                (unless (eq d eieio-unbound)
-                 (eieio-perform-slot-validation-for-default a tp d skipnil)
+                 (eieio--perform-slot-validation-for-default a tp d skipnil)
                  (setcar dp d))
                ;; If we have a new initarg, check for it.
                (when init
@@ -959,19 +766,19 @@ if default value is nil."
     (let ((value (eieio-default-eval-maybe d)))
       (if (not (member a (eieio--class-class-allocation-a newc)))
          (progn
-           (eieio-perform-slot-validation-for-default a type value skipnil)
+           (eieio--perform-slot-validation-for-default a type value skipnil)
            ;; Here we have found a :class version of a slot.  This
            ;; requires a very different approach.
-           (setf (eieio--class-class-allocation-a newc) (cons a 
(eieio--class-class-allocation-a newc)))
-           (setf (eieio--class-class-allocation-doc newc) (cons doc 
(eieio--class-class-allocation-doc newc)))
-           (setf (eieio--class-class-allocation-type newc) (cons type 
(eieio--class-class-allocation-type newc)))
-           (setf (eieio--class-class-allocation-custom newc) (cons cust 
(eieio--class-class-allocation-custom newc)))
-           (setf (eieio--class-class-allocation-custom-label newc) (cons label 
(eieio--class-class-allocation-custom-label newc)))
-           (setf (eieio--class-class-allocation-custom-group newc) (cons custg 
(eieio--class-class-allocation-custom-group newc)))
-           (setf (eieio--class-class-allocation-protection newc) (cons prot 
(eieio--class-class-allocation-protection newc)))
+           (push a (eieio--class-class-allocation-a newc))
+           (push doc (eieio--class-class-allocation-doc newc))
+           (push type (eieio--class-class-allocation-type newc))
+           (push cust (eieio--class-class-allocation-custom newc))
+           (push label (eieio--class-class-allocation-custom-label newc))
+           (push custg (eieio--class-class-allocation-custom-group newc))
+           (push prot (eieio--class-class-allocation-protection newc))
            ;; Default value is stored in the 'values section, since new objects
            ;; can't initialize from this element.
-           (setf (eieio--class-class-allocation-values newc) (cons value 
(eieio--class-class-allocation-values newc))))
+           (push value (eieio--class-class-allocation-values newc)))
        (when defaultoverride
          ;; There is a match, and we must override the old value.
          (let* ((ca (eieio--class-class-allocation-a newc))
@@ -996,7 +803,7 @@ if default value is nil."
              ;;       is to change the default, so allow unbound in.
 
              ;; If we have a repeat, only update the value...
-             (eieio-perform-slot-validation-for-default a tp value skipnil)
+             (eieio--perform-slot-validation-for-default a tp value skipnil)
              (setcar dp value))
 
            ;; PLN Tue Jun 26 11:57:06 2007 : The protection is
@@ -1045,246 +852,81 @@ if default value is nil."
   "Copy into NEWC the slots of PARENTS.
 Follow the rules of not overwriting early parents when applying to
 the new child class."
-  (let ((ps (eieio--class-parent newc))
-       (sn (class-option-assoc (eieio--class-options newc)
-                               ':allow-nil-initform)))
-    (while ps
+  (let ((sn (eieio--class-option-assoc (eieio--class-options newc)
+                                       :allow-nil-initform)))
+    (dolist (pcv (eieio--class-parent newc))
       ;; First, duplicate all the slots of the parent.
-      (let ((pcv (class-v (car ps))))
-       (let ((pa (eieio--class-public-a pcv))
-             (pd (eieio--class-public-d pcv))
-             (pdoc (eieio--class-public-doc pcv))
-             (ptype (eieio--class-public-type pcv))
-             (pcust (eieio--class-public-custom pcv))
-             (plabel (eieio--class-public-custom-label pcv))
-             (pcustg (eieio--class-public-custom-group pcv))
-             (printer (eieio--class-public-printer pcv))
-             (pprot (eieio--class-protection pcv))
-             (pinit (eieio--class-initarg-tuples pcv))
-             (i 0))
-         (while pa
-           (eieio-add-new-slot newc
-                                (car pa) (car pd) (car pdoc) (aref ptype i)
-                                (car pcust) (car plabel) (car pcustg)
-                                (car printer)
-                                (car pprot) (car-safe (car pinit)) nil nil sn)
-           ;; Increment each value.
-           (setq pa (cdr pa)
-                 pd (cdr pd)
-                 pdoc (cdr pdoc)
-                 i (1+ i)
-                 pcust (cdr pcust)
-                 plabel (cdr plabel)
-                 pcustg (cdr pcustg)
-                 printer (cdr printer)
-                 pprot (cdr pprot)
-                 pinit (cdr pinit))
-           )) ;; while/let
-       ;; Now duplicate all the class alloc slots.
-       (let ((pa (eieio--class-class-allocation-a pcv))
-             (pdoc (eieio--class-class-allocation-doc pcv))
-             (ptype (eieio--class-class-allocation-type pcv))
-             (pcust (eieio--class-class-allocation-custom pcv))
-             (plabel (eieio--class-class-allocation-custom-label pcv))
-             (pcustg (eieio--class-class-allocation-custom-group pcv))
-             (printer (eieio--class-class-allocation-printer pcv))
-             (pprot (eieio--class-class-allocation-protection pcv))
-             (pval (eieio--class-class-allocation-values pcv))
-             (i 0))
-         (while pa
-           (eieio-add-new-slot newc
-                                (car pa) (aref pval i) (car pdoc) (aref ptype 
i)
-                                (car pcust) (car plabel) (car pcustg)
-                                (car printer)
-                                (car pprot) nil ':class sn)
-           ;; Increment each value.
-           (setq pa (cdr pa)
-                 pdoc (cdr pdoc)
-                 pcust (cdr pcust)
-                 plabel (cdr plabel)
-                 pcustg (cdr pcustg)
-                 printer (cdr printer)
-                 pprot (cdr pprot)
-                 i (1+ i))
-           ))) ;; while/let
-      ;; Loop over each parent class
-      (setq ps (cdr ps)))
-    ))
+      (let ((pa (eieio--class-public-a pcv))
+            (pd (eieio--class-public-d pcv))
+            (pdoc (eieio--class-public-doc pcv))
+            (ptype (eieio--class-public-type pcv))
+            (pcust (eieio--class-public-custom pcv))
+            (plabel (eieio--class-public-custom-label pcv))
+            (pcustg (eieio--class-public-custom-group pcv))
+            (printer (eieio--class-public-printer pcv))
+            (pprot (eieio--class-protection pcv))
+            (pinit (eieio--class-initarg-tuples pcv))
+            (i 0))
+        (while pa
+          (eieio--add-new-slot newc
+                               (car pa) (car pd) (car pdoc) (aref ptype i)
+                               (car pcust) (car plabel) (car pcustg)
+                               (car printer)
+                               (car pprot) (car-safe (car pinit)) nil nil sn)
+          ;; Increment each value.
+          (setq pa (cdr pa)
+                pd (cdr pd)
+                pdoc (cdr pdoc)
+                i (1+ i)
+                pcust (cdr pcust)
+                plabel (cdr plabel)
+                pcustg (cdr pcustg)
+                printer (cdr printer)
+                pprot (cdr pprot)
+                pinit (cdr pinit))
+          )) ;; while/let
+      ;; Now duplicate all the class alloc slots.
+      (let ((pa (eieio--class-class-allocation-a pcv))
+            (pdoc (eieio--class-class-allocation-doc pcv))
+            (ptype (eieio--class-class-allocation-type pcv))
+            (pcust (eieio--class-class-allocation-custom pcv))
+            (plabel (eieio--class-class-allocation-custom-label pcv))
+            (pcustg (eieio--class-class-allocation-custom-group pcv))
+            (printer (eieio--class-class-allocation-printer pcv))
+            (pprot (eieio--class-class-allocation-protection pcv))
+            (pval (eieio--class-class-allocation-values pcv))
+            (i 0))
+        (while pa
+          (eieio--add-new-slot newc
+                               (car pa) (aref pval i) (car pdoc) (aref ptype i)
+                               (car pcust) (car plabel) (car pcustg)
+                               (car printer)
+                               (car pprot) nil :class sn)
+          ;; Increment each value.
+          (setq pa (cdr pa)
+                pdoc (cdr pdoc)
+                pcust (cdr pcust)
+                plabel (cdr plabel)
+                pcustg (cdr pcustg)
+                printer (cdr printer)
+                pprot (cdr pprot)
+                i (1+ i))
+          )))))
 
 
-;;; CLOS methods and generics
-;;
-
-(defun eieio--defgeneric-init-form (method doc-string)
-  "Form to use for the initial definition of a generic."
-  (cond
-   ((or (not (fboundp method))
-        (eq 'autoload (car-safe (symbol-function method))))
-    ;; Make sure the method tables are installed.
-    (eieiomt-install method)
-    ;; Construct the actual body of this function.
-    (eieio-defgeneric-form method doc-string))
-   ((generic-p method) (symbol-function method))           ;Leave it as-is.
-   (t (error "You cannot create a generic/method over an existing symbol: %s"
-             method))))
-
-(defun eieio-defgeneric-form (method doc-string)
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-DOC-STRING is the documentation attached to METHOD."
-  `(lambda (&rest local-args)
-     ,doc-string
-     (eieio-generic-call (quote ,method) local-args)))
-
-(defsubst eieio-defgeneric-reset-generic-form (method)
-  "Setup METHOD to call the generic form."
-  (let ((doc-string (documentation method)))
-    (fset method (eieio-defgeneric-form method doc-string))))
-
-(defun eieio-defgeneric-form-primary-only (method doc-string)
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-DOC-STRING is the documentation attached to METHOD."
-  `(lambda (&rest local-args)
-     ,doc-string
-     (eieio-generic-call-primary-only (quote ,method) local-args)))
-
-(defsubst eieio-defgeneric-reset-generic-form-primary-only (method)
-  "Setup METHOD to call the generic form."
-  (let ((doc-string (documentation method)))
-    (fset method (eieio-defgeneric-form-primary-only method doc-string))))
-
-(declare-function no-applicable-method "eieio" (object method &rest args))
-
-(defun eieio-defgeneric-form-primary-only-one (method doc-string
-                                                     class
-                                                     impl
-                                                     )
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-DOC-STRING is the documentation attached to METHOD.
-CLASS is the class symbol needed for private method access.
-IMPL is the symbol holding the method implementation."
-  ;; NOTE: I tried out byte compiling this little fcn.  Turns out it
-  ;; is faster to execute this for not byte-compiled.  ie, install this,
-  ;; then measure calls going through here.  I wonder why.
-  (require 'bytecomp)
-  (let ((byte-compile-warnings nil))
-    (byte-compile
-     `(lambda (&rest local-args)
-       ,doc-string
-       ;; This is a cool cheat.  Usually we need to look up in the
-       ;; method table to find out if there is a method or not.  We can
-       ;; instead make that determination at load time when there is
-       ;; only one method.  If the first arg is not a child of the class
-       ;; of that one implementation, then clearly, there is no method def.
-       (if (not (eieio-object-p (car local-args)))
-           ;; Not an object.  Just signal.
-           (signal 'no-method-definition
-                    (list ',method local-args))
-
-         ;; We do have an object.  Make sure it is the right type.
-         (if ,(if (eq class eieio-default-superclass)
-                  nil  ; default superclass means just an obj.  Already asked.
-                `(not (child-of-class-p (eieio--object-class (car local-args))
-                                        ',class)))
-
-             ;; If not the right kind of object, call no applicable
-             (apply #'no-applicable-method (car local-args)
-                    ',method local-args)
-
-           ;; It is ok, do the call.
-           ;; Fill in inter-call variables then evaluate the method.
-           (let ((eieio-generic-call-next-method-list nil)
-                 (eieio-generic-call-key method-primary)
-                 (eieio-generic-call-methodname ',method)
-                 (eieio-generic-call-arglst local-args)
-                 )
-             (eieio--with-scoped-class ',class
-               ,(if (< emacs-major-version 24)
-                    `(apply ,(list 'quote impl) local-args)
-                  `(apply #',impl local-args)))
-             ;(,impl local-args)
-             )))))))
-
-(defsubst eieio-defgeneric-reset-generic-form-primary-only-one (method)
-  "Setup METHOD to call the generic form."
-  (let* ((doc-string (documentation method))
-        (M (get method 'eieio-method-tree))
-        (entry (car (aref M method-primary)))
-        )
-    (fset method (eieio-defgeneric-form-primary-only-one
-                 method doc-string
-                 (car entry)
-                 (cdr entry)
-                 ))))
-
-(defun eieio-unbind-method-implementations (method)
-  "Make the generic method METHOD have no implementations.
-It will leave the original generic function in place,
-but remove reference to all implementations of METHOD."
-  (put method 'eieio-method-tree nil)
-  (put method 'eieio-method-obarray nil))
-
-(defun eieio--defmethod (method kind argclass code)
-  "Work part of the `defmethod' macro defining METHOD with ARGS."
-  (let ((key
-         ;; Find optional keys.
-         (cond ((memq kind '(:BEFORE :before)) method-before)
-               ((memq kind '(:AFTER :after)) method-after)
-               ((memq kind '(:STATIC :static)) method-static)
-               ((memq kind '(:PRIMARY :primary nil)) method-primary)
-               ;; Primary key.
-               ;; (t method-primary)
-               (t (error "Unknown method kind %S" kind)))))
-    ;; Make sure there is a generic (when called from defclass).
-    (eieio--defalias
-     method (eieio--defgeneric-init-form
-             method (or (documentation code)
-                        (format "Generically created method `%s'." method))))
-    ;; Create symbol for property to bind to.  If the first arg is of
-    ;; the form (varname vartype) and `vartype' is a class, then
-    ;; that class will be the type symbol.  If not, then it will fall
-    ;; under the type `primary' which is a non-specific calling of the
-    ;; function.
-    (if argclass
-        (if (not (class-p argclass))
-            (error "Unknown class type %s in method parameters"
-                   argclass))
-      ;; Generics are higher.
-      (setq key (eieio-specialized-key-to-generic-key key)))
-    ;; Put this lambda into the symbol so we can find it.
-    (eieiomt-add method code key argclass)
-    )
-
-  (when eieio-optimize-primary-methods-flag
-    ;; Optimizing step:
-    ;;
-    ;; If this method, after this setup, only has primary methods, then
-    ;; we can setup the generic that way.
-    (if (generic-primary-only-p method)
-       ;; If there is only one primary method, then we can go one more
-       ;; optimization step.
-       (if (generic-primary-only-one-p method)
-           (eieio-defgeneric-reset-generic-form-primary-only-one method)
-         (eieio-defgeneric-reset-generic-form-primary-only method))
-      (eieio-defgeneric-reset-generic-form method)))
-
-  method)
-
 ;;; Slot type validation
 
 ;; This is a hideous hack for replacing `typep' from cl-macs, to avoid
 ;; requiring the CL library at run-time.  It can be eliminated if/when
 ;; `typep' is merged into Emacs core.
 
-(defun eieio-perform-slot-validation (spec value)
+(defun eieio--perform-slot-validation (spec value)
   "Return non-nil if SPEC does not match VALUE."
   (or (eq spec t)                      ; t always passes
       (eq value eieio-unbound)         ; unbound always passes
       (cl-typep value spec)))
 
-(defun eieio-validate-slot-value (class slot-idx value slot)
+(defun eieio--validate-slot-value (class slot-idx value slot)
   "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid.
 Checks the :type specifier.
 SLOT is the slot that is being checked, and is only used when throwing
@@ -1292,22 +934,24 @@ an error."
   (if eieio-skip-typecheck
       nil
     ;; Trim off object IDX junk added in for the object index.
-    (setq slot-idx (- slot-idx 3))
-    (let ((st (aref (eieio--class-public-type (class-v class)) slot-idx)))
-      (if (not (eieio-perform-slot-validation st value))
-         (signal 'invalid-slot-type (list class slot st value))))))
+    (setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots)))
+    (let ((st (aref (eieio--class-public-type class) slot-idx)))
+      (if (not (eieio--perform-slot-validation st value))
+         (signal 'invalid-slot-type
+                  (list (eieio--class-symbol class) slot st value))))))
 
-(defun eieio-validate-class-slot-value (class slot-idx value slot)
+(defun eieio--validate-class-slot-value (class slot-idx value slot)
   "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid.
 Checks the :type specifier.
 SLOT is the slot that is being checked, and is only used when throwing
 an error."
   (if eieio-skip-typecheck
       nil
-    (let ((st (aref (eieio--class-class-allocation-type (class-v class))
+    (let ((st (aref (eieio--class-class-allocation-type class)
                    slot-idx)))
-      (if (not (eieio-perform-slot-validation st value))
-         (signal 'invalid-slot-type (list class slot st value))))))
+      (if (not (eieio--perform-slot-validation st value))
+         (signal 'invalid-slot-type
+                  (list (eieio--class-symbol class) slot st value))))))
 
 (defun eieio-barf-if-slot-unbound (value instance slotname fn)
   "Throw a signal if VALUE is a representation of an UNBOUND slot.
@@ -1315,7 +959,7 @@ INSTANCE is the object being referenced.  SLOTNAME is the 
offending
 slot.  If the slot is ok, return VALUE.
 Argument FN is the function calling this verifier."
   (if (and (eq value eieio-unbound) (not eieio-skip-typecheck))
-      (slot-unbound instance (eieio--object-class instance) slotname fn)
+      (slot-unbound instance (eieio--object-class-name instance) slotname fn)
     value))
 
 
@@ -1326,14 +970,17 @@ Argument FN is the function calling this verifier."
   (eieio--check-type (or eieio-object-p class-p) obj)
   (eieio--check-type symbolp slot)
   (if (class-p obj) (eieio-class-un-autoload obj))
-  (let* ((class (if (class-p obj) obj (eieio--object-class obj)))
-        (c (eieio-slot-name-index class obj slot)))
+  (let* ((class (cond ((symbolp obj)
+                       (error "eieio-oref called on a class!")
+                       (eieio--class-v obj))
+                      (t (eieio--object-class-object obj))))
+        (c (eieio--slot-name-index class obj slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
        ;; Let's check that info out.
-       (if (setq c (eieio-class-slot-name-index class slot))
+       (if (setq c (eieio--class-slot-name-index class slot))
            ;; Oref that slot.
-           (aref (eieio--class-class-allocation-values (class-v class)) c)
+           (aref (eieio--class-class-allocation-values class) c)
          ;; The slot-missing method is a cool way of allowing an object author
          ;; to intercept missing slot definitions.  Since it is also the LAST
          ;; thing called in this fn, its return value would be retrieved.
@@ -1349,26 +996,30 @@ Argument FN is the function calling this verifier."
 Fills in OBJ's SLOT with its default value."
   (eieio--check-type (or eieio-object-p class-p) obj)
   (eieio--check-type symbolp slot)
-  (let* ((cl (if (eieio-object-p obj) (eieio--object-class obj) obj))
-        (c (eieio-slot-name-index cl obj slot)))
+  (let* ((cl (cond ((symbolp obj) (eieio--class-v obj))
+                   (t (eieio--object-class-object obj))))
+        (c (eieio--slot-name-index cl obj slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
        ;; Let's check that info out.
        (if (setq c
-                 (eieio-class-slot-name-index cl slot))
+                 (eieio--class-slot-name-index cl slot))
            ;; Oref that slot.
-           (aref (eieio--class-class-allocation-values (class-v cl))
+           (aref (eieio--class-class-allocation-values cl)
                  c)
          (slot-missing obj slot 'oref-default)
          ;;(signal 'invalid-slot-name (list (class-name cl) slot))
          )
       (eieio-barf-if-slot-unbound
-       (let ((val (nth (- c 3) (eieio--class-public-d (class-v cl)))))
+       (let ((val (nth (- c (eval-when-compile eieio--object-num-slots))
+                       (eieio--class-public-d cl))))
         (eieio-default-eval-maybe val))
-       obj cl 'oref-default))))
+       obj (eieio--class-symbol cl) 'oref-default))))
 
 (defun eieio-default-eval-maybe (val)
   "Check VAL, and return what `oref-default' would provide."
+  ;; FIXME: What the hell is this supposed to do?  Shouldn't it evaluate
+  ;; variables as well?  Why not just always call `eval'?
   (cond
    ;; Is it a function call?  If so, evaluate it.
    ((eieio-eval-default-p val)
@@ -1384,69 +1035,71 @@ Fills in OBJ's SLOT with its default value."
 Fills in OBJ's SLOT with VALUE."
   (eieio--check-type eieio-object-p obj)
   (eieio--check-type symbolp slot)
-  (let ((c (eieio-slot-name-index (eieio--object-class obj) obj slot)))
+  (let* ((class (eieio--object-class-object obj))
+         (c (eieio--slot-name-index class obj slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
        ;; Let's check that info out.
        (if (setq c
-                 (eieio-class-slot-name-index (eieio--object-class obj) slot))
+                 (eieio--class-slot-name-index class slot))
            ;; Oset that slot.
            (progn
-             (eieio-validate-class-slot-value (eieio--object-class obj) c 
value slot)
-             (aset (eieio--class-class-allocation-values (class-v 
(eieio--object-class obj)))
+             (eieio--validate-class-slot-value class c value slot)
+             (aset (eieio--class-class-allocation-values class)
                    c value))
          ;; See oref for comment on `slot-missing'
          (slot-missing obj slot 'oset value)
          ;;(signal 'invalid-slot-name (list (eieio-object-name obj) slot))
          )
-      (eieio-validate-slot-value (eieio--object-class obj) c value slot)
+      (eieio--validate-slot-value class c value slot)
       (aset obj c value))))
 
 (defun eieio-oset-default (class slot value)
   "Do the work for the macro `oset-default'.
 Fills in the default value in CLASS' in SLOT with VALUE."
-  (eieio--check-type class-p class)
+  (setq class (eieio--class-object class))
+  (eieio--check-type eieio--class-p class)
   (eieio--check-type symbolp slot)
   (eieio--with-scoped-class class
-    (let* ((c (eieio-slot-name-index class nil slot)))
+    (let* ((c (eieio--slot-name-index class nil slot)))
       (if (not c)
          ;; It might be missing because it is a :class allocated slot.
          ;; Let's check that info out.
-         (if (setq c (eieio-class-slot-name-index class slot))
+         (if (setq c (eieio--class-slot-name-index class slot))
              (progn
                ;; Oref that slot.
-               (eieio-validate-class-slot-value class c value slot)
-               (aset (eieio--class-class-allocation-values (class-v class)) c
+               (eieio--validate-class-slot-value class c value slot)
+               (aset (eieio--class-class-allocation-values class) c
                      value))
-           (signal 'invalid-slot-name (list (eieio-class-name class) slot)))
-       (eieio-validate-slot-value class c value slot)
+           (signal 'invalid-slot-name (list (eieio--class-symbol class) slot)))
+       (eieio--validate-slot-value class c value slot)
        ;; Set this into the storage for defaults.
-       (setcar (nthcdr (- c 3) (eieio--class-public-d (class-v class)))
+       (setcar (nthcdr (- c (eval-when-compile eieio--object-num-slots))
+                        (eieio--class-public-d class))
                value)
        ;; Take the value, and put it into our cache object.
-       (eieio-oset (eieio--class-default-object-cache (class-v class))
+       (eieio-oset (eieio--class-default-object-cache class)
                    slot value)
        ))))
 
 
 ;;; EIEIO internal search functions
 ;;
-(defun eieio-slot-originating-class-p (start-class slot)
+(defun eieio--slot-originating-class-p (start-class slot)
   "Return non-nil if START-CLASS is the first class to define SLOT.
 This is for testing if the class currently in scope is the class that defines 
SLOT
 so that we can protect private slots."
-  (let ((par (eieio-class-parents-fast start-class))
+  (let ((par (eieio--class-parent start-class))
        (ret t))
-    (if (not par)
-       t
-      (while (and par ret)
-       (if (intern-soft (symbol-name slot)
-                        (eieio--class-symbol-obarray (class-v (car par))))
-           (setq ret nil))
-       (setq par (cdr par)))
-      ret)))
-
-(defun eieio-slot-name-index (class obj slot)
+    (or (not par)
+        (progn
+          (while (and par ret)
+            (if (gethash slot (eieio--class-symbol-hashtable (car par)))
+                (setq ret nil))
+            (setq par (cdr par)))
+          ret))))
+
+(defun eieio--slot-name-index (class obj slot)
   "In CLASS for OBJ find the index of the named SLOT.
 The slot is a symbol which is installed in CLASS by the `defclass'
 call.  OBJ can be nil, but if it is an object, and the slot in question
@@ -1455,36 +1108,41 @@ scoped class.
 If SLOT is the value created with :initarg instead,
 reverse-lookup that name, and recurse with the associated slot value."
   ;; Removed checks to outside this call
-  (let* ((fsym (intern-soft (symbol-name slot)
-                           (eieio--class-symbol-obarray (class-v class))))
-        (fsi (if (symbolp fsym) (symbol-value fsym) nil)))
+  (let* ((fsym (gethash slot (eieio--class-symbol-hashtable class)))
+        (fsi (car fsym)))
     (if (integerp fsi)
        (cond
-        ((not (get fsym 'protection))
-         (+ 3 fsi))
-        ((and (eq (get fsym 'protection) 'protected)
+        ((not (cdr fsym))
+         (+ (eval-when-compile eieio--object-num-slots) fsi))
+        ((and (eq (cdr fsym) 'protected)
               (eieio--scoped-class)
               (or (child-of-class-p class (eieio--scoped-class))
                   (and (eieio-object-p obj)
-                       (child-of-class-p class (eieio--object-class obj)))))
-         (+ 3 fsi))
-        ((and (eq (get fsym 'protection) 'private)
+                        ;; AFAICT, for all callers, if `obj' is not a class,
+                        ;; then its class is `class'.
+                       ;;(child-of-class-p class (eieio--object-class-object 
obj))
+                        (progn
+                          (cl-assert (eq class (eieio--object-class-object 
obj)))
+                          t))))
+         (+ (eval-when-compile eieio--object-num-slots) fsi))
+        ((and (eq (cdr fsym) 'private)
               (or (and (eieio--scoped-class)
-                       (eieio-slot-originating-class-p (eieio--scoped-class) 
slot))
+                       (eieio--slot-originating-class-p
+                         (eieio--scoped-class) slot))
                   eieio-initializing-object))
-         (+ 3 fsi))
+         (+ (eval-when-compile eieio--object-num-slots) fsi))
         (t nil))
-      (let ((fn (eieio-initarg-to-attribute class slot)))
-       (if fn (eieio-slot-name-index class obj fn) nil)))))
+      (let ((fn (eieio--initarg-to-attribute class slot)))
+       (if fn (eieio--slot-name-index class obj fn) nil)))))
 
-(defun eieio-class-slot-name-index (class slot)
+(defun eieio--class-slot-name-index (class slot)
   "In CLASS find the index of the named SLOT.
 The slot is a symbol which is installed in CLASS by the `defclass'
 call.  If SLOT is the value created with :initarg instead,
 reverse-lookup that name, and recurse with the associated slot value."
   ;; This will happen less often, and with fewer slots.  Do this the
   ;; storage cheap way.
-  (let* ((a (eieio--class-class-allocation-a (class-v class)))
+  (let* ((a (eieio--class-class-allocation-a class))
         (l1 (length a))
         (af (memq slot a))
         (l2 (length af)))
@@ -1501,36 +1159,28 @@ reverse-lookup that name, and recurse with the 
associated slot value."
 If SET-ALL is non-nil, then when a default is nil, that value is
 reset.  If SET-ALL is nil, the slots are only reset if the default is
 not nil."
-  (eieio--with-scoped-class (eieio--object-class obj)
+  (eieio--with-scoped-class (eieio--object-class-object obj)
     (let ((eieio-initializing-object t)
-         (pub (eieio--class-public-a (class-v (eieio--object-class obj)))))
+         (pub (eieio--class-public-a (eieio--object-class-object obj))))
       (while pub
        (let ((df (eieio-oref-default obj (car pub))))
          (if (or df set-all)
              (eieio-oset obj (car pub) df)))
        (setq pub (cdr pub))))))
 
-(defun eieio-initarg-to-attribute (class initarg)
+(defun eieio--initarg-to-attribute (class initarg)
   "For CLASS, convert INITARG to the actual attribute name.
 If there is no translation, pass it in directly (so we can cheat if
 need be... May remove that later...)"
-  (let ((tuple (assoc initarg (eieio--class-initarg-tuples (class-v class)))))
+  (let ((tuple (assoc initarg (eieio--class-initarg-tuples class))))
     (if tuple
        (cdr tuple)
       nil)))
 
-(defun eieio-attribute-to-initarg (class attribute)
-  "In CLASS, convert the ATTRIBUTE into the corresponding init argument tag.
-This is usually a symbol that starts with `:'."
-  (let ((tuple (rassoc attribute (eieio--class-initarg-tuples (class-v 
class)))))
-    (if tuple
-       (car tuple)
-      nil)))
-
 ;;;
 ;; Method Invocation order: C3
-(defun eieio-c3-candidate (class remaining-inputs)
-  "Return CLASS if it can go in the result now, otherwise nil"
+(defun eieio--c3-candidate (class remaining-inputs)
+  "Return CLASS if it can go in the result now, otherwise nil."
   ;; Ensure CLASS is not in any position but the first in any of the
   ;; element lists of REMAINING-INPUTS.
   (and (not (let ((found nil))
@@ -1540,7 +1190,7 @@ This is usually a symbol that starts with `:'."
              found))
        class))
 
-(defun eieio-c3-merge-lists (reversed-partial-result remaining-inputs)
+(defun eieio--c3-merge-lists (reversed-partial-result remaining-inputs)
   "Merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order, if 
possible.
 If a consistent order does not exist, signal an error."
   (if (let ((tail remaining-inputs)
@@ -1559,41 +1209,38 @@ If a consistent order does not exist, signal an error."
           (next (progn
                   (while (and tail (not found))
                     (setq found (and (car tail)
-                                     (eieio-c3-candidate (caar tail)
-                                                         remaining-inputs))
+                                     (eieio--c3-candidate (caar tail)
+                                                           remaining-inputs))
                           tail (cdr tail)))
                   found)))
       (if next
          ;; The graph is consistent so far, add NEXT to result and
          ;; merge input lists, dropping NEXT from their heads where
          ;; applicable.
-         (eieio-c3-merge-lists
+         (eieio--c3-merge-lists
           (cons next reversed-partial-result)
           (mapcar (lambda (l) (if (eq (cl-first l) next) (cl-rest l) l))
                   remaining-inputs))
        ;; The graph is inconsistent, give up
        (signal 'inconsistent-class-hierarchy (list remaining-inputs))))))
 
-(defun eieio-class-precedence-c3 (class)
+(defun eieio--class-precedence-c3 (class)
   "Return all parents of CLASS in c3 order."
-  (let ((parents (eieio-class-parents-fast class)))
-    (eieio-c3-merge-lists
+  (let ((parents (eieio--class-parent (eieio--class-v class))))
+    (eieio--c3-merge-lists
      (list class)
      (append
       (or
-       (mapcar
-       (lambda (x)
-         (eieio-class-precedence-c3 x))
-       parents)
-       '((eieio-default-superclass)))
+       (mapcar #'eieio--class-precedence-c3 parents)
+       `((,eieio-default-superclass)))
       (list parents))))
   )
 ;;;
 ;; Method Invocation Order: Depth First
 
-(defun eieio-class-precedence-dfs (class)
+(defun eieio--class-precedence-dfs (class)
   "Return all parents of CLASS in depth-first order."
-  (let* ((parents (eieio-class-parents-fast class))
+  (let* ((parents (eieio--class-parent class))
         (classes (copy-sequence
                   (apply #'append
                          (list class)
@@ -1601,9 +1248,9 @@ If a consistent order does not exist, signal an error."
                           (mapcar
                            (lambda (parent)
                              (cons parent
-                                   (eieio-class-precedence-dfs parent)))
+                                   (eieio--class-precedence-dfs parent)))
                            parents)
-                          '((eieio-default-superclass))))))
+                          `((,eieio-default-superclass))))))
         (tail classes))
     ;; Remove duplicates.
     (while tail
@@ -1613,563 +1260,55 @@ If a consistent order does not exist, signal an error."
 
 ;;;
 ;; Method Invocation Order: Breadth First
-(defun eieio-class-precedence-bfs (class)
+(defun eieio--class-precedence-bfs (class)
   "Return all parents of CLASS in breadth-first order."
-  (let ((result)
-       (queue (or (eieio-class-parents-fast class)
-                  '(eieio-default-superclass))))
+  (let* ((result)
+         (queue (or (eieio--class-parent class)
+                    `(,eieio-default-superclass))))
     (while queue
       (let ((head (pop queue)))
        (unless (member head result)
          (push head result)
-         (unless (eq head 'eieio-default-superclass)
-           (setq queue (append queue (or (eieio-class-parents-fast head)
-                                         '(eieio-default-superclass))))))))
+         (unless (eq head eieio-default-superclass)
+           (setq queue (append queue (or (eieio--class-parent head)
+                                         `(,eieio-default-superclass))))))))
     (cons class (nreverse result)))
   )
 
 ;;;
 ;; Method Invocation Order
 
-(defun eieio-class-precedence-list (class)
+(defun eieio--class-precedence-list (class)
   "Return (transitively closed) list of parents of CLASS.
 The order, in which the parents are returned depends on the
 method invocation orders of the involved classes."
-  (if (or (null class) (eq class 'eieio-default-superclass))
+  (if (or (null class) (eq class eieio-default-superclass))
       nil
-    (cl-case (class-method-invocation-order class)
+    (cl-case (eieio--class-method-invocation-order class)
       (:depth-first
-       (eieio-class-precedence-dfs class))
+       (eieio--class-precedence-dfs class))
       (:breadth-first
-       (eieio-class-precedence-bfs class))
+       (eieio--class-precedence-bfs class))
       (:c3
-       (eieio-class-precedence-c3 class))))
+       (eieio--class-precedence-c3 class))))
   )
 (define-obsolete-function-alias
-  'class-precedence-list 'eieio-class-precedence-list "24.4")
-
-
-;;; CLOS generics internal function handling
-;;
-(defvar eieio-generic-call-methodname nil
-  "When using `call-next-method', provides a context on how to do it.")
-(defvar eieio-generic-call-arglst nil
-  "When using `call-next-method', provides a context for parameters.")
-(defvar eieio-generic-call-key nil
-  "When using `call-next-method', provides a context for the current key.
-Keys are a number representing :before, :primary, and :after methods.")
-(defvar eieio-generic-call-next-method-list nil
-  "When executing a PRIMARY or STATIC method, track the 'next-method'.
-During executions, the list is first generated, then as each next method
-is called, the next method is popped off the stack.")
-
-(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks
-  'eieio-pre-method-execution-functions "24.3")
-(defvar eieio-pre-method-execution-functions nil
-  "Abnormal hook run just before an EIEIO method is executed.
-The hook function must accept one argument, the list of forms
-about to be executed.")
-
-(defun eieio-generic-call (method args)
-  "Call METHOD with ARGS.
-ARGS provides the context on which implementation to use.
-This should only be called from a generic function."
-  ;; We must expand our arguments first as they are always
-  ;; passed in as quoted symbols
-  (let ((newargs nil) (mclass nil)  (lambdas nil) (tlambdas nil) (keys nil)
-       (eieio-generic-call-methodname method)
-       (eieio-generic-call-arglst args)
-       (firstarg nil)
-       (primarymethodlist nil))
-    ;; get a copy
-    (setq newargs args
-         firstarg (car newargs))
-    ;; Is the class passed in autoloaded?
-    ;; Since class names are also constructors, they can be autoloaded
-    ;; via the autoload command.  Check for this, and load them in.
-    ;; It is ok if it doesn't turn out to be a class.  Probably want that
-    ;; function loaded anyway.
-    (if (and (symbolp firstarg)
-            (fboundp firstarg)
-            (listp (symbol-function firstarg))
-            (eq 'autoload (car (symbol-function firstarg))))
-       (load (nth 1 (symbol-function firstarg))))
-    ;; Determine the class to use.
-    (cond ((eieio-object-p firstarg)
-          (setq mclass (eieio--object-class firstarg)))
-         ((class-p firstarg)
-          (setq mclass firstarg))
-         )
-    ;; Make sure the class is a valid class
-    ;; mclass can be nil (meaning a generic for should be used.
-    ;; mclass cannot have a value that is not a class, however.
-    (when (and (not (null mclass)) (not (class-p mclass)))
-      (error "Cannot dispatch method %S on class %S"
-            method mclass)
-      )
-    ;; Now create a list in reverse order of all the calls we have
-    ;; make in order to successfully do this right.  Rules:
-    ;; 1) Only call generics if scoped-class is not defined
-    ;;    This prevents multiple calls in the case of recursion
-    ;; 2) Only call static if this is a static method.
-    ;; 3) Only call specifics if the definition allows for them.
-    ;; 4) Call in order based on :before, :primary, and :after
-    (when (eieio-object-p firstarg)
-      ;; Non-static calls do all this stuff.
-
-      ;; :after methods
-      (setq tlambdas
-           (if mclass
-               (eieiomt-method-list method method-after mclass)
-             (list (eieio-generic-form method method-after nil)))
-           ;;(or (and mclass (eieio-generic-form method method-after mclass))
-           ;;  (eieio-generic-form method method-after nil))
-           )
-      (setq lambdas (append tlambdas lambdas)
-           keys (append (make-list (length tlambdas) method-after) keys))
-
-      ;; :primary methods
-      (setq tlambdas
-           (or (and mclass (eieio-generic-form method method-primary mclass))
-               (eieio-generic-form method method-primary nil)))
-      (when tlambdas
-       (setq lambdas (cons tlambdas lambdas)
-             keys (cons method-primary keys)
-             primarymethodlist
-             (eieiomt-method-list method method-primary mclass)))
-
-      ;; :before methods
-      (setq tlambdas
-           (if mclass
-               (eieiomt-method-list method method-before mclass)
-             (list (eieio-generic-form method method-before nil)))
-           ;;(or (and mclass (eieio-generic-form method method-before mclass))
-           ;;  (eieio-generic-form method method-before nil))
-           )
-      (setq lambdas (append tlambdas lambdas)
-           keys (append (make-list (length tlambdas) method-before) keys))
-      )
-
-    (if mclass
-       ;; For the case of a class,
-       ;; if there were no methods found, then there could be :static methods.
-       (when (not lambdas)
-         (setq tlambdas
-               (eieio-generic-form method method-static mclass))
-         (setq lambdas (cons tlambdas lambdas)
-               keys (cons method-static keys)
-               primarymethodlist  ;; Re-use even with bad name here
-               (eieiomt-method-list method method-static mclass)))
-      ;; For the case of no class (ie - mclass == nil) then there may
-      ;; be a primary method.
-      (setq tlambdas
-           (eieio-generic-form method method-primary nil))
-      (when tlambdas
-       (setq lambdas (cons tlambdas lambdas)
-             keys (cons method-primary keys)
-             primarymethodlist
-             (eieiomt-method-list method method-primary nil)))
-      )
-
-    (run-hook-with-args 'eieio-pre-method-execution-functions
-                       primarymethodlist)
-
-    ;; Now loop through all occurrences forms which we must execute
-    ;; (which are happily sorted now) and execute them all!
-    (let ((rval nil) (lastval nil) (found nil))
-      (while lambdas
-       (if (car lambdas)
-           (eieio--with-scoped-class (cdr (car lambdas))
-             (let* ((eieio-generic-call-key (car keys))
-                    (has-return-val
-                     (or (= eieio-generic-call-key method-primary)
-                         (= eieio-generic-call-key method-static)))
-                    (eieio-generic-call-next-method-list
-                     ;; Use the cdr, as the first element is the fcn
-                     ;; we are calling right now.
-                     (when has-return-val (cdr primarymethodlist)))
-                    )
-               (setq found t)
-               ;;(setq rval (apply (car (car lambdas)) newargs))
-               (setq lastval (apply (car (car lambdas)) newargs))
-               (when has-return-val
-                 (setq rval lastval))
-               )))
-       (setq lambdas (cdr lambdas)
-             keys (cdr keys)))
-      (if (not found)
-         (if (eieio-object-p (car args))
-             (setq rval (apply #'no-applicable-method (car args) method args))
-           (signal
-            'no-method-definition
-            (list method args))))
-      rval)))
-
-(defun eieio-generic-call-primary-only (method args)
-  "Call METHOD with ARGS for methods with only :PRIMARY implementations.
-ARGS provides the context on which implementation to use.
-This should only be called from a generic function.
-
-This method is like `eieio-generic-call', but only
-implementations in the :PRIMARY slot are queried.  After many
-years of use, it appears that over 90% of methods in use
-have :PRIMARY implementations only.  We can therefore optimize
-for this common case to improve performance."
-  ;; We must expand our arguments first as they are always
-  ;; passed in as quoted symbols
-  (let ((newargs nil) (mclass nil)  (lambdas nil)
-       (eieio-generic-call-methodname method)
-       (eieio-generic-call-arglst args)
-       (firstarg nil)
-       (primarymethodlist nil)
-       )
-    ;; get a copy
-    (setq newargs args
-         firstarg (car newargs))
-
-    ;; Determine the class to use.
-    (cond ((eieio-object-p firstarg)
-          (setq mclass (eieio--object-class firstarg)))
-         ((not firstarg)
-          (error "Method %s called on nil" method))
-         ((not (eieio-object-p firstarg))
-          (error "Primary-only method %s called on something not an object" 
method))
-         (t
-          (error "EIEIO Error: Improperly classified method %s as primary only"
-                 method)
-         ))
-    ;; Make sure the class is a valid class
-    ;; mclass can be nil (meaning a generic for should be used.
-    ;; mclass cannot have a value that is not a class, however.
-    (when (null mclass)
-      (error "Cannot dispatch method %S on class %S" method mclass)
-      )
-
-    ;; :primary methods
-    (setq lambdas (eieio-generic-form method method-primary mclass))
-    (setq primarymethodlist  ;; Re-use even with bad name here
-         (eieiomt-method-list method method-primary mclass))
-
-    ;; Now loop through all occurrences forms which we must execute
-    ;; (which are happily sorted now) and execute them all!
-    (eieio--with-scoped-class (cdr lambdas)
-      (let* ((rval nil) (lastval nil)
-            (eieio-generic-call-key method-primary)
-            ;; Use the cdr, as the first element is the fcn
-            ;; we are calling right now.
-            (eieio-generic-call-next-method-list (cdr primarymethodlist))
-            )
-
-       (if (or (not lambdas) (not (car lambdas)))
-
-           ;; No methods found for this impl...
-           (if (eieio-object-p (car args))
-               (setq rval (apply #'no-applicable-method
-                                  (car args) method args))
-             (signal
-              'no-method-definition
-              (list method args)))
-
-         ;; Do the regular implementation here.
-
-         (run-hook-with-args 'eieio-pre-method-execution-functions
-                             lambdas)
-
-         (setq lastval (apply (car lambdas) newargs))
-         (setq rval lastval))
-
-       rval))))
-
-(defun eieiomt-method-list (method key class)
-  "Return an alist list of methods lambdas.
-METHOD is the method name.
-KEY represents either :before, or :after methods.
-CLASS is the starting class to search from in the method tree.
-If CLASS is nil, then an empty list of methods should be returned."
-  ;; Note: eieiomt - the MT means MethodTree.  See more comments below
-  ;; for the rest of the eieiomt methods.
-
-  ;; Collect lambda expressions stored for the class and its parent
-  ;; classes.
-  (let (lambdas)
-    (dolist (ancestor (eieio-class-precedence-list class))
-      ;; Lookup the form to use for the PRIMARY object for the next level
-      (let ((tmpl (eieio-generic-form method key ancestor)))
-       (when (and tmpl
-                  (or (not lambdas)
-                      ;; This prevents duplicates coming out of the
-                      ;; class method optimizer.  Perhaps we should
-                      ;; just not optimize before/afters?
-                      (not (member tmpl lambdas))))
-         (push tmpl lambdas))))
-
-    ;; Return collected lambda. For :after methods, return in current
-    ;; order (most general class last); Otherwise, reverse order.
-    (if (eq key method-after)
-       lambdas
-      (nreverse lambdas))))
-
-
-;;;
-;; eieio-method-tree : eieiomt-
-;;
-;; Stored as eieio-method-tree in property list of a generic method
-;;
-;; (eieio-method-tree . [BEFORE PRIMARY AFTER
-;;                       genericBEFORE genericPRIMARY genericAFTER])
-;; and
-;; (eieio-method-obarray . [BEFORE PRIMARY AFTER
-;;                          genericBEFORE genericPRIMARY genericAFTER])
-;;    where the association is a vector.
-;;    (aref 0  -- all static methods.
-;;    (aref 1  -- all methods classified as :before
-;;    (aref 2  -- all methods classified as :primary
-;;    (aref 3  -- all methods classified as :after
-;;    (aref 4  -- a generic classified as :before
-;;    (aref 5  -- a generic classified as :primary
-;;    (aref 6  -- a generic classified as :after
-;;
-(defvar eieiomt-optimizing-obarray nil
-  "While mapping atoms, this contain the obarray being optimized.")
-
-(defun eieiomt-install (method-name)
-  "Install the method tree, and obarray onto METHOD-NAME.
-Do not do the work if they already exist."
-  (let ((emtv (get method-name 'eieio-method-tree))
-       (emto (get method-name 'eieio-method-obarray)))
-    (if (or (not emtv) (not emto))
-       (progn
-         (setq emtv (put method-name 'eieio-method-tree
-                         (make-vector method-num-slots nil))
-               emto (put method-name 'eieio-method-obarray
-                         (make-vector method-num-slots nil)))
-         (aset emto 0 (make-vector 11 0))
-         (aset emto 1 (make-vector 11 0))
-         (aset emto 2 (make-vector 41 0))
-         (aset emto 3 (make-vector 11 0))
-         ))))
-
-(defun eieiomt-add (method-name method key class)
-  "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS.
-METHOD-NAME is the name created by a call to `defgeneric'.
-METHOD are the forms for a given implementation.
-KEY is an integer (see comment in eieio.el near this function) which
-is associated with the :static :before :primary and :after tags.
-It also indicates if CLASS is defined or not.
-CLASS is the class this method is associated with."
-  (if (or (> key method-num-slots) (< key 0))
-      (error "eieiomt-add: method key error!"))
-  (let ((emtv (get method-name 'eieio-method-tree))
-       (emto (get method-name 'eieio-method-obarray)))
-    ;; Make sure the method tables are available.
-    (if (or (not emtv) (not emto))
-       (error "Programmer error: eieiomt-add"))
-    ;; only add new cells on if it doesn't already exist!
-    (if (assq class (aref emtv key))
-       (setcdr (assq class (aref emtv key)) method)
-      (aset emtv key (cons (cons class method) (aref emtv key))))
-    ;; Add function definition into newly created symbol, and store
-    ;; said symbol in the correct obarray, otherwise use the
-    ;; other array to keep this stuff
-    (if (< key method-num-lists)
-       (let ((nsym (intern (symbol-name class) (aref emto key))))
-         (fset nsym method)))
-    ;; Save the defmethod file location in a symbol property.
-    (let ((fname (if load-in-progress
-                    load-file-name
-                  buffer-file-name))
-         loc)
-      (when fname
-       (when (string-match "\\.elc$" fname)
-         (setq fname (substring fname 0 (1- (length fname)))))
-       (setq loc (get method-name 'method-locations))
-       (cl-pushnew (list class fname) loc :test 'equal)
-       (put method-name 'method-locations loc)))
-    ;; Now optimize the entire obarray
-    (if (< key method-num-lists)
-       (let ((eieiomt-optimizing-obarray (aref emto key)))
-         ;; @todo - Is this overkill?  Should we just clear the symbol?
-         (mapatoms 'eieiomt-sym-optimize eieiomt-optimizing-obarray)))
-    ))
-
-(defun eieiomt-next (class)
-  "Return the next parent class for CLASS.
-If CLASS is a superclass, return variable `eieio-default-superclass'.
-If CLASS is variable `eieio-default-superclass' then return nil.
-This is different from function `class-parent' as class parent returns
-nil for superclasses.  This function performs no type checking!"
-  ;; No type-checking because all calls are made from functions which
-  ;; are safe and do checking for us.
-  (or (eieio-class-parents-fast class)
-      (if (eq class 'eieio-default-superclass)
-         nil
-       '(eieio-default-superclass))))
-
-(defun eieiomt-sym-optimize (s)
-  "Find the next class above S which has a function body for the optimizer."
-  ;; Set the value to nil in case there is no nearest cell.
-  (set s nil)
-  ;; Find the nearest cell that has a function body. If we find one,
-  ;; we replace the nil from above.
-  (let ((external-symbol (intern-soft (symbol-name s))))
-    (catch 'done
-      (dolist (ancestor
-               (cl-rest (eieio-class-precedence-list external-symbol)))
-       (let ((ov (intern-soft (symbol-name ancestor)
-                              eieiomt-optimizing-obarray)))
-         (when (fboundp ov)
-           (set s ov) ;; store ov as our next symbol
-           (throw 'done ancestor)))))))
-
-(defun eieio-generic-form (method key class)
- "Return the lambda form belonging to METHOD using KEY based upon CLASS.
-If CLASS is not a class then use `generic' instead.  If class has
-no form, but has a parent class, then trace to that parent class.
-The first time a form is requested from a symbol, an optimized path
-is memorized for faster future use."
- (let ((emto (aref (get method 'eieio-method-obarray)
-                  (if class key (eieio-specialized-key-to-generic-key key)))))
-   (if (class-p class)
-       ;; 1) find our symbol
-       (let ((cs (intern-soft (symbol-name class) emto)))
-        (if (not cs)
-            ;; 2) If there isn't one, then make one.
-            ;;    This can be slow since it only occurs once
-            (progn
-              (setq cs (intern (symbol-name class) emto))
-              ;; 2.1) Cache its nearest neighbor with a quick optimize
-              ;;      which should only occur once for this call ever
-              (let ((eieiomt-optimizing-obarray emto))
-                (eieiomt-sym-optimize cs))))
-        ;; 3) If it's bound return this one.
-        (if (fboundp  cs)
-            (cons cs (eieio--class-symbol (class-v class)))
-          ;; 4) If it's not bound then this variable knows something
-          (if (symbol-value cs)
-              (progn
-                ;; 4.1) This symbol holds the next class in its value
-                (setq class (symbol-value cs)
-                      cs (intern-soft (symbol-name class) emto))
-                ;; 4.2) The optimizer should always have chosen a
-                ;;      function-symbol
-                ;;(if (fboundp cs)
-                (cons cs (eieio--class-symbol (class-v (intern (symbol-name 
class)))))
-                  ;;(error "EIEIO optimizer: erratic data loss!"))
-                )
-              ;; There never will be a funcall...
-              nil)))
-     ;; for a generic call, what is a list, is the function body we want.
-     (let ((emtl (aref (get method 'eieio-method-tree)
-                      (if class key (eieio-specialized-key-to-generic-key 
key)))))
-       (if emtl
-          ;; The car of EMTL is supposed to be a class, which in this
-          ;; case is nil, so skip it.
-          (cons (cdr (car emtl)) nil)
-        nil)))))
+  'class-precedence-list 'eieio--class-precedence-list "24.4")
 
 
 ;;; Here are some special types of errors
 ;;
-(define-error 'no-method-definition "No method definition")
-(define-error 'no-next-method "No next method")
 (define-error 'invalid-slot-name "Invalid slot name")
 (define-error 'invalid-slot-type "Invalid slot type")
 (define-error 'unbound-slot "Unbound slot")
 (define-error 'inconsistent-class-hierarchy "Inconsistent class hierarchy")
 
-;;; Obsolete backward compatibility functions.
-;; Needed to run byte-code compiled with the EIEIO of Emacs-23.
-
-(defun eieio-defmethod (method args)
-  "Obsolete work part of an old version of the `defmethod' macro."
-  (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa)
-    ;; find optional keys
-    (setq key
-         (cond ((memq (car args) '(:BEFORE :before))
-                (setq args (cdr args))
-                method-before)
-               ((memq (car args) '(:AFTER :after))
-                (setq args (cdr args))
-                method-after)
-               ((memq (car args) '(:STATIC :static))
-                (setq args (cdr args))
-                method-static)
-               ((memq (car args) '(:PRIMARY :primary))
-                (setq args (cdr args))
-                method-primary)
-               ;; Primary key.
-               (t method-primary)))
-    ;; Get body, and fix contents of args to be the arguments of the fn.
-    (setq body (cdr args)
-         args (car args))
-    (setq loopa args)
-    ;; Create a fixed version of the arguments.
-    (while loopa
-      (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa))
-                        argfix))
-      (setq loopa (cdr loopa)))
-    ;; Make sure there is a generic.
-    (eieio-defgeneric
-     method
-     (if (stringp (car body))
-        (car body) (format "Generically created method `%s'." method)))
-    ;; create symbol for property to bind to.  If the first arg is of
-    ;; the form (varname vartype) and `vartype' is a class, then
-    ;; that class will be the type symbol.  If not, then it will fall
-    ;; under the type `primary' which is a non-specific calling of the
-    ;; function.
-    (setq firstarg (car args))
-    (if (listp firstarg)
-       (progn
-         (setq argclass  (nth 1 firstarg))
-         (if (not (class-p argclass))
-             (error "Unknown class type %s in method parameters"
-                    (nth 1 firstarg))))
-      ;; Generics are higher.
-      (setq key (eieio-specialized-key-to-generic-key key)))
-    ;; Put this lambda into the symbol so we can find it.
-    (if (byte-code-function-p (car-safe body))
-       (eieiomt-add method (car-safe body) key argclass)
-      (eieiomt-add method (append (list 'lambda (reverse argfix)) body)
-                  key argclass))
-    )
-
-  (when eieio-optimize-primary-methods-flag
-    ;; Optimizing step:
-    ;;
-    ;; If this method, after this setup, only has primary methods, then
-    ;; we can setup the generic that way.
-    (if (generic-primary-only-p method)
-       ;; If there is only one primary method, then we can go one more
-       ;; optimization step.
-       (if (generic-primary-only-one-p method)
-           (eieio-defgeneric-reset-generic-form-primary-only-one method)
-         (eieio-defgeneric-reset-generic-form-primary-only method))
-      (eieio-defgeneric-reset-generic-form method)))
-
-  method)
-(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1")
-
-(defun eieio-defgeneric (method doc-string)
-  "Obsolete work part of an old version of the `defgeneric' macro."
-  (if (and (fboundp method) (not (generic-p method))
-          (or (byte-code-function-p (symbol-function method))
-              (not (eq 'autoload (car (symbol-function method)))))
-          )
-      (error "You cannot create a generic/method over an existing symbol: %s"
-            method))
-  ;; Don't do this over and over.
-  (unless (fboundp 'method)
-    ;; This defun tells emacs where the first definition of this
-    ;; method is defined.
-    `(defun ,method nil)
-    ;; Make sure the method tables are installed.
-    (eieiomt-install method)
-    ;; Apply the actual body of this function.
-    (fset method (eieio-defgeneric-form method doc-string))
-    ;; Return the method
-    'method))
-(make-obsolete 'eieio-defgeneric nil "24.1")
+;;; Backward compatibility functions
+;; To support .elc files compiled for older versions of EIEIO.
+
+(defun eieio-defclass (cname superclasses slots options)
+  (eval `(defclass ,cname ,superclasses ,slots ,options)))
+
 
 (provide 'eieio-core)
 
diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el
index dc85b4c..d0eaaf2 100644
--- a/lisp/emacs-lisp/eieio-custom.el
+++ b/lisp/emacs-lisp/eieio-custom.el
@@ -1,4 +1,4 @@
-;;; eieio-custom.el -- eieio object customization
+;;; eieio-custom.el -- eieio object customization  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1999-2001, 2005, 2007-2015 Free Software Foundation,
 ;; Inc.
@@ -70,7 +70,7 @@ of these.")
             :documentation "A number of thingies."))
   "A class for testing the widget on.")
 
-(defcustom eieio-widget-test (eieio-widget-test-class "Foo")
+(defcustom eieio-widget-test (eieio-widget-test-class)
   "Test variable for editing an object."
   :type 'object
   :group 'eieio)
@@ -136,7 +136,7 @@ Updates occur regardless of the current customization 
group.")
           ))
     (widget-value-set vc (widget-value vc))))
 
-(defun eieio-custom-toggle-parent (widget &rest ignore)
+(defun eieio-custom-toggle-parent (widget &rest _)
   "Toggle visibility of parent of WIDGET.
 Optional argument IGNORE is an extraneous parameter."
   (eieio-custom-toggle-hide (widget-get widget :parent)))
@@ -154,7 +154,7 @@ Optional argument IGNORE is an extraneous parameter."
   :clone-object-children nil
   )
 
-(defun eieio-object-match (widget value)
+(defun eieio-object-match (_widget _value)
   "Match info for WIDGET against VALUE."
   ;; Write me
   t)
@@ -193,7 +193,7 @@ Optional argument IGNORE is an extraneous parameter."
   (let* ((chil nil)
         (obj (widget-get widget :value))
         (master-group (widget-get widget :eieio-group))
-        (cv (class-v (eieio--object-class obj)))
+        (cv (eieio--object-class-object obj))
         (slots (eieio--class-public-a cv))
         (flabel (eieio--class-public-custom-label cv))
         (fgroup (eieio--class-public-custom-group cv))
@@ -208,7 +208,8 @@ Optional argument IGNORE is an extraneous parameter."
                         chil)))
     ;; Display information about the group being shown
     (when master-group
-      (let ((groups (class-option (eieio--object-class obj) :custom-groups)))
+      (let ((groups (eieio--class-option (eieio--object-class-object obj)
+                                         :custom-groups)))
        (widget-insert "Groups:")
        (while groups
          (widget-insert "  ")
@@ -216,7 +217,7 @@ Optional argument IGNORE is an extraneous parameter."
              (widget-insert "*" (capitalize (symbol-name master-group)) "*")
            (widget-create 'push-button
                           :thing (cons obj (car groups))
-                          :notify (lambda (widget &rest stuff)
+                          :notify (lambda (widget &rest _)
                                     (eieio-customize-object
                                      (car (widget-get widget :thing))
                                      (cdr (widget-get widget :thing))))
@@ -260,8 +261,8 @@ Optional argument IGNORE is an extraneous parameter."
                                 (car flabel)
                               (let ((s (symbol-name
                                         (or
-                                         (class-slot-initarg
-                                          (eieio--object-class obj)
+                                         (eieio--class-slot-initarg
+                                          (eieio--object-class-object obj)
                                           (car slots))
                                          (car slots)))))
                                 (capitalize
@@ -288,7 +289,7 @@ Optional argument IGNORE is an extraneous parameter."
   "Get the value of WIDGET."
   (let* ((obj (widget-get widget :value))
         (master-group eieio-cog)
-        (cv (class-v (eieio--object-class obj)))
+        (cv (eieio--object-class-object obj))
         (fgroup (eieio--class-public-custom-group cv))
         (wids (widget-get widget :children))
         (name (if (widget-get widget :eieio-show-name)
@@ -296,7 +297,7 @@ Optional argument IGNORE is an extraneous parameter."
                 nil))
         (chil (if (widget-get widget :eieio-show-name)
                   (nthcdr 1 wids) wids))
-        (cv (class-v (eieio--object-class obj)))
+        (cv (eieio--object-class-object obj))
         (slots (eieio--class-public-a cv))
         (fcust (eieio--class-public-custom cv)))
     ;; If there are any prefix widgets, clear them.
@@ -317,11 +318,11 @@ Optional argument IGNORE is an extraneous parameter."
            fgroup (cdr fgroup)
            fcust (cdr fcust)))
     ;; Set any name updates on it.
-    (if name (setf (eieio--object-name obj) name))
+    (if name (eieio-object-set-name-string obj name))
     ;; This is the same object we had before.
     obj))
 
-(defmethod eieio-done-customizing ((obj eieio-default-superclass))
+(defmethod eieio-done-customizing ((_obj eieio-default-superclass))
   "When applying change to a widget, call this method.
 This method is called by the default widget-edit commands.
 User made commands should also call this method when applying changes.
@@ -385,18 +386,18 @@ These groups are specified with the `:group' slot flag."
     (make-local-variable 'eieio-cog)
     (setq eieio-cog g)))
 
-(defmethod eieio-custom-object-apply-reset ((obj eieio-default-superclass))
+(defmethod eieio-custom-object-apply-reset ((_obj eieio-default-superclass))
   "Insert an Apply and Reset button into the object editor.
 Argument OBJ is the object being customized."
   (widget-create 'push-button
-                :notify (lambda (&rest ignore)
+                :notify (lambda (&rest _)
                           (widget-apply eieio-wo :value-get)
                           (eieio-done-customizing eieio-co)
                           (bury-buffer))
                 "Accept")
   (widget-insert "   ")
   (widget-create 'push-button
-                :notify (lambda (&rest ignore)
+                :notify (lambda (&rest _)
                           ;; I think the act of getting it sets
                           ;; its value through the get function.
                           (message "Applying Changes...")
@@ -406,13 +407,13 @@ Argument OBJ is the object being customized."
                 "Apply")
   (widget-insert "   ")
   (widget-create 'push-button
-                :notify (lambda (&rest ignore)
+                :notify (lambda (&rest _)
                           (message "Resetting")
                           (eieio-customize-object eieio-co eieio-cog))
                 "Reset")
   (widget-insert "   ")
   (widget-create 'push-button
-                :notify (lambda (&rest ignore)
+                :notify (lambda (&rest _)
                           (bury-buffer))
                 "Cancel"))
 
@@ -431,13 +432,11 @@ Must return the created widget."
   :clone-object-children t
   )
 
-(defun eieio-object-value-to-abstract (widget value)
+(defun eieio-object-value-to-abstract (_widget value)
   "For WIDGET, convert VALUE to an abstract /safe/ representation."
-  (if (eieio-object-p value) value
-    (if (null value) value
-      nil)))
+  (if (eieio-object-p value) value))
 
-(defun eieio-object-abstract-to-value (widget value)
+(defun eieio-object-abstract-to-value (_widget value)
   "For WIDGET, convert VALUE from an abstract /safe/ representation."
   value)
 
@@ -453,7 +452,7 @@ Must return the created widget."
            (vector (concat "Group " (symbol-name group))
                    (list 'customize-object obj (list 'quote group))
                    t))
-         (class-option (eieio--object-class obj) :custom-groups)))
+         (eieio--class-option (eieio--object-class-object obj) 
:custom-groups)))
 
 (defvar eieio-read-custom-group-history nil
   "History for the custom group reader.")
@@ -461,7 +460,8 @@ Must return the created widget."
 (defmethod eieio-read-customization-group ((obj eieio-default-superclass))
   "Do a completing read on the name of a customization group in OBJ.
 Return the symbol for the group, or nil"
-  (let ((g (class-option (eieio--object-class obj) :custom-groups)))
+  (let ((g (eieio--class-option (eieio--object-class-object obj)
+                                :custom-groups)))
     (if (= (length g) 1)
        (car g)
       ;; Make the association list
diff --git a/lisp/emacs-lisp/eieio-datadebug.el 
b/lisp/emacs-lisp/eieio-datadebug.el
index 0a51ecf..43d9a03 100644
--- a/lisp/emacs-lisp/eieio-datadebug.el
+++ b/lisp/emacs-lisp/eieio-datadebug.el
@@ -1,4 +1,4 @@
-;;; eieio-datadebug.el --- EIEIO extensions to the data debugger.
+;;; eieio-datadebug.el --- EIEIO extensions to the data debugger.  -*- 
lexical-binding:t -*-
 
 ;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
 
@@ -87,7 +87,7 @@ PREBUTTONTEXT is some text between PREFIX and the object 
button."
                             prefix
                             "Name: ")
     (let* ((cl (eieio-object-class obj))
-          (cv (class-v cl)))
+          (cv (eieio--class-v cl)))
       (data-debug-insert-thing (class-constructor cl)
                               prefix
                               "Class: ")
@@ -96,7 +96,8 @@ PREBUTTONTEXT is some text between PREFIX and the object 
button."
            )
        (while publa
          (if (slot-boundp obj (car publa))
-             (let* ((i (class-slot-initarg cl (car publa)))
+             (let* ((i (eieio--class-slot-initarg (eieio--class-v cl)
+                                                   (car publa)))
                     (v (eieio-oref obj (car publa))))
                (data-debug-insert-thing
                 v prefix (concat
@@ -104,7 +105,8 @@ PREBUTTONTEXT is some text between PREFIX and the object 
button."
                             (symbol-name (car publa)))
                           " ")))
            ;; Unbound case
-           (let ((i (class-slot-initarg cl (car publa))))
+           (let ((i (eieio--class-slot-initarg (eieio--class-v cl)
+                                                (car publa))))
              (data-debug-insert-custom
               "#unbound" prefix
               (concat (if i (symbol-name i)
@@ -135,9 +137,9 @@ PREBUTTONTEXT is some text between PREFIX and the object 
button."
   (let* ((eieio-pre-method-execution-functions
          (lambda (l) (throw 'moose l) ))
         (data
-         (catch 'moose (eieio-generic-call
+         (catch 'moose (eieio--generic-call
                         method (list class))))
-        (buf (data-debug-new-buffer "*Method Invocation*"))
+        (_buf (data-debug-new-buffer "*Method Invocation*"))
         (data2 (mapcar (lambda (sym)
                          (symbol-function (car sym)))
                          data)))
diff --git a/lisp/emacs-lisp/eieio-generic.el b/lisp/emacs-lisp/eieio-generic.el
new file mode 100644
index 0000000..0e90074
--- /dev/null
+++ b/lisp/emacs-lisp/eieio-generic.el
@@ -0,0 +1,904 @@
+;;; eieio-generic.el --- CLOS-style generics for EIEIO  -*- lexical-binding:t 
-*-
+
+;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc.
+
+;; Author: Eric M. Ludlam <address@hidden>
+;; Keywords: OO, lisp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; The "core" part of EIEIO is the implementation for the object
+;; system (such as eieio-defclass, or eieio-defmethod) but not the
+;; base classes for the object system, which are defined in EIEIO.
+;;
+;; See the commentary for eieio.el for more about EIEIO itself.
+
+;;; Code:
+
+(require 'eieio-core)
+(declare-function child-of-class-p "eieio")
+
+(defconst eieio--method-static 0 "Index into :static tag on a method.")
+(defconst eieio--method-before 1 "Index into :before tag on a method.")
+(defconst eieio--method-primary 2 "Index into :primary tag on a method.")
+(defconst eieio--method-after 3 "Index into :after tag on a method.")
+(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in 
which groups of functions are kept.")
+(defconst eieio--method-generic-before 4 "Index into generic :before tag on a 
method.")
+(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on 
a method.")
+(defconst eieio--method-generic-after 6 "Index into generic :after tag on a 
method.")
+(defconst eieio--method-num-slots 7 "Number of indexes into a method's 
vector.")
+
+(defsubst eieio--specialized-key-to-generic-key (key)
+  "Convert a specialized KEY into a generic method key."
+  (cond ((eq key eieio--method-static) 0) ;; don't convert
+       ((< key eieio--method-num-lists) (+ key 3)) ;; The conversion
+       (t key) ;; already generic.. maybe.
+       ))
+
+
+(defsubst generic-p (method)
+  "Return non-nil if symbol METHOD is a generic function.
+Only methods have the symbol `eieio-method-hashtable' as a property
+\(which contains a list of all bindings to that method type.)"
+  (and (fboundp method) (get method 'eieio-method-hashtable)))
+
+(defun eieio--generic-primary-only-p (method)
+  "Return t if symbol METHOD is a generic function with only primary methods.
+Only methods have the symbol `eieio-method-hashtable' as a property (which
+contains a list of all bindings to that method type.)
+Methods with only primary implementations are executed in an optimized way."
+  (and (generic-p method)
+       (let ((M (get method 'eieio-method-tree)))
+        (not (or (>= 0 (length (aref M eieio--method-primary)))
+                  (aref M eieio--method-static)
+                  (aref M eieio--method-before)
+                  (aref M eieio--method-after)
+                  (aref M eieio--method-generic-before)
+                  (aref M eieio--method-generic-primary)
+                  (aref M eieio--method-generic-after)))
+         )))
+
+(defun eieio--generic-primary-only-one-p (method)
+  "Return t if symbol METHOD is a generic function with only primary methods.
+Only methods have the symbol `eieio-method-hashtable' as a property (which
+contains a list of all bindings to that method type.)
+Methods with only primary implementations are executed in an optimized way."
+  (and (generic-p method)
+       (let ((M (get method 'eieio-method-tree)))
+        (not (or (/= 1 (length (aref M eieio--method-primary)))
+                  (aref M eieio--method-static)
+                  (aref M eieio--method-before)
+                  (aref M eieio--method-after)
+                  (aref M eieio--method-generic-before)
+                  (aref M eieio--method-generic-primary)
+                  (aref M eieio--method-generic-after)))
+         )))
+
+(defun eieio--defgeneric-init-form (method doc-string)
+  "Form to use for the initial definition of a generic."
+  (while (and (fboundp method) (symbolp (symbol-function method)))
+    ;; Follow aliases, so methods applied to obsolete aliases still work.
+    (setq method (symbol-function method)))
+
+  (cond
+   ((or (not (fboundp method))
+        (eq 'autoload (car-safe (symbol-function method))))
+    ;; Make sure the method tables are installed.
+    (eieio--mt-install method)
+    ;; Construct the actual body of this function.
+    (put method 'function-documentation doc-string)
+    (eieio--defgeneric-form method))
+   ((generic-p method) (symbol-function method))           ;Leave it as-is.
+   (t (error "You cannot create a generic/method over an existing symbol: %s"
+             method))))
+
+(defun eieio--defgeneric-form (method)
+  "The lambda form that would be used as the function defined on METHOD.
+All methods should call the same EIEIO function for dispatch.
+DOC-STRING is the documentation attached to METHOD."
+  (lambda (&rest local-args)
+    (eieio--generic-call method local-args)))
+
+(defun eieio--defgeneric-form-primary-only (method)
+  "The lambda form that would be used as the function defined on METHOD.
+All methods should call the same EIEIO function for dispatch.
+DOC-STRING is the documentation attached to METHOD."
+  (lambda (&rest local-args)
+    (eieio--generic-call-primary-only method local-args)))
+
+(defvar eieio--generic-call-arglst nil
+  "When using `call-next-method', provides a context for parameters.")
+(defvar eieio--generic-call-key nil
+  "When using `call-next-method', provides a context for the current key.
+Keys are a number representing :before, :primary, and :after methods.")
+(defvar eieio--generic-call-next-method-list nil
+  "When executing a PRIMARY or STATIC method, track the 'next-method'.
+During executions, the list is first generated, then as each next method
+is called, the next method is popped off the stack.")
+
+(defun eieio--defgeneric-form-primary-only-one (method class impl)
+  "The lambda form that would be used as the function defined on METHOD.
+All methods should call the same EIEIO function for dispatch.
+CLASS is the class symbol needed for private method access.
+IMPL is the symbol holding the method implementation."
+  (lambda (&rest local-args)
+    ;; This is a cool cheat.  Usually we need to look up in the
+    ;; method table to find out if there is a method or not.  We can
+    ;; instead make that determination at load time when there is
+    ;; only one method.  If the first arg is not a child of the class
+    ;; of that one implementation, then clearly, there is no method def.
+    (if (not (eieio-object-p (car local-args)))
+        ;; Not an object.  Just signal.
+        (signal 'no-method-definition
+                (list method local-args))
+
+      ;; We do have an object.  Make sure it is the right type.
+      (if (not (child-of-class-p (eieio--object-class-object (car local-args))
+                                 class))
+
+          ;; If not the right kind of object, call no applicable
+          (apply #'no-applicable-method (car local-args)
+                 method local-args)
+
+        ;; It is ok, do the call.
+        ;; Fill in inter-call variables then evaluate the method.
+        (let ((eieio--generic-call-next-method-list nil)
+              (eieio--generic-call-key eieio--method-primary)
+              (eieio--generic-call-arglst local-args)
+              )
+          (eieio--with-scoped-class (eieio--class-v class)
+            (apply impl local-args)))))))
+
+(defun eieio-unbind-method-implementations (method)
+  "Make the generic method METHOD have no implementations.
+It will leave the original generic function in place,
+but remove reference to all implementations of METHOD."
+  (put method 'eieio-method-tree nil)
+  (put method 'eieio-method-hashtable nil))
+
+(defun eieio--method-optimize-primary (method)
+  (when eieio-optimize-primary-methods-flag
+    ;; Optimizing step:
+    ;;
+    ;; If this method, after this setup, only has primary methods, then
+    ;; we can setup the generic that way.
+    (let ((doc-string (documentation method 'raw)))
+      (put method 'function-documentation doc-string)
+      ;; Use `defalias' so as to interact properly with nadvice.el.
+      (defalias method
+        (if (eieio--generic-primary-only-p method)
+            ;; If there is only one primary method, then we can go one more
+            ;; optimization step.
+            (if (eieio--generic-primary-only-one-p method)
+                (let* ((M (get method 'eieio-method-tree))
+                       (entry (car (aref M eieio--method-primary))))
+                  (eieio--defgeneric-form-primary-only-one
+                   method (car entry) (cdr entry)))
+              (eieio--defgeneric-form-primary-only method))
+          (eieio--defgeneric-form method))))))
+
+(defun eieio--defmethod (method kind argclass code)
+  "Work part of the `defmethod' macro defining METHOD with ARGS."
+  (let ((key
+         ;; Find optional keys.
+         (cond ((memq kind '(:BEFORE :before)) eieio--method-before)
+               ((memq kind '(:AFTER :after)) eieio--method-after)
+               ((memq kind '(:STATIC :static)) eieio--method-static)
+               ((memq kind '(:PRIMARY :primary nil)) eieio--method-primary)
+               ;; Primary key.
+               ;; (t eieio--method-primary)
+               (t (error "Unknown method kind %S" kind)))))
+
+    (while (and (fboundp method) (symbolp (symbol-function method)))
+      ;; Follow aliases, so methods applied to obsolete aliases still work.
+      (setq method (symbol-function method)))
+
+    ;; Make sure there is a generic (when called from defclass).
+    (eieio--defalias
+     method (eieio--defgeneric-init-form
+             method (or (documentation code)
+                        (format "Generically created method `%s'." method))))
+    ;; Create symbol for property to bind to.  If the first arg is of
+    ;; the form (varname vartype) and `vartype' is a class, then
+    ;; that class will be the type symbol.  If not, then it will fall
+    ;; under the type `primary' which is a non-specific calling of the
+    ;; function.
+    (if argclass
+        (if (not (class-p argclass))    ;FIXME: Accept cl-defstructs!
+            (error "Unknown class type %s in method parameters"
+                   argclass))
+      ;; Generics are higher.
+      (setq key (eieio--specialized-key-to-generic-key key)))
+    ;; Put this lambda into the symbol so we can find it.
+    (eieio--mt-add method code key argclass)
+    )
+
+  (eieio--method-optimize-primary method)
+
+  method)
+
+(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks
+  'eieio-pre-method-execution-functions "24.3")
+(defvar eieio-pre-method-execution-functions nil
+  "Abnormal hook run just before an EIEIO method is executed.
+The hook function must accept one argument, the list of forms
+about to be executed.")
+
+(defun eieio--generic-call (method args)
+  "Call METHOD with ARGS.
+ARGS provides the context on which implementation to use.
+This should only be called from a generic function."
+  ;; We must expand our arguments first as they are always
+  ;; passed in as quoted symbols
+  (let ((newargs nil) (mclass nil)  (lambdas nil) (tlambdas nil) (keys nil)
+       (eieio--generic-call-arglst args)
+       (firstarg nil)
+       (primarymethodlist nil))
+    ;; get a copy
+    (setq newargs args
+         firstarg (car newargs))
+    ;; Is the class passed in autoloaded?
+    ;; Since class names are also constructors, they can be autoloaded
+    ;; via the autoload command.  Check for this, and load them in.
+    ;; It is ok if it doesn't turn out to be a class.  Probably want that
+    ;; function loaded anyway.
+    (if (and (symbolp firstarg)
+            (fboundp firstarg)
+            (autoloadp (symbol-function firstarg)))
+       (autoload-do-load (symbol-function firstarg)))
+    ;; Determine the class to use.
+    (cond ((eieio-object-p firstarg)
+          (setq mclass (eieio--object-class-name firstarg)))
+         ((class-p firstarg)
+          (setq mclass firstarg))
+         )
+    ;; Make sure the class is a valid class
+    ;; mclass can be nil (meaning a generic for should be used.
+    ;; mclass cannot have a value that is not a class, however.
+    (unless (or (null mclass) (class-p mclass))
+      (error "Cannot dispatch method %S on class %S"
+            method mclass)
+      )
+    ;; Now create a list in reverse order of all the calls we have
+    ;; make in order to successfully do this right.  Rules:
+    ;; 1) Only call generics if scoped-class is not defined
+    ;;    This prevents multiple calls in the case of recursion
+    ;; 2) Only call static if this is a static method.
+    ;; 3) Only call specifics if the definition allows for them.
+    ;; 4) Call in order based on :before, :primary, and :after
+    (when (eieio-object-p firstarg)
+      ;; Non-static calls do all this stuff.
+
+      ;; :after methods
+      (setq tlambdas
+           (if mclass
+               (eieio--mt-method-list method eieio--method-after mclass)
+             (list (eieio--generic-form method eieio--method-after nil)))
+           ;;(or (and mclass (eieio--generic-form method eieio--method-after 
mclass))
+           ;;  (eieio--generic-form method eieio--method-after nil))
+           )
+      (setq lambdas (append tlambdas lambdas)
+           keys (append (make-list (length tlambdas) eieio--method-after) 
keys))
+
+      ;; :primary methods
+      (setq tlambdas
+           (or (and mclass (eieio--generic-form method eieio--method-primary 
mclass))
+               (eieio--generic-form method eieio--method-primary nil)))
+      (when tlambdas
+       (setq lambdas (cons tlambdas lambdas)
+             keys (cons eieio--method-primary keys)
+             primarymethodlist
+             (eieio--mt-method-list method eieio--method-primary mclass)))
+
+      ;; :before methods
+      (setq tlambdas
+           (if mclass
+               (eieio--mt-method-list method eieio--method-before mclass)
+             (list (eieio--generic-form method eieio--method-before nil)))
+           ;;(or (and mclass (eieio--generic-form method eieio--method-before 
mclass))
+           ;;  (eieio--generic-form method eieio--method-before nil))
+           )
+      (setq lambdas (append tlambdas lambdas)
+           keys (append (make-list (length tlambdas) eieio--method-before) 
keys))
+      )
+
+    (if mclass
+       ;; For the case of a class,
+       ;; if there were no methods found, then there could be :static methods.
+       (when (not lambdas)
+         (setq tlambdas
+               (eieio--generic-form method eieio--method-static mclass))
+         (setq lambdas (cons tlambdas lambdas)
+               keys (cons eieio--method-static keys)
+               primarymethodlist  ;; Re-use even with bad name here
+               (eieio--mt-method-list method eieio--method-static mclass)))
+      ;; For the case of no class (ie - mclass == nil) then there may
+      ;; be a primary method.
+      (setq tlambdas
+           (eieio--generic-form method eieio--method-primary nil))
+      (when tlambdas
+       (setq lambdas (cons tlambdas lambdas)
+             keys (cons eieio--method-primary keys)
+             primarymethodlist
+             (eieio--mt-method-list method eieio--method-primary nil)))
+      )
+
+    (run-hook-with-args 'eieio-pre-method-execution-functions
+                       primarymethodlist)
+
+    ;; Now loop through all occurrences forms which we must execute
+    ;; (which are happily sorted now) and execute them all!
+    (let ((rval nil) (lastval nil) (found nil))
+      (while lambdas
+       (if (car lambdas)
+           (eieio--with-scoped-class (cdr (car lambdas))
+             (let* ((eieio--generic-call-key (car keys))
+                    (has-return-val
+                     (or (= eieio--generic-call-key eieio--method-primary)
+                         (= eieio--generic-call-key eieio--method-static)))
+                    (eieio--generic-call-next-method-list
+                     ;; Use the cdr, as the first element is the fcn
+                     ;; we are calling right now.
+                     (when has-return-val (cdr primarymethodlist)))
+                    )
+               (setq found t)
+               ;;(setq rval (apply (car (car lambdas)) newargs))
+               (setq lastval (apply (car (car lambdas)) newargs))
+               (when has-return-val
+                 (setq rval lastval))
+               )))
+       (setq lambdas (cdr lambdas)
+             keys (cdr keys)))
+      (if (not found)
+         (if (eieio-object-p (car args))
+             (setq rval (apply #'no-applicable-method (car args) method args))
+           (signal
+            'no-method-definition
+            (list method args))))
+      rval)))
+
+(defun eieio--generic-call-primary-only (method args)
+  "Call METHOD with ARGS for methods with only :PRIMARY implementations.
+ARGS provides the context on which implementation to use.
+This should only be called from a generic function.
+
+This method is like `eieio--generic-call', but only
+implementations in the :PRIMARY slot are queried.  After many
+years of use, it appears that over 90% of methods in use
+have :PRIMARY implementations only.  We can therefore optimize
+for this common case to improve performance."
+  ;; We must expand our arguments first as they are always
+  ;; passed in as quoted symbols
+  (let ((newargs nil) (mclass nil)  (lambdas nil)
+       (eieio--generic-call-arglst args)
+       (firstarg nil)
+       (primarymethodlist nil)
+       )
+    ;; get a copy
+    (setq newargs args
+         firstarg (car newargs))
+
+    ;; Determine the class to use.
+    (cond ((eieio-object-p firstarg)
+          (setq mclass (eieio--object-class-name firstarg)))
+         ((not firstarg)
+          (error "Method %s called on nil" method))
+         (t
+          (error "Primary-only method %s called on something not an object" 
method)))
+    ;; Make sure the class is a valid class
+    ;; mclass can be nil (meaning a generic for should be used.
+    ;; mclass cannot have a value that is not a class, however.
+    (when (null mclass)
+      (error "Cannot dispatch method %S on class %S" method mclass)
+      )
+
+    ;; :primary methods
+    (setq lambdas (eieio--generic-form method eieio--method-primary mclass))
+    (setq primarymethodlist  ;; Re-use even with bad name here
+         (eieio--mt-method-list method eieio--method-primary mclass))
+
+    ;; Now loop through all occurrences forms which we must execute
+    ;; (which are happily sorted now) and execute them all!
+    (eieio--with-scoped-class (cdr lambdas)
+      (let* ((rval nil) (lastval nil)
+            (eieio--generic-call-key eieio--method-primary)
+            ;; Use the cdr, as the first element is the fcn
+            ;; we are calling right now.
+            (eieio--generic-call-next-method-list (cdr primarymethodlist))
+            )
+
+       (if (or (not lambdas) (not (car lambdas)))
+
+           ;; No methods found for this impl...
+           (if (eieio-object-p (car args))
+               (setq rval (apply #'no-applicable-method
+                                  (car args) method args))
+             (signal
+              'no-method-definition
+              (list method args)))
+
+         ;; Do the regular implementation here.
+
+         (run-hook-with-args 'eieio-pre-method-execution-functions
+                             lambdas)
+
+         (setq lastval (apply (car lambdas) newargs))
+         (setq rval lastval))
+
+       rval))))
+
+(defun eieio--mt-method-list (method key class)
+  "Return an alist list of methods lambdas.
+METHOD is the method name.
+KEY represents either :before, or :after methods.
+CLASS is the starting class to search from in the method tree.
+If CLASS is nil, then an empty list of methods should be returned."
+  ;; Note: eieiomt - the MT means MethodTree.  See more comments below
+  ;; for the rest of the eieiomt methods.
+
+  ;; Collect lambda expressions stored for the class and its parent
+  ;; classes.
+  (let (lambdas)
+    (dolist (ancestor (eieio--class-precedence-list (eieio--class-v class)))
+      ;; Lookup the form to use for the PRIMARY object for the next level
+      (let ((tmpl (eieio--generic-form method key ancestor)))
+       (when (and tmpl
+                  (or (not lambdas)
+                      ;; This prevents duplicates coming out of the
+                      ;; class method optimizer.  Perhaps we should
+                      ;; just not optimize before/afters?
+                      (not (member tmpl lambdas))))
+         (push tmpl lambdas))))
+
+    ;; Return collected lambda. For :after methods, return in current
+    ;; order (most general class last); Otherwise, reverse order.
+    (if (eq key eieio--method-after)
+       lambdas
+      (nreverse lambdas))))
+
+
+;;;
+;; eieio-method-tree : eieio--mt-
+;;
+;; Stored as eieio-method-tree in property list of a generic method
+;;
+;; (eieio-method-tree . [BEFORE PRIMARY AFTER
+;;                       genericBEFORE genericPRIMARY genericAFTER])
+;; and
+;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER
+;;                          genericBEFORE genericPRIMARY genericAFTER])
+;;    where the association is a vector.
+;;    (aref 0  -- all static methods.
+;;    (aref 1  -- all methods classified as :before
+;;    (aref 2  -- all methods classified as :primary
+;;    (aref 3  -- all methods classified as :after
+;;    (aref 4  -- a generic classified as :before
+;;    (aref 5  -- a generic classified as :primary
+;;    (aref 6  -- a generic classified as :after
+;;
+(defvar eieio--mt--optimizing-hashtable nil
+  "While mapping atoms, this contain the hashtable being optimized.")
+
+(defun eieio--mt-install (method-name)
+  "Install the method tree, and hashtable onto METHOD-NAME.
+Do not do the work if they already exist."
+  (unless (and (get method-name 'eieio-method-tree)
+               (get method-name 'eieio-method-hashtable))
+    (put method-name 'eieio-method-tree
+         (make-vector eieio--method-num-slots nil))
+    (let ((emto (put method-name 'eieio-method-hashtable
+                     (make-vector eieio--method-num-slots nil))))
+      (aset emto 0 (make-hash-table :test 'eq))
+      (aset emto 1 (make-hash-table :test 'eq))
+      (aset emto 2 (make-hash-table :test 'eq))
+      (aset emto 3 (make-hash-table :test 'eq)))))
+
+(defun eieio--mt-add (method-name method key class)
+  "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS.
+METHOD-NAME is the name created by a call to `defgeneric'.
+METHOD are the forms for a given implementation.
+KEY is an integer (see comment in eieio.el near this function) which
+is associated with the :static :before :primary and :after tags.
+It also indicates if CLASS is defined or not.
+CLASS is the class this method is associated with."
+  (if (or (> key eieio--method-num-slots) (< key 0))
+      (error "eieio--mt-add: method key error!"))
+  (let ((emtv (get method-name 'eieio-method-tree))
+       (emto (get method-name 'eieio-method-hashtable)))
+    ;; Make sure the method tables are available.
+    (unless (and emtv emto)
+      (error "Programmer error: eieio--mt-add"))
+    ;; only add new cells on if it doesn't already exist!
+    (if (assq class (aref emtv key))
+       (setcdr (assq class (aref emtv key)) method)
+      (aset emtv key (cons (cons class method) (aref emtv key))))
+    ;; Add function definition into newly created symbol, and store
+    ;; said symbol in the correct hashtable, otherwise use the
+    ;; other array to keep this stuff.
+    (if (< key eieio--method-num-lists)
+        (puthash (eieio--class-v class) (list method) (aref emto key)))
+    ;; Save the defmethod file location in a symbol property.
+    (let ((fname (if load-in-progress
+                    load-file-name
+                  buffer-file-name)))
+      (when fname
+       (when (string-match "\\.elc\\'" fname)
+         (setq fname (substring fname 0 (1- (length fname)))))
+       (cl-pushnew (list class fname) (get method-name 'method-locations)
+                    :test 'equal)))
+    ;; Now optimize the entire hashtable.
+    (if (< key eieio--method-num-lists)
+       (let ((eieio--mt--optimizing-hashtable (aref emto key)))
+         ;; @todo - Is this overkill?  Should we just clear the symbol?
+         (maphash #'eieio--mt--sym-optimize eieio--mt--optimizing-hashtable)))
+    ))
+
+(defun eieio--mt-next (class)
+  "Return the next parent class for CLASS.
+If CLASS is a superclass, return variable `eieio-default-superclass'.
+If CLASS is variable `eieio-default-superclass' then return nil.
+This is different from function `class-parent' as class parent returns
+nil for superclasses.  This function performs no type checking!"
+  ;; No type-checking because all calls are made from functions which
+  ;; are safe and do checking for us.
+  (or (eieio--class-parent (eieio--class-v class))
+      (if (eq class 'eieio-default-superclass)
+         nil
+       '(eieio-default-superclass))))
+
+(defun eieio--mt--sym-optimize (class s)
+  "Find the next class above S which has a function body for the optimizer."
+  ;; Set the value to nil in case there is no nearest cell.
+  (setcdr s nil)
+  ;; Find the nearest cell that has a function body. If we find one,
+  ;; we replace the nil from above.
+  (catch 'done
+    (dolist (ancestor
+             (cl-rest (eieio--class-precedence-list class)))
+      (let ((ov (gethash ancestor eieio--mt--optimizing-hashtable)))
+        (when (car ov)
+          (setcdr s ancestor) ;; store ov as our next symbol
+          (throw 'done ancestor))))))
+
+(defun eieio--generic-form (method key class)
+ "Return the lambda form belonging to METHOD using KEY based upon CLASS.
+If CLASS is not a class then use `generic' instead.  If class has
+no form, but has a parent class, then trace to that parent class.
+The first time a form is requested from a symbol, an optimized path
+is memorized for faster future use."
+ (if (symbolp class) (setq class (eieio--class-v class)))
+ (let ((emto (aref (get method 'eieio-method-hashtable)
+                  (if class key (eieio--specialized-key-to-generic-key key)))))
+   (if (eieio--class-p class)
+       ;; 1) find our symbol
+       (let ((cs (gethash class emto)))
+        (unless cs
+           ;; 2) If there isn't one, then make one.
+           ;;    This can be slow since it only occurs once
+           (puthash class (setq cs (list nil)) emto)
+           ;; 2.1) Cache its nearest neighbor with a quick optimize
+           ;;      which should only occur once for this call ever
+           (let ((eieio--mt--optimizing-hashtable emto))
+             (eieio--mt--sym-optimize class cs)))
+        ;; 3) If it's bound return this one.
+        (if (car cs)
+            (cons (car cs) class)
+          ;; 4) If it's not bound then this variable knows something
+          (if (cdr cs)
+              (progn
+                ;; 4.1) This symbol holds the next class in its value
+                (setq class (cdr cs)
+                      cs (gethash class emto))
+                ;; 4.2) The optimizer should always have chosen a
+                ;;      function-symbol
+                ;;(if (car cs)
+                (cons (car cs) class)
+                 ;;(error "EIEIO optimizer: erratic data loss!"))
+                )
+             ;; There never will be a funcall...
+             nil)))
+     ;; for a generic call, what is a list, is the function body we want.
+     (let ((emtl (aref (get method 'eieio-method-tree)
+                      (if class key (eieio--specialized-key-to-generic-key 
key)))))
+       (if emtl
+          ;; The car of EMTL is supposed to be a class, which in this
+          ;; case is nil, so skip it.
+          (cons (cdr (car emtl)) nil)
+        nil)))))
+
+
+(define-error 'no-method-definition "No method definition")
+(define-error 'no-next-method "No next method")
+
+;;; CLOS methods and generics
+;;
+(defmacro defgeneric (method _args &optional doc-string)
+  "Create a generic function METHOD.
+DOC-STRING is the base documentation for this class.  A generic
+function has no body, as its purpose is to decide which method body
+is appropriate to use.  Uses `defmethod' to create methods, and calls
+`defgeneric' for you.  With this implementation the ARGS are
+currently ignored.  You can use `defgeneric' to apply specialized
+top level documentation to a method."
+  (declare (doc-string 3))
+  `(eieio--defalias ',method
+                    (eieio--defgeneric-init-form ',method ,doc-string)))
+
+(defmacro defmethod (method &rest args)
+  "Create a new METHOD through `defgeneric' with ARGS.
+
+The optional second argument KEY is a specifier that
+modifies how the method is called, including:
+   :before  - Method will be called before the :primary
+   :primary - The default if not specified
+   :after   - Method will be called after the :primary
+   :static  - First arg could be an object or class
+The next argument is the ARGLIST.  The ARGLIST specifies the arguments
+to the method as with `defun'.  The first argument can have a type
+specifier, such as:
+  ((VARNAME CLASS) ARG2 ...)
+where VARNAME is the name of the local variable for the method being
+created.  The CLASS is a class symbol for a class made with `defclass'.
+A DOCSTRING comes after the ARGLIST, and is optional.
+All the rest of the args are the BODY of the method.  A method will
+return the value of the last form in the BODY.
+
+Summary:
+
+ (defmethod mymethod [:before | :primary | :after | :static]
+                     ((typearg class-name) arg2 &optional opt &rest rest)
+    \"doc-string\"
+     body)"
+  (declare (doc-string 3)
+           (debug
+            (&define                    ; this means we are defining something
+             [&or name ("setf" :name setf name)]
+             ;; ^^ This is the methods symbol
+             [ &optional symbolp ]                ; this is key :before etc
+             list                                 ; arguments
+             [ &optional stringp ]                ; documentation string
+             def-body                             ; part to be debugged
+             )))
+  (let* ((key (if (keywordp (car args)) (pop args)))
+        (params (car args))
+        (arg1 (car params))
+         (fargs (if (consp arg1)
+                   (cons (car arg1) (cdr params))
+                 params))
+        (class (if (consp arg1) (nth 1 arg1)))
+         (code `(lambda ,fargs ,@(cdr args))))
+    `(progn
+       ;; Make sure there is a generic and the byte-compiler sees it.
+       (defgeneric ,method ,args
+         ,(or (documentation code)
+              (format "Generically created method `%s'." method)))
+       (eieio--defmethod ',method ',key ',class #',code))))
+
+
+
+;;;
+;; Method Calling Functions
+
+(defun next-method-p ()
+  "Return non-nil if there is a next method.
+Returns a list of lambda expressions which is the `next-method'
+order."
+  eieio--generic-call-next-method-list)
+
+(defun call-next-method (&rest replacement-args)
+  "Call the superclass method from a subclass method.
+The superclass method is specified in the current method list,
+and is called the next method.
+
+If REPLACEMENT-ARGS is non-nil, then use them instead of
+`eieio--generic-call-arglst'.  The generic arg list are the
+arguments passed in at the top level.
+
+Use `next-method-p' to find out if there is a next method to call."
+  (if (not (eieio--scoped-class))
+      (error "`call-next-method' not called within a class specific method"))
+  (if (and (/= eieio--generic-call-key eieio--method-primary)
+          (/= eieio--generic-call-key eieio--method-static))
+      (error "Cannot `call-next-method' except in :primary or :static methods")
+    )
+  (let ((newargs (or replacement-args eieio--generic-call-arglst))
+       (next (car eieio--generic-call-next-method-list))
+       )
+    (if (not (and next (car next)))
+       (apply #'no-next-method newargs)
+      (let* ((eieio--generic-call-next-method-list
+             (cdr eieio--generic-call-next-method-list))
+            (eieio--generic-call-arglst newargs)
+            (fcn (car next))
+            )
+       (eieio--with-scoped-class (cdr next)
+         (apply fcn newargs)) ))))
+
+(defgeneric no-applicable-method (object method &rest args)
+  "Called if there are no implementations for OBJECT in METHOD.")
+
+(defmethod no-applicable-method (object method &rest _args)
+  "Called if there are no implementations for OBJECT in METHOD.
+OBJECT is the object which has no method implementation.
+ARGS are the arguments that were passed to METHOD.
+
+Implement this for a class to block this signal.  The return
+value becomes the return value of the original method call."
+  (signal 'no-method-definition (list method object)))
+
+(defgeneric no-next-method (object &rest args)
+"Called from `call-next-method' when no additional methods are available.")
+
+(defmethod no-next-method (object &rest args)
+  "Called from `call-next-method' when no additional methods are available.
+OBJECT is othe object being called on `call-next-method'.
+ARGS are the arguments it is called by.
+This method signals `no-next-method' by default.  Override this
+method to not throw an error, and its return value becomes the
+return value of `call-next-method'."
+  (signal 'no-next-method (list object args)))
+
+(add-hook 'help-fns-describe-function-functions 'eieio--help-generic)
+(defun eieio--help-generic (generic)
+  "Describe GENERIC if it is a generic function."
+  (when (and (symbolp generic) (generic-p generic))
+    (save-excursion
+      (goto-char (point-min))
+      (when (re-search-forward " in `.+'.$" nil t)
+       (replace-match ".")))
+    (save-excursion
+      (insert "\n\nThis is a generic function"
+             (cond
+              ((and (eieio--generic-primary-only-p generic)
+                    (eieio--generic-primary-only-one-p generic))
+               " with only one primary method")
+              ((eieio--generic-primary-only-p generic)
+               " with only primary methods")
+              (t ""))
+             ".\n\n")
+      (insert (propertize "Implementations:\n\n" 'face 'bold))
+      (let ((i 4)
+           (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
+       ;; Loop over fanciful generics
+       (while (< i 7)
+         (let ((gm (aref (get generic 'eieio-method-tree) i)))
+           (when gm
+             (insert "Generic "
+                     (aref prefix (- i 3))
+                     "\n"
+                     (or (nth 2 gm) "Undocumented")
+                     "\n\n")))
+         (setq i (1+ i)))
+       (setq i 0)
+       ;; Loop over defined class-specific methods
+       (while (< i 4)
+         (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
+                cname location)
+           (while gm
+             (setq cname (caar gm))
+             (insert "`")
+             (help-insert-xref-button (symbol-name cname)
+                                      'help-variable cname)
+             (insert "' " (aref prefix i) " ")
+             ;; argument list
+             (let* ((func (cdr (car gm)))
+                    (arglst (help-function-arglist func)))
+               (prin1 arglst (current-buffer)))
+             (insert "\n"
+                     (or (documentation (cdr (car gm)))
+                         "Undocumented"))
+             ;; Print file location if available
+             (when (and (setq location (get generic 'method-locations))
+                        (setq location (assoc cname location)))
+               (setq location (cadr location))
+               (insert "\n\nDefined in `")
+               (help-insert-xref-button
+                (file-name-nondirectory location)
+                'eieio-method-def cname generic location)
+               (insert "'\n"))
+             (setq gm (cdr gm))
+             (insert "\n")))
+         (setq i (1+ i)))))))
+
+;;; Obsolete backward compatibility functions.
+;; Needed to run byte-code compiled with the EIEIO of Emacs-23.
+
+(defun eieio-defmethod (method args)
+  "Obsolete work part of an old version of the `defmethod' macro."
+  (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa)
+    ;; find optional keys
+    (setq key
+         (cond ((memq (car args) '(:BEFORE :before))
+                (setq args (cdr args))
+                eieio--method-before)
+               ((memq (car args) '(:AFTER :after))
+                (setq args (cdr args))
+                eieio--method-after)
+               ((memq (car args) '(:STATIC :static))
+                (setq args (cdr args))
+                eieio--method-static)
+               ((memq (car args) '(:PRIMARY :primary))
+                (setq args (cdr args))
+                eieio--method-primary)
+               ;; Primary key.
+               (t eieio--method-primary)))
+    ;; Get body, and fix contents of args to be the arguments of the fn.
+    (setq body (cdr args)
+         args (car args))
+    (setq loopa args)
+    ;; Create a fixed version of the arguments.
+    (while loopa
+      (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa))
+                        argfix))
+      (setq loopa (cdr loopa)))
+    ;; Make sure there is a generic.
+    (eieio-defgeneric
+     method
+     (if (stringp (car body))
+        (car body) (format "Generically created method `%s'." method)))
+    ;; create symbol for property to bind to.  If the first arg is of
+    ;; the form (varname vartype) and `vartype' is a class, then
+    ;; that class will be the type symbol.  If not, then it will fall
+    ;; under the type `primary' which is a non-specific calling of the
+    ;; function.
+    (setq firstarg (car args))
+    (if (listp firstarg)
+       (progn
+         (setq argclass  (nth 1 firstarg))
+         (if (not (class-p argclass))
+             (error "Unknown class type %s in method parameters"
+                    (nth 1 firstarg))))
+      ;; Generics are higher.
+      (setq key (eieio--specialized-key-to-generic-key key)))
+    ;; Put this lambda into the symbol so we can find it.
+    (if (byte-code-function-p (car-safe body))
+       (eieio--mt-add method (car-safe body) key argclass)
+      (eieio--mt-add method (append (list 'lambda (reverse argfix)) body)
+                  key argclass))
+    )
+
+  (eieio--method-optimize-primary method)
+
+  method)
+(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1")
+
+(defun eieio-defgeneric (method doc-string)
+  "Obsolete work part of an old version of the `defgeneric' macro."
+  (if (and (fboundp method) (not (generic-p method))
+          (or (byte-code-function-p (symbol-function method))
+              (not (eq 'autoload (car (symbol-function method)))))
+          )
+      (error "You cannot create a generic/method over an existing symbol: %s"
+            method))
+  ;; Don't do this over and over.
+  (unless (fboundp 'method)
+    ;; This defun tells emacs where the first definition of this
+    ;; method is defined.
+    `(defun ,method nil)
+    ;; Make sure the method tables are installed.
+    (eieio--mt-install method)
+    ;; Apply the actual body of this function.
+    (put method 'function-documentation doc-string)
+    (fset method (eieio--defgeneric-form method))
+    ;; Return the method
+    'method))
+(make-obsolete 'eieio-defgeneric nil "24.1")
+
+(provide 'eieio-generic)
+
+;;; eieio-generic.el ends here
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index bef7ceb..13ad120 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -60,7 +60,7 @@ Argument PREFIX is the character prefix to use.
 Argument CH-PREFIX is another character prefix to display."
   (eieio--check-type class-p this-root)
   (let ((myname (symbol-name this-root))
-       (chl (eieio--class-children (class-v this-root)))
+       (chl (eieio--class-children (eieio--class-v this-root)))
        (fprefix (concat ch-prefix "  +--"))
        (mprefix (concat ch-prefix "  |  "))
        (lprefix (concat ch-prefix "     ")))
@@ -81,7 +81,7 @@ If CLASS is actually an object, then also display current 
values of that object.
   ;; Header line
   (prin1 class)
   (insert " is a"
-         (if (class-option class :abstract)
+         (if (eieio--class-option (eieio--class-v class) :abstract)
              "n abstract"
            "")
          " class")
@@ -149,7 +149,7 @@ If CLASS is actually an object, then also display current 
values of that object.
 (defun eieio-help-class-slots (class)
   "Print help description for the slots in CLASS.
 Outputs to the current buffer."
-  (let* ((cv (class-v class))
+  (let* ((cv (eieio--class-v class))
         (docs   (eieio--class-public-doc cv))
         (names  (eieio--class-public-a cv))
         (deflt  (eieio--class-public-d cv))
@@ -218,11 +218,10 @@ Outputs to the current buffer."
 (defun eieio-build-class-list (class)
   "Return a list of all classes that inherit from CLASS."
   (if (class-p class)
-      (apply #'append
-            (mapcar
-             (lambda (c)
-               (append (list c) (eieio-build-class-list c)))
-             (eieio-class-children-fast class)))
+      (cl-mapcan
+       (lambda (c)
+         (append (list c) (eieio-build-class-list c)))
+       (eieio--class-children (eieio--class-v class)))
     (list class)))
 
 (defun eieio-build-class-alist (&optional class instantiable-only buildlist)
@@ -231,15 +230,16 @@ Optional argument CLASS is the class to start with.
 If INSTANTIABLE-ONLY is non nil, only allow names of classes which
 are not abstract, otherwise allow all classes.
 Optional argument BUILDLIST is more list to attach and is used internally."
-  (let* ((cc (or class eieio-default-superclass))
-        (sublst (eieio--class-children (class-v cc))))
+  (let* ((cc (or class 'eieio-default-superclass))
+        (sublst (eieio--class-children (eieio--class-v cc))))
     (unless (assoc (symbol-name cc) buildlist)
       (when (or (not instantiable-only) (not (class-abstract-p cc)))
+        ;; FIXME: Completion tables don't need alists, and ede/generic.el needs
+        ;; the symbols rather than their names.
        (setq buildlist (cons (cons (symbol-name cc) 1) buildlist))))
-    (while sublst
+    (dolist (elem sublst)
       (setq buildlist (eieio-build-class-alist
-                      (car sublst) instantiable-only buildlist))
-      (setq sublst (cdr sublst)))
+                      elem instantiable-only buildlist)))
     buildlist))
 
 (defvar eieio-read-class nil
@@ -311,132 +311,59 @@ are not abstract."
          (eieio-help-class ctr))
        ))))
 
-
-;;;###autoload
-(defun eieio-help-generic (generic)
-  "Describe GENERIC if it is a generic function."
-  (when (and (symbolp generic) (generic-p generic))
-    (save-excursion
-      (goto-char (point-min))
-      (when (re-search-forward " in `.+'.$" nil t)
-       (replace-match ".")))
-    (save-excursion
-      (insert "\n\nThis is a generic function"
-             (cond
-              ((and (generic-primary-only-p generic)
-                    (generic-primary-only-one-p generic))
-               " with only one primary method")
-              ((generic-primary-only-p generic)
-               " with only primary methods")
-              (t ""))
-             ".\n\n")
-      (insert (propertize "Implementations:\n\n" 'face 'bold))
-      (let ((i 4)
-           (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
-       ;; Loop over fanciful generics
-       (while (< i 7)
-         (let ((gm (aref (get generic 'eieio-method-tree) i)))
-           (when gm
-             (insert "Generic "
-                     (aref prefix (- i 3))
-                     "\n"
-                     (or (nth 2 gm) "Undocumented")
-                     "\n\n")))
-         (setq i (1+ i)))
-       (setq i 0)
-       ;; Loop over defined class-specific methods
-       (while (< i 4)
-         (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
-                cname location)
-           (while gm
-             (setq cname (caar gm))
-             (insert "`")
-             (help-insert-xref-button (symbol-name cname)
-                                      'help-variable cname)
-             (insert "' " (aref prefix i) " ")
-             ;; argument list
-             (let* ((func (cdr (car gm)))
-                    (arglst (help-function-arglist func)))
-               (prin1 arglst (current-buffer)))
-             (insert "\n"
-                     (or (documentation (cdr (car gm)))
-                         "Undocumented"))
-             ;; Print file location if available
-             (when (and (setq location (get generic 'method-locations))
-                        (setq location (assoc cname location)))
-               (setq location (cadr location))
-               (insert "\n\nDefined in `")
-               (help-insert-xref-button
-                (file-name-nondirectory location)
-                'eieio-method-def cname generic location)
-               (insert "'\n"))
-             (setq gm (cdr gm))
-             (insert "\n")))
-         (setq i (1+ i)))))))
-
 (defun eieio-all-generic-functions (&optional class)
   "Return a list of all generic functions.
 Optional CLASS argument returns only those functions that contain
 methods for CLASS."
-  (let ((l nil) tree (cn (if class (symbol-name class) nil)))
+  (let ((l nil))
     (mapatoms
      (lambda (symbol)
-       (setq tree (get symbol 'eieio-method-obarray))
-       (if tree
-          (progn
-            ;; A symbol might be interned for that class in one of
-            ;; these three slots in the method-obarray.
-            (if (or (not class)
-                    (fboundp (intern-soft cn (aref tree 0)))
-                    (fboundp (intern-soft cn (aref tree 1)))
-                    (fboundp (intern-soft cn (aref tree 2))))
-                (setq l (cons symbol l)))))))
+       (let ((tree (get symbol 'eieio-method-hashtable)))
+         (when tree
+           ;; A symbol might be interned for that class in one of
+           ;; these three slots in the method-obarray.
+           (if (or (not class)
+                   (car (gethash class (aref tree 0)))
+                   (car (gethash class (aref tree 1)))
+                   (car (gethash class (aref tree 2))))
+               (setq l (cons symbol l)))))))
     l))
 
 (defun eieio-method-documentation (generic class)
   "Return a list of the specific documentation of GENERIC for CLASS.
 If there is not an explicit method for CLASS in GENERIC, or if that
 function has no documentation, then return nil."
-  (let ((tree (get generic 'eieio-method-obarray))
-       (cn (symbol-name class))
-       before primary after)
-    (if (not tree)
-       nil
+  (let ((tree (get generic 'eieio-method-hashtable)))
+    (when tree
       ;; A symbol might be interned for that class in one of
-      ;; these three slots in the method-obarray.
-      (setq before (intern-soft cn (aref tree 0))
-           primary (intern-soft cn (aref tree 1))
-           after (intern-soft cn (aref tree 2)))
-      (if (not (or (fboundp before)
-                  (fboundp primary)
-                  (fboundp after)))
-         nil
-       (list (if (fboundp before)
-                 (cons (help-function-arglist before)
-                       (documentation before))
-               nil)
-             (if (fboundp primary)
-                 (cons (help-function-arglist primary)
-                       (documentation primary))
-               nil)
-             (if (fboundp after)
-                 (cons (help-function-arglist after)
-                       (documentation after))
-               nil))))))
+      ;; these three slots in the method-hashtable.
+      ;; FIXME: Where do these 0/1/2 come from?  Isn't 0 for :static,
+      ;; 1 for before, and 2 for primary (and 3 for after)?
+      (let ((before  (car (gethash class (aref tree 0))))
+           (primary (car (gethash class (aref tree 1))))
+           (after   (car (gethash class (aref tree 2)))))
+        (if (not (or before primary after))
+            nil
+          (list (if before
+                    (cons (help-function-arglist before)
+                          (documentation before))
+                  nil)
+                (if primary
+                    (cons (help-function-arglist primary)
+                          (documentation primary))
+                  nil)
+                (if after
+                    (cons (help-function-arglist after)
+                          (documentation after))
+                  nil)))))))
 
 (defvar eieio-read-generic nil
   "History of the `eieio-read-generic' prompt.")
 
-(defun eieio-read-generic-p (fn)
-  "Function used in function `eieio-read-generic'.
-This is because `generic-p' is a macro.
-Argument FN is the function to test."
-  (generic-p fn))
-
 (defun eieio-read-generic (prompt &optional historyvar)
   "Read a generic function from the minibuffer with PROMPT.
 Optional argument HISTORYVAR is the variable to use as history."
-  (intern (completing-read prompt obarray 'eieio-read-generic-p
+  (intern (completing-read prompt obarray #'generic-p
                           t nil (or historyvar 'eieio-read-generic))))
 
 ;;; METHOD STATS
@@ -627,21 +554,21 @@ Optional argument HISTORYVAR is the variable to use as 
history."
   ()
   "Menu part in easymenu format used in speedbar while in `eieio' mode.")
 
-(defun eieio-class-speedbar (dir-or-object depth)
+(defun eieio-class-speedbar (_dir-or-object _depth)
   "Create buttons in speedbar that represents the current project.
 DIR-OR-OBJECT is the object to expand, or nil, and DEPTH is the
 current expansion depth."
   (when (eq (point-min) (point-max))
     ;; This function is only called once, to start the whole deal.
     ;; Create and expand the default object.
-    (eieio-class-button eieio-default-superclass 0)
+    (eieio-class-button 'eieio-default-superclass 0)
     (forward-line -1)
     (speedbar-expand-line)))
 
 (defun eieio-class-button (class depth)
   "Draw a speedbar button at the current point for CLASS at DEPTH."
   (eieio--check-type class-p class)
-  (let ((subclasses (eieio--class-children (class-v class))))
+  (let ((subclasses (eieio--class-children (eieio--class-v class))))
     (if subclasses
        (speedbar-make-tag-line 'angle ?+
                                'eieio-sb-expand
@@ -666,7 +593,7 @@ Argument INDENT is the depth of indentation."
         (speedbar-with-writable
           (save-excursion
             (end-of-line) (forward-char 1)
-            (let ((subclasses (eieio--class-children (class-v class))))
+            (let ((subclasses (eieio--class-children (eieio--class-v class))))
               (while subclasses
                 (eieio-class-button (car subclasses) (1+ indent))
                 (setq subclasses (cdr subclasses)))))))
@@ -676,7 +603,7 @@ Argument INDENT is the depth of indentation."
        (t (error "Ooops...  not sure what to do")))
   (speedbar-center-buffer-smartly))
 
-(defun eieio-describe-class-sb (text token indent)
+(defun eieio-describe-class-sb (_text token _indent)
   "Describe the class TEXT in TOKEN.
 INDENT is the current indentation level."
   (dframe-with-attached-buffer
diff --git a/lisp/emacs-lisp/eieio-speedbar.el 
b/lisp/emacs-lisp/eieio-speedbar.el
index cf67625..b236f0f 100644
--- a/lisp/emacs-lisp/eieio-speedbar.el
+++ b/lisp/emacs-lisp/eieio-speedbar.el
@@ -1,4 +1,4 @@
-;;; eieio-speedbar.el -- Classes for managing speedbar displays.
+;;; eieio-speedbar.el -- Classes for managing speedbar displays.  -*- 
lexical-binding:t -*-
 
 ;; Copyright (C) 1999-2002, 2005, 2007-2015 Free Software Foundation,
 ;; Inc.
@@ -200,7 +200,7 @@ that path."
   "Return a string describing OBJECT."
   (eieio-object-name-string object))
 
-(defmethod eieio-speedbar-derive-line-path (object)
+(defmethod eieio-speedbar-derive-line-path (_object)
   "Return the path which OBJECT has something to do with."
   nil)
 
@@ -321,7 +321,7 @@ Argument DEPTH is the depth at which the tag line is 
inserted."
       (if exp
          (eieio-speedbar-expand object (1+ depth))))))
 
-(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) depth)
+(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) _depth)
   "Base method for creating tag lines for non-object children."
   (error "You must implement `eieio-speedbar-child-make-tag-lines' for %s"
         (eieio-object-name object)))
@@ -340,7 +340,7 @@ OBJECT."
 
 ;;; Speedbar specific function callbacks.
 ;;
-(defun eieio-speedbar-object-click (text token indent)
+(defun eieio-speedbar-object-click (_text token _indent)
   "Handle a user click on TEXT representing object TOKEN.
 The object is at indentation level INDENT."
   (eieio-speedbar-handle-click token))
@@ -412,7 +412,7 @@ Optional DEPTH is the depth we start at."
 
 ;;; Methods to the eieio-speedbar-* classes which need to be overridden.
 ;;
-(defmethod eieio-speedbar-object-children ((object eieio-speedbar))
+(defmethod eieio-speedbar-object-children ((_object eieio-speedbar))
   "Return a list of children to be displayed in speedbar.
 If the return value is a list of OBJECTs, then those objects are
 queried for details.  If the return list is made of strings,
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 3610054..419a78b 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -53,17 +53,16 @@
   (message eieio-version))
 
 (require 'eieio-core)
+(require 'eieio-generic)
 
 
 ;;; Defining a new class
 ;;
-(defmacro defclass (name superclass slots &rest options-and-doc)
+(defmacro defclass (name superclasses slots &rest options-and-doc)
   "Define NAME as a new class derived from SUPERCLASS with SLOTS.
 OPTIONS-AND-DOC is used as the class' options and base documentation.
-SUPERCLASS is a list of superclasses to inherit from, with SLOTS
-being the slots residing in that class definition.  NOTE: Currently
-only one slot may exist in SUPERCLASS as multiple inheritance is not
-yet supported.  Supported tags are:
+SUPERCLASSES is a list of superclasses to inherit from, with SLOTS
+being the slots residing in that class definition.  Supported tags are:
 
   :initform   - Initializing form.
   :initarg    - Tag used during initialization.
@@ -114,12 +113,178 @@ Options in CLOS not supported in EIEIO:
 Due to the way class options are set up, you can add any tags you wish,
 and reference them using the function `class-option'."
   (declare (doc-string 4))
-  ;; This is eval-and-compile only to silence spurious compiler warnings
-  ;; about functions and variables not known to be defined.
-  ;; When eieio-defclass code is merged here and this becomes
-  ;; transparent to the compiler, the eval-and-compile can be removed.
-  `(eval-and-compile
-     (eieio-defclass ',name ',superclass ',slots ',options-and-doc)))
+  (eieio--check-type listp superclasses)
+
+  (cond ((and (stringp (car options-and-doc))
+              (/= 1 (% (length options-and-doc) 2)))
+         (error "Too many arguments to `defclass'"))
+        ((and (symbolp (car options-and-doc))
+              (/= 0 (% (length options-and-doc) 2)))
+         (error "Too many arguments to `defclass'")))
+
+  (if (stringp (car options-and-doc))
+      (setq options-and-doc
+            (cons :documentation options-and-doc)))
+
+  ;; Make sure the method invocation order is a valid value.
+  (let ((io (eieio--class-option-assoc options-and-doc
+                                       :method-invocation-order)))
+    (when (and io (not (member io '(:depth-first :breadth-first :c3))))
+      (error "Method invocation order %s is not allowed" io)))
+
+  (let ((testsym1 (intern (concat (symbol-name name) "-p")))
+        (testsym2 (intern (format "eieio--childp--%s" name)))
+        (accessors ()))
+
+    ;; Collect the accessors we need to define.
+    (pcase-dolist (`(,sname . ,soptions) slots)
+      (let* ((acces   (plist-get soptions :accessor))
+            (initarg (plist-get soptions :initarg))
+            (reader  (plist-get soptions :reader))
+            (writer  (plist-get soptions :writer))
+            (alloc   (plist-get soptions :allocation))
+            (label   (plist-get soptions :label)))
+
+       (if eieio-error-unsupported-class-tags
+           (let ((tmp soptions))
+             (while tmp
+               (if (not (member (car tmp) '(:accessor
+                                            :initform
+                                            :initarg
+                                            :documentation
+                                            :protection
+                                            :reader
+                                            :writer
+                                            :allocation
+                                            :type
+                                            :custom
+                                            :label
+                                            :group
+                                            :printer
+                                            :allow-nil-initform
+                                            :custom-groups)))
+                   (signal 'invalid-slot-type (list (car tmp))))
+               (setq tmp (cdr (cdr tmp))))))
+
+       ;; Make sure the :allocation parameter has a valid value.
+       (if (not (memq alloc '(nil :class :instance)))
+           (signal 'invalid-slot-type (list :allocation alloc)))
+
+       ;; Label is nil, or a string
+       (if (not (or (null label) (stringp label)))
+           (signal 'invalid-slot-type (list :label label)))
+
+       ;; Is there an initarg, but allocation of class?
+       (if (and initarg (eq alloc :class))
+           (message "Class allocated slots do not need :initarg"))
+
+       ;; Anyone can have an accessor function.  This creates a function
+       ;; of the specified name, and also performs a `defsetf' if applicable
+       ;; so that users can `setf' the space returned by this function.
+       (when acces
+          ;; FIXME: The defmethod below only defines a part of the generic
+          ;; function (good), but the define-setter below affects the whole
+          ;; generic function (bad)!
+          (push `(gv-define-setter ,acces (store object)
+                   ;; Apparently, eieio-oset-default doesn't work like
+                   ;;  oref-default and only accept class arguments!
+                   (list ',(if nil ;; (eq alloc :class)
+                               'eieio-oset-default
+                             'eieio-oset)
+                         object '',sname store))
+                accessors)
+          (push `(defmethod ,acces ,(if (eq alloc :class) :static :primary)
+                   ((this ,name))
+                   ,(format
+                     "Retrieve the slot `%S' from an object of class `%S'."
+                     sname name)
+                   (if (slot-boundp this ',sname)
+                       ;; Use oref-default for :class allocated slots, since
+                       ;; these also accept the use of a class argument instead
+                       ;; of an object argument.
+                       (,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref)
+                        this ',sname)
+                     ;; Else - Some error?  nil?
+                     nil))
+                accessors))
+
+       ;; If a writer is defined, then create a generic method of that
+       ;; name whose purpose is to set the value of the slot.
+       (if writer
+            (push `(defmethod ,writer ((this ,name) value)
+                     ,(format "Set the slot `%S' of an object of class `%S'."
+                              sname name)
+                     (setf (slot-value this ',sname) value))
+                  accessors))
+       ;; If a reader is defined, then create a generic method
+       ;; of that name whose purpose is to access this slot value.
+       (if reader
+            (push `(defmethod ,reader ((this ,name))
+                     ,(format "Access the slot `%S' from object of class `%S'."
+                              sname name)
+                     (slot-value this ',sname))
+                  accessors))
+       ))
+
+    `(progn
+       ;; This test must be created right away so we can have self-
+       ;; referencing classes.  ei, a class whose slot can contain only
+       ;; pointers to itself.
+
+       ;; Create the test function.
+       (defun ,testsym1 (obj)
+         ,(format "Test OBJ to see if it an object of type %S." name)
+         (and (eieio-object-p obj)
+              (same-class-p obj ',name)))
+
+       (defun ,testsym2 (obj)
+         ,(format
+           "Test OBJ to see if it an object is a child of type %S."
+           name)
+         (and (eieio-object-p obj)
+              (object-of-class-p obj ',name)))
+
+       ,@(when eieio-backward-compatibility
+           (let ((f (intern (format "%s-child-p" name))))
+             `((defalias ',f ',testsym2)
+               (make-obsolete
+                ',f ,(format "use (cl-typep ... '%s) instead" name) "25.1"))))
+
+       ;; When using typep, (typep OBJ 'myclass) returns t for objects which
+       ;; are subclasses of myclass.  For our predicates, however, it is
+       ;; important for EIEIO to be backwards compatible, where
+       ;; myobject-p, and myobject-child-p are different.
+       ;; "cl" uses this technique to specify symbols with specific typep
+       ;; test, so we can let typep have the CLOS documented behavior
+       ;; while keeping our above predicate clean.
+
+       (put ',name 'cl-deftype-satisfies #',testsym2)
+
+       (eieio-defclass-internal ',name ',superclasses ',slots 
',options-and-doc)
+
+       ,@accessors
+
+       ;; Create the constructor function
+       ,(if (eieio--class-option-assoc options-and-doc :abstract)
+            ;; Abstract classes cannot be instantiated.  Say so.
+            (let ((abs (eieio--class-option-assoc options-and-doc :abstract)))
+              (if (not (stringp abs))
+                  (setq abs (format "Class %s is abstract" name)))
+              `(defun ,name (&rest _)
+                 ,(format "You cannot create a new object of type %S." name)
+                 (error ,abs)))
+
+          ;; Non-abstract classes need a constructor.
+          `(defun ,name (&rest slots)
+             ,(format "Create a new object with name NAME of class type %S."
+                      name)
+             (if (and slots
+                      (let ((x (car slots)))
+                        (or (stringp x) (null x))))
+                 (funcall (if eieio-backward-compatibility #'ignore #'message)
+                          "Obsolete name %S passed to %S constructor"
+                          (pop slots) ',name))
+             (apply #'eieio-constructor ',name slots))))))
 
 
 ;;; CLOS style implementation of object creators.
@@ -144,75 +309,16 @@ In EIEIO, the class' constructor requires a name for use 
when printing.
 `make-instance' in CLOS doesn't use names the way Emacs does, so the
 class is used as the name slot instead when INITARGS doesn't start with
 a string."
-  (if (and (car initargs) (stringp (car initargs)))
-      (apply (class-constructor class) initargs)
-    (apply  (class-constructor class)
-           (cond ((symbolp class) (symbol-name class))
-                 (t (format "%S" class)))
-           initargs)))
+  (apply (class-constructor class) initargs))
 
 
-;;; CLOS methods and generics
-;;
-(defmacro defgeneric (method _args &optional doc-string)
-  "Create a generic function METHOD.
-DOC-STRING is the base documentation for this class.  A generic
-function has no body, as its purpose is to decide which method body
-is appropriate to use.  Uses `defmethod' to create methods, and calls
-`defgeneric' for you.  With this implementation the ARGS are
-currently ignored.  You can use `defgeneric' to apply specialized
-top level documentation to a method."
-  (declare (doc-string 3))
-  `(eieio--defalias ',method
-                    (eieio--defgeneric-init-form ',method ,doc-string)))
-
-(defmacro defmethod (method &rest args)
-  "Create a new METHOD through `defgeneric' with ARGS.
-
-The optional second argument KEY is a specifier that
-modifies how the method is called, including:
-   :before  - Method will be called before the :primary
-   :primary - The default if not specified
-   :after   - Method will be called after the :primary
-   :static  - First arg could be an object or class
-The next argument is the ARGLIST.  The ARGLIST specifies the arguments
-to the method as with `defun'.  The first argument can have a type
-specifier, such as:
-  ((VARNAME CLASS) ARG2 ...)
-where VARNAME is the name of the local variable for the method being
-created.  The CLASS is a class symbol for a class made with `defclass'.
-A DOCSTRING comes after the ARGLIST, and is optional.
-All the rest of the args are the BODY of the method.  A method will
-return the value of the last form in the BODY.
-
-Summary:
-
- (defmethod mymethod [:before | :primary | :after | :static]
-                     ((typearg class-name) arg2 &optional opt &rest rest)
-    \"doc-string\"
-     body)"
-  (declare (doc-string 3))
-  (let* ((key (if (keywordp (car args)) (pop args)))
-        (params (car args))
-        (arg1 (car params))
-         (fargs (if (consp arg1)
-                   (cons (car arg1) (cdr params))
-                 params))
-        (class (if (consp arg1) (nth 1 arg1)))
-         (code `(lambda ,fargs ,@(cdr args))))
-    `(progn
-       ;; Make sure there is a generic and the byte-compiler sees it.
-       (defgeneric ,method ,args
-         ,(or (documentation code)
-              (format "Generically created method `%s'." method)))
-       (eieio--defmethod ',method ',key ',class #',code))))
-
 ;;; Get/Set slots in an object.
 ;;
 (defmacro oref (obj slot)
   "Retrieve the value stored in OBJ in the slot named by SLOT.
 Slot is the name of the slot when created by `defclass' or the label
 created by the :initarg tag."
+  (declare (debug (form symbolp)))
   `(eieio-oref ,obj (quote ,slot)))
 
 (defalias 'slot-value 'eieio-oref)
@@ -223,6 +329,7 @@ created by the :initarg tag."
 The default value is the value installed in a class with the :initform
 tag.  SLOT can be the slot name, or the tag specified by the :initarg
 tag in the `defclass' call."
+  (declare (debug (form symbolp)))
   `(eieio-oref-default ,obj (quote ,slot)))
 
 ;;; Handy CLOS macros
@@ -246,7 +353,7 @@ SPEC-LIST is of a form similar to `let'.  For example:
 Where each VAR is the local variable given to the associated
 SLOT.  A slot specified without a variable name is given a
 variable name of the same name as the slot."
-  (declare (indent 2))
+  (declare (indent 2) (debug (sexp sexp def-body)))
   (require 'cl-lib)
   ;; Transform the spec-list into a cl-symbol-macrolet spec-list.
   (let ((mappings (mapcar (lambda (entry)
@@ -261,33 +368,43 @@ variable name of the same name as the slot."
 ;;  well embedded into an object.
 ;;
 (define-obsolete-function-alias
-  'object-class-fast #'eieio--object-class "24.4")
+  'object-class-fast #'eieio--object-class-name "24.4")
 
 (defun eieio-object-name (obj &optional extra)
   "Return a Lisp like symbol string for object OBJ.
 If EXTRA, include that in the string returned to represent the symbol."
   (eieio--check-type eieio-object-p obj)
-  (format "#<%s %s%s>" (symbol-name (eieio--object-class obj))
-         (eieio--object-name obj) (or extra "")))
+  (format "#<%s %s%s>" (eieio--object-class-name obj)
+         (eieio-object-name-string obj) (or extra "")))
 (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4")
 
-(defun eieio-object-name-string (obj) "Return a string which is OBJ's name."
-  (eieio--check-type eieio-object-p obj)
-  (eieio--object-name obj))
+(defconst eieio--object-names (make-hash-table :test #'eq :weakness 'key))
+
+;; In the past, every EIEIO object had a `name' field, so we had the two method
+;; below "for free".  Since this field is very rarely used, we got rid of it
+;; and instead we keep it in a weak hash-tables, for those very rare objects
+;; that use it.
+(defmethod eieio-object-name-string (obj)
+  "Return a string which is OBJ's name."
+  (declare (obsolete eieio-named "25.1"))
+  (or (gethash obj eieio--object-names)
+      (symbol-name (eieio-object-class obj))))
 (define-obsolete-function-alias
   'object-name-string #'eieio-object-name-string "24.4")
 
-(defun eieio-object-set-name-string (obj name)
+(defmethod eieio-object-set-name-string (obj name)
   "Set the string which is OBJ's NAME."
-  (eieio--check-type eieio-object-p obj)
+  (declare (obsolete eieio-named "25.1"))
   (eieio--check-type stringp name)
-  (setf (eieio--object-name obj) name))
+  (setf (gethash obj eieio--object-names) name))
 (define-obsolete-function-alias
   'object-set-name-string 'eieio-object-set-name-string "24.4")
 
-(defun eieio-object-class (obj) "Return the class struct defining OBJ."
+(defun eieio-object-class (obj)
+  "Return the class struct defining OBJ."
+  ;; FIXME: We say we return a "struct" but we return a symbol instead!
   (eieio--check-type eieio-object-p obj)
-  (eieio--object-class obj))
+  (eieio--object-class-name obj))
 (define-obsolete-function-alias 'object-class #'eieio-object-class "24.4")
 ;; CLOS name, maybe?
 (define-obsolete-function-alias 'class-of #'eieio-object-class "24.4")
@@ -295,7 +412,7 @@ If EXTRA, include that in the string returned to represent 
the symbol."
 (defun eieio-object-class-name (obj)
   "Return a Lisp like symbol name for OBJ's class."
   (eieio--check-type eieio-object-p obj)
-  (eieio-class-name (eieio--object-class obj)))
+  (eieio-class-name (eieio--object-class-name obj)))
 (define-obsolete-function-alias
   'object-class-name 'eieio-object-class-name "24.4")
 
@@ -303,15 +420,16 @@ If EXTRA, include that in the string returned to 
represent the symbol."
   "Return parent classes to CLASS.  (overload of variable).
 
 The CLOS function `class-direct-superclasses' is aliased to this function."
-  (eieio--check-type class-p class)
-  (eieio-class-parents-fast class))
+  (let ((c (eieio-class-object class)))
+    (eieio--class-parent c)))
+
 (define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4")
 
 (defun eieio-class-children (class)
   "Return child classes to CLASS.
 The CLOS function `class-direct-subclasses' is aliased to this function."
   (eieio--check-type class-p class)
-  (eieio-class-children-fast class))
+  (eieio--class-children (eieio--class-v class)))
 (define-obsolete-function-alias
   'class-children #'eieio-class-children "24.4")
 
@@ -326,38 +444,44 @@ The CLOS function `class-direct-subclasses' is aliased to 
this function."
   `(car (eieio-class-parents ,class)))
 (define-obsolete-function-alias 'class-parent 'eieio-class-parent "24.4")
 
-(defun same-class-p (obj class) "Return t if OBJ is of class-type CLASS."
-  (eieio--check-type class-p class)
+(defun same-class-p (obj class)
+  "Return t if OBJ is of class-type CLASS."
+  (setq class (eieio--class-object class))
+  (eieio--check-type eieio--class-p class)
   (eieio--check-type eieio-object-p obj)
-  (same-class-fast-p obj class))
+  (eq (eieio--object-class-object obj) class))
 
 (defun object-of-class-p (obj class)
   "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses."
   (eieio--check-type eieio-object-p obj)
   ;; class will be checked one layer down
-  (child-of-class-p (eieio--object-class obj) class))
+  (child-of-class-p (eieio--object-class-object obj) class))
 ;; Backwards compatibility
 (defalias 'obj-of-class-p 'object-of-class-p)
 
 (defun child-of-class-p (child class)
   "Return non-nil if CHILD class is a subclass of CLASS."
-  (eieio--check-type class-p class)
-  (eieio--check-type class-p child)
-  (let ((p nil))
-    (while (and child (not (eq child class)))
-      (setq p (append p (eieio--class-parent (class-v child)))
-           child (car p)
-           p (cdr p)))
-    (if child t)))
+  (setq child (eieio--class-object child))
+  (eieio--check-type eieio--class-p child)
+  ;; `eieio-default-superclass' is never mentioned in eieio--class-parent,
+  ;; so we have to special case it here.
+  (or (eq class 'eieio-default-superclass)
+      (let ((p nil))
+        (setq class (eieio--class-object class))
+        (eieio--check-type eieio--class-p class)
+        (while (and child (not (eq child class)))
+          (setq p (append p (eieio--class-parent child))
+                child (pop p)))
+        (if child t))))
 
 (defun object-slots (obj)
   "Return list of slots available in OBJ."
   (eieio--check-type eieio-object-p obj)
-  (eieio--class-public-a (class-v (eieio--object-class obj))))
+  (eieio--class-public-a (eieio--object-class-object obj)))
 
-(defun class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg."
-  (eieio--check-type class-p class)
-  (let ((ia (eieio--class-initarg-tuples (class-v class)))
+(defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's 
:initarg."
+  (eieio--check-type eieio--class-p class)
+  (let ((ia (eieio--class-initarg-tuples class))
        (f nil))
     (while (and ia (not f))
       (if (eq (cdr (car ia)) slot)
@@ -371,6 +495,7 @@ The CLOS function `class-direct-subclasses' is aliased to 
this function."
   "Set the value in OBJ for slot SLOT to VALUE.
 SLOT is the slot name as specified in `defclass' or the tag created
 with in the :initarg slot.  VALUE can be any Lisp object."
+  (declare (debug (form symbolp form)))
   `(eieio-oset ,obj (quote ,slot) ,value))
 
 (defmacro oset-default (class slot value)
@@ -378,6 +503,7 @@ with in the :initarg slot.  VALUE can be any Lisp object."
 The default value is usually set with the :initform tag during class
 creation.  This allows users to change the default behavior of classes
 after they are created."
+  (declare (debug (form symbolp form)))
   `(eieio-oset-default ,class (quote ,slot) ,value))
 
 ;;; CLOS queries into classes and slots
@@ -402,11 +528,9 @@ OBJECT can be an instance or a class."
 
 (defun slot-exists-p (object-or-class slot)
   "Return non-nil if OBJECT-OR-CLASS has SLOT."
-  (let ((cv (class-v (cond ((eieio-object-p object-or-class)
-                           (eieio-object-class object-or-class))
-                          ((class-p object-or-class)
-                           object-or-class))
-                    )))
+  (let ((cv (cond ((eieio-object-p object-or-class)
+                   (eieio--object-class-object object-or-class))
+                  (t (eieio-class-object object-or-class)))))
     (or (memq slot (eieio--class-public-a cv))
        (memq slot (eieio--class-class-allocation-a cv)))
     ))
@@ -418,7 +542,7 @@ If ERRORP is non-nil, `wrong-argument-type' is signaled."
   (if (not (class-p symbol))
       (if errorp (signal 'wrong-type-argument (list 'class-p symbol))
        nil)
-    (class-v symbol)))
+    (eieio--class-v symbol)))
 
 ;;; Slightly more complex utility functions for objects
 ;;
@@ -496,44 +620,6 @@ If SLOT is unbound, do nothing."
       nil
     (eieio-oset object slot (delete item (eieio-oref object slot)))))
 
-;;;
-;; Method Calling Functions
-
-(defun next-method-p ()
-  "Return non-nil if there is a next method.
-Returns a list of lambda expressions which is the `next-method'
-order."
-  eieio-generic-call-next-method-list)
-
-(defun call-next-method (&rest replacement-args)
-  "Call the superclass method from a subclass method.
-The superclass method is specified in the current method list,
-and is called the next method.
-
-If REPLACEMENT-ARGS is non-nil, then use them instead of
-`eieio-generic-call-arglst'.  The generic arg list are the
-arguments passed in at the top level.
-
-Use `next-method-p' to find out if there is a next method to call."
-  (if (not (eieio--scoped-class))
-      (error "`call-next-method' not called within a class specific method"))
-  (if (and (/= eieio-generic-call-key method-primary)
-          (/= eieio-generic-call-key method-static))
-      (error "Cannot `call-next-method' except in :primary or :static methods")
-    )
-  (let ((newargs (or replacement-args eieio-generic-call-arglst))
-       (next (car eieio-generic-call-next-method-list))
-       )
-    (if (or (not next) (not (car next)))
-       (apply #'no-next-method (car newargs) (cdr newargs))
-      (let* ((eieio-generic-call-next-method-list
-             (cdr eieio-generic-call-next-method-list))
-            (eieio-generic-call-arglst newargs)
-            (fcn (car next))
-            )
-       (eieio--with-scoped-class (cdr next)
-         (apply fcn newargs)) ))))
-
 ;;; Here are some CLOS items that need the CL package
 ;;
 
@@ -556,22 +642,23 @@ Its slots are automatically adopted by classes with no 
specified parents.
 This class is not stored in the `parent' slot of a class vector."
   :abstract t)
 
+(setq eieio-default-superclass (eieio--class-v 'eieio-default-superclass))
+
 (defalias 'standard-class 'eieio-default-superclass)
 
-(defgeneric constructor (class newname &rest slots)
+(defgeneric eieio-constructor (class &rest slots)
   "Default constructor for CLASS `eieio-default-superclass'.")
 
-(defmethod constructor :static
-  ((class eieio-default-superclass) newname &rest slots)
+(define-obsolete-function-alias 'constructor #'eieio-constructor "25.1")
+
+(defmethod eieio-constructor :static
+  ((class eieio-default-superclass) &rest slots)
   "Default constructor for CLASS `eieio-default-superclass'.
-NEWNAME is the name to be given to the constructed object.
 SLOTS are the initialization slots used by `shared-initialize'.
 This static method is called when an object is constructed.
 It allocates the vector used to represent an EIEIO object, and then
 calls `shared-initialize' on that object."
-  (let* ((new-object (copy-sequence (eieio--class-default-object-cache 
(class-v class)))))
-    ;; Update the name for the newly created object.
-    (setf (eieio--object-name new-object) newname)
+  (let* ((new-object (copy-sequence (eieio--class-default-object-cache 
(eieio--class-v class)))))
     ;; Call the initialize method on the new object with the slots
     ;; that were passed down to us.
     (initialize-instance new-object slots)
@@ -585,10 +672,10 @@ Called from the constructor routine.")
 (defmethod shared-initialize ((obj eieio-default-superclass) slots)
   "Set slots of OBJ with SLOTS which is a list of name/value pairs.
 Called from the constructor routine."
-  (eieio--with-scoped-class (eieio--object-class obj)
+  (eieio--with-scoped-class (eieio--object-class-object obj)
     (while slots
-      (let ((rn (eieio-initarg-to-attribute (eieio--object-class obj)
-                                           (car slots))))
+      (let ((rn (eieio--initarg-to-attribute (eieio--object-class-object obj)
+                                             (car slots))))
        (if (not rn)
            (slot-missing obj (car slots) 'oset (car (cdr slots)))
          (eieio-oset obj rn (car (cdr slots)))))
@@ -609,7 +696,7 @@ not taken, then new objects of your class will not have 
their values
 dynamically set from SLOTS."
   ;; First, see if any of our defaults are `lambda', and
   ;; re-evaluate them and apply the value to our slots.
-  (let* ((this-class (class-v (eieio--object-class this)))
+  (let* ((this-class (eieio--object-class-object this))
         (slot (eieio--class-public-a this-class))
         (defaults (eieio--class-public-d this-class)))
     (while slot
@@ -662,34 +749,6 @@ EIEIO can only dispatch on the first argument, so the 
first two are swapped."
   (signal 'unbound-slot (list (eieio-class-name class) (eieio-object-name 
object)
                              slot-name fn)))
 
-(defgeneric no-applicable-method (object method &rest args)
-  "Called if there are no implementations for OBJECT in METHOD.")
-
-(defmethod no-applicable-method ((object eieio-default-superclass)
-                                method &rest _args)
-  "Called if there are no implementations for OBJECT in METHOD.
-OBJECT is the object which has no method implementation.
-ARGS are the arguments that were passed to METHOD.
-
-Implement this for a class to block this signal.  The return
-value becomes the return value of the original method call."
-  (signal 'no-method-definition (list method (eieio-object-name object)))
-  )
-
-(defgeneric no-next-method (object &rest args)
-"Called from `call-next-method' when no additional methods are available.")
-
-(defmethod no-next-method ((object eieio-default-superclass)
-                          &rest args)
-  "Called from `call-next-method' when no additional methods are available.
-OBJECT is othe object being called on `call-next-method'.
-ARGS are the arguments it is called by.
-This method signals `no-next-method' by default.  Override this
-method to not throw an error, and its return value becomes the
-return value of `call-next-method'."
-  (signal 'no-next-method (list (eieio-object-name object) args))
-  )
-
 (defgeneric clone (obj &rest params)
   "Make a copy of OBJ, and then supply PARAMS.
 PARAMS is a parameter list of the same form used by `initialize-instance'.
@@ -699,18 +758,11 @@ first and modify the returned object.")
 
 (defmethod clone ((obj eieio-default-superclass) &rest params)
   "Make a copy of OBJ, and then apply PARAMS."
-  (let ((nobj (copy-sequence obj))
-       (nm (eieio--object-name obj))
-       (passname (and params (stringp (car params))))
-       (num 1))
-    (if params (shared-initialize nobj (if passname (cdr params) params)))
-    (if (not passname)
-       (save-match-data
-         (if (string-match "-\\([0-9]+\\)" nm)
-             (setq num (1+ (string-to-number (match-string 1 nm)))
-                   nm (substring nm 0 (match-beginning 0))))
-         (setf (eieio--object-name nobj) (concat nm "-" (int-to-string num))))
-      (setf (eieio--object-name nobj) (car params)))
+  (let ((nobj (copy-sequence obj)))
+    (if (stringp (car params))
+        (funcall (if eieio-backward-compatibility #'ignore #'message)
+                 "Obsolete name %S passed to clone" (pop params)))
+    (if params (shared-initialize nobj params))
     nobj))
 
 (defgeneric destructor (this &rest params)
@@ -764,7 +816,7 @@ this object."
     (princ comment)
     (princ "\n"))
   (let* ((cl (eieio-object-class this))
-        (cv (class-v cl)))
+        (cv (eieio--class-v cl)))
     ;; Now output readable lisp to recreate this object
     ;; It should look like this:
     ;; (<constructor> <name> <slot> <slot> ... )
@@ -782,7 +834,7 @@ this object."
          (eieio-print-depth (1+ eieio-print-depth)))
       (while publa
        (when (slot-boundp this (car publa))
-         (let ((i (class-slot-initarg cl (car publa)))
+         (let ((i (eieio--class-slot-initarg cv (car publa)))
                (v (eieio-oref this (car publa)))
                )
            (unless (or (not i) (equal v (car publd)))
@@ -848,7 +900,6 @@ of `eq'."
   (error "EIEIO: `change-class' is unimplemented"))
 
 ;; Hook ourselves into help system for describing classes and methods.
-(add-hook 'help-fns-describe-function-functions 'eieio-help-generic)
 (add-hook 'help-fns-describe-function-functions 'eieio-help-constructor)
 
 ;;; Interfacing with edebug
@@ -859,43 +910,23 @@ of `eq'."
 Used as advice around `edebug-prin1-to-string', held in the
 variable PRINT-FUNCTION.  Optional argument NOESCAPE is passed to
 `prin1-to-string' when appropriate."
-  (cond ((class-p object) (eieio-class-name object))
+  (cond ((eieio--class-p object) (eieio-class-name object))
        ((eieio-object-p object) (object-print object))
-       ((and (listp object) (or (class-p (car object))
+       ((and (listp object) (or (eieio--class-p (car object))
                                 (eieio-object-p (car object))))
-        (concat "(" (mapconcat #'eieio-edebug-prin1-to-string object " ")
+        (concat "(" (mapconcat
+                      (lambda (x) (eieio-edebug-prin1-to-string print-function 
x))
+                      object " ")
                  ")"))
        (t (funcall print-function object noescape))))
 
-(add-hook 'edebug-setup-hook
-         (lambda ()
-           (def-edebug-spec defmethod
-             (&define                  ; this means we are defining something
-              [&or name ("setf" :name setf name)]
-              ;; ^^ This is the methods symbol
-              [ &optional symbolp ]    ; this is key :before etc
-              list              ; arguments
-              [ &optional stringp ]    ; documentation string
-              def-body                 ; part to be debugged
-              ))
-           ;; The rest of the macros
-           (def-edebug-spec oref (form quote))
-           (def-edebug-spec oref-default (form quote))
-           (def-edebug-spec oset (form quote form))
-           (def-edebug-spec oset-default (form quote form))
-           (def-edebug-spec class-v form)
-           (def-edebug-spec class-p form)
-           (def-edebug-spec eieio-object-p form)
-           (def-edebug-spec class-constructor form)
-           (def-edebug-spec generic-p form)
-           (def-edebug-spec with-slots (list list def-body))
-           (advice-add 'edebug-prin1-to-string
-                       :around #'eieio-edebug-prin1-to-string)))
+(advice-add 'edebug-prin1-to-string
+            :around #'eieio-edebug-prin1-to-string)
 
 
 ;;; Start of automatically extracted autoloads.
 
-;;;### (autoloads nil "eieio-custom" "eieio-custom.el" 
"62709d76ae43f4fe70ed922391f9c64d")
+;;;### (autoloads nil "eieio-custom" "eieio-custom.el" 
"9a908efef1720439feb6323c1dd01770")
 ;;; Generated autoloads from eieio-custom.el
 
 (autoload 'customize-object "eieio-custom" "\
@@ -906,7 +937,7 @@ Optional argument GROUP is the sub-group of slots to 
display.
 
 ;;;***
 
-;;;### (autoloads nil "eieio-opt" "eieio-opt.el" 
"76058d02377b677eed3d15c28fc7ab21")
+;;;### (autoloads nil "eieio-opt" "eieio-opt.el" 
"e922bf7ebc7dcb272480c4ba148da1ac")
 ;;; Generated autoloads from eieio-opt.el
 
 (autoload 'eieio-browse "eieio-opt" "\
@@ -927,11 +958,6 @@ Describe CTR if it is a class constructor.
 
 \(fn CTR)" nil nil)
 
-(autoload 'eieio-help-generic "eieio-opt" "\
-Describe GENERIC if it is a generic function.
-
-\(fn GENERIC)" nil nil)
-
 ;;;***
 
 ;;; End of automatically extracted autoloads.
diff --git a/lisp/files.el b/lisp/files.el
index 80b538c..1533c35 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -729,38 +729,6 @@ The path separator is colon in GNU and GNU-like systems."
                     (lambda (f) (and (file-directory-p f) 'dir-ok)))
        (error "No such directory found via CDPATH environment variable"))))
 
-(defun file-tree-walk (dir action &rest args)
-  "Walk DIR executing ACTION on each file, with ARGS as additional arguments.
-For each file, the function calls ACTION as follows:
-
-   \(ACTION DIRECTORY BASENAME ARGS\)
-
-Where DIRECTORY is the leading directory of the file,
-      BASENAME is the basename of the file,
-      and ARGS are as specified in the call to this function, or nil if 
omitted.
-
-The ACTION is applied to each subdirectory before descending into
-it, and if nil is returned at that point, the descent will be
-prevented.  Directory entries are sorted with string-lessp."
-  (cond ((file-directory-p dir)
-        (setq dir (file-name-as-directory dir))
-        (let ((lst (directory-files dir nil nil t))
-              fullname file)
-          (while lst
-            (setq file (car lst))
-            (setq lst (cdr lst))
-            (cond ((member file '("." "..")))
-                  (t
-                   (and (apply action dir file args)
-                        (setq fullname (concat dir file))
-                        (file-directory-p fullname)
-                        (apply 'file-tree-walk fullname action args)))))))
-       (t
-        (apply action
-               (file-name-directory dir)
-               (file-name-nondirectory dir)
-               args))))
-
 (defsubst directory-name-p (name)
   "Return non-nil if NAME ends with a slash character."
   (and (> (length name) 0)
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 73a0de7..20de9ae 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,7 @@
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * registry.el: Don't use <class> as a variable.
+
 2014-12-29  Paul Eggert  <address@hidden>
 
        * message.el (message-make-fqdn):
@@ -10,6 +14,12 @@
        * mm-decode.el (mm-shr): Bind `shr-width' to `fill-column' so that
        lines don't get overlong when responding.
 
+2014-12-19  Andreas Schwab  <address@hidden>
+
+       * gnus-group.el (gnus-read-ephemeral-bug-group):
+       Bind coding-system-for-read and coding-system-for-write only around
+       with-temp-file, and make buffer unibyte.  Don't write temp file twice.
+
 2014-12-18  Paul Eggert  <address@hidden>
 
        * registry.el (registry-db): Set default slot later.
@@ -67,9 +77,9 @@
 
 2014-12-09  Lars Magne Ingebrigtsen  <address@hidden>
 
-       * gnus-art.el (gnus-article-mime-handles): Refactored out into own
+       * gnus-art.el (gnus-article-mime-handles): Refactor out into own
        function for reuse.
-       (gnus-mime-buttonize-attachments-in-header): Adjusted.
+       (gnus-mime-buttonize-attachments-in-header): Adjust.
 
 2014-12-07  Lars Magne Ingebrigtsen  <address@hidden>
 
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 29c380f..f3dcc40 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -2455,27 +2455,27 @@ the bug number, and browsing the URL must return mbox 
output."
     (setq ids (string-to-number ids)))
   (unless (listp ids)
     (setq ids (list ids)))
-  (let ((tmpfile (mm-make-temp-file "gnus-temp-group-"))
-       (coding-system-for-write 'binary)
-       (coding-system-for-read 'binary))
-    (with-temp-file tmpfile
-      (dolist (id ids)
-       (url-insert-file-contents (format mbox-url id)))
-      (goto-char (point-min))
-      ;; Add the debbugs address so that we can respond to reports easily.
-      (while (re-search-forward "^To: " nil t)
-       (end-of-line)
-       (insert (format ", address@hidden" (car ids)
-                       (gnus-replace-in-string
-                        (gnus-replace-in-string mbox-url "^http://"; "")
-                        "/.*$" ""))))
-      (write-region (point-min) (point-max) tmpfile)
-      (gnus-group-read-ephemeral-group
-       (format "nndoc+ephemeral:bug#%s"
-              (mapconcat 'number-to-string ids ","))
-       `(nndoc ,tmpfile
-              (nndoc-article-type mbox))
-       nil window-conf))
+  (let ((tmpfile (mm-make-temp-file "gnus-temp-group-")))
+    (let ((coding-system-for-write 'binary)
+         (coding-system-for-read 'binary))
+      (with-temp-file tmpfile
+       (mm-disable-multibyte)
+       (dolist (id ids)
+         (url-insert-file-contents (format mbox-url id)))
+       (goto-char (point-min))
+       ;; Add the debbugs address so that we can respond to reports easily.
+       (while (re-search-forward "^To: " nil t)
+         (end-of-line)
+         (insert (format ", address@hidden" (car ids)
+                         (gnus-replace-in-string
+                          (gnus-replace-in-string mbox-url "^http://"; "")
+                          "/.*$" ""))))))
+    (gnus-group-read-ephemeral-group
+     (format "nndoc+ephemeral:bug#%s"
+            (mapconcat 'number-to-string ids ","))
+     `(nndoc ,tmpfile
+            (nndoc-article-type mbox))
+     nil window-conf)
     (delete-file tmpfile)))
 
 (defun gnus-read-ephemeral-debian-bug-group (number)
diff --git a/lisp/gnus/registry.el b/lisp/gnus/registry.el
index b3a2abf..55b83a8 100644
--- a/lisp/gnus/registry.el
+++ b/lisp/gnus/registry.el
@@ -124,7 +124,7 @@
          :type hash-table
          :documentation "The data hashtable.")))
 ;; Do this separately, since defclass doesn't allow expressions in :initform.
-(oset-default registry-db max-size most-positive-fixnum)
+(oset-default 'registry-db max-size most-positive-fixnum)
 
 (defmethod initialize-instance :BEFORE ((this registry-db) slots)
   "Check whether a registry object needs to be upgraded."
diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el
index 9eb091f..429c14b 100644
--- a/lisp/international/ccl.el
+++ b/lisp/international/ccl.el
@@ -1355,6 +1355,14 @@ IF :=    (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1)
 BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...])
 
 ;; Execute STATEMENTs until (break) or (end) is executed.
+
+;; Create a block of STATEMENTs for repeating.  The STATEMENTs
+;; are executed sequentially until REPEAT or BREAK is executed.
+;; If REPEAT statement is executed, STATEMENTs are executed from the
+;; start again.  If BREAK statements is executed, the execution
+;; exits from the block.  If neither REPEAT nor BREAK is
+;; executed, the execution exits from the block after executing the
+;; last STATEMENT.
 LOOP := (loop STATEMENT [STATEMENT ...])
 
 ;; Terminate the most inner loop.
@@ -1501,17 +1509,42 @@ ARRAY := `[' integer ... `]'
 
 
 TRANSLATE :=
-       (translate-character REG(table) REG(charset) REG(codepoint))
-       | (translate-character SYMBOL REG(charset) REG(codepoint))
-        ;; SYMBOL must refer to a table defined by `define-translation-table'.
+       ;; Decode character SRC, translate it by translate table
+       ;; TABLE, and encode it back to DST.  TABLE is specified
+       ;; by its id number in REG_0, SRC is specified by its
+       ;; charset id number and codepoint in REG_1 and REG_2
+       ;; respectively.
+       ;; On encoding, the charset of highest priority is selected.
+       ;; After the execution, DST is specified by its charset
+       ;; id number and codepoint in REG_1 and REG_2 respectively.
+       (translate-character REG_0 REG_1 REG_2)
+
+       ;; Same as above except for SYMBOL specifying the name of
+       ;; the translate table defined by `define-translation-table'.
+       | (translate-character SYMBOL REG_1 REG_2)
+
 LOOKUP :=
-       (lookup-character SYMBOL REG(charset) REG(codepoint))
+       ;; Look up character SRC in hash table TABLE.  TABLE is
+       ;; specified by its name in SYMBOL, and SRC is specified by
+       ;; its charset id number and codepoint in REG_1 and REG_2
+       ;; respectively.
+       ;; If its associated value is an integer, set REG_1 to that
+       ;; value, and set r7 to 1.  Otherwise, set r7 to 0.
+       (lookup-character SYMBOL REG_1 REG_2)
+
+       ;; Look up integer value N in hash table TABLE.  TABLE is
+       ;; specified by its name in SYMBOL and N is specified in
+       ;; REG.
+       ;; If its associated value is a character, set REG to that
+       ;; value, and set r7 to 1.  Otherwise, set r7 to 0.
        | (lookup-integer SYMBOL REG(integer))
-        ;; SYMBOL refers to a table defined by `define-translation-hash-table'.
+
 MAP :=
-     (iterate-multiple-map REG REG MAP-IDs)
-     | (map-multiple REG REG (MAP-SET))
-     | (map-single REG REG MAP-ID)
+       ;; The following statements are for internal use only.
+       (iterate-multiple-map REG REG MAP-IDs)
+       | (map-multiple REG REG (MAP-SET))
+       | (map-single REG REG MAP-ID)
+
 MAP-IDs := MAP-ID ...
 MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
 MAP-ID := integer
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 1631244..538bd97 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -826,16 +826,27 @@ styles for specific categories, such as files, buffers, 
etc."
   :type completion--styles-type
   :version "23.1")
 
-(defcustom completion-category-overrides
-  '((buffer (styles . (basic substring))))
-  "List of `completion-styles' overrides for specific categories.
+(defvar completion-category-defaults
+  '((buffer (styles . (basic substring)))
+    (unicode-name (styles . (basic substring))))
+  "Default settings for specific completion categories.
+Each entry has the shape (CATEGORY . ALIST) where ALIST is
+an association list that can specify properties such as:
+- `styles': the list of `completion-styles' to use for that category.
+- `cycle': the `completion-cycle-threshold' to use for that category.
+Categories are symbols such as `buffer' and `file', used when
+completing buffer and file names, respectively.")
+
+(defcustom completion-category-overrides nil
+  "List of category-specific user overrides for completion styles.
 Each override has the shape (CATEGORY . ALIST) where ALIST is
 an association list that can specify properties such as:
 - `styles': the list of `completion-styles' to use for that category.
 - `cycle': the `completion-cycle-threshold' to use for that category.
 Categories are symbols such as `buffer' and `file', used when
-completing buffer and file names, respectively."
-  :version "24.1"
+completing buffer and file names, respectively.
+This overrides the defaults specified in `completion-category-defaults'."
+  :version "25.1"
   :type `(alist :key-type (choice :tag "Category"
                                  (const buffer)
                                   (const file)
@@ -851,9 +862,13 @@ completing buffer and file names, respectively."
                 (const :tag "Select one value from the menu." cycle)
                  ,completion--cycling-threshold-type))))
 
+(defun completion--category-override (category tag)
+  (or (assq tag (cdr (assq category completion-category-overrides)))
+      (assq tag (cdr (assq category completion-category-defaults)))))
+
 (defun completion--styles (metadata)
   (let* ((cat (completion-metadata-get metadata 'category))
-         (over (assq 'styles (cdr (assq cat completion-category-overrides)))))
+         (over (completion--category-override cat 'styles)))
     (if over
         (delete-dups (append (cdr over) (copy-sequence completion-styles)))
        completion-styles)))
@@ -967,7 +982,7 @@ completion candidates than this number."
 
 (defun completion--cycle-threshold (metadata)
   (let* ((cat (completion-metadata-get metadata 'category))
-         (over (assq 'cycle (cdr (assq cat completion-category-overrides)))))
+         (over (completion--category-override cat 'cycle)))
     (if over (cdr over) completion-cycle-threshold)))
 
 (defvar-local completion-all-sorted-completions nil)
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 2ce95d9..6a6da17 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -255,14 +255,18 @@ word(s) will be searched for via `eww-search-prefix'."
         ((string-match-p "\\`ftp://"; url)
          (user-error "FTP is not supported."))
         (t
-         (if (and (= (length (split-string url)) 1)
-                 (or (and (not (string-match-p "\\`[\"\'].*[\"\']\\'" url))
-                          (> (length (split-string url "[.:]")) 1))
-                     (string-match eww-local-regex url)))
+         (if (or (string-match "\\`https?:" url)
+                ;; Also try to match "naked" URLs like
+                ;; en.wikipedia.org/wiki/Free software
+                (string-match "\\`[A-Za-z_]+\\.[A-Za-z._]+/" url)
+                (and (= (length (split-string url)) 1)
+                     (or (and (not (string-match-p "\\`[\"\'].*[\"\']\\'" url))
+                              (> (length (split-string url "[.:]")) 1))
+                         (string-match eww-local-regex url))))
              (progn
                (unless (string-match-p "\\`[a-zA-Z][-a-zA-Z0-9+.]*://" url)
                  (setq url (concat "http://"; url)))
-               ;; some site don't redirect final /
+               ;; Some sites do not redirect final /
                (when (string= (url-filename (url-generic-parse-url url)) "")
                  (setq url (concat url "/"))))
            (setq url (concat eww-search-prefix
@@ -273,6 +277,7 @@ word(s) will be searched for via `eww-search-prefix'."
        (eww-save-history))
     (eww-setup-buffer)
     (plist-put eww-data :url url)
+    (plist-put eww-data :title "")
     (eww-update-header-line-format)
     (let ((inhibit-read-only t))
       (insert (format "Loading %s..." url))
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index ed824cf..feb934c 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -894,7 +894,12 @@ START, and END.  Note that START and END should be 
markers."
   (add-text-properties
    start (point)
    (list 'shr-url url
-        'help-echo (if title (shr-fold-text (format "%s (%s)" url title)) url)
+        'help-echo (let ((iri (or (ignore-errors
+                                    (decode-coding-string
+                                     (url-unhex-string url)
+                                     'utf-8 t))
+                                  url)))
+                     (if title (format "%s (%s)" iri title) iri))
         'follow-link t
         'mouse-face 'highlight
         'keymap shr-map)))
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index de6a339..c25e52c 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -248,7 +248,7 @@ name as matched contains
 
 (defconst js--function-heading-1-re
   (concat
-   "^\\s-*function\\s-+\\(" js--name-re "\\)")
+   "^\\s-*function\\(?:\\s-\\|\\*\\)+\\(" js--name-re "\\)")
   "Regexp matching the start of a JavaScript function header.
 Match group 1 is the name of the function.")
 
@@ -796,6 +796,9 @@ determined.  Otherwise, return nil."
   (let ((name t))
     (forward-word)
     (forward-comment most-positive-fixnum)
+    (when (eq (char-after) ?*)
+      (forward-char)
+      (forward-comment most-positive-fixnum))
     (when (looking-at js--name-re)
       (setq name (match-string-no-properties 0))
       (goto-char (match-end 0)))
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 41b70c7..b822619 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -434,7 +434,8 @@ GROUP is a string for decoration purposes and XREF is an
                        (list 'xref-location location
                              'face 'font-lock-keyword-face
                              'mouse-face 'highlight
-                             'keymap xref--button-map)
+                             'keymap xref--button-map
+                             'help-echo "mouse-2: display, RET or mouse-1: 
navigate")
                        description))
                     (when (or more1 more2)
                       (insert "\n")))))
diff --git a/lisp/shell.el b/lisp/shell.el
index 6e336eb..f71d140 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -309,13 +309,6 @@ for Shell mode only."
                 (const :tag "on" t))
   :group 'shell)
 
-(defcustom shell-display-buffer-actions display-buffer-base-action
-  "The `display-buffer' actions for the `*shell*' buffer."
-  :type display-buffer--action-custom-type
-  :risky t
-  :version "25.1"
-  :group 'shell)
-
 (defvar shell-dirstack nil
   "List of directories saved by pushd in this buffer's shell.
 Thus, this does not include the shell's current directory.")
@@ -726,7 +719,7 @@ Otherwise, one argument `-i' is passed to the shell.
 
   ;; The buffer's window must be correctly set when we call comint (so
   ;; that comint sets the COLUMNS env var properly).
-  (pop-to-buffer buffer shell-display-buffer-actions)
+  (pop-to-buffer buffer)
   (unless (comint-check-proc buffer)
     (let* ((prog (or explicit-shell-file-name
                     (getenv "ESHELL") shell-file-name))
diff --git a/lisp/simple.el b/lisp/simple.el
index e15291a..25293ed 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5604,14 +5604,22 @@ If NOERROR, don't signal an error if we can't move that 
many lines."
                (>  (cdr temporary-goal-column) 0))
            (setq target-hscroll (cdr temporary-goal-column)))
       ;; Otherwise, we should reset `temporary-goal-column'.
-      (let ((posn (posn-at-point)))
+      (let ((posn (posn-at-point))
+           x-pos)
        (cond
         ;; Handle the `overflow-newline-into-fringe' case:
         ((eq (nth 1 posn) 'right-fringe)
          (setq temporary-goal-column (cons (- (window-width) 1) hscroll)))
         ((car (posn-x-y posn))
+         (setq x-pos (car (posn-x-y posn)))
+         ;; In R2L lines, the X pixel coordinate is measured from the
+         ;; left edge of the window, but columns are still counted
+         ;; from the logical-order beginning of the line, i.e. from
+         ;; the right edge in this case.  We need to adjust for that.
+         (if (eq (current-bidi-paragraph-direction) 'right-to-left)
+             (setq x-pos (- (window-body-width nil t) 1 x-pos)))
          (setq temporary-goal-column
-               (cons (/ (float (car (posn-x-y posn)))
+               (cons (/ (float x-pos)
                         (frame-char-width))
                       hscroll))))))
     (if target-hscroll
diff --git a/lisp/subr.el b/lisp/subr.el
index 8237a5b..0534585 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1312,6 +1312,7 @@ is converted into a string by expressing it in decimal."
 (make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register 
"23.1")
 (make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1")
 (make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1")
+(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
 (make-obsolete 'window-redisplay-end-trigger nil "23.1")
 (make-obsolete 'set-window-redisplay-end-trigger nil "23.1")
 
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 3b1f6c7..7801f4f 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -886,7 +886,7 @@ current, and kill the buffer that visits the link."
     (define-key map "=" 'vc-diff)
     (define-key map "D" 'vc-root-diff)
     (define-key map "~" 'vc-revision-other-window)
-    (define-key map "[delete]" 'vc-delete-file)
+    (define-key map "x" 'vc-delete-file)
     map))
 (fset 'vc-prefix-map vc-prefix-map)
 (define-key ctl-x-map "v" 'vc-prefix-map)
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 4217338..e0c4bde 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 43
+# stdio_h.m4 serial 44
 dnl Copyright (C) 2007-2015 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,6 +12,24 @@ AC_DEFUN([gl_STDIO_H],
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
   gl_NEXT_HEADERS([stdio.h])
 
+  dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and
+  dnl inttypes.h behave like gnu instead of system; we must give our
+  dnl printf wrapper the right attribute to match.
+  AC_CACHE_CHECK([whether inttypes macros match system or gnu printf],
+    [gl_cv_func_printf_attribute_flavor],
+    [AC_EGREP_CPP([findme .(ll|j)d. findme],
+      [#define __STDC_FORMAT_MACROS 1
+       #include <stdio.h>
+       #include <inttypes.h>
+       findme PRIdMAX findme
+      ], [gl_cv_func_printf_attribute_flavor=gnu],
+      [gl_cv_func_printf_attribute_flavor=system])])
+  if test "$gl_cv_func_printf_attribute_flavor" = gnu; then
+    AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1],
+      [Define to 1 if printf and friends should be labeled with
+       attribute "__gnu_printf__" instead of "__printf__"])
+  fi
+
   dnl No need to create extra modules for these functions. Everyone who uses
   dnl <stdio.h> likely needs them.
   GNULIB_FSCANF=1
diff --git a/src/.gdbinit b/src/.gdbinit
index 0f21382..1a2a973 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -70,6 +70,16 @@ define xgettype
   set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 
: (EMACS_UINT) $bugfix >> VALBITS)
 end
 
+# Access the name of a symbol
+define xsymname
+  if (CHECK_LISP_OBJECT_TYPE)
+    set $bugfix = $arg0.i
+  else
+    set $bugfix = $arg0
+  end
+  set $symname = ((struct Lisp_Symbol *) ((char *)lispsym + $bugfix))->name
+end
+
 # Set up something to print out s-expressions.
 # We save and restore print_output_debug_flag to prevent the w32 port
 # from calling OutputDebugString, which causes GDB to display each
@@ -1073,8 +1083,8 @@ end
 
 define xprintsym
   xgetptr $arg0
-  set $sym = (struct Lisp_Symbol *) $ptr
-  xgetptr $sym->name
+  xsymname $ptr
+  xgetptr $symname
   set $sym_name = (struct Lisp_String *) $ptr
   xprintstr $sym_name
 end
@@ -1258,8 +1268,8 @@ tbreak init_sys_modes
 commands
   silent
   xgetptr globals.f_Vinitial_window_system
-  set $tem = (struct Lisp_Symbol *) $ptr
-  xgetptr $tem->name
+  xsymname $ptr
+  xgetptr $symname
   set $tem = (struct Lisp_String *) $ptr
   set $tem = (char *) $tem->data
   # If we are running in synchronous mode, we want a chance to look
diff --git a/src/ChangeLog b/src/ChangeLog
index 8cf2696..8f441be 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,246 @@
+2015-01-11  Paul Eggert  <address@hidden>
+
+       Port to MSB hosts without optimization
+       E.g., when configuring --with-wide-int CFLAGS='-O0' on x86,
+       the inline function XTYPE needs to be declared before being used.
+       * lisp.h (XTYPE): New forward declaration.
+
+2015-01-10  Paul Eggert  <address@hidden>
+
+       Port to 32-bit --with-wide-int
+       Prefer symbol indexes to struct Lisp_Symbol * casted and then
+       widened, as the latter had trouble with GCC on Fedora 21 when
+       configured --with-wide-int and when used in static initializers.
+       * alloc.c (garbage_collect_1, which_symbols):
+       * lread.c (init_obarray):
+       Prefer builtin_lisp_symbol when it can be used.
+       * dispextern.h (struct image_type.type):
+       * font.c (font_property_table.key):
+       * frame.c (struct frame_parm_table.sym):
+       * keyboard.c (scroll_bar_parts, struct event_head):
+       * xdisp.c (struct props.name):
+       Use the index of a builtin symbol rather than its address.
+       All uses changed.
+       * lisp.h (TAG_SYMPTR, XSYMBOL_INIT): Remove, replacing with ...
+       (TAG_SYMOFFSET, SYMBOL_INDEX): ... new macros that deal with
+       symbol indexes rather than pointers, and which work better on MSB
+       hosts because they shift right before tagging.  All uses changed.
+       (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END):
+       No longer noops on wide-int hosts, since they work now.
+       (builtin_lisp_symbol): New function.
+
+       Port to HAVE_FREETYPE && !HAVE_XFT
+       * dispextern.h (struct face.extra) [HAVE_FREETYPE && !HAVE_XFT]:
+       * font.h (syms_of_xftfont) [HAVE_FREETYPE && !HAVE_XFT]:
+       Declare in this case too.
+
+2015-01-10  Eli Zaretskii  <address@hidden>
+
+       * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI.
+
+       * w32notify.c (Fw32notify_add_watch, w32_get_watch_object): Use
+       make_pointer_integer instead of XIL.
+       (Fw32notify_rm_watch): Use XINTPTR instead of XLI.
+
+       * w32inevt.c (handle_file_notifications): Use make_pointer_integer
+       instead of XIL.  Put a list of the descriptor, action, and file
+       name in event->arg, instead of spreading them between event->code
+       and event->arg.
+
+       * w32term.c (queue_notifications): Use make_pointer_integer
+       instead of XIL.  Put a list of the descriptor, action, and file
+       name in event->arg, instead of spreading them between event->code
+       and event->arg.
+
+       * keyboard.c (kbd_buffer_get_event) [HAVE_W32NOTIFY]: Adjust Lisp
+       event creation to changes in w32term.c and w32inevt.c above.
+
+2015-01-09  Paul Eggert  <address@hidden>
+
+       Port Qnil==0 changes to 32-bit --with-wide-int
+       * lisp.h (lisp_h_XSYMBOL, XSYMBOL): Assume USE_LSB_TAG in the
+       macro-implemented version.  For the non-USE_LSB_TAG case, supply
+       a new inline function that is the inverse of the new TAG_SYMPTR.
+       (lisp_h_XUNTAGBASE, XUNTAGBASE): Remove.  All uses removed.
+       (TAG_SYMPTR) [!USE_LSB_TAG]: If the pointer subtraction yields a
+       negative number, don't allow sign bits to bleed into the encoded
+       value.  Shift in zero bits instead.
+
+       Refactor pointer-to-integer conversion
+       * gfilenotify.c (monitor_to_lisp, lisp_to_monitor):
+       Rename and move to lisp.h.  All uses changed.
+       * lisp.h (XINTPTR, make_pointer_integer): New inline functions,
+       which are renamed from gfilenotify.c's lisp_to_monitor and
+       monitor_to_lisp, and with more-generic void * signatures.
+
+2015-01-08  Eli Zaretskii  <address@hidden>
+
+       * dispnew.c (buffer_posn_from_coords): Fix the value of the column
+       returned for right-to-left screen lines.  (Before the change on
+       2014-12-30, the incorrectly-computed X pixel coordinate concealed
+       this bug.)
+
+       * .gdbinit (xsymname): New subroutine.
+       (xprintsym, initial-tbreak): Use it to access the name of a symbol
+       in a way that doesn't cause GDB to barf when it tries to
+       dereference a NULL pointer.
+
+       * xdisp.c (next_element_from_c_string): Use Lisp integer zero as
+       the object.
+       (set_cursor_from_row, try_cursor_movement, dump_glyph)
+       (insert_left_trunc_glyphs, append_space_for_newline)
+       (extend_face_to_end_of_line, highlight_trailing_whitespace)
+       (find_row_edges, ROW_GLYPH_NEWLINE_P, Fmove_point_visually)
+       (Fbidi_resolved_levels, produce_special_glyphs)
+       (rows_from_pos_range, mouse_face_from_buffer_pos)
+       (note_mouse_highlight): Use nil as the object for glyphs inserted
+       by the display engine, and test with NILP instead of INTEGERP.
+       (Bug#19535)
+
+       * w32fns.c (Fx_show_tip): Use NILP to test for glyphs inserted by
+       the display engine.
+
+       * xfns.c (Fx_show_tip): Use NILP to test for glyphs inserted by
+       the display engine.
+
+       * dispextern.h (struct glyph, struct it): Update comments for the
+       OBJECT members.
+
+2015-01-08  Paul Eggert  <address@hidden>
+
+       Port new Lisp symbol init to x86 --with-wide-int
+       * lisp.h (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END):
+       Define to empty on platforms where EMACS_INT_MAX != INTPTR_MAX, as
+       GCC (at least) does not allow a constant initializer to widen an
+       address constant.
+
+       * lisp.h (TAG_SYMPTR): Don't do arithmetic on NULL.
+       This is a followup to the "Port Qnil==0 XUNTAG to clang" patch.
+       Although clang doesn't need it, some other compiler might, and
+       it's easy enough to be safe.
+
+       * conf_post.h (ATTRIBUTE_ALLOC_SIZE): Port to clang 3.5.0.
+       Apparently clang removed support for the alloc_size attribute.
+
+       Port Qnil==0 XUNTAG to clang
+       clang has undefined behavior if the program subtracts an integer
+       from (char *) 0.  Problem reported by YAMAMOTO Mitsuharu in:
+       http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00132.html
+       * lisp.h (lisp_h_XUNTAG) [USE_LSB_TAG]:
+       (XUNTAG) [!USE_LSB_TAG]: Port to clang 3.5.0.
+
+       Port GFileMonitor * hack to Qnil==0 platforms
+       Reported by Glenn Morris in: http://bugs.gnu.org/15880#112
+       * gfilenotify.c (monitor_to_lisp, lisp_to_monitor): New functions.
+       (dir_monitor_callback, Fgfile_add_watch, Fgfile_rm_watch): Use them.
+
+2015-01-06  Jan Djärv  <address@hidden>
+
+       * nsterm.m (x_set_window_size): Call updateFrameSize to get real
+       size instead of using widht/height.  The frame may be constrained.
+
+2015-01-05  Paul Eggert  <address@hidden>
+
+       * lisp.h (XSYMBOL): Parenthesize id in forward decl.
+       Needed when neither optimizing nor inlining.
+       Also, sort decls alphabetically.
+
+2015-01-05  Eli Zaretskii  <address@hidden>
+
+       * w32proc.c, w32.h, w32fns.c, w32font.c, w32menu.c, w32notify.c:
+       * w32proc.c, w32select.c, w32term.c, w32uniscribe.c: Remove
+       declarations of Q* variables that represent symbols.
+
+2015-01-05  Paul Eggert  <address@hidden>
+
+       Use 0 for Qnil
+       Fixes Bug#15880.
+       If USE_LSB_TAG, arrange for the representation of Qnil to be zero so
+       that NILP (x) is equivalent to testing whether x is 0 at the
+       machine level.  The overall effects of this and the previous patch
+       shrink the size of the text segment by 2.3% and speeds up
+       compilation of all the .elc files by about 0.5% on my platform,
+       which is Fedora 20 x86-64.
+       * lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
+       (make_lisp_symbol) [USE_LSB_TAG]:
+       Symbols now tag the difference from lispsym, not the pointer.
+       (lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros.
+       (Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons):
+       Renumber so that Lisp_Symbol is 0, so that Qnil is zero.
+       (XSYMBOL): New forward decl.
+       (XUNTAGBASE): New function.
+       (XUNTAG): Use it.
+
+       Compute C decls for DEFSYMs automatically
+       Fixes Bug#15880.
+       This patch also makes Q constants (e.g., Qnil) constant addresses
+       from the C point of view.
+       * alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle.c:
+       * casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c:
+       * composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c:
+       * doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c:
+       * frame.c, fringe.c, ftfont.c, ftxfont.c, gfilenotify.c, gnutls.c:
+       * image.c, inotify.c, insdel.c, keyboard.c, keymap.c, lread.c:
+       * macfont.m, macros.c, minibuf.c, nsfns.m, nsfont.m, nsimage.m:
+       * nsmenu.m, nsselect.m, nsterm.m, print.c, process.c, profiler.c:
+       * search.c, sound.c, syntax.c, term.c, terminal.c, textprop.c, undo.c:
+       * window.c, xdisp.c, xfaces.c, xfns.c, xftfont.c, xmenu.c, xml.c:
+       * xselect.c, xsettings.c, xterm.c:
+       Remove Q vars that represent symbols (e.g., Qnil, Qt, Qemacs).
+       These names are now defined automatically by make-docfile.
+       * alloc.c (init_symbol): New function.
+       (Fmake_symbol): Use it.
+       (c_symbol_p): New function.
+       (valid_lisp_object_p, purecopy): Use it.
+       * alloc.c (marked_pinned_symbols):
+       Use make_lisp_symbol instead of make_lisp_ptr.
+       (garbage_collect_1): Mark lispsym symbols.
+       (CHECK_ALLOCATED_AND_LIVE_SYMBOL): New macro.
+       (mark_object): Use it.
+       (sweep_symbols): Sweep lispsym symbols.
+       (symbol_uses_obj): New function.
+       (which_symbols): Use it.  Work for lispsym symbols, too.
+       (init_alloc_once): Initialize Vpurify_flag here; no need to wait,
+       since Qt's address is already known now.
+       (syms_of_alloc): Add lispsym count to symbols_consed.
+       * buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0),
+       when testing whether storage is all bits zero.
+       * dispextern.h (struct image_type):
+       * font.c (font_property_table):
+       * frame.c (struct frame_parm_table, frame_parms):
+       * keyboard.c (scroll_bar_parts, struct event_head):
+       * xdisp.c (struct props):
+       Use XSYMBOL_INIT (Qfoo) and struct Lisp_Symbol * rather than &Qfoo and
+       Lisp_Object *, since Qfoo is no longer an object whose address can be
+       taken.  All uses changed.
+       * eval.c (run_hook): New function.  Most uses of Frun_hooks changed to
+       use it, so that they no longer need to take the address of a Lisp sym.
+       (syms_of_eval): Don't use DEFSYM on Vrun_hooks, as it's a variable.
+       * frame.c (syms_of_frame): Add defsyms for the frame_parms table.
+       * keyboard.c (syms_of_keyboard): Don't DEFSYM Qmenu_bar here.
+       DEFSYM Qdeactivate_mark before the corresponding var.
+       * keymap.c (syms_of_keymap): Use DEFSYM for Qmenu_bar and Qmode_line
+       instead of interning their symbols; this avoids duplicates.
+       (LISP_INITIALLY, TAG_PTR)
+       (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END, XSYMBOL_INIT):
+       New macros.
+       (LISP_INITIALLY_ZERO): Use it.
+       (enum symbol_interned, enum symbol_redirect, struct Lisp_Symbol)
+       (EXFUN, DEFUN_ARGS_MANY, DEFUN_ARGS_UNEVALLED, DEFUN_ARGS_*):
+       Move decls up, to avoid forward uses.  Include globals.h earlier, too.
+       (make_lisp_symbol): New function.
+       (XSETSYMBOL): Use it.
+       (DEFSYM): Now just a placeholder for make-docfile.
+       * lread.c (DEFINE_SYMBOLS): Define, for globals.h.
+       (intern_sym): New function, with body taken from old intern_driver.
+       (intern_driver): Use it.  Last arg is now Lisp integer, not ptrdiff_t.
+       All uses changed.
+       (define_symbol): New function.
+       (init_obarray): Define the C symbols taken from lispsym.
+       Use plain DEFSYM for Qt and Qnil.
+       * syntax.c (init_syntax_once): No need to worry about
+       Qchar_table_extra_slots.
+
 2015-01-04  Paul Eggert  <address@hidden>
 
        'temacs -nw' should not call missing functions
@@ -146,6 +389,10 @@
        * xterm.c (do_ewmh_fullscreen): Don't remove maximized_horz/vert
        when going to fullscreen (Bug#0x180004f).
 
+2014-12-27  Eli Zaretskii  <address@hidden>
+
+       * window.c (Fwindow_body_width): Doc fix.  (Bug#19395)
+
 2014-12-27  Stefan Monnier  <address@hidden>
 
        * buffer.c (syms_of_buffer) <Vafter_change_functions>: fix docstring.
diff --git a/src/alloc.c b/src/alloc.c
index ecea3e8a..7c93733 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -263,23 +263,6 @@ no_sanitize_memcpy (void *dest, void const *src, size_t 
size)
 
 #endif /* MAX_SAVE_STACK > 0 */
 
-static Lisp_Object Qconses;
-static Lisp_Object Qsymbols;
-static Lisp_Object Qmiscs;
-static Lisp_Object Qstrings;
-static Lisp_Object Qvectors;
-static Lisp_Object Qfloats;
-static Lisp_Object Qintervals;
-static Lisp_Object Qbuffers;
-static Lisp_Object Qstring_bytes, Qvector_slots, Qheap;
-static Lisp_Object Qgc_cons_threshold;
-Lisp_Object Qautomatic_gc;
-Lisp_Object Qchar_table_extra_slots;
-
-/* Hook run after GC has finished.  */
-
-static Lisp_Object Qpost_gc_hook;
-
 static void mark_terminals (void);
 static void gc_sweep (void);
 static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -3410,13 +3393,29 @@ set_symbol_name (Lisp_Object sym, Lisp_Object name)
   XSYMBOL (sym)->name = name;
 }
 
+void
+init_symbol (Lisp_Object val, Lisp_Object name)
+{
+  struct Lisp_Symbol *p = XSYMBOL (val);
+  set_symbol_name (val, name);
+  set_symbol_plist (val, Qnil);
+  p->redirect = SYMBOL_PLAINVAL;
+  SET_SYMBOL_VAL (p, Qunbound);
+  set_symbol_function (val, Qnil);
+  set_symbol_next (val, NULL);
+  p->gcmarkbit = false;
+  p->interned = SYMBOL_UNINTERNED;
+  p->constant = 0;
+  p->declared_special = false;
+  p->pinned = false;
+}
+
 DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
        doc: /* Return a newly allocated uninterned symbol whose name is NAME.
 Its value is void, and its function definition and property list are nil.  */)
   (Lisp_Object name)
 {
-  register Lisp_Object val;
-  register struct Lisp_Symbol *p;
+  Lisp_Object val;
 
   CHECK_STRING (name);
 
@@ -3444,18 +3443,7 @@ Its value is void, and its function definition and 
property list are nil.  */)
 
   MALLOC_UNBLOCK_INPUT;
 
-  p = XSYMBOL (val);
-  set_symbol_name (val, name);
-  set_symbol_plist (val, Qnil);
-  p->redirect = SYMBOL_PLAINVAL;
-  SET_SYMBOL_VAL (p, Qunbound);
-  set_symbol_function (val, Qnil);
-  set_symbol_next (val, NULL);
-  p->gcmarkbit = false;
-  p->interned = SYMBOL_UNINTERNED;
-  p->constant = 0;
-  p->declared_special = false;
-  p->pinned = false;
+  init_symbol (val, name);
   consing_since_gc += sizeof (struct Lisp_Symbol);
   symbols_consed++;
   total_free_symbols--;
@@ -4925,6 +4913,14 @@ mark_stack (void *end)
 
 #endif /* GC_MARK_STACK != 0 */
 
+static bool
+c_symbol_p (struct Lisp_Symbol *sym)
+{
+  char *lispsym_ptr = (char *) lispsym;
+  char *sym_ptr = (char *) sym;
+  ptrdiff_t lispsym_offset = sym_ptr - lispsym_ptr;
+  return 0 <= lispsym_offset && lispsym_offset < sizeof lispsym;
+}
 
 /* Determine whether it is safe to access memory at address P.  */
 static int
@@ -4978,6 +4974,9 @@ valid_lisp_object_p (Lisp_Object obj)
   if (PURE_POINTER_P (p))
     return 1;
 
+  if (SYMBOLP (obj) && c_symbol_p (p))
+    return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0;
+
   if (p == &buffer_defaults || p == &buffer_local_symbols)
     return 2;
 
@@ -5343,7 +5342,7 @@ purecopy (Lisp_Object obj)
     }
   else if (SYMBOLP (obj))
     {
-      if (!XSYMBOL (obj)->pinned)
+      if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj)))
        { /* We can't purify them, but they appear in many pure objects.
             Mark them as `pinned' so we know to mark them at every GC cycle.  
*/
          XSYMBOL (obj)->pinned = true;
@@ -5532,7 +5531,7 @@ mark_pinned_symbols (void)
       union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
       for (; sym < end; ++sym)
        if (sym->s.pinned)
-         mark_object (make_lisp_ptr (&sym->s, Lisp_Symbol));
+         mark_object (make_lisp_symbol (&sym->s));
 
       lim = SYMBOL_BLOCK_SIZE;
     }
@@ -5566,7 +5565,7 @@ garbage_collect_1 (void *end)
     return Qnil;
 
   /* Record this function, so it appears on the profiler's backtraces.  */
-  record_in_backtrace (Qautomatic_gc, &Qnil, 0);
+  record_in_backtrace (Qautomatic_gc, 0, 0);
 
   check_cons_list ();
 
@@ -5630,6 +5629,9 @@ garbage_collect_1 (void *end)
   mark_buffer (&buffer_defaults);
   mark_buffer (&buffer_local_symbols);
 
+  for (i = 0; i < ARRAYELTS (lispsym); i++)
+    mark_object (builtin_lisp_symbol (i));
+
   for (i = 0; i < staticidx; i++)
     mark_object (*staticvec[i]);
 
@@ -6193,17 +6195,28 @@ mark_object (Lisp_Object arg)
       emacs_abort ();                          \
   } while (0)
 
-  /* Check both of the above conditions.  */
+  /* Check both of the above conditions, for non-symbols.  */
 #define CHECK_ALLOCATED_AND_LIVE(LIVEP)                \
   do {                                         \
     CHECK_ALLOCATED ();                                \
     CHECK_LIVE (LIVEP);                                \
   } while (0)                                  \
 
+  /* Check both of the above conditions, for symbols.  */
+#define CHECK_ALLOCATED_AND_LIVE_SYMBOL()      \
+  do {                                         \
+    if (!c_symbol_p (ptr))                     \
+      {                                                \
+       CHECK_ALLOCATED ();                     \
+       CHECK_LIVE (live_symbol_p);             \
+      }                                                \
+  } while (0)                                  \
+
 #else /* not GC_CHECK_MARKED_OBJECTS */
 
-#define CHECK_LIVE(LIVEP)              ((void) 0)
-#define CHECK_ALLOCATED_AND_LIVE(LIVEP)        ((void) 0)
+#define CHECK_LIVE(LIVEP)                      ((void) 0)
+#define CHECK_ALLOCATED_AND_LIVE(LIVEP)                ((void) 0)
+#define CHECK_ALLOCATED_AND_LIVE_SYMBOL()      ((void) 0)
 
 #endif /* not GC_CHECK_MARKED_OBJECTS */
 
@@ -6363,7 +6376,7 @@ mark_object (Lisp_Object arg)
       nextsym:
        if (ptr->gcmarkbit)
          break;
-       CHECK_ALLOCATED_AND_LIVE (live_symbol_p);
+       CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
        ptr->gcmarkbit = 1;
        /* Attempt to catch bogus objects.  */
         eassert (valid_lisp_object_p (ptr->function));
@@ -6720,13 +6733,16 @@ NO_INLINE /* For better stack traces */
 static void
 sweep_symbols (void)
 {
-  register struct symbol_block *sblk;
+  struct symbol_block *sblk;
   struct symbol_block **sprev = &symbol_block;
-  register int lim = symbol_block_index;
-  EMACS_INT num_free = 0, num_used = 0;
+  int lim = symbol_block_index;
+  EMACS_INT num_free = 0, num_used = ARRAYELTS (lispsym);
 
   symbol_free_list = NULL;
 
+  for (int i = 0; i < ARRAYELTS (lispsym); i++)
+    lispsym[i].gcmarkbit = 0;
+
   for (sblk = symbol_block; sblk; sblk = *sprev)
     {
       int this_free = 0;
@@ -6974,6 +6990,21 @@ Frames, windows, buffers, and subprocesses count as 
vectors
                bounded_number (strings_consed));
 }
 
+static bool
+symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
+{
+  struct Lisp_Symbol *sym = XSYMBOL (symbol);
+  Lisp_Object val = find_symbol_value (symbol);
+  return (EQ (val, obj)
+         || EQ (sym->function, obj)
+         || (!NILP (sym->function)
+             && COMPILEDP (sym->function)
+             && EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
+         || (!NILP (val)
+             && COMPILEDP (val)
+             && EQ (AREF (val, COMPILED_BYTECODE), obj)));
+}
+
 /* Find at most FIND_MAX symbols which have OBJ as their value or
    function.  This is used in gdbinit's `xwhichsymbols' command.  */
 
@@ -6986,6 +7017,17 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
 
    if (! DEADP (obj))
      {
+       for (int i = 0; i < ARRAYELTS (lispsym); i++)
+        {
+          Lisp_Object sym = builtin_lisp_symbol (i);
+          if (symbol_uses_obj (sym, obj))
+            {
+              found = Fcons (sym, found);
+              if (--find_max == 0)
+                goto out;
+            }
+        }
+
        for (sblk = symbol_block; sblk; sblk = sblk->next)
         {
           union aligned_Lisp_Symbol *aligned_sym = sblk->symbols;
@@ -6993,25 +7035,13 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
 
           for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++)
             {
-              struct Lisp_Symbol *sym = &aligned_sym->s;
-              Lisp_Object val;
-              Lisp_Object tem;
-
               if (sblk == symbol_block && bn >= symbol_block_index)
                 break;
 
-              XSETSYMBOL (tem, sym);
-              val = find_symbol_value (tem);
-              if (EQ (val, obj)
-                  || EQ (sym->function, obj)
-                  || (!NILP (sym->function)
-                      && COMPILEDP (sym->function)
-                      && EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
-                  || (!NILP (val)
-                      && COMPILEDP (val)
-                      && EQ (AREF (val, COMPILED_BYTECODE), obj)))
+              Lisp_Object sym = make_lisp_symbol (&aligned_sym->s);
+              if (symbol_uses_obj (sym, obj))
                 {
-                  found = Fcons (tem, found);
+                  found = Fcons (sym, found);
                   if (--find_max == 0)
                     goto out;
                 }
@@ -7154,7 +7184,9 @@ verify_alloca (void)
 void
 init_alloc_once (void)
 {
-  /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet!  */
+  /* Even though Qt's contents are not set up, its address is known.  */
+  Vpurify_flag = Qt;
+
   purebeg = PUREBEG;
   pure_size = PURESIZE;
 
@@ -7230,6 +7262,7 @@ If this portion is smaller than `gc-cons-threshold', this 
is ignored.  */);
 
   DEFVAR_INT ("symbols-consed", symbols_consed,
              doc: /* Number of symbols that have been consed so far.  */);
+  symbols_consed += ARRAYELTS (lispsym);
 
   DEFVAR_INT ("string-chars-consed", string_chars_consed,
              doc: /* Number of string characters that have been consed so far. 
 */);
diff --git a/src/bidi.c b/src/bidi.c
index ef0092f..cbc1820 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -262,7 +262,6 @@ typedef enum {
 } bidi_category_t;
 
 static Lisp_Object paragraph_start_re, paragraph_separate_re;
-static Lisp_Object Qparagraph_start, Qparagraph_separate;
 
 
 /***********************************************************************
diff --git a/src/buffer.c b/src/buffer.c
index 7023a51..2ea69f3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -118,41 +118,8 @@ static void reset_buffer_local_variables (struct buffer *, 
bool);
    due to user rplac'ing this alist or its elements.  */
 Lisp_Object Vbuffer_alist;
 
-static Lisp_Object Qkill_buffer_query_functions;
-
-/* Hook run before changing a major mode.  */
-static Lisp_Object Qchange_major_mode_hook;
-
-Lisp_Object Qfirst_change_hook;
-Lisp_Object Qbefore_change_functions;
-Lisp_Object Qafter_change_functions;
-
-static Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
-static Lisp_Object Qpermanent_local_hook;
-
-static Lisp_Object Qprotected_field;
-
 static Lisp_Object QSFundamental;      /* A string "Fundamental".  */
 
-static Lisp_Object Qkill_buffer_hook;
-static Lisp_Object Qbuffer_list_update_hook;
-
-static Lisp_Object Qget_file_buffer;
-
-static Lisp_Object Qoverlayp;
-
-Lisp_Object Qpriority, Qbefore_string, Qafter_string;
-
-static Lisp_Object Qevaporate;
-
-Lisp_Object Qmodification_hooks;
-Lisp_Object Qinsert_in_front_hooks;
-Lisp_Object Qinsert_behind_hooks;
-
-Lisp_Object Qchoice, Qrange, Qleft, Qright;
-Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
-static Lisp_Object Qoverwrite_mode, Qfraction;
-
 static void alloc_buffer_text (struct buffer *, ptrdiff_t);
 static void free_buffer_text (struct buffer *b);
 static struct Lisp_Overlay * copy_overlays (struct buffer *, struct 
Lisp_Overlay *);
@@ -1719,7 +1686,7 @@ cleaning up all windows currently displaying the buffer 
to be killed. */)
       return unbind_to (count, Qt);
 
     /* Then run the hooks.  */
-    Frun_hooks (1, &Qkill_buffer_hook);
+    run_hook (Qkill_buffer_hook);
     unbind_to (count, Qnil);
   }
 
@@ -2748,7 +2715,7 @@ The first thing this function does is run
 the normal hook `change-major-mode-hook'.  */)
   (void)
 {
-  Frun_hooks (1, &Qchange_major_mode_hook);
+  run_hook (Qchange_major_mode_hook);
 
   /* Make sure none of the bindings in local_var_alist
      remain swapped in, in their symbols.  */
@@ -5071,9 +5038,9 @@ init_buffer_once (void)
   /* Make sure all markable slots in buffer_defaults
      are initialized reasonably, so mark_buffer won't choke.  */
   reset_buffer (&buffer_defaults);
-  eassert (EQ (BVAR (&buffer_defaults, name), make_number (0)));
+  eassert (NILP (BVAR (&buffer_defaults, name)));
   reset_buffer_local_variables (&buffer_defaults, 1);
-  eassert (EQ (BVAR (&buffer_local_symbols, name), make_number (0)));
+  eassert (NILP (BVAR (&buffer_local_symbols, name)));
   reset_buffer (&buffer_local_symbols);
   reset_buffer_local_variables (&buffer_local_symbols, 1);
   /* Prevent GC from getting confused.  */
diff --git a/src/buffer.h b/src/buffer.h
index 1b2b5b6..81852ca 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1141,12 +1141,6 @@ record_unwind_current_buffer (void)
   } while (false)
 
 extern Lisp_Object Vbuffer_alist;
-extern Lisp_Object Qbefore_change_functions;
-extern Lisp_Object Qafter_change_functions;
-extern Lisp_Object Qfirst_change_hook;
-extern Lisp_Object Qpriority, Qbefore_string, Qafter_string;
-extern Lisp_Object Qchoice, Qrange, Qleft, Qright;
-extern Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
 
 /* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is
    a `for' loop which iterates over the buffers from Vbuffer_alist.  */
diff --git a/src/bytecode.c b/src/bytecode.c
index 1d89d02..b458367 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -69,7 +69,6 @@ by Hallvard:
 
 #ifdef BYTE_CODE_METER
 
-Lisp_Object Qbyte_code_meter;
 #define METER_2(code1, code2) AREF (AREF (Vbyte_code_meter, code1), code2)
 #define METER_1(code) METER_2 (0, code)
 
diff --git a/src/callint.c b/src/callint.c
index 200c9ed..2595503 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -28,18 +28,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "window.h"
 #include "keymap.h"
 
-Lisp_Object Qminus, Qplus;
-static Lisp_Object Qfuncall_interactively;
-static Lisp_Object Qcommand_debug_status;
-static Lisp_Object Qenable_recursive_minibuffers;
-
-static Lisp_Object Qhandle_shift_selection;
-static Lisp_Object Qread_number;
-
-Lisp_Object Qmouse_leave_buffer_hook;
-
-static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif;
-Lisp_Object Qwhen, Qprogn;
 static Lisp_Object preserved_fns;
 
 /* Marker used within call-interactively to refer to point.  */
@@ -477,7 +465,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
                error ("Attempt to select inactive minibuffer window");
 
              /* If the current buffer wants to clean up, let it.  */
-              Frun_hooks (1, &Qmouse_leave_buffer_hook);
+              run_hook (Qmouse_leave_buffer_hook);
 
              Fselect_window (w, Qnil);
            }
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 2268003..8755353 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -30,8 +30,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 
 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
-
-Lisp_Object Qidentity;
 
 static Lisp_Object
 casify_object (enum case_action flag, Lisp_Object obj)
diff --git a/src/casetab.c b/src/casetab.c
index 4bedc17..b086abc 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -24,7 +24,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "character.h"
 #include "buffer.h"
 
-static Lisp_Object Qcase_table_p, Qcase_table;
 Lisp_Object Vascii_downcase_table;
 static Lisp_Object Vascii_upcase_table;
 Lisp_Object Vascii_canon_table;
diff --git a/src/category.c b/src/category.c
index 09c7824..b20493e 100644
--- a/src/category.c
+++ b/src/category.c
@@ -53,8 +53,6 @@ bset_category_table (struct buffer *b, Lisp_Object val)
 
    For the moment, we are not using this feature.  */
 static int category_table_version;
-
-static Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, 
Qcategory_table_p;
 
 /* Category set staff.  */
 
diff --git a/src/ccl.c b/src/ccl.c
index 109d6c0..053544c 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -34,21 +34,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "ccl.h"
 #include "coding.h"
 
-Lisp_Object Qccl, Qcclp;
-
-/* This symbol is a property which associates with ccl program vector.
-   Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector.  */
-static Lisp_Object Qccl_program;
-
-/* These symbols are properties which associate with code conversion
-   map and their ID respectively.  */
-static Lisp_Object Qcode_conversion_map;
-static Lisp_Object Qcode_conversion_map_id;
-
-/* Symbols of ccl program have this property, a value of the property
-   is an index for Vccl_program_table. */
-static Lisp_Object Qccl_program_idx;
-
 /* Table of registered CCL programs.  Each element is a vector of
    NAME, CCL_PROG, RESOLVEDP, and UPDATEDP, where NAME (symbol) is the
    name of the program, CCL_PROG (vector) is the compiled code of the
@@ -2297,8 +2282,17 @@ syms_of_ccl (void)
 
   DEFSYM (Qccl, "ccl");
   DEFSYM (Qcclp, "cclp");
+
+  /* This symbol is a property which associates with ccl program vector.
+     Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector.  */
   DEFSYM (Qccl_program, "ccl-program");
+
+  /* Symbols of ccl program have this property, a value of the property
+     is an index for Vccl_program_table. */
   DEFSYM (Qccl_program_idx, "ccl-program-idx");
+
+  /* These symbols are properties which associate with code conversion
+     map and their ID respectively.  */
   DEFSYM (Qcode_conversion_map, "code-conversion-map");
   DEFSYM (Qcode_conversion_map_id, "code-conversion-map-id");
 
diff --git a/src/ccl.h b/src/ccl.h
index b01a73f..7b72dc7 100644
--- a/src/ccl.h
+++ b/src/ccl.h
@@ -81,8 +81,6 @@ extern bool setup_ccl_program (struct ccl_program *, 
Lisp_Object);
 extern void ccl_driver (struct ccl_program *, int *, int *, int, int,
                         Lisp_Object);
 
-extern Lisp_Object Qccl, Qcclp;
-
 #define CHECK_CCL_PROGRAM(x)                   \
   do {                                         \
     if (NILP (Fccl_program_p (x)))             \
diff --git a/src/character.c b/src/character.c
index ad3fe12..4a5c7ec 100644
--- a/src/character.c
+++ b/src/character.c
@@ -48,16 +48,10 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #endif /* emacs */
 
-Lisp_Object Qcharacterp;
-
-static Lisp_Object Qauto_fill_chars;
-
 /* Char-table of information about which character to unify to which
    Unicode character.  Mainly used by the macro MAYBE_UNIFY_CHAR.  */
 Lisp_Object Vchar_unify_table;
 
-static Lisp_Object Qchar_script_table;
-
 
 
 /* If character code C has modifier masks, reflect them to the
diff --git a/src/character.h b/src/character.h
index 624f4ff..5043880 100644
--- a/src/character.h
+++ b/src/character.h
@@ -657,7 +657,6 @@ extern ptrdiff_t c_string_width (const unsigned char *, 
ptrdiff_t, int,
 extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t,
                                    ptrdiff_t *, ptrdiff_t *);
 
-extern Lisp_Object Qcharacterp;
 extern Lisp_Object Vchar_unify_table;
 extern Lisp_Object string_escape_byte8 (Lisp_Object);
 
diff --git a/src/charset.c b/src/charset.c
index 33436d5..ea1480e 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -66,16 +66,7 @@ struct charset *charset_table;
 static ptrdiff_t charset_table_size;
 static int charset_table_used;
 
-Lisp_Object Qcharsetp;
-
-/* Special charset symbols.  */
-Lisp_Object Qascii;
-static Lisp_Object Qeight_bit;
-static Lisp_Object Qiso_8859_1;
-static Lisp_Object Qunicode;
-static Lisp_Object Qemacs;
-
-/* The corresponding charsets.  */
+/* Special charsets corresponding to symbols.  */
 int charset_ascii;
 int charset_eight_bit;
 static int charset_iso_8859_1;
@@ -88,9 +79,6 @@ int charset_jisx0208_1978;
 int charset_jisx0208;
 int charset_ksc5601;
 
-/* Value of charset attribute `charset-iso-plane'.  */
-static Lisp_Object Qgl, Qgr;
-
 /* Charset of unibyte characters.  */
 int charset_unibyte;
 
@@ -2344,12 +2332,14 @@ syms_of_charset (void)
 {
   DEFSYM (Qcharsetp, "charsetp");
 
+  /* Special charset symbols.  */
   DEFSYM (Qascii, "ascii");
   DEFSYM (Qunicode, "unicode");
   DEFSYM (Qemacs, "emacs");
   DEFSYM (Qeight_bit, "eight-bit");
   DEFSYM (Qiso_8859_1, "iso-8859-1");
 
+  /* Value of charset attribute `charset-iso-plane'.  */
   DEFSYM (Qgl, "gl");
   DEFSYM (Qgr, "gr");
 
@@ -2362,10 +2352,6 @@ syms_of_charset (void)
   staticpro (&Vemacs_mule_charset_list);
   Vemacs_mule_charset_list = Qnil;
 
-  /* Don't staticpro them here.  It's done in syms_of_fns.  */
-  QCtest = intern_c_string (":test");
-  Qeq = intern_c_string ("eq");
-
   staticpro (&Vcharset_hash_table);
   {
     Lisp_Object args[2];
diff --git a/src/charset.h b/src/charset.h
index f66ca0d..f657598 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -519,9 +519,6 @@ extern int 
iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL];
 
 
 
-extern Lisp_Object Qcharsetp;
-
-extern Lisp_Object Qascii;
 extern int charset_ascii, charset_eight_bit;
 extern int charset_unicode;
 extern int charset_jisx0201_roman;
diff --git a/src/chartab.c b/src/chartab.c
index bfbbf79..013a5be 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -57,9 +57,6 @@ static const int chartab_bits[4] =
 /* Preamble for uniprop (Unicode character property) tables.  See the
    comment of "Unicode character property tables".  */
 
-/* Purpose of uniprop tables. */
-static Lisp_Object Qchar_code_property_table;
-
 /* Types of decoder and encoder functions for uniprop values.  */
 typedef Lisp_Object (*uniprop_decoder_t) (Lisp_Object, Lisp_Object);
 typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object);
@@ -1378,6 +1375,7 @@ CHAR-TABLE must be what returned by 
`unicode-property-table-internal'. */)
 void
 syms_of_chartab (void)
 {
+  /* Purpose of uniprop tables. */
   DEFSYM (Qchar_code_property_table, "char-code-property-table");
 
   defsubr (&Smake_char_table);
diff --git a/src/cmds.c b/src/cmds.c
index 485a235..270fc39 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -31,11 +31,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "dispextern.h"
 #include "frame.h"
 
-static Lisp_Object Qkill_forward_chars, Qkill_backward_chars;
-
-/* A possible value for a buffer's overwrite-mode variable.  */
-static Lisp_Object Qoverwrite_mode_binary;
-
 static int internal_self_insert (int, EMACS_INT);
 
 DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
@@ -322,9 +317,6 @@ At the end, it runs `post-self-insert-hook'.  */)
    return 0.  A value of 1 indicates this *might* not have been simple.
    A value of 2 means this did things that call for an undo boundary.  */
 
-static Lisp_Object Qexpand_abbrev;
-static Lisp_Object Qpost_self_insert_hook;
-
 static int
 internal_self_insert (int c, EMACS_INT n)
 {
@@ -507,7 +499,7 @@ internal_self_insert (int c, EMACS_INT n)
     }
 
   /* Run hooks for electric keys.  */
-  Frun_hooks (1, &Qpost_self_insert_hook);
+  run_hook (Qpost_self_insert_hook);
 
   return hairy;
 }
@@ -519,7 +511,10 @@ syms_of_cmds (void)
 {
   DEFSYM (Qkill_backward_chars, "kill-backward-chars");
   DEFSYM (Qkill_forward_chars, "kill-forward-chars");
+
+  /* A possible value for a buffer's overwrite-mode variable.  */
   DEFSYM (Qoverwrite_mode_binary, "overwrite-mode-binary");
+
   DEFSYM (Qexpand_abbrev, "expand-abbrev");
   DEFSYM (Qpost_self_insert_hook, "post-self-insert-hook");
 
diff --git a/src/coding.c b/src/coding.c
index f3f8dc1..20c6476 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -303,35 +303,6 @@ encode_coding_XXX (struct coding_system *coding)
 
 Lisp_Object Vcoding_system_hash_table;
 
-static Lisp_Object Qcoding_system, Qeol_type;
-static Lisp_Object Qcoding_aliases;
-Lisp_Object Qunix, Qdos;
-static Lisp_Object Qmac;
-Lisp_Object Qbuffer_file_coding_system;
-static Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
-static Lisp_Object Qdefault_char;
-Lisp_Object Qno_conversion, Qundecided;
-Lisp_Object Qcharset, Qutf_8;
-static Lisp_Object Qiso_2022;
-static Lisp_Object Qutf_16, Qshift_jis, Qbig5;
-static Lisp_Object Qbig, Qlittle;
-static Lisp_Object Qcoding_system_history;
-static Lisp_Object Qvalid_codes;
-static Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
-static Lisp_Object QCdecode_translation_table, QCencode_translation_table;
-static Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
-static Lisp_Object QCascii_compatible_p;
-
-Lisp_Object Qcall_process, Qcall_process_region;
-Lisp_Object Qstart_process, Qopen_network_stream;
-static Lisp_Object Qtarget_idx;
-
-static Lisp_Object Qinsufficient_source, Qinvalid_source, Qinterrupted;
-
-/* If a symbol has this property, evaluate the value to define the
-   symbol as a coding system.  */
-static Lisp_Object Qcoding_system_define_form;
-
 /* Format of end-of-line decided by system.  This is Qunix on
    Unix and Mac, Qdos on DOS/Windows.
    This has an effect only for external encoding (i.e. for output to
@@ -340,17 +311,6 @@ static Lisp_Object system_eol_type;
 
 #ifdef emacs
 
-Lisp_Object Qcoding_system_p, Qcoding_system_error;
-
-/* Coding system emacs-mule and raw-text are for converting only
-   end-of-line format.  */
-Lisp_Object Qemacs_mule, Qraw_text;
-Lisp_Object Qutf_8_emacs;
-
-#if defined (WINDOWSNT) || defined (CYGWIN)
-static Lisp_Object Qutf_16le;
-#endif
-
 /* Coding-systems are handed between Emacs Lisp programs and C internal
    routines by the following three variables.  */
 /* Coding system to be used to encode text for terminal display when
@@ -359,11 +319,6 @@ struct coding_system safe_terminal_coding;
 
 #endif /* emacs */
 
-Lisp_Object Qtranslation_table;
-Lisp_Object Qtranslation_table_id;
-static Lisp_Object Qtranslation_table_for_decode;
-static Lisp_Object Qtranslation_table_for_encode;
-
 /* Two special coding systems.  */
 static Lisp_Object Vsjis_coding_system;
 static Lisp_Object Vbig5_coding_system;
@@ -10903,6 +10858,7 @@ syms_of_coding (void)
 
   DEFSYM (Qcoding_system_p, "coding-system-p");
 
+  /* Error signaled when there's a problem with detecting a coding system.  */
   DEFSYM (Qcoding_system_error, "coding-system-error");
   Fput (Qcoding_system_error, Qerror_conditions,
        listn (CONSTYPE_PURE, 2, Qcoding_system_error, Qerror));
@@ -10917,6 +10873,8 @@ syms_of_coding (void)
 
   DEFSYM (Qvalid_codes, "valid-codes");
 
+  /* Coding system emacs-mule and raw-text are for converting only
+     end-of-line format.  */
   DEFSYM (Qemacs_mule, "emacs-mule");
 
   DEFSYM (QCcategory, ":category");
@@ -10979,6 +10937,9 @@ syms_of_coding (void)
   DEFSYM (Qinsufficient_source, "insufficient-source");
   DEFSYM (Qinvalid_source, "invalid-source");
   DEFSYM (Qinterrupted, "interrupted");
+
+  /* If a symbol has this property, evaluate the value to define the
+     symbol as a coding system.  */
   DEFSYM (Qcoding_system_define_form, "coding-system-define-form");
 
   defsubr (&Scoding_system_p);
diff --git a/src/coding.h b/src/coding.h
index 2b56e5a..d49d786 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -763,23 +763,7 @@ extern Lisp_Object from_unicode_buffer (const wchar_t 
*wstr);
 extern Lisp_Object preferred_coding_system (void);
 
 
-extern Lisp_Object Qutf_8, Qutf_8_emacs;
-
-extern Lisp_Object Qcoding_category_index;
-extern Lisp_Object Qcoding_system_p;
-extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided;
-extern Lisp_Object Qbuffer_file_coding_system;
-
-extern Lisp_Object Qunix, Qdos;
-
-extern Lisp_Object Qtranslation_table;
-extern Lisp_Object Qtranslation_table_id;
-
 #ifdef emacs
-extern Lisp_Object Qfile_coding_system;
-extern Lisp_Object Qcall_process, Qcall_process_region;
-extern Lisp_Object Qstart_process, Qopen_network_stream;
-extern Lisp_Object Qwrite_region;
 
 extern char *emacs_strerror (int);
 
@@ -789,9 +773,6 @@ extern struct coding_system safe_terminal_coding;
 
 #endif
 
-/* Error signaled when there's a problem with detecting coding system */
-extern Lisp_Object Qcoding_system_error;
-
 extern char emacs_mule_bytes[256];
 
 #endif /* EMACS_CODING_H */
diff --git a/src/composite.c b/src/composite.c
index 4b22499..8ac5ef7 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -134,8 +134,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 */
 
 
-Lisp_Object Qcomposition;
-
 /* Table of pointers to the structure `composition' indexed by
    COMPOSITION-ID.  This structure is for storing information about
    each composition except for COMPONENTS-VEC.  */
@@ -152,8 +150,6 @@ ptrdiff_t n_compositions;
    COMPOSITION-ID.  */
 Lisp_Object composition_hash_table;
 
-static Lisp_Object Qauto_composed;
-static Lisp_Object Qauto_composition_function;
 /* Maximum number of characters to look back for
    auto-compositions.  */
 #define MAX_AUTO_COMPOSITION_LOOKBACK 3
diff --git a/src/composite.h b/src/composite.h
index e0d4e85..fb9f9eb 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -190,7 +190,6 @@ extern ptrdiff_t n_compositions;
 #define CHECK_BORDER   (CHECK_HEAD | CHECK_TAIL)
 #define CHECK_ALL      (CHECK_BORDER | CHECK_INSIDE)
 
-extern Lisp_Object Qcomposition;
 extern Lisp_Object composition_hash_table;
 extern ptrdiff_t get_composition_id (ptrdiff_t, ptrdiff_t, ptrdiff_t,
                                     Lisp_Object, Lisp_Object);
diff --git a/src/conf_post.h b/src/conf_post.h
index 479d044..1a080fa 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -245,7 +245,9 @@ extern void _DebPrint (const char *fmt, ...);
 # define ATTRIBUTE_MALLOC
 #endif
 
-#if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
+#if (__clang__                                 \
+     ? __has_attribute (alloc_size)            \
+     : 4 < __GNUC__ + (3 <= __GNUC_MINOR__))
 # define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
 #else
 # define ATTRIBUTE_ALLOC_SIZE(args)
diff --git a/src/data.c b/src/data.c
index 3992792..820c3ce 100644
--- a/src/data.c
+++ b/src/data.c
@@ -37,58 +37,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "font.h"
 #include "keymap.h"
 
-Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
-static Lisp_Object Qsubr;
-Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
-Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range;
-static Lisp_Object Qwrong_length_argument;
-static Lisp_Object Qwrong_type_argument;
-Lisp_Object Qvoid_variable, Qvoid_function;
-static Lisp_Object Qcyclic_function_indirection;
-static Lisp_Object Qcyclic_variable_indirection;
-Lisp_Object Qcircular_list;
-static Lisp_Object Qsetting_constant;
-Lisp_Object Qinvalid_read_syntax;
-Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
-Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
-Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
-Lisp_Object Qtext_read_only;
-
-Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp;
-static Lisp_Object Qnatnump;
-Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
-Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
-Lisp_Object Qbool_vector_p;
-Lisp_Object Qbuffer_or_string_p;
-static Lisp_Object Qkeywordp, Qboundp;
-Lisp_Object Qfboundp;
-Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
-
-Lisp_Object Qcdr;
-static Lisp_Object Qad_advice_info, Qad_activate_internal;
-
-static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error;
-Lisp_Object Qrange_error, Qoverflow_error;
-
-Lisp_Object Qfloatp;
-Lisp_Object Qnumberp, Qnumber_or_marker_p;
-
-Lisp_Object Qinteger, Qsymbol;
-static Lisp_Object Qcons, Qfloat, Qmisc, Qstring, Qvector;
-Lisp_Object Qwindow;
-static Lisp_Object Qoverlay, Qwindow_configuration;
-static Lisp_Object Qprocess, Qmarker;
-static Lisp_Object Qcompiled_function, Qframe;
-Lisp_Object Qbuffer;
-static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
-static Lisp_Object Qsubrp;
-static Lisp_Object Qmany, Qunevalled;
-Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
-static Lisp_Object Qdefun;
-
-Lisp_Object Qinteractive_form;
-static Lisp_Object Qdefalias_fset_function;
-
 static void swap_in_symval_forwarding (struct Lisp_Symbol *,
                                       struct Lisp_Buffer_Local_Value *);
 
@@ -3584,10 +3532,6 @@ syms_of_data (void)
   PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail),
             "Arithmetic underflow error");
 
-  staticpro (&Qnil);
-  staticpro (&Qt);
-  staticpro (&Qunbound);
-
   /* Types that type-of returns.  */
   DEFSYM (Qinteger, "integer");
   DEFSYM (Qsymbol, "symbol");
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 9de6949..3bdec0f 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -41,37 +41,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #endif
 
 
-/* Subroutines.  */
-static Lisp_Object Qdbus__init_bus;
-static Lisp_Object Qdbus_get_unique_name;
-static Lisp_Object Qdbus_message_internal;
-
-/* D-Bus error symbol.  */
-static Lisp_Object Qdbus_error;
-
-/* Lisp symbols of the system and session buses.  */
-static Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
-
-/* Lisp symbol for method call timeout.  */
-static Lisp_Object QCdbus_timeout;
-
-/* Lisp symbols of D-Bus types.  */
-static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
-static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
-static Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
-static Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
-static Lisp_Object QCdbus_type_double, QCdbus_type_string;
-static Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
-#ifdef DBUS_TYPE_UNIX_FD
-static Lisp_Object QCdbus_type_unix_fd;
-#endif
-static Lisp_Object QCdbus_type_array, QCdbus_type_variant;
-static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
-
-/* Lisp symbols of objects in `dbus-registered-objects-table'.  */
-static Lisp_Object QCdbus_registered_serial, QCdbus_registered_method;
-static Lisp_Object QCdbus_registered_signal;
-
 /* Alist of D-Bus buses we are polling for messages.
    The key is the symbol or string of the bus, and the value is the
    connection address.  */
@@ -1755,15 +1724,21 @@ syms_of_dbusbind (void)
   DEFSYM (Qdbus_message_internal, "dbus-message-internal");
   defsubr (&Sdbus_message_internal);
 
+  /* D-Bus error symbol.  */
   DEFSYM (Qdbus_error, "dbus-error");
   Fput (Qdbus_error, Qerror_conditions,
        list2 (Qdbus_error, Qerror));
   Fput (Qdbus_error, Qerror_message,
        build_pure_c_string ("D-Bus error"));
 
+  /* Lisp symbols of the system and session buses.  */
   DEFSYM (QCdbus_system_bus, ":system");
   DEFSYM (QCdbus_session_bus, ":session");
+
+  /* Lisp symbol for method call timeout.  */
   DEFSYM (QCdbus_timeout, ":timeout");
+
+  /* Lisp symbols of D-Bus types.  */
   DEFSYM (QCdbus_type_byte, ":byte");
   DEFSYM (QCdbus_type_boolean, ":boolean");
   DEFSYM (QCdbus_type_int16, ":int16");
@@ -1783,6 +1758,8 @@ syms_of_dbusbind (void)
   DEFSYM (QCdbus_type_variant, ":variant");
   DEFSYM (QCdbus_type_struct, ":struct");
   DEFSYM (QCdbus_type_dict_entry, ":dict-entry");
+
+  /* Lisp symbols of objects in `dbus-registered-objects-table'.  */
   DEFSYM (QCdbus_registered_serial, ":serial");
   DEFSYM (QCdbus_registered_method, ":method");
   DEFSYM (QCdbus_registered_signal, ":signal");
diff --git a/src/decompress.c b/src/decompress.c
index 3c0ef10..b14f0a2 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -28,8 +28,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #include <verify.h>
 
-static Lisp_Object Qzlib_dll;
-
 #ifdef WINDOWSNT
 # include <windows.h>
 # include "w32.h"
diff --git a/src/dired.c b/src/dired.c
index 3ca400e..00f9a5b 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -51,13 +51,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "msdos.h"     /* for fstatat */
 #endif
 
-static Lisp_Object Qdirectory_files;
-static Lisp_Object Qdirectory_files_and_attributes;
-static Lisp_Object Qfile_name_completion;
-static Lisp_Object Qfile_name_all_completions;
-static Lisp_Object Qfile_attributes;
-static Lisp_Object Qfile_attributes_lessp;
-
 static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
 static Lisp_Object file_attributes (int, char const *, Lisp_Object);
 
@@ -450,7 +443,6 @@ These are all file names in directory DIRECTORY which begin 
with FILE.  */)
 }
 
 static int file_name_completion_stat (int, struct dirent *, struct stat *);
-static Lisp_Object Qdefault_directory;
 
 static Lisp_Object
 file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
diff --git a/src/dispextern.h b/src/dispextern.h
index 10c84da..bf0c2fc 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -393,10 +393,9 @@ struct glyph
 
   /* Lisp object source of this glyph.  Currently either a buffer or a
      string, if the glyph was produced from characters which came from
-     a buffer or a string; or Lisp integer zero (a.k.a. "null object")
-     if the glyph was inserted by redisplay for its own purposes, such
-     as padding or truncation/continuation glyphs, or the
-     overlay-arrow glyphs on TTYs.  */
+     a buffer or a string; or nil if the glyph was inserted by
+     redisplay for its own purposes, such as padding, truncation, or
+     continuation glyphs, or the overlay-arrow glyphs on TTYs.  */
   Lisp_Object object;
 
   /* Width in pixels.  */
@@ -1727,8 +1726,8 @@ struct face
      attributes except the font.  */
   struct face *ascii_face;
 
-#ifdef HAVE_XFT
-  /* Extra member that a font-driver uses privately.  */
+#if defined HAVE_XFT || defined HAVE_FREETYPE
+/* Extra member that a font-driver uses privately.  */
   void *extra;
 #endif
 };
@@ -2552,11 +2551,11 @@ struct it
      Object is normally the buffer which is being rendered, but it can
      also be a Lisp string in case the current display element comes
      from an overlay string or from a display string (before- or
-     after-string).  It may also be nil when a C string is being
-     rendered, e.g., during mode-line or header-line update.  It can
-     also be a cons cell of the form `(space ...)', when we produce a
-     stretch glyph from a `display' specification.  Finally, it can be
-     a zero-valued Lisp integer, but only temporarily, when we are
+     after-string).  It may also be a zero-valued Lisp integer when a
+     C string is being rendered, e.g., during mode-line or header-line
+     update.  It can also be a cons cell of the form `(space ...)',
+     when we produce a stretch glyph from a `display' specification.
+     Finally, it can be nil, but only temporarily, when we are
      producing special glyphs for display purposes, like truncation
      and continuation glyphs, or blanks that extend each line to the
      edge of the window on a TTY.
@@ -2934,8 +2933,8 @@ struct redisplay_interface
 
 struct image_type
 {
-  /* A symbol uniquely identifying the image type, .e.g `jpeg'.  */
-  Lisp_Object *type;
+  /* Index of a symbol uniquely identifying the image type, e.g., 'jpeg'.  */
+  int type;
 
   /* Check that SPEC is a valid image specification for the given
      image type.  Value is true if SPEC is valid.  */
@@ -3249,7 +3248,6 @@ void move_it_in_display_line (struct it *it,
                              enum move_operation_enum op);
 bool in_display_vector_p (struct it *);
 int frame_mode_line_height (struct frame *);
-extern Lisp_Object Qtool_bar;
 extern bool redisplaying_p;
 extern bool help_echo_showing_p;
 extern Lisp_Object help_echo_string, help_echo_window;
@@ -3429,7 +3427,6 @@ int face_at_string_position (struct window *w, 
Lisp_Object string,
 int merge_faces (struct frame *, Lisp_Object, int, int);
 int compute_char_face (struct frame *, int, Lisp_Object);
 void free_all_realized_faces (Lisp_Object);
-extern Lisp_Object Qforeground_color, Qbackground_color;
 extern char unspecified_fg[], unspecified_bg[];
 
 /* Defined in xfns.c.  */
@@ -3519,7 +3516,6 @@ void do_pending_window_change (bool);
 void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
 void init_display (void);
 void syms_of_display (void);
-extern Lisp_Object Qredisplay_dont_pause;
 extern void spec_glyph_lookup_face (struct window *, GLYPH *);
 extern void fill_up_frame_row_with_spaces (struct glyph_row *, int);
 
diff --git a/src/dispnew.c b/src/dispnew.c
index 6e0fcc3..bb75973 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -106,8 +106,6 @@ static void set_window_update_flags (struct window *w, bool 
on_p);
 
 bool display_completed;
 
-Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
-
 /* True means SIGWINCH happened when not safe.  */
 
 static bool delayed_size_change;
@@ -5177,7 +5175,7 @@ buffer_posn_from_coords (struct window *w, int *x, int 
*y, struct display_pos *p
 
   Fset_buffer (old_current_buffer);
 
-  *dx = x0 + it.first_visible_x - it.current_x;
+  *dx = to_x - it.current_x;
   *dy = *y - it.current_y;
 
   string = w->contents;
@@ -5252,9 +5250,9 @@ buffer_posn_from_coords (struct window *w, int *x, int 
*y, struct display_pos *p
     }
 
   /* Add extra (default width) columns if clicked after EOL. */
-  x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x);
-  if (x0 > x1)
-    it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
+  x1 = max (0, it.current_x + it.pixel_width);
+  if (to_x > x1)
+    it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
 
   *x = it.hpos;
   *y = it.vpos;
@@ -6204,7 +6202,9 @@ syms_of_display (void)
   frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
   staticpro (&frame_and_buffer_state);
 
+  /* This is the "purpose" slot of a display table.  */
   DEFSYM (Qdisplay_table, "display-table");
+
   DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
 
   DEFVAR_INT ("baud-rate", baud_rate,
diff --git a/src/disptab.h b/src/disptab.h
index cea040f..7afc862 100644
--- a/src/disptab.h
+++ b/src/disptab.h
@@ -48,9 +48,6 @@ extern struct Lisp_Char_Table *window_display_table (struct 
window *);
 /* Defined in indent.c.  */
 extern struct Lisp_Char_Table *buffer_display_table (void);
 
-/* This is the `purpose' slot of a display table.  */
-extern Lisp_Object Qdisplay_table;
-
 /* Return the current length of the GLYPH table,
    or 0 if the table isn't currently valid.  */
 #define GLYPH_TABLE_LENGTH  \
diff --git a/src/doc.c b/src/doc.c
index 3359444..a6ef84b 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -35,8 +35,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "keyboard.h"
 #include "keymap.h"
 
-Lisp_Object Qfunction_documentation;
-
 /* Buffer used for reading from documentation file.  */
 static char *get_doc_string_buffer;
 static ptrdiff_t get_doc_string_buffer_size;
diff --git a/src/dosfns.c b/src/dosfns.c
index 8c0fed2..e506e9f 100644
--- a/src/dosfns.c
+++ b/src/dosfns.c
@@ -409,8 +409,6 @@ msdos_stdcolor_idx (const char *name)
 Lisp_Object
 msdos_stdcolor_name (int idx)
 {
-  extern Lisp_Object Qunspecified;
-
   if (idx == FACE_TTY_DEFAULT_FG_COLOR)
     return build_string (unspecified_fg);
   else if (idx == FACE_TTY_DEFAULT_BG_COLOR)
diff --git a/src/editfns.c b/src/editfns.c
index 37f85b3..cd15f65 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -76,16 +76,6 @@ static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
 # define HAVE_TM_GMTOFF false
 #endif
 
-static Lisp_Object Qbuffer_access_fontify_functions;
-
-/* Symbol for the text property used to mark fields.  */
-
-Lisp_Object Qfield;
-
-/* A special value for Qfield properties.  */
-
-static Lisp_Object Qboundary;
-
 /* The startup value of the TZ environment variable; null if unset.  */
 static char const *initial_tz;
 
@@ -915,17 +905,11 @@ save_excursion_restore (Lisp_Object info)
   if (! NILP (tem))
     {
       if (! EQ (omark, nmark))
-        {
-          tem = intern ("activate-mark-hook");
-          Frun_hooks (1, &tem);
-        }
+       run_hook (intern ("activate-mark-hook"));
     }
   /* If mark has ceased to be active, run deactivate hook.  */
   else if (! NILP (tem1))
-    {
-      tem = intern ("deactivate-mark-hook");
-      Frun_hooks (1, &tem);
-    }
+    run_hook (intern ("deactivate-mark-hook"));
 
   /* If buffer was visible in a window, and a different window was
      selected, and the old selected window is still showing this
@@ -5009,8 +4993,12 @@ functions if all the text being accessed has this 
property.  */);
   defsubr (&Sregion_beginning);
   defsubr (&Sregion_end);
 
+  /* Symbol for the text property used to mark fields.  */
   DEFSYM (Qfield, "field");
+
+  /* A special value for Qfield properties.  */
   DEFSYM (Qboundary, "boundary");
+
   defsubr (&Sfield_beginning);
   defsubr (&Sfield_end);
   defsubr (&Sfield_string);
diff --git a/src/emacs.c b/src/emacs.c
index e7131c0..e7094b1 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -151,13 +151,6 @@ static bool malloc_using_checking;
 extern void malloc_enable_thread (void);
 #endif
 
-Lisp_Object Qfile_name_handler_alist;
-
-Lisp_Object Qrisky_local_variable;
-
-Lisp_Object Qkill_emacs;
-static Lisp_Object Qkill_emacs_hook;
-
 /* If true, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
 bool inhibit_window_system;
@@ -1919,7 +1912,7 @@ all of which are called before Emacs is actually killed.  
*/)
   /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
      set.  */
   waiting_for_input = 0;
-  Frun_hooks (1, &Qkill_emacs_hook);
+  run_hook (Qkill_emacs_hook);
   UNGCPRO;
 
 #ifdef HAVE_X_WINDOWS
diff --git a/src/eval.c b/src/eval.c
index 4748712..7e4b016 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -38,22 +38,6 @@ struct handler *handlerlist;
 int gcpro_level;
 #endif
 
-Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp;
-Lisp_Object Qinhibit_quit;
-Lisp_Object Qand_rest;
-static Lisp_Object Qand_optional;
-static Lisp_Object Qinhibit_debugger;
-static Lisp_Object Qdeclare;
-Lisp_Object Qinternal_interpreter_environment, Qclosure;
-
-static Lisp_Object Qdebug;
-
-/* This holds either the symbol `run-hooks' or nil.
-   It is nil at an early stage of startup, and when Emacs
-   is shutting down.  */
-
-Lisp_Object Vrun_hooks;
-
 /* Non-nil means record all fset's and provide's, to be undone
    if the file being autoloaded is not fully loaded.
    They are recorded by being consed onto the front of Vautoload_queue:
@@ -61,6 +45,11 @@ Lisp_Object Vrun_hooks;
 
 Lisp_Object Vautoload_queue;
 
+/* This holds either the symbol `run-hooks' or nil.
+   It is nil at an early stage of startup, and when Emacs
+   is shutting down.  */
+Lisp_Object Vrun_hooks;
+
 /* Current number of specbindings allocated in specpdl, not counting
    the dummy entry specpdl[-1].  */
 
@@ -2363,14 +2352,10 @@ Instead, use `add-hook' and specify t for the LOCAL 
argument.
 usage: (run-hooks &rest HOOKS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  Lisp_Object hook[1];
   ptrdiff_t i;
 
   for (i = 0; i < nargs; i++)
-    {
-      hook[0] = args[i];
-      run_hook_with_args (1, hook, funcall_nil);
-    }
+    run_hook (args[i]);
 
   return Qnil;
 }
@@ -2536,6 +2521,14 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
     }
 }
 
+/* Run the hook HOOK, giving each function no args.  */
+
+void
+run_hook (Lisp_Object hook)
+{
+  Frun_hook_with_args (1, &hook);
+}
+
 /* Run the hook HOOK, giving each function the two args ARG1 and ARG2.  */
 
 void
@@ -3762,7 +3755,8 @@ alist of active lexical bindings.  */);
      (Just imagine if someone makes it buffer-local).  */
   Funintern (Qinternal_interpreter_environment, Qnil);
 
-  DEFSYM (Vrun_hooks, "run-hooks");
+  Vrun_hooks = intern_c_string ("run-hooks");
+  staticpro (&Vrun_hooks);
 
   staticpro (&Vautoload_queue);
   Vautoload_queue = Qnil;
diff --git a/src/fileio.c b/src/fileio.c
index 0f0fd1a..15c6f91 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -113,50 +113,10 @@ static bool auto_save_error_occurred;
 static bool valid_timestamp_file_system;
 static dev_t timestamp_file_system;
 
-/* The symbol bound to coding-system-for-read when
-   insert-file-contents is called for recovering a file.  This is not
-   an actual coding system name, but just an indicator to tell
-   insert-file-contents to use `emacs-mule' with a special flag for
-   auto saving and recovering a file.  */
-static Lisp_Object Qauto_save_coding;
-
-/* Property name of a file name handler,
-   which gives a list of operations it handles..  */
-static Lisp_Object Qoperations;
-
-/* Lisp functions for translating file formats.  */
-static Lisp_Object Qformat_decode, Qformat_annotate_function;
-
-/* Lisp function for setting buffer-file-coding-system and the
-   multibyteness of the current buffer after inserting a file.  */
-static Lisp_Object Qafter_insert_file_set_coding;
-
-static Lisp_Object Qwrite_region_annotate_functions;
 /* Each time an annotation function changes the buffer, the new buffer
    is added here.  */
 static Lisp_Object Vwrite_region_annotation_buffers;
 
-static Lisp_Object Qdelete_by_moving_to_trash;
-
-/* Lisp function for moving files to trash.  */
-static Lisp_Object Qmove_file_to_trash;
-
-/* Lisp function for recursively copying directories.  */
-static Lisp_Object Qcopy_directory;
-
-/* Lisp function for recursively deleting directories.  */
-static Lisp_Object Qdelete_directory;
-
-static Lisp_Object Qsubstitute_env_in_file_name;
-static Lisp_Object Qget_buffer_window_list;
-
-Lisp_Object Qfile_error, Qfile_notify_error;
-static Lisp_Object Qfile_already_exists, Qfile_date_error;
-static Lisp_Object Qexcl;
-Lisp_Object Qfile_name_history;
-
-static Lisp_Object Qcar_less_than_car;
-
 static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
                     Lisp_Object *, struct coding_system *);
 static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
@@ -291,43 +251,6 @@ restore_point_unwind (Lisp_Object location)
 }
 
 
-static Lisp_Object Qexpand_file_name;
-static Lisp_Object Qsubstitute_in_file_name;
-static Lisp_Object Qdirectory_file_name;
-static Lisp_Object Qfile_name_directory;
-static Lisp_Object Qfile_name_nondirectory;
-static Lisp_Object Qunhandled_file_name_directory;
-static Lisp_Object Qfile_name_as_directory;
-static Lisp_Object Qcopy_file;
-static Lisp_Object Qmake_directory_internal;
-static Lisp_Object Qmake_directory;
-static Lisp_Object Qdelete_directory_internal;
-Lisp_Object Qdelete_file;
-static Lisp_Object Qrename_file;
-static Lisp_Object Qadd_name_to_file;
-static Lisp_Object Qmake_symbolic_link;
-Lisp_Object Qfile_exists_p;
-static Lisp_Object Qfile_executable_p;
-static Lisp_Object Qfile_readable_p;
-static Lisp_Object Qfile_writable_p;
-static Lisp_Object Qfile_symlink_p;
-static Lisp_Object Qaccess_file;
-Lisp_Object Qfile_directory_p;
-static Lisp_Object Qfile_regular_p;
-static Lisp_Object Qfile_accessible_directory_p;
-static Lisp_Object Qfile_modes;
-static Lisp_Object Qset_file_modes;
-static Lisp_Object Qset_file_times;
-static Lisp_Object Qfile_selinux_context;
-static Lisp_Object Qset_file_selinux_context;
-static Lisp_Object Qfile_acl;
-static Lisp_Object Qset_file_acl;
-static Lisp_Object Qfile_newer_than_file_p;
-Lisp_Object Qinsert_file_contents;
-Lisp_Object Qwrite_region;
-static Lisp_Object Qverify_visited_file_modtime;
-static Lisp_Object Qset_visited_file_modtime;
-
 DEFUN ("find-file-name-handler", Ffind_file_name_handler,
        Sfind_file_name_handler, 2, 2, 0,
        doc: /* Return FILENAME's handler function for OPERATION, if it has one.
@@ -5866,7 +5789,10 @@ init_fileio (void)
 void
 syms_of_fileio (void)
 {
+  /* Property name of a file name handler,
+     which gives a list of operations it handles.  */
   DEFSYM (Qoperations, "operations");
+
   DEFSYM (Qexpand_file_name, "expand-file-name");
   DEFSYM (Qsubstitute_in_file_name, "substitute-in-file-name");
   DEFSYM (Qdirectory_file_name, "directory-file-name");
@@ -5903,6 +5829,12 @@ syms_of_fileio (void)
   DEFSYM (Qwrite_region, "write-region");
   DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime");
   DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime");
+
+  /* The symbol bound to coding-system-for-read when
+     insert-file-contents is called for recovering a file.  This is not
+     an actual coding system name, but just an indicator to tell
+     insert-file-contents to use `emacs-mule' with a special flag for
+     auto saving and recovering a file.  */
   DEFSYM (Qauto_save_coding, "auto-save-coding");
 
   DEFSYM (Qfile_name_history, "file-name-history");
@@ -5938,9 +5870,14 @@ On MS-Windows, the value of this variable is largely 
ignored if
 behaves as if file names were encoded in `utf-8'.  */);
   Vdefault_file_name_coding_system = Qnil;
 
+  /* Lisp functions for translating file formats.  */
   DEFSYM (Qformat_decode, "format-decode");
   DEFSYM (Qformat_annotate_function, "format-annotate-function");
+
+  /* Lisp function for setting buffer-file-coding-system and the
+     multibyteness of the current buffer after inserting a file.  */
   DEFSYM (Qafter_insert_file_set_coding, "after-insert-file-set-coding");
+
   DEFSYM (Qcar_less_than_car, "car-less-than-car");
 
   Fput (Qfile_error, Qerror_conditions,
@@ -6094,11 +6031,17 @@ When non-nil, certain file deletion commands use the 
function
 This includes interactive calls to `delete-file' and
 `delete-directory' and the Dired deletion commands.  */);
   delete_by_moving_to_trash = 0;
-  Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
+  DEFSYM (Qdelete_by_moving_to_trash, "delete-by-moving-to-trash");
 
+  /* Lisp function for moving files to trash.  */
   DEFSYM (Qmove_file_to_trash, "move-file-to-trash");
+
+  /* Lisp function for recursively copying directories.  */
   DEFSYM (Qcopy_directory, "copy-directory");
+
+  /* Lisp function for recursively deleting directories.  */
   DEFSYM (Qdelete_directory, "delete-directory");
+
   DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name");
   DEFSYM (Qget_buffer_window_list, "get-buffer-window-list");
 
diff --git a/src/fns.c b/src/fns.c
index 9c9501a..7739663 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -41,16 +41,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "xterm.h"
 #endif
 
-Lisp_Object Qstring_lessp;
-static Lisp_Object Qstring_collate_lessp, Qstring_collate_equalp;
-static Lisp_Object Qprovide, Qrequire;
-static Lisp_Object Qyes_or_no_p_history;
-Lisp_Object Qcursor_in_echo_area;
-static Lisp_Object Qwidget_type;
-static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
-
-static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
-
 static void sort_vector_copy (Lisp_Object, ptrdiff_t,
                              Lisp_Object [restrict], Lisp_Object [restrict]);
 static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object);
@@ -2788,8 +2778,6 @@ advisable.  */)
   return ret;
 }
 
-static Lisp_Object Qsubfeatures;
-
 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
        doc: /* Return t if FEATURE is present in this Emacs.
 
@@ -2808,8 +2796,6 @@ SUBFEATURE can be used to check a specific subfeature of 
FEATURE.  */)
   return (NILP (tem)) ? Qnil : Qt;
 }
 
-static Lisp_Object Qfuncall;
-
 DEFUN ("provide", Fprovide, Sprovide, 1, 2, 0,
        doc: /* Announce that FEATURE is a feature of the current Emacs.
 The optional argument SUBFEATURES should be a list of symbols listing
@@ -3596,14 +3582,6 @@ base64_decode_1 (const char *from, char *to, ptrdiff_t 
length,
 
 static struct Lisp_Hash_Table *weak_hash_tables;
 
-/* Various symbols.  */
-
-static Lisp_Object Qhash_table_p;
-static Lisp_Object Qkey, Qvalue, Qeql;
-Lisp_Object Qeq, Qequal;
-Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
-static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
-
 
 /***********************************************************************
                               Utilities
diff --git a/src/font.c b/src/font.c
index dea18a1..a68c3c7 100644
--- a/src/font.c
+++ b/src/font.c
@@ -41,16 +41,8 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-Lisp_Object Qopentype;
-
-/* Important character set strings.  */
-Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
-
 #define DEFAULT_ENCODING Qiso8859_1
 
-/* Unicode category `Cf'.  */
-static Lisp_Object QCf;
-
 /* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */
 static Lisp_Object font_style_table;
 
@@ -110,21 +102,6 @@ static const struct table_entry width_table[] =
   { 200, { "ultra-expanded", "ultraexpanded", "wide" }}
 };
 
-Lisp_Object QCfoundry;
-static Lisp_Object QCadstyle, QCregistry;
-/* Symbols representing keys of font extra info.  */
-Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth;
-Lisp_Object QCantialias, QCfont_entity;
-static Lisp_Object QCfc_unknown_spec;
-/* Symbols representing values of font spacing property.  */
-static Lisp_Object Qc, Qm, Qd;
-Lisp_Object Qp;
-/* Special ADSTYLE properties to avoid fonts used for Latin
-   characters; used in xfont.c and ftfont.c.  */
-Lisp_Object Qja, Qko;
-
-static Lisp_Object QCuser_spec;
-
 /* Alist of font registry symbols and the corresponding charset
    information.  The information is retrieved from
    Vfont_encoding_alist on demand.
@@ -309,7 +286,7 @@ font_intern_prop (const char *str, ptrdiff_t len, bool 
force_symbol)
     return tem;
   name = make_specified_string (str, nchars, len,
                                len != nchars && len == nbytes);
-  return intern_driver (name, obarray, XINT (tem));
+  return intern_driver (name, obarray, tem);
 }
 
 /* Return a pixel size of font-spec SPEC on frame F.  */
@@ -662,30 +639,30 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val)
    values.  */
 static const struct
 {
-  /* Pointer to the key symbol.  */
-  Lisp_Object *key;
+  /* Index of the key symbol.  */
+  int key;
   /* Function to validate PROP's value VAL, or NULL if any value is
      ok.  The value is VAL or its regularized value if VAL is valid,
      and Qerror if not.  */
   Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val);
 } font_property_table[] =
-  { { &QCtype, font_prop_validate_symbol },
-    { &QCfoundry, font_prop_validate_symbol },
-    { &QCfamily, font_prop_validate_symbol },
-    { &QCadstyle, font_prop_validate_symbol },
-    { &QCregistry, font_prop_validate_symbol },
-    { &QCweight, font_prop_validate_style },
-    { &QCslant, font_prop_validate_style },
-    { &QCwidth, font_prop_validate_style },
-    { &QCsize, font_prop_validate_non_neg },
-    { &QCdpi, font_prop_validate_non_neg },
-    { &QCspacing, font_prop_validate_spacing },
-    { &QCavgwidth, font_prop_validate_non_neg },
+  { { SYMBOL_INDEX (QCtype), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCfoundry), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCfamily), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCadstyle), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCregistry), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCweight), font_prop_validate_style },
+    { SYMBOL_INDEX (QCslant), font_prop_validate_style },
+    { SYMBOL_INDEX (QCwidth), font_prop_validate_style },
+    { SYMBOL_INDEX (QCsize), font_prop_validate_non_neg },
+    { SYMBOL_INDEX (QCdpi), font_prop_validate_non_neg },
+    { SYMBOL_INDEX (QCspacing), font_prop_validate_spacing },
+    { SYMBOL_INDEX (QCavgwidth), font_prop_validate_non_neg },
     /* The order of the above entries must match with enum
        font_property_index.  */
-    { &QClang, font_prop_validate_symbol },
-    { &QCscript, font_prop_validate_symbol },
-    { &QCotf, font_prop_validate_otf }
+    { SYMBOL_INDEX (QClang), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCscript), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCotf), font_prop_validate_otf }
   };
 
 /* Return an index number of font property KEY or -1 if KEY is not an
@@ -697,7 +674,7 @@ get_font_prop_index (Lisp_Object key)
   int i;
 
   for (i = 0; i < ARRAYELTS (font_property_table); i++)
-    if (EQ (key, *font_property_table[i].key))
+    if (EQ (key, builtin_lisp_symbol (font_property_table[i].key)))
       return i;
   return -1;
 }
@@ -714,7 +691,7 @@ font_prop_validate (int idx, Lisp_Object prop, Lisp_Object 
val)
   if (NILP (val))
     return val;
   if (NILP (prop))
-    prop = *font_property_table[idx].key;
+    prop = builtin_lisp_symbol (font_property_table[idx].key);
   else
     {
       idx = get_font_prop_index (prop);
@@ -5169,19 +5146,21 @@ syms_of_font (void)
 
   DEFSYM (Qopentype, "opentype");
 
+  /* Important character set symbols.  */
   DEFSYM (Qascii_0, "ascii-0");
   DEFSYM (Qiso8859_1, "iso8859-1");
   DEFSYM (Qiso10646_1, "iso10646-1");
   DEFSYM (Qunicode_bmp, "unicode-bmp");
   DEFSYM (Qunicode_sip, "unicode-sip");
 
+  /* Unicode category `Cf'.  */
   DEFSYM (QCf, "Cf");
 
+  /* Symbols representing keys of font extra info.  */
   DEFSYM (QCotf, ":otf");
   DEFSYM (QClang, ":lang");
   DEFSYM (QCscript, ":script");
   DEFSYM (QCantialias, ":antialias");
-
   DEFSYM (QCfoundry, ":foundry");
   DEFSYM (QCadstyle, ":adstyle");
   DEFSYM (QCregistry, ":registry");
@@ -5192,11 +5171,14 @@ syms_of_font (void)
   DEFSYM (QCfont_entity, ":font-entity");
   DEFSYM (QCfc_unknown_spec, ":fc-unknown-spec");
 
+  /* Symbols representing values of font spacing property.  */
   DEFSYM (Qc, "c");
   DEFSYM (Qm, "m");
   DEFSYM (Qp, "p");
   DEFSYM (Qd, "d");
 
+  /* Special ADSTYLE properties to avoid fonts used for Latin
+     characters; used in xfont.c and ftfont.c.  */
   DEFSYM (Qja, "ja");
   DEFSYM (Qko, "ko");
 
diff --git a/src/font.h b/src/font.h
index 617860c..5a3e38a 100644
--- a/src/font.h
+++ b/src/font.h
@@ -56,7 +56,6 @@ INLINE_HEADER_BEGIN
        Note: Only the method `open' of a font-driver can create this
        object, and it should never be modified by Lisp.  */
 
-extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
 
 /* An enumerator for each font property.  This is used as an index to
    the vector of FONT-SPEC and FONT-ENTITY.
@@ -239,17 +238,6 @@ enum font_property_index
 #define FONT_BASE(f) ((f)->ascent)
 #define FONT_DESCENT(f) ((f)->descent)
 
-extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript;
-extern Lisp_Object QCavgwidth, QCantialias, QCfont_entity;
-extern Lisp_Object Qp;
-
-
-/* Important character set symbols.  */
-extern Lisp_Object Qascii_0;
-extern Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
-
-/* Special ADSTYLE properties to avoid fonts used for Latin characters.  */
-extern Lisp_Object Qja, Qko;
 
 /* Structure for a font-spec.  */
 
@@ -791,12 +779,11 @@ extern struct font_driver xfont_driver;
 extern void syms_of_xfont (void);
 extern void syms_of_ftxfont (void);
 #ifdef HAVE_XFT
-extern Lisp_Object Qxft;
 extern struct font_driver xftfont_driver;
-extern void syms_of_xftfont (void);
 #endif
 #if defined HAVE_FREETYPE || defined HAVE_XFT
 extern struct font_driver ftxfont_driver;
+extern void syms_of_xftfont (void);
 #endif
 #ifdef HAVE_BDFFONT
 extern void syms_of_bdffont (void);
@@ -808,7 +795,6 @@ extern struct font_driver uniscribe_font_driver;
 extern void syms_of_w32font (void);
 #endif /* HAVE_NTGUI */
 #ifdef HAVE_NS
-extern Lisp_Object Qfontsize;
 extern struct font_driver nsfont_driver;
 extern void syms_of_nsfont (void);
 extern void syms_of_macfont (void);
@@ -818,8 +804,6 @@ extern void syms_of_macfont (void);
 #define FONT_DEBUG
 #endif
 
-extern Lisp_Object QCfoundry;
-
 extern void font_add_log (const char *, Lisp_Object, Lisp_Object);
 extern void font_deferred_log (const char *, Lisp_Object, Lisp_Object);
 
diff --git a/src/fontset.c b/src/fontset.c
index 974b144..b257da1 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -152,11 +152,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 /********** VARIABLES and FUNCTION PROTOTYPES **********/
 
-static Lisp_Object Qfontset;
-static Lisp_Object Qfontset_info;
-static Lisp_Object Qprepend, Qappend;
-Lisp_Object Qlatin;
-
 /* Vector containing all fontsets.  */
 static Lisp_Object Vfontset_table;
 
diff --git a/src/fontset.h b/src/fontset.h
index e743555..6103944 100644
--- a/src/fontset.h
+++ b/src/fontset.h
@@ -36,7 +36,6 @@ extern int fontset_from_font (Lisp_Object);
 extern int fs_query_fontset (Lisp_Object, int);
 extern Lisp_Object list_fontsets (struct frame *, Lisp_Object, int);
 
-extern Lisp_Object Qlatin;
 extern Lisp_Object fontset_name (int);
 extern Lisp_Object fontset_ascii (int);
 
diff --git a/src/frame.c b/src/frame.c
index 9394ae4..3d2ffbf 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -55,76 +55,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "widget.h"
 #endif
 
-#ifdef HAVE_NS
-Lisp_Object Qns_parse_geometry;
-#endif
-
-Lisp_Object Qframep, Qframe_live_p;
-Lisp_Object Qicon, Qmodeline;
-Lisp_Object Qonly, Qnone;
-Lisp_Object Qx, Qw32, Qpc, Qns;
-Lisp_Object Qvisible;
-Lisp_Object Qdisplay_type;
-static Lisp_Object Qbackground_mode;
-Lisp_Object Qnoelisp;
-
-static Lisp_Object Qx_frame_parameter;
-Lisp_Object Qx_resource_name;
-Lisp_Object Qterminal;
-
-/* Frame parameters (set or reported).  */
-
-Lisp_Object Qauto_raise, Qauto_lower;
-Lisp_Object Qborder_color, Qborder_width;
-Lisp_Object Qcursor_color, Qcursor_type;
-Lisp_Object Qheight, Qwidth;
-Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
-Lisp_Object Qtooltip;
-Lisp_Object Qinternal_border_width;
-Lisp_Object Qright_divider_width, Qbottom_divider_width;
-Lisp_Object Qmouse_color;
-Lisp_Object Qminibuffer;
-Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
-Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars;
-Lisp_Object Qvisibility;
-Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
-Lisp_Object Qscreen_gamma;
-Lisp_Object Qline_spacing;
-static Lisp_Object Quser_position, Quser_size;
-Lisp_Object Qwait_for_wm;
-static Lisp_Object Qwindow_id;
-#ifdef HAVE_X_WINDOWS
-static Lisp_Object Qouter_window_id;
-#endif
-Lisp_Object Qparent_id;
-Lisp_Object Qtitle, Qname;
-static Lisp_Object Qexplicit_name;
-Lisp_Object Qunsplittable;
-Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
-Lisp_Object Qleft_fringe, Qright_fringe;
-Lisp_Object Qbuffer_predicate;
-static Lisp_Object Qbuffer_list, Qburied_buffer_list;
-Lisp_Object Qtty_color_mode;
-Lisp_Object Qtty, Qtty_type;
-
-Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
-Lisp_Object Qsticky;
-Lisp_Object Qfont_backend;
-Lisp_Object Qalpha;
-
-Lisp_Object Qface_set_after_frame_default;
-
-static Lisp_Object Qfocus_in_hook;
-static Lisp_Object Qfocus_out_hook;
-static Lisp_Object Qdelete_frame_functions;
-static Lisp_Object Qframe_windows_min_size;
-static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
-
-Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
-Lisp_Object Qexternal_border_size, Qtitle_height;
-Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
-Lisp_Object Qtool_bar_external, Qtool_bar_size;
-
 /* The currently selected frame.  */
 
 Lisp_Object selected_frame;
@@ -1221,7 +1151,7 @@ to that frame.  */)
 {
   /* Preserve prefix arg that the command loop just cleared.  */
   kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
-  Frun_hooks (1, &Qmouse_leave_buffer_hook);
+  run_hook (Qmouse_leave_buffer_hook);
   /* `switch-frame' implies a focus in.  */
   call1 (intern ("handle-focus-in"), event);
   return do_switch_frame (event, 0, 0, Qnil);
@@ -2995,48 +2925,48 @@ or bottommost possible position (that stays within the 
screen).  */)
 
 struct frame_parm_table {
   const char *name;
-  Lisp_Object *variable;
+  int sym;
 };
 
 static const struct frame_parm_table frame_parms[] =
 {
-  {"auto-raise",               &Qauto_raise},
-  {"auto-lower",               &Qauto_lower},
-  {"background-color",         0},
-  {"border-color",             &Qborder_color},
-  {"border-width",             &Qborder_width},
-  {"cursor-color",             &Qcursor_color},
-  {"cursor-type",              &Qcursor_type},
-  {"font",                     0},
-  {"foreground-color",         0},
-  {"icon-name",                        &Qicon_name},
-  {"icon-type",                        &Qicon_type},
-  {"internal-border-width",    &Qinternal_border_width},
-  {"right-divider-width",      &Qright_divider_width},
-  {"bottom-divider-width",     &Qbottom_divider_width},
-  {"menu-bar-lines",           &Qmenu_bar_lines},
-  {"mouse-color",              &Qmouse_color},
-  {"name",                     &Qname},
-  {"scroll-bar-width",         &Qscroll_bar_width},
-  {"scroll-bar-height",                &Qscroll_bar_height},
-  {"title",                    &Qtitle},
-  {"unsplittable",             &Qunsplittable},
-  {"vertical-scroll-bars",     &Qvertical_scroll_bars},
-  {"horizontal-scroll-bars",   &Qhorizontal_scroll_bars},
-  {"visibility",               &Qvisibility},
-  {"tool-bar-lines",           &Qtool_bar_lines},
-  {"scroll-bar-foreground",    &Qscroll_bar_foreground},
-  {"scroll-bar-background",    &Qscroll_bar_background},
-  {"screen-gamma",             &Qscreen_gamma},
-  {"line-spacing",             &Qline_spacing},
-  {"left-fringe",              &Qleft_fringe},
-  {"right-fringe",             &Qright_fringe},
-  {"wait-for-wm",              &Qwait_for_wm},
-  {"fullscreen",                &Qfullscreen},
-  {"font-backend",             &Qfont_backend},
-  {"alpha",                    &Qalpha},
-  {"sticky",                   &Qsticky},
-  {"tool-bar-position",                &Qtool_bar_position},
+  {"auto-raise",               SYMBOL_INDEX (Qauto_raise)},
+  {"auto-lower",               SYMBOL_INDEX (Qauto_lower)},
+  {"background-color",         -1},
+  {"border-color",             SYMBOL_INDEX (Qborder_color)},
+  {"border-width",             SYMBOL_INDEX (Qborder_width)},
+  {"cursor-color",             SYMBOL_INDEX (Qcursor_color)},
+  {"cursor-type",              SYMBOL_INDEX (Qcursor_type)},
+  {"font",                     -1},
+  {"foreground-color",         -1},
+  {"icon-name",                        SYMBOL_INDEX (Qicon_name)},
+  {"icon-type",                        SYMBOL_INDEX (Qicon_type)},
+  {"internal-border-width",    SYMBOL_INDEX (Qinternal_border_width)},
+  {"right-divider-width",      SYMBOL_INDEX (Qright_divider_width)},
+  {"bottom-divider-width",     SYMBOL_INDEX (Qbottom_divider_width)},
+  {"menu-bar-lines",           SYMBOL_INDEX (Qmenu_bar_lines)},
+  {"mouse-color",              SYMBOL_INDEX (Qmouse_color)},
+  {"name",                     SYMBOL_INDEX (Qname)},
+  {"scroll-bar-width",         SYMBOL_INDEX (Qscroll_bar_width)},
+  {"scroll-bar-height",                SYMBOL_INDEX (Qscroll_bar_height)},
+  {"title",                    SYMBOL_INDEX (Qtitle)},
+  {"unsplittable",             SYMBOL_INDEX (Qunsplittable)},
+  {"vertical-scroll-bars",     SYMBOL_INDEX (Qvertical_scroll_bars)},
+  {"horizontal-scroll-bars",   SYMBOL_INDEX (Qhorizontal_scroll_bars)},
+  {"visibility",               SYMBOL_INDEX (Qvisibility)},
+  {"tool-bar-lines",           SYMBOL_INDEX (Qtool_bar_lines)},
+  {"scroll-bar-foreground",    SYMBOL_INDEX (Qscroll_bar_foreground)},
+  {"scroll-bar-background",    SYMBOL_INDEX (Qscroll_bar_background)},
+  {"screen-gamma",             SYMBOL_INDEX (Qscreen_gamma)},
+  {"line-spacing",             SYMBOL_INDEX (Qline_spacing)},
+  {"left-fringe",              SYMBOL_INDEX (Qleft_fringe)},
+  {"right-fringe",             SYMBOL_INDEX (Qright_fringe)},
+  {"wait-for-wm",              SYMBOL_INDEX (Qwait_for_wm)},
+  {"fullscreen",                SYMBOL_INDEX (Qfullscreen)},
+  {"font-backend",             SYMBOL_INDEX (Qfont_backend)},
+  {"alpha",                    SYMBOL_INDEX (Qalpha)},
+  {"sticky",                   SYMBOL_INDEX (Qsticky)},
+  {"tool-bar-position",                SYMBOL_INDEX (Qtool_bar_position)},
 };
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -4854,17 +4784,49 @@ syms_of_frame (void)
   DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
 #endif
 
+  DEFSYM (Qalpha, "alpha");
+  DEFSYM (Qauto_lower, "auto-lower");
+  DEFSYM (Qauto_raise, "auto-raise");
+  DEFSYM (Qborder_color, "border-color");
+  DEFSYM (Qborder_width, "border-width");
+  DEFSYM (Qbottom_divider_width, "bottom-divider-width");
+  DEFSYM (Qcursor_color, "cursor-color");
+  DEFSYM (Qcursor_type, "cursor-type");
+  DEFSYM (Qfont_backend, "font-backend");
+  DEFSYM (Qfullscreen, "fullscreen");
+  DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars");
+  DEFSYM (Qicon_name, "icon-name");
+  DEFSYM (Qicon_type, "icon-type");
+  DEFSYM (Qinternal_border_width, "internal-border-width");
+  DEFSYM (Qleft_fringe, "left-fringe");
+  DEFSYM (Qline_spacing, "line-spacing");
+  DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
+  DEFSYM (Qmouse_color, "mouse-color");
+  DEFSYM (Qname, "name");
+  DEFSYM (Qright_divider_width, "right-divider-width");
+  DEFSYM (Qright_fringe, "right-fringe");
+  DEFSYM (Qscreen_gamma, "screen-gamma");
+  DEFSYM (Qscroll_bar_background, "scroll-bar-background");
+  DEFSYM (Qscroll_bar_foreground, "scroll-bar-foreground");
+  DEFSYM (Qscroll_bar_height, "scroll-bar-height");
+  DEFSYM (Qscroll_bar_width, "scroll-bar-width");
+  DEFSYM (Qsticky, "sticky");
+  DEFSYM (Qtitle, "title");
+  DEFSYM (Qtool_bar_lines, "tool-bar-lines");
+  DEFSYM (Qtool_bar_position, "tool-bar-position");
+  DEFSYM (Qunsplittable, "unsplittable");
+  DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars");
+  DEFSYM (Qvisibility, "visibility");
+  DEFSYM (Qwait_for_wm, "wait-for-wm");
+
   {
     int i;
 
     for (i = 0; i < ARRAYELTS (frame_parms); i++)
       {
-       Lisp_Object v = intern_c_string (frame_parms[i].name);
-       if (frame_parms[i].variable)
-         {
-           *frame_parms[i].variable = v;
-           staticpro (frame_parms[i].variable);
-         }
+       Lisp_Object v = (frame_parms[i].sym < 0
+                        ? intern_c_string (frame_parms[i].name)
+                        : builtin_lisp_symbol (frame_parms[i].sym));
        Fput (v, Qx_frame_parameter, make_number (i));
       }
   }
diff --git a/src/frame.h b/src/frame.h
index 80603ce..d1ed4d4 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1095,11 +1095,6 @@ SET_FRAME_VISIBLE (struct frame *f, int v)
   (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i))
 
 extern Lisp_Object selected_frame;
-extern Lisp_Object Qframep, Qframe_live_p;
-extern Lisp_Object Qtty, Qtty_type;
-extern Lisp_Object Qtty_color_mode;
-extern Lisp_Object Qterminal;
-extern Lisp_Object Qnoelisp;
 
 extern struct frame *decode_window_system_frame (Lisp_Object);
 extern struct frame *decode_live_frame (Lisp_Object);
@@ -1344,51 +1339,6 @@ extern Lisp_Object Vframe_list;
                                Frame Parameters
  ***********************************************************************/
 
-extern Lisp_Object Qauto_raise, Qauto_lower;
-extern Lisp_Object Qborder_color, Qborder_width;
-extern Lisp_Object Qbuffer_predicate;
-extern Lisp_Object Qcursor_color, Qcursor_type;
-extern Lisp_Object Qfont;
-extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top;
-extern Lisp_Object Qinternal_border_width;
-extern Lisp_Object Qright_divider_width, Qbottom_divider_width;
-extern Lisp_Object Qtooltip;
-extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
-extern Lisp_Object Qmouse_color;
-extern Lisp_Object Qname, Qtitle;
-extern Lisp_Object Qparent_id;
-extern Lisp_Object Qunsplittable, Qvisibility;
-extern Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
-extern Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars;
-extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
-extern Lisp_Object Qscreen_gamma;
-extern Lisp_Object Qline_spacing;
-extern Lisp_Object Qwait_for_wm;
-extern Lisp_Object Qfullscreen;
-extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
-extern Lisp_Object Qsticky;
-extern Lisp_Object Qfont_backend;
-extern Lisp_Object Qalpha;
-
-extern Lisp_Object Qleft_fringe, Qright_fringe;
-extern Lisp_Object Qheight, Qwidth;
-extern Lisp_Object Qminibuffer, Qmodeline;
-extern Lisp_Object Qx, Qw32, Qpc, Qns;
-extern Lisp_Object Qvisible;
-extern Lisp_Object Qdisplay_type;
-
-extern Lisp_Object Qx_resource_name;
-
-extern Lisp_Object Qtop, Qbox, Qbottom;
-extern Lisp_Object Qdisplay;
-
-extern Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
-extern Lisp_Object Qexternal_border_size, Qtitle_height;
-extern Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
-extern Lisp_Object Qtool_bar_external, Qtool_bar_size;
-
-extern Lisp_Object Qrun_hook_with_args;
-
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* The class of this X application.  */
@@ -1399,7 +1349,6 @@ extern void x_set_scroll_bar_default_height (struct frame 
*);
 extern void x_set_offset (struct frame *, int, int, int);
 extern void x_wm_set_size_hint (struct frame *f, long flags, bool 
user_position);
 extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int);
-extern Lisp_Object Qface_set_after_frame_default;
 extern void x_set_frame_parameters (struct frame *, Lisp_Object);
 extern void x_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object);
 extern void x_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object);
diff --git a/src/fringe.c b/src/fringe.c
index 9d393f8..c7262d1 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -65,10 +65,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
    must specify physical bitmap symbols.
 */
 
-static Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow;
-static Lisp_Object Qempty_line, Qtop_bottom;
-static Lisp_Object Qhollow_small;
-
 enum fringe_bitmap_align
 {
   ALIGN_BITMAP_CENTER = 0,
diff --git a/src/ftfont.c b/src/ftfont.c
index 8169806..9707b6c 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -38,12 +38,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "font.h"
 #include "ftfont.h"
 
-/* Symbolic type of this font-driver.  */
-static Lisp_Object Qfreetype;
-
-/* Fontconfig's generic families and their aliases.  */
-static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
-
 /* Flag to tell if FcInit is already called or not.  */
 static bool fc_initialized;
 
@@ -2667,7 +2661,10 @@ ftfont_filter_properties (Lisp_Object font, Lisp_Object 
alist)
 void
 syms_of_ftfont (void)
 {
+  /* Symbolic type of this font-driver.  */
   DEFSYM (Qfreetype, "freetype");
+
+  /* Fontconfig's generic families and their aliases.  */
   DEFSYM (Qmonospace, "monospace");
   DEFSYM (Qsans_serif, "sans-serif");
   DEFSYM (Qserif, "serif");
diff --git a/src/ftxfont.c b/src/ftxfont.c
index 52d8445..cd2bf3e 100644
--- a/src/ftxfont.c
+++ b/src/ftxfont.c
@@ -35,8 +35,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 /* FTX font driver.  */
 
-static Lisp_Object Qftx;
-
 struct font_driver ftxfont_driver;
 
 struct ftxfont_frame_data
diff --git a/src/gfilenotify.c b/src/gfilenotify.c
index 7434a37..e03bec9 100644
--- a/src/gfilenotify.c
+++ b/src/gfilenotify.c
@@ -29,24 +29,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "process.h"
 
 
-/* Subroutines.  */
-static Lisp_Object Qgfile_add_watch;
-static Lisp_Object Qgfile_rm_watch;
-
-/* Filter objects.  */
-static Lisp_Object Qwatch_mounts;      /* G_FILE_MONITOR_WATCH_MOUNTS  */
-static Lisp_Object Qsend_moved;        /* G_FILE_MONITOR_SEND_MOVED  */
-
-/* Event types.  */
-static Lisp_Object Qchanged;           /* G_FILE_MONITOR_EVENT_CHANGED  */
-static Lisp_Object Qchanges_done_hint; /* 
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT  */
-static Lisp_Object Qdeleted;           /* G_FILE_MONITOR_EVENT_DELETED  */
-static Lisp_Object Qcreated;           /* G_FILE_MONITOR_EVENT_CREATED  */
-static Lisp_Object Qattribute_changed; /* 
G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED  */
-static Lisp_Object Qpre_unmount;       /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT  */
-static Lisp_Object Qunmounted;         /* G_FILE_MONITOR_EVENT_UNMOUNTED  */
-static Lisp_Object Qmoved;             /* G_FILE_MONITOR_EVENT_MOVED  */
-
 static Lisp_Object watch_list;
 
 /* This is the callback function for arriving signals from
@@ -95,7 +77,7 @@ dir_monitor_callback (GFileMonitor *monitor,
     }
 
   /* Determine callback function.  */
-  monitor_object = XIL ((intptr_t) monitor);
+  monitor_object = make_pointer_integer (monitor);
   eassert (INTEGERP (monitor_object));
   watch_object = assq_no_quit (monitor_object, watch_list);
 
@@ -164,7 +146,7 @@ FILE is the name of the file whose event is being reported. 
 FILE1
 will be reported only in case of the 'moved' event.  */)
   (Lisp_Object file, Lisp_Object flags, Lisp_Object callback)
 {
-  Lisp_Object watch_descriptor, watch_object;
+  Lisp_Object watch_object;
   GFile *gfile;
   GFileMonitor *monitor;
   GFileMonitorFlags gflags = G_FILE_MONITOR_NONE;
@@ -194,10 +176,9 @@ will be reported only in case of the 'moved' event.  */)
   if (! monitor)
     xsignal2 (Qfile_notify_error, build_string ("Cannot watch file"), file);
 
-  /* On all known glib platforms, converting MONITOR directly to a
-     Lisp_Object value results is a Lisp integer, which is safe.  This
-     assumption is dicey, though, so check it now.  */
-  watch_descriptor = XIL ((intptr_t) monitor);
+  Lisp_Object watch_descriptor = make_pointer_integer (monitor);
+
+  /* Check the dicey assumption that make_pointer_integer is safe.  */
   if (! INTEGERP (watch_descriptor))
     {
       g_object_unref (monitor);
@@ -221,8 +202,6 @@ DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 
1, 1, 0,
 WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.  */)
      (Lisp_Object watch_descriptor)
 {
-  intptr_t int_monitor;
-  GFileMonitor *monitor;
   Lisp_Object watch_object = assq_no_quit (watch_descriptor, watch_list);
 
   if (! CONSP (watch_object))
@@ -230,8 +209,7 @@ WATCH-DESCRIPTOR should be an object returned by 
`gfile-add-watch'.  */)
              watch_descriptor);
 
   eassert (INTEGERP (watch_descriptor));
-  int_monitor = XLI (watch_descriptor);
-  monitor = (GFileMonitor *) int_monitor;
+  GFileMonitor *monitor = XINTPTR (watch_descriptor);
   if (!g_file_monitor_cancel (monitor))
     xsignal2 (Qfile_notify_error, build_string ("Could not rm watch"),
              watch_descriptor);
@@ -258,23 +236,27 @@ globals_of_gfilenotify (void)
 void
 syms_of_gfilenotify (void)
 {
-
   DEFSYM (Qgfile_add_watch, "gfile-add-watch");
   defsubr (&Sgfile_add_watch);
 
   DEFSYM (Qgfile_rm_watch, "gfile-rm-watch");
   defsubr (&Sgfile_rm_watch);
 
-  DEFSYM (Qwatch_mounts, "watch-mounts");
-  DEFSYM (Qsend_moved, "send-moved");
-  DEFSYM (Qchanged, "changed");
+  /* Filter objects.  */
+  DEFSYM (Qwatch_mounts, "watch-mounts"); /* G_FILE_MONITOR_WATCH_MOUNTS  */
+  DEFSYM (Qsend_moved, "send-moved");  /* G_FILE_MONITOR_SEND_MOVED  */
+
+  /* Event types.  */
+  DEFSYM (Qchanged, "changed");        /* G_FILE_MONITOR_EVENT_CHANGED  */
   DEFSYM (Qchanges_done_hint, "changes-done-hint");
-  DEFSYM (Qdeleted, "deleted");
-  DEFSYM (Qcreated, "created");
+                               /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT  */
+  DEFSYM (Qdeleted, "deleted");        /* G_FILE_MONITOR_EVENT_DELETED  */
+  DEFSYM (Qcreated, "created");        /* G_FILE_MONITOR_EVENT_CREATED  */
   DEFSYM (Qattribute_changed, "attribute-changed");
-  DEFSYM (Qpre_unmount, "pre-unmount");
-  DEFSYM (Qunmounted, "unmounted");
-  DEFSYM (Qmoved, "moved");
+                               /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED  */
+  DEFSYM (Qpre_unmount, "pre-unmount");        /* 
G_FILE_MONITOR_EVENT_PRE_UNMOUNT  */
+  DEFSYM (Qunmounted, "unmounted");    /* G_FILE_MONITOR_EVENT_UNMOUNTED  */
+  DEFSYM (Qmoved, "moved");    /* G_FILE_MONITOR_EVENT_MOVED  */
 
   staticpro (&watch_list);
 
diff --git a/src/gnutls.c b/src/gnutls.c
index 4d248f8..75fe614 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -35,28 +35,8 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
 
-static Lisp_Object Qgnutls_dll;
-static Lisp_Object Qgnutls_code;
-static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
-static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
-  Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake;
 static bool gnutls_global_initialized;
 
-/* The following are for the property list of `gnutls-boot'.  */
-static Lisp_Object QCgnutls_bootprop_priority;
-static Lisp_Object QCgnutls_bootprop_trustfiles;
-static Lisp_Object QCgnutls_bootprop_keylist;
-static Lisp_Object QCgnutls_bootprop_crlfiles;
-static Lisp_Object QCgnutls_bootprop_callbacks;
-static Lisp_Object QCgnutls_bootprop_loglevel;
-static Lisp_Object QCgnutls_bootprop_hostname;
-static Lisp_Object QCgnutls_bootprop_min_prime_bits;
-static Lisp_Object QCgnutls_bootprop_verify_flags;
-static Lisp_Object QCgnutls_bootprop_verify_error;
-
-/* Callback keys for `gnutls-boot'.  Unused currently.  */
-static Lisp_Object QCgnutls_bootprop_callbacks_verify;
-
 static void gnutls_log_function (int, const char *);
 static void gnutls_log_function2 (int, const char *, const char *);
 #ifdef HAVE_GNUTLS3
@@ -1656,13 +1636,14 @@ syms_of_gnutls (void)
   DEFSYM (Qgnutls_code, "gnutls-code");
   DEFSYM (Qgnutls_anon, "gnutls-anon");
   DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
+
+  /* The following are for the property list of 'gnutls-boot'.  */
   DEFSYM (QCgnutls_bootprop_hostname, ":hostname");
   DEFSYM (QCgnutls_bootprop_priority, ":priority");
   DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles");
   DEFSYM (QCgnutls_bootprop_keylist, ":keylist");
   DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
   DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks");
-  DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify");
   DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
   DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
   DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
diff --git a/src/image.c b/src/image.c
index 6240c64..5d08a89 100644
--- a/src/image.c
+++ b/src/image.c
@@ -86,12 +86,6 @@ typedef struct w32_bitmap_record Bitmap_Record;
 #define x_defined_color w32_defined_color
 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
 
-/* Versions of libpng, libgif, and libjpeg that we were compiled with,
-   or -1 if no PNG/GIF support was compiled in.  This is tested by
-   w32-win.el to correctly set up the alist used to search for the
-   respective image libraries.  */
-Lisp_Object Qlibpng_version, Qlibgif_version, Qlibjpeg_version;
-
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
@@ -110,11 +104,6 @@ typedef struct ns_bitmap_record Bitmap_Record;
 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
 #endif /* HAVE_NS */
 
-
-/* The symbol `postscript' identifying images of this type.  */
-
-static Lisp_Object Qpostscript;
-
 static void x_disable_image (struct frame *, struct image *);
 static void x_edge_detection (struct frame *, struct image *, Lisp_Object,
                               Lisp_Object);
@@ -126,8 +115,6 @@ static void free_color_table (void);
 static unsigned long *colors_in_color_table (int *n);
 #endif
 
-static Lisp_Object QCmax_width, QCmax_height;
-
 /* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
    id, which is just an int that this section returns.  Bitmaps are
    reference counted so they can be shared among frames.
@@ -537,24 +524,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
 
 static struct image_type *image_types;
 
-/* The symbol `xbm' which is used as the type symbol for XBM images.  */
-
-static Lisp_Object Qxbm;
-
-/* Keywords.  */
-
-Lisp_Object QCascent, QCmargin, QCrelief;
-Lisp_Object QCconversion;
-static Lisp_Object QCheuristic_mask;
-static Lisp_Object QCcolor_symbols;
-static Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry;
-static Lisp_Object QCcrop, QCrotation;
-
-/* Other symbols.  */
-
-static Lisp_Object Qcount, Qextension_data, Qdelay;
-static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
-
 /* Forward function prototypes.  */
 
 static struct image_type *lookup_image_type (Lisp_Object);
@@ -579,27 +548,29 @@ static struct image_type *
 define_image_type (struct image_type *type)
 {
   struct image_type *p = NULL;
-  Lisp_Object target_type = *type->type;
-  bool type_valid = 1;
+  int new_type = type->type;
+  bool type_valid = true;
 
   block_input ();
 
   for (p = image_types; p; p = p->next)
-    if (EQ (*p->type, target_type))
+    if (p->type == new_type)
       goto done;
 
   if (type->init)
     {
 #if defined HAVE_NTGUI && defined WINDOWSNT
       /* If we failed to load the library before, don't try again.  */
-      Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
+      Lisp_Object tested = Fassq (builtin_lisp_symbol (new_type),
+                                 Vlibrary_cache);
       if (CONSP (tested) && NILP (XCDR (tested)))
-       type_valid = 0;
+       type_valid = false;
       else
 #endif
        {
          type_valid = type->init ();
-         CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
+         CACHE_IMAGE_TYPE (builtin_lisp_symbol (new_type),
+                           type_valid ? Qt : Qnil);
        }
     }
 
@@ -1777,7 +1748,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
 
          /* Do image transformations and compute masks, unless we
             don't have the image yet.  */
-         if (!EQ (*img->type->type, Qpostscript))
+         if (!EQ (builtin_lisp_symbol (img->type->type), Qpostscript))
            postprocess_image (f, img);
        }
 
@@ -2362,7 +2333,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
 
 static struct image_type xbm_type =
 {
-  &Qxbm,
+  SYMBOL_INDEX (Qxbm),
   xbm_image_p,
   xbm_load,
   x_clear_image,
@@ -3121,9 +3092,6 @@ static bool xpm_load (struct frame *f, struct image *img);
 #endif /* HAVE_XPM */
 
 #if defined (HAVE_XPM) || defined (HAVE_NS)
-/* The symbol `xpm' identifying XPM-format images.  */
-
-static Lisp_Object Qxpm;
 
 /* Indices of image specification fields in xpm_format, below.  */
 
@@ -3171,7 +3139,7 @@ static bool init_xpm_functions (void);
 
 static struct image_type xpm_type =
 {
-  &Qxpm,
+  SYMBOL_INDEX (Qxpm),
   xpm_image_p,
   xpm_load,
   x_clear_image,
@@ -5059,10 +5027,6 @@ x_build_heuristic_mask (struct frame *f, struct image 
*img, Lisp_Object how)
 static bool pbm_image_p (Lisp_Object object);
 static bool pbm_load (struct frame *f, struct image *img);
 
-/* The symbol `pbm' identifying images of this type.  */
-
-static Lisp_Object Qpbm;
-
 /* Indices of image specification fields in gs_format, below.  */
 
 enum pbm_keyword_index
@@ -5103,7 +5067,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
 
 static struct image_type pbm_type =
 {
-  &Qpbm,
+  SYMBOL_INDEX (Qpbm),
   pbm_image_p,
   pbm_load,
   x_clear_image,
@@ -5446,10 +5410,6 @@ pbm_load (struct frame *f, struct image *img)
 static bool png_image_p (Lisp_Object object);
 static bool png_load (struct frame *f, struct image *img);
 
-/* The symbol `png' identifying images of this type.  */
-
-static Lisp_Object Qpng;
-
 /* Indices of image specification fields in png_format, below.  */
 
 enum png_keyword_index
@@ -5494,7 +5454,7 @@ static bool init_png_functions (void);
 
 static struct image_type png_type =
 {
-  &Qpng,
+  SYMBOL_INDEX (Qpng),
   png_image_p,
   png_load,
   x_clear_image,
@@ -6102,10 +6062,6 @@ png_load (struct frame *f, struct image *img)
 static bool jpeg_image_p (Lisp_Object object);
 static bool jpeg_load (struct frame *f, struct image *img);
 
-/* The symbol `jpeg' identifying images of this type.  */
-
-static Lisp_Object Qjpeg;
-
 /* Indices of image specification fields in gs_format, below.  */
 
 enum jpeg_keyword_index
@@ -6150,7 +6106,7 @@ static bool init_jpeg_functions (void);
 
 static struct image_type jpeg_type =
 {
-  &Qjpeg,
+  SYMBOL_INDEX (Qjpeg),
   jpeg_image_p,
   jpeg_load,
   x_clear_image,
@@ -6704,10 +6660,6 @@ jpeg_load (struct frame *f, struct image *img)
 static bool tiff_image_p (Lisp_Object object);
 static bool tiff_load (struct frame *f, struct image *img);
 
-/* The symbol `tiff' identifying images of this type.  */
-
-static Lisp_Object Qtiff;
-
 /* Indices of image specification fields in tiff_format, below.  */
 
 enum tiff_keyword_index
@@ -6754,7 +6706,7 @@ static bool init_tiff_functions (void);
 
 static struct image_type tiff_type =
 {
-  &Qtiff,
+  SYMBOL_INDEX (Qtiff),
   tiff_image_p,
   tiff_load,
   x_clear_image,
@@ -7167,10 +7119,6 @@ static bool gif_image_p (Lisp_Object object);
 static bool gif_load (struct frame *f, struct image *img);
 static void gif_clear_image (struct frame *f, struct image *img);
 
-/* The symbol `gif' identifying images of this type.  */
-
-static Lisp_Object Qgif;
-
 /* Indices of image specification fields in gif_format, below.  */
 
 enum gif_keyword_index
@@ -7217,7 +7165,7 @@ static bool init_gif_functions (void);
 
 static struct image_type gif_type =
 {
-  &Qgif,
+  SYMBOL_INDEX (Qgif),
   gif_image_p,
   gif_load,
   gif_clear_image,
@@ -7841,8 +7789,6 @@ compute_image_size (size_t width, size_t height,
   *d_height = desired_height;
 }
 
-static Lisp_Object Qimagemagick;
-
 static bool imagemagick_image_p (Lisp_Object);
 static bool imagemagick_load (struct frame *, struct image *);
 static void imagemagick_clear_image (struct frame *, struct image *);
@@ -7906,7 +7852,7 @@ static bool init_imagemagick_functions (void);
 
 static struct image_type imagemagick_type =
   {
-    &Qimagemagick,
+    SYMBOL_INDEX (Qimagemagick),
     imagemagick_image_p,
     imagemagick_load,
     imagemagick_clear_image,
@@ -8632,10 +8578,6 @@ static bool svg_load (struct frame *f, struct image 
*img);
 static bool svg_load_image (struct frame *, struct image *,
                            unsigned char *, ptrdiff_t, char *);
 
-/* The symbol `svg' identifying images of this type. */
-
-static Lisp_Object Qsvg;
-
 /* Indices of image specification fields in svg_format, below.  */
 
 enum svg_keyword_index
@@ -8682,7 +8624,7 @@ static bool init_svg_functions (void);
 
 static struct image_type svg_type =
 {
-  &Qsvg,
+  SYMBOL_INDEX (Qsvg),
   svg_image_p,
   svg_load,
   x_clear_image,
@@ -8737,8 +8679,6 @@ DEF_DLL_FN (void, g_type_init, (void));
 DEF_DLL_FN (void, g_object_unref, (gpointer));
 DEF_DLL_FN (void, g_error_free, (GError *));
 
-Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
-
 static bool
 init_svg_functions (void)
 {
@@ -9056,10 +8996,6 @@ static bool gs_image_p (Lisp_Object object);
 static bool gs_load (struct frame *f, struct image *img);
 static void gs_clear_image (struct frame *f, struct image *img);
 
-/* Keyword symbols.  */
-
-static Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
-
 /* Indices of image specification fields in gs_format, below.  */
 
 enum gs_keyword_index
@@ -9104,7 +9040,7 @@ static const struct image_keyword gs_format[GS_LAST] =
 
 static struct image_type gs_type =
 {
-  &Qpostscript,
+  SYMBOL_INDEX (Qpostscript),
   gs_image_p,
   gs_load,
   gs_clear_image,
@@ -9479,10 +9415,12 @@ as a ratio to the frame height and width.  If the value 
is
 non-numeric, there is no explicit limit on the size of images.  */);
   Vmax_image_size = make_float (MAX_IMAGE_SIZE);
 
+  /* Other symbols.  */
   DEFSYM (Qcount, "count");
   DEFSYM (Qextension_data, "extension-data");
   DEFSYM (Qdelay, "delay");
 
+  /* Keywords.  */
   DEFSYM (QCascent, ":ascent");
   DEFSYM (QCmargin, ":margin");
   DEFSYM (QCrelief, ":relief");
@@ -9497,6 +9435,7 @@ non-numeric, there is no explicit limit on the size of 
images.  */);
   DEFSYM (QCcolor_adjustment, ":color-adjustment");
   DEFSYM (QCmask, ":mask");
 
+  /* Other symbols.  */
   DEFSYM (Qlaplace, "laplace");
   DEFSYM (Qemboss, "emboss");
   DEFSYM (Qedge_detection, "edge-detection");
@@ -9514,6 +9453,10 @@ non-numeric, there is no explicit limit on the size of 
images.  */);
 #endif /* HAVE_GHOSTSCRIPT */
 
 #ifdef HAVE_NTGUI
+  /* Versions of libpng, libgif, and libjpeg that we were compiled with,
+     or -1 if no PNG/GIF support was compiled in.  This is tested by
+     w32-win.el to correctly set up the alist used to search for the
+     respective image libraries.  */
   DEFSYM (Qlibpng_version, "libpng-version");
   Fset (Qlibpng_version,
 #if HAVE_PNG
diff --git a/src/inotify.c b/src/inotify.c
index 8e8ab20..eddad73 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -29,34 +29,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "frame.h" /* Required for termhooks.h.  */
 #include "termhooks.h"
 
-static Lisp_Object Qaccess;        /* IN_ACCESS */
-static Lisp_Object Qattrib;        /* IN_ATTRIB */
-static Lisp_Object Qclose_write;   /* IN_CLOSE_WRITE */
-static Lisp_Object Qclose_nowrite; /* IN_CLOSE_NOWRITE */
-static Lisp_Object Qcreate;        /* IN_CREATE */
-static Lisp_Object Qdelete;        /* IN_DELETE */
-static Lisp_Object Qdelete_self;   /* IN_DELETE_SELF */
-static Lisp_Object Qmodify;        /* IN_MODIFY */
-static Lisp_Object Qmove_self;     /* IN_MOVE_SELF */
-static Lisp_Object Qmoved_from;    /* IN_MOVED_FROM */
-static Lisp_Object Qmoved_to;      /* IN_MOVED_TO */
-static Lisp_Object Qopen;          /* IN_OPEN */
-
-static Lisp_Object Qall_events;    /* IN_ALL_EVENTS */
-static Lisp_Object Qmove;          /* IN_MOVE */
-static Lisp_Object Qclose;         /* IN_CLOSE */
-
-static Lisp_Object Qdont_follow;   /* IN_DONT_FOLLOW */
-static Lisp_Object Qexcl_unlink;   /* IN_EXCL_UNLINK */
-static Lisp_Object Qmask_add;      /* IN_MASK_ADD */
-static Lisp_Object Qoneshot;       /* IN_ONESHOT */
-static Lisp_Object Qonlydir;       /* IN_ONLYDIR */
-
-static Lisp_Object Qignored;       /* IN_IGNORED */
-static Lisp_Object Qisdir;         /* IN_ISDIR */
-static Lisp_Object Qq_overflow;    /* IN_Q_OVERFLOW */
-static Lisp_Object Qunmount;       /* IN_UNMOUNT */
-
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
 
@@ -398,33 +370,34 @@ See inotify_rm_watch(2) for more information.
 void
 syms_of_inotify (void)
 {
-  DEFSYM (Qaccess, "access");
-  DEFSYM (Qattrib, "attrib");
-  DEFSYM (Qclose_write, "close-write");
+  DEFSYM (Qaccess, "access");          /* IN_ACCESS */
+  DEFSYM (Qattrib, "attrib");          /* IN_ATTRIB */
+  DEFSYM (Qclose_write, "close-write");        /* IN_CLOSE_WRITE */
   DEFSYM (Qclose_nowrite, "close-nowrite");
-  DEFSYM (Qcreate, "create");
-  DEFSYM (Qdelete, "delete");
-  DEFSYM (Qdelete_self, "delete-self");
-  DEFSYM (Qmodify, "modify");
-  DEFSYM (Qmove_self, "move-self");
-  DEFSYM (Qmoved_from, "moved-from");
-  DEFSYM (Qmoved_to, "moved-to");
-  DEFSYM (Qopen, "open");
-
-  DEFSYM (Qall_events, "all-events");
-  DEFSYM (Qmove, "move");
-  DEFSYM (Qclose, "close");
-
-  DEFSYM (Qdont_follow, "dont-follow");
-  DEFSYM (Qexcl_unlink, "excl-unlink");
-  DEFSYM (Qmask_add, "mask-add");
-  DEFSYM (Qoneshot, "oneshot");
-  DEFSYM (Qonlydir, "onlydir");
-
-  DEFSYM (Qignored, "ignored");
-  DEFSYM (Qisdir, "isdir");
-  DEFSYM (Qq_overflow, "q-overflow");
-  DEFSYM (Qunmount, "unmount");
+                                       /* IN_CLOSE_NOWRITE */
+  DEFSYM (Qcreate, "create");          /* IN_CREATE */
+  DEFSYM (Qdelete, "delete");          /* IN_DELETE */
+  DEFSYM (Qdelete_self, "delete-self");        /* IN_DELETE_SELF */
+  DEFSYM (Qmodify, "modify");          /* IN_MODIFY */
+  DEFSYM (Qmove_self, "move-self");    /* IN_MOVE_SELF */
+  DEFSYM (Qmoved_from, "moved-from");  /* IN_MOVED_FROM */
+  DEFSYM (Qmoved_to, "moved-to");      /* IN_MOVED_TO */
+  DEFSYM (Qopen, "open");              /* IN_OPEN */
+
+  DEFSYM (Qall_events, "all-events");  /* IN_ALL_EVENTS */
+  DEFSYM (Qmove, "move");              /* IN_MOVE */
+  DEFSYM (Qclose, "close");            /* IN_CLOSE */
+
+  DEFSYM (Qdont_follow, "dont-follow");        /* IN_DONT_FOLLOW */
+  DEFSYM (Qexcl_unlink, "excl-unlink");        /* IN_EXCL_UNLINK */
+  DEFSYM (Qmask_add, "mask-add");      /* IN_MASK_ADD */
+  DEFSYM (Qoneshot, "oneshot");                /* IN_ONESHOT */
+  DEFSYM (Qonlydir, "onlydir");                /* IN_ONLYDIR */
+
+  DEFSYM (Qignored, "ignored");                /* IN_IGNORED */
+  DEFSYM (Qisdir, "isdir");            /* IN_ISDIR */
+  DEFSYM (Qq_overflow, "q-overflow");  /* IN_Q_OVERFLOW */
+  DEFSYM (Qunmount, "unmount");                /* IN_UNMOUNT */
 
   defsubr (&Sinotify_add_watch);
   defsubr (&Sinotify_rm_watch);
diff --git a/src/insdel.c b/src/insdel.c
index a1bec4a..4463721 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -52,8 +52,6 @@ static Lisp_Object combine_after_change_list;
 /* Buffer which combine_after_change_list is about.  */
 static Lisp_Object combine_after_change_buffer;
 
-Lisp_Object Qinhibit_modification_hooks;
-
 static void signal_before_change (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
 
 /* Also used in marker.c to enable expensive marker checks.  */
@@ -1781,8 +1779,6 @@ modify_text (ptrdiff_t start, ptrdiff_t end)
   bset_point_before_scroll (current_buffer, Qnil);
 }
 
-Lisp_Object Qregion_extract_function;
-
 /* Check that it is okay to modify the buffer between START and END,
    which are char positions.
 
@@ -1995,7 +1991,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t 
end_int,
     {
       PRESERVE_VALUE;
       PRESERVE_START_END;
-      Frun_hooks (1, &Qfirst_change_hook);
+      run_hook (Qfirst_change_hook);
     }
 
   /* Now run the before-change-functions if any.  */
diff --git a/src/intervals.h b/src/intervals.h
index 8f0f348..b2260d0 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -271,21 +271,7 @@ extern INTERVAL interval_of (ptrdiff_t, Lisp_Object);
 /* Defined in xdisp.c.  */
 extern int invisible_p (Lisp_Object, Lisp_Object);
 
-/* Declared in textprop.c.  */
-
-/* Types of hooks.  */
-extern Lisp_Object Qpoint_left;
-extern Lisp_Object Qpoint_entered;
-extern Lisp_Object Qmodification_hooks;
-extern Lisp_Object Qcategory;
-extern Lisp_Object Qlocal_map;
-
-/* Visual properties text (including strings) may have.  */
-extern Lisp_Object Qinvisible, Qintangible;
-
-/* Sticky properties.  */
-extern Lisp_Object Qfront_sticky, Qrear_nonsticky;
-
+/* Defined in textprop.c.  */
 extern Lisp_Object copy_text_properties (Lisp_Object, Lisp_Object,
                                          Lisp_Object, Lisp_Object,
                                          Lisp_Object, Lisp_Object);
diff --git a/src/keyboard.c b/src/keyboard.c
index 9261c4b..86c840d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -88,11 +88,6 @@ static KBOARD *all_kboards;
 /* True in the single-kboard state, false in the any-kboard state.  */
 static bool single_kboard;
 
-/* Non-nil disable property on a command means
-   do not execute it; call disabled-command-function's value instead.  */
-Lisp_Object Qdisabled;
-static Lisp_Object Qdisabled_command_function;
-
 #define NUM_RECENT_KEYS (300)
 
 /* Index for storing next element into recent_keys.  */
@@ -232,42 +227,11 @@ static ptrdiff_t last_point_position;
    'volatile' here.  */
 Lisp_Object internal_last_event_frame;
 
-static Lisp_Object Qgui_set_selection, Qhandle_switch_frame;
-static Lisp_Object Qhandle_select_window;
-Lisp_Object QPRIMARY;
-
-static Lisp_Object Qself_insert_command;
-static Lisp_Object Qforward_char;
-static Lisp_Object Qbackward_char;
-Lisp_Object Qundefined;
-static Lisp_Object Qtimer_event_handler;
-
 /* `read_key_sequence' stores here the command definition of the
    key sequence that it reads.  */
 static Lisp_Object read_key_sequence_cmd;
 static Lisp_Object read_key_sequence_remapped;
 
-static Lisp_Object Qinput_method_function;
-
-static Lisp_Object Qdeactivate_mark;
-
-Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook;
-
-static Lisp_Object Qecho_area_clear_hook;
-
-/* Hooks to run before and after each command.  */
-static Lisp_Object Qpre_command_hook;
-static Lisp_Object Qpost_command_hook;
-
-static Lisp_Object Qdeferred_action_function;
-
-static Lisp_Object Qdelayed_warnings_hook;
-
-static Lisp_Object Qinput_method_exit_on_first_char;
-static Lisp_Object Qinput_method_use_echo_area;
-
-static Lisp_Object Qhelp_form_show;
-
 /* File in which we write all commands we read.  */
 static FILE *dribble;
 
@@ -346,86 +310,12 @@ static struct input_event * volatile kbd_store_ptr;
    dequeuing functions?  Such a flag could be screwed up by interrupts
    at inopportune times.  */
 
-/* Symbols to head events.  */
-static Lisp_Object Qmouse_movement;
-static Lisp_Object Qscroll_bar_movement;
-Lisp_Object Qswitch_frame;
-static Lisp_Object Qfocus_in, Qfocus_out;
-static Lisp_Object Qdelete_frame;
-static Lisp_Object Qiconify_frame;
-static Lisp_Object Qmake_frame_visible;
-static Lisp_Object Qselect_window;
-Lisp_Object Qhelp_echo;
-
-static Lisp_Object Qmouse_fixup_help_message;
-
-/* Symbols to denote kinds of events.  */
-static Lisp_Object Qfunction_key;
-Lisp_Object Qmouse_click;
-#ifdef HAVE_NTGUI
-Lisp_Object Qlanguage_change;
-#endif
-static Lisp_Object Qdrag_n_drop;
-static Lisp_Object Qsave_session;
-#ifdef HAVE_DBUS
-static Lisp_Object Qdbus_event;
-#endif
-#ifdef HAVE_XWIDGETS
-Lisp_Object Qxwidget_event;
-#endif
-#ifdef USE_FILE_NOTIFY
-static Lisp_Object Qfile_notify;
-#endif /* USE_FILE_NOTIFY */
-static Lisp_Object Qconfig_changed_event;
-
-/* Lisp_Object Qmouse_movement; - also an event header */
-
-/* Properties of event headers.  */
-Lisp_Object Qevent_kind;
-static Lisp_Object Qevent_symbol_elements;
-
-/* Menu and tool bar item parts.  */
-static Lisp_Object Qmenu_enable;
-static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence;
-Lisp_Object QCfilter;
-
-/* Non-nil disable property on a command means
-   do not execute it; call disabled-command-function's value instead.  */
-Lisp_Object QCtoggle, QCradio;
-static Lisp_Object QCbutton, QClabel;
-
-static Lisp_Object QCvert_only;
-
-/* An event header symbol HEAD may have a property named
-   Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
-   BASE is the base, unmodified version of HEAD, and MODIFIERS is the
-   mask of modifiers applied to it.  If present, this is used to help
-   speed up parse_modifiers.  */
-Lisp_Object Qevent_symbol_element_mask;
-
-/* An unmodified event header BASE may have a property named
-   Qmodifier_cache, which is an alist mapping modifier masks onto
-   modified versions of BASE.  If present, this helps speed up
-   apply_modifiers.  */
-static Lisp_Object Qmodifier_cache;
-
-/* Symbols to use for parts of windows.  */
-Lisp_Object Qmode_line;
-Lisp_Object Qvertical_line;
-Lisp_Object Qright_divider, Qbottom_divider;
-Lisp_Object Qmenu_bar;
-
-static Lisp_Object Qecho_keystrokes;
-
 static void recursive_edit_unwind (Lisp_Object buffer);
 static Lisp_Object command_loop (void);
-static Lisp_Object Qcommand_execute;
 
 static void echo_now (void);
 static ptrdiff_t echo_length (void);
 
-static Lisp_Object Qpolling_period;
-
 /* Incremented whenever a timer is run.  */
 unsigned timers_run;
 
@@ -1716,10 +1606,7 @@ command_loop_1 (void)
                }
 
              if (current_buffer != prev_buffer || MODIFF != prev_modiff)
-                {
-                  Lisp_Object hook = intern ("activate-mark-hook");
-                  Frun_hooks (1, &hook);
-                }
+               run_hook (intern ("activate-mark-hook"));
            }
 
          Vsaved_region_selection = Qnil;
@@ -4138,11 +4025,7 @@ kbd_buffer_get_event (KBOARD **kbp,
        {
 #ifdef HAVE_W32NOTIFY
          /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK).  */
-         obj = list3 (Qfile_notify,
-                      list3 (make_number (event->code),
-                             XCAR (event->arg),
-                             XCDR (event->arg)),
-                      event->frame_or_window);
+         obj = list3 (Qfile_notify, event->arg, event->frame_or_window);
 #else
           obj = make_lispy_event (event);
 #endif
@@ -5295,22 +5178,17 @@ static const char *const lispy_drag_n_drop_names[] =
   "drag-n-drop"
 };
 
-/* Scroll bar parts.  */
-static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
-static Lisp_Object Qbefore_handle, Qhorizontal_handle, Qafter_handle;
-Lisp_Object Qup, Qdown, Qtop, Qbottom;
-static Lisp_Object Qleftmost, Qrightmost;
-static Lisp_Object Qend_scroll;
-static Lisp_Object Qratio;
-
-/* An array of scroll bar parts, indexed by an enum scroll_bar_part value.
-   Note that Qnil corresponds to scroll_bar_nowhere and should not appear
-   in Lisp events.  */
-static Lisp_Object *const scroll_bar_parts[] = {
-  &Qnil, &Qabove_handle, &Qhandle, &Qbelow_handle,
-  &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio,
-  &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle,
-  &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio
+/* An array of symbol indexes of scroll bar parts, indexed by an enum
+   scroll_bar_part value.  Note that Qnil corresponds to
+   scroll_bar_nowhere and should not appear in Lisp events.  */
+static short const scroll_bar_parts[] = {
+  SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qabove_handle), SYMBOL_INDEX (Qhandle),
+  SYMBOL_INDEX (Qbelow_handle), SYMBOL_INDEX (Qup), SYMBOL_INDEX (Qdown),
+  SYMBOL_INDEX (Qtop), SYMBOL_INDEX (Qbottom), SYMBOL_INDEX (Qend_scroll),
+  SYMBOL_INDEX (Qratio), SYMBOL_INDEX (Qbefore_handle),
+  SYMBOL_INDEX (Qhorizontal_handle), SYMBOL_INDEX (Qafter_handle),
+  SYMBOL_INDEX (Qleft), SYMBOL_INDEX (Qright), SYMBOL_INDEX (Qleftmost),
+  SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
 };
 
 /* A vector, indexed by button number, giving the down-going location
@@ -5583,7 +5461,8 @@ static Lisp_Object
 make_scroll_bar_position (struct input_event *ev, Lisp_Object type)
 {
   return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y),
-               make_number (ev->timestamp), *scroll_bar_parts[ev->part]);
+               make_number (ev->timestamp),
+               builtin_lisp_symbol (scroll_bar_parts[ev->part]));
 }
 
 /* Given a struct input_event, build the lisp event which represents
@@ -6231,7 +6110,7 @@ make_lispy_movement (struct frame *frame, Lisp_Object 
bar_window, enum scroll_ba
     {
       Lisp_Object part_sym;
 
-      part_sym = *scroll_bar_parts[(int) part];
+      part_sym = builtin_lisp_symbol (scroll_bar_parts[part]);
       return list2 (Qscroll_bar_movement,
                    list5 (bar_window,
                           Qvertical_scroll_bar,
@@ -8095,11 +7974,6 @@ static Lisp_Object tool_bar_item_properties;
 
 static int ntool_bar_items;
 
-/* The symbols `:image' and `:rtl'.  */
-
-static Lisp_Object QCimage;
-static Lisp_Object QCrtl;
-
 /* Function prototypes.  */
 
 static void init_tool_bar_items (Lisp_Object);
@@ -10358,7 +10232,6 @@ On such systems, Emacs starts a subshell instead of 
suspending.  */)
   int old_height, old_width;
   int width, height;
   struct gcpro gcpro1;
-  Lisp_Object hook;
 
   if (tty_list && tty_list->next)
     error ("There are other tty frames open; close them before suspending 
Emacs");
@@ -10366,9 +10239,7 @@ On such systems, Emacs starts a subshell instead of 
suspending.  */)
   if (!NILP (stuffstring))
     CHECK_STRING (stuffstring);
 
-  /* Run the functions in suspend-hook.  */
-  hook = intern ("suspend-hook");
-  Frun_hooks (1, &hook);
+  run_hook (intern ("suspend-hook"));
 
   GCPRO1 (stuffstring);
   get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
@@ -10392,9 +10263,7 @@ On such systems, Emacs starts a subshell instead of 
suspending.  */)
                       height - FRAME_MENU_BAR_LINES (SELECTED_FRAME ()),
                       0, 0, 0, 0);
 
-  /* Run suspend-resume-hook.  */
-  hook = intern ("suspend-resume-hook");
-  Frun_hooks (1, &hook);
+  run_hook (intern ("suspend-resume-hook"));
 
   UNGCPRO;
   return Qnil;
@@ -11138,26 +11007,29 @@ init_keyboard (void)
 #endif
 }
 
-/* This type's only use is in syms_of_keyboard, to initialize the
-   event header symbols and put properties on them.  */
-struct event_head {
-  Lisp_Object *var;
-  const char *name;
-  Lisp_Object *kind;
+/* This type's only use is in syms_of_keyboard, to put properties on the
+   event header symbols.  */
+struct event_head
+{
+  short var;
+  short kind;
 };
 
 static const struct event_head head_table[] = {
-  {&Qmouse_movement,      "mouse-movement",      &Qmouse_movement},
-  {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement},
-  {&Qswitch_frame,        "switch-frame",        &Qswitch_frame},
-  {&Qfocus_in,            "focus-in",            &Qfocus_in},
-  {&Qfocus_out,           "focus-out",          &Qfocus_out},
-  {&Qdelete_frame,        "delete-frame",        &Qdelete_frame},
-  {&Qiconify_frame,       "iconify-frame",       &Qiconify_frame},
-  {&Qmake_frame_visible,  "make-frame-visible",  &Qmake_frame_visible},
+  {SYMBOL_INDEX (Qmouse_movement),      SYMBOL_INDEX (Qmouse_movement)},
+  {SYMBOL_INDEX (Qscroll_bar_movement), SYMBOL_INDEX (Qmouse_movement)},
+
+  /* Some of the event heads.  */
+  {SYMBOL_INDEX (Qswitch_frame),        SYMBOL_INDEX (Qswitch_frame)},
+
+  {SYMBOL_INDEX (Qfocus_in),            SYMBOL_INDEX (Qfocus_in)},
+  {SYMBOL_INDEX (Qfocus_out),           SYMBOL_INDEX (Qfocus_out)},
+  {SYMBOL_INDEX (Qdelete_frame),        SYMBOL_INDEX (Qdelete_frame)},
+  {SYMBOL_INDEX (Qiconify_frame),       SYMBOL_INDEX (Qiconify_frame)},
+  {SYMBOL_INDEX (Qmake_frame_visible),  SYMBOL_INDEX (Qmake_frame_visible)},
   /* `select-window' should be handled just like `switch-frame'
      in read_key_sequence.  */
-  {&Qselect_window,       "select-window",       &Qswitch_frame}
+  {SYMBOL_INDEX (Qselect_window),       SYMBOL_INDEX (Qswitch_frame)}
 };
 
 void
@@ -11196,17 +11068,29 @@ syms_of_keyboard (void)
   DEFSYM (Qself_insert_command, "self-insert-command");
   DEFSYM (Qforward_char, "forward-char");
   DEFSYM (Qbackward_char, "backward-char");
+
+  /* Non-nil disable property on a command means do not execute it;
+     call disabled-command-function's value instead.  */
   DEFSYM (Qdisabled, "disabled");
+
   DEFSYM (Qundefined, "undefined");
+
+  /* Hooks to run before and after each command.  */
   DEFSYM (Qpre_command_hook, "pre-command-hook");
   DEFSYM (Qpost_command_hook, "post-command-hook");
+
   DEFSYM (Qdeferred_action_function, "deferred-action-function");
   DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
   DEFSYM (Qfunction_key, "function-key");
+
+  /* The values of Qevent_kind properties.  */
   DEFSYM (Qmouse_click, "mouse-click");
+
   DEFSYM (Qdrag_n_drop, "drag-n-drop");
   DEFSYM (Qsave_session, "save-session");
   DEFSYM (Qconfig_changed_event, "config-changed-event");
+
+  /* Menu and tool bar item parts.  */
   DEFSYM (Qmenu_enable, "menu-enable");
 
 #ifdef HAVE_NTGUI
@@ -11225,6 +11109,7 @@ syms_of_keyboard (void)
   DEFSYM (Qfile_notify, "file-notify");
 #endif /* USE_FILE_NOTIFY */
 
+  /* Menu and tool bar item parts.  */
   DEFSYM (QCenable, ":enable");
   DEFSYM (QCvisible, ":visible");
   DEFSYM (QChelp, ":help");
@@ -11232,14 +11117,16 @@ syms_of_keyboard (void)
   DEFSYM (QCbutton, ":button");
   DEFSYM (QCkeys, ":keys");
   DEFSYM (QCkey_sequence, ":key-sequence");
+
+  /* Non-nil disable property on a command means
+     do not execute it; call disabled-command-function's value instead.  */
   DEFSYM (QCtoggle, ":toggle");
   DEFSYM (QCradio, ":radio");
   DEFSYM (QClabel, ":label");
   DEFSYM (QCvert_only, ":vert-only");
 
-  DEFSYM (Qmode_line, "mode-line");
+  /* Symbols to use for parts of windows.  */
   DEFSYM (Qvertical_line, "vertical-line");
-  DEFSYM (Qmenu_bar, "menu-bar");
   DEFSYM (Qright_divider, "right-divider");
   DEFSYM (Qbottom_divider, "bottom-divider");
 
@@ -11262,9 +11149,21 @@ syms_of_keyboard (void)
   DEFSYM (Qleftmost, "leftmost");
   DEFSYM (Qrightmost, "rightmost");
 
+  /* Properties of event headers.  */
   DEFSYM (Qevent_kind, "event-kind");
   DEFSYM (Qevent_symbol_elements, "event-symbol-elements");
+
+  /* An event header symbol HEAD may have a property named
+     Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
+     BASE is the base, unmodified version of HEAD, and MODIFIERS is the
+     mask of modifiers applied to it.  If present, this is used to help
+     speed up parse_modifiers.  */
   DEFSYM (Qevent_symbol_element_mask, "event-symbol-element-mask");
+
+  /* An unmodified event header BASE may have a property named
+     Qmodifier_cache, which is an alist mapping modifier masks onto
+     modified versions of BASE.  If present, this helps speed up
+     apply_modifiers.  */
   DEFSYM (Qmodifier_cache, "modifier-cache");
 
   DEFSYM (Qrecompute_lucid_menubar, "recompute-lucid-menubar");
@@ -11273,7 +11172,10 @@ syms_of_keyboard (void)
   DEFSYM (Qpolling_period, "polling-period");
 
   DEFSYM (Qgui_set_selection, "gui-set-selection");
+
+  /* The primary selection.  */
   DEFSYM (QPRIMARY, "PRIMARY");
+
   DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
   DEFSYM (Qhandle_select_window, "handle-select-window");
 
@@ -11288,17 +11190,26 @@ syms_of_keyboard (void)
   Fset (Qinput_method_exit_on_first_char, Qnil);
   Fset (Qinput_method_use_echo_area, Qnil);
 
+  /* Symbols to head events.  */
+  DEFSYM (Qmouse_movement, "mouse-movement");
+  DEFSYM (Qscroll_bar_movement, "scroll-bar-movement");
+  DEFSYM (Qswitch_frame, "switch-frame");
+  DEFSYM (Qfocus_in, "focus-in");
+  DEFSYM (Qfocus_out, "focus-out");
+  DEFSYM (Qdelete_frame, "delete-frame");
+  DEFSYM (Qiconify_frame, "iconify-frame");
+  DEFSYM (Qmake_frame_visible, "make-frame-visible");
+  DEFSYM (Qselect_window, "select-window");
   {
     int i;
-    int len = ARRAYELTS (head_table);
 
-    for (i = 0; i < len; i++)
+    for (i = 0; i < ARRAYELTS (head_table); i++)
       {
        const struct event_head *p = &head_table[i];
-       *p->var = intern_c_string (p->name);
-       staticpro (p->var);
-       Fput (*p->var, Qevent_kind, *p->kind);
-       Fput (*p->var, Qevent_symbol_elements, list1 (*p->var));
+       Lisp_Object var = builtin_lisp_symbol (p->var);
+       Lisp_Object kind = builtin_lisp_symbol (p->kind);
+       Fput (var, Qevent_kind, kind);
+       Fput (var, Qevent_symbol_elements, list1 (var));
       }
   }
 
@@ -11624,13 +11535,13 @@ with no modifiers; thus, setting 
`extra-keyboard-modifiers' to zero
 cancels any modification.  */);
   extra_keyboard_modifiers = 0;
 
+  DEFSYM (Qdeactivate_mark, "deactivate-mark");
   DEFVAR_LISP ("deactivate-mark", Vdeactivate_mark,
               doc: /* If an editing command sets this to t, deactivate the 
mark afterward.
 The command loop sets this to nil before each command,
 and tests the value when the command returns.
 Buffer modification stores t in this variable.  */);
   Vdeactivate_mark = Qnil;
-  DEFSYM (Qdeactivate_mark, "deactivate-mark");
   Fmake_variable_buffer_local (Qdeactivate_mark);
 
   DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
diff --git a/src/keyboard.h b/src/keyboard.h
index 534e201..0ce6d18 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -248,8 +248,6 @@ extern ptrdiff_t this_command_key_count;
    generated by the next character.  */
 extern Lisp_Object internal_last_event_frame;
 
-extern Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook;
-
 /* This holds a Lisp vector that holds the properties of a single
    menu item while decoding it in parse_menu_item.
    Using a Lisp vector to hold this information while we decode it
@@ -387,25 +385,10 @@ extern void unuse_menu_items (void);
 #define POSN_INBUFFER_P(posn) (NILP (POSN_STRING (posn)))
 #define POSN_BUFFER_POSN(posn) (Fnth (make_number (5), (posn)))
 
-/* Some of the event heads.  */
-extern Lisp_Object Qswitch_frame;
-
-/* Properties on event heads.  */
-extern Lisp_Object Qevent_kind;
-
-/* The values of Qevent_kind properties.  */
-extern Lisp_Object Qmouse_click;
-
-extern Lisp_Object Qhelp_echo;
-
 /* Getting the kind of an event head.  */
 #define EVENT_HEAD_KIND(event_head) \
   (Fget ((event_head), Qevent_kind))
 
-/* Symbols to use for non-text mouse positions.  */
-extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line;
-extern Lisp_Object Qright_divider, Qbottom_divider;
-
 /* True while doing kbd input.  */
 extern bool waiting_for_input;
 
@@ -415,9 +398,6 @@ extern struct timespec *input_available_clear_time;
 
 extern bool ignore_mouse_drag_p;
 
-/* The primary selection.  */
-extern Lisp_Object QPRIMARY;
-
 extern Lisp_Object parse_modifiers (Lisp_Object);
 extern Lisp_Object reorder_modifiers (Lisp_Object);
 extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object,
@@ -428,17 +408,6 @@ extern int parse_solitary_modifier (Lisp_Object symbol);
 /* This is like Vthis_command, except that commands never set it.  */
 extern Lisp_Object real_this_command;
 
-/* Non-nil disable property on a command means
-   do not execute it; call disabled-command-function's value instead.  */
-extern Lisp_Object QCtoggle, QCradio;
-
-/* An event header symbol HEAD may have a property named
-   Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
-   BASE is the base, unmodified version of HEAD, and MODIFIERS is the
-   mask of modifiers applied to it.  If present, this is used to help
-   speed up parse_modifiers.  */
-extern Lisp_Object Qevent_symbol_element_mask;
-
 extern int quit_char;
 
 extern unsigned int timers_run;
diff --git a/src/keymap.c b/src/keymap.c
index ab21a22..9c7b4d2 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -76,12 +76,6 @@ Lisp_Object control_x_map;   /* The keymap used for globally 
bound
                                   bindings when spaces are not encouraged
                                   in the minibuf.  */
 
-/* Keymap used for minibuffers when doing completion.  */
-/* Keymap used for minibuffers when doing completion and require a match.  */
-static Lisp_Object Qkeymapp, Qnon_ascii;
-Lisp_Object Qkeymap, Qmenu_item, Qremap;
-static Lisp_Object QCadvertised_binding;
-
 /* Alist of elements like (DEL . "\d").  */
 static Lisp_Object exclude_keys;
 
@@ -654,8 +648,6 @@ map_keymap (Lisp_Object map, map_keymap_function_t fun, 
Lisp_Object args,
   UNGCPRO;
 }
 
-static Lisp_Object Qkeymap_canonicalize;
-
 /* Same as map_keymap, but does it right, properly eliminating duplicate
    bindings due to inheritance.   */
 void
@@ -1998,7 +1990,6 @@ then the value includes only maps for prefixes that start 
with PREFIX.  */)
     }
   return maps;
 }
-static Lisp_Object Qsingle_key_description, Qkey_description;
 
 /* This function cannot GC.  */
 
@@ -3734,12 +3725,15 @@ be preferred.  */);
   Vwhere_is_preferred_modifier = Qnil;
   where_is_preferred_modifier = 0;
 
+  DEFSYM (Qmenu_bar, "menu-bar");
+  DEFSYM (Qmode_line, "mode-line");
+
   staticpro (&Vmouse_events);
   Vmouse_events = listn (CONSTYPE_PURE, 9,
-                        intern_c_string ("menu-bar"),
+                        Qmenu_bar,
                         intern_c_string ("tool-bar"),
                         intern_c_string ("header-line"),
-                        intern_c_string ("mode-line"),
+                        Qmode_line,
                         intern_c_string ("mouse-1"),
                         intern_c_string ("mouse-2"),
                         intern_c_string ("mouse-3"),
@@ -3748,6 +3742,9 @@ be preferred.  */);
 
   DEFSYM (Qsingle_key_description, "single-key-description");
   DEFSYM (Qkey_description, "key-description");
+
+  /* Keymap used for minibuffers when doing completion.  */
+  /* Keymap used for minibuffers when doing completion and require a match.  */
   DEFSYM (Qkeymapp, "keymapp");
   DEFSYM (Qnon_ascii, "non-ascii");
   DEFSYM (Qmenu_item, "menu-item");
diff --git a/src/keymap.h b/src/keymap.h
index 4649acb..215dd3f 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -30,9 +30,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #define KEY_DESCRIPTION_SIZE ((2 * 6) + 1 + (CHARACTERBITS / 3) + 1 + 1)
 
 #define KEYMAPP(m) (!NILP (get_keymap (m, false, false)))
-extern Lisp_Object Qkeymap, Qmenu_bar;
-extern Lisp_Object Qremap;
-extern Lisp_Object Qmenu_item;
 extern Lisp_Object current_global_map;
 extern char *push_key_description (EMACS_INT, char *);
 extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, bool, bool, bool);
diff --git a/src/lisp.h b/src/lisp.h
index d416661..9e1f150 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -233,8 +233,8 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
 
    USE_LSB_TAG not only requires the least 3 bits of pointers returned by
    malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
-   on the few static Lisp_Objects used: all the defsubr as well
-   as the two special buffers buffer_defaults and buffer_local_symbols.  */
+   on the few static Lisp_Objects used: lispsym, all the defsubr, and
+   the two special buffers buffer_defaults and buffer_local_symbols.  */
 
 enum Lisp_Bits
   {
@@ -354,9 +354,8 @@ error !;
 #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))
-#define lisp_h_XSYMBOL(a) \
-   (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol))
+#define lisp_h_XPNTR(a) \
+   (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
@@ -365,8 +364,12 @@ error !;
     XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0))
 # define lisp_h_XFASTINT(a) XINT (a)
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
+# define lisp_h_XSYMBOL(a) \
+    (eassert (SYMBOLP (a)), \
+     (struct Lisp_Symbol *) ((uintptr_t) XLI (a) - Lisp_Symbol \
+                            + (char *) lispsym))
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type)))
+# define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type)))
 #endif
 
 /* When compiling via gcc -O0, define the key operations as macros, as
@@ -398,7 +401,6 @@ error !;
 # define XCONS(a) lisp_h_XCONS (a)
 # define XHASH(a) lisp_h_XHASH (a)
 # define XPNTR(a) lisp_h_XPNTR (a)
-# define XSYMBOL(a) lisp_h_XSYMBOL (a)
 # ifndef GC_CHECK_CONS_LIST
 #  define check_cons_list() lisp_h_check_cons_list ()
 # endif
@@ -406,6 +408,7 @@ error !;
 #  define make_number(n) lisp_h_make_number (n)
 #  define XFASTINT(a) lisp_h_XFASTINT (a)
 #  define XINT(a) lisp_h_XINT (a)
+#  define XSYMBOL(a) lisp_h_XSYMBOL (a)
 #  define XTYPE(a) lisp_h_XTYPE (a)
 #  define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
 # endif
@@ -447,20 +450,20 @@ error !;
 
 enum Lisp_Type
   {
-    /* Integer.  XINT (obj) is the integer value.  */
-    Lisp_Int0 = 0,
-    Lisp_Int1 = USE_LSB_TAG ? 1 << INTTYPEBITS : 1,
-
     /* Symbol.  XSYMBOL (object) points to a struct Lisp_Symbol.  */
-    Lisp_Symbol = 2,
+    Lisp_Symbol = 0,
 
     /* Miscellaneous.  XMISC (object) points to a union Lisp_Misc,
        whose first member indicates the subtype.  */
-    Lisp_Misc = 3,
+    Lisp_Misc = 1,
+
+    /* Integer.  XINT (obj) is the integer value.  */
+    Lisp_Int0 = 2,
+    Lisp_Int1 = USE_LSB_TAG ? 6 : 3,
 
     /* String.  XSTRING (object) points to a struct Lisp_String.
        The length of the string, and its contents, are stored therein.  */
-    Lisp_String = USE_LSB_TAG ? 1 : 1 << INTTYPEBITS,
+    Lisp_String = 4,
 
     /* Vector of Lisp objects, or something resembling it.
        XVECTOR (object) points to a struct Lisp_Vector, which contains
@@ -469,7 +472,7 @@ enum Lisp_Type
     Lisp_Vectorlike = 5,
 
     /* Cons.  XCONS (object) points to a struct Lisp_Cons.  */
-    Lisp_Cons = 6,
+    Lisp_Cons = USE_LSB_TAG ? 3 : 6,
 
     Lisp_Float = 7
   };
@@ -562,7 +565,7 @@ enum Lisp_Fwd_Type
 
 typedef struct { EMACS_INT i; } Lisp_Object;
 
-#define LISP_INITIALLY_ZERO {0}
+#define LISP_INITIALLY(i) {i}
 
 #undef CHECK_LISP_OBJECT_TYPE
 enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true };
@@ -571,9 +574,11 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 
true };
 /* If a struct type is not wanted, define Lisp_Object as just a number.  */
 
 typedef EMACS_INT Lisp_Object;
-#define LISP_INITIALLY_ZERO 0
+#define LISP_INITIALLY(i) (i)
 enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
 #endif /* CHECK_LISP_OBJECT_TYPE */
+
+#define LISP_INITIALLY_ZERO LISP_INITIALLY (0)
 
 /* Forward declarations.  */
 
@@ -604,18 +609,15 @@ INLINE bool (SYMBOLP) (Lisp_Object);
 INLINE bool (VECTORLIKEP) (Lisp_Object);
 INLINE bool WINDOWP (Lisp_Object);
 INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
+INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object);
+INLINE enum Lisp_Type (XTYPE) (Lisp_Object);
+INLINE void *(XUNTAG) (Lisp_Object, int);
 
 /* Defined in chartab.c.  */
 extern Lisp_Object char_table_ref (Lisp_Object, int);
 extern void char_table_set (Lisp_Object, int, Lisp_Object);
 
 /* Defined in data.c.  */
-extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p;
-extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil;
-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 _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
 extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object);
 
@@ -625,22 +627,122 @@ extern bool might_dump;
    Used during startup to detect startup of dumped Emacs.  */
 extern bool initialized;
 
-/* Defined in eval.c.  */
-extern Lisp_Object Qautoload;
-
 /* Defined in floatfns.c.  */
 extern double extract_float (Lisp_Object);
 
-/* Defined in process.c.  */
-extern Lisp_Object Qprocessp;
+
+/* Interned state of a symbol.  */
+
+enum symbol_interned
+{
+  SYMBOL_UNINTERNED = 0,
+  SYMBOL_INTERNED = 1,
+  SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2
+};
 
-/* Defined in window.c.  */
-extern Lisp_Object Qwindowp;
+enum symbol_redirect
+{
+  SYMBOL_PLAINVAL  = 4,
+  SYMBOL_VARALIAS  = 1,
+  SYMBOL_LOCALIZED = 2,
+  SYMBOL_FORWARDED = 3
+};
+
+struct Lisp_Symbol
+{
+  bool_bf gcmarkbit : 1;
+
+  /* Indicates where the value can be found:
+     0 : it's a plain var, the value is in the `value' field.
+     1 : it's a varalias, the value is really in the `alias' symbol.
+     2 : it's a localized var, the value is in the `blv' object.
+     3 : it's a forwarding variable, the value is in `forward'.  */
+  ENUM_BF (symbol_redirect) redirect : 3;
+
+  /* Non-zero means symbol is constant, i.e. changing its value
+     should signal an error.  If the value is 3, then the var
+     can be changed, but only by `defconst'.  */
+  unsigned constant : 2;
+
+  /* Interned state of the symbol.  This is an enumerator from
+     enum symbol_interned.  */
+  unsigned interned : 2;
+
+  /* True means that this variable has been explicitly declared
+     special (with `defvar' etc), and shouldn't be lexically bound.  */
+  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;
+
+  /* Value of the symbol or Qunbound if unbound.  Which alternative of the
+     union is used depends on the `redirect' field above.  */
+  union {
+    Lisp_Object value;
+    struct Lisp_Symbol *alias;
+    struct Lisp_Buffer_Local_Value *blv;
+    union Lisp_Fwd *fwd;
+  } val;
+
+  /* Function value of the symbol or Qnil if not fboundp.  */
+  Lisp_Object function;
+
+  /* The symbol's property list.  */
+  Lisp_Object plist;
+
+  /* Next symbol in obarray bucket, if the symbol is interned.  */
+  struct Lisp_Symbol *next;
+};
+
+/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
+   meaning as in the DEFUN macro, and is used to construct a prototype.  */
+/* We can use the same trick as in the DEFUN macro to generate the
+   appropriate prototype.  */
+#define EXFUN(fnname, maxargs) \
+  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
+
+/* Note that the weird token-substitution semantics of ANSI C makes
+   this work for MANY and UNEVALLED.  */
+#define DEFUN_ARGS_MANY                (ptrdiff_t, Lisp_Object *)
+#define DEFUN_ARGS_UNEVALLED   (Lisp_Object)
+#define DEFUN_ARGS_0   (void)
+#define DEFUN_ARGS_1   (Lisp_Object)
+#define DEFUN_ARGS_2   (Lisp_Object, Lisp_Object)
+#define DEFUN_ARGS_3   (Lisp_Object, Lisp_Object, Lisp_Object)
+#define DEFUN_ARGS_4   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
+#define DEFUN_ARGS_5   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
+                        Lisp_Object)
+#define DEFUN_ARGS_6   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
+                        Lisp_Object, Lisp_Object)
+#define DEFUN_ARGS_7   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
+                        Lisp_Object, Lisp_Object, Lisp_Object)
+#define DEFUN_ARGS_8   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
+                        Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
+
+/* Yield an integer that contains TAG along with PTR.  */
+#define TAG_PTR(tag, ptr) \
+  ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
+
+/* Yield an integer that contains a symbol tag along with OFFSET.
+   OFFSET should be the offset in bytes from 'lispsym' to the symbol.  */
+#define TAG_SYMOFFSET(offset)                              \
+  TAG_PTR (Lisp_Symbol,                                            \
+          ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS)))
+
+/* Declare extern constants for Lisp symbols.  These can be helpful
+   when using a debugger like GDB, on older platforms where the debug
+   format does not represent C macros.  */
+#define DEFINE_LISP_SYMBOL_BEGIN(name) \
+   DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
+#define DEFINE_LISP_SYMBOL_END(name) \
+   DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMOFFSET (i##name \
+                                                        * sizeof *lispsym)))
+
+#include "globals.h"
 
-/* Defined in xdisp.c.  */
-extern Lisp_Object Qimage;
-extern Lisp_Object Qfontification_functions;
-
 /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
    At the machine level, these operations are no-ops.  */
 LISP_MACRO_DEFUN (XLI, EMACS_INT, (Lisp_Object o), (o))
@@ -731,6 +833,7 @@ LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n))
 LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a))
+LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
 
@@ -785,6 +888,17 @@ XFASTINT (Lisp_Object a)
   return n;
 }
 
+/* Extract A's value as a symbol.  */
+INLINE struct Lisp_Symbol *
+XSYMBOL (Lisp_Object a)
+{
+  uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol);
+  if (! USE_LSB_TAG)
+    i <<= GCTYPEBITS;
+  void *p = (char *) lispsym + i;
+  return p;
+}
+
 /* Extract A's type.  */
 INLINE enum Lisp_Type
 XTYPE (Lisp_Object a)
@@ -797,12 +911,8 @@ XTYPE (Lisp_Object a)
 INLINE void *
 XUNTAG (Lisp_Object a, int type)
 {
-  if (USE_LSB_TAG)
-    {
-      intptr_t i = XLI (a) - type;
-      return (void *) i;
-    }
-  return XPNTR (a);
+  intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+  return (void *) i;
 }
 
 #endif /* ! USE_LSB_TAG */
@@ -864,7 +974,9 @@ XSTRING (Lisp_Object a)
   return XUNTAG (a, Lisp_String);
 }
 
-LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
+/* The index of the C-defined Lisp symbol SYM.
+   This can be used in a static initializer.  */
+#define SYMBOL_INDEX(sym) i##sym
 
 INLINE struct Lisp_Float *
 XFLOAT (Lisp_Object a)
@@ -935,14 +1047,26 @@ XBOOL_VECTOR (Lisp_Object a)
 INLINE Lisp_Object
 make_lisp_ptr (void *ptr, enum Lisp_Type type)
 {
-  EMACS_UINT utype = type;
-  EMACS_UINT typebits = USE_LSB_TAG ? type : utype << VALBITS;
-  Lisp_Object a = XIL (typebits | (uintptr_t) ptr);
+  Lisp_Object a = XIL (TAG_PTR (type, ptr));
   eassert (XTYPE (a) == type && XUNTAG (a, type) == ptr);
   return a;
 }
 
 INLINE Lisp_Object
+make_lisp_symbol (struct Lisp_Symbol *sym)
+{
+  Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+  eassert (XSYMBOL (a) == sym);
+  return a;
+}
+
+INLINE Lisp_Object
+builtin_lisp_symbol (int index)
+{
+  return make_lisp_symbol (lispsym + index);
+}
+
+INLINE Lisp_Object
 make_lisp_proc (struct Lisp_Process *p)
 {
   return make_lisp_ptr (p, Lisp_Vectorlike);
@@ -953,7 +1077,7 @@ make_lisp_proc (struct Lisp_Process *p)
 #define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
 #define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
 #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
-#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol))
+#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
 #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
 #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc))
 
@@ -991,6 +1115,25 @@ make_lisp_proc (struct Lisp_Process *p)
 #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
 #define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE))
 
+/* Efficiently convert a pointer to a Lisp object and back.  The
+   pointer is represented as a Lisp integer, so the garbage collector
+   does not know about it.  The pointer should not have both Lisp_Int1
+   bits set, which makes this conversion inherently unportable.  */
+
+INLINE void *
+XINTPTR (Lisp_Object a)
+{
+  return XUNTAG (a, Lisp_Int0);
+}
+
+INLINE Lisp_Object
+make_pointer_integer (void *p)
+{
+  Lisp_Object a = XIL (TAG_PTR (Lisp_Int0, p));
+  eassert (INTEGERP (a) && XINTPTR (a) == p);
+  return a;
+}
+
 /* Type checking.  */
 
 LISP_MACRO_DEFUN_VOID (CHECK_TYPE,
@@ -1560,72 +1703,6 @@ verify ((offsetof (struct Lisp_Sub_Char_Table, contents)
                               Symbols
  ***********************************************************************/
 
-/* Interned state of a symbol.  */
-
-enum symbol_interned
-{
-  SYMBOL_UNINTERNED = 0,
-  SYMBOL_INTERNED = 1,
-  SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2
-};
-
-enum symbol_redirect
-{
-  SYMBOL_PLAINVAL  = 4,
-  SYMBOL_VARALIAS  = 1,
-  SYMBOL_LOCALIZED = 2,
-  SYMBOL_FORWARDED = 3
-};
-
-struct Lisp_Symbol
-{
-  bool_bf gcmarkbit : 1;
-
-  /* Indicates where the value can be found:
-     0 : it's a plain var, the value is in the `value' field.
-     1 : it's a varalias, the value is really in the `alias' symbol.
-     2 : it's a localized var, the value is in the `blv' object.
-     3 : it's a forwarding variable, the value is in `forward'.  */
-  ENUM_BF (symbol_redirect) redirect : 3;
-
-  /* Non-zero means symbol is constant, i.e. changing its value
-     should signal an error.  If the value is 3, then the var
-     can be changed, but only by `defconst'.  */
-  unsigned constant : 2;
-
-  /* Interned state of the symbol.  This is an enumerator from
-     enum symbol_interned.  */
-  unsigned interned : 2;
-
-  /* True means that this variable has been explicitly declared
-     special (with `defvar' etc), and shouldn't be lexically bound.  */
-  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;
-
-  /* Value of the symbol or Qunbound if unbound.  Which alternative of the
-     union is used depends on the `redirect' field above.  */
-  union {
-    Lisp_Object value;
-    struct Lisp_Symbol *alias;
-    struct Lisp_Buffer_Local_Value *blv;
-    union Lisp_Fwd *fwd;
-  } val;
-
-  /* Function value of the symbol or Qnil if not fboundp.  */
-  Lisp_Object function;
-
-  /* The symbol's property list.  */
-  Lisp_Object plist;
-
-  /* Next symbol in obarray bucket, if the symbol is interned.  */
-  struct Lisp_Symbol *next;
-};
-
 /* Value is name of symbol.  */
 
 LISP_MACRO_DEFUN (SYMBOL_VAL, Lisp_Object, (struct Lisp_Symbol *sym), (sym))
@@ -1699,8 +1776,9 @@ 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 (false)
+/* Placeholder for make-docfile to process.  The actual symbol
+   definition is done by lread.c's defsym.  */
+#define DEFSYM(sym, name) /* empty */
 
 
 /***********************************************************************
@@ -2694,24 +2772,6 @@ CHECK_NUMBER_CDR (Lisp_Object x)
    Lisp_Object fnname
 #endif
 
-/* Note that the weird token-substitution semantics of ANSI C makes
-   this work for MANY and UNEVALLED.  */
-#define DEFUN_ARGS_MANY                (ptrdiff_t, Lisp_Object *)
-#define DEFUN_ARGS_UNEVALLED   (Lisp_Object)
-#define DEFUN_ARGS_0   (void)
-#define DEFUN_ARGS_1   (Lisp_Object)
-#define DEFUN_ARGS_2   (Lisp_Object, Lisp_Object)
-#define DEFUN_ARGS_3   (Lisp_Object, Lisp_Object, Lisp_Object)
-#define DEFUN_ARGS_4   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
-#define DEFUN_ARGS_5   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
-                        Lisp_Object)
-#define DEFUN_ARGS_6   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
-                        Lisp_Object, Lisp_Object)
-#define DEFUN_ARGS_7   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
-                        Lisp_Object, Lisp_Object, Lisp_Object)
-#define DEFUN_ARGS_8   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
-                        Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
-
 /* True if OBJ is a Lisp function.  */
 INLINE bool
 FUNCTIONP (Lisp_Object obj)
@@ -3260,15 +3320,6 @@ extern int gcpro_level;
 
 void staticpro (Lisp_Object *);
 
-/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
-   meaning as in the DEFUN macro, and is used to construct a prototype.  */
-/* We can use the same trick as in the DEFUN macro to generate the
-   appropriate prototype.  */
-#define EXFUN(fnname, maxargs) \
-  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
-
-#include "globals.h"
-
 /* Forward declarations for prototypes.  */
 struct window;
 struct frame;
@@ -3387,30 +3438,6 @@ set_sub_char_table_contents (Lisp_Object table, 
ptrdiff_t idx, Lisp_Object val)
 }
 
 /* Defined in data.c.  */
-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;
-extern Lisp_Object Qinvalid_read_syntax;
-extern Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
-extern Lisp_Object Quser_error, Qend_of_file, Qarith_error, Qmark_inactive;
-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 Qsequencep;
-extern Lisp_Object Qchar_or_string_p, Qinteger_or_marker_p;
-extern Lisp_Object Qfboundp;
-
-extern Lisp_Object Qcdr;
-
-extern Lisp_Object Qrange_error, Qoverflow_error;
-
-extern Lisp_Object Qnumber_or_marker_p;
-
-extern Lisp_Object Qbuffer, Qinteger, Qsymbol;
-
-/* Defined in data.c.  */
 extern Lisp_Object indirect_function (Lisp_Object);
 extern Lisp_Object find_symbol_value (Lisp_Object);
 enum Arith_Comparison {
@@ -3466,7 +3493,6 @@ extern void syms_of_cmds (void);
 extern void keys_of_cmds (void);
 
 /* Defined in coding.c.  */
-extern Lisp_Object Qcharset;
 extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t,
                                          ptrdiff_t, bool, bool, Lisp_Object);
 extern void init_coding (void);
@@ -3490,14 +3516,10 @@ extern void init_syntax_once (void);
 extern void syms_of_syntax (void);
 
 /* Defined in fns.c.  */
-extern Lisp_Object QCrehash_size, QCrehash_threshold;
 enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
 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);
-extern Lisp_Object Qcursor_in_echo_area;
-extern Lisp_Object Qstring_lessp;
-extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq;
 EMACS_UINT hash_string (char const *, ptrdiff_t);
 EMACS_UINT sxhash (Lisp_Object, int);
 Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
@@ -3537,15 +3559,11 @@ extern void init_fringe_once (void);
 #endif /* HAVE_WINDOW_SYSTEM */
 
 /* Defined in image.c.  */
-extern Lisp_Object QCascent, QCmargin, QCrelief;
-extern Lisp_Object QCconversion;
 extern int x_bitmap_mask (struct frame *, ptrdiff_t);
 extern void reset_image_types (void);
 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);
@@ -3600,18 +3618,6 @@ extern Lisp_Object Vwindow_system;
 extern Lisp_Object sit_for (Lisp_Object, bool, int);
 
 /* Defined in xdisp.c.  */
-extern Lisp_Object Qinhibit_point_motion_hooks;
-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 Qtext, Qboth, Qboth_horiz, Qtext_image_horiz;
-extern Lisp_Object Qspace, Qcenter, QCalign_to;
-extern Lisp_Object Qbar, Qhbar, Qhollow;
-extern Lisp_Object Qleft_margin, Qright_margin;
-extern Lisp_Object QCdata, QCfile;
-extern Lisp_Object QCmap;
-extern Lisp_Object Qrisky_local_variable;
 extern bool noninteractive_need_newline;
 extern Lisp_Object echo_area_buffer[2];
 extern void add_to_log (const char *, Lisp_Object, Lisp_Object);
@@ -3745,8 +3751,6 @@ build_string (const char *str)
 
 extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
 extern void make_byte_code (struct Lisp_Vector *);
-extern Lisp_Object Qautomatic_gc;
-extern Lisp_Object Qchar_table_extra_slots;
 extern struct Lisp_Vector *allocate_vector (EMACS_INT);
 
 /* Make an uninitialized vector for SIZE objects.  NOTE: you must
@@ -3850,11 +3854,8 @@ extern void syms_of_chartab (void);
 /* Defined in print.c.  */
 extern Lisp_Object Vprin1_to_string_buffer;
 extern void debug_print (Lisp_Object) EXTERNALLY_VISIBLE;
-extern Lisp_Object Qstandard_output;
-extern Lisp_Object Qexternal_debugging_output;
 extern void temp_output_buffer_setup (const char *);
 extern int print_level;
-extern Lisp_Object Qprint_escape_newlines;
 extern void write_string (const char *, int);
 extern void print_error_message (Lisp_Object, Lisp_Object, const char *,
                                 Lisp_Object);
@@ -3878,13 +3879,11 @@ extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char 
const *, ptrdiff_t,
   ATTRIBUTE_FORMAT_PRINTF (5, 0);
 
 /* Defined in lread.c.  */
-extern Lisp_Object Qsize, Qvariable_documentation, Qstandard_input;
-extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
-extern Lisp_Object Qlexical_binding;
 extern Lisp_Object check_obarray (Lisp_Object);
 extern Lisp_Object intern_1 (const char *, ptrdiff_t);
 extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t);
-extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, ptrdiff_t);
+extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, Lisp_Object);
+extern void init_symbol (Lisp_Object, Lisp_Object);
 extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t);
 INLINE void
 LOADHIST_ATTACH (Lisp_Object x)
@@ -3916,10 +3915,8 @@ intern_c_string (const char *str)
 
 /* Defined in eval.c.  */
 extern EMACS_INT lisp_eval_depth;
-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;
+extern Lisp_Object Vrun_hooks;
 extern Lisp_Object Vsignaling_function;
 extern Lisp_Object inhibit_lisp_code;
 extern struct handler *handlerlist;
@@ -3931,7 +3928,7 @@ extern struct handler *handlerlist;
      call1 (Vrun_hooks, Qmy_funny_hook);
 
    should no longer be used.  */
-extern Lisp_Object Vrun_hooks;
+extern void run_hook (Lisp_Object);
 extern void run_hook_with_args_2 (Lisp_Object, Lisp_Object, Lisp_Object);
 extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
                                       Lisp_Object (*funcall)
@@ -3992,7 +3989,6 @@ extern bool let_shadows_global_binding_p (Lisp_Object 
symbol);
 
 
 /* Defined in editfns.c.  */
-extern Lisp_Object Qfield;
 extern void insert1 (Lisp_Object);
 extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
 extern Lisp_Object save_excursion_save (void);
@@ -4039,12 +4035,6 @@ extern void syms_of_marker (void);
 
 /* Defined in fileio.c.  */
 
-extern Lisp_Object Qfile_error;
-extern Lisp_Object Qfile_notify_error;
-extern Lisp_Object Qfile_exists_p;
-extern Lisp_Object Qfile_directory_p;
-extern Lisp_Object Qinsert_file_contents;
-extern Lisp_Object Qfile_name_history;
 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,
@@ -4061,7 +4051,6 @@ extern bool file_accessible_directory_p (Lisp_Object);
 extern void init_fileio (void);
 extern void syms_of_fileio (void);
 extern Lisp_Object make_temp_name (Lisp_Object, bool);
-extern Lisp_Object Qdelete_file;
 
 /* Defined in search.c.  */
 extern void shrink_regexp_cache (void);
@@ -4091,7 +4080,6 @@ extern void clear_regexp_cache (void);
 
 /* Defined in minibuf.c.  */
 
-extern Lisp_Object Qcompletion_ignore_case;
 extern Lisp_Object Vminibuffer_list;
 extern Lisp_Object last_minibuf_string;
 extern Lisp_Object get_minibuffer (EMACS_INT);
@@ -4100,15 +4088,10 @@ 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);
 
 /* Defined in casefiddle.c.  */
 
-extern Lisp_Object Qidentity;
 extern void syms_of_casefiddle (void);
 extern void keys_of_casefiddle (void);
 
@@ -4122,8 +4105,6 @@ extern void syms_of_casetab (void);
 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;
 extern Lisp_Object last_undo_boundary;
 extern bool input_pending;
 #ifdef HAVE_STACK_OVERFLOW_HANDLING
@@ -4157,7 +4138,6 @@ extern bool indented_beyond_p (ptrdiff_t, ptrdiff_t, 
EMACS_INT);
 extern void syms_of_indent (void);
 
 /* Defined in frame.c.  */
-extern Lisp_Object Qonly, Qnone;
 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);
@@ -4173,9 +4153,7 @@ extern bool display_arg;
 #endif
 extern Lisp_Object decode_env_path (const char *, const char *, bool);
 extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
-extern Lisp_Object Qfile_name_handler_alist;
 extern _Noreturn void terminate_due_to_signal (int, int);
-extern Lisp_Object Qkill_emacs;
 #ifdef WINDOWSNT
 extern Lisp_Object Vlibrary_cache;
 #endif
@@ -4210,7 +4188,6 @@ extern bool inhibit_window_system;
 extern bool running_asynch_code;
 
 /* Defined in process.c.  */
-extern Lisp_Object QCtype, Qlocal;
 extern void kill_buffer_processes (Lisp_Object);
 extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object,
                                        struct Lisp_Process *, int);
@@ -4246,7 +4223,6 @@ extern void set_initial_environment (void);
 extern void syms_of_callproc (void);
 
 /* Defined in doc.c.  */
-extern Lisp_Object Qfunction_documentation;
 extern Lisp_Object read_doc_string (Lisp_Object);
 extern Lisp_Object get_doc_string (Lisp_Object, bool, bool);
 extern void syms_of_doc (void);
@@ -4267,8 +4243,6 @@ extern void init_macros (void);
 extern void syms_of_macros (void);
 
 /* Defined in undo.c.  */
-extern Lisp_Object Qapply;
-extern Lisp_Object Qinhibit_read_only;
 extern void truncate_undo_list (struct buffer *);
 extern void record_insert (ptrdiff_t, ptrdiff_t);
 extern void record_delete (ptrdiff_t, Lisp_Object, bool);
@@ -4278,11 +4252,8 @@ extern void record_property_change (ptrdiff_t, ptrdiff_t,
                                    Lisp_Object, Lisp_Object,
                                     Lisp_Object);
 extern void syms_of_undo (void);
-/* Defined in textprop.c.  */
-extern Lisp_Object Qmouse_face;
-extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks;
-extern Lisp_Object Qminibuffer_prompt;
 
+/* Defined in textprop.c.  */
 extern void report_interval_modification (Lisp_Object, Lisp_Object);
 
 /* Defined in menu.c.  */
@@ -4366,9 +4337,6 @@ extern void init_font (void);
 #ifdef HAVE_WINDOW_SYSTEM
 /* Defined in fontset.c.  */
 extern void syms_of_fontset (void);
-
-/* Defined in xfns.c, w32fns.c, or macfns.c.  */
-extern Lisp_Object Qfont_param;
 #endif
 
 /* Defined in gfilenotify.c */
@@ -4388,16 +4356,6 @@ extern void syms_of_w32notify (void);
 #endif
 
 /* Defined in xfaces.c.  */
-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;
-extern Lisp_Object QCfamily, QCweight, QCslant;
-extern Lisp_Object QCheight, QCname, QCwidth, QCforeground, QCbackground;
-extern Lisp_Object Qextra_light, Qlight, Qsemi_light, Qsemi_bold;
-extern Lisp_Object Qbold, Qextra_bold, Qultra_bold;
-extern Lisp_Object Qoblique, Qitalic;
 extern Lisp_Object Vface_alternative_font_family_alist;
 extern Lisp_Object Vface_alternative_font_registry_alist;
 extern void syms_of_xfaces (void);
diff --git a/src/lread.c b/src/lread.c
index 6463e10..7f7bd89 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -18,6 +18,8 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
+/* Tell globals.h to define tables needed by init_obarray.  */
+#define DEFINE_SYMBOLS
 
 #include <config.h>
 #include "sysstdio.h"
@@ -64,32 +66,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #define file_tell ftell
 #endif
 
-/* Hash table read constants.  */
-static Lisp_Object Qhash_table, Qdata;
-static Lisp_Object Qtest;
-Lisp_Object Qsize;
-static Lisp_Object Qweakness;
-static Lisp_Object Qrehash_size;
-static Lisp_Object Qrehash_threshold;
-
-static Lisp_Object Qread_char, Qget_file_char, Qcurrent_load_list;
-Lisp_Object Qstandard_input;
-Lisp_Object Qvariable_documentation;
-static Lisp_Object Qascii_character, Qload, Qload_file_name;
-Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
-static Lisp_Object Qinhibit_file_name_operation;
-static Lisp_Object Qeval_buffer_list;
-Lisp_Object Qlexical_binding;
-static Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 
*/
-
-/* Used instead of Qget_file_char while loading *.elc files compiled
-   by Emacs 21 or older.  */
-static Lisp_Object Qget_emacs_mule_file_char;
-
-static Lisp_Object Qload_force_doc_strings;
-
-static Lisp_Object Qload_in_progress;
-
 /* The association list of objects read with the #n=object form.
    Each member of the list has the form (n . object), and is used to
    look up the object for the corresponding #n# construct.
@@ -133,7 +109,6 @@ static file_offset prev_saved_doc_string_position;
    Fread initializes this to false, so we need not specbind it
    or worry about what happens to it when there is an error.  */
 static bool new_backquote_flag;
-static Lisp_Object Qold_style_backquotes;
 
 /* A list of file names for files being loaded in Fload.  Used to
    check for recursive loads.  */
@@ -1430,8 +1405,6 @@ directories, make sure the PREDICATE function returns 
`dir-ok' for them.  */)
   return file;
 }
 
-static Lisp_Object Qdir_ok;
-
 /* Search for a file whose name is STR, looking in directories
    in the Lisp list PATH, and trying suffixes from SUFFIX.
    On success, return a file descriptor (or 1 or -2 as described below).
@@ -3792,30 +3765,38 @@ check_obarray (Lisp_Object obarray)
   return obarray;
 }
 
-/* Intern a symbol with name STRING in OBARRAY using bucket INDEX.  */
+/* Intern symbol SYM in OBARRAY using bucket INDEX.  */
 
-Lisp_Object
-intern_driver (Lisp_Object string, Lisp_Object obarray, ptrdiff_t index)
+static Lisp_Object
+intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
 {
-  Lisp_Object *ptr, sym = Fmake_symbol (string);
+  Lisp_Object *ptr;
 
   XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray)
                             ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY
                             : SYMBOL_INTERNED);
 
-  if ((SREF (string, 0) == ':') && EQ (obarray, initial_obarray))
+  if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray))
     {
       XSYMBOL (sym)->constant = 1;
       XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL;
       SET_SYMBOL_VAL (XSYMBOL (sym), sym);
     }
 
-  ptr = aref_addr (obarray, index);
+  ptr = aref_addr (obarray, XINT (index));
   set_symbol_next (sym, SYMBOLP (*ptr) ? XSYMBOL (*ptr) : NULL);
   *ptr = sym;
   return sym;
 }
 
+/* Intern a symbol with name STRING in OBARRAY using bucket INDEX.  */
+
+Lisp_Object
+intern_driver (Lisp_Object string, Lisp_Object obarray, Lisp_Object index)
+{
+  return intern_sym (Fmake_symbol (string), obarray, index);
+}
+
 /* Intern the C string STR: return a symbol with that name,
    interned in the current obarray.  */
 
@@ -3826,7 +3807,7 @@ intern_1 (const char *str, ptrdiff_t len)
   Lisp_Object tem = oblookup (obarray, str, len, len);
 
   return SYMBOLP (tem) ? tem : intern_driver (make_string (str, len),
-                                             obarray, XINT (tem));
+                                             obarray, tem);
 }
 
 Lisp_Object
@@ -3840,10 +3821,27 @@ intern_c_string_1 (const char *str, ptrdiff_t len)
       /* Creating a non-pure string from a string literal not implemented yet.
         We could just use make_string here and live with the extra copy.  */
       eassert (!NILP (Vpurify_flag));
-      tem = intern_driver (make_pure_c_string (str, len), obarray, XINT (tem));
+      tem = intern_driver (make_pure_c_string (str, len), obarray, tem);
     }
   return tem;
 }
+
+static void
+define_symbol (Lisp_Object sym, char const *str)
+{
+  ptrdiff_t len = strlen (str);
+  Lisp_Object string = make_pure_c_string (str, len);
+  init_symbol (sym, string);
+
+  /* Qunbound is uninterned, so that it's not confused with any symbol
+     'unbound' created by a Lisp program.  */
+  if (! EQ (sym, Qunbound))
+    {
+      Lisp_Object bucket = oblookup (initial_obarray, str, len, len);
+      eassert (INTEGERP (bucket));
+      intern_sym (sym, initial_obarray, bucket);
+    }
+}
 
 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
        doc: /* Return the canonical symbol whose name is STRING.
@@ -3859,8 +3857,8 @@ it defaults to the value of `obarray'.  */)
 
   tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
   if (!SYMBOLP (tem))
-    tem = intern_driver (NILP (Vpurify_flag) ? string
-                        : Fpurecopy (string), obarray, XINT (tem));
+    tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string),
+                        obarray, tem);
   return tem;
 }
 
@@ -4059,24 +4057,17 @@ init_obarray (void)
   initial_obarray = Vobarray;
   staticpro (&initial_obarray);
 
-  Qunbound = Fmake_symbol (build_pure_c_string ("unbound"));
-  /* Set temporary dummy values to Qnil and Vpurify_flag to satisfy the
-     NILP (Vpurify_flag) check in intern_c_string.  */
-  Qnil = make_number (-1); Vpurify_flag = make_number (1);
-  Qnil = intern_c_string ("nil");
-
-  /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil,
-     so those two need to be fixed manually.  */
-  SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound);
-  set_symbol_function (Qunbound, Qnil);
-  set_symbol_plist (Qunbound, Qnil);
+  for (int i = 0; i < ARRAYELTS (lispsym); i++)
+    define_symbol (builtin_lisp_symbol (i), defsym_name[i]);
+
+  DEFSYM (Qunbound, "unbound");
+
+  DEFSYM (Qnil, "nil");
   SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil);
   XSYMBOL (Qnil)->constant = 1;
   XSYMBOL (Qnil)->declared_special = true;
-  set_symbol_plist (Qnil, Qnil);
-  set_symbol_function (Qnil, Qnil);
 
-  Qt = intern_c_string ("t");
+  DEFSYM (Qt, "t");
   SET_SYMBOL_VAL (XSYMBOL (Qt), Qt);
   XSYMBOL (Qt)->constant = 1;
   XSYMBOL (Qt)->declared_special = true;
@@ -4729,7 +4720,11 @@ that are loaded before your customizations are read!  
*/);
   DEFSYM (Qstandard_input, "standard-input");
   DEFSYM (Qread_char, "read-char");
   DEFSYM (Qget_file_char, "get-file-char");
+
+  /* Used instead of Qget_file_char while loading *.elc files compiled
+     by Emacs 21 or older.  */
   DEFSYM (Qget_emacs_mule_file_char, "get-emacs-mule-file-char");
+
   DEFSYM (Qload_force_doc_strings, "load-force-doc-strings");
 
   DEFSYM (Qbackquote, "`");
diff --git a/src/macfont.m b/src/macfont.m
index fb28dc8..f569934 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -40,9 +40,6 @@ Original author: YAMAMOTO Mitsuharu
 
 static struct font_driver macfont_driver;
 
-/* Core Text, for Mac OS X.  */
-static Lisp_Object Qmac_ct;
-
 static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph);
 static CGRect mac_ctfont_get_bounding_rect_for_glyph (CTFontRef, CGGlyph);
 static CFArrayRef mac_ctfont_create_available_families (void);
@@ -69,18 +66,6 @@ static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef,
                                              CGFontIndex);
 #endif
 
-/* The font property key specifying the font design destination.  The
-   value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video
-   text.  (See the documentation of X Logical Font Description
-   Conventions.)  In the Mac font driver, 1 means the screen font is
-   used for calculating some glyph metrics.  You can see the
-   difference with Monaco 8pt or 9pt, for example.  */
-static Lisp_Object QCdestination;
-
-/* The boolean-valued font property key specifying the use of
-   leading.  */
-static Lisp_Object QCminspace;
-
 struct macfont_metrics;
 
 /* The actual structure for Mac font that can be cast to struct font.  */
@@ -3927,10 +3912,19 @@ syms_of_macfont (void)
 {
   static struct font_driver mac_font_driver;
 
+  /* Core Text, for Mac OS X.  */
   DEFSYM (Qmac_ct, "mac-ct");
   macfont_driver.type = Qmac_ct;
   register_font_driver (&macfont_driver, NULL);
 
+  /* The font property key specifying the font design destination.  The
+     value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video
+     text.  (See the documentation of X Logical Font Description
+     Conventions.)  In the Mac font driver, 1 means the screen font is
+     used for calculating some glyph metrics.  You can see the
+     difference with Monaco 8pt or 9pt, for example.  */
   DEFSYM (QCdestination, ":destination");
+
+  /* The boolean-valued font property key specifying the use of leading.  */
   DEFSYM (QCminspace, ":minspace");
 }
diff --git a/src/macros.c b/src/macros.c
index 0801f0a..e5b8ab7 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -28,9 +28,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "window.h"
 #include "keyboard.h"
 
-static Lisp_Object Qexecute_kbd_macro;
-static Lisp_Object Qkbd_macro_termination_hook;
-
 /* Number of successful iterations so far
    for innermost keyboard macro.
    This is not bound at each level,
@@ -280,7 +277,7 @@ pop_kbd_macro (Lisp_Object info)
   tem = XCDR (info);
   executing_kbd_macro_index = XINT (XCAR (tem));
   Vreal_this_command = XCDR (tem);
-  Frun_hooks (1, &Qkbd_macro_termination_hook);
+  run_hook (Qkbd_macro_termination_hook);
 }
 
 DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0,
diff --git a/src/menu.h b/src/menu.h
index 182a181..de586a5 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -22,10 +22,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "systime.h" /* for Time */
 #include "../lwlib/lwlib-widget.h"
 
-#ifdef HAVE_NTGUI
-extern Lisp_Object Qunsupported__w32_dialog;
-#endif
-
 /* Bit fields used by terminal-specific menu_show_hook.  */
 
 enum {
diff --git a/src/minibuf.c b/src/minibuf.c
index b43bf7c..07f4892 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -54,37 +54,10 @@ static Lisp_Object minibuf_save_list;
 
 EMACS_INT minibuf_level;
 
-/* The maximum length of a minibuffer history.  */
-
-static Lisp_Object Qhistory_length;
-
 /* Fread_minibuffer leaves the input here as a string.  */
 
 Lisp_Object last_minibuf_string;
 
-static Lisp_Object Qminibuffer_history, Qbuffer_name_history;
-
-static Lisp_Object Qread_file_name_internal;
-
-/* Normal hooks for entry to and exit from minibuffer.  */
-
-static Lisp_Object Qminibuffer_setup_hook;
-static Lisp_Object Qminibuffer_exit_hook;
-
-Lisp_Object Qcompletion_ignore_case;
-static Lisp_Object Qminibuffer_completion_table;
-static Lisp_Object Qminibuffer_completion_predicate;
-static Lisp_Object Qminibuffer_completion_confirm;
-static Lisp_Object Qcustom_variable_p;
-
-static Lisp_Object Qminibuffer_default;
-
-static Lisp_Object Qcurrent_input_method, Qactivate_input_method;
-
-static Lisp_Object Qcase_fold_search;
-
-static Lisp_Object Qread_expression_history;
-
 /* Prompt to display in front of the mini-buffer contents.  */
 
 static Lisp_Object minibuf_prompt;
@@ -699,7 +672,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
   if (STRINGP (input_method) && !NILP (Ffboundp (Qactivate_input_method)))
     call1 (Qactivate_input_method, input_method);
 
-  Frun_hooks (1, &Qminibuffer_setup_hook);
+  run_hook (Qminibuffer_setup_hook);
 
   /* Don't allow the user to undo past this point.  */
   bset_undo_list (current_buffer, Qnil);
@@ -1821,8 +1794,6 @@ the values STRING, PREDICATE and `lambda'.  */)
     return Qt;
 }
 
-static Lisp_Object Qmetadata;
-
 DEFUN ("internal-complete-buffer", Finternal_complete_buffer, 
Sinternal_complete_buffer, 3, 3, 0,
        doc: /* Perform completion on buffer names.
 STRING and PREDICATE have the same meanings as in `try-completion',
@@ -1956,9 +1927,14 @@ syms_of_minibuf (void)
   Fset (Qbuffer_name_history, Qnil);
 
   DEFSYM (Qcustom_variable_p, "custom-variable-p");
+
+  /* Normal hooks for entry to and exit from minibuffer.  */
   DEFSYM (Qminibuffer_setup_hook, "minibuffer-setup-hook");
   DEFSYM (Qminibuffer_exit_hook, "minibuffer-exit-hook");
+
+  /* The maximum length of a minibuffer history.  */
   DEFSYM (Qhistory_length, "history-length");
+
   DEFSYM (Qcurrent_input_method, "current-input-method");
   DEFSYM (Qactivate_input_method, "activate-input-method");
   DEFSYM (Qcase_fold_search, "case-fold-search");
diff --git a/src/nsfns.m b/src/nsfns.m
index 42929b9..828ee88 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -61,35 +61,6 @@ int fns_trace_num = 1;
 
 extern NSArray *ns_send_types, *ns_return_types, *ns_drag_types;
 
-extern Lisp_Object Qforeground_color;
-extern Lisp_Object Qbackground_color;
-extern Lisp_Object Qcursor_color;
-extern Lisp_Object Qinternal_border_width;
-extern Lisp_Object Qvisibility;
-extern Lisp_Object Qcursor_type;
-extern Lisp_Object Qicon_type;
-extern Lisp_Object Qicon_name;
-extern Lisp_Object Qicon_left;
-extern Lisp_Object Qicon_top;
-extern Lisp_Object Qtop;
-extern Lisp_Object Qdisplay;
-extern Lisp_Object Qvertical_scroll_bars;
-extern Lisp_Object Qhorizontal_scroll_bars;
-extern Lisp_Object Qauto_raise;
-extern Lisp_Object Qauto_lower;
-extern Lisp_Object Qbox;
-extern Lisp_Object Qscroll_bar_width;
-extern Lisp_Object Qscroll_bar_height;
-extern Lisp_Object Qx_resource_name;
-extern Lisp_Object Qface_set_after_frame_default;
-extern Lisp_Object Qunderline, Qundefined;
-extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
-extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;
-
-
-Lisp_Object Qbuffered;
-Lisp_Object Qfontsize;
-
 EmacsTooltip *ns_tooltip = nil;
 
 /* Need forward declaration here to preserve organizational integrity of file 
*/
diff --git a/src/nsfont.m b/src/nsfont.m
index 22b3729..f5e89d3 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -45,11 +45,6 @@ Author: Adrian Robert (address@hidden)
 #define NSFONT_TRACE 0
 #define LCD_SMOOTHING_MARGIN 2
 
-extern Lisp_Object Qns;
-extern Lisp_Object Qnormal, Qbold, Qitalic;
-static Lisp_Object Qapple, Qroman, Qmedium;
-static Lisp_Object Qcondensed, Qexpanded;
-extern Lisp_Object Qappend;
 extern float ns_antialias_threshold;
 
 
@@ -1493,7 +1488,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned 
char block)
         characterIndex: (NSUInteger)charIndex
 {
   len = glyphIndex+length;
-  for (i =glyphIndex; i<len; i++) 
+  for (i =glyphIndex; i<len; i++)
     cglyphs[i] = glyphs[i-glyphIndex];
   if (len > maxGlyph)
     maxGlyph = len;
diff --git a/src/nsimage.m b/src/nsimage.m
index 2da22f2..f37ad38 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert 
(address@hidden)
 #include "nsterm.h"
 #include "frame.h"
 
-extern Lisp_Object QCfile, QCdata;
-
 /* call tracing */
 #if 0
 int image_trace_num = 0;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 0e2f4d1..26fe26e 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -59,12 +59,6 @@ int menu_trace_num = 0;
 #include "nsmenu_common.c"
 #endif
 
-extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook;
-extern Lisp_Object QCtoggle, QCradio;
-
-Lisp_Object Qdebug_on_next_call;
-extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-
 extern long context_menu_value;
 EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 
diff --git a/src/nsselect.m b/src/nsselect.m
index e2e5aad..1544b16 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert 
(address@hidden)
 #include "termhooks.h"
 #include "keyboard.h"
 
-static Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME;
-
 static Lisp_Object Vselection_alist;
 
 /* NSGeneralPboard is pretty much analogous to X11 CLIPBOARD */
diff --git a/src/nsterm.h b/src/nsterm.h
index 30c1424..9035ee1 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -792,7 +792,6 @@ struct glyph_string;
 void ns_dump_glyphstring (struct glyph_string *s);
 
 /* Implemented in nsterm, published in or needed from nsfns. */
-extern Lisp_Object Qfontsize;
 extern Lisp_Object ns_list_fonts (struct frame *f, Lisp_Object pattern,
                                   int size, int maxnames);
 extern void ns_clear_frame (struct frame *f);
diff --git a/src/nsterm.m b/src/nsterm.m
index 4a831a8..bf3192b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -225,14 +225,6 @@ static unsigned convert_ns_to_X_keysym[] =
   0x1B,                                0x1B   /* escape */
 };
 
-static Lisp_Object Qmodifier_value;
-Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
-extern Lisp_Object Qcursor_color, Qcursor_type, Qns;
-
-static Lisp_Object QUTF8_STRING;
-static Lisp_Object Qcocoa, Qgnustep;
-static Lisp_Object Qfile, Qurl;
-
 /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold,
    the maximum font size to NOT antialias.  On GNUstep there is currently
    no way to control this behavior. */
@@ -1412,15 +1404,8 @@ x_set_window_size (struct frame *f,
     [view setBoundsOrigin: origin];
   }
 
-  change_frame_size (f, width, height, 0, 1, 0, pixelwise);
-/*  SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
-
-  mark_window_cursors_off (XWINDOW (f->root_window));
-  cancel_mouse_face (f);
-
+  [view updateFrameSize: NO];
   unblock_input ();
-
-  do_pending_window_change (0);
 }
 
 
diff --git a/src/print.c b/src/print.c
index d3ece33..963979e 100644
--- a/src/print.c
+++ b/src/print.c
@@ -75,9 +75,6 @@ static ptrdiff_t print_buffer_pos;
 /* Bytes stored in print_buffer.  */
 static ptrdiff_t print_buffer_pos_byte;
 
-Lisp_Object Qprint_escape_newlines;
-static Lisp_Object Qprint_escape_multibyte, Qprint_escape_nonascii;
-
 /* Vprint_number_table is a table, that keeps objects that are going to
    be printed, to allow use of #n= and #n# to express sharing.
    For any given object, the table can give the following values:
@@ -510,7 +507,7 @@ temp_output_buffer_setup (const char *bufname)
   Ferase_buffer ();
   XSETBUFFER (buf, current_buffer);
 
-  Frun_hooks (1, &Qtemp_buffer_setup_hook);
+  run_hook (Qtemp_buffer_setup_hook);
 
   unbind_to (count, Qnil);
 
@@ -719,10 +716,6 @@ is used instead.  */)
   return object;
 }
 
-/* The subroutine object for external-debugging-output is kept here
-   for the convenience of the debugger.  */
-Lisp_Object Qexternal_debugging_output;
-
 DEFUN ("external-debugging-output", Fexternal_debugging_output, 
Sexternal_debugging_output, 1, 1, 0,
        doc: /* Write CHARACTER to stderr.
 You can call print while debugging emacs, and pass it this function
@@ -2235,7 +2228,10 @@ print_interval (INTERVAL interval, Lisp_Object 
printcharfun)
 void
 init_print_once (void)
 {
+  /* The subroutine object for external-debugging-output is kept here
+     for the convenience of the debugger.  */
   DEFSYM (Qexternal_debugging_output, "external-debugging-output");
+
   defsubr (&Sexternal_debugging_output);
 }
 
diff --git a/src/process.c b/src/process.c
index 6eb0f9e..9015383 100644
--- a/src/process.c
+++ b/src/process.c
@@ -140,12 +140,6 @@ extern int sys_select (int, fd_set *, fd_set *, fd_set *,
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 # pragma GCC diagnostic ignored "-Wstrict-overflow"
 #endif
-
-Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
-Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
-Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
-Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
-Lisp_Object QCname, QCtype;
 
 /* True if keyboard input is on hold, zero otherwise.  */
 
@@ -191,27 +185,6 @@ process_socket (int domain, int type, int protocol)
 # define socket(domain, type, protocol) process_socket (domain, type, protocol)
 #endif
 
-Lisp_Object Qprocessp;
-static Lisp_Object Qrun, Qstop, Qsignal;
-static Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
-Lisp_Object Qlocal;
-static Lisp_Object Qipv4, Qdatagram, Qseqpacket;
-static Lisp_Object Qreal, Qnetwork, Qserial;
-#ifdef AF_INET6
-static Lisp_Object Qipv6;
-#endif
-static Lisp_Object QCport, QCprocess;
-Lisp_Object QCspeed;
-Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
-Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
-static Lisp_Object QCbuffer, QChost, QCservice;
-static Lisp_Object QClocal, QCremote, QCcoding;
-static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
-static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
-static Lisp_Object Qlast_nonmenu_event;
-static Lisp_Object Qinternal_default_process_sentinel;
-static Lisp_Object Qinternal_default_process_filter;
-
 #define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
 #define NETCONN1_P(p) (EQ (p->type, Qnetwork))
 #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial))
@@ -7228,10 +7201,7 @@ syms_of_process (void)
   DEFSYM (Qsignal, "signal");
 
   /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it
-     here again.
-
-     Qexit = intern_c_string ("exit");
-     staticpro (&Qexit); */
+     here again.  */
 
   DEFSYM (Qopen, "open");
   DEFSYM (Qclosed, "closed");
diff --git a/src/process.h b/src/process.h
index 1c46350..7803672 100644
--- a/src/process.h
+++ b/src/process.h
@@ -197,15 +197,6 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object 
val)
    when exiting.  */
 extern bool inhibit_sentinels;
 
-extern Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname;
-extern Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime;
-extern Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
-extern Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtpgid, Qcstime;
-extern Lisp_Object Qtime, Qctime;
-extern Lisp_Object QCspeed;
-extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
-extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
-
 /* Exit statuses for GNU programs that exec other programs.  */
 enum
 {
diff --git a/src/profiler.c b/src/profiler.c
index 3d2c001..1b49afe 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -35,7 +35,6 @@ saturated_add (EMACS_INT a, EMACS_INT b)
 
 typedef struct Lisp_Hash_Table log_t;
 
-static Lisp_Object Qprofiler_backtrace_equal;
 static struct hash_table_test hashtest_profiler;
 
 static Lisp_Object
diff --git a/src/search.c b/src/search.c
index 2e9c992..0252542 100644
--- a/src/search.c
+++ b/src/search.c
@@ -84,12 +84,6 @@ static struct re_registers search_regs;
    Qnil if no searching has been done yet.  */
 static Lisp_Object last_thing_searched;
 
-/* Error condition signaled when regexp compile_pattern fails.  */
-static Lisp_Object Qinvalid_regexp;
-
-/* Error condition used for failing searches.  */
-static Lisp_Object Qsearch_failed;
-
 static void set_search_regs (ptrdiff_t, ptrdiff_t);
 static void save_search_regs (void);
 static EMACS_INT simple_search (EMACS_INT, unsigned char *, ptrdiff_t,
@@ -3329,7 +3323,10 @@ syms_of_search (void)
     }
   searchbuf_head = &searchbufs[0];
 
+  /* Error condition used for failing searches.  */
   DEFSYM (Qsearch_failed, "search-failed");
+
+  /* Error condition signaled when regexp compile_pattern fails.  */
   DEFSYM (Qinvalid_regexp, "invalid-regexp");
 
   Fput (Qsearch_failed, Qerror_conditions,
diff --git a/src/sound.c b/src/sound.c
index 88d86f6..6f7e2ad 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -99,12 +99,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 /* BEGIN: Common Definitions */
 
-/* Symbols.  */
-
-static Lisp_Object QCvolume, QCdevice;
-static Lisp_Object Qsound;
-static Lisp_Object Qplay_sound_functions;
-
 /* Indices of attributes in a sound attributes vector.  */
 
 enum sound_attr
diff --git a/src/syntax.c b/src/syntax.c
index a7ca6ec..2f82156 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -137,9 +137,6 @@ enum
     ST_STRING_STYLE = 256 + 2
   };
 
-static Lisp_Object Qsyntax_table_p;
-static Lisp_Object Qsyntax_table, Qscan_error;
-
 /* This is the internal form of the parse state used in parse-partial-sexp.  */
 
 struct lisp_parse_state
@@ -3500,11 +3497,6 @@ init_syntax_once (void)
   /* This has to be done here, before we call Fmake_char_table.  */
   DEFSYM (Qsyntax_table, "syntax-table");
 
-  /* This variable is DEFSYMed in alloc.c and not initialized yet, so
-     intern it here.  NOTE: you must guarantee that init_syntax_once
-     is called before all other users of this variable.  */
-  Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
-
   /* Create objects which can be shared among syntax tables.  */
   Vsyntax_code_object = make_uninit_vector (Smax);
   for (i = 0; i < Smax; i++)
diff --git a/src/term.c b/src/term.c
index 48447bc..d48bf7b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -130,9 +130,6 @@ enum no_color_bit
 
 static int max_frame_cols;
 
-static Lisp_Object Qtty_mode_set_strings;
-static Lisp_Object Qtty_mode_reset_strings;
-
 
 
 #ifdef HAVE_GPM
@@ -2710,12 +2707,6 @@ static const char *menu_help_message, 
*prev_menu_help_message;
    last menu help message.  */
 static int menu_help_paneno, menu_help_itemno;
 
-static Lisp_Object Qtty_menu_navigation_map, Qtty_menu_exit;
-static Lisp_Object Qtty_menu_prev_item, Qtty_menu_next_item;
-static Lisp_Object Qtty_menu_next_menu, Qtty_menu_prev_menu;
-static Lisp_Object Qtty_menu_select, Qtty_menu_ignore;
-static Lisp_Object Qtty_menu_mouse_movement;
-
 typedef struct tty_menu_struct
 {
   int count;
diff --git a/src/terminal.c b/src/terminal.c
index 65b6895..92befd2 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -37,10 +37,6 @@ static int next_terminal_id;
 /* The initial terminal device, created by initial_term_init.  */
 struct terminal *initial_terminal;
 
-Lisp_Object Qrun_hook_with_args;
-static Lisp_Object Qterminal_live_p;
-static Lisp_Object Qdelete_terminal_functions;
-
 static void delete_initial_terminal (struct terminal *);
 
 /* This setter is used only in this file, so it can be private.  */
diff --git a/src/textprop.c b/src/textprop.c
index 27ab08f..35f22bf 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -44,21 +44,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
   is enforced by the subrs installing properties onto the intervals.  */
 
 
-/* Types of hooks.  */
-static Lisp_Object Qmouse_left;
-static Lisp_Object Qmouse_entered;
-Lisp_Object Qpoint_left;
-Lisp_Object Qpoint_entered;
-Lisp_Object Qcategory;
-Lisp_Object Qlocal_map;
-
-/* Visual properties text (including strings) may have.  */
-static Lisp_Object Qforeground, Qbackground, Qunderline;
-Lisp_Object Qfont;
-static Lisp_Object Qstipple;
-Lisp_Object Qinvisible, Qintangible, Qmouse_face;
-static Lisp_Object Qread_only;
-Lisp_Object Qminibuffer_prompt;
 
 enum property_set_type
 {
@@ -67,9 +52,6 @@ enum property_set_type
   TEXT_PROPERTY_APPEND
 };
 
-/* Sticky properties.  */
-Lisp_Object Qfront_sticky, Qrear_nonsticky;
-
 /* If o1 is a cons whose cdr is a cons, return non-zero and set o2 to
    the o1's cdr.  Otherwise, return zero.  This is handy for
    traversing plists.  */
@@ -2383,7 +2365,7 @@ inherits it if NONSTICKINESS is nil.  The `front-sticky' 
and
   interval_insert_in_front_hooks = Qnil;
 
 
-  /* Common attributes one might give text */
+  /* Common attributes one might give text.  */
 
   DEFSYM (Qforeground, "foreground");
   DEFSYM (Qbackground, "background");
@@ -2401,7 +2383,7 @@ inherits it if NONSTICKINESS is nil.  The `front-sticky' 
and
   DEFSYM (Qmouse_face, "mouse-face");
   DEFSYM (Qminibuffer_prompt, "minibuffer-prompt");
 
-  /* Properties that text might use to specify certain actions */
+  /* Properties that text might use to specify certain actions.  */
 
   DEFSYM (Qmouse_left, "mouse-left");
   DEFSYM (Qmouse_entered, "mouse-entered");
diff --git a/src/undo.c b/src/undo.c
index 46b467a..948dcf9 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -34,12 +34,6 @@ static struct buffer *last_undo_buffer;
 static struct buffer *last_boundary_buffer;
 static ptrdiff_t last_boundary_position;
 
-Lisp_Object Qinhibit_read_only;
-
-/* Marker for function call undo list elements.  */
-
-Lisp_Object Qapply;
-
 /* The first time a command records something for undo.
    it also allocates the undo-boundary object
    which will be added to the list at the end of the command.
@@ -461,6 +455,8 @@ void
 syms_of_undo (void)
 {
   DEFSYM (Qinhibit_read_only, "inhibit-read-only");
+
+  /* Marker for function call undo list elements.  */
   DEFSYM (Qapply, "apply");
 
   pending_boundary = Qnil;
diff --git a/src/w32.c b/src/w32.c
index 3237c7b..31b1328 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -242,8 +242,6 @@ typedef struct _REPARSE_DATA_BUFFER {
 typedef HRESULT (WINAPI * ShGetFolderPath_fn)
   (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
 
-Lisp_Object QCloaded_from;
-
 void globals_of_w32 (void);
 static DWORD get_rid (PSID);
 static int is_symlink (const char *);
diff --git a/src/w32.h b/src/w32.h
index a8a525c..835557d 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -172,7 +172,6 @@ extern void init_timers (void);
 extern int _sys_read_ahead (int fd);
 extern int _sys_wait_accept (int fd);
 
-extern Lisp_Object QCloaded_from;
 extern HMODULE w32_delayed_load (Lisp_Object);
 
 extern int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
diff --git a/src/w32fns.c b/src/w32fns.c
index 26eeb5f..789a91a 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -93,19 +93,6 @@ extern char * w32_strerror (int error_no);
 #define IDC_HAND MAKEINTRESOURCE(32649)
 #endif
 
-Lisp_Object Qundefined_color;
-Lisp_Object Qcancel_timer;
-Lisp_Object Qfont_param;
-Lisp_Object Qhyper;
-Lisp_Object Qsuper;
-Lisp_Object Qmeta;
-Lisp_Object Qalt;
-Lisp_Object Qctrl;
-Lisp_Object Qcontrol;
-Lisp_Object Qshift;
-static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes;
-
-
 /* Prefix for system colors.  */
 #define SYSTEM_COLOR_PREFIX "System"
 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
@@ -6141,7 +6128,7 @@ Text larger than the specified size is clipped.  */)
                 place the cursor there.  Don't include the width of
                 this glyph.  */
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
          else
@@ -6151,7 +6138,7 @@ Text larger than the specified size is clipped.  */)
                 Don't count that glyph.  */
              struct glyph *g = row->glyphs[TEXT_AREA];
 
-             if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
+             if (g->type == STRETCH_GLYPH && NILP (g->object))
                {
                  row_width -= g->pixel_width;
                  seen_reversed_p = 1;
@@ -6200,7 +6187,7 @@ Text larger than the specified size is clipped.  */)
          if (row->used[TEXT_AREA] && !row->reversed_p)
            {
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
 
@@ -7248,7 +7235,7 @@ The return value is the hotkey-id if registered, 
otherwise nil.  */)
       /* Notify input thread about new hot-key definition, so that it
         takes effect without needing to switch focus.  */
       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
-                        (WPARAM) XLI (key), 0);
+                        (WPARAM) XINT (key), 0);
     }
 
   return key;
diff --git a/src/w32font.c b/src/w32font.c
index 1b0a8a2..ab77267 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -57,51 +57,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #define JOHAB_CHARSET 130
 #endif
 
-Lisp_Object Qgdi;
-Lisp_Object Quniscribe;
-static Lisp_Object QCformat;
-static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
-static Lisp_Object Qserif, Qscript, Qdecorative;
-static Lisp_Object Qraster, Qoutline, Qunknown;
-
-/* antialiasing  */
-static Lisp_Object Qstandard, Qsubpixel, Qnatural;
-
-/* languages */
-static Lisp_Object Qzh;
-
-/* scripts */
-static Lisp_Object Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
-static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
-static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
-static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
-static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
-static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
-static Lisp_Object Qkhmer, Qmongolian, Qbraille, Qhan;
-static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
-static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
-static Lisp_Object Qmusical_symbol, Qmathematical, Qcham, Qphonetic;
-/* Not defined in characters.el, but referenced in fontset.el.  */
-static Lisp_Object Qbalinese, Qbuginese, Qbuhid, Qcuneiform, Qcypriot;
-static Lisp_Object Qdeseret, Qglagolitic, Qgothic, Qhanunoo, Qkharoshthi;
-static Lisp_Object Qlimbu, Qlinear_b, Qold_italic, Qold_persian, Qosmanya;
-static Lisp_Object Qphags_pa, Qphoenician, Qshavian, Qsyloti_nagri;
-static Lisp_Object Qtagalog, Qtagbanwa, Qtai_le, Qtifinagh, Qugaritic;
-
-/* W32 charsets: for use in Vw32_charset_info_alist.  */
-static Lisp_Object Qw32_charset_ansi, Qw32_charset_default;
-static Lisp_Object Qw32_charset_symbol, Qw32_charset_shiftjis;
-static Lisp_Object Qw32_charset_hangeul, Qw32_charset_gb2312;
-static Lisp_Object Qw32_charset_chinesebig5, Qw32_charset_oem;
-static Lisp_Object Qw32_charset_easteurope, Qw32_charset_turkish;
-static Lisp_Object Qw32_charset_baltic, Qw32_charset_russian;
-static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek;
-static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese;
-static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac;
-
-/* Font spacing symbols - defined in font.c.  */
-extern Lisp_Object Qc, Qp, Qm;
-
 static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object);
 
 static BYTE w32_antialias_type (Lisp_Object);
@@ -291,7 +246,7 @@ intern_font_name (char * string)
   Lisp_Object obarray = check_obarray (Vobarray);
   Lisp_Object tem = oblookup (obarray, SDATA (str), len, len);
   /* This code is similar to intern function from lread.c.  */
-  return SYMBOLP (tem) ? tem : intern_driver (str, obarray, XINT (tem));
+  return SYMBOLP (tem) ? tem : intern_driver (str, obarray, tem);
 }
 
 /* w32 implementation of get_cache for font backend.
diff --git a/src/w32inevt.c b/src/w32inevt.c
index daf4a5c..e09903f 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -657,11 +657,12 @@ handle_file_notifications (struct input_event *hold_quit)
              Lisp_Object action = lispy_file_action (fni->Action);
 
              inev.kind = FILE_NOTIFY_EVENT;
-             inev.code = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
              inev.timestamp = GetTickCount ();
              inev.modifiers = 0;
              inev.frame_or_window = callback;
              inev.arg = Fcons (action, fname);
+             inev.arg = list3 (make_pointer_integer (notifications_desc),
+                               action, fname);
              kbd_buffer_store_event_hold (&inev, hold_quit);
 
              if (!fni->NextEntryOffset)
diff --git a/src/w32menu.c b/src/w32menu.c
index 72e0cab..7a946d2 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -98,8 +98,6 @@ AppendMenuW_Proc unicode_append_menu = NULL;
 MessageBoxW_Proc unicode_message_box = NULL;
 #endif /* NTGUI_UNICODE */
 
-Lisp_Object Qdebug_on_next_call, Qunsupported__w32_dialog;
-
 void set_frame_menubar (struct frame *, bool, bool);
 
 #ifdef HAVE_DIALOGS
diff --git a/src/w32notify.c b/src/w32notify.c
index 764ded6..ab6cd12 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -118,9 +118,7 @@ BYTE file_notifications[16384];
 DWORD notifications_size;
 void *notifications_desc;
 
-static Lisp_Object Qfile_name, Qdirectory_name, Qattributes;
-static Lisp_Object Qlast_write_time, Qlast_access_time, Qcreation_time;
-static Lisp_Object Qsecurity_desc, Qsubtree, watch_list;
+static Lisp_Object watch_list;
 
 /* Signal to the main thread that we have file notifications for it to
    process.  */
@@ -582,7 +580,7 @@ generate notifications correctly, though.  */)
        report_file_error ("Cannot watch file", Fcons (file, Qnil));
     }
   /* Store watch object in watch list. */
-  watch_descriptor = XIL ((EMACS_INT)dirwatch);
+  watch_descriptor = make_pointer_integer (dirwatch);
   watch_object = Fcons (watch_descriptor, callback);
   watch_list = Fcons (watch_object, watch_list);
 
@@ -607,7 +605,7 @@ WATCH-DESCRIPTOR should be an object returned by 
`w32notify-add-watch'.  */)
   if (!NILP (watch_object))
     {
       watch_list = Fdelete (watch_object, watch_list);
-      dirwatch = (struct notification *)XLI (watch_descriptor);
+      dirwatch = (struct notification *)XINTPTR (watch_descriptor);
       if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)))
        status = remove_watch (dirwatch);
     }
@@ -622,7 +620,7 @@ WATCH-DESCRIPTOR should be an object returned by 
`w32notify-add-watch'.  */)
 Lisp_Object
 w32_get_watch_object (void *desc)
 {
-  Lisp_Object descriptor = XIL ((EMACS_INT)desc);
+  Lisp_Object descriptor = make_pointer_integer (desc);
 
   /* This is called from the input queue handling code, inside a
      critical section, so we cannot possibly QUIT if watch_list is not
diff --git a/src/w32proc.c b/src/w32proc.c
index 0c178e7..26cfa29 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -72,8 +72,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD);
            + ((DWORD_PTR)(var) - (section)->VirtualAddress)            \
            + (filedata).file_base))
 
-Lisp_Object Qhigh, Qlow;
-
 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly.  */
 static signal_handler sig_handlers[NSIG];
 
diff --git a/src/w32select.c b/src/w32select.c
index f133f6d..3c554c6 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -107,17 +107,11 @@ static Lisp_Object validate_coding_system (Lisp_Object 
coding_system);
 static void setup_windows_coding_system (Lisp_Object coding_system,
                                         struct coding_system * coding);
 
-
-/* A remnant from X11: Symbol for the CLIPBORD selection type.  Other
-   selections are not used on Windows, so we don't need symbols for
-   PRIMARY and SECONDARY.  */
-Lisp_Object QCLIPBOARD;
-
 /* Internal pseudo-constants, initialized in globals_of_w32select()
    based on current system parameters. */
 static LCID DEFAULT_LCID;
 static UINT ANSICP, OEMCP;
-static Lisp_Object QUNICODE, QANSICP, QOEMCP;
+static Lisp_Object QANSICP, QOEMCP;
 
 /* A hidden window just for the clipboard management. */
 static HWND clipboard_owner;
diff --git a/src/w32term.c b/src/w32term.c
index e692d9d..ce28e05 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -220,10 +220,6 @@ static void w32fullscreen_hook (struct frame *);
 static void x_check_font (struct frame *, struct font *);
 #endif
 
-static Lisp_Object Qvendor_specific_keysyms;
-static Lisp_Object Qadded, Qremoved, Qmodified;
-static Lisp_Object Qrenamed_from, Qrenamed_to;
-
 
 /***********************************************************************
                              Debugging
@@ -3251,12 +3247,11 @@ queue_notifications (struct input_event *event, W32Msg 
*msg, struct frame *f,
              Lisp_Object action = lispy_file_action (fni->Action);
 
              event->kind = FILE_NOTIFY_EVENT;
-             event->code
-               = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
              event->timestamp = msg->msg.time;
              event->modifiers = 0;
              event->frame_or_window = callback;
-             event->arg = Fcons (action, fname);
+             event->arg = list3 (make_pointer_integer (notifications_desc),
+                                 action, fname);
              kbd_buffer_store_event (event);
              (*evcount)++;
 
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index 29fea6a..2a7fe2e 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -47,10 +47,6 @@ struct uniscribe_font_info
 
 int uniscribe_available = 0;
 
-/* Defined in w32font.c, since it is required there as well.  */
-extern Lisp_Object Quniscribe;
-extern Lisp_Object Qopentype;
-
 /* EnumFontFamiliesEx callback.  */
 static int CALLBACK ALIGN_STACK add_opentype_font_name_to_list (ENUMLOGFONTEX 
*,
                                                                NEWTEXTMETRICEX 
*,
diff --git a/src/window.c b/src/window.c
index 4da3350..4dec976 100644
--- a/src/window.c
+++ b/src/window.c
@@ -48,20 +48,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "xwidget.h"
 #endif
 
-Lisp_Object Qwindowp, Qwindow_live_p;
-static Lisp_Object Qwindow_valid_p;
-static Lisp_Object Qwindow_configuration_p;
-static Lisp_Object Qrecord_window_buffer;
-static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
-static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
-static Lisp_Object Qwindow_resize_root_window, 
Qwindow_resize_root_window_vertically;
-static Lisp_Object Qwindow_sanitize_window_sizes;
-static Lisp_Object Qwindow_pixel_to_total;
-static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
-static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
-static Lisp_Object Qfloor, Qceiling;
-static Lisp_Object Qwindow_point_insertion_type;
-
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
 static int get_leaf_windows (struct window *, struct window **, int);
@@ -118,15 +104,9 @@ Lisp_Object minibuf_window;
    shown as the selected window when the minibuffer is selected.  */
 Lisp_Object minibuf_selected_window;
 
-/* Hook run at end of temp_output_buffer_show.  */
-static Lisp_Object Qtemp_buffer_show_hook;
-
 /* Incremented for each window created.  */
 static int sequence_number;
 
-/* Hook to run when window config changes.  */
-static Lisp_Object Qwindow_configuration_change_hook;
-
 /* Used by the function window_scroll_pixel_based.  */
 static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
@@ -997,7 +977,10 @@ or scroll bars.
 If PIXELWISE is nil, return the largest integer smaller than WINDOW's
 pixel width divided by the character width of WINDOW's frame.  This
 means that if a column at the right of the text area is only partially
-visible, that column is not counted.  */)
+visible, that column is not counted.
+
+Note that the returned value includes the column reserved for the
+continuation glyph.  */)
   (Lisp_Object window, Lisp_Object pixelwise)
 {
   return make_number (window_body_width (decode_live_window (window),
@@ -3656,7 +3639,7 @@ temp_output_buffer_show (register Lisp_Object buf)
         record_unwind_protect (select_window_norecord, prev_window);
         Fselect_window (window, Qt);
         Fset_buffer (w->contents);
-        Frun_hooks (1, &Qtemp_buffer_show_hook);
+        run_hook (Qtemp_buffer_show_hook);
         unbind_to (count, Qnil);
       }
     }
diff --git a/src/window.h b/src/window.h
index 2ed0f3e..2ec28ab 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1085,7 +1085,6 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
   CHECK_TYPE (WINDOW_LIVE_P (WINDOW), Qwindow_live_p, WINDOW)
 
 /* These used to be in lisp.h.  */
-extern Lisp_Object Qwindow_live_p;
 extern Lisp_Object Vwindow_list;
 
 extern Lisp_Object window_list (void);
diff --git a/src/xdisp.c b/src/xdisp.c
index bd6ab62..8b68ab7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -327,52 +327,9 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #define INFINITY 10000000
 
-Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-Lisp_Object Qwindow_scroll_functions;
-static Lisp_Object Qwindow_text_change_functions;
-static Lisp_Object Qredisplay_end_trigger_functions;
-Lisp_Object Qinhibit_point_motion_hooks;
-static Lisp_Object QCeval, QCpropertize;
-Lisp_Object QCfile, QCdata;
-static Lisp_Object Qfontified;
-static Lisp_Object Qgrow_only;
-static Lisp_Object Qinhibit_eval_during_redisplay;
-static Lisp_Object Qbuffer_position, Qposition, Qobject;
-static Lisp_Object Qright_to_left, Qleft_to_right;
-
-/* Cursor shapes.  */
-Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
-
-/* Pointer shapes.  */
-static Lisp_Object Qarrow, Qhand;
-Lisp_Object Qtext;
-
 /* Holds the list (error).  */
 static Lisp_Object list_of_error;
 
-Lisp_Object Qfontification_functions;
-
-static Lisp_Object Qwrap_prefix;
-static Lisp_Object Qline_prefix;
-static Lisp_Object Qredisplay_internal;
-
-/* Non-nil means don't actually do any redisplay.  */
-
-Lisp_Object Qinhibit_redisplay;
-
-/* Names of text properties relevant for redisplay.  */
-
-Lisp_Object Qdisplay;
-
-Lisp_Object Qspace, QCalign_to;
-static Lisp_Object QCrelative_width, QCrelative_height;
-Lisp_Object Qleft_margin, Qright_margin;
-static Lisp_Object Qspace_width, Qraise;
-static Lisp_Object Qslice;
-Lisp_Object Qcenter;
-static Lisp_Object Qmargin, Qpointer;
-static Lisp_Object Qline_height;
-
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Test if overflow newline into fringe.  Called with iterator IT
@@ -406,31 +363,6 @@ static Lisp_Object Qline_height;
           && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' '                 \
               || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t'))))         \
 
-/* Name of the face used to highlight trailing whitespace.  */
-
-static Lisp_Object Qtrailing_whitespace;
-
-/* Name and number of the face used to highlight escape glyphs.  */
-
-static Lisp_Object Qescape_glyph;
-
-/* Name and number of the face used to highlight non-breaking spaces.  */
-
-static Lisp_Object Qnobreak_space;
-
-/* The symbol `image' which is the car of the lists used to represent
-   images in Lisp.  Also a tool bar style.  */
-
-Lisp_Object Qimage;
-
-/* The image map types.  */
-Lisp_Object QCmap;
-static Lisp_Object QCpointer;
-static Lisp_Object Qrect, Qcircle, Qpoly;
-
-/* Tool bar styles */
-Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
-
 /* Non-zero means print newline to stdout before next mini-buffer
    message.  */
 
@@ -480,21 +412,6 @@ static struct text_pos this_line_min_pos;
 
 static struct buffer *this_line_buffer;
 
-
-/* Values of those variables at last redisplay are stored as
-   properties on `overlay-arrow-position' symbol.  However, if
-   Voverlay_arrow_position is a marker, last-arrow-position is its
-   numerical position.  */
-
-static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
-
-/* Alternative overlay-arrow-string and overlay-arrow-bitmap
-   properties on a symbol in overlay-arrow-variable-list.  */
-
-static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
-
-Lisp_Object Qmenu_bar_update_hook;
-
 /* Nonzero if an overlay arrow has been displayed in this window.  */
 
 static bool overlay_arrow_seen;
@@ -570,11 +487,6 @@ static bool display_last_displayed_message_p;
 
 static bool message_buf_print;
 
-/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable.  */
-
-static Lisp_Object Qinhibit_menubar_update;
-static Lisp_Object Qmessage_truncate_lines;
-
 /* Set to 1 in clear_message to make redisplay_internal aware
    of an emptied echo area.  */
 
@@ -694,8 +606,6 @@ int trace_move;
 #define TRACE_MOVE(x)  (void) 0
 #endif
 
-static Lisp_Object Qauto_hscroll_mode;
-
 /* Buffer being redisplayed -- for redisplay_window_error.  */
 
 static struct buffer *displayed_buffer;
@@ -715,8 +625,8 @@ enum prop_handled
 
 struct props
 {
-  /* The name of the property.  */
-  Lisp_Object *name;
+  /* The symbol index of the name of the property.  */
+  short name;
 
   /* A unique index for the property.  */
   enum prop_idx idx;
@@ -737,14 +647,14 @@ static enum prop_handled handle_fontified_prop (struct it 
*);
 
 static struct props it_props[] =
 {
-  {&Qfontified,                FONTIFIED_PROP_IDX,     handle_fontified_prop},
+  {SYMBOL_INDEX (Qfontified),  FONTIFIED_PROP_IDX,     handle_fontified_prop},
   /* Handle `face' before `display' because some sub-properties of
      `display' need to know the face.  */
-  {&Qface,             FACE_PROP_IDX,          handle_face_prop},
-  {&Qdisplay,          DISPLAY_PROP_IDX,       handle_display_prop},
-  {&Qinvisible,                INVISIBLE_PROP_IDX,     handle_invisible_prop},
-  {&Qcomposition,      COMPOSITION_PROP_IDX,   handle_composition_prop},
-  {NULL,               0,                      NULL}
+  {SYMBOL_INDEX (Qface),       FACE_PROP_IDX,          handle_face_prop},
+  {SYMBOL_INDEX (Qdisplay),    DISPLAY_PROP_IDX,       handle_display_prop},
+  {SYMBOL_INDEX (Qinvisible),  INVISIBLE_PROP_IDX,     handle_invisible_prop},
+  {SYMBOL_INDEX (Qcomposition),        COMPOSITION_PROP_IDX, 
handle_composition_prop},
+  {0,                          0,                      NULL}
 };
 
 /* Value is the position described by X.  If X is a marker, value is
@@ -799,9 +709,6 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 
 bool redisplaying_p;
 
-static Lisp_Object Qinhibit_free_realized_faces;
-static Lisp_Object Qmode_line_default_help_echo;
-
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
 
@@ -827,15 +734,6 @@ static struct atimer *hourglass_atimer;
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Name of the face used to display glyphless characters.  */
-static Lisp_Object Qglyphless_char;
-
-/* Symbol for the purpose of Vglyphless_char_display.  */
-static Lisp_Object Qglyphless_char_display;
-
-/* Method symbols for Vglyphless_char_display.  */
-static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
-
 /* Default number of seconds to wait before displaying an hourglass
    cursor.  */
 #define DEFAULT_HOURGLASS_DELAY 1
@@ -2702,8 +2600,6 @@ safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
   return retval;
 }
 
-static Lisp_Object Qeval;
-
 Lisp_Object
 safe_eval (Lisp_Object sexpr)
 {
@@ -3626,7 +3522,8 @@ compute_stop_pos (struct it *it)
 
       /* Get properties here.  */
       for (p = it_props; p->handler; ++p)
-       values_here[p->idx] = textget (iv->plist, *p->name);
+       values_here[p->idx] = textget (iv->plist,
+                                      builtin_lisp_symbol (p->name));
 
       /* Look for an interval following iv that has different
         properties.  */
@@ -3638,9 +3535,8 @@ compute_stop_pos (struct it *it)
        {
          for (p = it_props; p->handler; ++p)
            {
-             Lisp_Object new_value;
-
-             new_value = textget (next_iv->plist, *p->name);
+             Lisp_Object new_value = textget (next_iv->plist,
+                                              builtin_lisp_symbol (p->name));
              if (!EQ (values_here[p->idx], new_value))
                break;
            }
@@ -8081,7 +7977,7 @@ next_element_from_c_string (struct it *it)
   eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
   it->what = IT_CHARACTER;
   BYTEPOS (it->position) = CHARPOS (it->position) = 0;
-  it->object = Qnil;
+  it->object = make_number (0);
 
   /* With bidi reordering, the character to display might not be the
      character at IT_CHARPOS.  BIDI_IT.FIRST_ELT non-zero means that
@@ -13534,7 +13430,7 @@ redisplay_internal (void)
   specbind (Qinhibit_free_realized_faces, Qnil);
 
   /* Record this function, so it appears on the profiler's backtraces.  */
-  record_in_backtrace (Qredisplay_internal, &Qnil, 0);
+  record_in_backtrace (Qredisplay_internal, 0, 0);
 
   FOR_EACH_FRAME (tail, frame)
     XFRAME (frame)->already_hscrolled_p = 0;
@@ -14441,14 +14337,14 @@ set_cursor_from_row (struct window *w, struct 
glyph_row *row,
       if (!row->reversed_p)
        {
          while (glyph < end
-                && INTEGERP (glyph->object)
+                && NILP (glyph->object)
                 && glyph->charpos < 0)
            {
              x += glyph->pixel_width;
              ++glyph;
            }
          while (end > glyph
-                && INTEGERP ((end - 1)->object)
+                && NILP ((end - 1)->object)
                 /* CHARPOS is zero for blanks and stretch glyphs
                    inserted by extend_face_to_end_of_line.  */
                 && (end - 1)->charpos <= 0)
@@ -14466,20 +14362,20 @@ set_cursor_from_row (struct window *w, struct 
glyph_row *row,
          glyph += row->used[TEXT_AREA] - 1;
 
          while (glyph > end + 1
-                && INTEGERP (glyph->object)
+                && NILP (glyph->object)
                 && glyph->charpos < 0)
            {
              --glyph;
              x -= glyph->pixel_width;
            }
-         if (INTEGERP (glyph->object) && glyph->charpos < 0)
+         if (NILP (glyph->object) && glyph->charpos < 0)
            --glyph;
          /* By default, in reversed rows we put the cursor on the
             rightmost (first in the reading order) glyph.  */
          for (g = end + 1; g < glyph; g++)
            x += g->pixel_width;
          while (end < glyph
-                && INTEGERP ((end + 1)->object)
+                && NILP ((end + 1)->object)
                 && (end + 1)->charpos <= 0)
            ++end;
          glyph_before = glyph + 1;
@@ -14510,7 +14406,7 @@ set_cursor_from_row (struct window *w, struct glyph_row 
*row,
     while (/* not marched to end of glyph row */
           glyph < end
           /* glyph was not inserted by redisplay for internal purposes */
-          && !INTEGERP (glyph->object))
+          && !NILP (glyph->object))
       {
        if (BUFFERP (glyph->object))
          {
@@ -14598,7 +14494,7 @@ set_cursor_from_row (struct window *w, struct glyph_row 
*row,
        ++glyph;
       }
   else if (glyph > end)        /* row is reversed */
-    while (!INTEGERP (glyph->object))
+    while (!NILP (glyph->object))
       {
        if (BUFFERP (glyph->object))
          {
@@ -14675,16 +14571,16 @@ set_cursor_from_row (struct window *w, struct 
glyph_row *row,
        && BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && !(bpos_max <= pt_old && pt_old <= bpos_covered))
     {
-      /* An empty line has a single glyph whose OBJECT is zero and
+      /* An empty line has a single glyph whose OBJECT is nil and
         whose CHARPOS is the position of a newline on that line.
         Note that on a TTY, there are more glyphs after that, which
         were produced by extend_face_to_end_of_line, but their
         CHARPOS is zero or negative.  */
       int empty_line_p =
        (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
-       && INTEGERP (glyph->object) && glyph->charpos > 0
+       && NILP (glyph->object) && glyph->charpos > 0
        /* On a TTY, continued and truncated rows also have a glyph at
-          their end whose OBJECT is zero and whose CHARPOS is
+          their end whose OBJECT is nil and whose CHARPOS is
           positive (the continuation and truncation glyphs), but such
           rows are obviously not "empty".  */
        && !(row->continued_p || row->truncated_on_right_p);
@@ -14961,7 +14857,7 @@ set_cursor_from_row (struct window *w, struct glyph_row 
*row,
                          && string_from_text_prop)
                      /* this candidate is from newline and its
                         position is not an exact match */
-                     || (INTEGERP (glyph->object)
+                     || (NILP (glyph->object)
                          && glyph->charpos != pt_old)))))
        return 0;
       /* If this candidate gives an exact match, use that.  */
@@ -14970,7 +14866,7 @@ set_cursor_from_row (struct window *w, struct glyph_row 
*row,
               terminating newline of a line, and point is on that
               newline, it wins because it's an exact match.  */
            || (!row->continued_p
-               && INTEGERP (glyph->object)
+               && NILP (glyph->object)
                && glyph->charpos == 0
                && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
          /* Otherwise, keep the candidate that comes from a row
@@ -15813,7 +15709,7 @@ try_cursor_movement (Lisp_Object window, struct 
text_pos startp, int *scroll_ste
 
                          exact_match_p =
                            (BUFFERP (g->object) && g->charpos == PT)
-                           || (INTEGERP (g->object)
+                           || (NILP (g->object)
                                && (g->charpos == PT
                                    || (g->charpos == 0 && endpos - 1 == PT)));
                        }
@@ -18674,7 +18570,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18697,7 +18593,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18718,7 +18614,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18739,7 +18635,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18862,7 +18758,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int 
glyphs)
              struct glyph *glyph = row->glyphs[area] + i;
              if (i == row->used[area] - 1
                  && area == TEXT_AREA
-                 && INTEGERP (glyph->object)
+                 && NILP (glyph->object)
                  && glyph->type == CHAR_GLYPH
                  && glyph->u.ch == ' ')
                {
@@ -19092,7 +18988,7 @@ insert_left_trunc_glyphs (struct it *it)
   truncate_it.area = TEXT_AREA;
   truncate_it.glyph_row->used[TEXT_AREA] = 0;
   CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
-  truncate_it.object = make_number (0);
+  truncate_it.object = Qnil;
   produce_special_glyphs (&truncate_it, IT_TRUNCATION);
 
   /* Overwrite glyphs from IT with truncation glyphs.  */
@@ -19375,7 +19271,7 @@ append_space_for_newline (struct it *it, int 
default_face_p)
 
          it->what = IT_CHARACTER;
          memset (&it->position, 0, sizeof it->position);
-         it->object = make_number (0);
+         it->object = Qnil;
          it->c = it->char_to_display = ' ';
          it->len = 1;
 
@@ -19567,7 +19463,7 @@ extend_face_to_end_of_line (struct it *it)
              else
                it->face_id = face->id;
              it->start_of_box_run_p = 0;
-             append_stretch_glyph (it, make_number (0), stretch_width,
+             append_stretch_glyph (it, Qnil, stretch_width,
                                    it->ascent + it->descent, stretch_ascent);
              it->position = saved_pos;
              it->avoid_cursor_p = saved_avoid_cursor;
@@ -19597,7 +19493,7 @@ extend_face_to_end_of_line (struct it *it)
 
       it->what = IT_CHARACTER;
       memset (&it->position, 0, sizeof it->position);
-      it->object = make_number (0);
+      it->object = Qnil;
       it->c = it->char_to_display = ' ';
       it->len = 1;
 
@@ -19726,14 +19622,14 @@ highlight_trailing_whitespace (struct frame *f, 
struct glyph_row *row)
        {
          while (glyph >= start
                 && glyph->type == CHAR_GLYPH
-                && INTEGERP (glyph->object))
+                && NILP (glyph->object))
            --glyph;
        }
       else
        {
          while (glyph <= start
                 && glyph->type == CHAR_GLYPH
-                && INTEGERP (glyph->object))
+                && NILP (glyph->object))
            ++glyph;
        }
 
@@ -20096,10 +19992,9 @@ find_row_edges (struct it *it, struct glyph_row *row,
            {
              start = r1->glyphs[TEXT_AREA];
              end = start + r1->used[TEXT_AREA];
-             /* Glyphs inserted by redisplay have an integer (zero)
-                as their object.  */
+             /* Glyphs inserted by redisplay have nil as their object.  */
              while (end > start
-                    && INTEGERP ((end - 1)->object)
+                    && NILP ((end - 1)->object)
                     && (end - 1)->charpos <= 0)
                --end;
              if (end > start)
@@ -20120,7 +20015,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
              end = r1->glyphs[TEXT_AREA] - 1;
              start = end + r1->used[TEXT_AREA];
              while (end < start
-                    && INTEGERP ((end + 1)->object)
+                    && NILP ((end + 1)->object)
                     && (end + 1)->charpos <= 0)
                ++end;
              if (end < start)
@@ -21273,7 +21168,7 @@ Value is the new character position of point.  */)
 
 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH)         \
   (!(ROW)->continued_p                         \
-   && INTEGERP ((GLYPH)->object)               \
+   && NILP ((GLYPH)->object)                   \
    && (GLYPH)->type == CHAR_GLYPH              \
    && (GLYPH)->u.ch == ' '                     \
    && (GLYPH)->charpos >= 0                    \
@@ -21315,7 +21210,7 @@ Value is the new character position of point.  */)
              w->cursor.vpos = -1;
              return make_number (PT);
            }
-         else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
+         else if (!NILP (g->object) && !EQ (g->object, gpt->object))
            {
              ptrdiff_t new_pos;
 
@@ -21352,7 +21247,7 @@ Value is the new character position of point.  */)
              return make_number (PT);
            }
        }
-      if (g == e || INTEGERP (g->object))
+      if (g == e || NILP (g->object))
        {
          if (row->truncated_on_left_p || row->truncated_on_right_p)
            goto simulate_display;
@@ -21385,7 +21280,7 @@ Value is the new character position of point.  */)
                         EOB also has one glyph, but its charpos is -1.  */
                      || (row->ends_at_zv_p
                          && !row->reversed_p
-                         && INTEGERP (g->object)
+                         && NILP (g->object)
                          && g->type == CHAR_GLYPH
                          && g->u.ch == ' '))
                    {
@@ -21423,7 +21318,7 @@ Value is the new character position of point.  */)
                      || g->type == STRETCH_GLYPH
                      || (row->ends_at_zv_p
                          && row->reversed_p
-                         && INTEGERP (g->object)
+                         && NILP (g->object)
                          && g->type == CHAR_GLYPH
                          && g->u.ch == ' '))
                    {
@@ -21787,13 +21682,13 @@ Emacs UBA implementation, in particular with the test 
suite.  */)
          /* Skip over glyphs at the start of the row that was
             generated by redisplay for its own needs.  */
          while (g < e
-                && INTEGERP (g->object)
+                && NILP (g->object)
                 && g->charpos < 0)
            g++;
          g1 = g;
 
          /* Count the "interesting" glyphs in this row.  */
-         for (nglyphs = 0; g < e && !INTEGERP (g->object); g++)
+         for (nglyphs = 0; g < e && !NILP (g->object); g++)
            nglyphs++;
 
          /* Create and fill the array.  */
@@ -21806,11 +21701,11 @@ Emacs UBA implementation, in particular with the test 
suite.  */)
          g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
          e = row->glyphs[TEXT_AREA] - 1;
          while (g > e
-                && INTEGERP (g->object)
+                && NILP (g->object)
                 && g->charpos < 0)
            g--;
          g1 = g;
-         for (nglyphs = 0; g > e && !INTEGERP (g->object); g--)
+         for (nglyphs = 0; g > e && !NILP (g->object); g--)
            nglyphs++;
          levels = make_uninit_vector (nglyphs);
          for (i = 0; g1 > g; i++, g1--)
@@ -26273,7 +26168,7 @@ produce_special_glyphs (struct it *it, enum 
display_element_type what)
   GLYPH glyph;
 
   temp_it = *it;
-  temp_it.object = make_number (0);
+  temp_it.object = Qnil;
   memset (&temp_it.current, 0, sizeof temp_it.current);
 
   if (what == IT_CONTINUATION)
@@ -26336,7 +26231,7 @@ produce_special_glyphs (struct it *it, enum 
display_element_type what)
            (((temp_it.ascent + temp_it.descent)
              * FONT_BASE (font)) / FONT_HEIGHT (font));
 
-         append_stretch_glyph (&temp_it, make_number (0), stretch_width,
+         append_stretch_glyph (&temp_it, Qnil, stretch_width,
                                temp_it.ascent + temp_it.descent,
                                stretch_ascent);
        }
@@ -28522,7 +28417,7 @@ rows_from_pos_range (struct window *w,
 
          while (g < e)
            {
-             if (((BUFFERP (g->object) || INTEGERP (g->object))
+             if (((BUFFERP (g->object) || NILP (g->object))
                   && start_charpos <= g->charpos && g->charpos < end_charpos)
                  /* A glyph that comes from DISP_STRING is by
                     definition to be highlighted.  */
@@ -28577,7 +28472,7 @@ rows_from_pos_range (struct window *w,
 
          while (g < e)
            {
-             if (((BUFFERP (g->object) || INTEGERP (g->object))
+             if (((BUFFERP (g->object) || NILP (g->object))
                   && ((start_charpos <= g->charpos && g->charpos < end_charpos)
                       /* If the buffer position of the first glyph in
                          the row is equal to END_CHARPOS, it means
@@ -28659,7 +28554,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
        {
          struct glyph *beg = prev->glyphs[TEXT_AREA];
          glyph = beg + prev->used[TEXT_AREA];
-         while (--glyph >= beg && INTEGERP (glyph->object));
+         while (--glyph >= beg && NILP (glyph->object));
          if (glyph < beg
              || !(EQ (glyph->object, before_string)
                   || EQ (glyph->object, disp_string)))
@@ -28723,7 +28618,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
        for (; glyph < end
-              && INTEGERP (glyph->object)
+              && NILP (glyph->object)
               && glyph->charpos < 0;
             ++glyph)
          x += glyph->pixel_width;
@@ -28732,7 +28627,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph < end
-            && !INTEGERP (glyph->object)
+            && !NILP (glyph->object)
             && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
@@ -28774,7 +28669,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
        for (; glyph > end
-              && INTEGERP (glyph->object)
+              && NILP (glyph->object)
               && glyph->charpos < 0;
             --glyph)
          ;
@@ -28783,7 +28678,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph > end
-            && !INTEGERP (glyph->object)
+            && !NILP (glyph->object)
             && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
@@ -28840,7 +28735,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         row, and also blanks and stretch glyphs inserted by
         extend_face_to_end_of_line.  */
       while (end > glyph
-            && INTEGERP ((end - 1)->object))
+            && NILP ((end - 1)->object))
        --end;
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
@@ -28848,7 +28743,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         and END_CHARPOS */
       for (--end;
             end > glyph
-            && !INTEGERP (end->object)
+            && !NILP (end->object)
             && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
@@ -28886,7 +28781,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       x = r2->x;
       end++;
       while (end < glyph
-            && INTEGERP (end->object))
+            && NILP (end->object))
        {
          x += end->pixel_width;
          ++end;
@@ -28897,7 +28792,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         and END_CHARPOS */
       for ( ;
             end < glyph
-            && !INTEGERP (end->object)
+            && !NILP (end->object)
             && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
@@ -29829,12 +29724,12 @@ note_mouse_highlight (struct frame *f, int x, int y)
       if (glyph == NULL
          || area != TEXT_AREA
          || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
-         /* Glyph's OBJECT is an integer for glyphs inserted by the
+         /* Glyph's OBJECT is nil for glyphs inserted by the
             display engine for its internal purposes, like truncation
             and continuation glyphs and blanks beyond the end of
             line's text on text terminals.  If we are over such a
             glyph, we are not over any text.  */
-         || INTEGERP (glyph->object)
+         || NILP (glyph->object)
          /* R2L rows have a stretch glyph at their front, which
             stands for no text, whereas L2R rows have no glyphs at
             all beyond the end of text.  Treat such stretch glyphs
@@ -30806,7 +30701,9 @@ syms_of_xdisp (void)
   Vmessage_stack = Qnil;
   staticpro (&Vmessage_stack);
 
+  /* Non-nil means don't actually do any redisplay.  */
   DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
+
   DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
 
   message_dolog_marker1 = Fmake_marker ();
@@ -30845,6 +30742,8 @@ syms_of_xdisp (void)
   DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
   DEFSYM (Qeval, "eval");
   DEFSYM (QCdata, ":data");
+
+  /* Names of text properties relevant for redisplay.  */
   DEFSYM (Qdisplay, "display");
   DEFSYM (Qspace_width, "space-width");
   DEFSYM (Qraise, "raise");
@@ -30864,40 +30763,69 @@ syms_of_xdisp (void)
   DEFSYM (QCfile, ":file");
   DEFSYM (Qfontified, "fontified");
   DEFSYM (Qfontification_functions, "fontification-functions");
+
+  /* Name of the face used to highlight trailing whitespace.  */
   DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
+
+  /* Name and number of the face used to highlight escape glyphs.  */
   DEFSYM (Qescape_glyph, "escape-glyph");
+
+  /* Name and number of the face used to highlight non-breaking spaces.  */
   DEFSYM (Qnobreak_space, "nobreak-space");
+
+  /* The symbol 'image' which is the car of the lists used to represent
+     images in Lisp.  Also a tool bar style.  */
   DEFSYM (Qimage, "image");
+
+  /* Tool bar styles.  */
   DEFSYM (Qtext, "text");
   DEFSYM (Qboth, "both");
   DEFSYM (Qboth_horiz, "both-horiz");
   DEFSYM (Qtext_image_horiz, "text-image-horiz");
+
+  /* The image map types.  */
   DEFSYM (QCmap, ":map");
   DEFSYM (QCpointer, ":pointer");
   DEFSYM (Qrect, "rect");
   DEFSYM (Qcircle, "circle");
   DEFSYM (Qpoly, "poly");
+
+  /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable.  */
+  DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
   DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
+
   DEFSYM (Qgrow_only, "grow-only");
-  DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
   DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
   DEFSYM (Qposition, "position");
   DEFSYM (Qbuffer_position, "buffer-position");
   DEFSYM (Qobject, "object");
+
+  /* Cursor shapes.  */
   DEFSYM (Qbar, "bar");
   DEFSYM (Qhbar, "hbar");
   DEFSYM (Qbox, "box");
   DEFSYM (Qhollow, "hollow");
+
+  /* Pointer shapes.  */
   DEFSYM (Qhand, "hand");
   DEFSYM (Qarrow, "arrow");
+  /* also Qtext */
+
   DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
 
   list_of_error = list1 (list2 (intern_c_string ("error"),
                                intern_c_string ("void-variable")));
   staticpro (&list_of_error);
 
+  /* Values of those variables at last redisplay are stored as
+     properties on 'overlay-arrow-position' symbol.  However, if
+     Voverlay_arrow_position is a marker, last-arrow-position is its
+     numerical position.  */
   DEFSYM (Qlast_arrow_position, "last-arrow-position");
   DEFSYM (Qlast_arrow_string, "last-arrow-string");
+
+  /* Alternative overlay-arrow-string and overlay-arrow-bitmap
+     properties on a symbol in overlay-arrow-variable-list.  */
   DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
   DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
 
@@ -31397,7 +31325,10 @@ cursor shapes.  */);
   hourglass_shown_p = 0;
 #endif /* HAVE_WINDOW_SYSTEM */
 
+  /* Name of the face used to display glyphless characters.  */
   DEFSYM (Qglyphless_char, "glyphless-char");
+
+  /* Method symbols for Vglyphless_char_display.  */
   DEFSYM (Qhex_code, "hex-code");
   DEFSYM (Qempty_box, "empty-box");
   DEFSYM (Qthin_space, "thin-space");
@@ -31410,6 +31341,7 @@ be redisplayed.  This set can be nil (meaning, only the 
selected window),
 or t (meaning all windows).  */);
   Vpre_redisplay_function = intern ("ignore");
 
+  /* Symbol for the purpose of Vglyphless_char_display.  */
   DEFSYM (Qglyphless_char_display, "glyphless-char-display");
   Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
 
diff --git a/src/xfaces.c b/src/xfaces.c
index 0600f53..6ecd857 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -278,57 +278,8 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #define FACE_CACHE_BUCKETS_SIZE 1001
 
-/* Keyword symbols used for face attribute names.  */
-
-Lisp_Object QCfamily, QCheight, QCweight, QCslant;
-static Lisp_Object QCunderline;
-static Lisp_Object QCinverse_video, QCstipple;
-Lisp_Object QCforeground, QCbackground;
-Lisp_Object QCwidth;
-static Lisp_Object QCfont, QCbold, QCitalic;
-static Lisp_Object QCreverse_video;
-static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
-static Lisp_Object QCfontset, QCdistant_foreground;
-
-/* Symbols used for attribute values.  */
-
-Lisp_Object Qnormal;
-Lisp_Object Qbold;
-static Lisp_Object Qline, Qwave;
-Lisp_Object Qextra_light, Qlight;
-Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
-Lisp_Object Qoblique;
-Lisp_Object Qitalic;
-static Lisp_Object Qreleased_button, Qpressed_button;
-static Lisp_Object QCstyle, QCcolor, QCline_width;
-Lisp_Object Qunspecified;      /* used in dosfns.c */
-static Lisp_Object QCignore_defface;
-
 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
 
-/* The name of the function to call when the background of the frame
-   has changed, frame_set_background_mode.  */
-
-static Lisp_Object Qframe_set_background_mode;
-
-/* Names of basic faces.  */
-
-Lisp_Object Qdefault, Qtool_bar, Qfringe;
-static Lisp_Object Qregion;
-Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
-static Lisp_Object Qborder, Qmouse, Qmenu;
-Lisp_Object Qmode_line_inactive;
-static Lisp_Object Qvertical_border;
-static Lisp_Object Qwindow_divider;
-static Lisp_Object Qwindow_divider_first_pixel;
-static Lisp_Object Qwindow_divider_last_pixel;
-
-/* The symbol `face-alias'.  A symbols having that property is an
-   alias for another face.  Value of the property is the name of
-   the aliased face.  */
-
-static Lisp_Object Qface_alias;
-
 /* Alist of alternative font families.  Each element is of the form
    (FAMILY FAMILY1 FAMILY2 ...).  If fonts of FAMILY can't be loaded,
    try FAMILY1, then FAMILY2, ...  */
@@ -341,32 +292,6 @@ Lisp_Object Vface_alternative_font_family_alist;
 
 Lisp_Object Vface_alternative_font_registry_alist;
 
-/* Allowed scalable fonts.  A value of nil means don't allow any
-   scalable fonts.  A value of t means allow the use of any scalable
-   font.  Otherwise, value must be a list of regular expressions.  A
-   font may be scaled if its name matches a regular expression in the
-   list.  */
-
-static Lisp_Object Qscalable_fonts_allowed;
-
-/* The symbols `foreground-color' and `background-color' which can be
-   used as part of a `face' property.  This is for compatibility with
-   Emacs 20.2.  */
-
-Lisp_Object Qforeground_color, Qbackground_color;
-
-/* The symbols `face' and `mouse-face' used as text properties.  */
-
-Lisp_Object Qface;
-
-/* Property for basic faces which other faces cannot inherit.  */
-
-static Lisp_Object Qface_no_inherit;
-
-/* Error symbol for wrong_type_argument in load_pixmap.  */
-
-static Lisp_Object Qbitmap_spec_p;
-
 /* The next ID to assign to Lisp faces.  */
 
 static int next_lface_id;
@@ -376,14 +301,6 @@ static int next_lface_id;
 static Lisp_Object *lface_id_to_name;
 static ptrdiff_t lface_id_to_name_size;
 
-/* TTY color-related functions (defined in tty-colors.el).  */
-
-static Lisp_Object Qtty_color_desc, Qtty_color_by_index, 
Qtty_color_standard_values;
-
-/* The name of the function used to compute colors on TTYs.  */
-
-static Lisp_Object Qtty_color_alist;
-
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Counter for calls to clear_face_cache.  If this counter reaches
@@ -6397,9 +6314,17 @@ DEFUN ("show-face-resources", Fshow_face_resources, 
Sshow_face_resources,
 void
 syms_of_xfaces (void)
 {
+  /* The symbols `face' and `mouse-face' used as text properties.  */
   DEFSYM (Qface, "face");
+
+  /* Property for basic faces which other faces cannot inherit.  */
   DEFSYM (Qface_no_inherit, "face-no-inherit");
+
+  /* Error symbol for wrong_type_argument in load_pixmap.  */
   DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
+
+  /* The name of the function to call when the background of the frame
+     has changed, frame_set_background_mode.  */
   DEFSYM (Qframe_set_background_mode, "frame-set-background-mode");
 
   /* Lisp face attribute keywords.  */
@@ -6442,12 +6367,22 @@ syms_of_xfaces (void)
   DEFSYM (Qultra_bold, "ultra-bold");
   DEFSYM (Qoblique, "oblique");
   DEFSYM (Qitalic, "italic");
+
+  /* The symbols `foreground-color' and `background-color' which can be
+     used as part of a `face' property.  This is for compatibility with
+     Emacs 20.2.  */
   DEFSYM (Qbackground_color, "background-color");
   DEFSYM (Qforeground_color, "foreground-color");
+
   DEFSYM (Qunspecified, "unspecified");
   DEFSYM (QCignore_defface, ":ignore-defface");
 
+  /* The symbol `face-alias'.  A symbol having that property is an
+     alias for another face.  Value of the property is the name of
+     the aliased face.  */
   DEFSYM (Qface_alias, "face-alias");
+
+  /* Names of basic faces.  */
   DEFSYM (Qdefault, "default");
   DEFSYM (Qtool_bar, "tool-bar");
   DEFSYM (Qregion, "region");
@@ -6460,13 +6395,23 @@ syms_of_xfaces (void)
   DEFSYM (Qmouse, "mouse");
   DEFSYM (Qmode_line_inactive, "mode-line-inactive");
   DEFSYM (Qvertical_border, "vertical-border");
+
+  /* TTY color-related functions (defined in tty-colors.el).  */
   DEFSYM (Qwindow_divider, "window-divider");
   DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
   DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
   DEFSYM (Qtty_color_desc, "tty-color-desc");
   DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
   DEFSYM (Qtty_color_by_index, "tty-color-by-index");
+
+  /* The name of the function used to compute colors on TTYs.  */
   DEFSYM (Qtty_color_alist, "tty-color-alist");
+
+  /* Allowed scalable fonts.  A value of nil means don't allow any
+     scalable fonts.  A value of t means allow the use of any scalable
+     font.  Otherwise, value must be a list of regular expressions.  A
+     font may be scaled if its name matches a regular expression in the
+     list.  */
   DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
 
   Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
diff --git a/src/xfns.c b/src/xfns.c
index 2ea5f06..4a41752 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -125,10 +125,6 @@ extern LWLIB_ID widget_id_tick;
 
 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
 
-static Lisp_Object Qundefined_color;
-static Lisp_Object Qcompound_text, Qcancel_timer;
-Lisp_Object Qfont_param;
-
 #ifdef GLYPH_DEBUG
 static ptrdiff_t image_cache_refcount;
 static int dpyinfo_refcount;
@@ -5498,7 +5494,7 @@ Text larger than the specified size is clipped.  */)
          if (!row->reversed_p)
            {
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
          else
@@ -5508,7 +5504,7 @@ Text larger than the specified size is clipped.  */)
                 Don't count that glyph.  */
              struct glyph *g = row->glyphs[TEXT_AREA];
 
-             if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
+             if (g->type == STRETCH_GLYPH && NILP (g->object))
                {
                  row_width -= g->pixel_width;
                  seen_reversed_p = 1;
@@ -5552,7 +5548,7 @@ Text larger than the specified size is clipped.  */)
          if (row->used[TEXT_AREA] && !row->reversed_p)
            {
              last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-             if (INTEGERP (last->object))
+             if (NILP (last->object))
                row_width -= last->pixel_width;
            }
 
diff --git a/src/xftfont.c b/src/xftfont.c
index f0ad8db..c587d81 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -38,9 +38,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 /* Xft font driver.  */
 
-Lisp_Object Qxft;
-static Lisp_Object QChinting, QCautohint, QChintstyle, QCrgba, QCembolden,
-  QClcdfilter;
 
 /* The actual structure for Xft font that can be cast to struct
    font.  */
diff --git a/src/xmenu.c b/src/xmenu.c
index c6bb9fa..fd667a8 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -108,8 +108,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #define TRUE 1
 #endif /* no TRUE */
 
-static Lisp_Object Qdebug_on_next_call;
-
+
 /* Flag which when set indicates a dialog or menu has been posted by
    Xt on behalf of one of the widget sets.  */
 static int popup_activated_flag;
diff --git a/src/xml.c b/src/xml.c
index 11a6e45..3e64788 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -29,8 +29,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "buffer.h"
 
 
-static Lisp_Object Qlibxml2_dll;
-
 #ifdef WINDOWSNT
 
 # include <windows.h>
diff --git a/src/xselect.c b/src/xselect.c
index 92460d1..33ff366 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -80,19 +80,6 @@ static void lisp_data_to_selection_data (struct 
x_display_info *, Lisp_Object,
 #define TRACE2(fmt, a0, a1)    (void) 0
 #endif
 
-
-static Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
-  QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
-  QATOM_PAIR, QCLIPBOARD_MANAGER, QSAVE_TARGETS;
-
-static Lisp_Object QCOMPOUND_TEXT;     /* This is a type of selection.  */
-static Lisp_Object QUTF8_STRING;       /* This is a type of selection.  */
-
-static Lisp_Object Qcompound_text_with_extensions;
-
-static Lisp_Object Qforeign_selection;
-static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
-
 /* Bytes needed to represent 'long' data.  This is as per libX11; it
    is not necessarily sizeof (long).  */
 #define X_LONG_SIZE 4
@@ -2687,8 +2674,11 @@ A value of 0 means wait as long as necessary.  This is 
initialized from the
   DEFSYM (QCLIPBOARD, "CLIPBOARD");
   DEFSYM (QTIMESTAMP, "TIMESTAMP");
   DEFSYM (QTEXT, "TEXT");
+
+  /* These are types of selection.  */
   DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
   DEFSYM (QUTF8_STRING, "UTF8_STRING");
+
   DEFSYM (QDELETE, "DELETE");
   DEFSYM (QMULTIPLE, "MULTIPLE");
   DEFSYM (QINCR, "INCR");
diff --git a/src/xsettings.c b/src/xsettings.c
index ec45d47..8dbc7d9 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -51,8 +51,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 static char *current_mono_font;
 static char *current_font;
 static struct x_display_info *first_dpyinfo;
-static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render,
-  Qtool_bar_style;
 static Lisp_Object current_tool_bar_style;
 
 /* Store an config changed event in to the event queue.  */
diff --git a/src/xterm.c b/src/xterm.c
index e3f4739..9a87a1e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -183,17 +183,9 @@ static Time ignore_next_mouse_click_timeout;
 
 static int x_noop_count;
 
-static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
-
-static Lisp_Object Qvendor_specific_keysyms;
-static Lisp_Object Qlatin_1;
-
 #ifdef USE_GTK
 /* The name of the Emacs icon file.  */
 static Lisp_Object xg_default_icon_file;
-
-/* Used in gtkutil.c.  */
-Lisp_Object Qx_gtk_map_stock;
 #endif
 
 /* Some functions take this as char *, not const char *.  */
diff --git a/src/xterm.h b/src/xterm.h
index 25ce67b..f2aff72 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1111,9 +1111,6 @@ extern bool x_session_have_connection (void);
 extern void x_session_close (void);
 #endif
 
-/* Defined in xterm.c */
-
-extern Lisp_Object Qx_gtk_map_stock;
 
 /* Is the frame embedded into another application? */
 
diff --git a/test/ChangeLog b/test/ChangeLog
index bb06147..83bb8bf 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,57 @@
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-tests.el (eieio-test-23-inheritance-check): Don't use
+       <foo>-child-p.
+
+       * automated/eieio-test-methodinvoke.el (eieio-test-method-store):
+       Update reference to eieio--generic-call-key.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-tests.el: Use cl-lib.  Don't use <class> as a 
variable.
+       Don't use <class>-list types and <class>-list-p predicates.
+
+       * automated/eieio-test-persist.el (persistent-with-objs-list-slot):
+       Don't use <class>-list type.
+
+       * automated/eieio-test-methodinvoke.el
+       (eieio-test-method-order-list-4):
+       Don't use <class> as a variable.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-tests.el (eieio-test-04-static-method)
+       (eieio-test-05-static-method-2): Use oref-default to access
+       class slots.
+       (eieio-test-23-inheritance-check): Don't assume that
+       eieio-class-parents returns class names, or that a class can only have
+       a single name.
+
+       * automated/eieio-test-persist.el (eieio--attribute-to-initarg):
+       Move from eieio-core.el.  Rename from eieio-attribute-to-initarg.
+       Change arg to be a class object.  Update all callers.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-test-methodinvoke.el (eieio-test-method-store):
+       Adjust to new semantics of eieio--scoped-class.
+       (eieio-test-match): Improve error feedback.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-tests.el: Remove dummy object names.
+
+       * automated/eieio-test-persist.el (persistent-with-objs-slot-subs):
+       The type FOO-child is the same as FOO.
+
+2015-01-08  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-test-methodinvoke.el (eieio-test-method-store):
+       Remove use of eieio-generic-call-methodname.
+       (eieio-test-method-order-list-3, eieio-test-method-order-list-6)
+       (eieio-test-method-order-list-7, eieio-test-method-order-list-8):
+       Adjust the expected result accordingly.
+
 2015-01-01  Michael Albinus  <address@hidden>
 
        * automated/tramp-tests.el (tramp--test-smb-or-windows-nt-p):
@@ -19,8 +73,7 @@
 2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
 
        * automated/python-tests.el
-       (python-shell-completion-native-interpreter-disabled-p-1): New
-       test.
+       (python-shell-completion-native-interpreter-disabled-p-1): New test.
 
 2014-12-27  Fabián Ezequiel Gallina  <address@hidden>
 
@@ -110,8 +163,8 @@
        (vc-test--create-repo-function): Rename from
        `vc-test--create-repo-if-not-supported'.  Adapt all callees.
        (vc-test--create-repo): Check also for revision-granularity.
-       (vc-test--unregister-function): Additional argument FILE.  Adapt
-       all callees.
+       (vc-test--unregister-function): Additional argument FILE.
+       Adapt all callees.
        (vc-test--working-revision): New defun.
        (vc-test-*-working-revision): New tests.
 
@@ -148,7 +201,7 @@
 2014-11-21  Ulf Jasper  <address@hidden>
 
        * automated/libxml-tests.el
-       (libxml-tests--data-comments-preserved): Renamed from
+       (libxml-tests--data-comments-preserved): Rename from
        'libxml-tests--data'.
        (libxml-tests--data-comments-discarded): New.
        (libxml-tests): Check whether 'libxml-parse-xml-region' is
@@ -175,8 +228,8 @@
 
 2014-11-17  Ulf Jasper  <address@hidden>
 
-       * automated/icalendar-tests.el (icalendar-tests--test-export): New
-       optional parameter `alarms'.
+       * automated/icalendar-tests.el (icalendar-tests--test-export):
+       New optional parameter `alarms'.
        (icalendar-export-alarms): New test for exporting icalendar
        alarms.
        (icalendar-tests--test-cycle): Let `icalendar-export-alarms' be nil.
@@ -190,8 +243,8 @@
 
 2014-11-16  Ulf Jasper  <address@hidden>
 
-       * automated/icalendar-tests.el (icalendar--parse-vtimezone): Add
-       testcase where offsets of standard time and daylight saving time
+       * automated/icalendar-tests.el (icalendar--parse-vtimezone):
+       Add testcase where offsets of standard time and daylight saving time
        are equal.
        (icalendar-real-world): Fix error in test case.  Expected result
        was wrong when offsets of standard time and daylight saving time
diff --git a/test/automated/eieio-test-methodinvoke.el 
b/test/automated/eieio-test-methodinvoke.el
index f2fe378..2de836c 100644
--- a/test/automated/eieio-test-methodinvoke.el
+++ b/test/automated/eieio-test-methodinvoke.el
@@ -61,16 +61,17 @@
 (defun eieio-test-method-store ()
   "Store current invocation class symbol in the invocation order list."
   (let* ((keysym (aref [ :STATIC :BEFORE :PRIMARY :AFTER ]
-                      (or eieio-generic-call-key 0)))
-        (c (list eieio-generic-call-methodname keysym (eieio--scoped-class))))
-    (setq eieio-test-method-order-list
-         (cons c eieio-test-method-order-list))))
+                      (or eieio--generic-call-key 0)))
+         ;; FIXME: Don't depend on `eieio--scoped-class'!
+        (c (list keysym (eieio--class-symbol (eieio--scoped-class)))))
+    (push c eieio-test-method-order-list)))
 
 (defun eieio-test-match (rightanswer)
   "Do a test match."
   (if (equal rightanswer eieio-test-method-order-list)
       t
-    (error "eieio-test-methodinvoke.el: Test Failed!")))
+    (error "eieio-test-methodinvoke.el: Test Failed: %S != %S"
+           rightanswer eieio-test-method-order-list)))
 
 (defvar eieio-test-call-next-method-arguments nil
   "List of passed to methods during execution of `call-next-method'.")
@@ -121,17 +122,17 @@
 (ert-deftest eieio-test-method-order-list-3 ()
   (let ((eieio-test-method-order-list nil)
        (ans '(
-              (eitest-F :BEFORE eitest-B)
-              (eitest-F :BEFORE eitest-B-base1)
-              (eitest-F :BEFORE eitest-B-base2)
+              (:BEFORE eitest-B)
+              (:BEFORE eitest-B-base1)
+              (:BEFORE eitest-B-base2)
 
-              (eitest-F :PRIMARY eitest-B)
-              (eitest-F :PRIMARY eitest-B-base1)
-              (eitest-F :PRIMARY eitest-B-base2)
+              (:PRIMARY eitest-B)
+              (:PRIMARY eitest-B-base1)
+              (:PRIMARY eitest-B-base2)
 
-              (eitest-F :AFTER eitest-B-base2)
-              (eitest-F :AFTER eitest-B-base1)
-              (eitest-F :AFTER eitest-B)
+              (:AFTER eitest-B-base2)
+              (:AFTER eitest-B-base1)
+              (:AFTER eitest-B)
               )))
     (eitest-F (eitest-B nil))
     (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list))
@@ -145,7 +146,7 @@
 
 (ert-deftest eieio-test-method-order-list-4 ()
   ;; Both of these situations should succeed.
-  (should (eitest-H eitest-A))
+  (should (eitest-H 'eitest-A))
   (should (eitest-H (eitest-A nil))))
 
 ;;; Return value from :PRIMARY
@@ -176,17 +177,18 @@
 (defclass C-base2 () ())
 (defclass C (C-base1 C-base2) ())
 
+;; Just use the obsolete name once, to make sure it also works.
 (defmethod constructor :STATIC ((p C-base1) &rest args)
   (eieio-test-method-store)
   (if (next-method-p) (call-next-method))
   )
 
-(defmethod constructor :STATIC ((p C-base2) &rest args)
+(defmethod eieio-constructor :STATIC ((p C-base2) &rest args)
   (eieio-test-method-store)
   (if (next-method-p) (call-next-method))
   )
 
-(defmethod constructor :STATIC ((p C) &rest args)
+(defmethod eieio-constructor :STATIC ((p C) &rest args)
   (eieio-test-method-store)
   (call-next-method)
   )
@@ -194,9 +196,9 @@
 (ert-deftest eieio-test-method-order-list-6 ()
   (let ((eieio-test-method-order-list nil)
        (ans '(
-              (constructor :STATIC C)
-              (constructor :STATIC C-base1)
-              (constructor :STATIC C-base2)
+              (:STATIC C)
+              (:STATIC C-base1)
+              (:STATIC C-base2)
               )))
     (C nil)
     (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list))
@@ -239,10 +241,10 @@
 (ert-deftest eieio-test-method-order-list-7 ()
   (let ((eieio-test-method-order-list nil)
        (ans '(
-              (eitest-F :PRIMARY D)
-              (eitest-F :PRIMARY D-base1)
-              ;; (eitest-F :PRIMARY D-base2)
-              (eitest-F :PRIMARY D-base0)
+              (:PRIMARY D)
+              (:PRIMARY D-base1)
+              ;; (:PRIMARY D-base2)
+              (:PRIMARY D-base0)
               )))
     (eitest-F (D nil))
     (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list))
@@ -278,10 +280,10 @@
 (ert-deftest eieio-test-method-order-list-8 ()
   (let ((eieio-test-method-order-list nil)
        (ans '(
-              (eitest-F :PRIMARY E)
-              (eitest-F :PRIMARY E-base1)
-              (eitest-F :PRIMARY E-base2)
-              (eitest-F :PRIMARY E-base0)
+              (:PRIMARY E)
+              (:PRIMARY E-base1)
+              (:PRIMARY E-base2)
+              (:PRIMARY E-base0)
               )))
     (eitest-F (E nil))
     (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list))
diff --git a/test/automated/eieio-test-persist.el 
b/test/automated/eieio-test-persist.el
index 2db1dbe..7bb2f1c 100644
--- a/test/automated/eieio-test-persist.el
+++ b/test/automated/eieio-test-persist.el
@@ -32,6 +32,14 @@
 (require 'eieio-base)
 (require 'ert)
 
+(defun eieio--attribute-to-initarg (class attribute)
+  "In CLASS, convert the ATTRIBUTE into the corresponding init argument tag.
+This is usually a symbol that starts with `:'."
+  (let ((tuple (rassoc attribute (eieio--class-initarg-tuples class))))
+    (if tuple
+       (car tuple)
+      nil)))
+
 (defun persist-test-save-and-compare (original)
   "Compare the object ORIGINAL against the one read fromdisk."
 
@@ -40,7 +48,7 @@
   (let* ((file (oref original :file))
         (class (eieio-object-class original))
         (fromdisk (eieio-persistent-read file class))
-        (cv (class-v class))
+        (cv (eieio--class-v class))
         (slot-names  (eieio--class-public-a cv))
         (slot-deflt  (eieio--class-public-d cv))
         )
@@ -53,7 +61,8 @@
       (let* ((oneslot (car slot-names))
             (origvalue (eieio-oref original oneslot))
             (fromdiskvalue (eieio-oref fromdisk oneslot))
-            (initarg-p (eieio-attribute-to-initarg class oneslot))
+            (initarg-p (eieio--attribute-to-initarg
+                         (eieio--class-v class) oneslot))
             )
 
        (if initarg-p
@@ -175,7 +184,7 @@ persistent class.")
 
 (defclass persistent-with-objs-slot-subs (eieio-persistent)
   ((pnp :initarg :pnp
-       :type (or null persist-not-persistent-child)
+       :type (or null persist-not-persistent)
        :initform nil))
   "Class for testing the saving of slots with objects in them.")
 
@@ -194,7 +203,7 @@ persistent class.")
 ;; A slot that contains another object that isn't persistent
 (defclass persistent-with-objs-list-slot (eieio-persistent)
   ((pnp :initarg :pnp
-       :type persist-not-persistent-list
+       :type (list-of persist-not-persistent)
        :initform nil))
   "Class for testing the saving of slots with objects in them.")
 
diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el
index 15b6504..0b1ff1f 100644
--- a/test/automated/eieio-tests.el
+++ b/test/automated/eieio-tests.el
@@ -29,7 +29,7 @@
 (require 'eieio-base)
 (require 'eieio-opt)
 
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
 
 ;;; Code:
 ;; Set up some test classes
@@ -158,7 +158,7 @@
 (ert-deftest eieio-test-02-abstract-class ()
   ;; Abstract classes cannot be instantiated, so this should throw an
   ;; error
-  (should-error (abstract-class "Test")))
+  (should-error (abstract-class)))
 
 (defgeneric generic1 () "First generic function")
 
@@ -180,7 +180,7 @@
     "Method generic1 that can take a non-object."
     not-an-object)
 
-  (let ((ans-obj (generic1 (class-a "test")))
+  (let ((ans-obj (generic1 (class-a)))
        (ans-num (generic1 666)))
     (should (eq ans-obj 'monkey))
     (should (eq ans-num 666))))
@@ -199,10 +199,10 @@ Argument C is the class bound to this static method."
 
 (ert-deftest eieio-test-04-static-method ()
   ;; Call static method on a class and see if it worked
-  (static-method-class-method static-method-class 'class)
-  (should (eq (oref static-method-class some-slot) 'class))
-  (static-method-class-method (static-method-class "test") 'object)
-  (should (eq (oref static-method-class some-slot) 'object)))
+  (static-method-class-method 'static-method-class 'class)
+  (should (eq (oref-default 'static-method-class some-slot) 'class))
+  (static-method-class-method (static-method-class) 'object)
+  (should (eq (oref-default 'static-method-class some-slot) 'object)))
 
 (ert-deftest eieio-test-05-static-method-2 ()
   (defclass static-method-class-2 (static-method-class)
@@ -215,10 +215,10 @@ Argument C is the class bound to this static method."
     (if (eieio-object-p c) (setq c (eieio-object-class c)))
     (oset-default c some-slot (intern (concat "moose-" (symbol-name value)))))
 
-  (static-method-class-method static-method-class-2 'class)
-  (should (eq (oref static-method-class-2 some-slot) 'moose-class))
-  (static-method-class-method (static-method-class-2 "test") 'object)
-  (should (eq (oref static-method-class-2 some-slot) 'moose-object)))
+  (static-method-class-method 'static-method-class-2 'class)
+  (should (eq (oref-default 'static-method-class-2 some-slot) 'moose-class))
+  (static-method-class-method (static-method-class-2) 'object)
+  (should (eq (oref-default 'static-method-class-2 some-slot) 'moose-object)))
 
 
 ;;; Perform method testing
@@ -231,14 +231,14 @@ Argument C is the class bound to this static method."
 (defvar eitest-b nil)
 (ert-deftest eieio-test-06-allocate-objects ()
    ;; allocate an object to use
-   (should (setq eitest-ab (class-ab "abby")))
-   (should (setq eitest-a (class-a "aye")))
-   (should (setq eitest-b (class-b "fooby"))))
+   (should (setq eitest-ab (class-ab)))
+   (should (setq eitest-a (class-a)))
+   (should (setq eitest-b (class-b))))
 
 (ert-deftest eieio-test-07-make-instance ()
   (should (make-instance 'class-ab))
   (should (make-instance 'class-a :water 'cho))
-  (should (make-instance 'class-b "a name")))
+  (should (make-instance 'class-b)))
 
 (defmethod class-cn ((a class-a))
   "Try calling `call-next-method' when there isn't one.
@@ -355,7 +355,7 @@ METHOD is the method that was attempting to be called."
     (call-next-method)
     (oset a test-tag 1))
 
-  (let ((ca (class-a "class act")))
+  (let ((ca (class-a)))
     (should-not (/=  (oref ca test-tag) 2))))
 
 
@@ -404,7 +404,7 @@ METHOD is the method that was attempting to be called."
    (t (call-next-method))))
 
 (ert-deftest eieio-test-17-virtual-slot ()
-  (setq eitest-vsca (virtual-slot-class "eitest-vsca" :base-value 1))
+  (setq eitest-vsca (virtual-slot-class :base-value 1))
   ;; Check slot values
   (should (= (oref eitest-vsca :base-value) 1))
   (should (= (oref eitest-vsca :derived-value) 2))
@@ -419,7 +419,7 @@ METHOD is the method that was attempting to be called."
 
   ;; should also be possible to initialize instance using virtual slot
 
-  (setq eitest-vscb (virtual-slot-class "eitest-vscb" :derived-value 5))
+  (setq eitest-vscb (virtual-slot-class :derived-value 5))
   (should (= (oref eitest-vscb :base-value) 4))
   (should (= (oref eitest-vscb :derived-value) 5)))
 
@@ -445,7 +445,7 @@ METHOD is the method that was attempting to be called."
   ;; After setting 'water to 'moose, make sure a new object has
   ;; the right stuff.
   (oset-default (eieio-object-class eitest-a) water 'penguin)
-  (should (eq (oref (class-a "foo") water) 'penguin))
+  (should (eq (oref (class-a) water) 'penguin))
 
   ;; Revert the above
   (defmethod slot-unbound ((a class-a) &rest foo)
@@ -459,12 +459,12 @@ METHOD is the method that was attempting to be called."
   ;; We should not be able to set a string here
   (should-error (oset eitest-ab water "a string, not a symbol") :type 
'invalid-slot-type)
   (should-error (oset eitest-ab classslot "a string, not a symbol") :type 
'invalid-slot-type)
-  (should-error (class-a "broken-type-a" :water "a string not a symbol") :type 
'invalid-slot-type))
+  (should-error (class-a :water "a string not a symbol") :type 
'invalid-slot-type))
 
 (ert-deftest eieio-test-20-class-allocated-slots ()
   ;; Test out class allocated slots
   (defvar eitest-aa nil)
-  (setq eitest-aa (class-a "another"))
+  (setq eitest-aa (class-a))
 
   ;; Make sure class slots do not track between objects
   (let ((newval 'moose))
@@ -474,12 +474,12 @@ METHOD is the method that was attempting to be called."
 
   ;; Slot should be bound
   (should (slot-boundp eitest-a 'classslot))
-  (should (slot-boundp class-a 'classslot))
+  (should (slot-boundp 'class-a 'classslot))
 
   (slot-makeunbound eitest-a 'classslot)
 
   (should-not (slot-boundp eitest-a 'classslot))
-  (should-not (slot-boundp class-a 'classslot)))
+  (should-not (slot-boundp 'class-a 'classslot)))
 
 
 (defvar eieio-test-permuting-value nil)
@@ -499,7 +499,7 @@ METHOD is the method that was attempting to be called."
 (ert-deftest eieio-test-21-eval-at-construction-time ()
   ;; initforms that need to be evalled at construction time.
   (setq eieio-test-permuting-value 2)
-  (setq eitest-pvinit (inittest "permuteme"))
+  (setq eitest-pvinit (inittest))
 
   (should (eq (oref eitest-pvinit staticval) 1))
   (should (eq (oref eitest-pvinit symval) 'eieio-test-permuting-value))
@@ -515,11 +515,11 @@ METHOD is the method that was attempting to be called."
     "Test class that will be a calculated value.")
 
   (defclass eitest-superior nil
-    ((sub :initform (eitest-subordinate "test")
+    ((sub :initform (eitest-subordinate)
          :type eitest-subordinate))
     "A class with an initform that creates a class.")
 
-  (should (setq eitest-tests (eitest-superior "test")))
+  (should (setq eitest-tests (eitest-superior)))
 
   (should-error
    (eval
@@ -530,33 +530,35 @@ METHOD is the method that was attempting to be called."
    :type 'invalid-slot-type))
 
 (ert-deftest eieio-test-23-inheritance-check ()
-  (should (child-of-class-p class-ab class-a))
-  (should (child-of-class-p class-ab class-b))
-  (should (object-of-class-p eitest-a class-a))
-  (should (object-of-class-p eitest-ab class-a))
-  (should (object-of-class-p eitest-ab class-b))
-  (should (object-of-class-p eitest-ab class-ab))
-  (should (eq (eieio-class-parents class-a) nil))
-  (should (equal (eieio-class-parents class-ab) '(class-a class-b)))
-  (should (same-class-p eitest-a class-a))
+  (should (child-of-class-p 'class-ab 'class-a))
+  (should (child-of-class-p 'class-ab 'class-b))
+  (should (object-of-class-p eitest-a 'class-a))
+  (should (object-of-class-p eitest-ab 'class-a))
+  (should (object-of-class-p eitest-ab 'class-b))
+  (should (object-of-class-p eitest-ab 'class-ab))
+  (should (eq (eieio-class-parents 'class-a) nil))
+  ;; FIXME: eieio-class-parents now returns class objects!
+  (should (equal (mapcar #'eieio-class-object (eieio-class-parents 'class-ab))
+                 (mapcar #'eieio-class-object '(class-a class-b))))
+  (should (same-class-p eitest-a 'class-a))
   (should (class-a-p eitest-a))
   (should (not (class-a-p eitest-ab)))
-  (should (class-a-child-p eitest-a))
-  (should (class-a-child-p eitest-ab))
+  (should (cl-typep eitest-a 'class-a))
+  (should (cl-typep eitest-ab 'class-a))
   (should (not (class-a-p "foo")))
-  (should (not (class-a-child-p "foo"))))
+  (should (not (cl-typep "foo" 'class-a))))
 
 (ert-deftest eieio-test-24-object-predicates ()
-  (let ((listooa (list (class-ab "ab") (class-a "a")))
-       (listoob (list (class-ab "ab") (class-b "b"))))
-    (should (class-a-list-p listooa))
-    (should (class-b-list-p listoob))
-    (should-not (class-b-list-p listooa))
-    (should-not (class-a-list-p listoob))))
+  (let ((listooa (list (class-ab) (class-a)))
+       (listoob (list (class-ab) (class-b))))
+    (should (cl-typep listooa '(list-of class-a)))
+    (should (cl-typep listoob '(list-of class-b)))
+    (should-not (cl-typep listooa '(list-of class-b)))
+    (should-not (cl-typep listoob '(list-of class-a)))))
 
 (defvar eitest-t1 nil)
 (ert-deftest eieio-test-25-slot-tests ()
-  (setq eitest-t1 (class-c "C1"))
+  (setq eitest-t1 (class-c))
   ;; Slot initialization
   (should (eq (oref eitest-t1 slot-1) 'moose))
   (should (eq (oref eitest-t1 :moose) 'moose))
@@ -565,9 +567,9 @@ METHOD is the method that was attempting to be called."
   ;; Check private slot accessor
   (should (string= (get-slot-2 eitest-t1) "penguin"))
   ;; Pass string instead of symbol
-  (should-error (class-c "C2" :moose "not a symbol") :type 'invalid-slot-type)
+  (should-error (class-c :moose "not a symbol") :type 'invalid-slot-type)
   (should (eq (get-slot-3 eitest-t1) 'emu))
-  (should (eq (get-slot-3 class-c) 'emu))
+  (should (eq (get-slot-3 'class-c) 'emu))
   ;; Check setf
   (setf (get-slot-3 eitest-t1) 'setf-emu)
   (should (eq (get-slot-3 eitest-t1) 'setf-emu))
@@ -577,13 +579,13 @@ METHOD is the method that was attempting to be called."
 (defvar eitest-t2 nil)
 (ert-deftest eieio-test-26-default-inheritance ()
   ;; See previous test, nor for subclass
-  (setq eitest-t2 (class-subc "subc"))
+  (setq eitest-t2 (class-subc))
   (should (eq (oref eitest-t2 slot-1) 'moose))
   (should (eq (oref eitest-t2 :moose) 'moose))
   (should (string= (get-slot-2 eitest-t2) "linux"))
   (should-error (oref eitest-t2 slot-2) :type 'invalid-slot-name)
   (should (string= (get-slot-2 eitest-t2) "linux"))
-  (should-error (class-subc "C2" :moose "not a symbol") :type 
'invalid-slot-type))
+  (should-error (class-subc :moose "not a symbol") :type 'invalid-slot-type))
 
 ;;(ert-deftest eieio-test-27-inherited-new-value ()
   ;;; HACK ALERT: The new value of a class slot is inherited by the
@@ -647,8 +649,8 @@ Do not override for `prot-2'."
 (defvar eitest-p1 nil)
 (defvar eitest-p2 nil)
 (ert-deftest eieio-test-28-slot-protection ()
-  (setq eitest-p1 (prot-1 ""))
-  (setq eitest-p2 (prot-2 ""))
+  (setq eitest-p1 (prot-1))
+  (setq eitest-p2 (prot-2))
   ;; Access public slots
   (oref eitest-p1 slot-1)
   (oref eitest-p2 slot-1)
@@ -743,7 +745,7 @@ Subclasses to override slot attributes.")
          "This class should throw an error.")))
 
   ;; Initform should override instance allocation
-  (let ((obj (slotattr-ok "moose")))
+  (let ((obj (slotattr-ok)))
     (should (eq (oref obj initform) 'no-init))))
 
 (defclass slotattr-class-base ()
@@ -792,10 +794,10 @@ Subclasses to override slot attributes.")
          ((type :type string)
           )
          "This class should throw an error.")))
-  (should (eq (oref-default slotattr-class-ok initform) 'no-init)))
+  (should (eq (oref-default 'slotattr-class-ok initform) 'no-init)))
 
 (ert-deftest eieio-test-32-slot-attribute-override-2 ()
-  (let* ((cv (class-v 'slotattr-ok))
+  (let* ((cv (eieio--class-v 'slotattr-ok))
         (docs   (eieio--class-public-doc cv))
         (names  (eieio--class-public-a cv))
         (cust   (eieio--class-public-custom cv))
@@ -826,7 +828,7 @@ Subclasses to override slot attributes.")
 
 (ert-deftest eieio-test-32-test-clone-boring-objects ()
   ;; A simple make instance with EIEIO extension
-  (should (setq eitest-CLONETEST1 (make-instance 'class-a "a")))
+  (should (setq eitest-CLONETEST1 (make-instance 'class-a)))
   (should (setq eitest-CLONETEST2 (clone eitest-CLONETEST1)))
 
   ;; CLOS form of make-instance
@@ -840,7 +842,7 @@ Subclasses to override slot attributes.")
 
 (ert-deftest eieio-test-33-instance-tracker ()
   (let (IT-list IT1)
-    (should (setq IT1 (IT "trackme")))
+    (should (setq IT1 (IT)))
     ;; The instance tracker must find this
     (should (eieio-instance-tracker-find 'die 'slot1 'IT-list))
     ;; Test deletion
@@ -852,8 +854,8 @@ Subclasses to override slot attributes.")
   "A Singleton test object.")
 
 (ert-deftest eieio-test-34-singletons ()
-  (let ((obj1 (SINGLE "Moose"))
-       (obj2 (SINGLE "Cow")))
+  (let ((obj1 (SINGLE))
+       (obj2 (SINGLE)))
     (should (eieio-object-p obj1))
     (should (eieio-object-p obj2))
     (should (eq obj1 obj2))
@@ -866,7 +868,7 @@ Subclasses to override slot attributes.")
 
 (ert-deftest eieio-test-35-named-object ()
   (let (N)
-    (should (setq N (NAMED "Foo")))
+    (should (setq N (NAMED :object-name "Foo")))
     (should (string= "Foo" (oref N object-name)))
     (should-error (oref N missing-slot) :type 'invalid-slot-name)
     (oset N object-name "NewName")
@@ -882,8 +884,8 @@ Subclasses to override slot attributes.")
   "Instantiable child")
 
 (ert-deftest eieio-test-36-build-class-alist ()
-  (should (= (length (eieio-build-class-alist opt-test1 nil)) 2))
-  (should (= (length (eieio-build-class-alist opt-test1 t)) 1)))
+  (should (= (length (eieio-build-class-alist 'opt-test1 nil)) 2))
+  (should (= (length (eieio-build-class-alist 'opt-test1 t)) 1)))
 
 (provide 'eieio-tests)
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]