Subject: bug#15880: Compute C declarations for DEFSYMs automatically.

From: Paul Eggert <[email-masked]>
Date: Tue, 23 Dec 2014 15:51:13 -0800

On 12/23/2014 09:15 AM, Stefan Monnier wrote:
> Could you split this patch into at least two parts:
> - auto-generate the symbols from make-docfile.
> - make Qnil be zero.
> The other part (make those Q<foo> be link-time constants) could be
> a third patch or folded into one of the other two.
>

Sure.  It's easy to create one patch for autogeneration and link-time 
constants, and a second patch for making Qnil be zero. Attached.  These 
are relative to trunk commit e55a467ec0f758c311d358ceb7d66a8a7d9482c3 
dated today.
>From 480237524a0f82ae13e12e005e3f64920514fad2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 23 Dec 2014 13:29:07 -0800
Subject: [PATCH 1/2] 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.
* 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.
* alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle:
* 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 (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.
---
 lib-src/ChangeLog      |  23 ++++
 lib-src/make-docfile.c | 280 ++++++++++++++++++++++++++++-----------
 src/ChangeLog          |  72 +++++++++++
 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/data.c             |  56 --------
 src/dbusbind.c         |  39 ++----
 src/decompress.c       |   2 -
 src/dired.c            |   8 --
 src/dispextern.h       |   7 +-
 src/dispnew.c          |   4 +-
 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             |  68 ++++------
 src/font.h             |  16 ---
 src/fontset.c          |   5 -
 src/fontset.h          |   1 -
 src/frame.c            | 186 +++++++++++---------------
 src/frame.h            |  51 --------
 src/fringe.c           |   4 -
 src/ftfont.c           |   9 +-
 src/ftxfont.c          |   2 -
 src/gfilenotify.c      |  40 ++----
 src/gnutls.c           |  23 +---
 src/image.c            | 104 ++++-----------
 src/inotify.c          |  81 ++++--------
 src/insdel.c           |   6 +-
 src/intervals.h        |  16 +--
 src/keyboard.c         | 241 ++++++++++++----------------------
 src/keyboard.h         |  31 -----
 src/keymap.c           |  19 ++-
 src/keymap.h           |   3 -
 src/lisp.h             | 345 ++++++++++++++++++-------------------------------
 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           |   8 --
 src/print.c            |  20 +--
 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/w32font.c          |   2 +-
 src/window.c           |  22 +---
 src/window.h           |   1 -
 src/xdisp.c            | 164 +++++++----------------
 src/xfaces.c           | 111 ++++------------
 src/xfns.c             |   4 -
 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 -
 94 files changed, 1017 insertions(+), 1981 deletions(-)

diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 9b6c0da..846ba94 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,26 @@
+2014-12-23  Paul Eggert  <[email-masked]>
+
+	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.
+
 2014-12-14  Glenn Morris  <[email-masked]>
 
 	* grep-changelog: Remove file.
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 884b6c1..04b872f 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;
     }
 }
 
@@ -591,17 +617,44 @@ compare_globals (const void *a, const void *b)
 }
 
 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 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 +670,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 +689,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 a%s (&lispsym[%d])\n"
+		 "#define %s make_lisp_symbol (a%s)\n"
+		 "DEFINE_LISP_SYMBOL_END (a%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,38 +708,63 @@ 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
-	      || strcmp (globals[i].name, "Ftool_bar_height") == 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, "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, "Fidentity") == 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
+#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");
 }
 
 
@@ -691,9 +777,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')
@@ -719,8 +802,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;
@@ -749,37 +839,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')
 	{
@@ -796,7 +902,7 @@ scan_c_file (char *filename, const char *mode)
 
       if (generate_globals
 	  && (!defvarflag || defvarperbufferflag || type == INVALID)
-	  && !defunflag)
+	  && !defunflag && type != SYMBOL)
 	continue;
 
       while (c != '(')
@@ -806,15 +912,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
@@ -826,6 +936,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);
 	    }
@@ -836,13 +948,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 *\/)  */
@@ -895,7 +1021,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/src/ChangeLog b/src/ChangeLog
index b90471e..456eba0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,75 @@
+2014-12-23  Paul Eggert  <[email-masked]>
+
+	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:
+	* 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 (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.
+
 2014-12-23  Didier Verna  <[email-masked]> (tiny change).
 
 	* nsselect.m (Fns_selection_owner_p): Return a Lisp boolean, not a
diff --git a/src/alloc.c b/src/alloc.c
index eada96c..2200b2e 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 (make_lisp_symbol (&lispsym[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 = make_lisp_symbol (&lispsym[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 4538545..050cb7b 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 b57d968..b7ca260 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -114,41 +114,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 *);
@@ -1715,7 +1682,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);
   }
 
@@ -2739,7 +2706,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.  */
@@ -5062,9 +5029,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 284cfa7..db760b4 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 d3c8b47..dcc9cb9 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 9467695..d59d070 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 a7477bb..a21be0d 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 aea1f2f..42b5b24 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 a4610e4..6ec7d7d 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 54093bf..070ded0 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 a8e48df..1b7e09a 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 7fcb153..749541b 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 6c6c3e6..f31ce96 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 9a05218..ac14537 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 e4b52f6..740f86c 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 ffd839f..6d0b665 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 8982c90..38ae071 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 1080eb0..d511e44 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/data.c b/src/data.c
index 7151d22..da05e6c 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 4852739..dd5dc5a 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 24ce852..04707ee 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 8afba24..6dfe93a 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 8fd3ef9..62f8a0e 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2904,8 +2904,8 @@ struct redisplay_interface
 
 struct image_type
 {
-  /* A symbol uniquely identifying the image type, .e.g `jpeg'.  */
-  Lisp_Object *type;
+  /* A symbol uniquely identifying the image type, e.g., 'jpeg'.  */
+  struct Lisp_Symbol *type;
 
   /* Check that SPEC is a valid image specification for the given
      image type.  Value is true if SPEC is valid.  */
@@ -3219,7 +3219,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;
@@ -3399,7 +3398,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.  */
@@ -3489,7 +3487,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 212caa8..a1601f9 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -102,8 +102,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;
@@ -6191,7 +6189,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 81c22b8..394b4c5 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 1b87c23..e9857ba 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -34,8 +34,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 bdd296b..d008958 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 0a07886..29aa17c 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;
 
@@ -904,17 +894,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
@@ -4996,8 +4980,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 b9654d0..fcc4e1f 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -148,13 +148,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;
@@ -1913,7 +1906,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 8194468..2e46047 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 39514ee..51a3329 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 e891fdb..0275aa1 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 d10d228..8c21be3 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.  */
@@ -663,29 +640,29 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val)
 static const struct
 {
   /* Pointer to the key symbol.  */
-  Lisp_Object *key;
+  struct Lisp_Symbol *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 },
+  { { XSYMBOL_INIT (QCtype), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCfoundry), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCfamily), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCadstyle), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCregistry), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCweight), font_prop_validate_style },
+    { XSYMBOL_INIT (QCslant), font_prop_validate_style },
+    { XSYMBOL_INIT (QCwidth), font_prop_validate_style },
+    { XSYMBOL_INIT (QCsize), font_prop_validate_non_neg },
+    { XSYMBOL_INIT (QCdpi), font_prop_validate_non_neg },
+    { XSYMBOL_INIT (QCspacing), font_prop_validate_spacing },
+    { XSYMBOL_INIT (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 }
+    { XSYMBOL_INIT (QClang), font_prop_validate_symbol },
+    { XSYMBOL_INIT (QCscript), font_prop_validate_symbol },
+    { XSYMBOL_INIT (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, make_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 = make_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 5278341..7494e20 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,7 +779,6 @@ 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
@@ -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 ac50be1..57f7468 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 884244e..032dd42 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 3127366..78bb6fd 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;
@@ -1209,7 +1139,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);
@@ -2983,48 +2913,48 @@ or bottommost possible position (that stays within the screen).  */)
 
 struct frame_parm_table {
   const char *name;
-  Lisp_Object *variable;
+  struct Lisp_Symbol *sym;
 };
 
 static const struct frame_parm_table frame_parms[] =
 {
-  {"auto-raise",		&Qauto_raise},
-  {"auto-lower",		&Qauto_lower},
+  {"auto-raise",		XSYMBOL_INIT (Qauto_raise)},
+  {"auto-lower",		XSYMBOL_INIT (Qauto_lower)},
   {"background-color",		0},
-  {"border-color",		&Qborder_color},
-  {"border-width",		&Qborder_width},
-  {"cursor-color",		&Qcursor_color},
-  {"cursor-type",		&Qcursor_type},
+  {"border-color",		XSYMBOL_INIT (Qborder_color)},
+  {"border-width",		XSYMBOL_INIT (Qborder_width)},
+  {"cursor-color",		XSYMBOL_INIT (Qcursor_color)},
+  {"cursor-type",		XSYMBOL_INIT (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},
+  {"icon-name",			XSYMBOL_INIT (Qicon_name)},
+  {"icon-type",			XSYMBOL_INIT (Qicon_type)},
+  {"internal-border-width",	XSYMBOL_INIT (Qinternal_border_width)},
+  {"right-divider-width",	XSYMBOL_INIT (Qright_divider_width)},
+  {"bottom-divider-width",	XSYMBOL_INIT (Qbottom_divider_width)},
+  {"menu-bar-lines",		XSYMBOL_INIT (Qmenu_bar_lines)},
+  {"mouse-color",		XSYMBOL_INIT (Qmouse_color)},
+  {"name",			XSYMBOL_INIT (Qname)},
+  {"scroll-bar-width",		XSYMBOL_INIT (Qscroll_bar_width)},
+  {"scroll-bar-height",		XSYMBOL_INIT (Qscroll_bar_height)},
+  {"title",			XSYMBOL_INIT (Qtitle)},
+  {"unsplittable",		XSYMBOL_INIT (Qunsplittable)},
+  {"vertical-scroll-bars",	XSYMBOL_INIT (Qvertical_scroll_bars)},
+  {"horizontal-scroll-bars",	XSYMBOL_INIT (Qhorizontal_scroll_bars)},
+  {"visibility",		XSYMBOL_INIT (Qvisibility)},
+  {"tool-bar-lines",		XSYMBOL_INIT (Qtool_bar_lines)},
+  {"scroll-bar-foreground",	XSYMBOL_INIT (Qscroll_bar_foreground)},
+  {"scroll-bar-background",	XSYMBOL_INIT (Qscroll_bar_background)},
+  {"screen-gamma",		XSYMBOL_INIT (Qscreen_gamma)},
+  {"line-spacing",		XSYMBOL_INIT (Qline_spacing)},
+  {"left-fringe",		XSYMBOL_INIT (Qleft_fringe)},
+  {"right-fringe",		XSYMBOL_INIT (Qright_fringe)},
+  {"wait-for-wm",		XSYMBOL_INIT (Qwait_for_wm)},
+  {"fullscreen",                XSYMBOL_INIT (Qfullscreen)},
+  {"font-backend",		XSYMBOL_INIT (Qfont_backend)},
+  {"alpha",			XSYMBOL_INIT (Qalpha)},
+  {"sticky",			XSYMBOL_INIT (Qsticky)},
+  {"tool-bar-position",		XSYMBOL_INIT (Qtool_bar_position)},
 };
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -4842,17 +4772,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
+			 ? make_lisp_symbol (frame_parms[i].sym)
+			 : intern_c_string (frame_parms[i].name));
 	Fput (v, Qx_frame_parameter, make_number (i));
       }
   }
diff --git a/src/frame.h b/src/frame.h
index 1aa8804..4667250 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 3c0e883..40e7d6f 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 4c12ef5..a46c8bf 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 7e4608b..ee72fed 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 9882f27..5f0efc9 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
@@ -258,23 +240,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 bf9f132..603d7e9 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
@@ -1639,13 +1619,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 a73a725..0e19e22 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,28 @@ static struct image_type *
 define_image_type (struct image_type *type)
 {
   struct image_type *p = NULL;
-  Lisp_Object target_type = *type->type;
+  struct Lisp_Symbol *new_type = type->type;
   bool type_valid = 1;
 
   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 (make_lisp_symbol (new_type), Vlibrary_cache);
       if (CONSP (tested) && NILP (XCDR (tested)))
 	type_valid = 0;
       else
 #endif
 	{
 	  type_valid = type->init ();
-	  CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
+	  CACHE_IMAGE_TYPE (make_lisp_symbol (new_type),
+			    type_valid ? Qt : Qnil);
 	}
     }
 
@@ -1777,7 +1747,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 (make_lisp_symbol (img->type->type), Qpostscript))
 	    postprocess_image (f, img);
 	}
 
@@ -2375,7 +2345,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
 
 static struct image_type xbm_type =
 {
-  &Qxbm,
+  XSYMBOL_INIT (Qxbm),
   xbm_image_p,
   xbm_load,
   x_clear_image,
@@ -3134,9 +3104,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.  */
 
@@ -3184,7 +3151,7 @@ static bool init_xpm_functions (void);
 
 static struct image_type xpm_type =
 {
-  &Qxpm,
+  XSYMBOL_INIT (Qxpm),
   xpm_image_p,
   xpm_load,
   x_clear_image,
@@ -5072,10 +5039,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
@@ -5116,7 +5079,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
 
 static struct image_type pbm_type =
 {
-  &Qpbm,
+  XSYMBOL_INIT (Qpbm),
   pbm_image_p,
   pbm_load,
   x_clear_image,
@@ -5459,10 +5422,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
@@ -5507,7 +5466,7 @@ static bool init_png_functions (void);
 
 static struct image_type png_type =
 {
-  &Qpng,
+  XSYMBOL_INIT (Qpng),
   png_image_p,
   png_load,
   x_clear_image,
@@ -6092,10 +6051,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
@@ -6140,7 +6095,7 @@ static bool init_jpeg_functions (void);
 
 static struct image_type jpeg_type =
 {
-  &Qjpeg,
+  XSYMBOL_INIT (Qjpeg),
   jpeg_image_p,
   jpeg_load,
   x_clear_image,
@@ -6683,10 +6638,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
@@ -6733,7 +6684,7 @@ static bool init_tiff_functions (void);
 
 static struct image_type tiff_type =
 {
-  &Qtiff,
+  XSYMBOL_INIT (Qtiff),
   tiff_image_p,
   tiff_load,
   x_clear_image,
@@ -7140,10 +7091,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
@@ -7190,7 +7137,7 @@ static bool init_gif_functions (void);
 
 static struct image_type gif_type =
 {
-  &Qgif,
+  XSYMBOL_INIT (Qgif),
   gif_image_p,
   gif_load,
   gif_clear_image,
@@ -7812,8 +7759,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 *);
@@ -7877,7 +7822,7 @@ static bool init_imagemagick_functions (void);
 
 static struct image_type imagemagick_type =
   {
-    &Qimagemagick,
+    XSYMBOL_INIT (Qimagemagick),
     imagemagick_image_p,
     imagemagick_load,
     imagemagick_clear_image,
@@ -8603,10 +8548,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
@@ -8653,7 +8594,7 @@ static bool init_svg_functions (void);
 
 static struct image_type svg_type =
 {
-  &Qsvg,
+  XSYMBOL_INIT (Qsvg),
   svg_image_p,
   svg_load,
   x_clear_image,
@@ -8706,8 +8647,6 @@ DEF_IMGLIB_FN (void, g_type_init, (void));
 DEF_IMGLIB_FN (void, g_object_unref, (gpointer));
 DEF_IMGLIB_FN (void, g_error_free, (GError *));
 
-Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
-
 static bool
 init_svg_functions (void)
 {
@@ -9010,10 +8949,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
@@ -9058,7 +8993,7 @@ static const struct image_keyword gs_format[GS_LAST] =
 
 static struct image_type gs_type =
 {
-  &Qpostscript,
+  XSYMBOL_INIT (Qpostscript),
   gs_image_p,
   gs_load,
   gs_clear_image,
@@ -9433,10 +9368,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");
@@ -9451,6 +9388,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");
@@ -9468,6 +9406,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 c55b130..15a1c24 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 7b4ee3b..379d844 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -51,8 +51,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.  */
@@ -1780,8 +1778,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.
 
@@ -1994,7 +1990,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 bd1f49d..10640b7 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 d76a8fc..aca7648 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -87,11 +87,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.  */
@@ -231,42 +226,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;
 
@@ -345,83 +309,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 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;
 
@@ -1712,10 +1605,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;
@@ -5277,22 +5167,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
+static struct Lisp_Symbol *const scroll_bar_parts[] = {
+  XSYMBOL_INIT (Qnil), XSYMBOL_INIT (Qabove_handle), XSYMBOL_INIT (Qhandle),
+  XSYMBOL_INIT (Qbelow_handle), XSYMBOL_INIT (Qup), XSYMBOL_INIT (Qdown),
+  XSYMBOL_INIT (Qtop), XSYMBOL_INIT (Qbottom), XSYMBOL_INIT (Qend_scroll),
+  XSYMBOL_INIT (Qratio), XSYMBOL_INIT (Qbefore_handle),
+  XSYMBOL_INIT (Qhorizontal_handle), XSYMBOL_INIT (Qafter_handle),
+  XSYMBOL_INIT (Qleft), XSYMBOL_INIT (Qright), XSYMBOL_INIT (Qleftmost),
+  XSYMBOL_INIT (Qrightmost), XSYMBOL_INIT (Qend_scroll), XSYMBOL_INIT (Qratio)
 };
 
 /* A vector, indexed by button number, giving the down-going location
@@ -5565,7 +5450,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),
+		make_lisp_symbol (scroll_bar_parts[ev->part]));
 }
 
 /* Given a struct input_event, build the lisp event which represents
@@ -6204,7 +6090,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 = make_lisp_symbol (scroll_bar_parts[part]);
       return list2 (Qscroll_bar_movement,
 		    list5 (bar_window,
 			   Qvertical_scroll_bar,
@@ -8068,11 +7954,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);
@@ -10331,7 +10212,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");
@@ -10339,9 +10219,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);
@@ -10365,9 +10243,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;
@@ -11111,26 +10987,30 @@ 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.  */
+/* This type's only use is in syms_of_keyboard, to put properties on the
+   event header symbols.  */
 struct event_head {
-  Lisp_Object *var;
-  const char *name;
-  Lisp_Object *kind;
+  struct Lisp_Symbol *var;
+  struct Lisp_Symbol *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},
+  {XSYMBOL_INIT (Qmouse_movement),      XSYMBOL_INIT (Qmouse_movement)},
+  {XSYMBOL_INIT (Qscroll_bar_movement), XSYMBOL_INIT (Qmouse_movement)},
+
+  /* Some of the event heads.  */
+  {XSYMBOL_INIT (Qswitch_frame),        XSYMBOL_INIT (Qswitch_frame)},
+
+  {XSYMBOL_INIT (Qfocus_in),            XSYMBOL_INIT (Qfocus_in)},
+  {XSYMBOL_INIT (Qfocus_out),           XSYMBOL_INIT (Qfocus_out)},
+  {XSYMBOL_INIT (Qdelete_frame),        XSYMBOL_INIT (Qdelete_frame)},
+  {XSYMBOL_INIT (Qiconify_frame),       XSYMBOL_INIT (Qiconify_frame)},
+  {XSYMBOL_INIT (Qmake_frame_visible),  XSYMBOL_INIT (Qmake_frame_visible)},
   /* `select-window' should be handled just like `switch-frame'
      in read_key_sequence.  */
-  {&Qselect_window,       "select-window",       &Qswitch_frame}
+  {XSYMBOL_INIT (Qselect_window),       XSYMBOL_INIT (Qswitch_frame)}
 };
 
 void
@@ -11169,17 +11049,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
@@ -11194,6 +11086,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");
@@ -11201,14 +11094,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");
 
@@ -11231,9 +11126,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");
@@ -11242,7 +11149,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");
 
@@ -11257,17 +11167,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 = make_lisp_symbol (p->var);
+	Lisp_Object kind = make_lisp_symbol (p->kind);
+	Fput (var, Qevent_kind, kind);
+	Fput (var, Qevent_symbol_elements, list1 (var));
       }
   }
 
@@ -11593,13 +11512,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 da83b9b..897f924 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 c7c7d19..8924b50 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 b01886d..bcbab76 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 3a6d247..1a56d88 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -562,7 +562,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 +571,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.  */
 
@@ -610,12 +612,6 @@ 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 +621,116 @@ 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.  */
 
-/* Defined in window.c.  */
-extern Lisp_Object Qwindowp;
+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;
+};
+
+/* 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))
+
+/* 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.  Athough these symbols are
+   useless on modern platforms, they don't hurt performance all that much.  */
+#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_PTR (Lisp_Symbol, name)))
+
+#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))
@@ -861,6 +951,10 @@ XSTRING (Lisp_Object a)
 
 LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
 
+/* XSYMBOL_INIT (Qfoo) is like XSYMBOL (Qfoo), except it is valid in
+   static initializers, and SYM must be a C-defined symbol.  */
+#define XSYMBOL_INIT(sym) a##sym
+
 INLINE struct Lisp_Float *
 XFLOAT (Lisp_Object a)
 {
@@ -930,14 +1024,18 @@ 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)
+{
+  return make_lisp_ptr (sym, Lisp_Symbol);
+}
+
+INLINE Lisp_Object
 make_lisp_proc (struct Lisp_Process *p)
 {
   return make_lisp_ptr (p, Lisp_Vectorlike);
@@ -948,7 +1046,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))
 
@@ -1555,72 +1653,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))
@@ -1694,8 +1726,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 */
 
 
 /***********************************************************************
@@ -2689,24 +2722,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)
@@ -3255,15 +3270,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;
@@ -3382,30 +3388,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 {
@@ -3461,7 +3443,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);
@@ -3485,14 +3466,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,
@@ -3532,15 +3509,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);
@@ -3595,18 +3568,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);
@@ -3740,8 +3701,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
@@ -3845,11 +3804,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);
@@ -3873,13 +3829,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)
@@ -3911,10 +3865,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;
@@ -3926,7 +3878,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)
@@ -3987,7 +3939,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);
@@ -4034,12 +3985,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,
@@ -4056,7 +4001,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);
@@ -4086,7 +4030,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);
@@ -4095,15 +4038,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);
 
@@ -4117,8 +4055,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
@@ -4152,7 +4088,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);
@@ -4168,9 +4103,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
@@ -4205,7 +4138,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);
@@ -4241,7 +4173,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);
@@ -4262,8 +4193,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);
@@ -4273,11 +4202,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.  */
@@ -4361,9 +4287,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 */
@@ -4383,16 +4306,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 afa47aa..1452bae 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 (make_lisp_symbol (&lispsym[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 7054839..dff6113 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 c3d26d0..4260f46 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 4dd7f17..0059eb8 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 27b5f7b..3788589 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 578ec12..90464fc 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 13c7b0b..564cc42 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -45,11 +45,6 @@ Author: Adrian Robert ([email-masked])
 #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 640dfcb..34ac04a 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert ([email-masked])
 #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 ffd1e4d..9463932 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 8863bd2..c3083ad 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert ([email-masked])
 #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 c3841a4..e772fec 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 7f4b8b2..8333ab3 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. */
diff --git a/src/print.c b/src/print.c
index 7723b98..10598b1 100644
--- a/src/print.c
+++ b/src/print.c
@@ -37,14 +37,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "termhooks.h"		/* For struct terminal.  */
 #include "font.h"
 
-Lisp_Object Qstandard_output;
-
-static Lisp_Object Qtemp_buffer_setup_hook;
-
-/* These are used to print like we read.  */
-
-static Lisp_Object Qfloat_output_format;
-
 #include <float.h>
 #include <ftoastr.h>
 
@@ -72,9 +64,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:
@@ -507,7 +496,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);
 
@@ -716,10 +705,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
@@ -2220,7 +2205,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 c58ae3e..fb90654 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 56c0f6d..04b397a 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 919aabc..073c80d 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 c6ae9d7..780bcb9 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 b49348f..21db2de 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 dc84ca6..de43740 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 04f6e33..34b3da7 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 0cd6a0b..196b277 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 7ecac62..f3079b0 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 2dde02b..4f642f2 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/w32font.c b/src/w32font.c
index 8959318..e66648c 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -291,7 +291,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/window.c b/src/window.c
index 2177a1d..d5e9e7a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -45,20 +45,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "msdos.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);
@@ -115,15 +101,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;
@@ -3645,7 +3625,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 4e4c65b..82e7719 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 0e3e1a2..c438116 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -324,52 +324,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
@@ -403,31 +360,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.  */
 
@@ -477,21 +409,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;
@@ -567,11 +484,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.  */
 
@@ -691,8 +603,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;
@@ -713,7 +623,7 @@ enum prop_handled
 struct props
 {
   /* The name of the property.  */
-  Lisp_Object *name;
+  struct Lisp_Symbol *name;
 
   /* A unique index for the property.  */
   enum prop_idx idx;
@@ -734,13 +644,13 @@ static enum prop_handled handle_fontified_prop (struct it *);
 
 static struct props it_props[] =
 {
-  {&Qfontified,		FONTIFIED_PROP_IDX,	handle_fontified_prop},
+  {XSYMBOL_INIT (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},
+  {XSYMBOL_INIT (Qface),		FACE_PROP_IDX,		handle_face_prop},
+  {XSYMBOL_INIT (Qdisplay),		DISPLAY_PROP_IDX,	handle_display_prop},
+  {XSYMBOL_INIT (Qinvisible),		INVISIBLE_PROP_IDX,	handle_invisible_prop},
+  {XSYMBOL_INIT (Qcomposition),	COMPOSITION_PROP_IDX,	handle_composition_prop},
   {NULL,		0,			NULL}
 };
 
@@ -796,9 +706,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.)  */
 
@@ -824,15 +731,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
@@ -2681,8 +2579,6 @@ safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
   return retval;
 }
 
-static Lisp_Object Qeval;
-
 Lisp_Object
 safe_eval (Lisp_Object sexpr)
 {
@@ -3605,7 +3501,7 @@ 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, make_lisp_symbol (p->name));
 
       /* Look for an interval following iv that has different
 	 properties.  */
@@ -3617,9 +3513,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,
+					       make_lisp_symbol (p->name));
 	      if (!EQ (values_here[p->idx], new_value))
 		break;
 	    }
@@ -13486,7 +13381,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;
@@ -30579,7 +30474,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 ();
@@ -30618,6 +30515,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");
@@ -30637,40 +30536,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");
 
@@ -31170,7 +31098,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");
@@ -31183,6 +31114,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 fbdd3c8..c7ce2e7 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 1b17311..28ba850 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;
diff --git a/src/xftfont.c b/src/xftfont.c
index 0a883a7..7040e6b 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 0f69ee2..e0836e4 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 d418202..c4da1f1 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 92e8982..dbc0f86 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -79,19 +79,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
@@ -2690,8 +2677,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 5f4275d..86f2551 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 0640208..2d89aed 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -180,17 +180,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 31c3261..ea281c0 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1111,9 +1111,6 @@ extern int 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? */
 
-- 
1.9.3

>From 8123564631888aa10a080a7c284dc09124aeb300 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 23 Dec 2014 15:44:44 -0800
Subject: [PATCH 2/2] Use 0 for Qnil

Fixes Bug#15880.
This patch arranges 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 the 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.
* lib-src/make-docfile.c (compare_globals):
Consider 'nil' to be the least.
* src/lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
(make_lisp_symbol):
Symbols now tag the difference from lispsym, instead of 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.
---
 lib-src/ChangeLog      |  3 +++
 lib-src/make-docfile.c | 10 +++++++++
 src/ChangeLog          | 17 +++++++++++++++
 src/lisp.h             | 58 +++++++++++++++++++++++++++++++++-----------------
 4 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 846ba94..610c176 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,5 +1,8 @@
 2014-12-23  Paul Eggert  <[email-masked]>
 
+	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.
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 04b872f..1d00ffc 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -613,6 +613,16 @@ 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 aQnil is firat.  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);
 }
 
diff --git a/src/ChangeLog b/src/ChangeLog
index 456eba0..86911f6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,22 @@
 2014-12-23  Paul Eggert  <[email-masked]>
 
+	Use 0 for Qnil
+	Fixes Bug#15880.
+	This patch arranges 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 the 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):
+	Symbols now tag the difference from lispsym, instead of 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
diff --git a/src/lisp.h b/src/lisp.h
index 1a56d88..370dcb0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -354,9 +354,11 @@ 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_XPNTR(a) \
+   (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
 #define lisp_h_XSYMBOL(a) \
-   (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol))
+   (eassert (SYMBOLP (a)), \
+    (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
@@ -366,7 +368,9 @@ error !;
 # define lisp_h_XFASTINT(a) XINT (a)
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type)))
+# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0)
+# define lisp_h_XUNTAGBASE(a, type, base) \
+    ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a)))
 #endif
 
 /* When compiling via gcc -O0, define the key operations as macros, as
@@ -408,6 +412,7 @@ error !;
 #  define XINT(a) lisp_h_XINT (a)
 #  define XTYPE(a) lisp_h_XTYPE (a)
 #  define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
+#  define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base)
 # endif
 #endif
 
@@ -447,20 +452,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 +474,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
   };
@@ -604,6 +609,8 @@ INLINE bool SUB_CHAR_TABLE_P (Lisp_Object);
 INLINE bool SUBRP (Lisp_Object);
 INLINE bool (SYMBOLP) (Lisp_Object);
 INLINE bool (VECTORLIKEP) (Lisp_Object);
+INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object);
+INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *);
 INLINE bool WINDOWP (Lisp_Object);
 INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
 
@@ -720,6 +727,9 @@ struct Lisp_Symbol
 #define TAG_PTR(tag, ptr) \
   ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
 
+/* Yield an integer that tags PTR as a symbol.  */
+#define TAG_SYMPTR(ptr) TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) lispsym)
+
 /* 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.  Athough these symbols are
@@ -727,7 +737,7 @@ struct Lisp_Symbol
 #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_PTR (Lisp_Symbol, name)))
+   DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name)))
 
 #include "globals.h"
 
@@ -818,6 +828,8 @@ LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (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))
+LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base),
+		  (a, type, base))
 
 #else /* ! USE_LSB_TAG */
 
@@ -878,16 +890,21 @@ XTYPE (Lisp_Object a)
   return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
 }
 
+/* Extract A's pointer value, assuming A's type is TYPE.
+   Add BASE to A's pointer value while extracting.  */
+INLINE void *
+XUNTAGBASE (Lisp_Object a, int type, void *base)
+{
+  char *b = base;
+  intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+  return b + i;
+}
+
 /* Extract A's pointer value, assuming A's type is TYPE.  */
 INLINE void *
 XUNTAG (Lisp_Object a, int type)
 {
-  if (USE_LSB_TAG)
-    {
-      intptr_t i = XLI (a) - type;
-      return (void *) i;
-    }
-  return XPNTR (a);
+  return XUNTAGBASE (a, type, 0);
 }
 
 #endif /* ! USE_LSB_TAG */
@@ -1032,7 +1049,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
 INLINE Lisp_Object
 make_lisp_symbol (struct Lisp_Symbol *sym)
 {
-  return make_lisp_ptr (sym, Lisp_Symbol);
+  Lisp_Object a = XIL (TAG_SYMPTR (sym));
+  eassert (XTYPE (a) == Lisp_Symbol
+	   && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym);
+  return a;
 }
 
 INLINE Lisp_Object
-- 
1.9.3