emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] scratch/accurate-warning-pos 580e663: First draught of cre


From: Alan Mackenzie
Subject: [Emacs-diffs] scratch/accurate-warning-pos 580e663: First draught of creation of "located symbols".
Date: Sun, 11 Nov 2018 07:09:54 -0500 (EST)

branch: scratch/accurate-warning-pos
commit 580e66335a52222fb95ef3564a6480357ef5326f
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    First draught of creation of "located symbols".
    
    This commit is the first on branch /scratch/accurate-warning-pos.
    
    * src/lisp.h (Lisp_Object, vectorlike_header, pvec_type, More_Lisp_Bits): 
Move
    to earlier on in the file to facilitate other changes.
    (Lisp_Located_Symbol): New struct type.
    (pvec_type): New entry PVEC_LOCATED_SYMBOL.
    (lisp_h_PSEUDOVECTORP): New macro.
    (lisp_h_LOCATED_SYMBOL_P, lisp_h_ONLY_SYMBOL_P, lisp_h_XONLY_SYMBOL)
    (lisp_h_XLOCATED_SYMBOL): New macros.
    (lisp_h_SYMBOLP, lisp_h_XSYMBOL): Macros enhanced to handle located symbols.
    (ONLY_SYMBOL_P, XONLY_SYMBOL): New macros.
    (LOCATED_SYMBOL_P, XLOCATED_SYMBOL, LOCATED_SYMBOL_SYM, LOCATED_SYMBOL_LOC):
    New inline functions.
    
    * src/alloc.c (build_located_symbol): New function
    
    * src/data.c (Ftype_of): New entry for PVEC_LOCATED_SYMBOL.
    (Fonly_symbol_p, Flocated_symbol_p, Flocated_symbol_sym, 
Flocated_symbol_loc):
    New defuns.
    (Vlocated_symbols_enabled): New Lisp variable.
    
    * src/fns.c (internal_equal): Replace located-symbols by their bare symbols
    for the purposes of comparison.
    
    * src/lread.c (read0, read1, read_list, read_vector, read_internal_start): 
Add
    a new bool argument locate_syms which means "convert symbol occurrences to
    located symbols".
    (read1): Add the code to perform the conversion to located symbols.
    (Fread_locating_symbols): New defun.
    
    * src/print.c (print_vectorlike): New switch arm for PVEC_LOCATED_SYMBOL.
---
 src/alloc.c |  15 +++
 src/data.c  |  49 +++++++++
 src/fns.c   |   7 ++
 src/lisp.h  | 342 ++++++++++++++++++++++++++++++++++++------------------------
 src/lread.c | 121 +++++++++++++--------
 src/print.c |  19 ++++
 6 files changed, 374 insertions(+), 179 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 0e48b33..7961fc1 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3670,6 +3670,21 @@ make_misc_ptr (void *a)
   return make_lisp_ptr (p, Lisp_Vectorlike);
 }
 
+/* Return a new located symbol with the specified SYMBOL and LOCATION. */
+Lisp_Object
+build_located_symbol (Lisp_Object symbol, Lisp_Object location)
+{
+  Lisp_Object val;
+  struct Lisp_Located_Symbol *p
+    = (struct Lisp_Located_Symbol *) allocate_vector (2);
+  XSETVECTOR (val, p);
+  XSETPVECTYPESIZE (XVECTOR (val), PVEC_LOCATED_SYMBOL, 2, 0);
+  p->sym = symbol;
+  p->loc = location;
+
+  return val;
+}
+
 /* Return a new overlay with specified START, END and PLIST.  */
 
 Lisp_Object
diff --git a/src/data.c b/src/data.c
index 538081e..768d87b 100644
--- a/src/data.c
+++ b/src/data.c
@@ -228,6 +228,7 @@ for example, (type-of 1) returns `integer'.  */)
         case PVEC_NORMAL_VECTOR: return Qvector;
        case PVEC_BIGNUM: return Qinteger;
        case PVEC_MARKER: return Qmarker;
+       case PVEC_LOCATED_SYMBOL: return Qlocated_symbol;
        case PVEC_OVERLAY: return Qoverlay;
        case PVEC_FINALIZER: return Qfinalizer;
 #ifdef HAVE_MODULES
@@ -326,6 +327,26 @@ DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0,
   return Qt;
 }
 
+DEFUN ("only-symbol-p", Fonly_symbol_p, Sonly_symbol_p, 1, 1, 0,
+       doc: /* Return t if OBJECT is a symbol, but not a located symbol.  */
+       attributes: const)
+  (Lisp_Object object)
+{
+  if (ONLY_SYMBOL_P (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("located-symbol-p", Flocated_symbol_p, Slocated_symbol_p, 1, 1, 0,
+       doc: /* Return t if OBJECT is a located symbol.  */
+       attributes: const)
+  (Lisp_Object object)
+{
+  if (LOCATED_SYMBOL_P (object))
+    return Qt;
+  return Qnil;
+}
+
 DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0,
        doc: /* Return t if OBJECT is a symbol.  */
        attributes: const)
@@ -751,6 +772,22 @@ DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
   return name;
 }
 
+DEFUN ("located-symbol-sym", Flocated_symbol_sym, Slocated_symbol_sym, 1, 1, 0,
+       doc: /* Return the symbol in a located symbol.  */)
+       (register Lisp_Object ls)
+{
+  /* Type checking is done in the following macro. */
+  return LOCATED_SYMBOL_SYM (ls);
+}
+
+DEFUN ("located-symbol-loc", Flocated_symbol_loc, Slocated_symbol_loc, 1, 1, 0,
+       doc: /* Return the location in a located symbol.  */)
+       (register Lisp_Object ls)
+{
+  /* Type checking is done in the following macro. */
+  return LOCATED_SYMBOL_LOC (ls);
+}
+
 DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
        doc: /* Set SYMBOL's function definition to DEFINITION, and return 
DEFINITION.  */)
   (register Lisp_Object symbol, Lisp_Object definition)
@@ -3818,6 +3855,8 @@ syms_of_data (void)
 
   DEFSYM (Qlistp, "listp");
   DEFSYM (Qconsp, "consp");
+  DEFSYM (Qonly_symbol_p, "only-symbol-p");
+  DEFSYM (Qlocated_symbol_p, "located-symbol-p");
   DEFSYM (Qsymbolp, "symbolp");
   DEFSYM (Qfixnump, "fixnump");
   DEFSYM (Qintegerp, "integerp");
@@ -3926,6 +3965,7 @@ syms_of_data (void)
   DEFSYM (Qstring, "string");
   DEFSYM (Qcons, "cons");
   DEFSYM (Qmarker, "marker");
+  DEFSYM (Qlocated_symbol, "located-symbol");
   DEFSYM (Qoverlay, "overlay");
   DEFSYM (Qfinalizer, "finalizer");
 #ifdef HAVE_MODULES
@@ -3973,6 +4013,8 @@ syms_of_data (void)
   defsubr (&Snumber_or_marker_p);
   defsubr (&Sfloatp);
   defsubr (&Snatnump);
+  defsubr (&Sonly_symbol_p);
+  defsubr (&Slocated_symbol_p);
   defsubr (&Ssymbolp);
   defsubr (&Skeywordp);
   defsubr (&Sstringp);
@@ -4003,6 +4045,8 @@ syms_of_data (void)
   defsubr (&Sindirect_function);
   defsubr (&Ssymbol_plist);
   defsubr (&Ssymbol_name);
+  defsubr (&Slocated_symbol_sym);
+  defsubr (&Slocated_symbol_loc);
   defsubr (&Smakunbound);
   defsubr (&Sfmakunbound);
   defsubr (&Sboundp);
@@ -4078,6 +4122,11 @@ This variable cannot be set; trying to do so will signal 
an error.  */);
   Vmost_negative_fixnum = make_fixnum (MOST_NEGATIVE_FIXNUM);
   make_symbol_constant (intern_c_string ("most-negative-fixnum"));
 
+  DEFVAR_LISP ("located-symbols-enabled", Vlocated_symbols_enabled,
+               doc: /* Non-nil when "located symbols" can be used in place of 
symbols.
+Bind this to non-nil in applications such as the byte compiler.  */);
+  Vlocated_symbols_enabled = Qnil;
+
   DEFSYM (Qwatchers, "watchers");
   DEFSYM (Qmakunbound, "makunbound");
   DEFSYM (Qunlet, "unlet");
diff --git a/src/fns.c b/src/fns.c
index c9a6dd6..d421bc4 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2379,6 +2379,13 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum 
equal_kind equal_kind,
        }
     }
 
+  /* A located symbol compares the contained symbol, and is `equal' to
+     the corresponding ordinary symbol.  */
+  if (LOCATED_SYMBOL_P (o1))
+    o1 = LOCATED_SYMBOL_SYM (o1);
+  if (LOCATED_SYMBOL_P (o2))
+    o2 = LOCATED_SYMBOL_SYM (o2);
+
   if (EQ (o1, o2))
     return true;
   if (XTYPE (o1) != XTYPE (o2))
diff --git a/src/lisp.h b/src/lisp.h
index eb67626..b4fc6f2 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -323,6 +323,64 @@ typedef union Lisp_X *Lisp_Word;
 typedef EMACS_INT Lisp_Word;
 #endif
 
+/* A Lisp_Object is a tagged pointer or integer.  Ordinarily it is a
+   Lisp_Word.  However, if CHECK_LISP_OBJECT_TYPE, it is a wrapper
+   around Lisp_Word, to help catch thinkos like 'Lisp_Object x = 0;'.
+
+   LISP_INITIALLY (W) initializes a Lisp object with a tagged value
+   that is a Lisp_Word W.  It can be used in a static initializer.  */
+
+#ifdef CHECK_LISP_OBJECT_TYPE
+typedef struct Lisp_Object { Lisp_Word i; } Lisp_Object;
+# define LISP_INITIALLY(w) {w}
+# undef CHECK_LISP_OBJECT_TYPE
+enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true };
+#else
+typedef Lisp_Word Lisp_Object;
+# define LISP_INITIALLY(w) (w)
+enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
+#endif
+
+/* Header of vector-like objects.  This documents the layout constraints on
+   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
+   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
+   and PSEUDOVECTORP cast their pointers to union vectorlike_header *,
+   because when two such pointers potentially alias, a compiler won't
+   incorrectly reorder loads and stores to their size fields.  See
+   Bug#8546.  This union formerly contained more members, and there's
+   no compelling reason to change it to a struct merely because the
+   number of members has been reduced to one.  */
+union vectorlike_header
+  {
+    /* The main member contains various pieces of information:
+       - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
+       - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
+         vector (0) or a pseudovector (1).
+       - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
+         of slots) of the vector.
+       - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
+        - a) pseudovector subtype held in PVEC_TYPE_MASK field;
+        - b) number of Lisp_Objects slots at the beginning of the object
+          held in PSEUDOVECTOR_SIZE_MASK field.  These objects are always
+          traced by the GC;
+        - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
+          measured in word_size units.  Rest fields may also include
+          Lisp_Objects, but these objects usually needs some special treatment
+          during GC.
+        There are some exceptions.  For PVEC_FREE, b) is always zero.  For
+        PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
+        Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
+        4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots.  */
+    ptrdiff_t size;
+  };
+
+struct Lisp_Located_Symbol
+  {
+    union vectorlike_header header;
+    Lisp_Object sym;            /* A symbol */
+    Lisp_Object loc;            /* A fixnum */
+  } GCALIGNED_STRUCT;
+
 /* Some operations are so commonly executed that they are implemented
    as macros, not functions, because otherwise runtime performance would
    suffer too much when compiling with GCC without optimization.
@@ -379,6 +437,97 @@ typedef EMACS_INT Lisp_Word;
 # endif
 #endif
 
+/* In the size word of a vector, this bit means the vector has been marked.  */
+
+DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
+# define ARRAY_MARK_FLAG PTRDIFF_MIN
+DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
+
+/* In the size word of a struct Lisp_Vector, this bit means it's really
+   some other vector-like object.  */
+DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
+# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
+DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
+
+/* In a pseudovector, the size field actually contains a word with one
+   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
+   with PVEC_TYPE_MASK to indicate the actual type.  */
+enum pvec_type
+{
+  PVEC_NORMAL_VECTOR,
+  PVEC_FREE,
+  PVEC_BIGNUM,
+  PVEC_MARKER,
+  PVEC_OVERLAY,
+  PVEC_FINALIZER,
+  PVEC_LOCATED_SYMBOL,
+  PVEC_MISC_PTR,
+#ifdef HAVE_MODULES
+  PVEC_USER_PTR,
+#endif
+  PVEC_PROCESS,
+  PVEC_FRAME,
+  PVEC_WINDOW,
+  PVEC_BOOL_VECTOR,
+  PVEC_BUFFER,
+  PVEC_HASH_TABLE,
+  PVEC_TERMINAL,
+  PVEC_WINDOW_CONFIGURATION,
+  PVEC_SUBR,
+  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
+  PVEC_XWIDGET,
+  PVEC_XWIDGET_VIEW,
+  PVEC_THREAD,
+  PVEC_MUTEX,
+  PVEC_CONDVAR,
+  PVEC_MODULE_FUNCTION,
+
+  /* These should be last, check internal_equal to see why.  */
+  PVEC_COMPILED,
+  PVEC_CHAR_TABLE,
+  PVEC_SUB_CHAR_TABLE,
+  PVEC_RECORD,
+  PVEC_FONT /* Should be last because it's used for range checking.  */
+};
+
+enum More_Lisp_Bits
+  {
+    /* For convenience, we also store the number of elements in these bits.
+       Note that this size is not necessarily the memory-footprint size, but
+       only the number of Lisp_Object fields (that need to be traced by GC).
+       The distinction is used, e.g., by Lisp_Process, which places extra
+       non-Lisp_Object fields at the end of the structure.  */
+    PSEUDOVECTOR_SIZE_BITS = 12,
+    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
+
+    /* To calculate the memory footprint of the pseudovector, it's useful
+       to store the size of non-Lisp area in word_size units here.  */
+    PSEUDOVECTOR_REST_BITS = 12,
+    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
+                             << PSEUDOVECTOR_SIZE_BITS),
+
+    /* Used to extract pseudovector subtype information.  */
+    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
+    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
+  };
+
+#define lisp_h_PSEUDOVECTORP(a,code)                            \
+  (lisp_h_VECTORLIKEP(a) &&                                     \
+   ((XUNTAG (a, Lisp_Vectorlike, union vectorlike_header)->size \
+     & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))                    \
+    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
+
+
+/* These functions extract various sorts of values from a Lisp_Object.
+   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
+   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
+   that cons.  */
+
+/* Largest and smallest representable fixnum values.  These are the C
+   values.  They are macros for use in #if and static initializers.  */
+#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
+#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
+
 #define lisp_h_CHECK_FIXNUM(x) CHECK_TYPE (FIXNUMP (x), Qfixnump, x)
 #define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x)
 #define lisp_h_CHECK_TYPE(ok, predicate, x) \
@@ -399,7 +548,11 @@ typedef EMACS_INT Lisp_Word;
 #define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->u.s.trapped_write)
 #define lisp_h_SYMBOL_VAL(sym) \
    (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), (sym)->u.s.val.value)
-#define lisp_h_SYMBOLP(x) TAGGEDP (x, Lisp_Symbol)
+#define lisp_h_LOCATED_SYMBOL_P(x) lisp_h_PSEUDOVECTORP (XIL(x), 
PVEC_LOCATED_SYMBOL)
+#define lisp_h_ONLY_SYMBOL_P(x) TAGGEDP (x, Lisp_Symbol)
+/* verify (NIL_IS_ZERO) */
+#define lisp_h_SYMBOLP(x) ((lisp_h_ONLY_SYMBOL_P (x) || \
+                            (Vlocated_symbols_enabled && 
(lisp_h_LOCATED_SYMBOL_P (x)))))
 #define lisp_h_TAGGEDP(a, tag) \
    (! (((unsigned) (XLI (a) >> (USE_LSB_TAG ? 0 : VALBITS)) \
        - (unsigned) (tag)) \
@@ -419,18 +572,31 @@ typedef EMACS_INT Lisp_Word;
 # define lisp_h_XFIXNAT(a) XFIXNUM (a)
 # define lisp_h_XFIXNUM(a) (XLI (a) >> INTTYPEBITS)
 # ifdef __CHKP__
-#  define lisp_h_XSYMBOL(a) \
-    (eassert (SYMBOLP (a)), \
+#  define lisp_h_XONLY_SYMBOL(a) \
+    (eassert (ONLY_SYMBOL_P (a)), \
      (struct Lisp_Symbol *) ((char *) XUNTAG (a, Lisp_Symbol, \
                                              struct Lisp_Symbol) \
                             + (intptr_t) lispsym))
 # else
    /* If !__CHKP__ this is equivalent, and is a bit faster as of GCC 7.  */
-#  define lisp_h_XSYMBOL(a) \
-    (eassert (SYMBOLP (a)), \
+#  define lisp_h_XONLY_SYMBOL(a) \
+    (eassert (ONLY_SYMBOL_P (a)), \
      (struct Lisp_Symbol *) ((intptr_t) XLI (a) - Lisp_Symbol \
                             + (char *) lispsym))
 # endif
+# define lisp_h_XLOCATED_SYMBOL(a)                      \
+    (eassert (LOCATED_SYMBOL_P (a)),                    \
+     (struct Lisp_Located_Symbol *) XUNTAG              \
+     (a, Lisp_Vectorlike, struct Lisp_Located_Symbol))
+/* verify (NIL_IS_ZERO) */
+# define lisp_h_XSYMBOL(a)                      \
+    (eassert (SYMBOLP (a)),                     \
+      (!Vlocated_symbols_enabled                \
+      ? (lisp_h_XONLY_SYMBOL (a))               \
+       : (lisp_h_ONLY_SYMBOL_P (a))             \
+      ? (lisp_h_XONLY_SYMBOL (a))               \
+       : lisp_h_XONLY_SYMBOL (lisp_h_XLOCATED_SYMBOL (a)->sym)))
+
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
 #endif
 
@@ -462,6 +628,7 @@ typedef EMACS_INT Lisp_Word;
 # define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym)
 # define SYMBOL_TRAPPED_WRITE_P(sym) lisp_h_SYMBOL_TRAPPED_WRITE_P (sym)
 # define SYMBOL_VAL(sym) lisp_h_SYMBOL_VAL (sym)
+# define ONLY_SYMBOL_P(x) lisp_h_ONLY_SYMBOL_P (x)
 # define SYMBOLP(x) lisp_h_SYMBOLP (x)
 # define TAGGEDP(a, tag) lisp_h_TAGGEDP (a, tag)
 # define VECTORLIKEP(x) lisp_h_VECTORLIKEP (x)
@@ -476,6 +643,7 @@ typedef EMACS_INT Lisp_Word;
 #  define make_fixnum(n) lisp_h_make_fixnum (n)
 #  define XFIXNAT(a) lisp_h_XFIXNAT (a)
 #  define XFIXNUM(a) lisp_h_XFIXNUM (a)
+#  define XONLY_SYMBOL(a)  lisp_h_XONLY_SYMBOL (a)
 #  define XSYMBOL(a) lisp_h_XSYMBOL (a)
 #  define XTYPE(a) lisp_h_XTYPE (a)
 # endif
@@ -585,24 +753,6 @@ enum Lisp_Fwd_Type
    You also need to add the new type to the constant
    `cl--typeof-types' in lisp/emacs-lisp/cl-preloaded.el.  */
 
-
-/* A Lisp_Object is a tagged pointer or integer.  Ordinarily it is a
-   Lisp_Word.  However, if CHECK_LISP_OBJECT_TYPE, it is a wrapper
-   around Lisp_Word, to help catch thinkos like 'Lisp_Object x = 0;'.
-
-   LISP_INITIALLY (W) initializes a Lisp object with a tagged value
-   that is a Lisp_Word W.  It can be used in a static initializer.  */
-
-#ifdef CHECK_LISP_OBJECT_TYPE
-typedef struct Lisp_Object { Lisp_Word i; } Lisp_Object;
-# define LISP_INITIALLY(w) {w}
-# undef CHECK_LISP_OBJECT_TYPE
-enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true };
-#else
-typedef Lisp_Word Lisp_Object;
-# define LISP_INITIALLY(w) (w)
-enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
-#endif
 
 /* Forward declarations.  */
 
@@ -621,7 +771,7 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object);
 
 /* Defined in data.c.  */
 extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
-
+extern Lisp_Object Vlocated_symbols_enabled;
 
 #ifdef CANNOT_DUMP
 enum { might_dump = false };
@@ -864,38 +1014,11 @@ typedef EMACS_UINT Lisp_Word_tag;
 
 #include "globals.h"
 
-/* Header of vector-like objects.  This documents the layout constraints on
-   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
-   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
-   and PSEUDOVECTORP cast their pointers to union vectorlike_header *,
-   because when two such pointers potentially alias, a compiler won't
-   incorrectly reorder loads and stores to their size fields.  See
-   Bug#8546.  This union formerly contained more members, and there's
-   no compelling reason to change it to a struct merely because the
-   number of members has been reduced to one.  */
-union vectorlike_header
-  {
-    /* The main member contains various pieces of information:
-       - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
-       - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
-         vector (0) or a pseudovector (1).
-       - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
-         of slots) of the vector.
-       - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
-        - a) pseudovector subtype held in PVEC_TYPE_MASK field;
-        - b) number of Lisp_Objects slots at the beginning of the object
-          held in PSEUDOVECTOR_SIZE_MASK field.  These objects are always
-          traced by the GC;
-        - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
-          measured in word_size units.  Rest fields may also include
-          Lisp_Objects, but these objects usually needs some special treatment
-          during GC.
-        There are some exceptions.  For PVEC_FREE, b) is always zero.  For
-        PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
-        Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
-        4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots.  */
-    ptrdiff_t size;
-  };
+INLINE bool
+(LOCATED_SYMBOL_P) (Lisp_Object x)
+{
+  return lisp_h_LOCATED_SYMBOL_P (x);
+}
 
 INLINE bool
 (SYMBOLP) (Lisp_Object x)
@@ -954,89 +1077,7 @@ INLINE void
   lisp_h_CHECK_SYMBOL (x);
 }
 
-/* In the size word of a vector, this bit means the vector has been marked.  */
-
-DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
-# define ARRAY_MARK_FLAG PTRDIFF_MIN
-DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
-
-/* In the size word of a struct Lisp_Vector, this bit means it's really
-   some other vector-like object.  */
-DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
-# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
-DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
-
-/* In a pseudovector, the size field actually contains a word with one
-   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
-   with PVEC_TYPE_MASK to indicate the actual type.  */
-enum pvec_type
-{
-  PVEC_NORMAL_VECTOR,
-  PVEC_FREE,
-  PVEC_BIGNUM,
-  PVEC_MARKER,
-  PVEC_OVERLAY,
-  PVEC_FINALIZER,
-  PVEC_MISC_PTR,
-#ifdef HAVE_MODULES
-  PVEC_USER_PTR,
-#endif
-  PVEC_PROCESS,
-  PVEC_FRAME,
-  PVEC_WINDOW,
-  PVEC_BOOL_VECTOR,
-  PVEC_BUFFER,
-  PVEC_HASH_TABLE,
-  PVEC_TERMINAL,
-  PVEC_WINDOW_CONFIGURATION,
-  PVEC_SUBR,
-  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
-  PVEC_XWIDGET,
-  PVEC_XWIDGET_VIEW,
-  PVEC_THREAD,
-  PVEC_MUTEX,
-  PVEC_CONDVAR,
-  PVEC_MODULE_FUNCTION,
-
-  /* These should be last, check internal_equal to see why.  */
-  PVEC_COMPILED,
-  PVEC_CHAR_TABLE,
-  PVEC_SUB_CHAR_TABLE,
-  PVEC_RECORD,
-  PVEC_FONT /* Should be last because it's used for range checking.  */
-};
-
-enum More_Lisp_Bits
-  {
-    /* For convenience, we also store the number of elements in these bits.
-       Note that this size is not necessarily the memory-footprint size, but
-       only the number of Lisp_Object fields (that need to be traced by GC).
-       The distinction is used, e.g., by Lisp_Process, which places extra
-       non-Lisp_Object fields at the end of the structure.  */
-    PSEUDOVECTOR_SIZE_BITS = 12,
-    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
-
-    /* To calculate the memory footprint of the pseudovector, it's useful
-       to store the size of non-Lisp area in word_size units here.  */
-    PSEUDOVECTOR_REST_BITS = 12,
-    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
-                             << PSEUDOVECTOR_SIZE_BITS),
-
-    /* Used to extract pseudovector subtype information.  */
-    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
-    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
-  };
 
-/* These functions extract various sorts of values from a Lisp_Object.
-   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
-   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
-   that cons.  */
-
-/* Largest and smallest representable fixnum values.  These are the C
-   values.  They are macros for use in #if and static initializers.  */
-#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
-#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
-
 #if USE_LSB_TAG
 
 INLINE Lisp_Object
@@ -1586,6 +1627,7 @@ PSEUDOVECTOR_TYPEP (union vectorlike_header *a, enum 
pvec_type code)
          == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
 }
 
+/* FIXME!!! 2018-11-09.  Consider using lisp_h_PSEUDOVECTOR here. */
 /* True if A is a pseudovector whose code is CODE.  */
 INLINE bool
 PSEUDOVECTORP (Lisp_Object a, int code)
@@ -2480,6 +2522,29 @@ XOVERLAY (Lisp_Object a)
   return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Overlay);
 }
 
+INLINE struct Lisp_Located_Symbol *
+XLOCATED_SYMBOL (Lisp_Object a)
+{
+    eassert (LOCATED_SYMBOL_P (a));
+    return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Located_Symbol);
+}
+
+INLINE Lisp_Object
+LOCATED_SYMBOL_SYM (Lisp_Object a)
+{
+  if (!LOCATED_SYMBOL_P (a))
+    wrong_type_argument (Qlocated_symbol_p, a);
+  return XLOCATED_SYMBOL (a)->sym;
+}
+
+INLINE Lisp_Object
+LOCATED_SYMBOL_LOC (Lisp_Object a)
+{
+  if (!LOCATED_SYMBOL_P (a))
+    wrong_type_argument (Qlocated_symbol_p, a);
+  return XLOCATED_SYMBOL (a)->loc;
+}
+
 #ifdef HAVE_MODULES
 INLINE bool
 USER_PTRP (Lisp_Object x)
@@ -3754,6 +3819,7 @@ extern bool gc_in_progress;
 extern Lisp_Object make_float (double);
 extern void display_malloc_warning (void);
 extern ptrdiff_t inhibit_garbage_collection (void);
+extern Lisp_Object build_located_symbol (Lisp_Object, Lisp_Object);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);
 extern void init_alloc_once (void);
diff --git a/src/lread.c b/src/lread.c
index 5f38714..3490d83 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -616,12 +616,12 @@ struct subst
 };
 
 static Lisp_Object read_internal_start (Lisp_Object, Lisp_Object,
-                                        Lisp_Object);
-static Lisp_Object read0 (Lisp_Object);
-static Lisp_Object read1 (Lisp_Object, int *, bool);
+                                        Lisp_Object, bool);
+static Lisp_Object read0 (Lisp_Object, bool);
+static Lisp_Object read1 (Lisp_Object, int *, bool, bool);
 
-static Lisp_Object read_list (bool, Lisp_Object);
-static Lisp_Object read_vector (Lisp_Object, bool);
+static Lisp_Object read_list (bool, Lisp_Object, bool);
+static Lisp_Object read_vector (Lisp_Object, bool, bool);
 
 static Lisp_Object substitute_object_recurse (struct subst *, Lisp_Object);
 static void substitute_in_interval (INTERVAL, void *);
@@ -2046,7 +2046,7 @@ readevalloop (Lisp_Object readcharfun,
                             Qnil, false);
       if (!NILP (Vpurify_flag) && c == '(')
        {
-         val = read_list (0, readcharfun);
+         val = read_list (0, readcharfun, false);
        }
       else
        {
@@ -2068,7 +2068,7 @@ readevalloop (Lisp_Object readcharfun,
          else if (! NILP (Vload_read_function))
            val = call1 (Vload_read_function, readcharfun);
          else
-           val = read_internal_start (readcharfun, Qnil, Qnil);
+           val = read_internal_start (readcharfun, Qnil, Qnil, false);
        }
       /* Empty hashes can be reused; otherwise, reset on next call.  */
       if (HASH_TABLE_P (read_objects_map)
@@ -2217,7 +2217,35 @@ STREAM or the value of `standard-input' may be:
     return call1 (intern ("read-minibuffer"),
                  build_string ("Lisp expression: "));
 
-  return read_internal_start (stream, Qnil, Qnil);
+  return read_internal_start (stream, Qnil, Qnil, false);
+}
+
+DEFUN ("read-locating-symbols", Fread_locating_symbols,
+       Sread_locating_symbols, 0, 1, 0,
+       doc: /* Read one Lisp expression as text from STREAM, return as Lisp 
object.
+Convert each occurrence of a symbol into a "located symbol" object.
+
+If STREAM is nil, use the value of `standard-input' (which see).
+STREAM or the value of `standard-input' may be:
+ a buffer (read from point and advance it)
+ a marker (read from where it points and advance it)
+ a function (call it with no arguments for each character,
+     call it with a char as argument to push a char back)
+ a string (takes text from string, starting at the beginning)
+ t (read text line using minibuffer and use it, or read from
+    standard input in batch mode).  */)
+  (Lisp_Object stream)
+{
+  if (NILP (stream))
+    stream = Vstandard_input;
+  if (EQ (stream, Qt))
+    stream = Qread_char;
+  if (EQ (stream, Qread_char))
+    /* FIXME: ?! When is this used !?  */
+    return call1 (intern ("read-minibuffer"),
+                 build_string ("Lisp expression: "));
+
+  return read_internal_start (stream, Qnil, Qnil, true);
 }
 
 DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
@@ -2233,14 +2261,17 @@ the end of STRING.  */)
   Lisp_Object ret;
   CHECK_STRING (string);
   /* `read_internal_start' sets `read_from_string_index'.  */
-  ret = read_internal_start (string, start, end);
+  ret = read_internal_start (string, start, end, false);
   return Fcons (ret, make_fixnum (read_from_string_index));
 }
 
 /* Function to set up the global context we need in toplevel read
-   calls.  START and END only used when STREAM is a string.  */
+   calls.  START and END only used when STREAM is a string.
+   LOCATE_SYMS true means read symbol occurrences as located
+   symbols.  */
 static Lisp_Object
-read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
+read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end,
+                     bool locate_syms)
 {
   Lisp_Object retval;
 
@@ -2281,7 +2312,7 @@ read_internal_start (Lisp_Object stream, Lisp_Object 
start, Lisp_Object end)
       read_from_string_limit = endval;
     }
 
-  retval = read0 (stream);
+  retval = read0 (stream, locate_syms);
   if (EQ (Vread_with_symbol_positions, Qt)
       || EQ (Vread_with_symbol_positions, stream))
     Vread_symbol_positions_list = Fnreverse (Vread_symbol_positions_list);
@@ -2310,12 +2341,12 @@ invalid_syntax (const char *s)
    are not allowed.  */
 
 static Lisp_Object
-read0 (Lisp_Object readcharfun)
+read0 (Lisp_Object readcharfun, bool locate_syms)
 {
   register Lisp_Object val;
   int c;
 
-  val = read1 (readcharfun, &c, 0);
+  val = read1 (readcharfun, &c, 0, locate_syms);
   if (!c)
     return val;
 
@@ -2736,10 +2767,11 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
    in *PCH and the return value is not interesting.  Else, we store
    zero in *PCH and we read and return one lisp object.
 
-   FIRST_IN_LIST is true if this is the first element of a list.  */
+   FIRST_IN_LIST is true if this is the first element of a list.
+   LOCATE_SYMS true means read symbol occurrences as located symbols.  */
 
 static Lisp_Object
-read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
+read1 (Lisp_Object readcharfun, int *pch, bool first_in_list, bool locate_syms)
 {
   int c;
   bool uninterned_symbol = false;
@@ -2758,10 +2790,10 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
   switch (c)
     {
     case '(':
-      return read_list (0, readcharfun);
+      return read_list (0, readcharfun, locate_syms);
 
     case '[':
-      return read_vector (readcharfun, 0);
+      return read_vector (readcharfun, 0, locate_syms);
 
     case ')':
     case ']':
@@ -2780,7 +2812,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
              /* Accept extended format for hash tables (extensible to
                 other types), e.g.
                 #s(hash-table size 2 test equal data (k1 v1 k2 v2))  */
-             Lisp_Object tmp = read_list (0, readcharfun);
+             Lisp_Object tmp = read_list (0, readcharfun, locate_syms);
              Lisp_Object head = CAR_SAFE (tmp);
              Lisp_Object data = Qnil;
              Lisp_Object val = Qnil;
@@ -2866,7 +2898,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
          if (c == '[')
            {
              Lisp_Object tmp;
-             tmp = read_vector (readcharfun, 0);
+             tmp = read_vector (readcharfun, 0, locate_syms);
              if (ASIZE (tmp) < CHAR_TABLE_STANDARD_SLOTS)
                error ("Invalid size char-table");
              XSETPVECTYPE (XVECTOR (tmp), PVEC_CHAR_TABLE);
@@ -2879,7 +2911,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                {
                  /* Sub char-table can't be read as a regular
                     vector because of a two C integer fields.  */
-                 Lisp_Object tbl, tmp = read_list (1, readcharfun);
+                 Lisp_Object tbl, tmp = read_list (1, readcharfun, 
locate_syms);
                  ptrdiff_t size = XFIXNUM (Flength (tmp));
                  int i, depth, min_char;
                  struct Lisp_Cons *cell;
@@ -2917,7 +2949,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
       if (c == '&')
        {
          Lisp_Object length;
-         length = read1 (readcharfun, pch, first_in_list);
+         length = read1 (readcharfun, pch, first_in_list, locate_syms);
          c = READCHAR;
          if (c == '"')
            {
@@ -2926,7 +2958,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
              unsigned char *data;
 
              UNREAD (c);
-             tmp = read1 (readcharfun, pch, first_in_list);
+             tmp = read1 (readcharfun, pch, first_in_list, locate_syms);
              if (STRING_MULTIBYTE (tmp)
                  || (size_in_chars != SCHARS (tmp)
                      /* We used to print 1 char too many
@@ -2954,7 +2986,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
             build them using function calls.  */
          Lisp_Object tmp;
          struct Lisp_Vector *vec;
-         tmp = read_vector (readcharfun, 1);
+         tmp = read_vector (readcharfun, 1, locate_syms);
          vec = XVECTOR (tmp);
          if (vec->header.size == 0)
            invalid_syntax ("Empty byte-code object");
@@ -2967,7 +2999,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
          int ch;
 
          /* Read the string itself.  */
-         tmp = read1 (readcharfun, &ch, 0);
+         tmp = read1 (readcharfun, &ch, 0, locate_syms);
          if (ch != 0 || !STRINGP (tmp))
            invalid_syntax ("#");
          /* Read the intervals and their properties.  */
@@ -2975,14 +3007,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
            {
              Lisp_Object beg, end, plist;
 
-             beg = read1 (readcharfun, &ch, 0);
+             beg = read1 (readcharfun, &ch, 0, locate_syms);
              end = plist = Qnil;
              if (ch == ')')
                break;
              if (ch == 0)
-               end = read1 (readcharfun, &ch, 0);
+               end = read1 (readcharfun, &ch, 0, locate_syms);
              if (ch == 0)
-               plist = read1 (readcharfun, &ch, 0);
+               plist = read1 (readcharfun, &ch, 0, locate_syms);
              if (ch)
                invalid_syntax ("Invalid string property list");
              Fset_text_properties (beg, end, plist, tmp);
@@ -3093,7 +3125,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
       if (c == '$')
        return Vload_file_name;
       if (c == '\'')
-       return list2 (Qfunction, read0 (readcharfun));
+       return list2 (Qfunction, read0 (readcharfun, locate_syms));
       /* #:foo is the uninterned symbol named foo.  */
       if (c == ':')
        {
@@ -3166,7 +3198,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                        hash_put (h, number, placeholder, hash);
 
                      /* Read the object itself.  */
-                     tem = read0 (readcharfun);
+                     tem = read0 (readcharfun, locate_syms);
 
                      /* If it can be recursive, remember it for
                         future substitutions.  */
@@ -3230,7 +3262,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
       goto retry;
 
     case '\'':
-      return list2 (Qquote, read0 (readcharfun));
+      return list2 (Qquote, read0 (readcharfun, locate_syms));
 
     case '`':
       {
@@ -3254,7 +3286,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
            bool saved_new_backquote_flag = new_backquote_flag;
 
            new_backquote_flag = 1;
-           value = read0 (readcharfun);
+           value = read0 (readcharfun, locate_syms);
            new_backquote_flag = saved_new_backquote_flag;
 
            return list2 (Qbackquote, value);
@@ -3294,7 +3326,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                comma_type = Qcomma;
              }
 
-           value = read0 (readcharfun);
+           value = read0 (readcharfun, locate_syms);
            return list2 (comma_type, value);
          }
        else
@@ -3586,6 +3618,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                  result = intern_driver (name, obarray, tem);
                }
            }
+          if (locate_syms)
+            result = build_located_symbol (result,
+                                           make_fixnum (start_position));
 
          if (EQ (Vread_with_symbol_positions, Qt)
              || EQ (Vread_with_symbol_positions, readcharfun))
@@ -3844,7 +3879,7 @@ string_to_number (char const *string, int base, ptrdiff_t 
*plen)
 
 
 static Lisp_Object
-read_vector (Lisp_Object readcharfun, bool bytecodeflag)
+read_vector (Lisp_Object readcharfun, bool bytecodeflag, bool locate_syms)
 {
   ptrdiff_t i, size;
   Lisp_Object *ptr;
@@ -3852,7 +3887,7 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag)
   struct Lisp_Cons *otem;
   Lisp_Object len;
 
-  tem = read_list (1, readcharfun);
+  tem = read_list (1, readcharfun, locate_syms);
   len = Flength (tem);
   if (bytecodeflag && XFIXNAT (len) <= COMPILED_STACK_DEPTH)
     error ("Invalid byte code");
@@ -3923,10 +3958,12 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag)
   return vector;
 }
 
-/* FLAG means check for ']' to terminate rather than ')' and '.'.  */
+/* FLAG means check for ']' to terminate rather than ')' and '.'.
+   LOCATE_SYMS true means read symbol occurrencess as located
+   symbols. */
 
 static Lisp_Object
-read_list (bool flag, Lisp_Object readcharfun)
+read_list (bool flag, Lisp_Object readcharfun, bool locate_syms)
 {
   Lisp_Object val, tail;
   Lisp_Object elt, tem;
@@ -3944,7 +3981,7 @@ read_list (bool flag, Lisp_Object readcharfun)
   while (1)
     {
       int ch;
-      elt = read1 (readcharfun, &ch, first_in_list);
+      elt = read1 (readcharfun, &ch, first_in_list, locate_syms);
 
       first_in_list = 0;
 
@@ -3988,10 +4025,10 @@ read_list (bool flag, Lisp_Object readcharfun)
          if (ch == '.')
            {
              if (!NILP (tail))
-               XSETCDR (tail, read0 (readcharfun));
+               XSETCDR (tail, read0 (readcharfun, locate_syms));
              else
-               val = read0 (readcharfun);
-             read1 (readcharfun, &ch, 0);
+               val = read0 (readcharfun, locate_syms);
+             read1 (readcharfun, &ch, 0, locate_syms);
 
              if (ch == ')')
                {
@@ -4808,6 +4845,7 @@ void
 syms_of_lread (void)
 {
   defsubr (&Sread);
+  defsubr (&Sread_locating_symbols);
   defsubr (&Sread_from_string);
   defsubr (&Slread__substitute_object_in_subtree);
   defsubr (&Sintern);
@@ -4984,6 +5022,7 @@ Called with a single argument (the stream from which to 
read).
 The default is to use the function `read'.  */);
   DEFSYM (Qread, "read");
   Vload_read_function = Qread;
+  DEFSYM (Qread_locating_symbols, "read-locating-symbols");
 
   DEFVAR_LISP ("load-source-file-function", Vload_source_file_function,
               doc: /* Function called in `load' to load an Emacs Lisp source 
file.
diff --git a/src/print.c b/src/print.c
index d15ff97..d138806 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1394,6 +1394,25 @@ print_vectorlike (Lisp_Object obj, Lisp_Object 
printcharfun, bool escapeflag,
       printchar ('>', printcharfun);
       break;
 
+    case PVEC_LOCATED_SYMBOL:
+      {
+        struct Lisp_Located_Symbol *ls = XLOCATED_SYMBOL (obj);
+        print_c_string ("#<symbol ", printcharfun);
+        if (SYMBOLP (ls->sym))
+          print_object (ls->sym, printcharfun, escapeflag);
+        else
+          print_c_string ("NOT A SYMBOL!!", printcharfun);
+        if (FIXNUMP (ls->loc))
+          {
+            print_c_string (" at ", printcharfun);
+            print_object (ls->loc, printcharfun, escapeflag);
+          }
+        else
+          print_c_string (" NOT A LOCATION!!", printcharfun);
+        printchar ('>', printcharfun);
+      }
+      break;
+
     case PVEC_OVERLAY:
       print_c_string ("#<overlay ", printcharfun);
       if (! XMARKER (OVERLAY_START (obj))->buffer)



reply via email to

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