2002-01-23 Elena Zannoni <ezannoni@redhat.com>
authorElena Zannoni <ezannoni@kwikemart.cygnus.com>
Thu, 24 Jan 2002 03:44:10 +0000 (03:44 +0000)
committerElena Zannoni <ezannoni@kwikemart.cygnus.com>
Thu, 24 Jan 2002 03:44:10 +0000 (03:44 +0000)
        * Makefile.in (hpread_h): Delete.
        (HFILES_NO_SRCDIR): Remove hpread.h.
        (ALLDEPFILES): Remove hp-psymtab-read.c and hp-symtab-read.c.
        (hpread.o): Update dependencies.
        (hp-psymtab-read.o, hp-symtab-read.o): Remove.

        * hp-psymtab-read.c: Remove file.
        * hp-symtab-read.c: Remove file.
        * hpread.h: Remove file.

        * hpread.c: Merge all contents of hp-psymtab-read.c,
        hp-symtab-read.c and hpread.h into this file, as it was prior to
        January 1999.

        * config/pa/hpux11w.mh, config/pa/hpux11.mh,
        config/pa/hpux1020.mh, config/pa/hppaosf.mh,
        config/pa/hppahpux.mh, config/pa/hppabsd.mh (NATDEPFILES):
        Remove hp-psymtab-read.o and hp-symtab-read.o, add hpread.o.

12 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/config/pa/hppabsd.mh
gdb/config/pa/hppahpux.mh
gdb/config/pa/hppaosf.mh
gdb/config/pa/hpux1020.mh
gdb/config/pa/hpux11.mh
gdb/config/pa/hpux11w.mh
gdb/hp-psymtab-read.c [deleted file]
gdb/hp-symtab-read.c [deleted file]
gdb/hpread.c
gdb/hpread.h [deleted file]

index 123aca2..fa8553c 100644 (file)
@@ -1,5 +1,26 @@
 2002-01-23  Elena Zannoni  <ezannoni@redhat.com>
 
+        * Makefile.in (hpread_h): Delete. 
+        (HFILES_NO_SRCDIR): Remove hpread.h.
+        (ALLDEPFILES): Remove hp-psymtab-read.c and hp-symtab-read.c.
+        (hpread.o): Update dependencies.
+        (hp-psymtab-read.o, hp-symtab-read.o): Remove.
+
+        * hp-psymtab-read.c: Remove file.
+        * hp-symtab-read.c: Remove file.
+        * hpread.h: Remove file.
+
+        * hpread.c: Merge all contents of hp-psymtab-read.c,
+        hp-symtab-read.c and hpread.h into this file, as it was prior to
+        January 1999.
+
+        * config/pa/hpux11w.mh, config/pa/hpux11.mh,
+        config/pa/hpux1020.mh, config/pa/hppaosf.mh, 
+        config/pa/hppahpux.mh, config/pa/hppabsd.mh (NATDEPFILES):
+        Remove hp-psymtab-read.o and hp-symtab-read.o, add hpread.o.
+
+2002-01-23  Elena Zannoni  <ezannoni@redhat.com>
+
        * ppc-linux-nat.c (ppc_register_u_addr, supply_gregset,
        fill_gregset): Call gdbarch_tdep() just once, assign result to
        variable and use that, instead of calling the function several
index 855e79f..215c698 100644 (file)
@@ -617,10 +617,6 @@ gdbcmd_h = gdbcmd.h $(command_h) $(ui_out_h)
 gdbcore_h =    gdbcore.h $(bfd_h)
 gdbthread_h =  gdbthread.h $(breakpoint_h)
 gdbtypes_h =   gdbtypes.h
-hpread_h =     hpread.h $(defs_h) $(bfd_h) $(gdb_string_h) $(hp_symtab_h) \
-               $(syms_h) $(symtab_h) $(symfile_h) $(objfiles_h) \
-               $(buildsym_h) $(complaints_h) $(gdb_stabs_h) $(gdbtypes_h) \
-               $(demangle_h)
 inf_loop_h =   inf-loop.h
 inferior_h =   inferior.h $(breakpoint_h)
 language_h =   language.h
@@ -660,7 +656,7 @@ xcoffsolib_h =      xcoffsolib.h
 
 HFILES_NO_SRCDIR = bcache.h buildsym.h call-cmds.h coff-solib.h defs.h \
        dst.h environ.h $(gdbcmd_h) gdb.h gdbcore.h \
-       gdb-stabs.h hpread.h $(inferior_h) language.h minimon.h monitor.h \
+       gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \
        objfiles.h parser-defs.h serial.h solib.h \
        symfile.h stabsread.h target.h terminal.h typeprint.h xcoffsolib.h \
        c-lang.h ch-lang.h f-lang.h \
@@ -1177,8 +1173,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
        core-sol2.c core-regset.c core-aout.c corelow.c \
        dcache.c delta68-nat.c dpx2-nat.c dstread.c exec.c fork-child.c \
        go32-nat.c h8300-tdep.c h8500-tdep.c \
-       hp300ux-nat.c hppa-tdep.c hppab-nat.c hppah-nat.c \
-        hp-psymtab-read.c hp-symtab-read.c \
+       hp300ux-nat.c hppa-tdep.c hppab-nat.c hppah-nat.c hpread.c \
        i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c i386-linux-nat.c \
        i386aix-nat.c i386m3-nat.c i386v4-nat.c i386ly-tdep.c \
        i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c \
@@ -1800,18 +1795,10 @@ hpux-thread.o: hpux-thread.c $(defs_h) $(gdbthread_h) $(target_h) inferior.h \
        $(CC) -c $(INTERNAL_CFLAGS) -I$(srcdir)/osf-share \
          -I$(srcdir)/osf-share/HP800 -I/usr/include/dce $(srcdir)/hpux-thread.c
 
-# FIXME!!!
 hpread.o: hpread.c $(bfd_h) $(buildsym_h) $(complaints_h) $(defs_h) \
-       $(gdb_stabs_h) $(objfiles_h) $(symfile_h) $(symtab_h) $(gdb_string_h)
-
-hp-psymtab-read.o: hp-psymtab-read.c $(hpread_h) $(bfd_h) $(buildsym_h) \
-       $(complaints_h) $(defs_h) $(gdb_stabs_h) $(objfiles_h) $(symfile_h) \
-       $(symtab_h) $(gdb_string_h)
-hp-symtab-read.o: hp-symtab-read.c $(hpread_h) $(bfd_h) $(buildsym_h) \
-       $(complaints_h) $(defs_h) $(gdb_stabs_h) $(objfiles_h) $(symfile_h) \
-       $(symtab_h) $(gdb_string_h)
-# END FIXME!!!  
+       $(demangle_h) $(gdb_stabs_h) $(gdbtypes_h) $(objfiles_h) \
+       $(symfile_h) $(syms_h) $(symtab_h) $(gdb_string_h) \
+       $(INCLUDE_DIR)/hp-symtab.h
 
 parse.o: parse.c $(command_h) $(defs_h) $(expression_h) $(frame_h) \
        $(gdbtypes_h) $(language_h) $(parser_defs_h) $(symtab_h) $(value_h) \
index c264db3..9d8a338 100644 (file)
@@ -1,6 +1,6 @@
 # Host: Hewlett-Packard PA-RISC machine, running BSD
 XM_FILE= xm-hppab.h
 NAT_FILE= nm-hppab.h
-NATDEPFILES= hppab-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hp-psymtab-read.o hp-symtab-read.o somsolib.o
+NATDEPFILES= hppab-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hpread.o somsolib.o
 
 GDBSERVER_DEPFILES= low-hppabsd.o
index 5d49f0c..c052057 100644 (file)
@@ -3,6 +3,6 @@
 XM_FILE= xm-hppah.h
 
 NAT_FILE= nm-hppah.h
-NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hp-psymtab-read.o hp-symtab-read.o somsolib.o
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hpread.o somsolib.o
 
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
index c2724b2..914e0a0 100644 (file)
@@ -1,7 +1,7 @@
 # Host: Hewlett-Packard PA-RISC machine, running BSD
 XM_FILE= xm-hppab.h
 NAT_FILE= nm-hppao.h
-NATDEPFILES= fork-child.o m3-nat.o hppam3-nat.o somread.o hp-psymtab-read.o hp-symtab-read.o somsolib.o
+NATDEPFILES= fork-child.o m3-nat.o hppam3-nat.o somread.o hpread.o somsolib.o
 NAT_CLIBS= -lmachid -lnetname -lmach
 
 GDBSERVER_DEPFILES= low-hppabsd.o
index 9687b60..e9c24ee 100644 (file)
@@ -5,6 +5,6 @@ MH_CFLAGS = -D__HP_CURSES
 XM_FILE= xm-hppah.h
 
 NAT_FILE= nm-hppah.h
-NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infptrace.o somread.o hp-psymtab-read.o hp-symtab-read.o somsolib.o
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infptrace.o somread.o hpread.o somsolib.o
 
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
index b9b60ac..a9919c4 100644 (file)
@@ -5,6 +5,6 @@ MH_CFLAGS = -D__HP_CURSES
 XM_FILE= xm-hppah.h
 
 NAT_FILE= nm-hppah11.h
-NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o somread.o hp-psymtab-read.o hp-symtab-read.o somsolib.o
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o somread.o hpread.o somsolib.o
 
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
index dad20a0..279efa1 100644 (file)
@@ -5,6 +5,6 @@ MH_CFLAGS = -D__HP_CURSES
 XM_FILE= xm-hppah.h
 
 NAT_FILE= nm-hppah11.h
-NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o hp-psymtab-read.o hp-symtab-read.o pa64solib.o
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o hpread.o pa64solib.o
 
 HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
diff --git a/gdb/hp-psymtab-read.c b/gdb/hp-psymtab-read.c
deleted file mode 100644 (file)
index a7a4a7f..0000000
+++ /dev/null
@@ -1,2319 +0,0 @@
-/* Read hp debug symbols and convert to internal format, for GDB.
-   Copyright 1993, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
-
-   Written by the Center for Software Science at the University of Utah
-   and by Cygnus Support.  */
-
-/* Common include file for hp_symtab_read.c and hp_psymtab_read.c.
-   This has nested includes of a bunch of stuff. */
-#include "hpread.h"
-#include "demangle.h"
-
-/* To generate dumping code, uncomment this define.  The dumping
-   itself is controlled by routine-local statics called "dumping". */
-/* #define DUMPING         1 */
-
-/* To use the quick look-up tables, uncomment this define. */
-#define QUICK_LOOK_UP      1
-
-/* To call PXDB to process un-processed files, uncomment this define. */
-#define USE_PXDB           1
-
-/* Forward procedure declarations */
-
-void hpread_symfile_init (struct objfile *);
-
-void do_pxdb (bfd *);
-
-void hpread_build_psymtabs (struct objfile *, int);
-
-void hpread_symfile_finish (struct objfile *);
-
-static union dnttentry *hpread_get_gntt (int, struct objfile *);
-
-static unsigned long hpread_get_textlow (int, int, struct objfile *, int);
-
-static struct partial_symtab *hpread_start_psymtab
-  (struct objfile *, char *, CORE_ADDR, int,
-   struct partial_symbol **, struct partial_symbol **);
-
-static struct partial_symtab *hpread_end_psymtab
-  (struct partial_symtab *, char **, int, int, CORE_ADDR,
-   struct partial_symtab **, int);
-
-/* End of forward routine declarations */
-
-#ifdef USE_PXDB
-
-/* NOTE use of system files!  May not be portable. */
-
-#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
-#define PXDB_BSD  "/usr/bin/pxdb"
-
-#include <stdlib.h>
-#include "gdb_string.h"
-
-/* check for the existence of a file, given its full pathname */
-int
-file_exists (char *filename)
-{
-  if (filename)
-    return (access (filename, F_OK) == 0);
-  return 0;
-}
-
-
-/* Translate from the "hp_language" enumeration in hp-symtab.h
-   used in the debug info to gdb's generic enumeration in defs.h. */
-static enum language
-trans_lang (enum hp_language in_lang)
-{
-  if (in_lang == HP_LANGUAGE_C)
-    return language_c;
-
-  else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
-    return language_cplus;
-
-  else if (in_lang == HP_LANGUAGE_FORTRAN)
-    return language_fortran;
-
-  else
-    return language_unknown;
-}
-
-static char main_string[] = "main";
-\f
-/* Call PXDB to process our file.
-
-   Approach copied from DDE's "dbgk_run_pxdb".  Note: we
-   don't check for BSD location of pxdb, nor for existence
-   of pxdb itself, etc.
-
-   NOTE: uses system function and string functions directly.
-
-   Return value: 1 if ok, 0 if not */
-int
-hpread_call_pxdb (const char *file_name)
-{
-  char *p;
-  int status;
-  int retval;
-
-  if (file_exists (PXDB_SVR4))
-    {
-      p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
-      strcpy (p, PXDB_SVR4);
-      strcat (p, " ");
-      strcat (p, file_name);
-
-      warning ("File not processed by pxdb--about to process now.\n");
-      status = system (p);
-
-      retval = (status == 0);
-    }
-  else
-    {
-      warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
-
-      retval = 0;
-    }
-  return retval;
-}                              /* hpread_call_pxdb */
-\f
-
-/* Return 1 if the file turns out to need pre-processing
-   by PXDB, and we have thus called PXDB to do this processing
-   and the file therefore needs to be re-loaded.  Otherwise
-   return 0. */
-int
-hpread_pxdb_needed (bfd *sym_bfd)
-{
-  asection *pinfo_section, *debug_section, *header_section;
-  unsigned int do_pxdb;
-  char *buf;
-  bfd_size_type header_section_size;
-
-  unsigned long tmp;
-  unsigned int pxdbed;
-
-  header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
-  if (!header_section)
-    {
-      return 0;                        /* No header at all, can't recover... */
-    }
-
-  debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
-  pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
-
-  if (pinfo_section && !debug_section)
-    {
-      /* Debug info with DOC, has different header format. 
-         this only happens if the file was pxdbed and compiled optimized
-         otherwise the PINFO section is not there. */
-      header_section_size = bfd_section_size (objfile->obfd, header_section);
-
-      if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
-       {
-         buf = alloca (sizeof (DOC_info_PXDB_header));
-
-         if (!bfd_get_section_contents (sym_bfd,
-                                        header_section,
-                                        buf, 0,
-                                        header_section_size))
-           error ("bfd_get_section_contents\n");
-
-         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
-         pxdbed = (tmp >> 31) & 0x1;
-
-         if (!pxdbed)
-           error ("file debug header info invalid\n");
-         do_pxdb = 0;
-       }
-
-      else
-       error ("invalid $HEADER$ size in executable \n");
-    }
-
-  else
-    {
-
-      /* this can be three different cases:
-         1. pxdbed and not doc
-         - DEBUG and HEADER sections are there
-         - header is PXDB_header type
-         - pxdbed flag is set to 1
-
-         2. not pxdbed and doc
-         - DEBUG and HEADER  sections are there
-         - header is DOC_info_header type
-         - pxdbed flag is set to 0
-
-         3. not pxdbed and not doc
-         - DEBUG and HEADER sections are there
-         - header is XDB_header type
-         - pxdbed flag is set to 0
-
-         NOTE: the pxdbed flag is meaningful also in the not
-         already pxdb processed version of the header,
-         because in case on non-already processed by pxdb files
-         that same bit in the header would be always zero.
-         Why? Because the bit is the leftmost bit of a word
-         which contains a 'length' which is always a positive value
-         so that bit is never set to 1 (otherwise it would be negative)
-
-         Given the above, we have two choices : either we ignore the
-         size of the header itself and just look at the pxdbed field,
-         or we check the size and then we (for safety and paranoia related
-         issues) check the bit.
-         The first solution is used by DDE, the second by PXDB itself.
-         I am using the second one here, because I already wrote it,
-         and it is the end of a long day.
-         Also, using the first approach would still involve size issues
-         because we need to read in the contents of the header section, and
-         give the correct amount of stuff we want to read to the
-         get_bfd_section_contents function.  */
-
-      /* decide which case depending on the size of the header section.
-         The size is as defined in hp-symtab.h  */
-
-      header_section_size = bfd_section_size (objfile->obfd, header_section);
-
-      if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */
-       {
-
-         buf = alloca (sizeof (PXDB_header));
-         if (!bfd_get_section_contents (sym_bfd,
-                                        header_section,
-                                        buf, 0,
-                                        header_section_size))
-           error ("bfd_get_section_contents\n");
-
-         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
-         pxdbed = (tmp >> 31) & 0x1;
-
-         if (pxdbed)
-           do_pxdb = 0;
-         else
-           error ("file debug header invalid\n");
-       }
-      else                     /*not pxdbed and doc OR not pxdbed and non doc */
-       do_pxdb = 1;
-    }
-
-  if (do_pxdb)
-    {
-      return 1;
-    }
-  else
-    {
-      return 0;
-    }
-}                              /* hpread_pxdb_needed */
-
-#endif
-
-/* Check whether the file needs to be preprocessed by pxdb. 
-   If so, call pxdb. */
-
-void
-do_pxdb (bfd *sym_bfd)
-{
-  /* The following code is HP-specific.  The "right" way of
-     doing this is unknown, but we bet would involve a target-
-     specific pre-file-load check using a generic mechanism. */
-
-  /* This code will not be executed if the file is not in SOM
-     format (i.e. if compiled with gcc) */
-  if (hpread_pxdb_needed (sym_bfd))
-    {
-      /*This file has not been pre-processed. Preprocess now */
-
-      if (hpread_call_pxdb (sym_bfd->filename))
-       {
-         /* The call above has changed the on-disk file, 
-            we can close the file anyway, because the
-            symbols will be reread in when the target is run */
-         bfd_close (sym_bfd);
-       }
-    }
-}
-\f
-
-
-#ifdef QUICK_LOOK_UP
-
-/* Code to handle quick lookup-tables follows. */
-
-
-/* Some useful macros */
-#define VALID_FILE(i)   ((i) < pxdb_header_p->fd_entries)
-#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
-#define VALID_PROC(i)   ((i) < pxdb_header_p->pd_entries)
-#define VALID_CLASS(i)  ((i) < pxdb_header_p->cd_entries)
-
-#define FILE_START(i)    (qFD[i].adrStart)
-#define MODULE_START(i) (qMD[i].adrStart)
-#define PROC_START(i)    (qPD[i].adrStart)
-
-#define FILE_END(i)   (qFD[i].adrEnd)
-#define MODULE_END(i) (qMD[i].adrEnd)
-#define PROC_END(i)   (qPD[i].adrEnd)
-
-#define FILE_ISYM(i)   (qFD[i].isym)
-#define MODULE_ISYM(i) (qMD[i].isym)
-#define PROC_ISYM(i)   (qPD[i].isym)
-
-#define VALID_CURR_FILE    (curr_fd < pxdb_header_p->fd_entries)
-#define VALID_CURR_MODULE  (curr_md < pxdb_header_p->md_entries)
-#define VALID_CURR_PROC    (curr_pd < pxdb_header_p->pd_entries)
-#define VALID_CURR_CLASS   (curr_cd < pxdb_header_p->cd_entries)
-
-#define CURR_FILE_START     (qFD[curr_fd].adrStart)
-#define CURR_MODULE_START   (qMD[curr_md].adrStart)
-#define CURR_PROC_START     (qPD[curr_pd].adrStart)
-
-#define CURR_FILE_END    (qFD[curr_fd].adrEnd)
-#define CURR_MODULE_END  (qMD[curr_md].adrEnd)
-#define CURR_PROC_END    (qPD[curr_pd].adrEnd)
-
-#define CURR_FILE_ISYM    (qFD[curr_fd].isym)
-#define CURR_MODULE_ISYM  (qMD[curr_md].isym)
-#define CURR_PROC_ISYM    (qPD[curr_pd].isym)
-
-#define TELL_OBJFILE                                      \
-            do {                                          \
-               if( !told_objfile ) {                      \
-                   told_objfile = 1;                      \
-                   warning ("\nIn object file \"%s\":\n", \
-                            objfile->name);               \
-               }                                          \
-            } while (0)
-\f
-
-
-/* Keeping track of the start/end symbol table (LNTT) indices of
-   psymtabs created so far */
-
-typedef struct
-{
-  int start;
-  int end;
-}
-pst_syms_struct;
-
-static pst_syms_struct *pst_syms_array = 0;
-
-static pst_syms_count = 0;
-static pst_syms_size = 0;
-
-/* used by the TELL_OBJFILE macro */
-static boolean told_objfile = 0;
-
-/* Set up psymtab symbol index stuff */
-static void
-init_pst_syms (void)
-{
-  pst_syms_count = 0;
-  pst_syms_size = 20;
-  pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
-}
-
-/* Clean up psymtab symbol index stuff */
-static void
-clear_pst_syms (void)
-{
-  pst_syms_count = 0;
-  pst_syms_size = 0;
-  xfree (pst_syms_array);
-  pst_syms_array = 0;
-}
-
-/* Add information about latest psymtab to symbol index table */
-static void
-record_pst_syms (int start_sym, int end_sym)
-{
-  if (++pst_syms_count > pst_syms_size)
-    {
-      pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
-                             2 * pst_syms_size * sizeof (pst_syms_struct));
-      pst_syms_size *= 2;
-    }
-  pst_syms_array[pst_syms_count - 1].start = start_sym;
-  pst_syms_array[pst_syms_count - 1].end = end_sym;
-}
-
-/* Find a suitable symbol table index which can serve as the upper
-   bound of a psymtab that starts at INDEX
-
-   This scans backwards in the psymtab symbol index table to find a
-   "hole" in which the given index can fit.  This is a heuristic!!
-   We don't search the entire table to check for multiple holes,
-   we don't care about overlaps, etc. 
-
-   Return 0 => not found */
-static int
-find_next_pst_start (int index)
-{
-  int i;
-
-  for (i = pst_syms_count - 1; i >= 0; i--)
-    if (pst_syms_array[i].end <= index)
-      return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
-
-  if (pst_syms_array[0].start > index)
-    return pst_syms_array[0].start - 1;
-
-  return 0;
-}
-\f
-
-
-/* Utility functions to find the ending symbol index for a psymtab */
-
-/* Find the next file entry that begins beyond INDEX, and return
-   its starting symbol index - 1.
-   QFD is the file table, CURR_FD is the file entry from where to start,
-   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
-
-   Return 0 => not found */
-static int
-find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd,
-                    PXDB_header_ptr pxdb_header_p)
-{
-  while (VALID_CURR_FILE)
-    {
-      if (CURR_FILE_ISYM >= index)
-       return CURR_FILE_ISYM - 1;
-      curr_fd++;
-    }
-  return 0;
-}
-
-/* Find the next procedure entry that begins beyond INDEX, and return
-   its starting symbol index - 1.
-   QPD is the procedure table, CURR_PD is the proc entry from where to start,
-   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
-
-   Return 0 => not found */
-static int
-find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd,
-                    PXDB_header_ptr pxdb_header_p)
-{
-  while (VALID_CURR_PROC)
-    {
-      if (CURR_PROC_ISYM >= index)
-       return CURR_PROC_ISYM - 1;
-      curr_pd++;
-    }
-  return 0;
-}
-
-/* Find the next module entry that begins beyond INDEX, and return
-   its starting symbol index - 1.
-   QMD is the module table, CURR_MD is the modue entry from where to start,
-   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
-
-   Return 0 => not found */
-static int
-find_next_module_isym (int index, quick_module_entry *qMD, int curr_md,
-                      PXDB_header_ptr pxdb_header_p)
-{
-  while (VALID_CURR_MODULE)
-    {
-      if (CURR_MODULE_ISYM >= index)
-       return CURR_MODULE_ISYM - 1;
-      curr_md++;
-    }
-  return 0;
-}
-
-/* Scan and record partial symbols for all functions starting from index
-   pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR.
-   Other parameters are explained in comments below. */
-
-/* This used to be inline in hpread_quick_traverse, but now that we do
-   essentially the same thing for two different cases (modules and
-   module-less files), it's better organized in a separate routine,
-   although it does take lots of arguments.  pai/1997-10-08
-   
-   CURR_PD_P is the pointer to the current proc index. QPD is the
-   procedure quick lookup table.  MAX_PROCS is the number of entries
-   in the proc. table.  START_ADR is the beginning of the code range
-   for the current psymtab.  end_adr is the end of the code range for
-   the current psymtab.  PST is the current psymtab.  VT_bits is
-   a pointer to the strings table of SOM debug space.  OBJFILE is
-   the current object file. */
-
-static int
-scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs,
-           CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst,
-           char *vt_bits, struct objfile *objfile)
-{
-  union dnttentry *dn_bufp;
-  int symbol_count = 0;                /* Total number of symbols in this psymtab */
-  int curr_pd = *curr_pd_p;    /* Convenience variable -- avoid dereferencing pointer all the time */
-
-#ifdef DUMPING
-  /* Turn this on for lots of debugging information in this routine */
-  static int dumping = 0;
-#endif
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
-    }
-#endif
-
-  while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
-    {
-
-      char *rtn_name;          /* mangled name */
-      char *rtn_dem_name;      /* qualified demangled name */
-      char *class_name;
-      int class;
-
-      if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
-         vt_bits[(long) qPD[curr_pd].sbAlias])         /* not a null string */
-       {
-         /* Get mangled name for the procedure, and demangle it */
-         rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
-         rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
-       }
-      else
-       {
-         rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
-         rtn_dem_name = NULL;
-       }
-
-      /* Hack to get around HP C/C++ compilers' insistence on providing
-         "_MAIN_" as an alternate name for "main" */
-      if ((strcmp (rtn_name, "_MAIN_") == 0) &&
-         (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
-       rtn_dem_name = rtn_name = main_string;
-
-#ifdef DUMPING
-      if (dumping)
-       {
-         printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
-       }
-#endif
-
-      /* Check for module-spanning routines. */
-      if (CURR_PROC_END > end_adr)
-       {
-         TELL_OBJFILE;
-         warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
-       }
-
-      /* Add this routine symbol to the list in the objfile. 
-         Unfortunately we have to go to the LNTT to determine the
-         correct list to put it on. An alternative (which the
-         code used to do) would be to not check and always throw
-         it on the "static" list. But if we go that route, then
-         symbol_lookup() needs to be tweaked a bit to account
-         for the fact that the function might not be found on
-         the correct list in the psymtab. - RT */
-      dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
-      if (dn_bufp->dfunc.global)
-       add_psymbol_with_dem_name_to_list (rtn_name,
-                                          strlen (rtn_name),
-                                          rtn_dem_name,
-                                          strlen (rtn_dem_name),
-                                          VAR_NAMESPACE,
-                                          LOC_BLOCK,   /* "I am a routine"        */
-                                          &objfile->global_psymbols,
-                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
-                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
-                                          0,   /* core addr?? */
-                     trans_lang ((enum hp_language) qPD[curr_pd].language),
-                                          objfile);
-      else
-       add_psymbol_with_dem_name_to_list (rtn_name,
-                                          strlen (rtn_name),
-                                          rtn_dem_name,
-                                          strlen (rtn_dem_name),
-                                          VAR_NAMESPACE,
-                                          LOC_BLOCK,   /* "I am a routine"        */
-                                          &objfile->static_psymbols,
-                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
-                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
-                                          0,   /* core addr?? */
-                     trans_lang ((enum hp_language) qPD[curr_pd].language),
-                                          objfile);
-
-      symbol_count++;
-      *curr_pd_p = ++curr_pd;  /* bump up count & reflect in caller */
-    }                          /* loop over procedures */
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      if (symbol_count == 0)
-       printf ("Scan_procs: no symbols found!\n");
-    }
-#endif
-
-  return symbol_count;
-}
-
-
-/* Traverse the quick look-up tables, building a set of psymtabs.
-
-   This constructs a psymtab for modules and files in the quick lookup
-   tables.
-
-   Mostly, modules correspond to compilation units, so we try to
-   create psymtabs that correspond to modules; however, in some cases
-   a file can result in a compiled object which does not have a module
-   entry for it, so in such cases we create a psymtab for the file.  */
-
-int
-hpread_quick_traverse (struct objfile *objfile, char *gntt_bits,
-                      char *vt_bits, PXDB_header_ptr pxdb_header_p)
-{
-  struct partial_symtab *pst;
-
-  char *addr;
-
-  quick_procedure_entry *qPD;
-  quick_file_entry *qFD;
-  quick_module_entry *qMD;
-  quick_class_entry *qCD;
-
-  int idx;
-  int i;
-  CORE_ADDR start_adr;         /* current psymtab's starting code addr   */
-  CORE_ADDR end_adr;           /* current psymtab's ending code addr     */
-  CORE_ADDR next_mod_adr;      /* next module's starting code addr    */
-  int curr_pd;                 /* current procedure */
-  int curr_fd;                 /* current file      */
-  int curr_md;                 /* current module    */
-  int start_sym;               /* current psymtab's starting symbol index */
-  int end_sym;                 /* current psymtab's ending symbol index   */
-  int max_LNTT_sym_index;
-  int syms_in_pst;
-  B_TYPE *class_entered;
-
-  struct partial_symbol **global_syms; /* We'll be filling in the "global"   */
-  struct partial_symbol **static_syms; /* and "static" tables in the objfile
-                                          as we go, so we need a pair of     
-                                          current pointers. */
-
-#ifdef DUMPING
-  /* Turn this on for lots of debugging information in this routine.
-     You get a blow-by-blow account of quick lookup table reading */
-  static int dumping = 0;
-#endif
-
-  pst = (struct partial_symtab *) 0;
-
-  /* Clear out some globals */
-  init_pst_syms ();
-  told_objfile = 0;
-
-  /* Demangling style -- if EDG style already set, don't change it,
-     as HP style causes some problems with the KAI EDG compiler */
-  if (current_demangling_style != edg_demangling)
-    {
-      /* Otherwise, ensure that we are using HP style demangling */
-      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
-    }
-
-  /* First we need to find the starting points of the quick
-     look-up tables in the GNTT. */
-
-  addr = gntt_bits;
-
-  qPD = (quick_procedure_entry_ptr) addr;
-  addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("\n Printing routines as we see them\n");
-      for (i = 0; VALID_PROC (i); i++)
-       {
-         idx = (long) qPD[i].sbProc;
-         printf ("%s %x..%x\n", &vt_bits[idx],
-                 (int) PROC_START (i),
-                 (int) PROC_END (i));
-       }
-    }
-#endif
-
-  qFD = (quick_file_entry_ptr) addr;
-  addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("\n Printing files as we see them\n");
-      for (i = 0; VALID_FILE (i); i++)
-       {
-         idx = (long) qFD[i].sbFile;
-         printf ("%s %x..%x\n", &vt_bits[idx],
-                 (int) FILE_START (i),
-                 (int) FILE_END (i));
-       }
-    }
-#endif
-
-  qMD = (quick_module_entry_ptr) addr;
-  addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("\n Printing modules as we see them\n");
-      for (i = 0; i < pxdb_header_p->md_entries; i++)
-       {
-         idx = (long) qMD[i].sbMod;
-         printf ("%s\n", &vt_bits[idx]);
-       }
-    }
-#endif
-
-  qCD = (quick_class_entry_ptr) addr;
-  addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("\n Printing classes as we see them\n");
-      for (i = 0; VALID_CLASS (i); i++)
-       {
-         idx = (long) qCD[i].sbClass;
-         printf ("%s\n", &vt_bits[idx]);
-       }
-
-      printf ("\n Done with dump, on to build!\n");
-    }
-#endif
-
-  /* We need this index only while hp-symtab-read.c expects
-     a byte offset to the end of the LNTT entries for a given
-     psymtab.  Thus the need for it should go away someday.
-
-     When it goes away, then we won't have any need to load the
-     LNTT from the objfile at psymtab-time, and start-up will be
-     faster.  To make that work, we'll need some way to create
-     a null pst for the "globals" pseudo-module. */
-  max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
-
-  /* Scan the module descriptors and make a psymtab for each.
-
-     We know the MDs, FDs and the PDs are in order by starting
-     address.  We use that fact to traverse all three arrays in
-     parallel, knowing when the next PD is in a new file
-     and we need to create a new psymtab. */
-  curr_pd = 0;                 /* Current procedure entry */
-  curr_fd = 0;                 /* Current file entry */
-  curr_md = 0;                 /* Current module entry */
-
-  start_adr = 0;               /* Current psymtab code range */
-  end_adr = 0;
-
-  start_sym = 0;               /* Current psymtab symbol range */
-  end_sym = 0;
-
-  syms_in_pst = 0;             /* Symbol count for psymtab */
-
-  /* Psts actually just have pointers into the objfile's
-     symbol table, not their own symbol tables. */
-  global_syms = objfile->global_psymbols.list;
-  static_syms = objfile->static_psymbols.list;
-
-
-  /* First skip over pseudo-entries with address 0.  These represent inlined
-     routines and abstract (uninstantiated) template routines.
-     FIXME: These should be read in and available -- even if we can't set
-     breakpoints, etc., there's some information that can be presented
-     to the user. pai/1997-10-08  */
-
-  while (VALID_CURR_PROC && (CURR_PROC_START == 0))
-    curr_pd++;
-
-  /* Loop over files, modules, and procedures in code address order. Each
-     time we enter an iteration of this loop, curr_pd points to the first
-     unprocessed procedure, curr_fd points to the first unprocessed file, and
-     curr_md to the first unprocessed module.  Each iteration of this loop
-     updates these as required -- any or all of them may be bumpd up
-     each time around.  When we exit this loop, we are done with all files
-     and modules in the tables -- there may still be some procedures, however.
-
-     Note: This code used to loop only over module entries, under the assumption
-     that files can occur via inclusions and are thus unreliable, while a
-     compiled object always corresponds to a module.  With CTTI in the HP aCC
-     compiler, it turns out that compiled objects may have only files and no
-     modules; so we have to loop over files and modules, creating psymtabs for
-     either as appropriate.  Unfortunately there are some problems (notably:
-     1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers
-     to the ending symbol indices of a module or a file) which make it quite hard
-     to do this correctly.  Currently it uses a bunch of heuristics to start and
-     end psymtabs; they seem to work well with most objects generated by aCC, but
-     who knows when that will change...   */
-
-  while (VALID_CURR_FILE || VALID_CURR_MODULE)
-    {
-
-      char *mod_name_string;
-      char *full_name_string;
-
-      /* First check for modules like "version.c", which have no code
-         in them but still have qMD entries.  They also have no qFD or
-         qPD entries.  Their start address is -1 and their end address
-         is 0.  */
-      if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
-       {
-
-         mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
-
-#ifdef DUMPING
-         if (dumping)
-           printf ("Module with data only %s\n", mod_name_string);
-#endif
-
-         /* We'll skip the rest (it makes error-checking easier), and
-            just make an empty pst.  Right now empty psts are not put
-            in the pst chain, so all this is for naught, but later it
-            might help.  */
-
-         pst = hpread_start_psymtab (objfile,
-                                     mod_name_string,
-                                     CURR_MODULE_START,        /* Low text address: bogus! */
-                      (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
-         /* ldsymoff */
-                                     global_syms,
-                                     static_syms);
-
-         pst = hpread_end_psymtab (pst,
-                                   NULL,       /* psymtab_include_list */
-                                   0,  /* includes_used        */
-                                 end_sym * sizeof (struct dntt_type_block),
-         /* byte index in LNTT of end 
-            = capping symbol offset  
-            = LDSYMOFF of nextfile */
-                                   0,  /* text high            */
-                                   NULL,       /* dependency_list      */
-                                   0);         /* dependencies_used    */
-
-         global_syms = objfile->global_psymbols.next;
-         static_syms = objfile->static_psymbols.next;
-
-         curr_md++;
-       }
-      else if (VALID_CURR_MODULE &&
-              ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
-               (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
-       {
-         TELL_OBJFILE;
-         warning ("Module \"%s\" [0x%s] has non-standard addresses.  It starts at 0x%s, ends at 0x%s, and will be skipped.",
-                  mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr));
-         /* On to next module */
-         curr_md++;
-       }
-      else
-       {
-         /* First check if we are looking at a file with code in it
-            that does not overlap the current module's code range */
-
-         if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
-           {
-
-             /* Looking at file not corresponding to any module,
-                create a psymtab for it */
-             full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
-             start_adr = CURR_FILE_START;
-             end_adr = CURR_FILE_END;
-             start_sym = CURR_FILE_ISYM;
-
-             /* Check if there are any procedures not handled until now, that
-                begin before the start address of this file, and if so, adjust
-                this module's start address to include them.  This handles routines that
-                are in between file or module ranges for some reason (probably
-                indicates a compiler bug */
-
-             if (CURR_PROC_START < start_adr)
-               {
-                 TELL_OBJFILE;
-                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
-                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
-                 start_adr = CURR_PROC_START;
-                 if (CURR_PROC_ISYM < start_sym)
-                   start_sym = CURR_PROC_ISYM;
-               }
-
-             /* Sometimes (compiler bug -- COBOL) the module end address is higher
-                than the start address of the next module, so check for that and
-                adjust accordingly */
-
-             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
-               {
-                 TELL_OBJFILE;
-                 warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
-                          full_name_string, curr_fd);
-                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
-               }
-             if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
-               {
-                 TELL_OBJFILE;
-                 warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
-                          full_name_string, curr_fd);
-                 end_adr = CURR_MODULE_START - 1;      /* Is -4 (or -8 for 64-bit) better? */
-               }
-
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("Make new psymtab for file %s (%x to %x).\n",
-                         full_name_string, start_adr, end_adr);
-               }
-#endif
-             /* Create the basic psymtab, connecting it in the list
-                for this objfile and pointing its symbol entries
-                to the current end of the symbol areas in the objfile.
-
-                The "ldsymoff" parameter is the byte offset in the LNTT
-                of the first symbol in this file.  Some day we should
-                turn this into an index (fix in hp-symtab-read.c as well).
-                And it's not even the right byte offset, as we're using
-                the size of a union! FIXME!  */
-             pst = hpread_start_psymtab (objfile,
-                                         full_name_string,
-                                         start_adr,    /* Low text address */
-                             (start_sym * sizeof (struct dntt_type_block)),
-             /* ldsymoff */
-                                         global_syms,
-                                         static_syms);
-
-             /* Set up to only enter each class referenced in this module once.  */
-             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
-             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
-
-             /* Scan the procedure descriptors for procedures in the current
-                file, based on the starting addresses. */
-
-             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
-                                       start_adr, end_adr, pst, vt_bits, objfile);
-
-             /* Get ending symbol offset */
-
-             end_sym = 0;
-             /* First check for starting index before previous psymtab */
-             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
-               {
-                 end_sym = find_next_pst_start (start_sym);
-               }
-             /* Look for next start index of a file or module, or procedure */
-             if (!end_sym)
-               {
-                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
-                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
-                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
-
-                 if (next_file_isym && next_module_isym)
-                   {
-                     /* pick lower of next file or module start index */
-                     end_sym = min (next_file_isym, next_module_isym);
-                   }
-                 else
-                   {
-                     /* one of them is zero, pick the other */
-                     end_sym = max (next_file_isym, next_module_isym);
-                   }
-
-                 /* As a precaution, check next procedure index too */
-                 if (!end_sym)
-                   end_sym = next_proc_isym;
-                 else
-                   end_sym = min (end_sym, next_proc_isym);
-               }
-
-             /* Couldn't find procedure, file, or module, use globals as default */
-             if (!end_sym)
-               end_sym = pxdb_header_p->globals;
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
-               }
-#endif
-
-             pst = hpread_end_psymtab (pst,
-                                       NULL,   /* psymtab_include_list */
-                                       0,      /* includes_used        */
-                                 end_sym * sizeof (struct dntt_type_block),
-             /* byte index in LNTT of end 
-                = capping symbol offset   
-                = LDSYMOFF of nextfile */
-                                       end_adr,        /* text high */
-                                       NULL,   /* dependency_list */
-                                       0);     /* dependencies_used */
-
-             record_pst_syms (start_sym, end_sym);
-
-             if (NULL == pst)
-               warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
-                         full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
-               }
-#endif
-             /* Prepare for the next psymtab. */
-             global_syms = objfile->global_psymbols.next;
-             static_syms = objfile->static_psymbols.next;
-             xfree (class_entered);
-
-             curr_fd++;
-           }                   /* Psymtab for file */
-         else
-           {
-             /* We have a module for which we create a psymtab */
-
-             mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
-
-             /* We will include the code ranges of any files that happen to
-                overlap with this module */
-
-             /* So, first pick the lower of the file's and module's start addresses */
-             start_adr = CURR_MODULE_START;
-             if (VALID_CURR_FILE)
-               {
-                 if (CURR_FILE_START < CURR_MODULE_START)
-                   {
-                     TELL_OBJFILE;
-                     warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
-                              &vt_bits[(long) qFD[curr_fd].sbFile],
-                              curr_fd, mod_name_string);
-
-                     start_adr = CURR_FILE_START;
-                   }
-               }
-
-             /* Also pick the lower of the file's and the module's start symbol indices */
-             start_sym = CURR_MODULE_ISYM;
-             if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
-               start_sym = CURR_FILE_ISYM;
-
-             /* For the end address, we scan through the files till we find one
-                that overlaps the current module but ends beyond it; if no such file exists we
-                simply use the module's start address.  
-                (Note, if file entries themselves overlap
-                we take the longest overlapping extension beyond the end of the module...)
-                We assume that modules never overlap. */
-
-             end_adr = CURR_MODULE_END;
-
-             if (VALID_CURR_FILE)
-               {
-                 while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
-                   {
-
-#ifdef DUMPING
-                     if (dumping)
-                       printf ("Maybe skipping file %s which overlaps with module %s\n",
-                               &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
-#endif
-                     if (CURR_FILE_END > end_adr)
-                       {
-                         TELL_OBJFILE;
-                         warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
-                                  &vt_bits[(long) qFD[curr_fd].sbFile],
-                                  curr_fd, mod_name_string);
-                         end_adr = CURR_FILE_END;
-                       }
-                     curr_fd++;
-                   }
-                 curr_fd--;    /* back up after going too far */
-               }
-
-             /* Sometimes (compiler bug -- COBOL) the module end address is higher
-                than the start address of the next module, so check for that and
-                adjust accordingly */
-
-             if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
-               {
-                 TELL_OBJFILE;
-                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
-                          mod_name_string, curr_md);
-                 end_adr = MODULE_START (curr_md + 1) - 1;     /* Is -4 (or -8 for 64-bit) better? */
-               }
-             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
-               {
-                 TELL_OBJFILE;
-                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
-                          mod_name_string, curr_md);
-                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
-               }
-
-             /* Use one file to get the full name for the module.  This
-                situation can arise if there is executable code in a #include
-                file.  Each file with code in it gets a qFD.  Files which don't
-                contribute code don't get a qFD, even if they include files
-                which do, e.g.: 
-
-                body.c:                    rtn.h:
-                int x;                     int main() {
-                #include "rtn.h"               return x;
-                }
-
-                There will a qFD for "rtn.h",and a qMD for "body.c",
-                but no qMD for "rtn.h" or qFD for "body.c"!
-
-                We pick the name of the last file to overlap with this
-                module.  C convention is to put include files first.  In a
-                perfect world, we could check names and use the file whose full
-                path name ends with the module name. */
-
-             if (VALID_CURR_FILE)
-               full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
-             else
-               full_name_string = mod_name_string;
-
-             /* Check if there are any procedures not handled until now, that
-                begin before the start address we have now, and if so, adjust
-                this psymtab's start address to include them.  This handles routines that
-                are in between file or module ranges for some reason (probably
-                indicates a compiler bug */
-
-             if (CURR_PROC_START < start_adr)
-               {
-                 TELL_OBJFILE;
-                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
-                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
-                 start_adr = CURR_PROC_START;
-                 if (CURR_PROC_ISYM < start_sym)
-                   start_sym = CURR_PROC_ISYM;
-               }
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
-                    mod_name_string, start_adr, end_adr, full_name_string);
-               }
-#endif
-             /* Create the basic psymtab, connecting it in the list
-                for this objfile and pointing its symbol entries
-                to the current end of the symbol areas in the objfile.
-
-                The "ldsymoff" parameter is the byte offset in the LNTT
-                of the first symbol in this file.  Some day we should
-                turn this into an index (fix in hp-symtab-read.c as well).
-                And it's not even the right byte offset, as we're using
-                the size of a union! FIXME!  */
-             pst = hpread_start_psymtab (objfile,
-                                         full_name_string,
-                                         start_adr,    /* Low text address */
-                             (start_sym * sizeof (struct dntt_type_block)),
-             /* ldsymoff */
-                                         global_syms,
-                                         static_syms);
-
-             /* Set up to only enter each class referenced in this module once.  */
-             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
-             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
-
-             /* Scan the procedure descriptors for procedures in the current
-                module, based on the starting addresses. */
-
-             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
-                                       start_adr, end_adr, pst, vt_bits, objfile);
-
-             /* Get ending symbol offset */
-
-             end_sym = 0;
-             /* First check for starting index before previous psymtab */
-             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
-               {
-                 end_sym = find_next_pst_start (start_sym);
-               }
-             /* Look for next start index of a file or module, or procedure */
-             if (!end_sym)
-               {
-                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
-                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
-                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
-
-                 if (next_file_isym && next_module_isym)
-                   {
-                     /* pick lower of next file or module start index */
-                     end_sym = min (next_file_isym, next_module_isym);
-                   }
-                 else
-                   {
-                     /* one of them is zero, pick the other */
-                     end_sym = max (next_file_isym, next_module_isym);
-                   }
-
-                 /* As a precaution, check next procedure index too */
-                 if (!end_sym)
-                   end_sym = next_proc_isym;
-                 else
-                   end_sym = min (end_sym, next_proc_isym);
-               }
-
-             /* Couldn't find procedure, file, or module, use globals as default */
-             if (!end_sym)
-               end_sym = pxdb_header_p->globals;
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
-               }
-#endif
-
-             pst = hpread_end_psymtab (pst,
-                                       NULL,   /* psymtab_include_list */
-                                       0,      /* includes_used        */
-                                 end_sym * sizeof (struct dntt_type_block),
-             /* byte index in LNTT of end 
-                = capping symbol offset   
-                = LDSYMOFF of nextfile */
-                                       end_adr,        /* text high */
-                                       NULL,   /* dependency_list      */
-                                       0);     /* dependencies_used    */
-
-             record_pst_syms (start_sym, end_sym);
-
-             if (NULL == pst)
-               warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
-
-#ifdef DUMPING
-             if (dumping)
-               {
-                 printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
-                         mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
-               }
-#endif
-
-             /* Prepare for the next psymtab. */
-             global_syms = objfile->global_psymbols.next;
-             static_syms = objfile->static_psymbols.next;
-             xfree (class_entered);
-
-             curr_md++;
-             curr_fd++;
-           }                   /* psymtab for module */
-       }                       /* psymtab for non-bogus file or module */
-    }                          /* End of while loop over all files & modules */
-
-  /* There may be some routines after all files and modules -- these will get
-     inserted in a separate new module of their own */
-  if (VALID_CURR_PROC)
-    {
-      start_adr = CURR_PROC_START;
-      end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
-      TELL_OBJFILE;
-      warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
-#ifdef DUMPING
-      if (dumping)
-       {
-         printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
-                 curr_pd, start_adr, end_adr);
-       }
-#endif
-      pst = hpread_start_psymtab (objfile,
-                                 "orphans",
-                                 start_adr,    /* Low text address */
-                        (CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
-      /* ldsymoff */
-                                 global_syms,
-                                 static_syms);
-
-      scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
-                 start_adr, end_adr, pst, vt_bits, objfile);
-
-      pst = hpread_end_psymtab (pst,
-                               NULL,   /* psymtab_include_list */
-                               0,      /* includes_used */
-                  pxdb_header_p->globals * sizeof (struct dntt_type_block),
-      /* byte index in LNTT of end 
-         = capping symbol offset   
-         = LDSYMOFF of nextfile */
-                               end_adr,        /* text high  */
-                               NULL,   /* dependency_list */
-                               0);     /* dependencies_used */
-    }
-
-
-#ifdef NEVER_NEVER
-  /* Now build psts for non-module things (in the tail of
-     the LNTT, after the last END MODULE entry).
-
-     If null psts were kept on the chain, this would be
-     a solution.  FIXME */
-  pst = hpread_start_psymtab (objfile,
-                             "globals",
-                             0,
-                             (pxdb_header_p->globals
-                              * sizeof (struct dntt_type_block)),
-                             objfile->global_psymbols.next,
-                             objfile->static_psymbols.next);
-  hpread_end_psymtab (pst,
-                     NULL, 0,
-                     (max_LNTT_sym_index * sizeof (struct dntt_type_block)),
-                     0,
-                     NULL, 0);
-#endif
-
-  clear_pst_syms ();
-
-  return 1;
-
-}                              /* End of hpread_quick_traverse. */
-\f
-
-/* Get appropriate header, based on pxdb type. 
-   Return value: 1 if ok, 0 if not */
-int
-hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p)
-{
-  asection *pinfo_section, *debug_section, *header_section;
-
-#ifdef DUMPING
-  /* Turn on for debugging information */
-  static int dumping = 0;
-#endif
-
-  header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
-  if (!header_section)
-    {
-      /* We don't have either PINFO or DEBUG sections.  But
-         stuff like "libc.sl" has no debug info.  There's no
-         need to warn the user of this, as it may be ok. The
-         caller will figure it out and issue any needed
-         messages. */
-#ifdef DUMPING
-      if (dumping)
-       printf ("==No debug info at all for %s.\n", objfile->name);
-#endif
-
-      return 0;
-    }
-
-  /* We would like either a $DEBUG$ or $PINFO$ section.
-     Once we know which, we can understand the header
-     data (which we have defined to suit the more common
-     $DEBUG$ case). */
-  debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
-  pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
-  if (debug_section)
-    {
-      /* The expected case: normal pxdb header. */
-      bfd_get_section_contents (objfile->obfd, header_section,
-                               pxdb_header_p, 0, sizeof (PXDB_header));
-
-      if (!pxdb_header_p->pxdbed)
-       {
-         /* This shouldn't happen if we check in "symfile.c". */
-         return 0;
-       }                       /* DEBUG section */
-    }
-
-  else if (pinfo_section)
-    {
-      /* The DOC case; we need to translate this into a
-         regular header. */
-      DOC_info_PXDB_header doc_header;
-
-#ifdef DUMPING
-      if (dumping)
-       {
-         printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
-       }
-#endif
-
-      bfd_get_section_contents (objfile->obfd,
-                               header_section,
-                               &doc_header, 0,
-                               sizeof (DOC_info_PXDB_header));
-
-      if (!doc_header.pxdbed)
-       {
-         /* This shouldn't happen if we check in "symfile.c". */
-         warning ("File \"%s\" not processed by pxdb!", objfile->name);
-         return 0;
-       }
-
-      /* Copy relevent fields to standard header passed in. */
-      pxdb_header_p->pd_entries = doc_header.pd_entries;
-      pxdb_header_p->fd_entries = doc_header.fd_entries;
-      pxdb_header_p->md_entries = doc_header.md_entries;
-      pxdb_header_p->pxdbed = doc_header.pxdbed;
-      pxdb_header_p->bighdr = doc_header.bighdr;
-      pxdb_header_p->sa_header = doc_header.sa_header;
-      pxdb_header_p->inlined = doc_header.inlined;
-      pxdb_header_p->globals = doc_header.globals;
-      pxdb_header_p->time = doc_header.time;
-      pxdb_header_p->pg_entries = doc_header.pg_entries;
-      pxdb_header_p->functions = doc_header.functions;
-      pxdb_header_p->files = doc_header.files;
-      pxdb_header_p->cd_entries = doc_header.cd_entries;
-      pxdb_header_p->aa_entries = doc_header.aa_entries;
-      pxdb_header_p->oi_entries = doc_header.oi_entries;
-      pxdb_header_p->version = doc_header.version;
-    }                          /* PINFO section */
-
-  else
-    {
-#ifdef DUMPING
-      if (dumping)
-       printf ("==No debug info at all for %s.\n", objfile->name);
-#endif
-
-      return 0;
-
-    }
-
-  return 1;
-}                              /* End of hpread_get_header */
-#endif /* QUICK_LOOK_UP */
-\f
-
-/* Initialization for reading native HP C debug symbols from OBJFILE.
-
-   Its only purpose in life is to set up the symbol reader's private
-   per-objfile data structures, and read in the raw contents of the debug
-   sections (attaching pointers to the debug info into the private data
-   structures).
-
-   Since BFD doesn't know how to read debug symbols in a format-independent
-   way (and may never do so...), we have to do it ourselves.  Note we may
-   be called on a file without native HP C debugging symbols.
-
-   FIXME, there should be a cleaner peephole into the BFD environment
-   here. */
-void
-hpread_symfile_init (struct objfile *objfile)
-{
-  asection *vt_section, *slt_section, *lntt_section, *gntt_section;
-
-  /* Allocate struct to keep track of the symfile */
-  objfile->sym_private = (PTR)
-    xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
-  memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
-
-  /* We haven't read in any types yet.  */
-  TYPE_VECTOR (objfile) = 0;
-
-  /* Read in data from the $GNTT$ subspace.  */
-  gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
-  if (!gntt_section)
-    return;
-
-  GNTT (objfile)
-    = obstack_alloc (&objfile->symbol_obstack,
-                    bfd_section_size (objfile->obfd, gntt_section));
-
-  bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
-                        0, bfd_section_size (objfile->obfd, gntt_section));
-
-  GNTT_SYMCOUNT (objfile)
-    = bfd_section_size (objfile->obfd, gntt_section)
-    / sizeof (struct dntt_type_block);
-
-  /* Read in data from the $LNTT$ subspace.   Also keep track of the number
-     of LNTT symbols.
-
-     FIXME: this could be moved into the psymtab-to-symtab expansion
-     code, and save startup time.  At the moment this data is
-     still used, though.  We'd need a way to tell hp-symtab-read.c
-     whether or not to load the LNTT. */
-  lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
-  if (!lntt_section)
-    return;
-
-  LNTT (objfile)
-    = obstack_alloc (&objfile->symbol_obstack,
-                    bfd_section_size (objfile->obfd, lntt_section));
-
-  bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
-                        0, bfd_section_size (objfile->obfd, lntt_section));
-
-  LNTT_SYMCOUNT (objfile)
-    = bfd_section_size (objfile->obfd, lntt_section)
-    / sizeof (struct dntt_type_block);
-
-  /* Read in data from the $SLT$ subspace.  $SLT$ contains information
-     on source line numbers.  */
-  slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
-  if (!slt_section)
-    return;
-
-  SLT (objfile) =
-    obstack_alloc (&objfile->symbol_obstack,
-                  bfd_section_size (objfile->obfd, slt_section));
-
-  bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
-                         0, bfd_section_size (objfile->obfd, slt_section));
-
-  /* Read in data from the $VT$ subspace.  $VT$ contains things like
-     names and constants.  Keep track of the number of symbols in the VT.  */
-  vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
-  if (!vt_section)
-    return;
-
-  VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
-
-  VT (objfile) =
-    (char *) obstack_alloc (&objfile->symbol_obstack,
-                           VT_SIZE (objfile));
-
-  bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
-                           0, VT_SIZE (objfile));
-}
-
-/* Scan and build partial symbols for a symbol file.
-
-   The minimal symbol table (either SOM or HP a.out) has already been
-   read in; all we need to do is setup partial symbols based on the
-   native debugging information.
-
-   Note that the minimal table is produced by the linker, and has
-   only global routines in it; the psymtab is based on compiler-
-   generated debug information and has non-global
-   routines in it as well as files and class information.
-
-   We assume hpread_symfile_init has been called to initialize the
-   symbol reader's private data structures.
-
-   MAINLINE is true if we are reading the main symbol table (as
-   opposed to a shared lib or dynamically loaded file). */
-
-void
-hpread_build_psymtabs (struct objfile *objfile, int mainline)
-{
-
-#ifdef DUMPING
-  /* Turn this on to get debugging output. */
-  static int dumping = 0;
-#endif
-
-  char *namestring;
-  int past_first_source_file = 0;
-  struct cleanup *old_chain;
-
-  int hp_symnum, symcount, i;
-  int scan_start = 0;
-
-  union dnttentry *dn_bufp;
-  unsigned long valu;
-  char *p;
-  int texthigh = 0;
-  int have_name = 0;
-
-  /* Current partial symtab */
-  struct partial_symtab *pst;
-
-  /* List of current psymtab's include files */
-  char **psymtab_include_list;
-  int includes_allocated;
-  int includes_used;
-
-  /* Index within current psymtab dependency list */
-  struct partial_symtab **dependency_list;
-  int dependencies_used, dependencies_allocated;
-
-  /* Just in case the stabs reader left turds lying around.  */
-  free_pending_blocks ();
-  make_cleanup (really_free_pendings, 0);
-
-  pst = (struct partial_symtab *) 0;
-
-  /* We shouldn't use alloca, instead use malloc/free.  Doing so avoids
-     a number of problems with cross compilation and creating useless holes
-     in the stack when we have to allocate new entries.  FIXME.  */
-
-  includes_allocated = 30;
-  includes_used = 0;
-  psymtab_include_list = (char **) alloca (includes_allocated *
-                                          sizeof (char *));
-
-  dependencies_allocated = 30;
-  dependencies_used = 0;
-  dependency_list =
-    (struct partial_symtab **) alloca (dependencies_allocated *
-                                      sizeof (struct partial_symtab *));
-
-  old_chain = make_cleanup_free_objfile (objfile);
-
-  last_source_file = 0;
-
-#ifdef QUICK_LOOK_UP
-  {
-    /* Begin code for new-style loading of quick look-up tables. */
-
-    /* elz: this checks whether the file has beeen processed by pxdb.
-       If not we would like to try to read the psymbols in
-       anyway, but it turns out to be not so easy. So this could 
-       actually be commented out, but I leave it in, just in case
-       we decide to add support for non-pxdb-ed stuff in the future. */
-    PXDB_header pxdb_header;
-    int found_modules_in_program;
-
-    if (hpread_get_header (objfile, &pxdb_header))
-      {
-       /* Build a minimal table.  No types, no global variables,
-          no include files.... */
-#ifdef DUMPING
-       if (dumping)
-         printf ("\nNew method for %s\n", objfile->name);
-#endif
-
-       /* elz: quick_traverse returns true if it found
-          some modules in the main source file, other
-          than those in end.c
-          In C and C++, all the files have MODULES entries
-          in the LNTT, and the quick table traverse is all 
-          based on finding these MODULES entries. Without 
-          those it cannot work. 
-          It happens that F77 programs don't have MODULES
-          so the quick traverse gets confused. F90 programs
-          have modules, and the quick method still works.
-          So, if modules (other than those in end.c) are
-          not found we give up on the quick table stuff, 
-          and fall back on the slower method  */
-       found_modules_in_program = hpread_quick_traverse (objfile,
-                                                         GNTT (objfile),
-                                                         VT (objfile),
-                                                         &pxdb_header);
-
-       discard_cleanups (old_chain);
-
-       /* Set up to scan the global section of the LNTT.
-
-          This field is not always correct: if there are
-          no globals, it will point to the last record in
-          the regular LNTT, which is usually an END MODULE.
-
-          Since it might happen that there could be a file
-          with just one global record, there's no way to
-          tell other than by looking at the record, so that's
-          done below. */
-       if (found_modules_in_program)
-         scan_start = pxdb_header.globals;
-      }
-#ifdef DUMPING
-    else
-      {
-       if (dumping)
-         printf ("\nGoing on to old method for %s\n", objfile->name);
-      }
-#endif
-  }
-#endif /* QUICK_LOOK_UP */
-
-  /* Make two passes, one over the GNTT symbols, the other for the
-     LNTT symbols.
-
-     JB comment: above isn't true--they only make one pass, over
-     the LNTT.  */
-  for (i = 0; i < 1; i++)
-    {
-      int within_function = 0;
-
-      if (i)
-       symcount = GNTT_SYMCOUNT (objfile);
-      else
-       symcount = LNTT_SYMCOUNT (objfile);
-
-
-      for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
-       {
-         QUIT;
-         if (i)
-           dn_bufp = hpread_get_gntt (hp_symnum, objfile);
-         else
-           dn_bufp = hpread_get_lntt (hp_symnum, objfile);
-
-         if (dn_bufp->dblock.extension)
-           continue;
-
-         /* Only handle things which are necessary for minimal symbols.
-            everything else is ignored.  */
-         switch (dn_bufp->dblock.kind)
-           {
-           case DNTT_TYPE_SRCFILE:
-             {
-#ifdef QUICK_LOOK_UP
-               if (scan_start == hp_symnum
-                   && symcount == hp_symnum + 1)
-                 {
-                   /* If there are NO globals in an executable,
-                      PXDB's index to the globals will point to
-                      the last record in the file, which 
-                      could be this record. (this happened for F77 libraries)
-                      ignore it and be done! */
-                   continue;
-                 }
-#endif /* QUICK_LOOK_UP */
-
-               /* A source file of some kind.  Note this may simply
-                  be an included file.  */
-               SET_NAMESTRING (dn_bufp, &namestring, objfile);
-
-               /* Check if this is the source file we are already working
-                  with.  */
-               if (pst && !strcmp (namestring, pst->filename))
-                 continue;
-
-               /* Check if this is an include file, if so check if we have
-                  already seen it.  Add it to the include list */
-               p = strrchr (namestring, '.');
-               if (!strcmp (p, ".h"))
-                 {
-                   int j, found;
-
-                   found = 0;
-                   for (j = 0; j < includes_used; j++)
-                     if (!strcmp (namestring, psymtab_include_list[j]))
-                       {
-                         found = 1;
-                         break;
-                       }
-                   if (found)
-                     continue;
-
-                   /* Add it to the list of includes seen so far and
-                      allocate more include space if necessary.  */
-                   psymtab_include_list[includes_used++] = namestring;
-                   if (includes_used >= includes_allocated)
-                     {
-                       char **orig = psymtab_include_list;
-
-                       psymtab_include_list = (char **)
-                         alloca ((includes_allocated *= 2) *
-                                 sizeof (char *));
-                       memcpy ((PTR) psymtab_include_list, (PTR) orig,
-                               includes_used * sizeof (char *));
-                     }
-                   continue;
-                 }
-
-               if (pst)
-                 {
-                   if (!have_name)
-                     {
-                       pst->filename = (char *)
-                         obstack_alloc (&pst->objfile->psymbol_obstack,
-                                        strlen (namestring) + 1);
-                       strcpy (pst->filename, namestring);
-                       have_name = 1;
-                       continue;
-                     }
-                   continue;
-                 }
-
-               /* This is a bonafide new source file.
-                  End the current partial symtab and start a new one.  */
-
-               if (pst && past_first_source_file)
-                 {
-                   hpread_end_psymtab (pst, psymtab_include_list,
-                                       includes_used,
-                                       (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                       texthigh,
-                                       dependency_list, dependencies_used);
-                   pst = (struct partial_symtab *) 0;
-                   includes_used = 0;
-                   dependencies_used = 0;
-                 }
-               else
-                 past_first_source_file = 1;
-
-               valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
-               valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-               pst = hpread_start_psymtab (objfile,
-                                           namestring, valu,
-                                           (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                           objfile->global_psymbols.next,
-                                           objfile->static_psymbols.next);
-               texthigh = valu;
-               have_name = 1;
-               continue;
-             }
-
-           case DNTT_TYPE_MODULE:
-             /* A source file.  It's still unclear to me what the
-                real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
-                is supposed to be.  */
-
-             /* First end the previous psymtab */
-             if (pst)
-               {
-                 hpread_end_psymtab (pst, psymtab_include_list, includes_used,
-                                     ((hp_symnum - 1)
-                                      * sizeof (struct dntt_type_block)),
-                                     texthigh,
-                                     dependency_list, dependencies_used);
-                 pst = (struct partial_symtab *) 0;
-                 includes_used = 0;
-                 dependencies_used = 0;
-                 have_name = 0;
-               }
-
-             /* Now begin a new module and a new psymtab for it */
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
-             valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             if (!pst)
-               {
-                 pst = hpread_start_psymtab (objfile,
-                                             namestring, valu,
-                                             (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                             objfile->static_psymbols.next);
-                 texthigh = valu;
-                 have_name = 0;
-               }
-             continue;
-
-           case DNTT_TYPE_FUNCTION:
-           case DNTT_TYPE_ENTRY:
-             /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
-                a secondary entry point.  */
-             valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
-                                                      SECT_OFF_TEXT (objfile));
-             if (valu > texthigh)
-               texthigh = valu;
-             valu = dn_bufp->dfunc.lowaddr +
-               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             if (dn_bufp->dfunc.global)
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_BLOCK,
-                                    &objfile->global_psymbols, valu,
-                                    0, language_unknown, objfile);
-             else
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_BLOCK,
-                                    &objfile->static_psymbols, valu,
-                                    0, language_unknown, objfile);
-             within_function = 1;
-             continue;
-
-           case DNTT_TYPE_DOC_FUNCTION:
-             valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
-                                                         SECT_OFF_TEXT (objfile));
-             if (valu > texthigh)
-               texthigh = valu;
-             valu = dn_bufp->ddocfunc.lowaddr +
-               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             if (dn_bufp->ddocfunc.global)
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_BLOCK,
-                                    &objfile->global_psymbols, valu,
-                                    0, language_unknown, objfile);
-             else
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_BLOCK,
-                                    &objfile->static_psymbols, valu,
-                                    0, language_unknown, objfile);
-             within_function = 1;
-             continue;
-
-           case DNTT_TYPE_BEGIN:
-           case DNTT_TYPE_END:
-             /* We don't check MODULE end here, because there can be
-                symbols beyond the module end which properly belong to the
-                current psymtab -- so we wait till the next MODULE start */
-
-
-#ifdef QUICK_LOOK_UP
-             if (scan_start == hp_symnum
-                 && symcount == hp_symnum + 1)
-               {
-                 /* If there are NO globals in an executable,
-                    PXDB's index to the globals will point to
-                    the last record in the file, which is
-                    probably an END MODULE, i.e. this record.
-                    ignore it and be done! */
-                 continue;
-               }
-#endif /* QUICK_LOOK_UP */
-
-             /* Scope block begin/end.  We only care about function
-                and file blocks right now.  */
-
-             if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
-                 (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
-               within_function = 0;
-             continue;
-
-           case DNTT_TYPE_SVAR:
-           case DNTT_TYPE_DVAR:
-           case DNTT_TYPE_TYPEDEF:
-           case DNTT_TYPE_TAGDEF:
-             {
-               /* Variables, typedefs an the like.  */
-               enum address_class storage;
-               namespace_enum namespace;
-
-               /* Don't add locals to the partial symbol table.  */
-               if (within_function
-                   && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
-                       || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
-                 continue;
-
-               /* TAGDEFs go into the structure namespace.  */
-               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
-                 namespace = STRUCT_NAMESPACE;
-               else
-                 namespace = VAR_NAMESPACE;
-
-               /* What kind of "storage" does this use?  */
-               if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
-                 storage = LOC_STATIC;
-               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
-                        && dn_bufp->ddvar.regvar)
-                 storage = LOC_REGISTER;
-               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
-                 storage = LOC_LOCAL;
-               else
-                 storage = LOC_UNDEF;
-
-               SET_NAMESTRING (dn_bufp, &namestring, objfile);
-               if (!pst)
-                 {
-                   pst = hpread_start_psymtab (objfile,
-                                               "globals", 0,
-                                               (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                            objfile->static_psymbols.next);
-                 }
-
-               /* Compute address of the data symbol */
-               valu = dn_bufp->dsvar.location;
-               /* Relocate in case it's in a shared library */
-               if (storage == LOC_STATIC)
-                 valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
-
-               /* Luckily, dvar, svar, typedef, and tagdef all
-                  have their "global" bit in the same place, so it works
-                  (though it's bad programming practice) to reference
-                  "dsvar.global" even though we may be looking at
-                  any of the above four types. */
-               if (dn_bufp->dsvar.global)
-                 {
-                   add_psymbol_to_list (namestring, strlen (namestring),
-                                        namespace, storage,
-                                        &objfile->global_psymbols,
-                                        valu,
-                                        0, language_unknown, objfile);
-                 }
-               else
-                 {
-                   add_psymbol_to_list (namestring, strlen (namestring),
-                                        namespace, storage,
-                                        &objfile->static_psymbols,
-                                        valu,
-                                        0, language_unknown, objfile);
-                 }
-
-               /* For TAGDEF's, the above code added the tagname to the
-                  struct namespace. This will cause tag "t" to be found
-                  on a reference of the form "(struct t) x". But for
-                  C++ classes, "t" will also be a typename, which we
-                  want to find on a reference of the form "ptype t".
-                  Therefore, we also add "t" to the var namespace.
-                  Do the same for enum's due to the way aCC generates
-                  debug info for these (see more extended comment
-                  in hp-symtab-read.c).
-                  We do the same for templates, so that "ptype t"
-                  where "t" is a template also works. */
-               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
-                 dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
-                 {
-                   int global = dn_bufp->dtag.global;
-                   /* Look ahead to see if it's a C++ class */
-                   dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
-                   if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
-                       dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
-                       dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-                     {
-                       if (global)
-                         {
-                           add_psymbol_to_list (namestring, strlen (namestring),
-                                                VAR_NAMESPACE, storage,
-                                                &objfile->global_psymbols,
-                                                dn_bufp->dsvar.location,
-                                             0, language_unknown, objfile);
-                         }
-                       else
-                         {
-                           add_psymbol_to_list (namestring, strlen (namestring),
-                                                VAR_NAMESPACE, storage,
-                                                &objfile->static_psymbols,
-                                                dn_bufp->dsvar.location,
-                                             0, language_unknown, objfile);
-                         }
-                     }
-                 }
-             }
-             continue;
-
-           case DNTT_TYPE_MEMENUM:
-           case DNTT_TYPE_CONST:
-             /* Constants and members of enumerated types.  */
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             if (!pst)
-               {
-                 pst = hpread_start_psymtab (objfile,
-                                             "globals", 0,
-                                             (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                             objfile->static_psymbols.next);
-               }
-             if (dn_bufp->dconst.global)
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_CONST,
-                                    &objfile->global_psymbols, 0,
-                                    0, language_unknown, objfile);
-             else
-               add_psymbol_to_list (namestring, strlen (namestring),
-                                    VAR_NAMESPACE, LOC_CONST,
-                                    &objfile->static_psymbols, 0,
-                                    0, language_unknown, objfile);
-             continue;
-           default:
-             continue;
-           }
-       }
-    }
-
-  /* End any pending partial symbol table. */
-  if (pst)
-    {
-      hpread_end_psymtab (pst, psymtab_include_list, includes_used,
-                         hp_symnum * sizeof (struct dntt_type_block),
-                         0, dependency_list, dependencies_used);
-    }
-
-  discard_cleanups (old_chain);
-}
-
-/* Perform any local cleanups required when we are done with a particular
-   objfile.  I.E, we are in the process of discarding all symbol information
-   for an objfile, freeing up all memory held for it, and unlinking the
-   objfile struct from the global list of known objfiles. */
-
-void
-hpread_symfile_finish (struct objfile *objfile)
-{
-  if (objfile->sym_private != NULL)
-    {
-      xmfree (objfile->md, objfile->sym_private);
-    }
-}
-\f
-
-/* The remaining functions are all for internal use only.  */
-
-/* Various small functions to get entries in the debug symbol sections.  */
-
-union dnttentry *
-hpread_get_lntt (int index, struct objfile *objfile)
-{
-  return (union dnttentry *)
-    &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
-}
-
-static union dnttentry *
-hpread_get_gntt (int index, struct objfile *objfile)
-{
-  return (union dnttentry *)
-    &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
-}
-
-union sltentry *
-hpread_get_slt (int index, struct objfile *objfile)
-{
-  return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
-}
-
-/* Get the low address associated with some symbol (typically the start
-   of a particular source file or module).  Since that information is not
-   stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we
-   must infer it from the existence of DNTT_TYPE_FUNCTION symbols.  */
-
-static unsigned long
-hpread_get_textlow (int global, int index, struct objfile *objfile,
-                   int symcount)
-{
-  union dnttentry *dn_bufp;
-  struct minimal_symbol *msymbol;
-
-  /* Look for a DNTT_TYPE_FUNCTION symbol.  */
-  if (index < symcount)                /* symcount is the number of symbols in */
-    {                          /*   the dbinfo, LNTT table */
-      do
-       {
-         if (global)
-           dn_bufp = hpread_get_gntt (index++, objfile);
-         else
-           dn_bufp = hpread_get_lntt (index++, objfile);
-       }
-      while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
-            && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
-            && dn_bufp->dblock.kind != DNTT_TYPE_END
-            && index < symcount);
-    }
-
-  /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION.  This
-     might happen when a sourcefile has no functions.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_END)
-    return 0;
-
-  /* Avoid going past the end of the LNTT file */
-  if (index == symcount)
-    return 0;
-
-  /* The minimal symbols are typically more accurate for some reason.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
-    msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
-                                    objfile);
-  else                         /* must be a DNTT_TYPE_DOC_FUNCTION */
-    msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
-                                    objfile);
-
-  if (msymbol)
-    return SYMBOL_VALUE_ADDRESS (msymbol);
-  else
-    return dn_bufp->dfunc.lowaddr;
-}
-
-/* Allocate and partially fill a partial symtab.  It will be
-   completely filled at the end of the symbol list.
-
-   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
-   is the address relative to which its symbols are (incremental) or 0
-   (normal). */
-
-static struct partial_symtab *
-hpread_start_psymtab (struct objfile *objfile, char *filename,
-                     CORE_ADDR textlow, int ldsymoff,
-                     struct partial_symbol **global_syms,
-                     struct partial_symbol **static_syms)
-{
-  int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-  extern void hpread_psymtab_to_symtab ();
-  struct partial_symtab *result =
-  start_psymtab_common (objfile, objfile->section_offsets,
-                       filename, textlow, global_syms, static_syms);
-
-  result->textlow += offset;
-  result->read_symtab_private = (char *)
-    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
-  LDSYMOFF (result) = ldsymoff;
-  result->read_symtab = hpread_psymtab_to_symtab;
-
-  return result;
-}
-\f
-
-/* Close off the current usage of PST.  
-   Returns PST or NULL if the partial symtab was empty and thrown away.
-
-   capping_symbol_offset  --Byte index in LNTT or GNTT of the
-   last symbol processed during the build
-   of the previous pst.
-
-   FIXME:  List variables and peculiarities of same.  */
-
-static struct partial_symtab *
-hpread_end_psymtab (struct partial_symtab *pst, char **include_list,
-                   int num_includes, int capping_symbol_offset,
-                   CORE_ADDR capping_text,
-                   struct partial_symtab **dependency_list,
-                   int number_dependencies)
-{
-  int i;
-  struct objfile *objfile = pst->objfile;
-  int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
-
-#ifdef DUMPING
-  /* Turn on to see what kind of a psymtab we've built. */
-  static int dumping = 0;
-#endif
-
-  if (capping_symbol_offset != -1)
-    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
-  else
-    LDSYMLEN (pst) = 0;
-  pst->texthigh = capping_text + offset;
-
-  pst->n_global_syms =
-    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
-  pst->n_static_syms =
-    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
-
-#ifdef DUMPING
-  if (dumping)
-    {
-      printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
-             pst->filename,
-             LDSYMOFF (pst),
-             LDSYMOFF (pst) / sizeof (struct dntt_type_block),
-             LDSYMLEN (pst),
-             LDSYMLEN (pst) / sizeof (struct dntt_type_block),
-             pst->n_global_syms, pst->n_static_syms);
-    }
-#endif
-
-  pst->number_of_dependencies = number_dependencies;
-  if (number_dependencies)
-    {
-      pst->dependencies = (struct partial_symtab **)
-       obstack_alloc (&objfile->psymbol_obstack,
-                   number_dependencies * sizeof (struct partial_symtab *));
-      memcpy (pst->dependencies, dependency_list,
-             number_dependencies * sizeof (struct partial_symtab *));
-    }
-  else
-    pst->dependencies = 0;
-
-  for (i = 0; i < num_includes; i++)
-    {
-      struct partial_symtab *subpst =
-      allocate_psymtab (include_list[i], objfile);
-
-      subpst->section_offsets = pst->section_offsets;
-      subpst->read_symtab_private =
-       (char *) obstack_alloc (&objfile->psymbol_obstack,
-                               sizeof (struct symloc));
-      LDSYMOFF (subpst) =
-       LDSYMLEN (subpst) =
-       subpst->textlow =
-       subpst->texthigh = 0;
-
-      /* We could save slight bits of space by only making one of these,
-         shared by the entire set of include files.  FIXME-someday.  */
-      subpst->dependencies = (struct partial_symtab **)
-       obstack_alloc (&objfile->psymbol_obstack,
-                      sizeof (struct partial_symtab *));
-      subpst->dependencies[0] = pst;
-      subpst->number_of_dependencies = 1;
-
-      subpst->globals_offset =
-       subpst->n_global_syms =
-       subpst->statics_offset =
-       subpst->n_static_syms = 0;
-
-      subpst->readin = 0;
-      subpst->symtab = 0;
-      subpst->read_symtab = pst->read_symtab;
-    }
-
-  sort_pst_symbols (pst);
-
-  /* If there is already a psymtab or symtab for a file of this name, remove it.
-     (If there is a symtab, more drastic things also happen.)
-     This happens in VxWorks.  */
-  free_named_symtabs (pst->filename);
-
-  if (num_includes == 0
-      && number_dependencies == 0
-      && pst->n_global_syms == 0
-      && pst->n_static_syms == 0)
-    {
-      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
-         it is on the obstack, but we can forget to chain it on the list. 
-         Empty psymtabs happen as a result of header files which don't have
-         any symbols in them.  There can be a lot of them.  But this check
-         is wrong, in that a psymtab with N_SLINE entries but nothing else
-         is not empty, but we don't realize that.  Fixing that without slowing
-         things down might be tricky.
-         It's also wrong if we're using the quick look-up tables, as
-         we can get empty psymtabs from modules with no routines in
-         them. */
-
-      discard_psymtab (pst);
-
-      /* Indicate that psymtab was thrown away.  */
-      pst = (struct partial_symtab *) NULL;
-
-    }
-  return pst;
-}
-
-
-/* End of hp-psymtab-read.c */
-
-/* Set indentation to 4 spaces for Emacs; this file is
-   mostly non-GNU-ish in its style :-( */
-#if 0
-***Local Variables:
-***c - basic - offset:4
-*** End:
-#endif
diff --git a/gdb/hp-symtab-read.c b/gdb/hp-symtab-read.c
deleted file mode 100644 (file)
index f5e1bd4..0000000
+++ /dev/null
@@ -1,3979 +0,0 @@
-/* Read hp debug symbols and convert to internal format, for GDB.
-   Copyright 1993, 1996, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
-
-   Written by the Center for Software Science at the University of Utah
-   and by Cygnus Support.  */
-
-/* Common include for hp-symtab-read.c and hp-psymtab-read.c.
- * Note this has nested includes for a bunch of stuff.
- */
-#include "defs.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "hpread.h"
-#include "demangle.h"
-#include "complaints.h"
-\f
-
-
-
-static struct complaint hpread_unhandled_end_common_complaint =
-{
-  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0
-};
-
-static struct complaint hpread_unhandled_type_complaint =
-{
-  "hpread_type_translate: unhandled type code.", 0, 0
-};
-
-static struct complaint hpread_struct_complaint =
-{
-  "hpread_read_struct_type: expected SVAR type...", 0, 0
-};
-
-static struct complaint hpread_array_complaint =
-{
-  "error in hpread_array_type.", 0, 0
-};
-
-static struct complaint hpread_type_lookup_complaint =
-{
-  "error in hpread_type_lookup().", 0, 0
-};
-
-
-static struct complaint hpread_unexpected_end_complaint =
-{
-  "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0
-};
-
-static struct complaint hpread_tagdef_complaint =
-{
-  "error processing class tagdef", 0, 0
-};
-
-static struct complaint hpread_unhandled_common_complaint =
-{
-  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0
-};
-
-static struct complaint hpread_unhandled_blockdata_complaint =
-{
-  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0
-};
-
-
-/* Forward procedure declarations */
-
-static unsigned long hpread_get_scope_start (sltpointer, struct objfile *);
-
-static unsigned long hpread_get_line (sltpointer, struct objfile *);
-
-static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
-
-static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
-
-void hpread_psymtab_to_symtab (struct partial_symtab *);
-
-static struct symtab *hpread_expand_symtab
-  (struct objfile *, int, int, CORE_ADDR, int,
-   struct section_offsets *, char *);
-
-static int hpread_type_translate (dnttpointer);
-
-static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
-
-static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
-
-static struct type *hpread_read_enum_type
-  (dnttpointer, union dnttentry *, struct objfile *);
-
-static struct type *hpread_read_function_type
-  (dnttpointer, union dnttentry *, struct objfile *, int);
-
-static struct type *hpread_read_doc_function_type
-  (dnttpointer, union dnttentry *, struct objfile *, int);
-
-static struct type *hpread_read_struct_type
-  (dnttpointer, union dnttentry *, struct objfile *);
-
-static struct type *hpread_get_nth_template_arg (struct objfile *, int);
-
-static struct type *hpread_read_templ_arg_type
-  (dnttpointer, union dnttentry *, struct objfile *, char *);
-
-static struct type *hpread_read_set_type
-  (dnttpointer, union dnttentry *, struct objfile *);
-
-static struct type *hpread_read_array_type
-  (dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile);
-
-static struct type *hpread_read_subrange_type
-  (dnttpointer, union dnttentry *, struct objfile *);
-
-static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
-
-static sltpointer hpread_record_lines
-  (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
-
-static void hpread_process_one_debug_symbol
-  (union dnttentry *, char *, struct section_offsets *,
-   struct objfile *, CORE_ADDR, int, char *, int, int *);
-
-static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int);
-
-static void fix_static_member_physnames
-  (struct type *, char *, struct objfile *);
-
-static void fixup_class_method_type
-  (struct type *, struct type *, struct objfile *);
-
-static void hpread_adjust_bitoffsets (struct type *, int);
-
-static dnttpointer hpread_get_next_skip_over_anon_unions
-  (int, dnttpointer, union dnttentry **, struct objfile *);
-
-/* Global to indicate presence of HP-compiled objects,
-   in particular, SOM executable file with SOM debug info 
-   Defined in symtab.c, used in hppa-tdep.c. */
-extern int hp_som_som_object_present;
-
-/* Static used to indicate a class type that requires a
-   fix-up of one of its method types */
-static struct type *fixup_class = NULL;
-
-/* Static used to indicate the method type that is to be
-   used to fix-up the type for fixup_class */
-static struct type *fixup_method = NULL;
-\f
-
-
-/* Get the nesting depth for the source line identified by INDEX.  */
-
-static unsigned long
-hpread_get_scope_start (sltpointer index, struct objfile *objfile)
-{
-  union sltentry *sl_bufp;
-
-  sl_bufp = hpread_get_slt (index, objfile);
-  return sl_bufp->sspec.backptr.dnttp.index;
-}
-
-/* Get the source line number the the line identified by INDEX.  */
-
-static unsigned long
-hpread_get_line (sltpointer index, struct objfile *objfile)
-{
-  union sltentry *sl_bufp;
-
-  sl_bufp = hpread_get_slt (index, objfile);
-  return sl_bufp->snorm.line;
-}
-
-/* Find the code address associated with a given sltpointer */
-
-static CORE_ADDR
-hpread_get_location (sltpointer index, struct objfile *objfile)
-{
-  union sltentry *sl_bufp;
-  int i;
-
-  /* code location of special sltentrys is determined from context */
-  sl_bufp = hpread_get_slt (index, objfile);
-
-  if (sl_bufp->snorm.sltdesc == SLT_END)
-    {
-      /* find previous normal sltentry and get address */
-      for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
-                  (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
-                  (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
-       sl_bufp = hpread_get_slt (index - i, objfile);
-      if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
-       return sl_bufp->snormoff.address;
-      else
-       return sl_bufp->snorm.address;
-    }
-
-  /* find next normal sltentry and get address */
-  for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
-              (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
-              (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
-    sl_bufp = hpread_get_slt (index + i, objfile);
-  if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
-    return sl_bufp->snormoff.address;
-  else
-    return sl_bufp->snorm.address;
-}
-\f
-
-/* Return 1 if an HP debug symbol of type KIND has a name associated with
- * it, else return 0. (This function is not currently used, but I'll
- * leave it here in case it proves useful later on. - RT).
- */
-
-int
-hpread_has_name (enum dntt_entry_type kind)
-{
-  switch (kind)
-    {
-    case DNTT_TYPE_SRCFILE:
-    case DNTT_TYPE_MODULE:
-    case DNTT_TYPE_FUNCTION:
-    case DNTT_TYPE_DOC_FUNCTION:
-    case DNTT_TYPE_ENTRY:
-    case DNTT_TYPE_IMPORT:
-    case DNTT_TYPE_LABEL:
-    case DNTT_TYPE_FPARAM:
-    case DNTT_TYPE_SVAR:
-    case DNTT_TYPE_DVAR:
-    case DNTT_TYPE_CONST:
-    case DNTT_TYPE_TYPEDEF:
-    case DNTT_TYPE_TAGDEF:
-    case DNTT_TYPE_MEMENUM:
-    case DNTT_TYPE_FIELD:
-    case DNTT_TYPE_SA:
-    case DNTT_TYPE_BLOCKDATA:
-    case DNTT_TYPE_MEMFUNC:
-    case DNTT_TYPE_DOC_MEMFUNC:
-      return 1;
-
-    case DNTT_TYPE_BEGIN:
-    case DNTT_TYPE_END:
-    case DNTT_TYPE_POINTER:
-    case DNTT_TYPE_ENUM:
-    case DNTT_TYPE_SET:
-    case DNTT_TYPE_ARRAY:
-    case DNTT_TYPE_STRUCT:
-    case DNTT_TYPE_UNION:
-    case DNTT_TYPE_VARIANT:
-    case DNTT_TYPE_FILE:
-    case DNTT_TYPE_FUNCTYPE:
-    case DNTT_TYPE_SUBRANGE:
-    case DNTT_TYPE_WITH:
-    case DNTT_TYPE_COMMON:
-    case DNTT_TYPE_COBSTRUCT:
-    case DNTT_TYPE_XREF:
-    case DNTT_TYPE_MACRO:
-    case DNTT_TYPE_CLASS_SCOPE:
-    case DNTT_TYPE_REFERENCE:
-    case DNTT_TYPE_PTRMEM:
-    case DNTT_TYPE_PTRMEMFUNC:
-    case DNTT_TYPE_CLASS:
-    case DNTT_TYPE_GENFIELD:
-    case DNTT_TYPE_VFUNC:
-    case DNTT_TYPE_MEMACCESS:
-    case DNTT_TYPE_INHERITANCE:
-    case DNTT_TYPE_FRIEND_CLASS:
-    case DNTT_TYPE_FRIEND_FUNC:
-    case DNTT_TYPE_MODIFIER:
-    case DNTT_TYPE_OBJECT_ID:
-    case DNTT_TYPE_TEMPLATE:
-    case DNTT_TYPE_TEMPLATE_ARG:
-    case DNTT_TYPE_FUNC_TEMPLATE:
-    case DNTT_TYPE_LINK:
-      /* DNTT_TYPE_DYN_ARRAY_DESC ? */
-      /* DNTT_TYPE_DESC_SUBRANGE ? */
-      /* DNTT_TYPE_BEGIN_EXT ? */
-      /* DNTT_TYPE_INLN ? */
-      /* DNTT_TYPE_INLN_LIST ? */
-      /* DNTT_TYPE_ALIAS ? */
-    default:
-      return 0;
-    }
-}
-
-/* Do the dirty work of reading in the full symbol from a partial symbol
-   table.  */
-
-static void
-hpread_psymtab_to_symtab_1 (struct partial_symtab *pst)
-{
-  struct cleanup *old_chain;
-  int i;
-
-  /* Get out quick if passed junk.  */
-  if (!pst)
-    return;
-
-  /* Complain if we've already read in this symbol table.  */
-  if (pst->readin)
-    {
-      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
-              pst->filename);
-      return;
-    }
-
-  /* Read in all partial symtabs on which this one is dependent */
-  for (i = 0; i < pst->number_of_dependencies; i++)
-    if (!pst->dependencies[i]->readin)
-      {
-       /* Inform about additional files that need to be read in.  */
-       if (info_verbose)
-         {
-           fputs_filtered (" ", gdb_stdout);
-           wrap_here ("");
-           fputs_filtered ("and ", gdb_stdout);
-           wrap_here ("");
-           printf_filtered ("%s...", pst->dependencies[i]->filename);
-           wrap_here ("");     /* Flush output */
-           gdb_flush (gdb_stdout);
-         }
-       hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
-      }
-
-  /* If it's real...  */
-  if (LDSYMLEN (pst))
-    {
-      /* Init stuff necessary for reading in symbols */
-      buildsym_init ();
-      old_chain = make_cleanup (really_free_pendings, 0);
-
-      pst->symtab =
-       hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
-                             pst->textlow, pst->texthigh - pst->textlow,
-                             pst->section_offsets, pst->filename);
-      sort_symtab_syms (pst->symtab);
-
-      do_cleanups (old_chain);
-    }
-
-  pst->readin = 1;
-}
-
-/* Read in all of the symbols for a given psymtab for real.
-   Be verbose about it if the user wants that.  */
-
-void
-hpread_psymtab_to_symtab (struct partial_symtab *pst)
-{
-  /* Get out quick if given junk.  */
-  if (!pst)
-    return;
-
-  /* Sanity check.  */
-  if (pst->readin)
-    {
-      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
-              pst->filename);
-      return;
-    }
-
-  /* elz: setting the flag to indicate that the code of the target
-     was compiled using an HP compiler (aCC, cc) 
-     the processing_acc_compilation variable is declared in the 
-     file buildsym.h, the HP_COMPILED_TARGET is defined to be equal
-     to 3 in the file tm_hppa.h */
-
-  processing_gcc_compilation = 0;
-
-  if (LDSYMLEN (pst) || pst->number_of_dependencies)
-    {
-      /* Print the message now, before reading the string table,
-         to avoid disconcerting pauses.  */
-      if (info_verbose)
-       {
-         printf_filtered ("Reading in symbols for %s...", pst->filename);
-         gdb_flush (gdb_stdout);
-       }
-
-      hpread_psymtab_to_symtab_1 (pst);
-
-      /* Match with global symbols.  This only needs to be done once,
-         after all of the symtabs and dependencies have been read in.   */
-      scan_file_globals (pst->objfile);
-
-      /* Finish up the debug error message.  */
-      if (info_verbose)
-       printf_filtered ("done.\n");
-    }
-}
-
-/* Read in a defined section of a specific object file's symbols.
-
-   DESC is the file descriptor for the file, positioned at the
-   beginning of the symtab
-   SYM_OFFSET is the offset within the file of
-   the beginning of the symbols we want to read
-   SYM_SIZE is the size of the symbol info to read in.
-   TEXT_OFFSET is the beginning of the text segment we are reading symbols for
-   TEXT_SIZE is the size of the text segment read in.
-   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
-
-static struct symtab *
-hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
-                     CORE_ADDR text_offset, int text_size,
-                     struct section_offsets *section_offsets, char *filename)
-{
-  char *namestring;
-  union dnttentry *dn_bufp;
-  unsigned max_symnum;
-  int at_module_boundary = 0;
-  /* 1 => at end, -1 => at beginning */
-
-  int sym_index = sym_offset / sizeof (struct dntt_type_block);
-
-  current_objfile = objfile;
-  subfile_stack = 0;
-
-  last_source_file = 0;
-
-  /* Demangling style -- if EDG style already set, don't change it,
-     as HP style causes some problems with the KAI EDG compiler */
-  if (current_demangling_style != edg_demangling)
-    {
-      /* Otherwise, ensure that we are using HP style demangling */
-      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
-    }
-
-  dn_bufp = hpread_get_lntt (sym_index, objfile);
-  if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
-       (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
-    {
-      start_symtab ("globals", NULL, 0);
-      record_debugformat ("HP");
-    }
-
-  /* The psymtab builder (hp-psymtab-read.c) is the one that
-   * determined the "sym_size" argument (i.e. how many DNTT symbols
-   * are in this symtab), which we use to compute "max_symnum"
-   * (point in DNTT to which we read). 
-   *
-   * Perhaps this should be changed so that 
-   * process_one_debug_symbol() "knows" when
-   * to stop reading (based on reading from the MODULE to the matching
-   * END), and take out this reliance on a #-syms being passed in...
-   * (I'm worried about the reliability of this number). But I'll
-   * leave it as-is, for now. - RT
-   *
-   * The change above has been made. I've left the "for" loop control
-   * in to prepare for backing this out again. -JB
-   */
-  max_symnum = sym_size / sizeof (struct dntt_type_block);
-  /* No reason to multiply on pst side and divide on sym side... FIXME */
-
-  /* Read in and process each debug symbol within the specified range.
-   */
-  for (symnum = 0;
-       symnum < max_symnum;
-       symnum++)
-    {
-      QUIT;                    /* Allow this to be interruptable */
-      dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
-
-      if (dn_bufp->dblock.extension)
-       continue;
-
-      /* Yow!  We call SET_NAMESTRING on things without names!  */
-      SET_NAMESTRING (dn_bufp, &namestring, objfile);
-
-      hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
-                                      objfile, text_offset, text_size,
-                                      filename, symnum + sym_index,
-                                      &at_module_boundary
-       );
-
-      /* OLD COMMENTS: This routine is only called for psts.  All psts
-       * correspond to MODULES.  If we ever do lazy-reading of globals
-       * from the LNTT, then there will be a pst which ends when the
-       * LNTT ends, and not at an END MODULE entry.  Then we'll have
-       * to re-visit this break.  
-
-       if( at_end_of_module )
-       break;
-
-       */
-
-      /* We no longer break out of the loop when we reach the end of a
-         module. The reason is that with CTTI, the compiler can generate
-         function symbols (for template function instantiations) which are not
-         in any module; typically they show up beyond a module's end, and
-         before the next module's start.  We include them in the current
-         module.  However, we still don't trust the MAX_SYMNUM value from
-         the psymtab, so we break out if we enter a new module. */
-
-      if (at_module_boundary == -1)
-       break;
-    }
-
-  current_objfile = NULL;
-  hp_som_som_object_present = 1;       /* Indicate we've processed an HP SOM SOM file */
-
-  return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
-}
-\f
-
-
-
-/* Convert basic types from HP debug format into GDB internal format.  */
-
-static int
-hpread_type_translate (dnttpointer typep)
-{
-  if (!typep.dntti.immediate)
-    {
-      error ("error in hpread_type_translate\n.");
-      return FT_VOID;
-    }
-
-  switch (typep.dntti.type)
-    {
-    case HP_TYPE_BOOLEAN:
-    case HP_TYPE_BOOLEAN_S300_COMPAT:
-    case HP_TYPE_BOOLEAN_VAX_COMPAT:
-      return FT_BOOLEAN;
-    case HP_TYPE_CHAR:         /* C signed char, C++ plain char */
-
-    case HP_TYPE_WIDE_CHAR:
-      return FT_CHAR;
-    case HP_TYPE_INT:
-      if (typep.dntti.bitlength <= 8)
-       return FT_SIGNED_CHAR;  /* C++ signed char */
-      if (typep.dntti.bitlength <= 16)
-       return FT_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_INTEGER;
-      return FT_LONG_LONG;
-    case HP_TYPE_LONG:
-      if (typep.dntti.bitlength <= 8)
-       return FT_SIGNED_CHAR;  /* C++ signed char. */
-      return FT_LONG;
-    case HP_TYPE_UNSIGNED_LONG:
-      if (typep.dntti.bitlength <= 8)
-       return FT_UNSIGNED_CHAR;        /* C/C++ unsigned char */
-      if (typep.dntti.bitlength <= 16)
-       return FT_UNSIGNED_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_UNSIGNED_LONG;
-      return FT_UNSIGNED_LONG_LONG;
-    case HP_TYPE_UNSIGNED_INT:
-      if (typep.dntti.bitlength <= 8)
-       return FT_UNSIGNED_CHAR;
-      if (typep.dntti.bitlength <= 16)
-       return FT_UNSIGNED_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_UNSIGNED_INTEGER;
-      return FT_UNSIGNED_LONG_LONG;
-    case HP_TYPE_REAL:
-    case HP_TYPE_REAL_3000:
-    case HP_TYPE_DOUBLE:
-      if (typep.dntti.bitlength == 64)
-       return FT_DBL_PREC_FLOAT;
-      if (typep.dntti.bitlength == 128)
-       return FT_EXT_PREC_FLOAT;
-      return FT_FLOAT;
-    case HP_TYPE_COMPLEX:
-    case HP_TYPE_COMPLEXS3000:
-      if (typep.dntti.bitlength == 128)
-       return FT_DBL_PREC_COMPLEX;
-      if (typep.dntti.bitlength == 192)
-       return FT_EXT_PREC_COMPLEX;
-      return FT_COMPLEX;
-    case HP_TYPE_VOID:
-      return FT_VOID;
-    case HP_TYPE_STRING200:
-    case HP_TYPE_LONGSTRING200:
-    case HP_TYPE_FTN_STRING_SPEC:
-    case HP_TYPE_MOD_STRING_SPEC:
-    case HP_TYPE_MOD_STRING_3000:
-    case HP_TYPE_FTN_STRING_S300_COMPAT:
-    case HP_TYPE_FTN_STRING_VAX_COMPAT:
-      return FT_STRING;
-    case HP_TYPE_TEMPLATE_ARG:
-      return FT_TEMPLATE_ARG;
-    case HP_TYPE_TEXT:
-    case HP_TYPE_FLABEL:
-    case HP_TYPE_PACKED_DECIMAL:
-    case HP_TYPE_ANYPOINTER:
-    case HP_TYPE_GLOBAL_ANYPOINTER:
-    case HP_TYPE_LOCAL_ANYPOINTER:
-    default:
-      warning ("hpread_type_translate: unhandled type code.\n");
-      return FT_VOID;
-    }
-}
-
-/* Given a position in the DNTT, return a pointer to the 
- * already-built "struct type" (if any), for the type defined 
- * at that position.
- */
-
-static struct type **
-hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
-{
-  unsigned old_len;
-  int index = hp_type.dnttp.index;
-  int size_changed = 0;
-
-  /* The immediate flag indicates this doesn't actually point to
-   * a type DNTT.
-   */
-  if (hp_type.dntti.immediate)
-    return NULL;
-
-  /* For each objfile, we maintain a "type vector".
-   * This an array of "struct type *"'s with one pointer per DNTT index.
-   * Given a DNTT index, we look in this array to see if we have
-   * already processed this DNTT and if it is a type definition.
-   * If so, then we can locate a pointer to the already-built
-   * "struct type", and not build it again.
-   * 
-   * The need for this arises because our DNTT-walking code wanders
-   * around. In particular, it will encounter the same type multiple
-   * times (once for each object of that type). We don't want to 
-   * built multiple "struct type"'s for the same thing.
-   *
-   * Having said this, I should point out that this type-vector is
-   * an expensive way to keep track of this. If most DNTT entries are 
-   * 3 words, the type-vector will be 1/3 the size of the DNTT itself.
-   * Alternative solutions:
-   * - Keep a compressed or hashed table. Less memory, but more expensive
-   *   to search and update.
-   * - (Suggested by JB): Overwrite the DNTT entry itself
-   *   with the info. Create a new type code "ALREADY_BUILT", and modify
-   *   the DNTT to have that type code and point to the already-built entry.
-   * -RT
-   */
-
-  if (index < LNTT_SYMCOUNT (objfile))
-    {
-      if (index >= TYPE_VECTOR_LENGTH (objfile))
-       {
-         old_len = TYPE_VECTOR_LENGTH (objfile);
-
-         /* See if we need to allocate a type-vector. */
-         if (old_len == 0)
-           {
-             TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
-             TYPE_VECTOR (objfile) = (struct type **)
-               xmmalloc (objfile->md, TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
-             memset (&TYPE_VECTOR (objfile)[old_len], 0,
-                     (TYPE_VECTOR_LENGTH (objfile) - old_len) *
-                     sizeof (struct type *));
-           }
-
-         /* See if we need to resize type-vector. With my change to
-          * initially allocate a correct-size type-vector, this code
-          * should no longer trigger.
-          */
-         while (index >= TYPE_VECTOR_LENGTH (objfile))
-           {
-             TYPE_VECTOR_LENGTH (objfile) *= 2;
-             size_changed = 1;
-           }
-         if (size_changed)
-           {
-             TYPE_VECTOR (objfile) = (struct type **)
-               xmrealloc (objfile->md,
-                          (char *) TYPE_VECTOR (objfile),
-                  (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
-
-             memset (&TYPE_VECTOR (objfile)[old_len], 0,
-                     (TYPE_VECTOR_LENGTH (objfile) - old_len) *
-                     sizeof (struct type *));
-           }
-
-       }
-      return &TYPE_VECTOR (objfile)[index];
-    }
-  else
-    return NULL;
-}
-
-/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
-   Note we'll just return the address of a GDB internal type if we already
-   have it lying around.  */
-
-static struct type *
-hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
-{
-  struct type **type_addr;
-
-  type_addr = hpread_lookup_type (hp_type, objfile);
-  if (*type_addr == 0)
-    {
-      *type_addr = alloc_type (objfile);
-
-      /* A hack - if we really are a C++ class symbol, then this default
-       * will get overriden later on.
-       */
-      TYPE_CPLUS_SPECIFIC (*type_addr)
-       = (struct cplus_struct_type *) &cplus_struct_default;
-    }
-
-  return *type_addr;
-}
-
-/* Read a native enumerated type and return it in GDB internal form.  */
-
-static struct type *
-hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                      struct objfile *objfile)
-{
-  struct type *type;
-  struct pending **symlist, *osyms, *syms;
-  struct pending *local_list = NULL;
-  int o_nsyms, nsyms = 0;
-  dnttpointer mem;
-  union dnttentry *memp;
-  char *name;
-  long n;
-  struct symbol *sym;
-
-  /* Allocate a GDB type. If we've already read in this enum type,
-   * it'll return the already built GDB type, so stop here.
-   * (Note: I added this check, to conform with what's done for 
-   *  struct, union, class.
-   *  I assume this is OK. - RT)
-   */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_ENUM)
-    return type;
-
-  /* HP C supports "sized enums", where a specifier such as "short" or
-     "char" can be used to get enums of different sizes. So don't assume
-     an enum is always 4 bytes long. pai/1997-08-21 */
-  TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
-
-  symlist = &file_symbols;
-  osyms = *symlist;
-  o_nsyms = osyms ? osyms->nsyms : 0;
-
-  /* Get a name for each member and add it to our list of members.  
-   * The list of "mem" SOM records we are walking should all be
-   * SOM type DNTT_TYPE_MEMENUM (not checked).
-   */
-  mem = dn_bufp->denum.firstmem;
-  while (mem.word && mem.word != DNTTNIL)
-    {
-      memp = hpread_get_lntt (mem.dnttp.index, objfile);
-
-      name = VT (objfile) + memp->dmember.name;
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
-                                            sizeof (struct symbol));
-      memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-                                       &objfile->symbol_obstack);
-      SYMBOL_CLASS (sym) = LOC_CONST;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      SYMBOL_VALUE (sym) = memp->dmember.value;
-      add_symbol_to_list (sym, symlist);
-      nsyms++;
-      mem = memp->dmember.nextmem;
-    }
-
-  /* Now that we know more about the enum, fill in more info.  */
-  TYPE_CODE (type) = TYPE_CODE_ENUM;
-  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
-  TYPE_NFIELDS (type) = nsyms;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms);
-
-  /* Find the symbols for the members and put them into the type.
-     The symbols can be found in the symlist that we put them on
-     to cause them to be defined.  osyms contains the old value
-     of that symlist; everything up to there was defined by us.
-
-     Note that we preserve the order of the enum constants, so
-     that in something like "enum {FOO, LAST_THING=FOO}" we print
-     FOO, not LAST_THING.  */
-  for (syms = *symlist, n = 0; syms; syms = syms->next)
-    {
-      int j = 0;
-      if (syms == osyms)
-       j = o_nsyms;
-      for (; j < syms->nsyms; j++, n++)
-       {
-         struct symbol *xsym = syms->symbol[j];
-         SYMBOL_TYPE (xsym) = type;
-         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
-         TYPE_FIELD_BITSIZE (type, n) = 0;
-       }
-      if (syms == osyms)
-       break;
-    }
-
-  return type;
-}
-
-/* Read and internalize a native function debug symbol.  */
-
-static struct type *
-hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                          struct objfile *objfile, int newblock)
-{
-  struct type *type, *type1;
-  struct pending *syms;
-  struct pending *local_list = NULL;
-  int nsyms = 0;
-  dnttpointer param;
-  union dnttentry *paramp;
-  char *name;
-  long n;
-  struct symbol *sym;
-  int record_args = 1;
-
-  /* See if we've already read in this type.  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
-    {
-      record_args = 0;         /* already read in, don't modify type */
-    }
-  else
-    {
-      /* Nope, so read it in and store it away.  */
-      if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
-         dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
-       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
-                                                         objfile));
-      else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
-       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
-                                                         objfile));
-      else                     /* expect DNTT_TYPE_FUNC_TEMPLATE */
-       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
-                                                         objfile));
-      memcpy ((char *) type, (char *) type1, sizeof (struct type));
-
-      /* Mark it -- in the middle of processing */
-      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
-    }
-
-  /* Now examine each parameter noting its type, location, and a
-     wealth of other information.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
-      dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
-    param = dn_bufp->dfunc.firstparam;
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
-    param = dn_bufp->dfunctype.firstparam;
-  else                         /* expect DNTT_TYPE_FUNC_TEMPLATE */
-    param = dn_bufp->dfunc_template.firstparam;
-  while (param.word && param.word != DNTTNIL)
-    {
-      paramp = hpread_get_lntt (param.dnttp.index, objfile);
-      nsyms++;
-      param = paramp->dfparam.nextparam;
-
-      /* Get the name.  */
-      name = VT (objfile) + paramp->dfparam.name;
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
-                                            sizeof (struct symbol));
-      (void) memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-                                       &objfile->symbol_obstack);
-
-      /* Figure out where it lives.  */
-      if (paramp->dfparam.regparam)
-       SYMBOL_CLASS (sym) = LOC_REGPARM;
-      else if (paramp->dfparam.indirect)
-       SYMBOL_CLASS (sym) = LOC_REF_ARG;
-      else
-       SYMBOL_CLASS (sym) = LOC_ARG;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      if (paramp->dfparam.copyparam)
-       {
-         SYMBOL_VALUE (sym) = paramp->dfparam.location;
-#ifdef HPREAD_ADJUST_STACK_ADDRESS
-         SYMBOL_VALUE (sym)
-           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
-#endif
-         /* This is likely a pass-by-invisible reference parameter,
-            Hack on the symbol class to make GDB happy.  */
-         /* ??rehrauer: This appears to be broken w/r/t to passing
-            C values of type float and struct.  Perhaps this ought
-            to be highighted as a special case, but for now, just
-            allowing these to be LOC_ARGs seems to work fine.
-          */
-#if 0
-         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
-#endif
-       }
-      else
-       SYMBOL_VALUE (sym) = paramp->dfparam.location;
-
-      /* Get its type.  */
-      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
-      /* Add it to the symbol list.  */
-      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
-       * called on FPARAM symbols from the process_one_debug_symbol()
-       * level... so parameters are getting added twice! (this shows
-       * up in the symbol dump you get from "maint print symbols ...").
-       * Note 2 (RT) I took out the processing of FPARAM from the 
-       * process_one_debug_symbol() level, so at the moment parameters are only
-       * being processed here. This seems to have no ill effect.
-       */
-      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
-         each fparam on the local_symbols list from here.  Now we use the
-         local_list to which fparams are added below, and set the param_symbols
-         global to point to that at the end of this routine. */
-      /* elz: I added this new list of symbols which is local to the function.
-         this list is the one which is actually used to build the type for the
-         function rather than the gloabal list pointed to by symlist.
-         Using a global list to keep track of the parameters is wrong, because 
-         this function is called recursively if one parameter happend to be
-         a function itself with more parameters in it. Adding parameters to the
-         same global symbol list would not work!      
-         Actually it did work in case of cc compiled programs where you do 
-         not check the parameter lists of the arguments. */
-      add_symbol_to_list (sym, &local_list);
-
-    }
-
-  /* If type was read in earlier, don't bother with modifying
-     the type struct */
-  if (!record_args)
-    goto finish;
-
-  /* Note how many parameters we found.  */
-  TYPE_NFIELDS (type) = nsyms;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack,
-                  sizeof (struct field) * nsyms);
-
-  /* Find the symbols for the parameters and 
-     use them to fill parameter-type information into the function-type.
-     The parameter symbols can be found in the local_list that we just put them on. */
-  /* Note that we preserve the order of the parameters, so
-     that in something like "enum {FOO, LAST_THING=FOO}" we print
-     FOO, not LAST_THING.  */
-
-  /* get the parameters types from the local list not the global list
-     so that the type can be correctly constructed for functions which
-     have function as parameters */
-  for (syms = local_list, n = 0; syms; syms = syms->next)
-    {
-      int j = 0;
-      for (j = 0; j < syms->nsyms; j++, n++)
-       {
-         struct symbol *xsym = syms->symbol[j];
-         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
-         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
-         TYPE_FIELD_BITSIZE (type, n) = 0;
-       }
-    }
-  /* Mark it as having been processed */
-  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
-
-  /* Check whether we need to fix-up a class type with this function's type */
-  if (fixup_class && (fixup_method == type))
-    {
-      fixup_class_method_type (fixup_class, fixup_method, objfile);
-      fixup_class = NULL;
-      fixup_method = NULL;
-    }
-
-  /* Set the param list of this level of the context stack
-     to our local list.  Do this only if this function was
-     called for creating a new block, and not if it was called
-     simply to get the function type. This prevents recursive
-     invocations from trashing param_symbols. */
-finish:
-  if (newblock)
-    param_symbols = local_list;
-
-  return type;
-}
-
-
-/* Read and internalize a native DOC function debug symbol.  */
-/* This is almost identical to hpread_read_function_type(), except
- * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc.
- * Since debug information for DOC functions is more likely to be
- * volatile, please leave it this way.
- */
-static struct type *
-hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                              struct objfile *objfile, int newblock)
-{
-  struct type *type, *type1;
-  struct pending *syms;
-  struct pending *local_list = NULL;
-  int nsyms = 0;
-  dnttpointer param;
-  union dnttentry *paramp;
-  char *name;
-  long n;
-  struct symbol *sym;
-  int record_args = 1;
-
-  /* See if we've already read in this type.  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
-    {
-      record_args = 0;         /* already read in, don't modify type */
-    }
-  else
-    {
-      /* Nope, so read it in and store it away.  */
-      if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
-         dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
-       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
-                                                         objfile));
-      memcpy ((char *) type, (char *) type1, sizeof (struct type));
-
-      /* Mark it -- in the middle of processing */
-      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
-    }
-
-  /* Now examine each parameter noting its type, location, and a
-     wealth of other information.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
-      dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
-    param = dn_bufp->ddocfunc.firstparam;
-  while (param.word && param.word != DNTTNIL)
-    {
-      paramp = hpread_get_lntt (param.dnttp.index, objfile);
-      nsyms++;
-      param = paramp->dfparam.nextparam;
-
-      /* Get the name.  */
-      name = VT (objfile) + paramp->dfparam.name;
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
-                                            sizeof (struct symbol));
-      (void) memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = name;
-
-      /* Figure out where it lives.  */
-      if (paramp->dfparam.regparam)
-       SYMBOL_CLASS (sym) = LOC_REGPARM;
-      else if (paramp->dfparam.indirect)
-       SYMBOL_CLASS (sym) = LOC_REF_ARG;
-      else
-       SYMBOL_CLASS (sym) = LOC_ARG;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      if (paramp->dfparam.copyparam)
-       {
-         SYMBOL_VALUE (sym) = paramp->dfparam.location;
-#ifdef HPREAD_ADJUST_STACK_ADDRESS
-         SYMBOL_VALUE (sym)
-           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
-#endif
-         /* This is likely a pass-by-invisible reference parameter,
-            Hack on the symbol class to make GDB happy.  */
-         /* ??rehrauer: This appears to be broken w/r/t to passing
-            C values of type float and struct.  Perhaps this ought
-            to be highighted as a special case, but for now, just
-            allowing these to be LOC_ARGs seems to work fine.
-          */
-#if 0
-         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
-#endif
-       }
-      else
-       SYMBOL_VALUE (sym) = paramp->dfparam.location;
-
-      /* Get its type.  */
-      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
-      /* Add it to the symbol list.  */
-      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
-       * called on FPARAM symbols from the process_one_debug_symbol()
-       * level... so parameters are getting added twice! (this shows
-       * up in the symbol dump you get from "maint print symbols ...").
-       * Note 2 (RT) I took out the processing of FPARAM from the 
-       * process_one_debug_symbol() level, so at the moment parameters are only
-       * being processed here. This seems to have no ill effect.
-       */
-      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
-         each fparam on the local_symbols list from here.  Now we use the
-         local_list to which fparams are added below, and set the param_symbols
-         global to point to that at the end of this routine. */
-
-      /* elz: I added this new list of symbols which is local to the function.
-         this list is the one which is actually used to build the type for the
-         function rather than the gloabal list pointed to by symlist.
-         Using a global list to keep track of the parameters is wrong, because 
-         this function is called recursively if one parameter happend to be
-         a function itself with more parameters in it. Adding parameters to the
-         same global symbol list would not work!      
-         Actually it did work in case of cc compiled programs where you do not check the
-         parameter lists of the arguments.  */
-      add_symbol_to_list (sym, &local_list);
-    }
-
-  /* If type was read in earlier, don't bother with modifying
-     the type struct */
-  if (!record_args)
-    goto finish;
-
-  /* Note how many parameters we found.  */
-  TYPE_NFIELDS (type) = nsyms;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack,
-                  sizeof (struct field) * nsyms);
-
-  /* Find the symbols for the parameters and 
-     use them to fill parameter-type information into the function-type.
-     The parameter symbols can be found in the local_list that we just put them on. */
-  /* Note that we preserve the order of the parameters, so
-     that in something like "enum {FOO, LAST_THING=FOO}" we print
-     FOO, not LAST_THING.  */
-
-  /* get the parameters types from the local list not the global list
-     so that the type can be correctly constructed for functions which
-     have function as parameters
-   */
-  for (syms = local_list, n = 0; syms; syms = syms->next)
-    {
-      int j = 0;
-      for (j = 0; j < syms->nsyms; j++, n++)
-       {
-         struct symbol *xsym = syms->symbol[j];
-         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
-         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
-         TYPE_FIELD_BITSIZE (type, n) = 0;
-       }
-    }
-
-  /* Mark it as having been processed */
-  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
-
-  /* Check whether we need to fix-up a class type with this function's type */
-  if (fixup_class && (fixup_method == type))
-    {
-      fixup_class_method_type (fixup_class, fixup_method, objfile);
-      fixup_class = NULL;
-      fixup_method = NULL;
-    }
-
-  /* Set the param list of this level of the context stack
-     to our local list.  Do this only if this function was
-     called for creating a new block, and not if it was called
-     simply to get the function type. This prevents recursive
-     invocations from trashing param_symbols. */
-finish:
-  if (newblock)
-    param_symbols = local_list;
-
-  return type;
-}
-
-
-
-/* A file-level variable which keeps track of the current-template
- * being processed. Set in hpread_read_struct_type() while processing
- * a template type. Referred to in hpread_get_nth_templ_arg().
- * Yes, this is a kludge, but it arises from the kludge that already
- * exists in symtab.h, namely the fact that they encode
- * "template argument n" with fundamental type FT_TEMPLATE_ARG and
- * bitlength n. This means that deep in processing fundamental types
- * I need to ask the question "what template am I in the middle of?".
- * The alternative to stuffing a global would be to pass an argument
- * down the chain of calls just for this purpose.
- * 
- * There may be problems handling nested templates... tough.
- */
-static struct type *current_template = NULL;
-
-/* Read in and internalize a structure definition.  
- * This same routine is called for struct, union, and class types.
- * Also called for templates, since they build a very similar
- * type entry as for class types.
- */
-
-static struct type *
-hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                        struct objfile *objfile)
-{
-  /* The data members get linked together into a list of struct nextfield's */
-  struct nextfield
-    {
-      struct nextfield *next;
-      struct field field;
-      unsigned char attributes;        /* store visibility and virtuality info */
-#define ATTR_VIRTUAL 1
-#define ATTR_PRIVATE 2
-#define ATTR_PROTECT 3
-    };
-
-
-  /* The methods get linked together into a list of struct next_fn_field's */
-  struct next_fn_field
-    {
-      struct next_fn_field *next;
-      struct fn_fieldlist field;
-      struct fn_field fn_field;
-      int num_fn_fields;
-    };
-
-  /* The template args get linked together into a list of struct next_template's */
-  struct next_template
-    {
-      struct next_template *next;
-      struct template_arg arg;
-    };
-
-  /* The template instantiations get linked together into a list of these... */
-  struct next_instantiation
-    {
-      struct next_instantiation *next;
-      struct type *t;
-    };
-
-  struct type *type;
-  struct type *baseclass;
-  struct type *memtype;
-  struct nextfield *list = 0, *tmp_list = 0;
-  struct next_fn_field *fn_list = 0;
-  struct next_fn_field *fn_p;
-  struct next_template *t_new, *t_list = 0;
-  struct nextfield *new;
-  struct next_fn_field *fn_new;
-  struct next_instantiation *i_new, *i_list = 0;
-  int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
-  int n_base_classes = 0, n_templ_args = 0;
-  int ninstantiations = 0;
-  dnttpointer field, fn_field, parent;
-  union dnttentry *fieldp, *fn_fieldp, *parentp;
-  int i;
-  int static_member = 0;
-  int const_member = 0;
-  int volatile_member = 0;
-  unsigned long vtbl_offset;
-  int need_bitvectors = 0;
-  char *method_name = NULL;
-  char *method_alias = NULL;
-
-
-  /* Is it something we've already dealt with?  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
-      (TYPE_CODE (type) == TYPE_CODE_UNION) ||
-      (TYPE_CODE (type) == TYPE_CODE_CLASS) ||
-      (TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
-    return type;
-
-  /* Get the basic type correct.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
-    {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
-      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
-    }
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
-    {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-      TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
-    }
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
-    {
-      TYPE_CODE (type) = TYPE_CODE_CLASS;
-      TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
-
-      /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory
-       * rather than &cplus_struct_default.
-       */
-      allocate_cplus_struct_type (type);
-
-      /* Fill in declared-type.
-       * (The C++ compiler will emit TYPE_CODE_CLASS 
-       * for all 3 of "class", "struct"
-       * "union", and we have to look at the "class_decl" field if we
-       * want to know how it was really declared)
-       */
-      /* (0==class, 1==union, 2==struct) */
-      TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl;
-    }
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-    {
-      /* Get the basic type correct.  */
-      TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
-      allocate_cplus_struct_type (type);
-      TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE;
-    }
-  else
-    return type;
-
-
-  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
-
-  /* For classes, read the parent list.
-   * Question (RT): Do we need to do this for templates also?
-   */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
-    {
-
-      /* First read the parent-list (classes from which we derive fields) */
-      parent = dn_bufp->dclass.parentlist;
-      while (parent.word && parent.word != DNTTNIL)
-       {
-         parentp = hpread_get_lntt (parent.dnttp.index, objfile);
-
-         /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */
-
-         /* Get space to record the next field/data-member. */
-         new = (struct nextfield *) alloca (sizeof (struct nextfield));
-         new->next = list;
-         list = new;
-
-         FIELD_BITSIZE (list->field) = 0;
-
-         /* The "classname" field is actually a DNTT pointer to the base class */
-         baseclass = hpread_type_lookup (parentp->dinheritance.classname,
-                                         objfile);
-         FIELD_TYPE (list->field) = baseclass;
-
-         list->field.name = type_name_no_tag (FIELD_TYPE (list->field));
-
-         list->attributes = 0;
-
-         /* Check for virtuality of base, and set the
-          * offset of the base subobject within the object.
-          * (Offset set to -1 for virtual bases (for now).)
-          */
-         if (parentp->dinheritance.Virtual)
-           {
-             B_SET (&(list->attributes), ATTR_VIRTUAL);
-             parentp->dinheritance.offset = -1;
-           }
-         else
-           FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
-
-         /* Check visibility */
-         switch (parentp->dinheritance.visibility)
-           {
-           case 1:
-             B_SET (&(list->attributes), ATTR_PROTECT);
-             break;
-           case 2:
-             B_SET (&(list->attributes), ATTR_PRIVATE);
-             break;
-           }
-
-         n_base_classes++;
-         nfields++;
-
-         parent = parentp->dinheritance.next;
-       }
-    }
-
-  /* For templates, read the template argument list.
-   * This must be done before processing the member list, because
-   * the member list may refer back to this. E.g.:
-   *   template <class T1, class T2> class q2 {
-   *     public:
-   *     T1 a;
-   *     T2 b;
-   *   };
-   * We need to read the argument list "T1", "T2" first.
-   */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-    {
-      /* Kludge alert: This stuffs a global "current_template" which
-       * is referred to by hpread_get_nth_templ_arg(). The global
-       * is cleared at the end of this routine.
-       */
-      current_template = type;
-
-      /* Read in the argument list */
-      field = dn_bufp->dtemplate.arglist;
-      while (field.word && field.word != DNTTNIL)
-       {
-         /* Get this template argument */
-         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
-         if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
-           {
-             warning ("Invalid debug info: Template argument entry is of wrong kind");
-             break;
-           }
-         /* Bump the count */
-         n_templ_args++;
-         /* Allocate and fill in a struct next_template */
-         t_new = (struct next_template *) alloca (sizeof (struct next_template));
-         t_new->next = t_list;
-         t_list = t_new;
-         t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
-         t_list->arg.type = hpread_read_templ_arg_type (field, fieldp,
-                                                objfile, t_list->arg.name);
-         /* Walk to the next template argument */
-         field = fieldp->dtempl_arg.nextarg;
-       }
-    }
-
-  TYPE_NTEMPLATE_ARGS (type) = n_templ_args;
-
-  if (n_templ_args > 0)
-    TYPE_TEMPLATE_ARGS (type) = (struct template_arg *)
-      obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args);
-  for (n = n_templ_args; t_list; t_list = t_list->next)
-    {
-      n -= 1;
-      TYPE_TEMPLATE_ARG (type, n) = t_list->arg;
-    }
-
-  /* Next read in and internalize all the fields/members.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
-    field = dn_bufp->dstruct.firstfield;
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
-    field = dn_bufp->dunion.firstfield;
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
-    field = dn_bufp->dclass.memberlist;
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-    field = dn_bufp->dtemplate.memberlist;
-  else
-    field.word = DNTTNIL;
-
-  while (field.word && field.word != DNTTNIL)
-    {
-      fieldp = hpread_get_lntt (field.dnttp.index, objfile);
-
-      /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD
-       * or a DNTT_TYPE_GENFIELD record. 
-       */
-      vtbl_offset = 0;
-      static_member = 0;
-      const_member = 0;
-      volatile_member = 0;
-
-      if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD)
-       {
-
-         /* The type will be GENFIELD if the field is a method or
-          * a static member (or some other cases -- see below)
-          */
-
-         /* Follow a link to get to the record for the field. */
-         fn_field = fieldp->dgenfield.field;
-         fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
-
-         /* Virtual funcs are indicated by a VFUNC which points to the
-          * real entry
-          */
-         if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC)
-           {
-             vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
-             fn_field = fn_fieldp->dvfunc.funcptr;
-             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
-           }
-
-         /* A function's entry may be preceded by a modifier which
-          * labels it static/constant/volatile.
-          */
-         if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER)
-           {
-             static_member = fn_fieldp->dmodifier.m_static;
-             const_member = fn_fieldp->dmodifier.m_const;
-             volatile_member = fn_fieldp->dmodifier.m_volatile;
-             fn_field = fn_fieldp->dmodifier.type;
-             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
-           }
-
-         /* Check whether we have a method */
-         if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
-             (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
-             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
-             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION))
-           {
-             /* Method found */
-
-             short ix = 0;
-
-             /* Look up function type of method */
-             memtype = hpread_type_lookup (fn_field, objfile);
-
-             /* Methods can be seen before classes in the SOM records.
-                If we are processing this class because it's a parameter of a
-                method, at this point the method's type is actually incomplete;
-                we'll have to fix it up later; mark the class for this. */
-
-             if (TYPE_INCOMPLETE (memtype))
-               {
-                 TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
-                 if (fixup_class)
-                   warning ("Two classes to fix up for method??  Type information may be incorrect for some classes.");
-                 if (fixup_method)
-                   warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
-                 fixup_class = type;   /* remember this class has to be fixed up */
-                 fixup_method = memtype;       /* remember the method type to be used in fixup */
-               }
-
-             /* HP aCC generates operator names without the "operator" keyword, and
-                generates null strings as names for operators that are 
-                user-defined type conversions to basic types (e.g. operator int ()).
-                So try to reconstruct name as best as possible. */
-
-             method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
-             method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
-
-             if (!method_name ||       /* no name */
-                 !*method_name ||      /* or null name */
-                 cplus_mangle_opname (method_name, DMGL_ANSI))         /* or name is an operator like "<" */
-               {
-                 char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
-                 char *op_string = strstr (tmp_name, "operator");
-                 method_name = xmalloc (strlen (op_string) + 1);       /* don't overwrite VT! */
-                 strcpy (method_name, op_string);
-               }
-
-             /* First check if a method of the same name has already been seen. */
-             fn_p = fn_list;
-             while (fn_p)
-               {
-                 if (STREQ (fn_p->field.name, method_name))
-                   break;
-                 fn_p = fn_p->next;
-               }
-
-             /* If no such method was found, allocate a new entry in the list */
-             if (!fn_p)
-               {
-                 /* Get space to record this member function */
-                 /* Note: alloca used; this will disappear on routine exit */
-                 fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
-                 fn_new->next = fn_list;
-                 fn_list = fn_new;
-
-                 /* Fill in the fields of the struct nextfield */
-
-                 /* Record the (unmangled) method name */
-                 fn_list->field.name = method_name;
-                 /* Initial space for overloaded methods */
-                 /* Note: xmalloc is used; this will persist after this routine exits */
-                 fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
-                 fn_list->field.length = 1;    /* Init # of overloaded instances */
-                 fn_list->num_fn_fields = 5;   /* # of entries for which space allocated */
-                 fn_p = fn_list;
-                 ix = 0;       /* array index for fn_field */
-                 /* Bump the total count of the distinctly named methods */
-                 n_fn_fields++;
-               }
-             else
-               /* Another overloaded instance of an already seen method name */
-               {
-                 if (++(fn_p->field.length) > fn_p->num_fn_fields)
-                   {
-                     /* Increase space allocated for overloaded instances */
-                     fn_p->field.fn_fields
-                       = (struct fn_field *) xrealloc (fn_p->field.fn_fields,
-                     (fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
-                     fn_p->num_fn_fields += 5;
-                   }
-                 ix = fn_p->field.length - 1;  /* array index for fn_field */
-               }
-
-             /* "physname" is intended to be the name of this overloaded instance. */
-             if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
-                 method_alias &&
-                 *method_alias)        /* not a null string */
-               fn_p->field.fn_fields[ix].physname = method_alias;
-             else
-               fn_p->field.fn_fields[ix].physname = method_name;
-             /* What's expected here is the function type */
-             /* But mark it as NULL if the method was incompletely processed
-                We'll fix this up later when the method is fully processed */
-             if (TYPE_INCOMPLETE (memtype))
-               {
-                 fn_p->field.fn_fields[ix].type = NULL;
-                 fn_p->field.fn_fields[ix].args = NULL;
-               }
-             else
-               {
-                 fn_p->field.fn_fields[ix].type = memtype;
-
-                 /* The argument list */
-                 fn_p->field.fn_fields[ix].type->type_specific.arg_types =
-                   (struct type **) obstack_alloc (&objfile->type_obstack,
-                          sizeof (struct type *) * (memtype->nfields + 1));
-                 for (i = 0; i < memtype->nfields; i++)
-                   fn_p->field.fn_fields[ix].type->type_specific.arg_types[i] = memtype->fields[i].type;
-                 /* void termination */
-                 fn_p->field.fn_fields[ix].type->type_specific.arg_types[memtype->nfields] = builtin_type_void;
-
-                 /* pai: It's not clear why this args field has to be set.  Perhaps
-                  * it should be eliminated entirely. */
-                 fn_p->field.fn_fields[ix].args =
-                   (struct type **) obstack_alloc (&objfile->type_obstack,
-                          sizeof (struct type *) * (memtype->nfields + 1));
-                 for (i = 0; i < memtype->nfields; i++)
-                   fn_p->field.fn_fields[ix].args[i] = memtype->fields[i].type;
-                 /* null-terminated, unlike arg_types above e */
-                 fn_p->field.fn_fields[ix].args[memtype->nfields] = NULL;
-               }
-             /* For virtual functions, fill in the voffset field with the
-              * virtual table offset. (This is just copied over from the
-              * SOM record; not sure if it is what GDB expects here...).
-              * But if the function is a static method, set it to 1.
-              * 
-              * Note that we have to add 1 because 1 indicates a static
-              * method, and 0 indicates a non-static, non-virtual method */
-
-             if (static_member)
-               fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
-             else
-               fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
-
-             /* Also fill in the fcontext field with the current
-              * class. (The latter isn't quite right: should be the baseclass
-              * that defines the virtual function... Note we do have
-              * a variable "baseclass" that we could stuff into the fcontext
-              * field, but "baseclass" isn't necessarily right either,
-              * since the virtual function could have been defined more
-              * than one level up).
-              */
-
-             if (vtbl_offset != 0)
-               fn_p->field.fn_fields[ix].fcontext = type;
-             else
-               fn_p->field.fn_fields[ix].fcontext = NULL;
-
-             /* Other random fields pertaining to this method */
-             fn_p->field.fn_fields[ix].is_const = const_member;
-             fn_p->field.fn_fields[ix].is_volatile = volatile_member;  /* ?? */
-             switch (fieldp->dgenfield.visibility)
-               {
-               case 1:
-                 fn_p->field.fn_fields[ix].is_protected = 1;
-                 fn_p->field.fn_fields[ix].is_private = 0;
-                 break;
-               case 2:
-                 fn_p->field.fn_fields[ix].is_protected = 0;
-                 fn_p->field.fn_fields[ix].is_private = 1;
-                 break;
-               default:        /* public */
-                 fn_p->field.fn_fields[ix].is_protected = 0;
-                 fn_p->field.fn_fields[ix].is_private = 0;
-               }
-             fn_p->field.fn_fields[ix].is_stub = 0;
-
-             /* HP aCC emits both MEMFUNC and FUNCTION entries for a method;
-                if the class points to the FUNCTION, there is usually separate
-                code for the method; but if we have a MEMFUNC, the method has
-                been inlined (and there is usually no FUNCTION entry)
-                FIXME Not sure if this test is accurate. pai/1997-08-22 */
-             if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
-                 (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
-               fn_p->field.fn_fields[ix].is_inlined = 1;
-             else
-               fn_p->field.fn_fields[ix].is_inlined = 0;
-
-             fn_p->field.fn_fields[ix].dummy = 0;
-
-             /* Bump the total count of the member functions */
-             n_fn_fields_total++;
-
-           }
-         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
-           {
-             /* This case is for static data members of classes */
-
-             /* pai:: FIXME -- check that "staticmem" bit is set */
-
-             /* Get space to record this static member */
-             new = (struct nextfield *) alloca (sizeof (struct nextfield));
-             new->next = list;
-             list = new;
-
-             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
-             FIELD_BITSIZE (list->field) = -1;         /* indicates static member */
-             SET_FIELD_PHYSNAME (list->field, 0);      /* initialize to empty */
-             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
-
-             FIELD_TYPE (list->field) = memtype;
-             list->attributes = 0;
-             switch (fieldp->dgenfield.visibility)
-               {
-               case 1:
-                 B_SET (&(list->attributes), ATTR_PROTECT);
-                 break;
-               case 2:
-                 B_SET (&(list->attributes), ATTR_PRIVATE);
-                 break;
-               }
-             nfields++;
-           }
-
-         else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
-           {
-             /* FIELDs follow GENFIELDs for fields of anonymous unions.
-                Code below is replicated from the case for FIELDs further
-                below, except that fieldp is replaced by fn_fieldp */
-             if (!fn_fieldp->dfield.a_union)
-               warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
-             /* Get space to record the next field/data-member. */
-             new = (struct nextfield *) alloca (sizeof (struct nextfield));
-             new->next = list;
-             list = new;
-
-             list->field.name = VT (objfile) + fn_fieldp->dfield.name;
-             FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
-             if (fn_fieldp->dfield.bitlength % 8)
-               list->field.bitsize = fn_fieldp->dfield.bitlength;
-             else
-               list->field.bitsize = 0;
-
-             memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
-             list->field.type = memtype;
-             list->attributes = 0;
-             switch (fn_fieldp->dfield.visibility)
-               {
-               case 1:
-                 B_SET (&(list->attributes), ATTR_PROTECT);
-                 break;
-               case 2:
-                 B_SET (&(list->attributes), ATTR_PRIVATE);
-                 break;
-               }
-             nfields++;
-           }
-         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
-           {
-             /* Field of anonymous union; union is not inside a class */
-             if (!fn_fieldp->dsvar.a_union)
-               warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
-             /* Get space to record the next field/data-member. */
-             new = (struct nextfield *) alloca (sizeof (struct nextfield));
-             new->next = list;
-             list = new;
-
-             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
-             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
-             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
-             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
-             list->field.type = memtype;
-             list->attributes = 0;
-             /* No info to set visibility -- always public */
-             nfields++;
-           }
-         else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
-           {
-             /* Field of anonymous union; union is not inside a class */
-             if (!fn_fieldp->ddvar.a_union)
-               warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
-             /* Get space to record the next field/data-member. */
-             new = (struct nextfield *) alloca (sizeof (struct nextfield));
-             new->next = list;
-             list = new;
-
-             list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
-             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
-             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
-             memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
-             list->field.type = memtype;
-             list->attributes = 0;
-             /* No info to set visibility -- always public */
-             nfields++;
-           }
-         else
-           {                   /* Not a method, nor a static data member, nor an anon union field */
-
-             /* This case is for miscellaneous type entries (local enums,
-                local function templates, etc.) that can be present
-                inside a class. */
-
-             /* Enums -- will be handled by other code that takes care
-                of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so
-                it's not clear we could have handled them here at all. */
-             /* FUNC_TEMPLATE: is handled by other code (?). */
-             /* MEMACCESS: modified access for inherited member. Not
-                sure what to do with this, ignoriing it at present. */
-
-             /* What other entries can appear following a GENFIELD which
-                we do not handle above?  (MODIFIER, VFUNC handled above.) */
-
-             if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
-                 (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
-                 (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
-               warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
-                        fn_fieldp->dblock.kind);
-           }
-         /* walk to the next FIELD or GENFIELD */
-         field = fieldp->dgenfield.nextfield;
-
-       }
-      else if (fieldp->dblock.kind == DNTT_TYPE_FIELD)
-       {
-
-         /* Ordinary structure/union/class field */
-         struct type *anon_union_type;
-
-         /* Get space to record the next field/data-member. */
-         new = (struct nextfield *) alloca (sizeof (struct nextfield));
-         new->next = list;
-         list = new;
-
-         list->field.name = VT (objfile) + fieldp->dfield.name;
-
-
-         /* A FIELD by itself (without a GENFIELD) can also be a static member */
-         if (fieldp->dfield.staticmem)
-           {
-             FIELD_BITPOS (list->field) = -1;
-             FIELD_BITSIZE (list->field) = 0;
-           }
-         else
-           /* Non-static data member */
-           {
-             FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
-             if (fieldp->dfield.bitlength % 8)
-               FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
-             else
-               FIELD_BITSIZE (list->field) = 0;
-           }
-
-         memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
-         FIELD_TYPE (list->field) = memtype;
-         list->attributes = 0;
-         switch (fieldp->dfield.visibility)
-           {
-           case 1:
-             B_SET (&(list->attributes), ATTR_PROTECT);
-             break;
-           case 2:
-             B_SET (&(list->attributes), ATTR_PRIVATE);
-             break;
-           }
-         nfields++;
-
-
-         /* Note 1: First, we have to check if the current field is an anonymous
-            union. If it is, then *its* fields are threaded along in the
-            nextfield chain. :-( This was supposed to help debuggers, but is
-            really just a nuisance since we deal with anonymous unions anyway by
-            checking that the name is null.  So anyway, we skip over the fields
-            of the anonymous union. pai/1997-08-22 */
-         /* Note 2: In addition, the bitoffsets for the fields of the anon union
-            are relative to the enclosing struct, *NOT* relative to the anon
-            union!  This is an even bigger nuisance -- we have to go in and munge
-            the anon union's type information appropriately. pai/1997-08-22 */
-
-         /* Both tasks noted above are done by a separate function.  This takes us
-            to the next FIELD or GENFIELD, skipping anon unions, and recursively
-            processing intermediate types. */
-         field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
-
-       }
-      else
-       {
-         /* neither field nor genfield ?? is this possible?? */
-         /* pai:: FIXME walk to the next -- how? */
-         warning ("Internal error: unexpected DNTT kind %d encountered as field of struct",
-                  fieldp->dblock.kind);
-         warning ("Skipping remaining fields of struct");
-         break;                /* get out of loop of fields */
-       }
-    }
-
-  /* If it's a template, read in the instantiation list */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-    {
-      ninstantiations = 0;
-      field = dn_bufp->dtemplate.expansions;
-      while (field.word && field.word != DNTTNIL)
-       {
-         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
-
-         /* The expansions or nextexp should point to a tagdef */
-         if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
-           break;
-
-         i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
-         i_new->next = i_list;
-         i_list = i_new;
-         i_list->t = hpread_type_lookup (field, objfile);
-         ninstantiations++;
-
-         /* And the "type" field of that should point to a class */
-         field = fieldp->dtag.type;
-         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
-         if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
-           break;
-
-         /* Get the next expansion */
-         field = fieldp->dclass.nextexp;
-       }
-    }
-  TYPE_NINSTANTIATIONS (type) = ninstantiations;
-  if (ninstantiations > 0)
-    TYPE_INSTANTIATIONS (type) = (struct type **)
-      obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations);
-  for (n = ninstantiations; i_list; i_list = i_list->next)
-    {
-      n -= 1;
-      TYPE_INSTANTIATION (type, n) = i_list->t;
-    }
-
-
-  /* Copy the field-list to GDB's symbol table */
-  TYPE_NFIELDS (type) = nfields;
-  TYPE_N_BASECLASSES (type) = n_base_classes;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
-  /* Copy the saved-up fields into the field vector.  */
-  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
-    {
-      n -= 1;
-      TYPE_FIELD (type, n) = tmp_list->field;
-    }
-
-  /* Copy the "function-field-list" (i.e., the list of member
-   * functions in the class) to GDB's symbol table 
-   */
-  TYPE_NFN_FIELDS (type) = n_fn_fields;
-  TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
-  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
-    obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
-  for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
-    {
-      n -= 1;
-      TYPE_FN_FIELDLIST (type, n) = fn_list->field;
-    }
-
-  /* pai:: FIXME -- perhaps each bitvector should be created individually */
-  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
-    {
-      n -= 1;
-      if (tmp_list->attributes)
-       {
-         need_bitvectors = 1;
-         break;
-       }
-    }
-
-  if (need_bitvectors)
-    {
-      /* pai:: this step probably redundant */
-      ALLOCATE_CPLUS_STRUCT_TYPE (type);
-
-      TYPE_FIELD_VIRTUAL_BITS (type) =
-       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
-
-      TYPE_FIELD_PRIVATE_BITS (type) =
-       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
-
-      TYPE_FIELD_PROTECTED_BITS (type) =
-       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
-
-      /* this field vector isn't actually used with HP aCC */
-      TYPE_FIELD_IGNORE_BITS (type) =
-       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
-
-      while (nfields-- > 0)
-       {
-         if (B_TST (&(list->attributes), ATTR_VIRTUAL))
-           SET_TYPE_FIELD_VIRTUAL (type, nfields);
-         if (B_TST (&(list->attributes), ATTR_PRIVATE))
-           SET_TYPE_FIELD_PRIVATE (type, nfields);
-         if (B_TST (&(list->attributes), ATTR_PROTECT))
-           SET_TYPE_FIELD_PROTECTED (type, nfields);
-
-         list = list->next;
-       }
-    }
-  else
-    {
-      TYPE_FIELD_VIRTUAL_BITS (type) = NULL;
-      TYPE_FIELD_PROTECTED_BITS (type) = NULL;
-      TYPE_FIELD_PRIVATE_BITS (type) = NULL;
-    }
-
-  if (has_vtable (type))
-    {
-      /* Allocate space for class runtime information */
-      TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info));
-      /* Set flag for vtable */
-      TYPE_VTABLE (type) = 1;
-      /* The first non-virtual base class with a vtable. */
-      TYPE_PRIMARY_BASE (type) = primary_base_class (type);
-      /* The virtual base list. */
-      TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type);
-    }
-  else
-    TYPE_RUNTIME_PTR (type) = NULL;
-
-  /* If this is a local type (C++ - declared inside a function), record file name & line # */
-  if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */ ))
-    {
-      TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
-      TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
-      strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
-      if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
-       TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
-      else
-       TYPE_LOCALTYPE_LINE (type) = 0;
-    }
-  else
-    TYPE_LOCALTYPE_PTR (type) = NULL;
-
-  /* Clear the global saying what template we are in the middle of processing */
-  current_template = NULL;
-
-  /* Fix up any cv-qualified versions of this type.  */
-  finish_cv_type (type);
-
-  return type;
-}
-
-/* Adjust the physnames for each static member of a struct
-   or class type to be something like "A::x"; then various
-   other pieces of code that do a lookup_symbol on the phyname
-   work correctly.
-   TYPE is a pointer to the struct/class type
-   NAME is a char * (string) which is the class/struct name
-   Void return */
-
-static void
-fix_static_member_physnames (struct type *type, char *class_name,
-                            struct objfile *objfile)
-{
-  int i;
-
-  /* We fix the member names only for classes or structs */
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
-    return;
-
-  for (i = 0; i < TYPE_NFIELDS (type); i++)
-    if (TYPE_FIELD_STATIC (type, i))
-      {
-       if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
-         return;               /* physnames are already set */
-
-       SET_FIELD_PHYSNAME (type->fields[i],
-                           obstack_alloc (&objfile->type_obstack,
-            strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
-       strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
-       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
-       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
-      }
-}
-
-/* Fix-up the type structure for a CLASS so that the type entry
- * for a method (previously marked with a null type in hpread_read_struct_type()
- * is set correctly to METHOD.
- * OBJFILE is as for other such functions. 
- * Void return. */
-
-static void
-fixup_class_method_type (struct type *class, struct type *method,
-                        struct objfile *objfile)
-{
-  int i, j, k;
-
-  if (!class || !method || !objfile)
-    return;
-
-  /* Only for types that have methods */
-  if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
-      (TYPE_CODE (class) != TYPE_CODE_UNION))
-    return;
-
-  /* Loop over all methods and find the one marked with a NULL type */
-  for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
-    for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
-      if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
-       {
-         /* Set the method type */
-         TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
-         /* The argument list */
-         (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types
-           = (struct type **) obstack_alloc (&objfile->type_obstack,
-                           sizeof (struct type *) * (method->nfields + 1));
-         for (k = 0; k < method->nfields; k++)
-           (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[k] = method->fields[k].type;
-         /* void termination */
-         (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[method->nfields] = builtin_type_void;
-
-         /* pai: It's not clear why this args field has to be set.  Perhaps
-          * it should be eliminated entirely. */
-         (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args
-           = (struct type **) obstack_alloc (&objfile->type_obstack,
-                           sizeof (struct type *) * (method->nfields + 1));
-         for (k = 0; k < method->nfields; k++)
-           (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[k] = method->fields[k].type;
-         /* null-terminated, unlike arg_types above */
-         (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[method->nfields] = NULL;
-
-         /* Break out of both loops -- only one method to fix up in a class */
-         goto finish;
-       }
-
-finish:
-  TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
-}
-
-
-/* If we're in the middle of processing a template, get a pointer
- * to the Nth template argument.
- * An example may make this clearer:
- *   template <class T1, class T2> class q2 {
- *     public:
- *     T1 a;
- *     T2 b;
- *   };
- * The type for "a" will be "first template arg" and
- * the type for "b" will be "second template arg".
- * We need to look these up in order to fill in "a" and "b"'s type.
- * This is called from hpread_type_lookup().
- */
-static struct type *
-hpread_get_nth_template_arg (struct objfile *objfile, int n)
-{
-  if (current_template != NULL)
-    return TYPE_TEMPLATE_ARG (current_template, n).type;
-  else
-    return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
-}
-
-/* Read in and internalize a TEMPL_ARG (template arg) symbol.  */
-
-static struct type *
-hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                           struct objfile *objfile, char *name)
-{
-  struct type *type;
-
-  /* See if it's something we've already deal with.  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
-    return type;
-
-  /* Nope.  Fill in the appropriate fields.  */
-  TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
-  TYPE_LENGTH (type) = 0;
-  TYPE_NFIELDS (type) = 0;
-  TYPE_NAME (type) = name;
-  return type;
-}
-
-/* Read in and internalize a set debug symbol.  */
-
-static struct type *
-hpread_read_set_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                     struct objfile *objfile)
-{
-  struct type *type;
-
-  /* See if it's something we've already deal with.  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_SET)
-    return type;
-
-  /* Nope.  Fill in the appropriate fields.  */
-  TYPE_CODE (type) = TYPE_CODE_SET;
-  TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
-  TYPE_NFIELDS (type) = 0;
-  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
-                                               objfile);
-  return type;
-}
-
-/* Read in and internalize an array debug symbol.  */
-
-static struct type *
-hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                       struct objfile *objfile)
-{
-  struct type *type;
-
-  /* Allocate an array type symbol.
-   * Why no check for already-read here, like in the other
-   * hpread_read_xxx_type routines?  Because it kept us 
-   * from properly determining the size of the array!  
-   */
-  type = hpread_alloc_type (hp_type, objfile);
-
-  TYPE_CODE (type) = TYPE_CODE_ARRAY;
-
-  /* Although the hp-symtab.h does not *require* this to be the case,
-   * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent.
-   * I.e., express both array-length and element-length in bits,
-   * or express both array-length and element-length in bytes.
-   */
-  if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
-       (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
-    {
-      warning ("error in hpread_array_type.\n");
-      return NULL;
-    }
-  else if (dn_bufp->darray.arraylength == 0x7fffffff)
-    {
-      /* The HP debug format represents char foo[]; as an array with
-       * length 0x7fffffff.  Internally GDB wants to represent this
-       *  as an array of length zero.  
-       */
-      TYPE_LENGTH (type) = 0;
-    }
-  else if (dn_bufp->darray.arrayisbytes)
-    TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
-  else                         /* arraylength is in bits */
-    TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
-
-  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
-                                               objfile);
-
-  /* The one "field" is used to store the subscript type */
-  /* Since C and C++ multi-dimensional arrays are simply represented
-   * as: array of array of ..., we only need one subscript-type
-   * per array. This subscript type is typically a subrange of integer.
-   * If this gets extended to support languages like Pascal, then
-   * we need to fix this to represent multi-dimensional arrays properly.
-   */
-  TYPE_NFIELDS (type) = 1;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack, sizeof (struct field));
-  TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
-                                                 objfile);
-  return type;
-}
-
-/* Read in and internalize a subrange debug symbol.  */
-static struct type *
-hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                          struct objfile *objfile)
-{
-  struct type *type;
-
-  /* Is it something we've already dealt with.  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if (TYPE_CODE (type) == TYPE_CODE_RANGE)
-    return type;
-
-  /* Nope, internalize it.  */
-  TYPE_CODE (type) = TYPE_CODE_RANGE;
-  TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
-  TYPE_NFIELDS (type) = 2;
-  TYPE_FIELDS (type)
-    = (struct field *) obstack_alloc (&objfile->type_obstack,
-                                     2 * sizeof (struct field));
-
-  if (dn_bufp->dsubr.dyn_low)
-    TYPE_FIELD_BITPOS (type, 0) = 0;
-  else
-    TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
-
-  if (dn_bufp->dsubr.dyn_high)
-    TYPE_FIELD_BITPOS (type, 1) = -1;
-  else
-    TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
-  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
-                                               objfile);
-  return type;
-}
-
-/* struct type * hpread_type_lookup(hp_type, objfile)
- *   Arguments:
- *     hp_type: A pointer into the DNTT specifying what type we
- *              are about to "look up"., or else [for fundamental types
- *              like int, float, ...] an "immediate" structure describing
- *              the type.
- *     objfile: ?
- *   Return value: A pointer to a "struct type" (representation of a
- *                 type in GDB's internal symbol table - see gdbtypes.h)
- *   Routine description:
- *     There are a variety of places when scanning the DNTT when we
- *     need to interpret a "type" field. The simplest and most basic 
- *     example is when we're processing the symbol table record
- *     for a data symbol (a SVAR or DVAR record). That has
- *     a "type" field specifying the type of the data symbol. That
- *     "type" field is either an "immediate" type specification (for the
- *     fundamental types) or a DNTT pointer (for more complicated types). 
- *     For the more complicated types, we may or may not have already
- *     processed the pointed-to type. (Multiple data symbols can of course
- *     share the same type).
- *     The job of hpread_type_lookup() is to process this "type" field.
- *     Most of the real work is done in subroutines. Here we interpret
- *     the immediate flag. If not immediate, chase the DNTT pointer to
- *     find our way to the SOM record describing the type, switch on
- *     the SOM kind, and then call an appropriate subroutine depending
- *     on what kind of type we are constructing. (e.g., an array type,
- *     a struct/class type, etc).
- */
-static struct type *
-hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
-{
-  union dnttentry *dn_bufp;
-  struct type *tmp_type;
-
-  /* First see if it's a simple builtin type.  */
-  if (hp_type.dntti.immediate)
-    {
-      /* If this is a template argument, the argument number is
-       * encoded in the bitlength. All other cases, just return
-       * GDB's representation of this fundamental type.
-       */
-      if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
-       return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength);
-      else
-       return lookup_fundamental_type (objfile,
-                                       hpread_type_translate (hp_type));
-    }
-
-  /* Not a builtin type.  We'll have to read it in.  */
-  if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
-    dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
-  else
-    /* This is a fancy way of returning NULL */
-    return lookup_fundamental_type (objfile, FT_VOID);
-
-  switch (dn_bufp->dblock.kind)
-    {
-    case DNTT_TYPE_SRCFILE:
-    case DNTT_TYPE_MODULE:
-    case DNTT_TYPE_ENTRY:
-    case DNTT_TYPE_BEGIN:
-    case DNTT_TYPE_END:
-    case DNTT_TYPE_IMPORT:
-    case DNTT_TYPE_LABEL:
-    case DNTT_TYPE_FPARAM:
-    case DNTT_TYPE_SVAR:
-    case DNTT_TYPE_DVAR:
-    case DNTT_TYPE_CONST:
-    case DNTT_TYPE_MEMENUM:
-    case DNTT_TYPE_VARIANT:
-    case DNTT_TYPE_FILE:
-    case DNTT_TYPE_WITH:
-    case DNTT_TYPE_COMMON:
-    case DNTT_TYPE_COBSTRUCT:
-    case DNTT_TYPE_XREF:
-    case DNTT_TYPE_SA:
-    case DNTT_TYPE_MACRO:
-    case DNTT_TYPE_BLOCKDATA:
-    case DNTT_TYPE_CLASS_SCOPE:
-    case DNTT_TYPE_MEMACCESS:
-    case DNTT_TYPE_INHERITANCE:
-    case DNTT_TYPE_OBJECT_ID:
-    case DNTT_TYPE_FRIEND_CLASS:
-    case DNTT_TYPE_FRIEND_FUNC:
-      /* These are not types - something went wrong.  */
-      /* This is a fancy way of returning NULL */
-      return lookup_fundamental_type (objfile, FT_VOID);
-
-    case DNTT_TYPE_FUNCTION:
-      /* We wind up here when dealing with class member functions 
-       * (called from hpread_read_struct_type(), i.e. when processing
-       * the class definition itself).
-       */
-      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_DOC_FUNCTION:
-      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_TYPEDEF:
-      {
-       /* A typedef - chase it down by making a recursive call */
-       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
-                                                     objfile);
-
-       /* The following came from the base hpread.c that we inherited.
-        * It is WRONG so I have commented it out. - RT
-        *...
-
-        char *suffix;
-        suffix = VT (objfile) + dn_bufp->dtype.name;
-        TYPE_NAME (structtype) = suffix;
-
-        * ... further explanation ....
-        *
-        * What we have here is a typedef pointing to a typedef.
-        * E.g.,
-        * typedef int foo;
-        * typedef foo fum;
-        *
-        * What we desire to build is (these are pictures
-        * of "struct type"'s): 
-        *
-        *  +---------+     +----------+     +------------+
-        *  | typedef |     | typedef  |     | fund. type |
-        *  |     type| ->  |      type| ->  |            |
-        *  | "fum"   |     | "foo"    |     | "int"      |
-        *  +---------+     +----------+     +------------+
-        *
-        * What this commented-out code is doing is smashing the
-        * name of pointed-to-type to be the same as the pointed-from
-        * type. So we wind up with something like:
-        *
-        *  +---------+     +----------+     +------------+
-        *  | typedef |     | typedef  |     | fund. type |
-        *  |     type| ->  |      type| ->  |            |
-        *  | "fum"   |     | "fum"    |     | "fum"      |
-        *  +---------+     +----------+     +------------+
-        * 
-        */
-
-       return structtype;
-      }
-
-    case DNTT_TYPE_TAGDEF:
-      {
-       /* Just a little different from above.  We have to tack on
-        * an identifier of some kind (struct, union, enum, class, etc).  
-        */
-       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
-                                                     objfile);
-       char *prefix, *suffix;
-       suffix = VT (objfile) + dn_bufp->dtype.name;
-
-       /* Lookup the next type in the list.  It should be a structure,
-        * union, class, enum, or template type.  
-        * We will need to attach that to our name.  
-        */
-       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
-         dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
-       else
-         {
-           complain (&hpread_type_lookup_complaint);
-           return NULL;
-         }
-
-       if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
-         {
-           prefix = "struct ";
-         }
-       else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
-         {
-           prefix = "union ";
-         }
-       else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
-         {
-           /* Further field for CLASS saying how it was really declared */
-           /* 0==class, 1==union, 2==struct */
-           if (dn_bufp->dclass.class_decl == 0)
-             prefix = "class ";
-           else if (dn_bufp->dclass.class_decl == 1)
-             prefix = "union ";
-           else if (dn_bufp->dclass.class_decl == 2)
-             prefix = "struct ";
-           else
-             prefix = "";
-         }
-       else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM)
-         {
-           prefix = "enum ";
-         }
-       else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-         {
-           prefix = "template ";
-         }
-       else
-         {
-           prefix = "";
-         }
-
-       /* Build the correct name.  */
-       structtype->name
-         = (char *) obstack_alloc (&objfile->type_obstack,
-                                   strlen (prefix) + strlen (suffix) + 1);
-       TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
-       TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
-       TYPE_TAG_NAME (structtype) = suffix;
-
-       /* For classes/structs, we have to set the static member "physnames"
-          to point to strings like "Class::Member" */
-       if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
-         fix_static_member_physnames (structtype, suffix, objfile);
-
-       return structtype;
-      }
-
-    case DNTT_TYPE_POINTER:
-      /* Pointer type - call a routine in gdbtypes.c that constructs
-       * the appropriate GDB type.
-       */
-      return make_pointer_type (
-                                hpread_type_lookup (dn_bufp->dptr.pointsto,
-                                                    objfile),
-                                NULL);
-
-    case DNTT_TYPE_REFERENCE:
-      /* C++ reference type - call a routine in gdbtypes.c that constructs
-       * the appropriate GDB type.
-       */
-      return make_reference_type (
-                          hpread_type_lookup (dn_bufp->dreference.pointsto,
-                                              objfile),
-                                  NULL);
-
-    case DNTT_TYPE_ENUM:
-      return hpread_read_enum_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_SET:
-      return hpread_read_set_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_SUBRANGE:
-      return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_ARRAY:
-      return hpread_read_array_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_STRUCT:
-    case DNTT_TYPE_UNION:
-      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_FIELD:
-      return hpread_type_lookup (dn_bufp->dfield.type, objfile);
-
-    case DNTT_TYPE_FUNCTYPE:
-      /* Here we want to read the function SOMs and return a 
-       * type for it. We get here, for instance, when processing
-       * pointer-to-function type.
-       */
-      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_PTRMEM:
-      /* Declares a C++ pointer-to-data-member type. 
-       * The "pointsto" field defines the class,
-       * while the "memtype" field defines the pointed-to-type.
-       */
-      {
-       struct type *ptrmemtype;
-       struct type *class_type;
-       struct type *memtype;
-       memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
-                                     objfile),
-         class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
-                                          objfile),
-         ptrmemtype = alloc_type (objfile);
-       smash_to_member_type (ptrmemtype, class_type, memtype);
-       return make_pointer_type (ptrmemtype, NULL);
-      }
-      break;
-
-    case DNTT_TYPE_PTRMEMFUNC:
-      /* Defines a C++ pointer-to-function-member type. 
-       * The "pointsto" field defines the class,
-       * while the "memtype" field defines the pointed-to-type.
-       */
-      {
-       struct type *ptrmemtype;
-       struct type *class_type;
-       struct type *functype;
-       struct type *retvaltype;
-       int nargs;
-       int i;
-       struct type **args_type;
-       class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
-                                        objfile);
-       functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
-                                      objfile);
-       retvaltype = TYPE_TARGET_TYPE (functype);
-       nargs = TYPE_NFIELDS (functype);
-       args_type = (struct type **) xmalloc ((nargs + 1) * sizeof (struct type *));
-       for (i = 0; i < nargs; i++)
-         {
-           args_type[i] = TYPE_FIELD_TYPE (functype, i);
-         }
-       args_type[nargs] = NULL;
-       ptrmemtype = alloc_type (objfile);
-       smash_to_method_type (ptrmemtype, class_type, retvaltype, args_type);
-       return make_pointer_type (ptrmemtype, NULL);
-      }
-      break;
-
-    case DNTT_TYPE_CLASS:
-      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
-
-    case DNTT_TYPE_GENFIELD:
-      /* Chase pointer from GENFIELD to FIELD, and make recursive
-       * call on that.
-       */
-      return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
-
-    case DNTT_TYPE_VFUNC:
-      /* C++ virtual function.
-       * We get here in the course of processing a class type which
-       * contains virtual functions. Just go through another level
-       * of indirection to get to the pointed-to function SOM.
-       */
-      return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
-
-    case DNTT_TYPE_MODIFIER:
-      /* Check the modifiers and then just make a recursive call on
-       * the "type" pointed to by the modifier DNTT.
-       * 
-       * pai:: FIXME -- do we ever want to handle "m_duplicate" and
-       * "m_void" modifiers?  Is static_flag really needed here?
-       * (m_static used for methods of classes, elsewhere).
-       */
-      tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
-                              dn_bufp->dmodifier.m_volatile,
-                     hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
-                              0);
-      return tmp_type;
-
-
-    case DNTT_TYPE_MEMFUNC:
-      /* Member function. Treat like a function.
-       * I think we get here in the course of processing a 
-       * pointer-to-member-function type...
-       */
-      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_DOC_MEMFUNC:
-      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_TEMPLATE:
-      /* Template - sort of the header for a template definition,
-       * which like a class, points to a member list and also points
-       * to a TEMPLATE_ARG list of type-arguments.
-       */
-      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
-
-    case DNTT_TYPE_TEMPLATE_ARG:
-      {
-       char *name;
-       /* The TEMPLATE record points to an argument list of
-        * TEMPLATE_ARG records, each of which describes one
-        * of the type-arguments. 
-        */
-       name = VT (objfile) + dn_bufp->dtempl_arg.name;
-       return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
-      }
-
-    case DNTT_TYPE_FUNC_TEMPLATE:
-      /* We wind up here when processing a TEMPLATE type, 
-       * if the template has member function(s).
-       * Treat it like a FUNCTION.
-       */
-      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
-
-    case DNTT_TYPE_LINK:
-      /* The LINK record is used to link up templates with instantiations.
-       * There is no type associated with the LINK record per se.
-       */
-      return lookup_fundamental_type (objfile, FT_VOID);
-
-      /* Also not yet handled... */
-      /* case DNTT_TYPE_DYN_ARRAY_DESC: */
-      /* case DNTT_TYPE_DESC_SUBRANGE: */
-      /* case DNTT_TYPE_BEGIN_EXT: */
-      /* case DNTT_TYPE_INLN: */
-      /* case DNTT_TYPE_INLN_LIST: */
-      /* case DNTT_TYPE_ALIAS: */
-    default:
-      /* A fancy way of returning NULL */
-      return lookup_fundamental_type (objfile, FT_VOID);
-    }
-}
-
-static sltpointer
-hpread_record_lines (struct subfile *subfile, sltpointer s_idx,
-                    sltpointer e_idx, struct objfile *objfile,
-                    CORE_ADDR offset)
-{
-  union sltentry *sl_bufp;
-
-  while (s_idx <= e_idx)
-    {
-      sl_bufp = hpread_get_slt (s_idx, objfile);
-      /* Only record "normal" entries in the SLT.  */
-      if (sl_bufp->snorm.sltdesc == SLT_NORMAL
-         || sl_bufp->snorm.sltdesc == SLT_EXIT)
-       record_line (subfile, sl_bufp->snorm.line,
-                    sl_bufp->snorm.address + offset);
-      else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
-       record_line (subfile, sl_bufp->snormoff.line,
-                    sl_bufp->snormoff.address + offset);
-      s_idx++;
-    }
-  return e_idx;
-}
-
-/* Given a function "f" which is a member of a class, find
- * the classname that it is a member of. Used to construct
- * the name (e.g., "c::f") which GDB will put in the
- * "demangled name" field of the function's symbol.
- * Called from hpread_process_one_debug_symbol()
- * If "f" is not a member function, return NULL.
- */
-char *
-class_of (struct type *functype)
-{
-  struct type *first_param_type;
-  char *first_param_name;
-  struct type *pointed_to_type;
-  char *class_name;
-
-  /* Check that the function has a first argument "this",
-   * and that "this" is a pointer to a class. If not,
-   * functype is not a member function, so return NULL.
-   */
-  if (TYPE_NFIELDS (functype) == 0)
-    return NULL;
-  first_param_name = TYPE_FIELD_NAME (functype, 0);
-  if (first_param_name == NULL)
-    return NULL;               /* paranoia */
-  if (strcmp (first_param_name, "this"))
-    return NULL;
-  first_param_type = TYPE_FIELD_TYPE (functype, 0);
-  if (first_param_type == NULL)
-    return NULL;               /* paranoia */
-  if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR)
-    return NULL;
-
-  /* Get the thing that "this" points to, check that
-   * it's a class, and get its class name.
-   */
-  pointed_to_type = TYPE_TARGET_TYPE (first_param_type);
-  if (pointed_to_type == NULL)
-    return NULL;               /* paranoia */
-  if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS)
-    return NULL;
-  class_name = TYPE_NAME (pointed_to_type);
-  if (class_name == NULL)
-    return NULL;               /* paranoia */
-
-  /* The class name may be of the form "class c", in which case
-   * we want to strip off the leading "class ".
-   */
-  if (strncmp (class_name, "class ", 6) == 0)
-    class_name += 6;
-
-  return class_name;
-}
-
-/* Internalize one native debug symbol. 
- * Called in a loop from hpread_expand_symtab(). 
- * Arguments:
- *   dn_bufp: 
- *   name: 
- *   section_offsets:
- *   objfile:
- *   text_offset: 
- *   text_size: 
- *   filename: 
- *   index:             Index of this symbol
- *   at_module_boundary_p Pointer to boolean flag to control caller's loop.
- */
-
-static void
-hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
-                                struct section_offsets *section_offsets,
-                                struct objfile *objfile, CORE_ADDR text_offset,
-                                int text_size, char *filename, int index,
-                                int *at_module_boundary_p)
-{
-  unsigned long desc;
-  int type;
-  CORE_ADDR valu;
-  int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
-  int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
-  union dnttentry *dn_temp;
-  dnttpointer hp_type;
-  struct symbol *sym;
-  struct context_stack *new;
-  char *class_scope_name;
-
-  /* Allocate one GDB debug symbol and fill in some default values. */
-  sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
-                                        sizeof (struct symbol));
-  memset (sym, 0, sizeof (struct symbol));
-  SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
-  SYMBOL_LANGUAGE (sym) = language_auto;
-  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-  SYMBOL_LINE (sym) = 0;
-  SYMBOL_VALUE (sym) = 0;
-  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-
-  /* Just a trick in case the SOM debug symbol is a type definition.
-   * There are routines that are set up to build a GDB type symbol, given
-   * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type".
-   * This allows us to call those same routines.
-   */
-  hp_type.dnttp.extension = 1;
-  hp_type.dnttp.immediate = 0;
-  hp_type.dnttp.global = 0;
-  hp_type.dnttp.index = index;
-
-  /* This "type" is the type of SOM record.
-   * Switch on SOM type.
-   */
-  type = dn_bufp->dblock.kind;
-  switch (type)
-    {
-    case DNTT_TYPE_SRCFILE:
-      /* This type of symbol indicates from which source file or
-       * include file any following data comes. It may indicate:
-       *
-       * o   The start of an entirely new source file (and thus
-       *     a new module)
-       *
-       * o   The start of a different source file due to #include
-       *
-       * o   The end of an include file and the return to the original
-       *     file. Thus if "foo.c" includes "bar.h", we see first
-       *     a SRCFILE for foo.c, then one for bar.h, and then one for
-       *     foo.c again.
-       *
-       * If it indicates the start of a new module then we must
-       * finish the symbol table of the previous module 
-       * (if any) and start accumulating a new symbol table.  
-       */
-
-      valu = text_offset;
-      if (!last_source_file)
-       {
-         /*
-          * A note on "last_source_file": this is a char* pointing
-          * to the actual file name.  "start_symtab" sets it,
-          * "end_symtab" clears it.
-          *
-          * So if "last_source_file" is NULL, then either this is
-          * the first record we are looking at, or a previous call
-          * to "end_symtab()" was made to close out the previous
-          * module.  Since we're now quitting the scan loop when we
-          * see a MODULE END record, we should never get here, except
-          * in the case that we're not using the quick look-up tables
-          * and have to use the old system as a fall-back.
-          */
-         start_symtab (name, NULL, valu);
-         record_debugformat ("HP");
-         SL_INDEX (objfile) = dn_bufp->dsfile.address;
-       }
-
-      else
-       {
-         /* Either a new include file, or a SRCFILE record
-          * saying we are back in the main source (or out of
-          * a nested include file) again.
-          */
-         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                                   SL_INDEX (objfile),
-                                                   dn_bufp->dsfile.address,
-                                                   objfile, offset);
-       }
-
-      /* A note on "start_subfile".  This routine will check
-       * the name we pass it and look for an existing subfile
-       * of that name.  There's thus only one sub-file for the
-       * actual source (e.g. for "foo.c" in foo.c), despite the
-       * fact that we'll see lots of SRCFILE entries for foo.c
-       * inside foo.c.
-       */
-      start_subfile (name, NULL);
-      break;
-
-    case DNTT_TYPE_MODULE:
-      /*
-       * We no longer ignore DNTT_TYPE_MODULE symbols.  The module 
-       * represents the meaningful semantic structure of a compilation
-       * unit.  We expect to start the psymtab-to-symtab expansion
-       * looking at a MODULE entry, and to end it at the corresponding
-       * END MODULE entry.
-       *
-       *--Begin outdated comments
-       * 
-       * This record signifies the start of a new source module
-       * In C/C++ there is no explicit "module" construct in the language,
-       * but each compilation unit is implicitly a module and they
-       * do emit the DNTT_TYPE_MODULE records.
-       * The end of the module is marked by a matching DNTT_TYPE_END record.
-       *
-       * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record 
-       * is it notices the DNTT_TYPE_END record for the previous 
-       * module (see comments under DNTT_TYPE_END case), and then treats
-       * the next DNTT_TYPE_SRCFILE record as if it were the module-start record.
-       * (i.e., it makes a start_symtab() call).
-       * This scheme seems a little convoluted, but I'll leave it 
-       * alone on the principle "if it ain't broke don't fix
-       * it". (RT).
-       *
-       *-- End outdated comments
-       */
-
-      valu = text_offset;
-      if (!last_source_file)
-       {
-         /* Start of a new module. We know this because "last_source_file"
-          * is NULL, which can only happen the first time or if we just 
-          * made a call to end_symtab() to close out the previous module.
-          */
-         start_symtab (name, NULL, valu);
-         SL_INDEX (objfile) = dn_bufp->dmodule.address;
-       }
-      else
-       {
-         /* This really shouldn't happen if we're using the quick
-          * look-up tables, as it would mean we'd scanned past an
-          * END MODULE entry.  But if we're not using the tables,
-          * we started the module on the SRCFILE entry, so it's ok.
-          * For now, accept this.
-          */
-         /* warning( "Error expanding psymtab, missed module end, found entry for %s",
-          *           name );
-          */
-         *at_module_boundary_p = -1;
-       }
-
-      start_subfile (name, NULL);
-      break;
-
-    case DNTT_TYPE_FUNCTION:
-    case DNTT_TYPE_ENTRY:
-      /* A function or secondary entry point.  */
-      valu = dn_bufp->dfunc.lowaddr + offset;
-
-      /* Record lines up to this point. */
-      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                               SL_INDEX (objfile),
-                                               dn_bufp->dfunc.address,
-                                               objfile, offset);
-
-      WITHIN_FUNCTION (objfile) = 1;
-      CURRENT_FUNCTION_VALUE (objfile) = valu;
-
-      /* Stack must be empty now.  */
-      if (context_stack_depth != 0)
-       complain (&lbrac_unmatched_complaint, (char *) symnum);
-      new = push_context (0, valu);
-
-      /* Built a type for the function. This includes processing
-       * the symbol records for the function parameters.
-       */
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
-      SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
-
-      /* The "SYMBOL_NAME" field is expected to be the mangled name
-       * (if any), which we get from the "alias" field of the SOM record
-       * if that exists.
-       */
-      if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
-         dn_bufp->dfunc.alias &&       /* has an alias */
-         *(char *) (VT (objfile) + dn_bufp->dfunc.alias))      /* not a null string */
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
-      else
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
-
-      /* Special hack to get around HP compilers' insistence on
-       * reporting "main" as "_MAIN_" for C/C++ */
-      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
-         (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
-
-      /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to
-       * be the demangled name.
-       */
-      if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
-       {
-         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
-          * calling the demangler in libiberty (cplus_demangle()) to
-          * do the job. This generally does the job, even though
-          * it's intended for the GNU compiler and not the aCC compiler
-          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
-          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
-          * Generally, we don't want params when we display
-          * a demangled name, but when I took out the DMGL_PARAMS,
-          * some things broke, so I'm leaving it in here, and
-          * working around the issue in stack.c. - RT
-          */
-         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
-         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
-             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
-           {
-
-             /* Well, the symbol name is mangled, but the
-              * demangler in libiberty failed so the demangled
-              * field is still NULL. Try to
-              * do the job ourselves based on the "name" field
-              * in the SOM record. A complication here is that
-              * the name field contains only the function name
-              * (like "f"), whereas we want the class qualification
-              * (as in "c::f"). Try to reconstruct that.
-              */
-             char *basename;
-             char *classname;
-             char *dem_name;
-             basename = VT (objfile) + dn_bufp->dfunc.name;
-             classname = class_of (SYMBOL_TYPE (sym));
-             if (classname)
-               {
-                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
-                 strcpy (dem_name, classname);
-                 strcat (dem_name, "::");
-                 strcat (dem_name, basename);
-                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
-                 SYMBOL_LANGUAGE (sym) = language_cplus;
-               }
-           }
-       }
-
-      /* Add the function symbol to the list of symbols in this blockvector */
-      if (dn_bufp->dfunc.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
-      new->name = sym;
-
-      /* Search forward to the next BEGIN and also read
-       * in the line info up to that point. 
-       * Not sure why this is needed.
-       * In HP FORTRAN this code is harmful since there   
-       * may not be a BEGIN after the FUNCTION.
-       * So I made it C/C++ specific. - RT
-       */
-      if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
-         dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
-       {
-         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
-           {
-             dn_bufp = hpread_get_lntt (++index, objfile);
-             if (dn_bufp->dblock.extension)
-               continue;
-           }
-         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                                   SL_INDEX (objfile),
-                                                   dn_bufp->dbegin.address,
-                                                   objfile, offset);
-         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
-       }
-      record_line (current_subfile, SYMBOL_LINE (sym), valu);
-      break;
-
-    case DNTT_TYPE_DOC_FUNCTION:
-      valu = dn_bufp->ddocfunc.lowaddr + offset;
-
-      /* Record lines up to this point. */
-      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                               SL_INDEX (objfile),
-                                               dn_bufp->ddocfunc.address,
-                                               objfile, offset);
-
-      WITHIN_FUNCTION (objfile) = 1;
-      CURRENT_FUNCTION_VALUE (objfile) = valu;
-      /* Stack must be empty now.  */
-      if (context_stack_depth != 0)
-       complain (&lbrac_unmatched_complaint, (char *) symnum);
-      new = push_context (0, valu);
-
-      /* Built a type for the function. This includes processing
-       * the symbol records for the function parameters.
-       */
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
-      SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
-
-      /* The "SYMBOL_NAME" field is expected to be the mangled name
-       * (if any), which we get from the "alias" field of the SOM record
-       * if that exists.
-       */
-      if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
-         dn_bufp->ddocfunc.alias &&    /* has an alias */
-         *(char *) (VT (objfile) + dn_bufp->ddocfunc.alias))   /* not a null string */
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
-      else
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
-
-      /* Special hack to get around HP compilers' insistence on
-       * reporting "main" as "_MAIN_" for C/C++ */
-      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
-         (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
-       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
-
-      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
-       {
-
-         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
-          * calling the demangler in libiberty (cplus_demangle()) to
-          * do the job. This generally does the job, even though
-          * it's intended for the GNU compiler and not the aCC compiler
-          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
-          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
-          * Generally, we don't want params when we display
-          * a demangled name, but when I took out the DMGL_PARAMS,
-          * some things broke, so I'm leaving it in here, and
-          * working around the issue in stack.c. - RT 
-          */
-         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
-
-         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
-             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
-           {
-
-             /* Well, the symbol name is mangled, but the
-              * demangler in libiberty failed so the demangled
-              * field is still NULL. Try to
-              * do the job ourselves based on the "name" field
-              * in the SOM record. A complication here is that
-              * the name field contains only the function name
-              * (like "f"), whereas we want the class qualification
-              * (as in "c::f"). Try to reconstruct that.
-              */
-             char *basename;
-             char *classname;
-             char *dem_name;
-             basename = VT (objfile) + dn_bufp->ddocfunc.name;
-             classname = class_of (SYMBOL_TYPE (sym));
-             if (classname)
-               {
-                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
-                 strcpy (dem_name, classname);
-                 strcat (dem_name, "::");
-                 strcat (dem_name, basename);
-                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
-                 SYMBOL_LANGUAGE (sym) = language_cplus;
-               }
-           }
-       }
-
-      /* Add the function symbol to the list of symbols in this blockvector */
-      if (dn_bufp->ddocfunc.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
-      new->name = sym;
-
-      /* Search forward to the next BEGIN and also read
-       * in the line info up to that point. 
-       * Not sure why this is needed.
-       * In HP FORTRAN this code is harmful since there   
-       * may not be a BEGIN after the FUNCTION.
-       * So I made it C/C++ specific. - RT
-       */
-      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
-         dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
-       {
-         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
-           {
-             dn_bufp = hpread_get_lntt (++index, objfile);
-             if (dn_bufp->dblock.extension)
-               continue;
-           }
-         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                                   SL_INDEX (objfile),
-                                                   dn_bufp->dbegin.address,
-                                                   objfile, offset);
-         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
-       }
-      record_line (current_subfile, SYMBOL_LINE (sym), valu);
-      break;
-
-    case DNTT_TYPE_BEGIN:
-      /* Begin a new scope. */
-      if (context_stack_depth == 1 /* this means we're at function level */  &&
-         context_stack[0].name != NULL /* this means it's a function */  &&
-         context_stack[0].depth == 0   /* this means it's the first BEGIN 
-                                          we've seen after the FUNCTION */
-       )
-       {
-         /* This is the first BEGIN after a FUNCTION.
-          * We ignore this one, since HP compilers always insert
-          * at least one BEGIN, i.e. it's:
-          * 
-          *     FUNCTION
-          *     argument symbols
-          *     BEGIN
-          *     local symbols
-          *        (possibly nested BEGIN ... END's if there are inner { } blocks)
-          *     END
-          *     END
-          *
-          * By ignoring this first BEGIN, the local symbols get treated
-          * as belonging to the function scope, and "print func::local_sym"
-          * works (which is what we want).
-          */
-
-         /* All we do here is increase the depth count associated with
-          * the FUNCTION entry in the context stack. This ensures that
-          * the next BEGIN we see (if any), representing a real nested { }
-          * block, will get processed.
-          */
-
-         context_stack[0].depth++;
-
-       }
-      else
-       {
-
-         /* Record lines up to this SLT pointer. */
-         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                                   SL_INDEX (objfile),
-                                                   dn_bufp->dbegin.address,
-                                                   objfile, offset);
-         /* Calculate start address of new scope */
-         valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
-         valu += offset;       /* Relocate for dynamic loading */
-         /* We use the scope start DNTT index as nesting depth identifier! */
-         desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
-         new = push_context (desc, valu);
-       }
-      break;
-
-    case DNTT_TYPE_END:
-      /* End a scope.  */
-
-      /* Valid end kinds are:
-       *  MODULE
-       *  FUNCTION
-       *  WITH
-       *  COMMON
-       *  BEGIN
-       *  CLASS_SCOPE
-       */
-
-      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                               SL_INDEX (objfile),
-                                               dn_bufp->dend.address,
-                                               objfile, offset);
-      switch (dn_bufp->dend.endkind)
-       {
-       case DNTT_TYPE_MODULE:
-         /* Ending a module ends the symbol table for that module.  
-          * Calling end_symtab() has the side effect of clearing the
-          * last_source_file pointer, which in turn signals 
-          * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE
-          * record as a module-begin.
-          */
-         valu = text_offset + text_size + offset;
-
-         /* Tell our caller that we're done with expanding the
-          * debug information for a module.
-          */
-         *at_module_boundary_p = 1;
-
-         /* Don't do this, as our caller will do it!
-
-          *      (void) end_symtab (valu, objfile, 0);
-          */
-         break;
-
-       case DNTT_TYPE_FUNCTION:
-         /* Ending a function, well, ends the function's scope.  */
-         dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
-                                    objfile);
-         valu = dn_temp->dfunc.hiaddr + offset;
-         /* Insert func params into local list */
-         merge_symbol_lists (&param_symbols, &local_symbols);
-         new = pop_context ();
-         /* Make a block for the local symbols within.  */
-         finish_block (new->name, &local_symbols, new->old_blocks,
-                       new->start_addr, valu, objfile);
-         WITHIN_FUNCTION (objfile) = 0;        /* This may have to change for Pascal */
-         local_symbols = new->locals;
-         param_symbols = new->params;
-         break;
-
-       case DNTT_TYPE_BEGIN:
-         if (context_stack_depth == 1 &&
-             context_stack[0].name != NULL &&
-             context_stack[0].depth == 1)
-           {
-             /* This is the END corresponding to the
-              * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above.
-              */
-             context_stack[0].depth--;
-           }
-         else
-           {
-             /* Ending a local scope.  */
-             valu = hpread_get_location (dn_bufp->dend.address, objfile);
-             /* Why in the hell is this needed?  */
-             valu += offset + 9;       /* Relocate for dynamic loading */
-             new = pop_context ();
-             desc = dn_bufp->dend.beginscope.dnttp.index;
-             if (desc != new->depth)
-               complain (&lbrac_mismatch_complaint, (char *) symnum);
-
-             /* Make a block for the local symbols within.  */
-             finish_block (new->name, &local_symbols, new->old_blocks,
-                           new->start_addr, valu, objfile);
-             local_symbols = new->locals;
-             param_symbols = new->params;
-           }
-         break;
-
-       case DNTT_TYPE_WITH:
-         /* Since we ignore the DNTT_TYPE_WITH that starts the scope,
-          * we can ignore the DNTT_TYPE_END that ends it.
-          */
-         break;
-
-       case DNTT_TYPE_COMMON:
-         /* End a FORTRAN common block. We don't currently handle these */
-         complain (&hpread_unhandled_end_common_complaint);
-         break;
-
-       case DNTT_TYPE_CLASS_SCOPE:
-
-         /* pai: FIXME Not handling nested classes for now -- must
-            * maintain a stack */
-         class_scope_name = NULL;
-
-#if 0
-         /* End a class scope */
-         valu = hpread_get_location (dn_bufp->dend.address, objfile);
-         /* Why in the hell is this needed?  */
-         valu += offset + 9;   /* Relocate for dynamic loading */
-         new = pop_context ();
-         desc = dn_bufp->dend.beginscope.dnttp.index;
-         if (desc != new->depth)
-           complain (&lbrac_mismatch_complaint, (char *) symnum);
-         /* Make a block for the local symbols within.  */
-         finish_block (new->name, &local_symbols, new->old_blocks,
-                       new->start_addr, valu, objfile);
-         local_symbols = new->locals;
-         param_symbols = new->params;
-#endif
-         break;
-
-       default:
-         complain (&hpread_unexpected_end_complaint);
-         break;
-       }
-      break;
-
-      /* DNTT_TYPE_IMPORT is not handled */
-
-    case DNTT_TYPE_LABEL:
-      SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
-      break;
-
-    case DNTT_TYPE_FPARAM:
-      /* Function parameters.  */
-      /* Note 1: This code was present in the 4.16 sources, and then
-         removed, because fparams are handled in
-         hpread_read_function_type().  However, while fparam symbols
-         are indeed handled twice, this code here cannot be removed
-         because then they don't get added to the local symbol list of
-         the function's code block, which leads to a failure to look
-         up locals, "this"-relative member names, etc.  So I've put
-         this code back in. pai/1997-07-21 */
-      /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols
-         in hpread_read_function_type(), so FPARAMS had to be handled
-         here.  I changed the location to be the appropriate argument
-         kinds rather than LOC_LOCAL. pai/1997-08-08 */
-      /* Note 3: Well, the fix in Note 2 above broke argument printing
-         in traceback frames, and further it makes assumptions about the
-         order of the FPARAM entries from HP compilers (cc and aCC in particular
-         generate them in reverse orders -- fixing one breaks for the other).
-         So I've added code in hpread_read_function_type() to add fparams
-         to a param_symbols list for the current context level.  These are
-         then merged into local_symbols when a function end is reached.
-         pai/1997-08-11 */
-
-      break;                   /* do nothing; handled in hpread_read_function_type() */
-
-#if 0                          /* Old code */
-      if (dn_bufp->dfparam.regparam)
-       SYMBOL_CLASS (sym) = LOC_REGISTER;
-      else if (dn_bufp->dfparam.indirect)
-       SYMBOL_CLASS (sym) = LOC_REF_ARG;
-      else
-       SYMBOL_CLASS (sym) = LOC_ARG;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      if (dn_bufp->dfparam.copyparam)
-       {
-         SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
-#ifdef HPREAD_ADJUST_STACK_ADDRESS
-         SYMBOL_VALUE (sym)
-           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
-#endif
-       }
-      else
-       SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
-      add_symbol_to_list (sym, &fparam_symbols);
-      break;
-#endif
-
-    case DNTT_TYPE_SVAR:
-      /* Static variables.  */
-      SYMBOL_CLASS (sym) = LOC_STATIC;
-
-      /* Note: There is a case that arises with globals in shared
-       * libraries where we need to set the address to LOC_INDIRECT.
-       * This case is if you have a global "g" in one library, and
-       * it is referenced "extern <type> g;" in another library.
-       * If we're processing the symbols for the referencing library,
-       * we'll see a global "g", but in this case the address given
-       * in the symbol table contains a pointer to the real "g".
-       * We use the storage class LOC_INDIRECT to indicate this. RT
-       */
-      if (is_in_import_list (SYMBOL_NAME (sym), objfile))
-       SYMBOL_CLASS (sym) = LOC_INDIRECT;
-
-      SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
-
-      if (dn_bufp->dsvar.global)
-       add_symbol_to_list (sym, &global_symbols);
-
-      else if (WITHIN_FUNCTION (objfile))
-       add_symbol_to_list (sym, &local_symbols);
-
-      else
-       add_symbol_to_list (sym, &file_symbols);
-
-      if (dn_bufp->dsvar.thread_specific)
-       {
-         /* Thread-local variable.
-          */
-         SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
-         SYMBOL_BASEREG (sym) = CR27_REGNUM;
-
-         if (objfile->flags & OBJF_SHARED)
-           {
-             /*
-              * This variable is not only thread local but
-              * in a shared library.
-              *
-              * Alas, the shared lib structures are private
-              * to "somsolib.c".  But C lets us point to one.
-              */
-             struct so_list *so;
-
-             if (objfile->obj_private == NULL)
-               error ("Internal error in reading shared library information.");
-
-             so = ((obj_private_data_t *) (objfile->obj_private))->so_info;
-             if (so == NULL)
-               error ("Internal error in reading shared library information.");
-
-             /* Thread-locals in shared libraries do NOT have the
-              * standard offset ("data_offset"), so we re-calculate
-              * where to look for this variable, using a call-back
-              * to interpret the private shared-library data.
-              */
-             SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location +
-               so_lib_thread_start_addr (so);
-           }
-       }
-      break;
-
-    case DNTT_TYPE_DVAR:
-      /* Dynamic variables.  */
-      if (dn_bufp->ddvar.regvar)
-       SYMBOL_CLASS (sym) = LOC_REGISTER;
-      else
-       SYMBOL_CLASS (sym) = LOC_LOCAL;
-
-      SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
-#ifdef HPREAD_ADJUST_STACK_ADDRESS
-      SYMBOL_VALUE (sym)
-       += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
-#endif
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
-      if (dn_bufp->ddvar.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else if (WITHIN_FUNCTION (objfile))
-       add_symbol_to_list (sym, &local_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
-      break;
-
-    case DNTT_TYPE_CONST:
-      /* A constant (pascal?).  */
-      SYMBOL_CLASS (sym) = LOC_CONST;
-      SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
-      if (dn_bufp->dconst.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else if (WITHIN_FUNCTION (objfile))
-       add_symbol_to_list (sym, &local_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
-      break;
-
-    case DNTT_TYPE_TYPEDEF:
-      /* A typedef. We do want to process these, since a name is
-       * added to the namespace for the typedef'ed name.
-       */
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
-      if (dn_bufp->dtype.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else if (WITHIN_FUNCTION (objfile))
-       add_symbol_to_list (sym, &local_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
-      break;
-
-    case DNTT_TYPE_TAGDEF:
-      {
-       int global = dn_bufp->dtag.global;
-       /* Structure, union, enum, template, or class tag definition */
-       /* We do want to process these, since a name is
-        * added to the namespace for the tag name (and if C++ class,
-        * for the typename also).
-        */
-       SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
-
-       /* The tag contains in its "type" field a pointer to the
-        * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM, 
-        * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE
-        * record that actually defines the type.
-        */
-       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
-       TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
-       TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
-       if (dn_bufp->dtag.global)
-         add_symbol_to_list (sym, &global_symbols);
-       else if (WITHIN_FUNCTION (objfile))
-         add_symbol_to_list (sym, &local_symbols);
-       else
-         add_symbol_to_list (sym, &file_symbols);
-
-       /* If this is a C++ class, then we additionally 
-        * need to define a typedef for the
-        * class type. E.g., so that the name "c" becomes visible as
-        * a type name when the user says "class c { ... }".
-        * In order to figure this out, we need to chase down the "type"
-        * field to get to the DNTT_TYPE_CLASS record. 
-        *
-        * We also add the typename for ENUM. Though this isn't
-        * strictly correct, it is necessary because of the debug info
-        * generated by the aCC compiler, in which we cannot
-        * distinguish between:
-        *   enum e { ... };
-        * and
-        *   typedef enum { ... } e;
-        * I.e., the compiler emits the same debug info for the above
-        * two cases, in both cases "e" appearing as a tagdef.
-        * Therefore go ahead and generate the typename so that
-        * "ptype e" will work in the above cases.
-        *
-        * We also add the typename for TEMPLATE, so as to allow "ptype t"
-        * when "t" is a template name. 
-        */
-       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
-         dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
-       else
-         {
-           complain (&hpread_tagdef_complaint);
-           return;
-         }
-       if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
-           dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
-           dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
-         {
-           struct symbol *newsym;
-
-           newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
-                                                   sizeof (struct symbol));
-           memset (newsym, 0, sizeof (struct symbol));
-           SYMBOL_NAME (newsym) = name;
-           SYMBOL_LANGUAGE (newsym) = language_auto;
-           SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE;
-           SYMBOL_LINE (newsym) = 0;
-           SYMBOL_VALUE (newsym) = 0;
-           SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
-           SYMBOL_TYPE (newsym) = sym->type;
-           if (global)
-             add_symbol_to_list (newsym, &global_symbols);
-           else if (WITHIN_FUNCTION (objfile))
-             add_symbol_to_list (newsym, &local_symbols);
-           else
-             add_symbol_to_list (newsym, &file_symbols);
-         }
-      }
-      break;
-
-    case DNTT_TYPE_POINTER:
-      /* Declares a pointer type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_ENUM:
-      /* Declares an enum type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_MEMENUM:
-      /* Member of enum */
-      /* Ignored at this level, but hpread_read_enum_type() will take
-       * care of walking the list of enumeration members.
-       */
-      break;
-
-    case DNTT_TYPE_SET:
-      /* Declares a set type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_SUBRANGE:
-      /* Declares a subrange type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_ARRAY:
-      /* Declares an array type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_STRUCT:
-    case DNTT_TYPE_UNION:
-      /* Declares an struct/union type. 
-       * Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_FIELD:
-      /* Structure/union/class field */
-      /* Ignored at this level, but hpread_read_struct_type() will take
-       * care of walking the list of structure/union/class members.
-       */
-      break;
-
-      /* DNTT_TYPE_VARIANT is not handled by GDB */
-
-      /* DNTT_TYPE_FILE is not handled by GDB */
-
-    case DNTT_TYPE_FUNCTYPE:
-      /* Function type */
-      /* Ignored at this level, handled within hpread_type_lookup() */
-      break;
-
-    case DNTT_TYPE_WITH:
-      /* This is emitted within methods to indicate "with <class>" 
-       * scoping rules (i.e., indicate that the class data members
-       * are directly visible).
-       * However, since GDB already infers this by looking at the
-       * "this" argument, interpreting the DNTT_TYPE_WITH 
-       * symbol record is unnecessary.
-       */
-      break;
-
-    case DNTT_TYPE_COMMON:
-      /* FORTRAN common. Not yet handled. */
-      complain (&hpread_unhandled_common_complaint);
-      break;
-
-      /* DNTT_TYPE_COBSTRUCT is not handled by GDB.  */
-      /* DNTT_TYPE_XREF is not handled by GDB.  */
-      /* DNTT_TYPE_SA is not handled by GDB.  */
-      /* DNTT_TYPE_MACRO is not handled by GDB */
-
-    case DNTT_TYPE_BLOCKDATA:
-      /* Not sure what this is - part of FORTRAN support maybe? 
-       * Anyway, not yet handled.
-       */
-      complain (&hpread_unhandled_blockdata_complaint);
-      break;
-
-    case DNTT_TYPE_CLASS_SCOPE:
-
-
-
-      /* The compiler brackets member functions with a CLASS_SCOPE/END
-       * pair of records, presumably to put them in a different scope
-       * from the module scope where they are normally defined.
-       * E.g., in the situation:
-       *   void f() { ... }
-       *   void c::f() { ...}
-       * The member function "c::f" will be bracketed by a CLASS_SCOPE/END.
-       * This causes "break f" at the module level to pick the
-       * the file-level function f(), not the member function
-       * (which needs to be referenced via "break c::f"). 
-       * 
-       * Here we record the class name to generate the demangled names of
-       * member functions later.
-       *
-       * FIXME Not being used now for anything -- cplus_demangle seems
-       * enough for getting the class-qualified names of functions. We
-       * may need this for handling nested classes and types.  */
-
-      /* pai: FIXME Not handling nested classes for now -- need to
-       * maintain a stack */
-
-      dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
-      if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
-       class_scope_name = VT (objfile) + dn_temp->dtag.name;
-      else
-       class_scope_name = NULL;
-
-#if 0
-
-      /* Begin a new scope.  */
-      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                               SL_INDEX (objfile),
-                                             dn_bufp->dclass_scope.address,
-                                               objfile, offset);
-      valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
-      valu += offset;          /* Relocate for dynamic loading */
-      desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
-      /* We use the scope start DNTT index as the nesting depth identifier! */
-      new = push_context (desc, valu);
-#endif
-      break;
-
-    case DNTT_TYPE_REFERENCE:
-      /* Declares a C++ reference type. Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level.
-       */
-      break;
-
-    case DNTT_TYPE_PTRMEM:
-      /* Declares a C++ pointer-to-data-member type. This does not
-       * need to be handled at this level; being a type description it
-       * is instead handled at the hpread_type_lookup() level.
-       */
-      break;
-
-    case DNTT_TYPE_PTRMEMFUNC:
-      /* Declares a C++ pointer-to-function-member type. This does not
-       * need to be handled at this level; being a type description it
-       * is instead handled at the hpread_type_lookup() level.
-       */
-      break;
-
-    case DNTT_TYPE_CLASS:
-      /* Declares a class type. 
-       * Should not be necessary to do anything
-       * with the type at this level; these are processed
-       * at the hpread_type_lookup() level. 
-       */
-      break;
-
-    case DNTT_TYPE_GENFIELD:
-      /* I believe this is used for class member functions */
-      /* Ignored at this level, but hpread_read_struct_type() will take
-       * care of walking the list of class members.
-       */
-      break;
-
-    case DNTT_TYPE_VFUNC:
-      /* Virtual function */
-      /* This does not have to be handled at this level; handled in
-       * the course of processing class symbols.
-       */
-      break;
-
-    case DNTT_TYPE_MEMACCESS:
-      /* DDE ignores this symbol table record.
-       * It has something to do with "modified access" to class members.
-       * I'll assume we can safely ignore it too.
-       */
-      break;
-
-    case DNTT_TYPE_INHERITANCE:
-      /* These don't have to be handled here, since they are handled
-       * within hpread_read_struct_type() in the process of constructing
-       * a class type.
-       */
-      break;
-
-    case DNTT_TYPE_FRIEND_CLASS:
-    case DNTT_TYPE_FRIEND_FUNC:
-      /* These can safely be ignored, as GDB doesn't need this
-       * info. DDE only uses it in "describe". We may later want
-       * to extend GDB's "ptype" to give this info, but for now
-       * it seems safe enough to ignore it.
-       */
-      break;
-
-    case DNTT_TYPE_MODIFIER:
-      /* Intended to supply "modified access" to a type */
-      /* From the way DDE handles this, it looks like it always
-       * modifies a type. Therefore it is safe to ignore it at this
-       * level, and handle it in hpread_type_lookup().
-       */
-      break;
-
-    case DNTT_TYPE_OBJECT_ID:
-      /* Just ignore this - that's all DDE does */
-      break;
-
-    case DNTT_TYPE_MEMFUNC:
-      /* Member function */
-      /* This does not have to be handled at this level; handled in
-       * the course of processing class symbols.
-       */
-      break;
-
-    case DNTT_TYPE_DOC_MEMFUNC:
-      /* Member function */
-      /* This does not have to be handled at this level; handled in
-       * the course of processing class symbols.
-       */
-      break;
-
-    case DNTT_TYPE_TEMPLATE:
-      /* Template - sort of the header for a template definition,
-       * which like a class, points to a member list and also points
-       * to a TEMPLATE_ARG list of type-arguments.
-       * We do not need to process TEMPLATE records at this level though.
-       */
-      break;
-
-    case DNTT_TYPE_TEMPLATE_ARG:
-      /* The TEMPLATE record points to an argument list of
-       * TEMPLATE_ARG records, each of which describes one
-       * of the type-arguments.
-       * We do not need to process TEMPLATE_ARG records at this level though.
-       */
-      break;
-
-    case DNTT_TYPE_FUNC_TEMPLATE:
-      /* This will get emitted for member functions of templates.
-       * But we don't need to process this record at this level though,
-       * we will process it in the course of processing a TEMPLATE
-       * record.
-       */
-      break;
-
-    case DNTT_TYPE_LINK:
-      /* The LINK record is used to link up templates with instantiations. */
-      /* It is not clear why this is needed, and furthermore aCC does
-       * not appear to generate this, so I think we can safely ignore it. - RT
-       */
-      break;
-
-      /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */
-      /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */
-      /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */
-      /* DNTT_TYPE_INLN is not handled by GDB */
-      /* DNTT_TYPE_INLN_LIST is not handled by GDB */
-      /* DNTT_TYPE_ALIAS is not handled by GDB */
-
-    default:
-      break;
-    }
-}
-
-/* Get nesting depth for a DNTT entry.
- * DN_BUFP points to a DNTT entry.
- * OBJFILE is the object file.
- * REPORT_NESTED is a flag; if 0, real nesting depth is
- * reported, if it is 1, the function simply returns a 
- * non-zero value if the nesting depth is anything > 0.
- * 
- * Return value is an integer.  0 => not a local type / name
- * positive return => type or name is local to some 
- * block or function.
- */
-
-
-/* elz: ATTENTION: FIXME: NOTE: WARNING!!!!
-   this function now returns 0 right away. It was taking too much time
-   at start up. Now, though, the local types are not handled correctly.
- */
-
-
-static int
-hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile,
-                       int report_nested)
-{
-  register int index;
-  register union dnttentry *dn_tmp;
-  register short depth = 0;
-/****************************/
-  return 0;
-/****************************/
-
-  index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
-
-  while (--index >= 0)
-    {
-      dn_tmp = hpread_get_lntt (index, objfile);
-      switch (dn_tmp->dblock.kind)
-       {
-       case DNTT_TYPE_MODULE:
-         return depth;
-       case DNTT_TYPE_END:
-         /* index is signed int; dnttp.index is 29-bit unsigned int! */
-         index = (int) dn_tmp->dend.beginscope.dnttp.index;
-         break;
-       case DNTT_TYPE_BEGIN:
-       case DNTT_TYPE_FUNCTION:
-       case DNTT_TYPE_DOC_FUNCTION:
-       case DNTT_TYPE_WITH:
-       case DNTT_TYPE_COMMON:
-       case DNTT_TYPE_CLASS_SCOPE:
-         depth++;
-         if (report_nested)
-           return 1;
-         break;
-       default:
-         break;
-       }
-    }
-  return depth;
-}
-
-/* Adjust the bitoffsets for all fields of an anonymous union of
-   type TYPE by negative BITS.  This handles HP aCC's hideous habit
-   of giving members of anonymous unions bit offsets relative to the
-   enclosing structure instead of relative to the union itself. */
-
-static void
-hpread_adjust_bitoffsets (struct type *type, int bits)
-{
-  register int i;
-
-  /* This is done only for unions; caller had better check that
-     it is an anonymous one. */
-  if (TYPE_CODE (type) != TYPE_CODE_UNION)
-    return;
-
-  /* Adjust each field; since this is a union, there are no base
-     classes. Also no static membes.  Also, no need for recursion as
-     the members of this union if themeselves structs or unions, have
-     the correct bitoffsets; if an anonymous union is a member of this
-     anonymous union, the code in hpread_read_struct_type() will
-     adjust for that. */
-
-  for (i = 0; i < TYPE_NFIELDS (type); i++)
-    TYPE_FIELD_BITPOS (type, i) -= bits;
-}
-
-/* Because of quirks in HP compilers' treatment of anonymous unions inside
-   classes, we have to chase through a chain of threaded FIELD entries.
-   If we encounter an anonymous union in the chain, we must recursively skip over
-   that too.
-
-   This function does a "next" in the chain of FIELD entries, but transparently
-   skips over anonymous unions' fields (recursively).
-
-   Inputs are the number of times to do "next" at the top level, the dnttpointer
-   (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it,
-   and the ubiquitous objfile parameter. (Note: FIELDP is a **.)  Return value
-   is a dnttpointer for the new field after all the skipped ones */
-
-static dnttpointer
-hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field,
-                                      union dnttentry **fieldp,
-                                      struct objfile *objfile)
-{
-  struct type *anon_type;
-  register int i;
-  int bitoffset;
-  char *name;
-
-  for (i = 0; i < skip_fields; i++)
-    {
-      /* Get type of item we're looking at now; recursively processes the types
-         of these intermediate items we skip over, so they aren't lost. */
-      anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
-      anon_type = CHECK_TYPEDEF (anon_type);
-      bitoffset = (*fieldp)->dfield.bitoffset;
-      name = VT (objfile) + (*fieldp)->dfield.name;
-      /* First skip over one item to avoid stack death on recursion */
-      field = (*fieldp)->dfield.nextfield;
-      *fieldp = hpread_get_lntt (field.dnttp.index, objfile);
-      /* Do we have another anonymous union? If so, adjust the bitoffsets
-         of its members and skip over its members. */
-      if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
-         (!name || STREQ (name, "")))
-       {
-         hpread_adjust_bitoffsets (anon_type, bitoffset);
-         field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
-       }
-    }
-  return field;
-}
index e793775..b7f0fc5 100644 (file)
@@ -132,32 +132,76 @@ extern struct complaint string_table_offset_complaint;
 extern struct complaint lbrac_unmatched_complaint;
 extern struct complaint lbrac_mismatch_complaint;
 \f
+static struct complaint hpread_unhandled_end_common_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0
+};
 
-void hpread_symfile_init (struct objfile *);
+static struct complaint hpread_unhandled_type_complaint =
+{
+  "hpread_type_translate: unhandled type code.", 0, 0
+};
 
-static struct type *hpread_read_array_type (dnttpointer, union dnttentry *,
-                                           struct objfile *);
+static struct complaint hpread_struct_complaint =
+{
+  "hpread_read_struct_type: expected SVAR type...", 0, 0
+};
 
-static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
+static struct complaint hpread_array_complaint =
+{
+  "error in hpread_array_type.", 0, 0
+};
 
-static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
+static struct complaint hpread_type_lookup_complaint =
+{
+  "error in hpread_type_lookup().", 0, 0
+};
 
-static struct type *hpread_read_enum_type
-  (dnttpointer, union dnttentry *, struct objfile *);
 
-static struct type *hpread_read_set_type
-  (dnttpointer, union dnttentry *, struct objfile *);
+static struct complaint hpread_unexpected_end_complaint =
+{
+  "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0
+};
 
-static struct type *hpread_read_subrange_type
-  (dnttpointer, union dnttentry *, struct objfile *);
+static struct complaint hpread_tagdef_complaint =
+{
+  "error processing class tagdef", 0, 0
+};
 
-static struct type *hpread_read_struct_type
-  (dnttpointer, union dnttentry *, struct objfile *);
+static struct complaint hpread_unhandled_common_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0
+};
+
+static struct complaint hpread_unhandled_blockdata_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0
+};
+
+/* To generate dumping code, uncomment this define.  The dumping
+   itself is controlled by routine-local statics called "dumping". */
+/* #define DUMPING         1 */
+
+/* To use the quick look-up tables, uncomment this define. */
+#define QUICK_LOOK_UP      1
+
+/* To call PXDB to process un-processed files, uncomment this define. */
+#define USE_PXDB           1
+
+/* Forward procedure declarations */
+
+void hpread_symfile_init (struct objfile *);
+
+void do_pxdb (bfd *);
 
 void hpread_build_psymtabs (struct objfile *, int);
 
 void hpread_symfile_finish (struct objfile *);
 
+static union dnttentry *hpread_get_gntt (int, struct objfile *);
+
+static unsigned long hpread_get_textlow (int, int, struct objfile *, int);
+
 static struct partial_symtab *hpread_start_psymtab
   (struct objfile *, char *, CORE_ADDR, int,
    struct partial_symbol **, struct partial_symbol **);
@@ -166,1060 +210,2932 @@ static struct partial_symtab *hpread_end_psymtab
   (struct partial_symtab *, char **, int, int, CORE_ADDR,
    struct partial_symtab **, int);
 
+static unsigned long hpread_get_scope_start (sltpointer, struct objfile *);
+
+static unsigned long hpread_get_line (sltpointer, struct objfile *);
+
+static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
+
+static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
+
+void hpread_psymtab_to_symtab (struct partial_symtab *);
+
 static struct symtab *hpread_expand_symtab
   (struct objfile *, int, int, CORE_ADDR, int,
    struct section_offsets *, char *);
 
-static void hpread_process_one_debug_symbol
-  (union dnttentry *, char *, struct section_offsets *,
-   struct objfile *, CORE_ADDR, int, char *, int);
+static int hpread_type_translate (dnttpointer);
 
-static sltpointer hpread_record_lines
-  (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
+static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_read_enum_type
+  (dnttpointer, union dnttentry *, struct objfile *);
 
 static struct type *hpread_read_function_type
+  (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_doc_function_type
+  (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_struct_type
   (dnttpointer, union dnttentry *, struct objfile *);
 
-static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
+static struct type *hpread_get_nth_template_arg (struct objfile *, int);
 
-static unsigned long hpread_get_depth (sltpointer, struct objfile *);
+static struct type *hpread_read_templ_arg_type
+  (dnttpointer, union dnttentry *, struct objfile *, char *);
 
-static unsigned long hpread_get_line (sltpointer, struct objfile *);
+static struct type *hpread_read_set_type
+  (dnttpointer, union dnttentry *, struct objfile *);
 
-static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
+static struct type *hpread_read_array_type
+  (dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile);
 
-static int hpread_type_translate (dnttpointer);
-static unsigned long hpread_get_textlow (int, int, struct objfile *);
-static union dnttentry *hpread_get_gntt (int, struct objfile *);
-static union dnttentry *hpread_get_lntt (int, struct objfile *);
-static union sltentry *hpread_get_slt (int, struct objfile *);
-static void hpread_psymtab_to_symtab (struct partial_symtab *);
-static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
-static int hpread_has_name (enum dntt_entry_type);
-\f
+static struct type *hpread_read_subrange_type
+  (dnttpointer, union dnttentry *, struct objfile *);
 
-/* Initialization for reading native HP C debug symbols from OBJFILE.
+static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
 
-   It's only purpose in life is to set up the symbol reader's private
-   per-objfile data structures, and read in the raw contents of the debug
-   sections (attaching pointers to the debug info into the private data
-   structures).
+static sltpointer hpread_record_lines
+  (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
 
-   Since BFD doesn't know how to read debug symbols in a format-independent
-   way (and may never do so...), we have to do it ourselves.  Note we may
-   be called on a file without native HP C debugging symbols.
-   FIXME, there should be a cleaner peephole into the BFD environment here.  */
+static void hpread_process_one_debug_symbol
+  (union dnttentry *, char *, struct section_offsets *,
+   struct objfile *, CORE_ADDR, int, char *, int, int *);
 
-void
-hpread_symfile_init (struct objfile *objfile)
-{
-  asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int);
 
-  /* Allocate struct to keep track of the symfile */
-  objfile->sym_private = (PTR)
-    xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
-  memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+static void fix_static_member_physnames
+  (struct type *, char *, struct objfile *);
 
-  /* We haven't read in any types yet.  */
-  TYPE_VECTOR (objfile) = 0;
+static void fixup_class_method_type
+  (struct type *, struct type *, struct objfile *);
 
-  /* Read in data from the $GNTT$ subspace.  */
-  gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
-  if (!gntt_section)
-    return;
+static void hpread_adjust_bitoffsets (struct type *, int);
 
-  GNTT (objfile)
-    = obstack_alloc (&objfile->symbol_obstack,
-                    bfd_section_size (objfile->obfd, gntt_section));
+static dnttpointer hpread_get_next_skip_over_anon_unions
+  (int, dnttpointer, union dnttentry **, struct objfile *);
 
-  bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
-                        0, bfd_section_size (objfile->obfd, gntt_section));
+\f
+/* Global to indicate presence of HP-compiled objects,
+   in particular, SOM executable file with SOM debug info 
+   Defined in symtab.c, used in hppa-tdep.c. */
+extern int hp_som_som_object_present;
 
-  GNTT_SYMCOUNT (objfile)
-    = bfd_section_size (objfile->obfd, gntt_section)
-    / sizeof (struct dntt_type_block);
+/* Static used to indicate a class type that requires a
+   fix-up of one of its method types */
+static struct type *fixup_class = NULL;
 
-  /* Read in data from the $LNTT$ subspace.   Also keep track of the number
-     of LNTT symbols.  */
-  lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
-  if (!lntt_section)
-    return;
+/* Static used to indicate the method type that is to be
+   used to fix-up the type for fixup_class */
+static struct type *fixup_method = NULL;
 
-  LNTT (objfile)
-    = obstack_alloc (&objfile->symbol_obstack,
-                    bfd_section_size (objfile->obfd, lntt_section));
+#ifdef USE_PXDB
 
-  bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
-                        0, bfd_section_size (objfile->obfd, lntt_section));
+/* NOTE use of system files!  May not be portable. */
 
-  LNTT_SYMCOUNT (objfile)
-    = bfd_section_size (objfile->obfd, lntt_section)
-    / sizeof (struct dntt_type_block);
+#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
+#define PXDB_BSD  "/usr/bin/pxdb"
 
-  /* Read in data from the $SLT$ subspace.  $SLT$ contains information
-     on source line numbers.  */
-  slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
-  if (!slt_section)
-    return;
+#include <stdlib.h>
+#include "gdb_string.h"
 
-  SLT (objfile) =
-    obstack_alloc (&objfile->symbol_obstack,
-                  bfd_section_size (objfile->obfd, slt_section));
+/* check for the existence of a file, given its full pathname */
+int
+file_exists (char *filename)
+{
+  if (filename)
+    return (access (filename, F_OK) == 0);
+  return 0;
+}
 
-  bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
-                         0, bfd_section_size (objfile->obfd, slt_section));
 
-  /* Read in data from the $VT$ subspace.  $VT$ contains things like
-     names and constants.  Keep track of the number of symbols in the VT.  */
-  vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
-  if (!vt_section)
-    return;
+/* Translate from the "hp_language" enumeration in hp-symtab.h
+   used in the debug info to gdb's generic enumeration in defs.h. */
+static enum language
+trans_lang (enum hp_language in_lang)
+{
+  if (in_lang == HP_LANGUAGE_C)
+    return language_c;
 
-  VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+  else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
+    return language_cplus;
 
-  VT (objfile) =
-    (char *) obstack_alloc (&objfile->symbol_obstack,
-                           VT_SIZE (objfile));
+  else if (in_lang == HP_LANGUAGE_FORTRAN)
+    return language_fortran;
 
-  bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
-                           0, VT_SIZE (objfile));
+  else
+    return language_unknown;
 }
 
-/* Scan and build partial symbols for a symbol file.
-
-   The minimal symbol table (either SOM or HP a.out) has already been
-   read in; all we need to do is setup partial symbols based on the
-   native debugging information.
+static char main_string[] = "main";
+\f
+/* Call PXDB to process our file.
 
-   We assume hpread_symfile_init has been called to initialize the
-   symbol reader's private data structures.
+   Approach copied from DDE's "dbgk_run_pxdb".  Note: we
+   don't check for BSD location of pxdb, nor for existence
+   of pxdb itself, etc.
 
-   MAINLINE is true if we are reading the main symbol
-   table (as opposed to a shared lib or dynamically loaded file).  */
+   NOTE: uses system function and string functions directly.
 
-void
-hpread_build_psymtabs (struct objfile *objfile, int mainline)
+   Return value: 1 if ok, 0 if not */
+int
+hpread_call_pxdb (const char *file_name)
 {
-  char *namestring;
-  int past_first_source_file = 0;
-  struct cleanup *old_chain;
+  char *p;
+  int status;
+  int retval;
 
-  int hp_symnum, symcount, i;
+  if (file_exists (PXDB_SVR4))
+    {
+      p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
+      strcpy (p, PXDB_SVR4);
+      strcat (p, " ");
+      strcat (p, file_name);
 
-  union dnttentry *dn_bufp;
-  unsigned long valu;
-  char *p;
-  int texthigh = 0;
-  int have_name = 0;
+      warning ("File not processed by pxdb--about to process now.\n");
+      status = system (p);
 
-  /* Current partial symtab */
-  struct partial_symtab *pst;
+      retval = (status == 0);
+    }
+  else
+    {
+      warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
 
-  /* List of current psymtab's include files */
-  char **psymtab_include_list;
-  int includes_allocated;
-  int includes_used;
+      retval = 0;
+    }
+  return retval;
+}                              /* hpread_call_pxdb */
+\f
 
-  /* Index within current psymtab dependency list */
-  struct partial_symtab **dependency_list;
-  int dependencies_used, dependencies_allocated;
+/* Return 1 if the file turns out to need pre-processing
+   by PXDB, and we have thus called PXDB to do this processing
+   and the file therefore needs to be re-loaded.  Otherwise
+   return 0. */
+int
+hpread_pxdb_needed (bfd *sym_bfd)
+{
+  asection *pinfo_section, *debug_section, *header_section;
+  unsigned int do_pxdb;
+  char *buf;
+  bfd_size_type header_section_size;
 
-  /* Just in case the stabs reader left turds lying around.  */
-  free_pending_blocks ();
-  make_cleanup (really_free_pendings, 0);
+  unsigned long tmp;
+  unsigned int pxdbed;
 
-  pst = (struct partial_symtab *) 0;
+  header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
+  if (!header_section)
+    {
+      return 0;                        /* No header at all, can't recover... */
+    }
 
-  /* We shouldn't use alloca, instead use malloc/free.  Doing so avoids
-     a number of problems with cross compilation and creating useless holes
-     in the stack when we have to allocate new entries.  FIXME.  */
+  debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
+  pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
 
-  includes_allocated = 30;
-  includes_used = 0;
-  psymtab_include_list = (char **) alloca (includes_allocated *
-                                          sizeof (char *));
+  if (pinfo_section && !debug_section)
+    {
+      /* Debug info with DOC, has different header format. 
+         this only happens if the file was pxdbed and compiled optimized
+         otherwise the PINFO section is not there. */
+      header_section_size = bfd_section_size (objfile->obfd, header_section);
 
-  dependencies_allocated = 30;
-  dependencies_used = 0;
-  dependency_list =
-    (struct partial_symtab **) alloca (dependencies_allocated *
-                                      sizeof (struct partial_symtab *));
+      if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
+       {
+         buf = alloca (sizeof (DOC_info_PXDB_header));
 
-  old_chain = make_cleanup_free_objfile (objfile);
+         if (!bfd_get_section_contents (sym_bfd,
+                                        header_section,
+                                        buf, 0,
+                                        header_section_size))
+           error ("bfd_get_section_contents\n");
 
-  last_source_file = 0;
+         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
+         pxdbed = (tmp >> 31) & 0x1;
 
-  /* Make two passes, one ofr the GNTT symbols, the other for the
-     LNTT symbols.  */
-  for (i = 0; i < 1; i++)
-    {
-      int within_function = 0;
+         if (!pxdbed)
+           error ("file debug header info invalid\n");
+         do_pxdb = 0;
+       }
 
-      if (i)
-       symcount = GNTT_SYMCOUNT (objfile);
       else
-       symcount = LNTT_SYMCOUNT (objfile);
+       error ("invalid $HEADER$ size in executable \n");
+    }
+
+  else
+    {
 
-      for (hp_symnum = 0; hp_symnum < symcount; hp_symnum++)
+      /* this can be three different cases:
+         1. pxdbed and not doc
+         - DEBUG and HEADER sections are there
+         - header is PXDB_header type
+         - pxdbed flag is set to 1
+
+         2. not pxdbed and doc
+         - DEBUG and HEADER  sections are there
+         - header is DOC_info_header type
+         - pxdbed flag is set to 0
+
+         3. not pxdbed and not doc
+         - DEBUG and HEADER sections are there
+         - header is XDB_header type
+         - pxdbed flag is set to 0
+
+         NOTE: the pxdbed flag is meaningful also in the not
+         already pxdb processed version of the header,
+         because in case on non-already processed by pxdb files
+         that same bit in the header would be always zero.
+         Why? Because the bit is the leftmost bit of a word
+         which contains a 'length' which is always a positive value
+         so that bit is never set to 1 (otherwise it would be negative)
+
+         Given the above, we have two choices : either we ignore the
+         size of the header itself and just look at the pxdbed field,
+         or we check the size and then we (for safety and paranoia related
+         issues) check the bit.
+         The first solution is used by DDE, the second by PXDB itself.
+         I am using the second one here, because I already wrote it,
+         and it is the end of a long day.
+         Also, using the first approach would still involve size issues
+         because we need to read in the contents of the header section, and
+         give the correct amount of stuff we want to read to the
+         get_bfd_section_contents function.  */
+
+      /* decide which case depending on the size of the header section.
+         The size is as defined in hp-symtab.h  */
+
+      header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+      if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */
        {
-         QUIT;
-         if (i)
-           dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+
+         buf = alloca (sizeof (PXDB_header));
+         if (!bfd_get_section_contents (sym_bfd,
+                                        header_section,
+                                        buf, 0,
+                                        header_section_size))
+           error ("bfd_get_section_contents\n");
+
+         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
+         pxdbed = (tmp >> 31) & 0x1;
+
+         if (pxdbed)
+           do_pxdb = 0;
          else
-           dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+           error ("file debug header invalid\n");
+       }
+      else                     /*not pxdbed and doc OR not pxdbed and non doc */
+       do_pxdb = 1;
+    }
 
-         if (dn_bufp->dblock.extension)
-           continue;
+  if (do_pxdb)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}                              /* hpread_pxdb_needed */
 
-         /* Only handle things which are necessary for minimal symbols.
-            everything else is ignored.  */
-         switch (dn_bufp->dblock.kind)
-           {
-           case DNTT_TYPE_SRCFILE:
-             {
-               /* A source file of some kind.  Note this may simply
-                  be an included file.  */
-               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+#endif
 
-               /* Check if this is the source file we are already working
-                  with.  */
-               if (pst && !strcmp (namestring, pst->filename))
-                 continue;
+/* Check whether the file needs to be preprocessed by pxdb. 
+   If so, call pxdb. */
 
-               /* Check if this is an include file, if so check if we have
-                  already seen it.  Add it to the include list */
-               p = strrchr (namestring, '.');
-               if (!strcmp (p, ".h"))
-                 {
-                   int j, found;
+void
+do_pxdb (bfd *sym_bfd)
+{
+  /* The following code is HP-specific.  The "right" way of
+     doing this is unknown, but we bet would involve a target-
+     specific pre-file-load check using a generic mechanism. */
 
-                   found = 0;
-                   for (j = 0; j < includes_used; j++)
-                     if (!strcmp (namestring, psymtab_include_list[j]))
-                       {
-                         found = 1;
-                         break;
-                       }
-                   if (found)
-                     continue;
+  /* This code will not be executed if the file is not in SOM
+     format (i.e. if compiled with gcc) */
+  if (hpread_pxdb_needed (sym_bfd))
+    {
+      /*This file has not been pre-processed. Preprocess now */
 
-                   /* Add it to the list of includes seen so far and
-                      allocate more include space if necessary.  */
-                   psymtab_include_list[includes_used++] = namestring;
-                   if (includes_used >= includes_allocated)
-                     {
-                       char **orig = psymtab_include_list;
+      if (hpread_call_pxdb (sym_bfd->filename))
+       {
+         /* The call above has changed the on-disk file, 
+            we can close the file anyway, because the
+            symbols will be reread in when the target is run */
+         bfd_close (sym_bfd);
+       }
+    }
+}
+\f
 
-                       psymtab_include_list = (char **)
-                         alloca ((includes_allocated *= 2) *
-                                 sizeof (char *));
-                       memcpy ((PTR) psymtab_include_list, (PTR) orig,
-                               includes_used * sizeof (char *));
-                     }
-                   continue;
-                 }
 
+#ifdef QUICK_LOOK_UP
 
-               if (pst)
-                 {
-                   if (!have_name)
-                     {
-                       pst->filename = (char *)
-                         obstack_alloc (&pst->objfile->psymbol_obstack,
-                                        strlen (namestring) + 1);
-                       strcpy (pst->filename, namestring);
-                       have_name = 1;
-                       continue;
-                     }
-                   continue;
-                 }
+/* Code to handle quick lookup-tables follows. */
 
-               /* This is a bonafide new source file.
-                  End the current partial symtab and start a new one.  */
 
-               if (pst && past_first_source_file)
-                 {
-                   hpread_end_psymtab (pst, psymtab_include_list,
-                                       includes_used,
-                                       (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                       texthigh,
-                                       dependency_list, dependencies_used);
-                   pst = (struct partial_symtab *) 0;
-                   includes_used = 0;
-                   dependencies_used = 0;
-                 }
-               else
-                 past_first_source_file = 1;
+/* Some useful macros */
+#define VALID_FILE(i)   ((i) < pxdb_header_p->fd_entries)
+#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
+#define VALID_PROC(i)   ((i) < pxdb_header_p->pd_entries)
+#define VALID_CLASS(i)  ((i) < pxdb_header_p->cd_entries)
 
-               valu = hpread_get_textlow (i, hp_symnum, objfile);
-               valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-               pst = hpread_start_psymtab (objfile,
-                                           namestring, valu,
-                                           (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                           objfile->global_psymbols.next,
-                                           objfile->static_psymbols.next);
-               texthigh = valu;
-               have_name = 1;
-               continue;
-             }
+#define FILE_START(i)    (qFD[i].adrStart)
+#define MODULE_START(i) (qMD[i].adrStart)
+#define PROC_START(i)    (qPD[i].adrStart)
 
-           case DNTT_TYPE_MODULE:
-             /* A source file.  It's still unclear to me what the
-                real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
-                is supposed to be.  */
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             valu = hpread_get_textlow (i, hp_symnum, objfile);
-             valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             if (!pst)
-               {
-                 pst = hpread_start_psymtab (objfile,
-                                             namestring, valu,
-                                             (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                             objfile->static_psymbols.next);
-                 texthigh = valu;
-                 have_name = 0;
-               }
-             continue;
-           case DNTT_TYPE_FUNCTION:
-           case DNTT_TYPE_ENTRY:
-             /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
-                a secondary entry point.  */
-             valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
-                                                      SECT_OFF_TEXT (objfile));
-             if (valu > texthigh)
-               texthigh = valu;
-             valu = dn_bufp->dfunc.lowaddr +
-               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             add_psymbol_to_list (namestring, strlen (namestring),
-                                  VAR_NAMESPACE, LOC_BLOCK,
-                                  &objfile->static_psymbols, valu,
-                                  0, language_unknown, objfile);
-             within_function = 1;
-             continue;
-           case DNTT_TYPE_BEGIN:
-           case DNTT_TYPE_END:
-             /* Scope block begin/end.  We only care about function
-                and file blocks right now.  */
-             if (dn_bufp->dend.endkind == DNTT_TYPE_MODULE)
-               {
-                 hpread_end_psymtab (pst, psymtab_include_list, includes_used,
-                                     (hp_symnum
-                                      * sizeof (struct dntt_type_block)),
-                                     texthigh,
-                                     dependency_list, dependencies_used);
-                 pst = (struct partial_symtab *) 0;
-                 includes_used = 0;
-                 dependencies_used = 0;
-                 have_name = 0;
-               }
-             if (dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION)
-               within_function = 0;
-             continue;
-           case DNTT_TYPE_SVAR:
-           case DNTT_TYPE_DVAR:
-           case DNTT_TYPE_TYPEDEF:
-           case DNTT_TYPE_TAGDEF:
-             {
-               /* Variables, typedefs an the like.  */
-               enum address_class storage;
-               namespace_enum namespace;
+#define FILE_END(i)   (qFD[i].adrEnd)
+#define MODULE_END(i) (qMD[i].adrEnd)
+#define PROC_END(i)   (qPD[i].adrEnd)
 
-               /* Don't add locals to the partial symbol table.  */
-               if (within_function
-                   && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
-                       || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
-                 continue;
+#define FILE_ISYM(i)   (qFD[i].isym)
+#define MODULE_ISYM(i) (qMD[i].isym)
+#define PROC_ISYM(i)   (qPD[i].isym)
 
-               /* TAGDEFs go into the structure namespace.  */
-               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
-                 namespace = STRUCT_NAMESPACE;
-               else
-                 namespace = VAR_NAMESPACE;
+#define VALID_CURR_FILE    (curr_fd < pxdb_header_p->fd_entries)
+#define VALID_CURR_MODULE  (curr_md < pxdb_header_p->md_entries)
+#define VALID_CURR_PROC    (curr_pd < pxdb_header_p->pd_entries)
+#define VALID_CURR_CLASS   (curr_cd < pxdb_header_p->cd_entries)
 
-               /* What kind of "storage" does this use?  */
-               if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
-                 storage = LOC_STATIC;
-               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
-                        && dn_bufp->ddvar.regvar)
-                 storage = LOC_REGISTER;
-               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
-                 storage = LOC_LOCAL;
-               else
-                 storage = LOC_UNDEF;
+#define CURR_FILE_START     (qFD[curr_fd].adrStart)
+#define CURR_MODULE_START   (qMD[curr_md].adrStart)
+#define CURR_PROC_START     (qPD[curr_pd].adrStart)
 
-               SET_NAMESTRING (dn_bufp, &namestring, objfile);
-               if (!pst)
-                 {
-                   pst = hpread_start_psymtab (objfile,
-                                               "globals", 0,
-                                               (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                            objfile->static_psymbols.next);
-                 }
-               if (dn_bufp->dsvar.global)
-                 {
-                   add_psymbol_to_list (namestring, strlen (namestring),
-                                        namespace, storage,
-                                        &objfile->global_psymbols,
-                                        dn_bufp->dsvar.location,
-                                        0, language_unknown, objfile);
-                 }
-               else
-                 {
-                   add_psymbol_to_list (namestring, strlen (namestring),
-                                        namespace, storage,
-                                        &objfile->static_psymbols,
-                                        dn_bufp->dsvar.location,
-                                        0, language_unknown, objfile);
-                 }
-               continue;
-             }
-           case DNTT_TYPE_MEMENUM:
-           case DNTT_TYPE_CONST:
-             /* Constants and members of enumerated types.  */
-             SET_NAMESTRING (dn_bufp, &namestring, objfile);
-             if (!pst)
-               {
-                 pst = hpread_start_psymtab (objfile,
-                                             "globals", 0,
-                                             (hp_symnum
-                                        * sizeof (struct dntt_type_block)),
-                                             objfile->global_psymbols.next,
-                                             objfile->static_psymbols.next);
-               }
-             add_psymbol_to_list (namestring, strlen (namestring),
-                                  VAR_NAMESPACE, LOC_CONST,
-                                  &objfile->static_psymbols, 0,
-                                  0, language_unknown, objfile);
-             continue;
-           default:
-             continue;
-           }
-       }
-    }
+#define CURR_FILE_END    (qFD[curr_fd].adrEnd)
+#define CURR_MODULE_END  (qMD[curr_md].adrEnd)
+#define CURR_PROC_END    (qPD[curr_pd].adrEnd)
 
-  /* End any pending partial symbol table.  */
-  if (pst)
-    {
-      hpread_end_psymtab (pst, psymtab_include_list, includes_used,
-                         hp_symnum * sizeof (struct dntt_type_block),
-                         0, dependency_list, dependencies_used);
-    }
+#define CURR_FILE_ISYM    (qFD[curr_fd].isym)
+#define CURR_MODULE_ISYM  (qMD[curr_md].isym)
+#define CURR_PROC_ISYM    (qPD[curr_pd].isym)
 
-  discard_cleanups (old_chain);
-}
+#define TELL_OBJFILE                                      \
+            do {                                          \
+               if( !told_objfile ) {                      \
+                   told_objfile = 1;                      \
+                   warning ("\nIn object file \"%s\":\n", \
+                            objfile->name);               \
+               }                                          \
+            } while (0)
+\f
 
-/* Perform any local cleanups required when we are done with a particular
-   objfile.  I.E, we are in the process of discarding all symbol information
-   for an objfile, freeing up all memory held for it, and unlinking the
-   objfile struct from the global list of known objfiles. */
 
-void
-hpread_symfile_finish (struct objfile *objfile)
+/* Keeping track of the start/end symbol table (LNTT) indices of
+   psymtabs created so far */
+
+typedef struct
 {
-  if (objfile->sym_private != NULL)
-    {
-      xmfree (objfile->md, objfile->sym_private);
-    }
+  int start;
+  int end;
 }
-\f
+pst_syms_struct;
 
-/* The remaining functions are all for internal use only.  */
+static pst_syms_struct *pst_syms_array = 0;
 
-/* Various small functions to get entries in the debug symbol sections.  */
+static pst_syms_count = 0;
+static pst_syms_size = 0;
 
-static union dnttentry *
-hpread_get_lntt (int index, struct objfile *objfile)
+/* used by the TELL_OBJFILE macro */
+static boolean told_objfile = 0;
+
+/* Set up psymtab symbol index stuff */
+static void
+init_pst_syms (void)
 {
-  return (union dnttentry *)
-    &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+  pst_syms_count = 0;
+  pst_syms_size = 20;
+  pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
 }
 
-static union dnttentry *
-hpread_get_gntt (int index, struct objfile *objfile)
+/* Clean up psymtab symbol index stuff */
+static void
+clear_pst_syms (void)
 {
-  return (union dnttentry *)
-    &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+  pst_syms_count = 0;
+  pst_syms_size = 0;
+  xfree (pst_syms_array);
+  pst_syms_array = 0;
 }
 
-static union sltentry *
-hpread_get_slt (int index, struct objfile *objfile)
+/* Add information about latest psymtab to symbol index table */
+static void
+record_pst_syms (int start_sym, int end_sym)
 {
-  return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
+  if (++pst_syms_count > pst_syms_size)
+    {
+      pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
+                             2 * pst_syms_size * sizeof (pst_syms_struct));
+      pst_syms_size *= 2;
+    }
+  pst_syms_array[pst_syms_count - 1].start = start_sym;
+  pst_syms_array[pst_syms_count - 1].end = end_sym;
 }
 
-/* Get the low address associated with some symbol (typically the start
-   of a particular source file or module).  Since that information is not
-   stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we
-   must infer it from the existence of DNTT_TYPE_FUNCTION symbols.  */
+/* Find a suitable symbol table index which can serve as the upper
+   bound of a psymtab that starts at INDEX
 
-static unsigned long
-hpread_get_textlow (int global, int index, struct objfile *objfile)
+   This scans backwards in the psymtab symbol index table to find a
+   "hole" in which the given index can fit.  This is a heuristic!!
+   We don't search the entire table to check for multiple holes,
+   we don't care about overlaps, etc. 
+
+   Return 0 => not found */
+static int
+find_next_pst_start (int index)
 {
-  union dnttentry *dn_bufp;
-  struct minimal_symbol *msymbol;
+  int i;
 
-  /* Look for a DNTT_TYPE_FUNCTION symbol.  */
-  do
-    {
-      if (global)
-       dn_bufp = hpread_get_gntt (index++, objfile);
-      else
-       dn_bufp = hpread_get_lntt (index++, objfile);
-    }
-  while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
-        && dn_bufp->dblock.kind != DNTT_TYPE_END);
+  for (i = pst_syms_count - 1; i >= 0; i--)
+    if (pst_syms_array[i].end <= index)
+      return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
 
-  /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION.  This
-     might happen when a sourcefile has no functions.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_END)
-    return 0;
+  if (pst_syms_array[0].start > index)
+    return pst_syms_array[0].start - 1;
 
-  /* The minimal symbols are typically more accurate for some reason.  */
-  msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
-                                  objfile);
-  if (msymbol)
-    return SYMBOL_VALUE_ADDRESS (msymbol);
-  else
-    return dn_bufp->dfunc.lowaddr;
+  return 0;
 }
+\f
 
-/* Get the nesting depth for the source line identified by INDEX.  */
 
-static unsigned long
-hpread_get_depth (sltpointer index, struct objfile *objfile)
-{
-  union sltentry *sl_bufp;
+/* Utility functions to find the ending symbol index for a psymtab */
 
-  sl_bufp = hpread_get_slt (index, objfile);
-  return sl_bufp->sspec.backptr.dnttp.index;
+/* Find the next file entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QFD is the file table, CURR_FD is the file entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+   Return 0 => not found */
+static int
+find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd,
+                    PXDB_header_ptr pxdb_header_p)
+{
+  while (VALID_CURR_FILE)
+    {
+      if (CURR_FILE_ISYM >= index)
+       return CURR_FILE_ISYM - 1;
+      curr_fd++;
+    }
+  return 0;
 }
 
-/* Get the source line number the the line identified by INDEX.  */
+/* Find the next procedure entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QPD is the procedure table, CURR_PD is the proc entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
 
-static unsigned long
-hpread_get_line (sltpointer index, struct objfile *objfile)
+   Return 0 => not found */
+static int
+find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd,
+                    PXDB_header_ptr pxdb_header_p)
 {
-  union sltentry *sl_bufp;
-
-  sl_bufp = hpread_get_slt (index, objfile);
-  return sl_bufp->snorm.line;
+  while (VALID_CURR_PROC)
+    {
+      if (CURR_PROC_ISYM >= index)
+       return CURR_PROC_ISYM - 1;
+      curr_pd++;
+    }
+  return 0;
 }
 
-static CORE_ADDR
-hpread_get_location (sltpointer index, struct objfile *objfile)
-{
-  union sltentry *sl_bufp;
-  int i;
-
-  /* code location of special sltentrys is determined from context */
-  sl_bufp = hpread_get_slt (index, objfile);
+/* Find the next module entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QMD is the module table, CURR_MD is the modue entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
 
-  if (sl_bufp->snorm.sltdesc == SLT_END)
+   Return 0 => not found */
+static int
+find_next_module_isym (int index, quick_module_entry *qMD, int curr_md,
+                      PXDB_header_ptr pxdb_header_p)
+{
+  while (VALID_CURR_MODULE)
     {
-      /* find previous normal sltentry and get address */
-      for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
-                  (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
-       sl_bufp = hpread_get_slt (index - i, objfile);
-      return sl_bufp->snorm.address;
+      if (CURR_MODULE_ISYM >= index)
+       return CURR_MODULE_ISYM - 1;
+      curr_md++;
     }
-
-  /* find next normal sltentry and get address */
-  for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
-              (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
-    sl_bufp = hpread_get_slt (index + i, objfile);
-  return sl_bufp->snorm.address;
+  return 0;
 }
-\f
 
-/* Return 1 if an HP debug symbol of type KIND has a name associated with
-   it, else return 0.  */
+/* Scan and record partial symbols for all functions starting from index
+   pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR.
+   Other parameters are explained in comments below. */
+
+/* This used to be inline in hpread_quick_traverse, but now that we do
+   essentially the same thing for two different cases (modules and
+   module-less files), it's better organized in a separate routine,
+   although it does take lots of arguments.  pai/1997-10-08
+   
+   CURR_PD_P is the pointer to the current proc index. QPD is the
+   procedure quick lookup table.  MAX_PROCS is the number of entries
+   in the proc. table.  START_ADR is the beginning of the code range
+   for the current psymtab.  end_adr is the end of the code range for
+   the current psymtab.  PST is the current psymtab.  VT_bits is
+   a pointer to the strings table of SOM debug space.  OBJFILE is
+   the current object file. */
 
 static int
-hpread_has_name (enum dntt_entry_type kind)
+scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs,
+           CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst,
+           char *vt_bits, struct objfile *objfile)
 {
-  switch (kind)
-    {
-    case DNTT_TYPE_SRCFILE:
-    case DNTT_TYPE_MODULE:
-    case DNTT_TYPE_FUNCTION:
-    case DNTT_TYPE_ENTRY:
-    case DNTT_TYPE_IMPORT:
-    case DNTT_TYPE_LABEL:
-    case DNTT_TYPE_FPARAM:
-    case DNTT_TYPE_SVAR:
-    case DNTT_TYPE_DVAR:
-    case DNTT_TYPE_CONST:
-    case DNTT_TYPE_TYPEDEF:
-    case DNTT_TYPE_TAGDEF:
-    case DNTT_TYPE_MEMENUM:
-    case DNTT_TYPE_FIELD:
-    case DNTT_TYPE_SA:
-      return 1;
+  union dnttentry *dn_bufp;
+  int symbol_count = 0;                /* Total number of symbols in this psymtab */
+  int curr_pd = *curr_pd_p;    /* Convenience variable -- avoid dereferencing pointer all the time */
 
-    case DNTT_TYPE_BEGIN:
-    case DNTT_TYPE_END:
-    case DNTT_TYPE_WITH:
-    case DNTT_TYPE_COMMON:
-    case DNTT_TYPE_POINTER:
-    case DNTT_TYPE_ENUM:
-    case DNTT_TYPE_SET:
-    case DNTT_TYPE_SUBRANGE:
-    case DNTT_TYPE_ARRAY:
-    case DNTT_TYPE_STRUCT:
-    case DNTT_TYPE_UNION:
-    case DNTT_TYPE_VARIANT:
-    case DNTT_TYPE_FILE:
-    case DNTT_TYPE_FUNCTYPE:
-    case DNTT_TYPE_COBSTRUCT:
-    case DNTT_TYPE_XREF:
-    case DNTT_TYPE_MACRO:
-    default:
-      return 0;
+#ifdef DUMPING
+  /* Turn this on for lots of debugging information in this routine */
+  static int dumping = 0;
+#endif
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
     }
-}
+#endif
 
-/* Allocate and partially fill a partial symtab.  It will be
-   completely filled at the end of the symbol list.
+  while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
+    {
 
-   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
-   is the address relative to which its symbols are (incremental) or 0
-   (normal). */
+      char *rtn_name;          /* mangled name */
+      char *rtn_dem_name;      /* qualified demangled name */
+      char *class_name;
+      int class;
 
-static struct partial_symtab *
-hpread_start_psymtab (struct objfile *objfile, char *filename,
-                     CORE_ADDR textlow, int ldsymoff,
-                     struct partial_symbol **global_syms,
-                     struct partial_symbol **static_syms)
-{
-  struct partial_symtab *result =
-  start_psymtab_common (objfile, section_offsets,
-                       filename, textlow, global_syms, static_syms);
+      if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
+         vt_bits[(long) qPD[curr_pd].sbAlias])         /* not a null string */
+       {
+         /* Get mangled name for the procedure, and demangle it */
+         rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
+         rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
+       }
+      else
+       {
+         rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
+         rtn_dem_name = NULL;
+       }
 
-  result->read_symtab_private = (char *)
-    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
-  LDSYMOFF (result) = ldsymoff;
-  result->read_symtab = hpread_psymtab_to_symtab;
+      /* Hack to get around HP C/C++ compilers' insistence on providing
+         "_MAIN_" as an alternate name for "main" */
+      if ((strcmp (rtn_name, "_MAIN_") == 0) &&
+         (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
+       rtn_dem_name = rtn_name = main_string;
 
-  return result;
+#ifdef DUMPING
+      if (dumping)
+       {
+         printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
+       }
+#endif
+
+      /* Check for module-spanning routines. */
+      if (CURR_PROC_END > end_adr)
+       {
+         TELL_OBJFILE;
+         warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
+       }
+
+      /* Add this routine symbol to the list in the objfile. 
+         Unfortunately we have to go to the LNTT to determine the
+         correct list to put it on. An alternative (which the
+         code used to do) would be to not check and always throw
+         it on the "static" list. But if we go that route, then
+         symbol_lookup() needs to be tweaked a bit to account
+         for the fact that the function might not be found on
+         the correct list in the psymtab. - RT */
+      dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
+      if (dn_bufp->dfunc.global)
+       add_psymbol_with_dem_name_to_list (rtn_name,
+                                          strlen (rtn_name),
+                                          rtn_dem_name,
+                                          strlen (rtn_dem_name),
+                                          VAR_NAMESPACE,
+                                          LOC_BLOCK,   /* "I am a routine"        */
+                                          &objfile->global_psymbols,
+                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
+                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+                                          0,   /* core addr?? */
+                     trans_lang ((enum hp_language) qPD[curr_pd].language),
+                                          objfile);
+      else
+       add_psymbol_with_dem_name_to_list (rtn_name,
+                                          strlen (rtn_name),
+                                          rtn_dem_name,
+                                          strlen (rtn_dem_name),
+                                          VAR_NAMESPACE,
+                                          LOC_BLOCK,   /* "I am a routine"        */
+                                          &objfile->static_psymbols,
+                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
+                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+                                          0,   /* core addr?? */
+                     trans_lang ((enum hp_language) qPD[curr_pd].language),
+                                          objfile);
+
+      symbol_count++;
+      *curr_pd_p = ++curr_pd;  /* bump up count & reflect in caller */
+    }                          /* loop over procedures */
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      if (symbol_count == 0)
+       printf ("Scan_procs: no symbols found!\n");
+    }
+#endif
+
+  return symbol_count;
 }
-\f
 
-/* Close off the current usage of PST.  
-   Returns PST or NULL if the partial symtab was empty and thrown away.
 
-   FIXME:  List variables and peculiarities of same.  */
+/* Traverse the quick look-up tables, building a set of psymtabs.
 
-static struct partial_symtab *
-hpread_end_psymtab (struct partial_symtab *pst, char **include_list,
-                   int num_includes, int capping_symbol_offset,
-                   CORE_ADDR capping_text,
-                   struct partial_symtab **dependency_list,
-                   int number_dependencies)
-{
-  int i;
-  struct objfile *objfile = pst->objfile;
+   This constructs a psymtab for modules and files in the quick lookup
+   tables.
 
-  if (capping_symbol_offset != -1)
-    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
-  pst->texthigh = capping_text;
+   Mostly, modules correspond to compilation units, so we try to
+   create psymtabs that correspond to modules; however, in some cases
+   a file can result in a compiled object which does not have a module
+   entry for it, so in such cases we create a psymtab for the file.  */
 
-  pst->n_global_syms =
-    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
-  pst->n_static_syms =
-    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+int
+hpread_quick_traverse (struct objfile *objfile, char *gntt_bits,
+                      char *vt_bits, PXDB_header_ptr pxdb_header_p)
+{
+  struct partial_symtab *pst;
 
-  pst->number_of_dependencies = number_dependencies;
-  if (number_dependencies)
-    {
-      pst->dependencies = (struct partial_symtab **)
-       obstack_alloc (&objfile->psymbol_obstack,
-                   number_dependencies * sizeof (struct partial_symtab *));
-      memcpy (pst->dependencies, dependency_list,
-             number_dependencies * sizeof (struct partial_symtab *));
-    }
-  else
-    pst->dependencies = 0;
+  char *addr;
 
-  for (i = 0; i < num_includes; i++)
-    {
-      struct partial_symtab *subpst =
-      allocate_psymtab (include_list[i], objfile);
+  quick_procedure_entry *qPD;
+  quick_file_entry *qFD;
+  quick_module_entry *qMD;
+  quick_class_entry *qCD;
 
-      subpst->section_offsets = pst->section_offsets;
-      subpst->read_symtab_private =
-       (char *) obstack_alloc (&objfile->psymbol_obstack,
-                               sizeof (struct symloc));
-      LDSYMOFF (subpst) =
-       LDSYMLEN (subpst) =
-       subpst->textlow =
-       subpst->texthigh = 0;
+  int idx;
+  int i;
+  CORE_ADDR start_adr;         /* current psymtab's starting code addr   */
+  CORE_ADDR end_adr;           /* current psymtab's ending code addr     */
+  CORE_ADDR next_mod_adr;      /* next module's starting code addr    */
+  int curr_pd;                 /* current procedure */
+  int curr_fd;                 /* current file      */
+  int curr_md;                 /* current module    */
+  int start_sym;               /* current psymtab's starting symbol index */
+  int end_sym;                 /* current psymtab's ending symbol index   */
+  int max_LNTT_sym_index;
+  int syms_in_pst;
+  B_TYPE *class_entered;
+
+  struct partial_symbol **global_syms; /* We'll be filling in the "global"   */
+  struct partial_symbol **static_syms; /* and "static" tables in the objfile
+                                          as we go, so we need a pair of     
+                                          current pointers. */
+
+#ifdef DUMPING
+  /* Turn this on for lots of debugging information in this routine.
+     You get a blow-by-blow account of quick lookup table reading */
+  static int dumping = 0;
+#endif
 
-      /* We could save slight bits of space by only making one of these,
-         shared by the entire set of include files.  FIXME-someday.  */
-      subpst->dependencies = (struct partial_symtab **)
-       obstack_alloc (&objfile->psymbol_obstack,
-                      sizeof (struct partial_symtab *));
-      subpst->dependencies[0] = pst;
-      subpst->number_of_dependencies = 1;
+  pst = (struct partial_symtab *) 0;
 
-      subpst->globals_offset =
-       subpst->n_global_syms =
-       subpst->statics_offset =
-       subpst->n_static_syms = 0;
+  /* Clear out some globals */
+  init_pst_syms ();
+  told_objfile = 0;
 
-      subpst->readin = 0;
-      subpst->symtab = 0;
-      subpst->read_symtab = pst->read_symtab;
+  /* Demangling style -- if EDG style already set, don't change it,
+     as HP style causes some problems with the KAI EDG compiler */
+  if (current_demangling_style != edg_demangling)
+    {
+      /* Otherwise, ensure that we are using HP style demangling */
+      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
     }
 
-  sort_pst_symbols (pst);
+  /* First we need to find the starting points of the quick
+     look-up tables in the GNTT. */
 
-  /* If there is already a psymtab or symtab for a file of this name, remove it.
-     (If there is a symtab, more drastic things also happen.)
-     This happens in VxWorks.  */
-  free_named_symtabs (pst->filename);
+  addr = gntt_bits;
 
-  if (num_includes == 0
-      && number_dependencies == 0
-      && pst->n_global_syms == 0
-      && pst->n_static_syms == 0)
+  qPD = (quick_procedure_entry_ptr) addr;
+  addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
+
+#ifdef DUMPING
+  if (dumping)
     {
-      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
-         it is on the obstack, but we can forget to chain it on the list.  */
-      /* Empty psymtabs happen as a result of header files which don't have
-         any symbols in them.  There can be a lot of them.  But this check
-         is wrong, in that a psymtab with N_SLINE entries but nothing else
-         is not empty, but we don't realize that.  Fixing that without slowing
-         things down might be tricky.  */
+      printf ("\n Printing routines as we see them\n");
+      for (i = 0; VALID_PROC (i); i++)
+       {
+         idx = (long) qPD[i].sbProc;
+         printf ("%s %x..%x\n", &vt_bits[idx],
+                 (int) PROC_START (i),
+                 (int) PROC_END (i));
+       }
+    }
+#endif
 
-      discard_psymtab (pst);
+  qFD = (quick_file_entry_ptr) addr;
+  addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
 
-      /* Indicate that psymtab was thrown away.  */
-      pst = (struct partial_symtab *) NULL;
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\n Printing files as we see them\n");
+      for (i = 0; VALID_FILE (i); i++)
+       {
+         idx = (long) qFD[i].sbFile;
+         printf ("%s %x..%x\n", &vt_bits[idx],
+                 (int) FILE_START (i),
+                 (int) FILE_END (i));
+       }
     }
-  return pst;
-}
-\f
-/* Do the dirty work of reading in the full symbol from a partial symbol
-   table.  */
-
-static void
-hpread_psymtab_to_symtab_1 (struct partial_symtab *pst)
-{
-  struct cleanup *old_chain;
-  int i;
+#endif
 
-  /* Get out quick if passed junk.  */
-  if (!pst)
-    return;
+  qMD = (quick_module_entry_ptr) addr;
+  addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
 
-  /* Complain if we've already read in this symbol table.  */
-  if (pst->readin)
+#ifdef DUMPING
+  if (dumping)
     {
-      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
-              pst->filename);
-      return;
+      printf ("\n Printing modules as we see them\n");
+      for (i = 0; i < pxdb_header_p->md_entries; i++)
+       {
+         idx = (long) qMD[i].sbMod;
+         printf ("%s\n", &vt_bits[idx]);
+       }
     }
+#endif
 
-  /* Read in all partial symtabs on which this one is dependent */
-  for (i = 0; i < pst->number_of_dependencies; i++)
-    if (!pst->dependencies[i]->readin)
-      {
-       /* Inform about additional files that need to be read in.  */
-       if (info_verbose)
-         {
-           fputs_filtered (" ", gdb_stdout);
-           wrap_here ("");
-           fputs_filtered ("and ", gdb_stdout);
-           wrap_here ("");
-           printf_filtered ("%s...", pst->dependencies[i]->filename);
-           wrap_here ("");     /* Flush output */
-           gdb_flush (gdb_stdout);
-         }
-       hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
-      }
+  qCD = (quick_class_entry_ptr) addr;
+  addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
 
-  /* If it's real...  */
-  if (LDSYMLEN (pst))
+#ifdef DUMPING
+  if (dumping)
     {
-      /* Init stuff necessary for reading in symbols */
-      buildsym_init ();
-      old_chain = make_cleanup (really_free_pendings, 0);
-
-      pst->symtab =
-       hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
-                             pst->textlow, pst->texthigh - pst->textlow,
-                             pst->section_offsets, pst->filename);
-      sort_symtab_syms (pst->symtab);
+      printf ("\n Printing classes as we see them\n");
+      for (i = 0; VALID_CLASS (i); i++)
+       {
+         idx = (long) qCD[i].sbClass;
+         printf ("%s\n", &vt_bits[idx]);
+       }
 
-      do_cleanups (old_chain);
+      printf ("\n Done with dump, on to build!\n");
     }
+#endif
 
-  pst->readin = 1;
-}
+  /* We need this index only while hp-symtab-read.c expects
+     a byte offset to the end of the LNTT entries for a given
+     psymtab.  Thus the need for it should go away someday.
+
+     When it goes away, then we won't have any need to load the
+     LNTT from the objfile at psymtab-time, and start-up will be
+     faster.  To make that work, we'll need some way to create
+     a null pst for the "globals" pseudo-module. */
+  max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
+
+  /* Scan the module descriptors and make a psymtab for each.
+
+     We know the MDs, FDs and the PDs are in order by starting
+     address.  We use that fact to traverse all three arrays in
+     parallel, knowing when the next PD is in a new file
+     and we need to create a new psymtab. */
+  curr_pd = 0;                 /* Current procedure entry */
+  curr_fd = 0;                 /* Current file entry */
+  curr_md = 0;                 /* Current module entry */
+
+  start_adr = 0;               /* Current psymtab code range */
+  end_adr = 0;
+
+  start_sym = 0;               /* Current psymtab symbol range */
+  end_sym = 0;
+
+  syms_in_pst = 0;             /* Symbol count for psymtab */
+
+  /* Psts actually just have pointers into the objfile's
+     symbol table, not their own symbol tables. */
+  global_syms = objfile->global_psymbols.list;
+  static_syms = objfile->static_psymbols.list;
+
+
+  /* First skip over pseudo-entries with address 0.  These represent inlined
+     routines and abstract (uninstantiated) template routines.
+     FIXME: These should be read in and available -- even if we can't set
+     breakpoints, etc., there's some information that can be presented
+     to the user. pai/1997-10-08  */
+
+  while (VALID_CURR_PROC && (CURR_PROC_START == 0))
+    curr_pd++;
+
+  /* Loop over files, modules, and procedures in code address order. Each
+     time we enter an iteration of this loop, curr_pd points to the first
+     unprocessed procedure, curr_fd points to the first unprocessed file, and
+     curr_md to the first unprocessed module.  Each iteration of this loop
+     updates these as required -- any or all of them may be bumpd up
+     each time around.  When we exit this loop, we are done with all files
+     and modules in the tables -- there may still be some procedures, however.
+
+     Note: This code used to loop only over module entries, under the assumption
+     that files can occur via inclusions and are thus unreliable, while a
+     compiled object always corresponds to a module.  With CTTI in the HP aCC
+     compiler, it turns out that compiled objects may have only files and no
+     modules; so we have to loop over files and modules, creating psymtabs for
+     either as appropriate.  Unfortunately there are some problems (notably:
+     1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers
+     to the ending symbol indices of a module or a file) which make it quite hard
+     to do this correctly.  Currently it uses a bunch of heuristics to start and
+     end psymtabs; they seem to work well with most objects generated by aCC, but
+     who knows when that will change...   */
+
+  while (VALID_CURR_FILE || VALID_CURR_MODULE)
+    {
 
-/* Read in all of the symbols for a given psymtab for real.
-   Be verbose about it if the user wants that.  */
+      char *mod_name_string;
+      char *full_name_string;
 
-static void
-hpread_psymtab_to_symtab (struct partial_symtab *pst)
-{
-  /* Get out quick if given junk.  */
-  if (!pst)
-    return;
+      /* First check for modules like "version.c", which have no code
+         in them but still have qMD entries.  They also have no qFD or
+         qPD entries.  Their start address is -1 and their end address
+         is 0.  */
+      if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
+       {
 
-  /* Sanity check.  */
-  if (pst->readin)
-    {
-      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
-              pst->filename);
-      return;
-    }
+         mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
 
-  if (LDSYMLEN (pst) || pst->number_of_dependencies)
-    {
-      /* Print the message now, before reading the string table,
-         to avoid disconcerting pauses.  */
-      if (info_verbose)
+#ifdef DUMPING
+         if (dumping)
+           printf ("Module with data only %s\n", mod_name_string);
+#endif
+
+         /* We'll skip the rest (it makes error-checking easier), and
+            just make an empty pst.  Right now empty psts are not put
+            in the pst chain, so all this is for naught, but later it
+            might help.  */
+
+         pst = hpread_start_psymtab (objfile,
+                                     mod_name_string,
+                                     CURR_MODULE_START,        /* Low text address: bogus! */
+                      (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
+         /* ldsymoff */
+                                     global_syms,
+                                     static_syms);
+
+         pst = hpread_end_psymtab (pst,
+                                   NULL,       /* psymtab_include_list */
+                                   0,  /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+         /* byte index in LNTT of end 
+            = capping symbol offset  
+            = LDSYMOFF of nextfile */
+                                   0,  /* text high            */
+                                   NULL,       /* dependency_list      */
+                                   0);         /* dependencies_used    */
+
+         global_syms = objfile->global_psymbols.next;
+         static_syms = objfile->static_psymbols.next;
+
+         curr_md++;
+       }
+      else if (VALID_CURR_MODULE &&
+              ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
+               (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
        {
-         printf_filtered ("Reading in symbols for %s...", pst->filename);
-         gdb_flush (gdb_stdout);
+         TELL_OBJFILE;
+         warning ("Module \"%s\" [0x%s] has non-standard addresses.  It starts at 0x%s, ends at 0x%s, and will be skipped.",
+                  mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr));
+         /* On to next module */
+         curr_md++;
        }
+      else
+       {
+         /* First check if we are looking at a file with code in it
+            that does not overlap the current module's code range */
 
-      hpread_psymtab_to_symtab_1 (pst);
+         if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
+           {
 
-      /* Match with global symbols.  This only needs to be done once,
-         after all of the symtabs and dependencies have been read in.   */
-      scan_file_globals (pst->objfile);
+             /* Looking at file not corresponding to any module,
+                create a psymtab for it */
+             full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+             start_adr = CURR_FILE_START;
+             end_adr = CURR_FILE_END;
+             start_sym = CURR_FILE_ISYM;
 
-      /* Finish up the debug error message.  */
-      if (info_verbose)
-       printf_filtered ("done.\n");
-    }
-}
-/* Read in a defined section of a specific object file's symbols.
+             /* Check if there are any procedures not handled until now, that
+                begin before the start address of this file, and if so, adjust
+                this module's start address to include them.  This handles routines that
+                are in between file or module ranges for some reason (probably
+                indicates a compiler bug */
 
-   DESC is the file descriptor for the file, positioned at the
-   beginning of the symtab
-   SYM_OFFSET is the offset within the file of
-   the beginning of the symbols we want to read
-   SYM_SIZE is the size of the symbol info to read in.
-   TEXT_OFFSET is the beginning of the text segment we are reading symbols for
-   TEXT_SIZE is the size of the text segment read in.
-   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+             if (CURR_PROC_START < start_adr)
+               {
+                 TELL_OBJFILE;
+                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+                 start_adr = CURR_PROC_START;
+                 if (CURR_PROC_ISYM < start_sym)
+                   start_sym = CURR_PROC_ISYM;
+               }
 
-static struct symtab *
-hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
-                     CORE_ADDR text_offset, int text_size,
-                     struct section_offsets *section_offsets, char *filename)
-{
-  char *namestring;
-  union dnttentry *dn_bufp;
-  unsigned max_symnum;
+             /* Sometimes (compiler bug -- COBOL) the module end address is higher
+                than the start address of the next module, so check for that and
+                adjust accordingly */
 
-  int sym_index = sym_offset / sizeof (struct dntt_type_block);
+             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+                          full_name_string, curr_fd);
+                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
+               }
+             if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+                          full_name_string, curr_fd);
+                 end_adr = CURR_MODULE_START - 1;      /* Is -4 (or -8 for 64-bit) better? */
+               }
 
-  current_objfile = objfile;
-  subfile_stack = 0;
 
-  last_source_file = 0;
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Make new psymtab for file %s (%x to %x).\n",
+                         full_name_string, start_adr, end_adr);
+               }
+#endif
+             /* Create the basic psymtab, connecting it in the list
+                for this objfile and pointing its symbol entries
+                to the current end of the symbol areas in the objfile.
+
+                The "ldsymoff" parameter is the byte offset in the LNTT
+                of the first symbol in this file.  Some day we should
+                turn this into an index (fix in hp-symtab-read.c as well).
+                And it's not even the right byte offset, as we're using
+                the size of a union! FIXME!  */
+             pst = hpread_start_psymtab (objfile,
+                                         full_name_string,
+                                         start_adr,    /* Low text address */
+                             (start_sym * sizeof (struct dntt_type_block)),
+             /* ldsymoff */
+                                         global_syms,
+                                         static_syms);
+
+             /* Set up to only enter each class referenced in this module once.  */
+             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+             /* Scan the procedure descriptors for procedures in the current
+                file, based on the starting addresses. */
+
+             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                                       start_adr, end_adr, pst, vt_bits, objfile);
+
+             /* Get ending symbol offset */
+
+             end_sym = 0;
+             /* First check for starting index before previous psymtab */
+             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+               {
+                 end_sym = find_next_pst_start (start_sym);
+               }
+             /* Look for next start index of a file or module, or procedure */
+             if (!end_sym)
+               {
+                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
+                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+                 if (next_file_isym && next_module_isym)
+                   {
+                     /* pick lower of next file or module start index */
+                     end_sym = min (next_file_isym, next_module_isym);
+                   }
+                 else
+                   {
+                     /* one of them is zero, pick the other */
+                     end_sym = max (next_file_isym, next_module_isym);
+                   }
+
+                 /* As a precaution, check next procedure index too */
+                 if (!end_sym)
+                   end_sym = next_proc_isym;
+                 else
+                   end_sym = min (end_sym, next_proc_isym);
+               }
 
-  dn_bufp = hpread_get_lntt (sym_index, objfile);
-  if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
-       (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
-    {
-      start_symtab ("globals", NULL, 0);
-      record_debugformat ("HP");
-    }
+             /* Couldn't find procedure, file, or module, use globals as default */
+             if (!end_sym)
+               end_sym = pxdb_header_p->globals;
 
-  max_symnum = sym_size / sizeof (struct dntt_type_block);
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
+               }
+#endif
 
-  /* Read in and process each debug symbol within the specified range.  */
-  for (symnum = 0;
-       symnum < max_symnum;
-       symnum++)
-    {
-      QUIT;                    /* Allow this to be interruptable */
-      dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+             pst = hpread_end_psymtab (pst,
+                                       NULL,   /* psymtab_include_list */
+                                       0,      /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+             /* byte index in LNTT of end 
+                = capping symbol offset   
+                = LDSYMOFF of nextfile */
+                                       end_adr,        /* text high */
+                                       NULL,   /* dependency_list */
+                                       0);     /* dependencies_used */
 
-      if (dn_bufp->dblock.extension)
-       continue;
+             record_pst_syms (start_sym, end_sym);
 
-      /* Yow!  We call SET_NAMESTRING on things without names!  */
-      SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (NULL == pst)
+               warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
 
-      hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
-                                      objfile, text_offset, text_size,
-                                      filename, symnum + sym_index);
-    }
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
+                         full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
+               }
+#endif
+             /* Prepare for the next psymtab. */
+             global_syms = objfile->global_psymbols.next;
+             static_syms = objfile->static_psymbols.next;
+             xfree (class_entered);
 
-  current_objfile = NULL;
+             curr_fd++;
+           }                   /* Psymtab for file */
+         else
+           {
+             /* We have a module for which we create a psymtab */
 
-  return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
-}
-\f
+             mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
 
-/* Convert basic types from HP debug format into GDB internal format.  */
+             /* We will include the code ranges of any files that happen to
+                overlap with this module */
 
-static int
-hpread_type_translate (dnttpointer typep)
-{
-  if (!typep.dntti.immediate)
-    internal_error (__FILE__, __LINE__, "failed internal consistency check");
+             /* So, first pick the lower of the file's and module's start addresses */
+             start_adr = CURR_MODULE_START;
+             if (VALID_CURR_FILE)
+               {
+                 if (CURR_FILE_START < CURR_MODULE_START)
+                   {
+                     TELL_OBJFILE;
+                     warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
+                              &vt_bits[(long) qFD[curr_fd].sbFile],
+                              curr_fd, mod_name_string);
+
+                     start_adr = CURR_FILE_START;
+                   }
+               }
 
-  switch (typep.dntti.type)
-    {
-    case HP_TYPE_BOOLEAN:
-    case HP_TYPE_BOOLEAN_S300_COMPAT:
-    case HP_TYPE_BOOLEAN_VAX_COMPAT:
-      return FT_BOOLEAN;
-      /* Ugh.  No way to distinguish between signed and unsigned chars.  */
-    case HP_TYPE_CHAR:
-    case HP_TYPE_WIDE_CHAR:
-      return FT_CHAR;
-    case HP_TYPE_INT:
-      if (typep.dntti.bitlength <= 8)
-       return FT_CHAR;
-      if (typep.dntti.bitlength <= 16)
-       return FT_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_INTEGER;
-      return FT_LONG_LONG;
-    case HP_TYPE_LONG:
-      return FT_LONG;
-    case HP_TYPE_UNSIGNED_LONG:
-      if (typep.dntti.bitlength <= 8)
-       return FT_UNSIGNED_CHAR;
-      if (typep.dntti.bitlength <= 16)
-       return FT_UNSIGNED_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_UNSIGNED_LONG;
-      return FT_UNSIGNED_LONG_LONG;
-    case HP_TYPE_UNSIGNED_INT:
-      if (typep.dntti.bitlength <= 8)
-       return FT_UNSIGNED_CHAR;
-      if (typep.dntti.bitlength <= 16)
-       return FT_UNSIGNED_SHORT;
-      if (typep.dntti.bitlength <= 32)
-       return FT_UNSIGNED_INTEGER;
-      return FT_UNSIGNED_LONG_LONG;
-    case HP_TYPE_REAL:
-    case HP_TYPE_REAL_3000:
-    case HP_TYPE_DOUBLE:
-      if (typep.dntti.bitlength == 64)
-       return FT_DBL_PREC_FLOAT;
-      if (typep.dntti.bitlength == 128)
-       return FT_EXT_PREC_FLOAT;
-      return FT_FLOAT;
-    case HP_TYPE_COMPLEX:
-    case HP_TYPE_COMPLEXS3000:
-      if (typep.dntti.bitlength == 128)
-       return FT_DBL_PREC_COMPLEX;
-      if (typep.dntti.bitlength == 192)
-       return FT_EXT_PREC_COMPLEX;
-      return FT_COMPLEX;
-    case HP_TYPE_STRING200:
-    case HP_TYPE_LONGSTRING200:
-    case HP_TYPE_FTN_STRING_SPEC:
-    case HP_TYPE_MOD_STRING_SPEC:
-    case HP_TYPE_MOD_STRING_3000:
-    case HP_TYPE_FTN_STRING_S300_COMPAT:
-    case HP_TYPE_FTN_STRING_VAX_COMPAT:
-      return FT_STRING;
-    default:
-      internal_error (__FILE__, __LINE__, "failed internal consistency check");
-    }
-}
+             /* Also pick the lower of the file's and the module's start symbol indices */
+             start_sym = CURR_MODULE_ISYM;
+             if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
+               start_sym = CURR_FILE_ISYM;
 
-/* Return the type associated with the index found in HP_TYPE.  */
+             /* For the end address, we scan through the files till we find one
+                that overlaps the current module but ends beyond it; if no such file exists we
+                simply use the module's start address.  
+                (Note, if file entries themselves overlap
+                we take the longest overlapping extension beyond the end of the module...)
+                We assume that modules never overlap. */
 
-static struct type **
-hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
-{
-  unsigned old_len;
-  int index = hp_type.dnttp.index;
+             end_adr = CURR_MODULE_END;
 
-  if (hp_type.dntti.immediate)
-    return NULL;
+             if (VALID_CURR_FILE)
+               {
+                 while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
+                   {
 
-  if (index < LNTT_SYMCOUNT (objfile))
+#ifdef DUMPING
+                     if (dumping)
+                       printf ("Maybe skipping file %s which overlaps with module %s\n",
+                               &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
+#endif
+                     if (CURR_FILE_END > end_adr)
+                       {
+                         TELL_OBJFILE;
+                         warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
+                                  &vt_bits[(long) qFD[curr_fd].sbFile],
+                                  curr_fd, mod_name_string);
+                         end_adr = CURR_FILE_END;
+                       }
+                     curr_fd++;
+                   }
+                 curr_fd--;    /* back up after going too far */
+               }
+
+             /* Sometimes (compiler bug -- COBOL) the module end address is higher
+                than the start address of the next module, so check for that and
+                adjust accordingly */
+
+             if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+                          mod_name_string, curr_md);
+                 end_adr = MODULE_START (curr_md + 1) - 1;     /* Is -4 (or -8 for 64-bit) better? */
+               }
+             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+                          mod_name_string, curr_md);
+                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
+               }
+
+             /* Use one file to get the full name for the module.  This
+                situation can arise if there is executable code in a #include
+                file.  Each file with code in it gets a qFD.  Files which don't
+                contribute code don't get a qFD, even if they include files
+                which do, e.g.: 
+
+                body.c:                    rtn.h:
+                int x;                     int main() {
+                #include "rtn.h"               return x;
+                }
+
+                There will a qFD for "rtn.h",and a qMD for "body.c",
+                but no qMD for "rtn.h" or qFD for "body.c"!
+
+                We pick the name of the last file to overlap with this
+                module.  C convention is to put include files first.  In a
+                perfect world, we could check names and use the file whose full
+                path name ends with the module name. */
+
+             if (VALID_CURR_FILE)
+               full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+             else
+               full_name_string = mod_name_string;
+
+             /* Check if there are any procedures not handled until now, that
+                begin before the start address we have now, and if so, adjust
+                this psymtab's start address to include them.  This handles routines that
+                are in between file or module ranges for some reason (probably
+                indicates a compiler bug */
+
+             if (CURR_PROC_START < start_adr)
+               {
+                 TELL_OBJFILE;
+                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+                 start_adr = CURR_PROC_START;
+                 if (CURR_PROC_ISYM < start_sym)
+                   start_sym = CURR_PROC_ISYM;
+               }
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
+                    mod_name_string, start_adr, end_adr, full_name_string);
+               }
+#endif
+             /* Create the basic psymtab, connecting it in the list
+                for this objfile and pointing its symbol entries
+                to the current end of the symbol areas in the objfile.
+
+                The "ldsymoff" parameter is the byte offset in the LNTT
+                of the first symbol in this file.  Some day we should
+                turn this into an index (fix in hp-symtab-read.c as well).
+                And it's not even the right byte offset, as we're using
+                the size of a union! FIXME!  */
+             pst = hpread_start_psymtab (objfile,
+                                         full_name_string,
+                                         start_adr,    /* Low text address */
+                             (start_sym * sizeof (struct dntt_type_block)),
+             /* ldsymoff */
+                                         global_syms,
+                                         static_syms);
+
+             /* Set up to only enter each class referenced in this module once.  */
+             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+             /* Scan the procedure descriptors for procedures in the current
+                module, based on the starting addresses. */
+
+             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                                       start_adr, end_adr, pst, vt_bits, objfile);
+
+             /* Get ending symbol offset */
+
+             end_sym = 0;
+             /* First check for starting index before previous psymtab */
+             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+               {
+                 end_sym = find_next_pst_start (start_sym);
+               }
+             /* Look for next start index of a file or module, or procedure */
+             if (!end_sym)
+               {
+                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
+                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+                 if (next_file_isym && next_module_isym)
+                   {
+                     /* pick lower of next file or module start index */
+                     end_sym = min (next_file_isym, next_module_isym);
+                   }
+                 else
+                   {
+                     /* one of them is zero, pick the other */
+                     end_sym = max (next_file_isym, next_module_isym);
+                   }
+
+                 /* As a precaution, check next procedure index too */
+                 if (!end_sym)
+                   end_sym = next_proc_isym;
+                 else
+                   end_sym = min (end_sym, next_proc_isym);
+               }
+
+             /* Couldn't find procedure, file, or module, use globals as default */
+             if (!end_sym)
+               end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
+               }
+#endif
+
+             pst = hpread_end_psymtab (pst,
+                                       NULL,   /* psymtab_include_list */
+                                       0,      /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+             /* byte index in LNTT of end 
+                = capping symbol offset   
+                = LDSYMOFF of nextfile */
+                                       end_adr,        /* text high */
+                                       NULL,   /* dependency_list      */
+                                       0);     /* dependencies_used    */
+
+             record_pst_syms (start_sym, end_sym);
+
+             if (NULL == pst)
+               warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
+                         mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
+               }
+#endif
+
+             /* Prepare for the next psymtab. */
+             global_syms = objfile->global_psymbols.next;
+             static_syms = objfile->static_psymbols.next;
+             xfree (class_entered);
+
+             curr_md++;
+             curr_fd++;
+           }                   /* psymtab for module */
+       }                       /* psymtab for non-bogus file or module */
+    }                          /* End of while loop over all files & modules */
+
+  /* There may be some routines after all files and modules -- these will get
+     inserted in a separate new module of their own */
+  if (VALID_CURR_PROC)
     {
-      if (index >= TYPE_VECTOR_LENGTH (objfile))
+      start_adr = CURR_PROC_START;
+      end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
+      TELL_OBJFILE;
+      warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
+#ifdef DUMPING
+      if (dumping)
        {
-         old_len = TYPE_VECTOR_LENGTH (objfile);
-         if (old_len == 0)
-           {
-             TYPE_VECTOR_LENGTH (objfile) = 100;
-             TYPE_VECTOR (objfile) = (struct type **)
-               xmmalloc (objfile->md,
-                    TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
-           }
-         while (index >= TYPE_VECTOR_LENGTH (objfile))
-           TYPE_VECTOR_LENGTH (objfile) *= 2;
-         TYPE_VECTOR (objfile) = (struct type **)
-           xmrealloc (objfile->md,
-                      (char *) TYPE_VECTOR (objfile),
-                  (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
-         memset (&TYPE_VECTOR (objfile)[old_len], 0,
-                 (TYPE_VECTOR_LENGTH (objfile) - old_len) *
-                 sizeof (struct type *));
+         printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
+                 curr_pd, start_adr, end_adr);
        }
-      return &TYPE_VECTOR (objfile)[index];
+#endif
+      pst = hpread_start_psymtab (objfile,
+                                 "orphans",
+                                 start_adr,    /* Low text address */
+                        (CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
+      /* ldsymoff */
+                                 global_syms,
+                                 static_syms);
+
+      scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                 start_adr, end_adr, pst, vt_bits, objfile);
+
+      pst = hpread_end_psymtab (pst,
+                               NULL,   /* psymtab_include_list */
+                               0,      /* includes_used */
+                  pxdb_header_p->globals * sizeof (struct dntt_type_block),
+      /* byte index in LNTT of end 
+         = capping symbol offset   
+         = LDSYMOFF of nextfile */
+                               end_adr,        /* text high  */
+                               NULL,   /* dependency_list */
+                               0);     /* dependencies_used */
     }
-  else
-    return NULL;
-}
 
-/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
-   Note we'll just return the address of a GDB internal type if we already
-   have it lying around.  */
 
-static struct type *
-hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
-{
-  struct type **type_addr;
+#ifdef NEVER_NEVER
+  /* Now build psts for non-module things (in the tail of
+     the LNTT, after the last END MODULE entry).
+
+     If null psts were kept on the chain, this would be
+     a solution.  FIXME */
+  pst = hpread_start_psymtab (objfile,
+                             "globals",
+                             0,
+                             (pxdb_header_p->globals
+                              * sizeof (struct dntt_type_block)),
+                             objfile->global_psymbols.next,
+                             objfile->static_psymbols.next);
+  hpread_end_psymtab (pst,
+                     NULL, 0,
+                     (max_LNTT_sym_index * sizeof (struct dntt_type_block)),
+                     0,
+                     NULL, 0);
+#endif
 
-  type_addr = hpread_lookup_type (hp_type, objfile);
-  if (*type_addr == 0)
-    *type_addr = alloc_type (objfile);
+  clear_pst_syms ();
 
-  TYPE_CPLUS_SPECIFIC (*type_addr)
-    = (struct cplus_struct_type *) &cplus_struct_default;
-  return *type_addr;
-}
+  return 1;
 
-/* Read a native enumerated type and return it in GDB internal form.  */
+}                              /* End of hpread_quick_traverse. */
+\f
 
-static struct type *
-hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                      struct objfile *objfile)
+/* Get appropriate header, based on pxdb type. 
+   Return value: 1 if ok, 0 if not */
+int
+hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p)
 {
-  struct type *type;
-  struct pending **symlist, *osyms, *syms;
-  int o_nsyms, nsyms = 0;
-  dnttpointer mem;
-  union dnttentry *memp;
-  char *name;
-  long n;
-  struct symbol *sym;
+  asection *pinfo_section, *debug_section, *header_section;
 
-  type = hpread_alloc_type (hp_type, objfile);
-  TYPE_LENGTH (type) = 4;
+#ifdef DUMPING
+  /* Turn on for debugging information */
+  static int dumping = 0;
+#endif
 
-  symlist = &file_symbols;
-  osyms = *symlist;
+  header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
+  if (!header_section)
+    {
+      /* We don't have either PINFO or DEBUG sections.  But
+         stuff like "libc.sl" has no debug info.  There's no
+         need to warn the user of this, as it may be ok. The
+         caller will figure it out and issue any needed
+         messages. */
+#ifdef DUMPING
+      if (dumping)
+       printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+      return 0;
+    }
+
+  /* We would like either a $DEBUG$ or $PINFO$ section.
+     Once we know which, we can understand the header
+     data (which we have defined to suit the more common
+     $DEBUG$ case). */
+  debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
+  pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
+  if (debug_section)
+    {
+      /* The expected case: normal pxdb header. */
+      bfd_get_section_contents (objfile->obfd, header_section,
+                               pxdb_header_p, 0, sizeof (PXDB_header));
+
+      if (!pxdb_header_p->pxdbed)
+       {
+         /* This shouldn't happen if we check in "symfile.c". */
+         return 0;
+       }                       /* DEBUG section */
+    }
+
+  else if (pinfo_section)
+    {
+      /* The DOC case; we need to translate this into a
+         regular header. */
+      DOC_info_PXDB_header doc_header;
+
+#ifdef DUMPING
+      if (dumping)
+       {
+         printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
+       }
+#endif
+
+      bfd_get_section_contents (objfile->obfd,
+                               header_section,
+                               &doc_header, 0,
+                               sizeof (DOC_info_PXDB_header));
+
+      if (!doc_header.pxdbed)
+       {
+         /* This shouldn't happen if we check in "symfile.c". */
+         warning ("File \"%s\" not processed by pxdb!", objfile->name);
+         return 0;
+       }
+
+      /* Copy relevent fields to standard header passed in. */
+      pxdb_header_p->pd_entries = doc_header.pd_entries;
+      pxdb_header_p->fd_entries = doc_header.fd_entries;
+      pxdb_header_p->md_entries = doc_header.md_entries;
+      pxdb_header_p->pxdbed = doc_header.pxdbed;
+      pxdb_header_p->bighdr = doc_header.bighdr;
+      pxdb_header_p->sa_header = doc_header.sa_header;
+      pxdb_header_p->inlined = doc_header.inlined;
+      pxdb_header_p->globals = doc_header.globals;
+      pxdb_header_p->time = doc_header.time;
+      pxdb_header_p->pg_entries = doc_header.pg_entries;
+      pxdb_header_p->functions = doc_header.functions;
+      pxdb_header_p->files = doc_header.files;
+      pxdb_header_p->cd_entries = doc_header.cd_entries;
+      pxdb_header_p->aa_entries = doc_header.aa_entries;
+      pxdb_header_p->oi_entries = doc_header.oi_entries;
+      pxdb_header_p->version = doc_header.version;
+    }                          /* PINFO section */
+
+  else
+    {
+#ifdef DUMPING
+      if (dumping)
+       printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+      return 0;
+
+    }
+
+  return 1;
+}                              /* End of hpread_get_header */
+#endif /* QUICK_LOOK_UP */
+\f
+
+/* Initialization for reading native HP C debug symbols from OBJFILE.
+
+   Its only purpose in life is to set up the symbol reader's private
+   per-objfile data structures, and read in the raw contents of the debug
+   sections (attaching pointers to the debug info into the private data
+   structures).
+
+   Since BFD doesn't know how to read debug symbols in a format-independent
+   way (and may never do so...), we have to do it ourselves.  Note we may
+   be called on a file without native HP C debugging symbols.
+
+   FIXME, there should be a cleaner peephole into the BFD environment
+   here. */
+void
+hpread_symfile_init (struct objfile *objfile)
+{
+  asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_private = (PTR)
+    xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
+  memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+
+  /* We haven't read in any types yet.  */
+  TYPE_VECTOR (objfile) = 0;
+
+  /* Read in data from the $GNTT$ subspace.  */
+  gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
+  if (!gntt_section)
+    return;
+
+  GNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, gntt_section));
+
+  bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
+                        0, bfd_section_size (objfile->obfd, gntt_section));
+
+  GNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, gntt_section)
+    / sizeof (struct dntt_type_block);
+
+  /* Read in data from the $LNTT$ subspace.   Also keep track of the number
+     of LNTT symbols.
+
+     FIXME: this could be moved into the psymtab-to-symtab expansion
+     code, and save startup time.  At the moment this data is
+     still used, though.  We'd need a way to tell hp-symtab-read.c
+     whether or not to load the LNTT. */
+  lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
+  if (!lntt_section)
+    return;
+
+  LNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, lntt_section));
+
+  bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
+                        0, bfd_section_size (objfile->obfd, lntt_section));
+
+  LNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, lntt_section)
+    / sizeof (struct dntt_type_block);
+
+  /* Read in data from the $SLT$ subspace.  $SLT$ contains information
+     on source line numbers.  */
+  slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
+  if (!slt_section)
+    return;
+
+  SLT (objfile) =
+    obstack_alloc (&objfile->symbol_obstack,
+                  bfd_section_size (objfile->obfd, slt_section));
+
+  bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
+                         0, bfd_section_size (objfile->obfd, slt_section));
+
+  /* Read in data from the $VT$ subspace.  $VT$ contains things like
+     names and constants.  Keep track of the number of symbols in the VT.  */
+  vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
+  if (!vt_section)
+    return;
+
+  VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+
+  VT (objfile) =
+    (char *) obstack_alloc (&objfile->symbol_obstack,
+                           VT_SIZE (objfile));
+
+  bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
+                           0, VT_SIZE (objfile));
+}
+
+/* Scan and build partial symbols for a symbol file.
+
+   The minimal symbol table (either SOM or HP a.out) has already been
+   read in; all we need to do is setup partial symbols based on the
+   native debugging information.
+
+   Note that the minimal table is produced by the linker, and has
+   only global routines in it; the psymtab is based on compiler-
+   generated debug information and has non-global
+   routines in it as well as files and class information.
+
+   We assume hpread_symfile_init has been called to initialize the
+   symbol reader's private data structures.
+
+   MAINLINE is true if we are reading the main symbol table (as
+   opposed to a shared lib or dynamically loaded file). */
+
+void
+hpread_build_psymtabs (struct objfile *objfile, int mainline)
+{
+
+#ifdef DUMPING
+  /* Turn this on to get debugging output. */
+  static int dumping = 0;
+#endif
+
+  char *namestring;
+  int past_first_source_file = 0;
+  struct cleanup *old_chain;
+
+  int hp_symnum, symcount, i;
+  int scan_start = 0;
+
+  union dnttentry *dn_bufp;
+  unsigned long valu;
+  char *p;
+  int texthigh = 0;
+  int have_name = 0;
+
+  /* Current partial symtab */
+  struct partial_symtab *pst;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+
+  /* Just in case the stabs reader left turds lying around.  */
+  free_pending_blocks ();
+  make_cleanup (really_free_pendings, 0);
+
+  pst = (struct partial_symtab *) 0;
+
+  /* We shouldn't use alloca, instead use malloc/free.  Doing so avoids
+     a number of problems with cross compilation and creating useless holes
+     in the stack when we have to allocate new entries.  FIXME.  */
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  old_chain = make_cleanup_free_objfile (objfile);
+
+  last_source_file = 0;
+
+#ifdef QUICK_LOOK_UP
+  {
+    /* Begin code for new-style loading of quick look-up tables. */
+
+    /* elz: this checks whether the file has beeen processed by pxdb.
+       If not we would like to try to read the psymbols in
+       anyway, but it turns out to be not so easy. So this could 
+       actually be commented out, but I leave it in, just in case
+       we decide to add support for non-pxdb-ed stuff in the future. */
+    PXDB_header pxdb_header;
+    int found_modules_in_program;
+
+    if (hpread_get_header (objfile, &pxdb_header))
+      {
+       /* Build a minimal table.  No types, no global variables,
+          no include files.... */
+#ifdef DUMPING
+       if (dumping)
+         printf ("\nNew method for %s\n", objfile->name);
+#endif
+
+       /* elz: quick_traverse returns true if it found
+          some modules in the main source file, other
+          than those in end.c
+          In C and C++, all the files have MODULES entries
+          in the LNTT, and the quick table traverse is all 
+          based on finding these MODULES entries. Without 
+          those it cannot work. 
+          It happens that F77 programs don't have MODULES
+          so the quick traverse gets confused. F90 programs
+          have modules, and the quick method still works.
+          So, if modules (other than those in end.c) are
+          not found we give up on the quick table stuff, 
+          and fall back on the slower method  */
+       found_modules_in_program = hpread_quick_traverse (objfile,
+                                                         GNTT (objfile),
+                                                         VT (objfile),
+                                                         &pxdb_header);
+
+       discard_cleanups (old_chain);
+
+       /* Set up to scan the global section of the LNTT.
+
+          This field is not always correct: if there are
+          no globals, it will point to the last record in
+          the regular LNTT, which is usually an END MODULE.
+
+          Since it might happen that there could be a file
+          with just one global record, there's no way to
+          tell other than by looking at the record, so that's
+          done below. */
+       if (found_modules_in_program)
+         scan_start = pxdb_header.globals;
+      }
+#ifdef DUMPING
+    else
+      {
+       if (dumping)
+         printf ("\nGoing on to old method for %s\n", objfile->name);
+      }
+#endif
+  }
+#endif /* QUICK_LOOK_UP */
+
+  /* Make two passes, one over the GNTT symbols, the other for the
+     LNTT symbols.
+
+     JB comment: above isn't true--they only make one pass, over
+     the LNTT.  */
+  for (i = 0; i < 1; i++)
+    {
+      int within_function = 0;
+
+      if (i)
+       symcount = GNTT_SYMCOUNT (objfile);
+      else
+       symcount = LNTT_SYMCOUNT (objfile);
+
+
+      for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
+       {
+         QUIT;
+         if (i)
+           dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+         else
+           dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+
+         if (dn_bufp->dblock.extension)
+           continue;
+
+         /* Only handle things which are necessary for minimal symbols.
+            everything else is ignored.  */
+         switch (dn_bufp->dblock.kind)
+           {
+           case DNTT_TYPE_SRCFILE:
+             {
+#ifdef QUICK_LOOK_UP
+               if (scan_start == hp_symnum
+                   && symcount == hp_symnum + 1)
+                 {
+                   /* If there are NO globals in an executable,
+                      PXDB's index to the globals will point to
+                      the last record in the file, which 
+                      could be this record. (this happened for F77 libraries)
+                      ignore it and be done! */
+                   continue;
+                 }
+#endif /* QUICK_LOOK_UP */
+
+               /* A source file of some kind.  Note this may simply
+                  be an included file.  */
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+               /* Check if this is the source file we are already working
+                  with.  */
+               if (pst && !strcmp (namestring, pst->filename))
+                 continue;
+
+               /* Check if this is an include file, if so check if we have
+                  already seen it.  Add it to the include list */
+               p = strrchr (namestring, '.');
+               if (!strcmp (p, ".h"))
+                 {
+                   int j, found;
+
+                   found = 0;
+                   for (j = 0; j < includes_used; j++)
+                     if (!strcmp (namestring, psymtab_include_list[j]))
+                       {
+                         found = 1;
+                         break;
+                       }
+                   if (found)
+                     continue;
+
+                   /* Add it to the list of includes seen so far and
+                      allocate more include space if necessary.  */
+                   psymtab_include_list[includes_used++] = namestring;
+                   if (includes_used >= includes_allocated)
+                     {
+                       char **orig = psymtab_include_list;
+
+                       psymtab_include_list = (char **)
+                         alloca ((includes_allocated *= 2) *
+                                 sizeof (char *));
+                       memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                               includes_used * sizeof (char *));
+                     }
+                   continue;
+                 }
+
+               if (pst)
+                 {
+                   if (!have_name)
+                     {
+                       pst->filename = (char *)
+                         obstack_alloc (&pst->objfile->psymbol_obstack,
+                                        strlen (namestring) + 1);
+                       strcpy (pst->filename, namestring);
+                       have_name = 1;
+                       continue;
+                     }
+                   continue;
+                 }
+
+               /* This is a bonafide new source file.
+                  End the current partial symtab and start a new one.  */
+
+               if (pst && past_first_source_file)
+                 {
+                   hpread_end_psymtab (pst, psymtab_include_list,
+                                       includes_used,
+                                       (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                       texthigh,
+                                       dependency_list, dependencies_used);
+                   pst = (struct partial_symtab *) 0;
+                   includes_used = 0;
+                   dependencies_used = 0;
+                 }
+               else
+                 past_first_source_file = 1;
+
+               valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+               valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+               pst = hpread_start_psymtab (objfile,
+                                           namestring, valu,
+                                           (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                           objfile->global_psymbols.next,
+                                           objfile->static_psymbols.next);
+               texthigh = valu;
+               have_name = 1;
+               continue;
+             }
+
+           case DNTT_TYPE_MODULE:
+             /* A source file.  It's still unclear to me what the
+                real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
+                is supposed to be.  */
+
+             /* First end the previous psymtab */
+             if (pst)
+               {
+                 hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                                     ((hp_symnum - 1)
+                                      * sizeof (struct dntt_type_block)),
+                                     texthigh,
+                                     dependency_list, dependencies_used);
+                 pst = (struct partial_symtab *) 0;
+                 includes_used = 0;
+                 dependencies_used = 0;
+                 have_name = 0;
+               }
+
+             /* Now begin a new module and a new psymtab for it */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+             valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             if (!pst)
+               {
+                 pst = hpread_start_psymtab (objfile,
+                                             namestring, valu,
+                                             (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                             objfile->static_psymbols.next);
+                 texthigh = valu;
+                 have_name = 0;
+               }
+             continue;
+
+           case DNTT_TYPE_FUNCTION:
+           case DNTT_TYPE_ENTRY:
+             /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
+                a secondary entry point.  */
+             valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+                                                      SECT_OFF_TEXT (objfile));
+             if (valu > texthigh)
+               texthigh = valu;
+             valu = dn_bufp->dfunc.lowaddr +
+               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (dn_bufp->dfunc.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->global_psymbols, valu,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->static_psymbols, valu,
+                                    0, language_unknown, objfile);
+             within_function = 1;
+             continue;
+
+           case DNTT_TYPE_DOC_FUNCTION:
+             valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+                                                         SECT_OFF_TEXT (objfile));
+             if (valu > texthigh)
+               texthigh = valu;
+             valu = dn_bufp->ddocfunc.lowaddr +
+               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (dn_bufp->ddocfunc.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->global_psymbols, valu,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->static_psymbols, valu,
+                                    0, language_unknown, objfile);
+             within_function = 1;
+             continue;
+
+           case DNTT_TYPE_BEGIN:
+           case DNTT_TYPE_END:
+             /* We don't check MODULE end here, because there can be
+                symbols beyond the module end which properly belong to the
+                current psymtab -- so we wait till the next MODULE start */
+
+
+#ifdef QUICK_LOOK_UP
+             if (scan_start == hp_symnum
+                 && symcount == hp_symnum + 1)
+               {
+                 /* If there are NO globals in an executable,
+                    PXDB's index to the globals will point to
+                    the last record in the file, which is
+                    probably an END MODULE, i.e. this record.
+                    ignore it and be done! */
+                 continue;
+               }
+#endif /* QUICK_LOOK_UP */
+
+             /* Scope block begin/end.  We only care about function
+                and file blocks right now.  */
+
+             if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
+                 (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
+               within_function = 0;
+             continue;
+
+           case DNTT_TYPE_SVAR:
+           case DNTT_TYPE_DVAR:
+           case DNTT_TYPE_TYPEDEF:
+           case DNTT_TYPE_TAGDEF:
+             {
+               /* Variables, typedefs an the like.  */
+               enum address_class storage;
+               namespace_enum namespace;
+
+               /* Don't add locals to the partial symbol table.  */
+               if (within_function
+                   && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
+                       || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
+                 continue;
+
+               /* TAGDEFs go into the structure namespace.  */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
+                 namespace = STRUCT_NAMESPACE;
+               else
+                 namespace = VAR_NAMESPACE;
+
+               /* What kind of "storage" does this use?  */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
+                 storage = LOC_STATIC;
+               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
+                        && dn_bufp->ddvar.regvar)
+                 storage = LOC_REGISTER;
+               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
+                 storage = LOC_LOCAL;
+               else
+                 storage = LOC_UNDEF;
+
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+               if (!pst)
+                 {
+                   pst = hpread_start_psymtab (objfile,
+                                               "globals", 0,
+                                               (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                            objfile->static_psymbols.next);
+                 }
+
+               /* Compute address of the data symbol */
+               valu = dn_bufp->dsvar.location;
+               /* Relocate in case it's in a shared library */
+               if (storage == LOC_STATIC)
+                 valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+
+               /* Luckily, dvar, svar, typedef, and tagdef all
+                  have their "global" bit in the same place, so it works
+                  (though it's bad programming practice) to reference
+                  "dsvar.global" even though we may be looking at
+                  any of the above four types. */
+               if (dn_bufp->dsvar.global)
+                 {
+                   add_psymbol_to_list (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        &objfile->global_psymbols,
+                                        valu,
+                                        0, language_unknown, objfile);
+                 }
+               else
+                 {
+                   add_psymbol_to_list (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        &objfile->static_psymbols,
+                                        valu,
+                                        0, language_unknown, objfile);
+                 }
+
+               /* For TAGDEF's, the above code added the tagname to the
+                  struct namespace. This will cause tag "t" to be found
+                  on a reference of the form "(struct t) x". But for
+                  C++ classes, "t" will also be a typename, which we
+                  want to find on a reference of the form "ptype t".
+                  Therefore, we also add "t" to the var namespace.
+                  Do the same for enum's due to the way aCC generates
+                  debug info for these (see more extended comment
+                  in hp-symtab-read.c).
+                  We do the same for templates, so that "ptype t"
+                  where "t" is a template also works. */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
+                 dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+                 {
+                   int global = dn_bufp->dtag.global;
+                   /* Look ahead to see if it's a C++ class */
+                   dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+                   if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+                       dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+                       dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+                     {
+                       if (global)
+                         {
+                           add_psymbol_to_list (namestring, strlen (namestring),
+                                                VAR_NAMESPACE, storage,
+                                                &objfile->global_psymbols,
+                                                dn_bufp->dsvar.location,
+                                             0, language_unknown, objfile);
+                         }
+                       else
+                         {
+                           add_psymbol_to_list (namestring, strlen (namestring),
+                                                VAR_NAMESPACE, storage,
+                                                &objfile->static_psymbols,
+                                                dn_bufp->dsvar.location,
+                                             0, language_unknown, objfile);
+                         }
+                     }
+                 }
+             }
+             continue;
+
+           case DNTT_TYPE_MEMENUM:
+           case DNTT_TYPE_CONST:
+             /* Constants and members of enumerated types.  */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (!pst)
+               {
+                 pst = hpread_start_psymtab (objfile,
+                                             "globals", 0,
+                                             (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                             objfile->static_psymbols.next);
+               }
+             if (dn_bufp->dconst.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_CONST,
+                                    &objfile->global_psymbols, 0,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_CONST,
+                                    &objfile->static_psymbols, 0,
+                                    0, language_unknown, objfile);
+             continue;
+           default:
+             continue;
+           }
+       }
+    }
+
+  /* End any pending partial symbol table. */
+  if (pst)
+    {
+      hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                         hp_symnum * sizeof (struct dntt_type_block),
+                         0, dependency_list, dependencies_used);
+    }
+
+  discard_cleanups (old_chain);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+void
+hpread_symfile_finish (struct objfile *objfile)
+{
+  if (objfile->sym_private != NULL)
+    {
+      xmfree (objfile->md, objfile->sym_private);
+    }
+}
+\f
+
+/* The remaining functions are all for internal use only.  */
+
+/* Various small functions to get entries in the debug symbol sections.  */
+
+union dnttentry *
+hpread_get_lntt (int index, struct objfile *objfile)
+{
+  return (union dnttentry *)
+    &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+static union dnttentry *
+hpread_get_gntt (int index, struct objfile *objfile)
+{
+  return (union dnttentry *)
+    &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+union sltentry *
+hpread_get_slt (int index, struct objfile *objfile)
+{
+  return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
+}
+
+/* Get the low address associated with some symbol (typically the start
+   of a particular source file or module).  Since that information is not
+   stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we
+   must infer it from the existence of DNTT_TYPE_FUNCTION symbols.  */
+
+static unsigned long
+hpread_get_textlow (int global, int index, struct objfile *objfile,
+                   int symcount)
+{
+  union dnttentry *dn_bufp;
+  struct minimal_symbol *msymbol;
+
+  /* Look for a DNTT_TYPE_FUNCTION symbol.  */
+  if (index < symcount)                /* symcount is the number of symbols in */
+    {                          /*   the dbinfo, LNTT table */
+      do
+       {
+         if (global)
+           dn_bufp = hpread_get_gntt (index++, objfile);
+         else
+           dn_bufp = hpread_get_lntt (index++, objfile);
+       }
+      while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
+            && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
+            && dn_bufp->dblock.kind != DNTT_TYPE_END
+            && index < symcount);
+    }
+
+  /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION.  This
+     might happen when a sourcefile has no functions.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_END)
+    return 0;
+
+  /* Avoid going past the end of the LNTT file */
+  if (index == symcount)
+    return 0;
+
+  /* The minimal symbols are typically more accurate for some reason.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
+    msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
+                                    objfile);
+  else                         /* must be a DNTT_TYPE_DOC_FUNCTION */
+    msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
+                                    objfile);
+
+  if (msymbol)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
+  else
+    return dn_bufp->dfunc.lowaddr;
+}
+
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+   is the address relative to which its symbols are (incremental) or 0
+   (normal). */
+
+static struct partial_symtab *
+hpread_start_psymtab (struct objfile *objfile, char *filename,
+                     CORE_ADDR textlow, int ldsymoff,
+                     struct partial_symbol **global_syms,
+                     struct partial_symbol **static_syms)
+{
+  int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+  extern void hpread_psymtab_to_symtab ();
+  struct partial_symtab *result =
+  start_psymtab_common (objfile, objfile->section_offsets,
+                       filename, textlow, global_syms, static_syms);
+
+  result->textlow += offset;
+  result->read_symtab_private = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  LDSYMOFF (result) = ldsymoff;
+  result->read_symtab = hpread_psymtab_to_symtab;
+
+  return result;
+}
+\f
+
+/* Close off the current usage of PST.  
+   Returns PST or NULL if the partial symtab was empty and thrown away.
+
+   capping_symbol_offset  --Byte index in LNTT or GNTT of the
+   last symbol processed during the build
+   of the previous pst.
+
+   FIXME:  List variables and peculiarities of same.  */
+
+static struct partial_symtab *
+hpread_end_psymtab (struct partial_symtab *pst, char **include_list,
+                   int num_includes, int capping_symbol_offset,
+                   CORE_ADDR capping_text,
+                   struct partial_symtab **dependency_list,
+                   int number_dependencies)
+{
+  int i;
+  struct objfile *objfile = pst->objfile;
+  int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+
+#ifdef DUMPING
+  /* Turn on to see what kind of a psymtab we've built. */
+  static int dumping = 0;
+#endif
+
+  if (capping_symbol_offset != -1)
+    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+  else
+    LDSYMLEN (pst) = 0;
+  pst->texthigh = capping_text + offset;
+
+  pst->n_global_syms =
+    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+  pst->n_static_syms =
+    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
+             pst->filename,
+             LDSYMOFF (pst),
+             LDSYMOFF (pst) / sizeof (struct dntt_type_block),
+             LDSYMLEN (pst),
+             LDSYMLEN (pst) / sizeof (struct dntt_type_block),
+             pst->n_global_syms, pst->n_static_syms);
+    }
+#endif
+
+  pst->number_of_dependencies = number_dependencies;
+  if (number_dependencies)
+    {
+      pst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                   number_dependencies * sizeof (struct partial_symtab *));
+      memcpy (pst->dependencies, dependency_list,
+             number_dependencies * sizeof (struct partial_symtab *));
+    }
+  else
+    pst->dependencies = 0;
+
+  for (i = 0; i < num_includes; i++)
+    {
+      struct partial_symtab *subpst =
+      allocate_psymtab (include_list[i], objfile);
+
+      subpst->section_offsets = pst->section_offsets;
+      subpst->read_symtab_private =
+       (char *) obstack_alloc (&objfile->psymbol_obstack,
+                               sizeof (struct symloc));
+      LDSYMOFF (subpst) =
+       LDSYMLEN (subpst) =
+       subpst->textlow =
+       subpst->texthigh = 0;
+
+      /* We could save slight bits of space by only making one of these,
+         shared by the entire set of include files.  FIXME-someday.  */
+      subpst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      sizeof (struct partial_symtab *));
+      subpst->dependencies[0] = pst;
+      subpst->number_of_dependencies = 1;
+
+      subpst->globals_offset =
+       subpst->n_global_syms =
+       subpst->statics_offset =
+       subpst->n_static_syms = 0;
+
+      subpst->readin = 0;
+      subpst->symtab = 0;
+      subpst->read_symtab = pst->read_symtab;
+    }
+
+  sort_pst_symbols (pst);
+
+  /* If there is already a psymtab or symtab for a file of this name, remove it.
+     (If there is a symtab, more drastic things also happen.)
+     This happens in VxWorks.  */
+  free_named_symtabs (pst->filename);
+
+  if (num_includes == 0
+      && number_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0)
+    {
+      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
+         it is on the obstack, but we can forget to chain it on the list. 
+         Empty psymtabs happen as a result of header files which don't have
+         any symbols in them.  There can be a lot of them.  But this check
+         is wrong, in that a psymtab with N_SLINE entries but nothing else
+         is not empty, but we don't realize that.  Fixing that without slowing
+         things down might be tricky.
+         It's also wrong if we're using the quick look-up tables, as
+         we can get empty psymtabs from modules with no routines in
+         them. */
+
+      discard_psymtab (pst);
+
+      /* Indicate that psymtab was thrown away.  */
+      pst = (struct partial_symtab *) NULL;
+
+    }
+  return pst;
+}
+
+\f
+/* Get the nesting depth for the source line identified by INDEX.  */
+
+static unsigned long
+hpread_get_scope_start (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->sspec.backptr.dnttp.index;
+}
+
+/* Get the source line number the the line identified by INDEX.  */
+
+static unsigned long
+hpread_get_line (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->snorm.line;
+}
+
+/* Find the code address associated with a given sltpointer */
+
+static CORE_ADDR
+hpread_get_location (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+  int i;
+
+  /* code location of special sltentrys is determined from context */
+  sl_bufp = hpread_get_slt (index, objfile);
+
+  if (sl_bufp->snorm.sltdesc == SLT_END)
+    {
+      /* find previous normal sltentry and get address */
+      for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+                  (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+                  (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+       sl_bufp = hpread_get_slt (index - i, objfile);
+      if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+       return sl_bufp->snormoff.address;
+      else
+       return sl_bufp->snorm.address;
+    }
+
+  /* find next normal sltentry and get address */
+  for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+              (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+              (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+    sl_bufp = hpread_get_slt (index + i, objfile);
+  if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+    return sl_bufp->snormoff.address;
+  else
+    return sl_bufp->snorm.address;
+}
+\f
+
+/* Return 1 if an HP debug symbol of type KIND has a name associated with
+ * it, else return 0. (This function is not currently used, but I'll
+ * leave it here in case it proves useful later on. - RT).
+ */
+
+int
+hpread_has_name (enum dntt_entry_type kind)
+{
+  switch (kind)
+    {
+    case DNTT_TYPE_SRCFILE:
+    case DNTT_TYPE_MODULE:
+    case DNTT_TYPE_FUNCTION:
+    case DNTT_TYPE_DOC_FUNCTION:
+    case DNTT_TYPE_ENTRY:
+    case DNTT_TYPE_IMPORT:
+    case DNTT_TYPE_LABEL:
+    case DNTT_TYPE_FPARAM:
+    case DNTT_TYPE_SVAR:
+    case DNTT_TYPE_DVAR:
+    case DNTT_TYPE_CONST:
+    case DNTT_TYPE_TYPEDEF:
+    case DNTT_TYPE_TAGDEF:
+    case DNTT_TYPE_MEMENUM:
+    case DNTT_TYPE_FIELD:
+    case DNTT_TYPE_SA:
+    case DNTT_TYPE_BLOCKDATA:
+    case DNTT_TYPE_MEMFUNC:
+    case DNTT_TYPE_DOC_MEMFUNC:
+      return 1;
+
+    case DNTT_TYPE_BEGIN:
+    case DNTT_TYPE_END:
+    case DNTT_TYPE_POINTER:
+    case DNTT_TYPE_ENUM:
+    case DNTT_TYPE_SET:
+    case DNTT_TYPE_ARRAY:
+    case DNTT_TYPE_STRUCT:
+    case DNTT_TYPE_UNION:
+    case DNTT_TYPE_VARIANT:
+    case DNTT_TYPE_FILE:
+    case DNTT_TYPE_FUNCTYPE:
+    case DNTT_TYPE_SUBRANGE:
+    case DNTT_TYPE_WITH:
+    case DNTT_TYPE_COMMON:
+    case DNTT_TYPE_COBSTRUCT:
+    case DNTT_TYPE_XREF:
+    case DNTT_TYPE_MACRO:
+    case DNTT_TYPE_CLASS_SCOPE:
+    case DNTT_TYPE_REFERENCE:
+    case DNTT_TYPE_PTRMEM:
+    case DNTT_TYPE_PTRMEMFUNC:
+    case DNTT_TYPE_CLASS:
+    case DNTT_TYPE_GENFIELD:
+    case DNTT_TYPE_VFUNC:
+    case DNTT_TYPE_MEMACCESS:
+    case DNTT_TYPE_INHERITANCE:
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+    case DNTT_TYPE_MODIFIER:
+    case DNTT_TYPE_OBJECT_ID:
+    case DNTT_TYPE_TEMPLATE:
+    case DNTT_TYPE_TEMPLATE_ARG:
+    case DNTT_TYPE_FUNC_TEMPLATE:
+    case DNTT_TYPE_LINK:
+      /* DNTT_TYPE_DYN_ARRAY_DESC ? */
+      /* DNTT_TYPE_DESC_SUBRANGE ? */
+      /* DNTT_TYPE_BEGIN_EXT ? */
+      /* DNTT_TYPE_INLN ? */
+      /* DNTT_TYPE_INLN_LIST ? */
+      /* DNTT_TYPE_ALIAS ? */
+    default:
+      return 0;
+    }
+}
+
+/* Do the dirty work of reading in the full symbol from a partial symbol
+   table.  */
+
+static void
+hpread_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  struct cleanup *old_chain;
+  int i;
+
+  /* Get out quick if passed junk.  */
+  if (!pst)
+    return;
+
+  /* Complain if we've already read in this symbol table.  */
+  if (pst->readin)
+    {
+      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+              pst->filename);
+      return;
+    }
+
+  /* Read in all partial symtabs on which this one is dependent */
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files that need to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", gdb_stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", gdb_stdout);
+           wrap_here ("");
+           printf_filtered ("%s...", pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           gdb_flush (gdb_stdout);
+         }
+       hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  /* If it's real...  */
+  if (LDSYMLEN (pst))
+    {
+      /* Init stuff necessary for reading in symbols */
+      buildsym_init ();
+      old_chain = make_cleanup (really_free_pendings, 0);
+
+      pst->symtab =
+       hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
+                             pst->textlow, pst->texthigh - pst->textlow,
+                             pst->section_offsets, pst->filename);
+      sort_symtab_syms (pst->symtab);
+
+      do_cleanups (old_chain);
+    }
+
+  pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+   Be verbose about it if the user wants that.  */
+
+void
+hpread_psymtab_to_symtab (struct partial_symtab *pst)
+{
+  /* Get out quick if given junk.  */
+  if (!pst)
+    return;
+
+  /* Sanity check.  */
+  if (pst->readin)
+    {
+      fprintf (stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+              pst->filename);
+      return;
+    }
+
+  /* elz: setting the flag to indicate that the code of the target
+     was compiled using an HP compiler (aCC, cc) 
+     the processing_acc_compilation variable is declared in the 
+     file buildsym.h, the HP_COMPILED_TARGET is defined to be equal
+     to 3 in the file tm_hppa.h */
+
+  processing_gcc_compilation = 0;
+
+  if (LDSYMLEN (pst) || pst->number_of_dependencies)
+    {
+      /* Print the message now, before reading the string table,
+         to avoid disconcerting pauses.  */
+      if (info_verbose)
+       {
+         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         gdb_flush (gdb_stdout);
+       }
+
+      hpread_psymtab_to_symtab_1 (pst);
+
+      /* Match with global symbols.  This only needs to be done once,
+         after all of the symtabs and dependencies have been read in.   */
+      scan_file_globals (pst->objfile);
+
+      /* Finish up the debug error message.  */
+      if (info_verbose)
+       printf_filtered ("done.\n");
+    }
+}
+
+/* Read in a defined section of a specific object file's symbols.
+
+   DESC is the file descriptor for the file, positioned at the
+   beginning of the symtab
+   SYM_OFFSET is the offset within the file of
+   the beginning of the symbols we want to read
+   SYM_SIZE is the size of the symbol info to read in.
+   TEXT_OFFSET is the beginning of the text segment we are reading symbols for
+   TEXT_SIZE is the size of the text segment read in.
+   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+
+static struct symtab *
+hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
+                     CORE_ADDR text_offset, int text_size,
+                     struct section_offsets *section_offsets, char *filename)
+{
+  char *namestring;
+  union dnttentry *dn_bufp;
+  unsigned max_symnum;
+  int at_module_boundary = 0;
+  /* 1 => at end, -1 => at beginning */
+
+  int sym_index = sym_offset / sizeof (struct dntt_type_block);
+
+  current_objfile = objfile;
+  subfile_stack = 0;
+
+  last_source_file = 0;
+
+  /* Demangling style -- if EDG style already set, don't change it,
+     as HP style causes some problems with the KAI EDG compiler */
+  if (current_demangling_style != edg_demangling)
+    {
+      /* Otherwise, ensure that we are using HP style demangling */
+      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+    }
+
+  dn_bufp = hpread_get_lntt (sym_index, objfile);
+  if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
+       (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
+    {
+      start_symtab ("globals", NULL, 0);
+      record_debugformat ("HP");
+    }
+
+  /* The psymtab builder (hp-psymtab-read.c) is the one that
+   * determined the "sym_size" argument (i.e. how many DNTT symbols
+   * are in this symtab), which we use to compute "max_symnum"
+   * (point in DNTT to which we read). 
+   *
+   * Perhaps this should be changed so that 
+   * process_one_debug_symbol() "knows" when
+   * to stop reading (based on reading from the MODULE to the matching
+   * END), and take out this reliance on a #-syms being passed in...
+   * (I'm worried about the reliability of this number). But I'll
+   * leave it as-is, for now. - RT
+   *
+   * The change above has been made. I've left the "for" loop control
+   * in to prepare for backing this out again. -JB
+   */
+  max_symnum = sym_size / sizeof (struct dntt_type_block);
+  /* No reason to multiply on pst side and divide on sym side... FIXME */
+
+  /* Read in and process each debug symbol within the specified range.
+   */
+  for (symnum = 0;
+       symnum < max_symnum;
+       symnum++)
+    {
+      QUIT;                    /* Allow this to be interruptable */
+      dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+
+      if (dn_bufp->dblock.extension)
+       continue;
+
+      /* Yow!  We call SET_NAMESTRING on things without names!  */
+      SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+      hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
+                                      objfile, text_offset, text_size,
+                                      filename, symnum + sym_index,
+                                      &at_module_boundary
+       );
+
+      /* OLD COMMENTS: This routine is only called for psts.  All psts
+       * correspond to MODULES.  If we ever do lazy-reading of globals
+       * from the LNTT, then there will be a pst which ends when the
+       * LNTT ends, and not at an END MODULE entry.  Then we'll have
+       * to re-visit this break.  
+
+       if( at_end_of_module )
+       break;
+
+       */
+
+      /* We no longer break out of the loop when we reach the end of a
+         module. The reason is that with CTTI, the compiler can generate
+         function symbols (for template function instantiations) which are not
+         in any module; typically they show up beyond a module's end, and
+         before the next module's start.  We include them in the current
+         module.  However, we still don't trust the MAX_SYMNUM value from
+         the psymtab, so we break out if we enter a new module. */
+
+      if (at_module_boundary == -1)
+       break;
+    }
+
+  current_objfile = NULL;
+  hp_som_som_object_present = 1;       /* Indicate we've processed an HP SOM SOM file */
+
+  return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+}
+\f
+
+
+
+/* Convert basic types from HP debug format into GDB internal format.  */
+
+static int
+hpread_type_translate (dnttpointer typep)
+{
+  if (!typep.dntti.immediate)
+    {
+      error ("error in hpread_type_translate\n.");
+      return FT_VOID;
+    }
+
+  switch (typep.dntti.type)
+    {
+    case HP_TYPE_BOOLEAN:
+    case HP_TYPE_BOOLEAN_S300_COMPAT:
+    case HP_TYPE_BOOLEAN_VAX_COMPAT:
+      return FT_BOOLEAN;
+    case HP_TYPE_CHAR:         /* C signed char, C++ plain char */
+
+    case HP_TYPE_WIDE_CHAR:
+      return FT_CHAR;
+    case HP_TYPE_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_SIGNED_CHAR;  /* C++ signed char */
+      if (typep.dntti.bitlength <= 16)
+       return FT_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_INTEGER;
+      return FT_LONG_LONG;
+    case HP_TYPE_LONG:
+      if (typep.dntti.bitlength <= 8)
+       return FT_SIGNED_CHAR;  /* C++ signed char. */
+      return FT_LONG;
+    case HP_TYPE_UNSIGNED_LONG:
+      if (typep.dntti.bitlength <= 8)
+       return FT_UNSIGNED_CHAR;        /* C/C++ unsigned char */
+      if (typep.dntti.bitlength <= 16)
+       return FT_UNSIGNED_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_UNSIGNED_LONG;
+      return FT_UNSIGNED_LONG_LONG;
+    case HP_TYPE_UNSIGNED_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_UNSIGNED_CHAR;
+      if (typep.dntti.bitlength <= 16)
+       return FT_UNSIGNED_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_UNSIGNED_INTEGER;
+      return FT_UNSIGNED_LONG_LONG;
+    case HP_TYPE_REAL:
+    case HP_TYPE_REAL_3000:
+    case HP_TYPE_DOUBLE:
+      if (typep.dntti.bitlength == 64)
+       return FT_DBL_PREC_FLOAT;
+      if (typep.dntti.bitlength == 128)
+       return FT_EXT_PREC_FLOAT;
+      return FT_FLOAT;
+    case HP_TYPE_COMPLEX:
+    case HP_TYPE_COMPLEXS3000:
+      if (typep.dntti.bitlength == 128)
+       return FT_DBL_PREC_COMPLEX;
+      if (typep.dntti.bitlength == 192)
+       return FT_EXT_PREC_COMPLEX;
+      return FT_COMPLEX;
+    case HP_TYPE_VOID:
+      return FT_VOID;
+    case HP_TYPE_STRING200:
+    case HP_TYPE_LONGSTRING200:
+    case HP_TYPE_FTN_STRING_SPEC:
+    case HP_TYPE_MOD_STRING_SPEC:
+    case HP_TYPE_MOD_STRING_3000:
+    case HP_TYPE_FTN_STRING_S300_COMPAT:
+    case HP_TYPE_FTN_STRING_VAX_COMPAT:
+      return FT_STRING;
+    case HP_TYPE_TEMPLATE_ARG:
+      return FT_TEMPLATE_ARG;
+    case HP_TYPE_TEXT:
+    case HP_TYPE_FLABEL:
+    case HP_TYPE_PACKED_DECIMAL:
+    case HP_TYPE_ANYPOINTER:
+    case HP_TYPE_GLOBAL_ANYPOINTER:
+    case HP_TYPE_LOCAL_ANYPOINTER:
+    default:
+      warning ("hpread_type_translate: unhandled type code.\n");
+      return FT_VOID;
+    }
+}
+
+/* Given a position in the DNTT, return a pointer to the 
+ * already-built "struct type" (if any), for the type defined 
+ * at that position.
+ */
+
+static struct type **
+hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
+{
+  unsigned old_len;
+  int index = hp_type.dnttp.index;
+  int size_changed = 0;
+
+  /* The immediate flag indicates this doesn't actually point to
+   * a type DNTT.
+   */
+  if (hp_type.dntti.immediate)
+    return NULL;
+
+  /* For each objfile, we maintain a "type vector".
+   * This an array of "struct type *"'s with one pointer per DNTT index.
+   * Given a DNTT index, we look in this array to see if we have
+   * already processed this DNTT and if it is a type definition.
+   * If so, then we can locate a pointer to the already-built
+   * "struct type", and not build it again.
+   * 
+   * The need for this arises because our DNTT-walking code wanders
+   * around. In particular, it will encounter the same type multiple
+   * times (once for each object of that type). We don't want to 
+   * built multiple "struct type"'s for the same thing.
+   *
+   * Having said this, I should point out that this type-vector is
+   * an expensive way to keep track of this. If most DNTT entries are 
+   * 3 words, the type-vector will be 1/3 the size of the DNTT itself.
+   * Alternative solutions:
+   * - Keep a compressed or hashed table. Less memory, but more expensive
+   *   to search and update.
+   * - (Suggested by JB): Overwrite the DNTT entry itself
+   *   with the info. Create a new type code "ALREADY_BUILT", and modify
+   *   the DNTT to have that type code and point to the already-built entry.
+   * -RT
+   */
+
+  if (index < LNTT_SYMCOUNT (objfile))
+    {
+      if (index >= TYPE_VECTOR_LENGTH (objfile))
+       {
+         old_len = TYPE_VECTOR_LENGTH (objfile);
+
+         /* See if we need to allocate a type-vector. */
+         if (old_len == 0)
+           {
+             TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
+             TYPE_VECTOR (objfile) = (struct type **)
+               xmmalloc (objfile->md, TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
+             memset (&TYPE_VECTOR (objfile)[old_len], 0,
+                     (TYPE_VECTOR_LENGTH (objfile) - old_len) *
+                     sizeof (struct type *));
+           }
+
+         /* See if we need to resize type-vector. With my change to
+          * initially allocate a correct-size type-vector, this code
+          * should no longer trigger.
+          */
+         while (index >= TYPE_VECTOR_LENGTH (objfile))
+           {
+             TYPE_VECTOR_LENGTH (objfile) *= 2;
+             size_changed = 1;
+           }
+         if (size_changed)
+           {
+             TYPE_VECTOR (objfile) = (struct type **)
+               xmrealloc (objfile->md,
+                          (char *) TYPE_VECTOR (objfile),
+                  (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
+
+             memset (&TYPE_VECTOR (objfile)[old_len], 0,
+                     (TYPE_VECTOR_LENGTH (objfile) - old_len) *
+                     sizeof (struct type *));
+           }
+
+       }
+      return &TYPE_VECTOR (objfile)[index];
+    }
+  else
+    return NULL;
+}
+
+/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
+   Note we'll just return the address of a GDB internal type if we already
+   have it lying around.  */
+
+static struct type *
+hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
+{
+  struct type **type_addr;
+
+  type_addr = hpread_lookup_type (hp_type, objfile);
+  if (*type_addr == 0)
+    {
+      *type_addr = alloc_type (objfile);
+
+      /* A hack - if we really are a C++ class symbol, then this default
+       * will get overriden later on.
+       */
+      TYPE_CPLUS_SPECIFIC (*type_addr)
+       = (struct cplus_struct_type *) &cplus_struct_default;
+    }
+
+  return *type_addr;
+}
+
+/* Read a native enumerated type and return it in GDB internal form.  */
+
+static struct type *
+hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                      struct objfile *objfile)
+{
+  struct type *type;
+  struct pending **symlist, *osyms, *syms;
+  struct pending *local_list = NULL;
+  int o_nsyms, nsyms = 0;
+  dnttpointer mem;
+  union dnttentry *memp;
+  char *name;
+  long n;
+  struct symbol *sym;
+
+  /* Allocate a GDB type. If we've already read in this enum type,
+   * it'll return the already built GDB type, so stop here.
+   * (Note: I added this check, to conform with what's done for 
+   *  struct, union, class.
+   *  I assume this is OK. - RT)
+   */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+    return type;
+
+  /* HP C supports "sized enums", where a specifier such as "short" or
+     "char" can be used to get enums of different sizes. So don't assume
+     an enum is always 4 bytes long. pai/1997-08-21 */
+  TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
+
+  symlist = &file_symbols;
+  osyms = *symlist;
   o_nsyms = osyms ? osyms->nsyms : 0;
 
-  /* Get a name for each member and add it to our list of members.  */
+  /* Get a name for each member and add it to our list of members.  
+   * The list of "mem" SOM records we are walking should all be
+   * SOM type DNTT_TYPE_MEMENUM (not checked).
+   */
   mem = dn_bufp->denum.firstmem;
-  while (mem.dnttp.extension && mem.word != DNTTNIL)
+  while (mem.word && mem.word != DNTTNIL)
     {
       memp = hpread_get_lntt (mem.dnttp.index, objfile);
 
@@ -1265,46 +3181,237 @@ hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
          TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
          TYPE_FIELD_BITSIZE (type, n) = 0;
        }
-      if (syms == osyms)
-       break;
+      if (syms == osyms)
+       break;
+    }
+
+  return type;
+}
+
+/* Read and internalize a native function debug symbol.  */
+
+static struct type *
+hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                          struct objfile *objfile, int newblock)
+{
+  struct type *type, *type1;
+  struct pending *syms;
+  struct pending *local_list = NULL;
+  int nsyms = 0;
+  dnttpointer param;
+  union dnttentry *paramp;
+  char *name;
+  long n;
+  struct symbol *sym;
+  int record_args = 1;
+
+  /* See if we've already read in this type.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+    {
+      record_args = 0;         /* already read in, don't modify type */
+    }
+  else
+    {
+      /* Nope, so read it in and store it away.  */
+      if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+         dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
+                                                         objfile));
+      else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
+                                                         objfile));
+      else                     /* expect DNTT_TYPE_FUNC_TEMPLATE */
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
+                                                         objfile));
+      memcpy ((char *) type, (char *) type1, sizeof (struct type));
+
+      /* Mark it -- in the middle of processing */
+      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+    }
+
+  /* Now examine each parameter noting its type, location, and a
+     wealth of other information.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+      dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+    param = dn_bufp->dfunc.firstparam;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+    param = dn_bufp->dfunctype.firstparam;
+  else                         /* expect DNTT_TYPE_FUNC_TEMPLATE */
+    param = dn_bufp->dfunc_template.firstparam;
+  while (param.word && param.word != DNTTNIL)
+    {
+      paramp = hpread_get_lntt (param.dnttp.index, objfile);
+      nsyms++;
+      param = paramp->dfparam.nextparam;
+
+      /* Get the name.  */
+      name = VT (objfile) + paramp->dfparam.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      (void) memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                       &objfile->symbol_obstack);
+
+      /* Figure out where it lives.  */
+      if (paramp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGPARM;
+      else if (paramp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (paramp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+         /* This is likely a pass-by-invisible reference parameter,
+            Hack on the symbol class to make GDB happy.  */
+         /* ??rehrauer: This appears to be broken w/r/t to passing
+            C values of type float and struct.  Perhaps this ought
+            to be highighted as a special case, but for now, just
+            allowing these to be LOC_ARGs seems to work fine.
+          */
+#if 0
+         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+      /* Get its type.  */
+      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+      /* Add it to the symbol list.  */
+      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+       * called on FPARAM symbols from the process_one_debug_symbol()
+       * level... so parameters are getting added twice! (this shows
+       * up in the symbol dump you get from "maint print symbols ...").
+       * Note 2 (RT) I took out the processing of FPARAM from the 
+       * process_one_debug_symbol() level, so at the moment parameters are only
+       * being processed here. This seems to have no ill effect.
+       */
+      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+         each fparam on the local_symbols list from here.  Now we use the
+         local_list to which fparams are added below, and set the param_symbols
+         global to point to that at the end of this routine. */
+      /* elz: I added this new list of symbols which is local to the function.
+         this list is the one which is actually used to build the type for the
+         function rather than the gloabal list pointed to by symlist.
+         Using a global list to keep track of the parameters is wrong, because 
+         this function is called recursively if one parameter happend to be
+         a function itself with more parameters in it. Adding parameters to the
+         same global symbol list would not work!      
+         Actually it did work in case of cc compiled programs where you do 
+         not check the parameter lists of the arguments. */
+      add_symbol_to_list (sym, &local_list);
+
+    }
+
+  /* If type was read in earlier, don't bother with modifying
+     the type struct */
+  if (!record_args)
+    goto finish;
+
+  /* Note how many parameters we found.  */
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack,
+                  sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the parameters and 
+     use them to fill parameter-type information into the function-type.
+     The parameter symbols can be found in the local_list that we just put them on. */
+  /* Note that we preserve the order of the parameters, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+
+  /* get the parameters types from the local list not the global list
+     so that the type can be correctly constructed for functions which
+     have function as parameters */
+  for (syms = local_list, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      for (j = 0; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+    }
+  /* Mark it as having been processed */
+  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+  /* Check whether we need to fix-up a class type with this function's type */
+  if (fixup_class && (fixup_method == type))
+    {
+      fixup_class_method_type (fixup_class, fixup_method, objfile);
+      fixup_class = NULL;
+      fixup_method = NULL;
     }
 
+  /* Set the param list of this level of the context stack
+     to our local list.  Do this only if this function was
+     called for creating a new block, and not if it was called
+     simply to get the function type. This prevents recursive
+     invocations from trashing param_symbols. */
+finish:
+  if (newblock)
+    param_symbols = local_list;
+
   return type;
 }
 
-/* Read and internalize a native function debug symbol.  */
 
+/* Read and internalize a native DOC function debug symbol.  */
+/* This is almost identical to hpread_read_function_type(), except
+ * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc.
+ * Since debug information for DOC functions is more likely to be
+ * volatile, please leave it this way.
+ */
 static struct type *
-hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                          struct objfile *objfile)
+hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                              struct objfile *objfile, int newblock)
 {
   struct type *type, *type1;
-  struct pending **symlist, *osyms, *syms;
-  int o_nsyms, nsyms = 0;
+  struct pending *syms;
+  struct pending *local_list = NULL;
+  int nsyms = 0;
   dnttpointer param;
   union dnttentry *paramp;
   char *name;
   long n;
   struct symbol *sym;
-
-  param = dn_bufp->dfunc.firstparam;
+  int record_args = 1;
 
   /* See if we've already read in this type.  */
   type = hpread_alloc_type (hp_type, objfile);
   if (TYPE_CODE (type) == TYPE_CODE_FUNC)
-    return type;
-
-  /* Nope, so read it in and store it away.  */
-  type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
-                                                   objfile));
-  memcpy ((char *) type, (char *) type1, sizeof (struct type));
-
-  symlist = &local_symbols;
-  osyms = *symlist;
-  o_nsyms = osyms ? osyms->nsyms : 0;
+    {
+      record_args = 0;         /* already read in, don't modify type */
+    }
+  else
+    {
+      /* Nope, so read it in and store it away.  */
+      if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+         dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
+                                                         objfile));
+      memcpy ((char *) type, (char *) type1, sizeof (struct type));
+
+      /* Mark it -- in the middle of processing */
+      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+    }
 
   /* Now examine each parameter noting its type, location, and a
      wealth of other information.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+      dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+    param = dn_bufp->ddocfunc.firstparam;
   while (param.word && param.word != DNTTNIL)
     {
       paramp = hpread_get_lntt (param.dnttp.index, objfile);
@@ -1316,145 +3423,1109 @@ hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
       sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
                                             sizeof (struct symbol));
       (void) memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-                                       &objfile->symbol_obstack);
+      SYMBOL_NAME (sym) = name;
+
+      /* Figure out where it lives.  */
+      if (paramp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGPARM;
+      else if (paramp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (paramp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+         /* This is likely a pass-by-invisible reference parameter,
+            Hack on the symbol class to make GDB happy.  */
+         /* ??rehrauer: This appears to be broken w/r/t to passing
+            C values of type float and struct.  Perhaps this ought
+            to be highighted as a special case, but for now, just
+            allowing these to be LOC_ARGs seems to work fine.
+          */
+#if 0
+         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+      /* Get its type.  */
+      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+      /* Add it to the symbol list.  */
+      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+       * called on FPARAM symbols from the process_one_debug_symbol()
+       * level... so parameters are getting added twice! (this shows
+       * up in the symbol dump you get from "maint print symbols ...").
+       * Note 2 (RT) I took out the processing of FPARAM from the 
+       * process_one_debug_symbol() level, so at the moment parameters are only
+       * being processed here. This seems to have no ill effect.
+       */
+      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+         each fparam on the local_symbols list from here.  Now we use the
+         local_list to which fparams are added below, and set the param_symbols
+         global to point to that at the end of this routine. */
+
+      /* elz: I added this new list of symbols which is local to the function.
+         this list is the one which is actually used to build the type for the
+         function rather than the gloabal list pointed to by symlist.
+         Using a global list to keep track of the parameters is wrong, because 
+         this function is called recursively if one parameter happend to be
+         a function itself with more parameters in it. Adding parameters to the
+         same global symbol list would not work!      
+         Actually it did work in case of cc compiled programs where you do not check the
+         parameter lists of the arguments.  */
+      add_symbol_to_list (sym, &local_list);
+    }
+
+  /* If type was read in earlier, don't bother with modifying
+     the type struct */
+  if (!record_args)
+    goto finish;
+
+  /* Note how many parameters we found.  */
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack,
+                  sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the parameters and 
+     use them to fill parameter-type information into the function-type.
+     The parameter symbols can be found in the local_list that we just put them on. */
+  /* Note that we preserve the order of the parameters, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+
+  /* get the parameters types from the local list not the global list
+     so that the type can be correctly constructed for functions which
+     have function as parameters
+   */
+  for (syms = local_list, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      for (j = 0; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+    }
+
+  /* Mark it as having been processed */
+  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+  /* Check whether we need to fix-up a class type with this function's type */
+  if (fixup_class && (fixup_method == type))
+    {
+      fixup_class_method_type (fixup_class, fixup_method, objfile);
+      fixup_class = NULL;
+      fixup_method = NULL;
+    }
+
+  /* Set the param list of this level of the context stack
+     to our local list.  Do this only if this function was
+     called for creating a new block, and not if it was called
+     simply to get the function type. This prevents recursive
+     invocations from trashing param_symbols. */
+finish:
+  if (newblock)
+    param_symbols = local_list;
+
+  return type;
+}
+
+
+
+/* A file-level variable which keeps track of the current-template
+ * being processed. Set in hpread_read_struct_type() while processing
+ * a template type. Referred to in hpread_get_nth_templ_arg().
+ * Yes, this is a kludge, but it arises from the kludge that already
+ * exists in symtab.h, namely the fact that they encode
+ * "template argument n" with fundamental type FT_TEMPLATE_ARG and
+ * bitlength n. This means that deep in processing fundamental types
+ * I need to ask the question "what template am I in the middle of?".
+ * The alternative to stuffing a global would be to pass an argument
+ * down the chain of calls just for this purpose.
+ * 
+ * There may be problems handling nested templates... tough.
+ */
+static struct type *current_template = NULL;
+
+/* Read in and internalize a structure definition.  
+ * This same routine is called for struct, union, and class types.
+ * Also called for templates, since they build a very similar
+ * type entry as for class types.
+ */
+
+static struct type *
+hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                        struct objfile *objfile)
+{
+  /* The data members get linked together into a list of struct nextfield's */
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+      unsigned char attributes;        /* store visibility and virtuality info */
+#define ATTR_VIRTUAL 1
+#define ATTR_PRIVATE 2
+#define ATTR_PROTECT 3
+    };
+
+
+  /* The methods get linked together into a list of struct next_fn_field's */
+  struct next_fn_field
+    {
+      struct next_fn_field *next;
+      struct fn_fieldlist field;
+      struct fn_field fn_field;
+      int num_fn_fields;
+    };
+
+  /* The template args get linked together into a list of struct next_template's */
+  struct next_template
+    {
+      struct next_template *next;
+      struct template_arg arg;
+    };
+
+  /* The template instantiations get linked together into a list of these... */
+  struct next_instantiation
+    {
+      struct next_instantiation *next;
+      struct type *t;
+    };
+
+  struct type *type;
+  struct type *baseclass;
+  struct type *memtype;
+  struct nextfield *list = 0, *tmp_list = 0;
+  struct next_fn_field *fn_list = 0;
+  struct next_fn_field *fn_p;
+  struct next_template *t_new, *t_list = 0;
+  struct nextfield *new;
+  struct next_fn_field *fn_new;
+  struct next_instantiation *i_new, *i_list = 0;
+  int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
+  int n_base_classes = 0, n_templ_args = 0;
+  int ninstantiations = 0;
+  dnttpointer field, fn_field, parent;
+  union dnttentry *fieldp, *fn_fieldp, *parentp;
+  int i;
+  int static_member = 0;
+  int const_member = 0;
+  int volatile_member = 0;
+  unsigned long vtbl_offset;
+  int need_bitvectors = 0;
+  char *method_name = NULL;
+  char *method_alias = NULL;
+
+
+  /* Is it something we've already dealt with?  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+      (TYPE_CODE (type) == TYPE_CODE_UNION) ||
+      (TYPE_CODE (type) == TYPE_CODE_CLASS) ||
+      (TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
+    return type;
+
+  /* Get the basic type correct.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+    {
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+    {
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+      TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    {
+      TYPE_CODE (type) = TYPE_CODE_CLASS;
+      TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
+
+      /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory
+       * rather than &cplus_struct_default.
+       */
+      allocate_cplus_struct_type (type);
+
+      /* Fill in declared-type.
+       * (The C++ compiler will emit TYPE_CODE_CLASS 
+       * for all 3 of "class", "struct"
+       * "union", and we have to look at the "class_decl" field if we
+       * want to know how it was really declared)
+       */
+      /* (0==class, 1==union, 2==struct) */
+      TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      /* Get the basic type correct.  */
+      TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
+      allocate_cplus_struct_type (type);
+      TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE;
+    }
+  else
+    return type;
+
+
+  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+  /* For classes, read the parent list.
+   * Question (RT): Do we need to do this for templates also?
+   */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    {
+
+      /* First read the parent-list (classes from which we derive fields) */
+      parent = dn_bufp->dclass.parentlist;
+      while (parent.word && parent.word != DNTTNIL)
+       {
+         parentp = hpread_get_lntt (parent.dnttp.index, objfile);
+
+         /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */
+
+         /* Get space to record the next field/data-member. */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         FIELD_BITSIZE (list->field) = 0;
+
+         /* The "classname" field is actually a DNTT pointer to the base class */
+         baseclass = hpread_type_lookup (parentp->dinheritance.classname,
+                                         objfile);
+         FIELD_TYPE (list->field) = baseclass;
+
+         list->field.name = type_name_no_tag (FIELD_TYPE (list->field));
+
+         list->attributes = 0;
+
+         /* Check for virtuality of base, and set the
+          * offset of the base subobject within the object.
+          * (Offset set to -1 for virtual bases (for now).)
+          */
+         if (parentp->dinheritance.Virtual)
+           {
+             B_SET (&(list->attributes), ATTR_VIRTUAL);
+             parentp->dinheritance.offset = -1;
+           }
+         else
+           FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
+
+         /* Check visibility */
+         switch (parentp->dinheritance.visibility)
+           {
+           case 1:
+             B_SET (&(list->attributes), ATTR_PROTECT);
+             break;
+           case 2:
+             B_SET (&(list->attributes), ATTR_PRIVATE);
+             break;
+           }
+
+         n_base_classes++;
+         nfields++;
+
+         parent = parentp->dinheritance.next;
+       }
+    }
+
+  /* For templates, read the template argument list.
+   * This must be done before processing the member list, because
+   * the member list may refer back to this. E.g.:
+   *   template <class T1, class T2> class q2 {
+   *     public:
+   *     T1 a;
+   *     T2 b;
+   *   };
+   * We need to read the argument list "T1", "T2" first.
+   */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      /* Kludge alert: This stuffs a global "current_template" which
+       * is referred to by hpread_get_nth_templ_arg(). The global
+       * is cleared at the end of this routine.
+       */
+      current_template = type;
+
+      /* Read in the argument list */
+      field = dn_bufp->dtemplate.arglist;
+      while (field.word && field.word != DNTTNIL)
+       {
+         /* Get this template argument */
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+         if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
+           {
+             warning ("Invalid debug info: Template argument entry is of wrong kind");
+             break;
+           }
+         /* Bump the count */
+         n_templ_args++;
+         /* Allocate and fill in a struct next_template */
+         t_new = (struct next_template *) alloca (sizeof (struct next_template));
+         t_new->next = t_list;
+         t_list = t_new;
+         t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
+         t_list->arg.type = hpread_read_templ_arg_type (field, fieldp,
+                                                objfile, t_list->arg.name);
+         /* Walk to the next template argument */
+         field = fieldp->dtempl_arg.nextarg;
+       }
+    }
+
+  TYPE_NTEMPLATE_ARGS (type) = n_templ_args;
+
+  if (n_templ_args > 0)
+    TYPE_TEMPLATE_ARGS (type) = (struct template_arg *)
+      obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args);
+  for (n = n_templ_args; t_list; t_list = t_list->next)
+    {
+      n -= 1;
+      TYPE_TEMPLATE_ARG (type, n) = t_list->arg;
+    }
+
+  /* Next read in and internalize all the fields/members.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+    field = dn_bufp->dstruct.firstfield;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+    field = dn_bufp->dunion.firstfield;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    field = dn_bufp->dclass.memberlist;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    field = dn_bufp->dtemplate.memberlist;
+  else
+    field.word = DNTTNIL;
+
+  while (field.word && field.word != DNTTNIL)
+    {
+      fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+      /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD
+       * or a DNTT_TYPE_GENFIELD record. 
+       */
+      vtbl_offset = 0;
+      static_member = 0;
+      const_member = 0;
+      volatile_member = 0;
+
+      if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD)
+       {
+
+         /* The type will be GENFIELD if the field is a method or
+          * a static member (or some other cases -- see below)
+          */
+
+         /* Follow a link to get to the record for the field. */
+         fn_field = fieldp->dgenfield.field;
+         fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+
+         /* Virtual funcs are indicated by a VFUNC which points to the
+          * real entry
+          */
+         if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC)
+           {
+             vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
+             fn_field = fn_fieldp->dvfunc.funcptr;
+             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+           }
+
+         /* A function's entry may be preceded by a modifier which
+          * labels it static/constant/volatile.
+          */
+         if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER)
+           {
+             static_member = fn_fieldp->dmodifier.m_static;
+             const_member = fn_fieldp->dmodifier.m_const;
+             volatile_member = fn_fieldp->dmodifier.m_volatile;
+             fn_field = fn_fieldp->dmodifier.type;
+             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+           }
+
+         /* Check whether we have a method */
+         if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION))
+           {
+             /* Method found */
+
+             short ix = 0;
+
+             /* Look up function type of method */
+             memtype = hpread_type_lookup (fn_field, objfile);
+
+             /* Methods can be seen before classes in the SOM records.
+                If we are processing this class because it's a parameter of a
+                method, at this point the method's type is actually incomplete;
+                we'll have to fix it up later; mark the class for this. */
+
+             if (TYPE_INCOMPLETE (memtype))
+               {
+                 TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+                 if (fixup_class)
+                   warning ("Two classes to fix up for method??  Type information may be incorrect for some classes.");
+                 if (fixup_method)
+                   warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
+                 fixup_class = type;   /* remember this class has to be fixed up */
+                 fixup_method = memtype;       /* remember the method type to be used in fixup */
+               }
+
+             /* HP aCC generates operator names without the "operator" keyword, and
+                generates null strings as names for operators that are 
+                user-defined type conversions to basic types (e.g. operator int ()).
+                So try to reconstruct name as best as possible. */
+
+             method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
+             method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
+
+             if (!method_name ||       /* no name */
+                 !*method_name ||      /* or null name */
+                 cplus_mangle_opname (method_name, DMGL_ANSI))         /* or name is an operator like "<" */
+               {
+                 char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
+                 char *op_string = strstr (tmp_name, "operator");
+                 method_name = xmalloc (strlen (op_string) + 1);       /* don't overwrite VT! */
+                 strcpy (method_name, op_string);
+               }
+
+             /* First check if a method of the same name has already been seen. */
+             fn_p = fn_list;
+             while (fn_p)
+               {
+                 if (STREQ (fn_p->field.name, method_name))
+                   break;
+                 fn_p = fn_p->next;
+               }
+
+             /* If no such method was found, allocate a new entry in the list */
+             if (!fn_p)
+               {
+                 /* Get space to record this member function */
+                 /* Note: alloca used; this will disappear on routine exit */
+                 fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
+                 fn_new->next = fn_list;
+                 fn_list = fn_new;
+
+                 /* Fill in the fields of the struct nextfield */
+
+                 /* Record the (unmangled) method name */
+                 fn_list->field.name = method_name;
+                 /* Initial space for overloaded methods */
+                 /* Note: xmalloc is used; this will persist after this routine exits */
+                 fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
+                 fn_list->field.length = 1;    /* Init # of overloaded instances */
+                 fn_list->num_fn_fields = 5;   /* # of entries for which space allocated */
+                 fn_p = fn_list;
+                 ix = 0;       /* array index for fn_field */
+                 /* Bump the total count of the distinctly named methods */
+                 n_fn_fields++;
+               }
+             else
+               /* Another overloaded instance of an already seen method name */
+               {
+                 if (++(fn_p->field.length) > fn_p->num_fn_fields)
+                   {
+                     /* Increase space allocated for overloaded instances */
+                     fn_p->field.fn_fields
+                       = (struct fn_field *) xrealloc (fn_p->field.fn_fields,
+                     (fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
+                     fn_p->num_fn_fields += 5;
+                   }
+                 ix = fn_p->field.length - 1;  /* array index for fn_field */
+               }
+
+             /* "physname" is intended to be the name of this overloaded instance. */
+             if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+                 method_alias &&
+                 *method_alias)        /* not a null string */
+               fn_p->field.fn_fields[ix].physname = method_alias;
+             else
+               fn_p->field.fn_fields[ix].physname = method_name;
+             /* What's expected here is the function type */
+             /* But mark it as NULL if the method was incompletely processed
+                We'll fix this up later when the method is fully processed */
+             if (TYPE_INCOMPLETE (memtype))
+               {
+                 fn_p->field.fn_fields[ix].type = NULL;
+                 fn_p->field.fn_fields[ix].args = NULL;
+               }
+             else
+               {
+                 fn_p->field.fn_fields[ix].type = memtype;
+
+                 /* The argument list */
+                 fn_p->field.fn_fields[ix].type->type_specific.arg_types =
+                   (struct type **) obstack_alloc (&objfile->type_obstack,
+                          sizeof (struct type *) * (memtype->nfields + 1));
+                 for (i = 0; i < memtype->nfields; i++)
+                   fn_p->field.fn_fields[ix].type->type_specific.arg_types[i] = memtype->fields[i].type;
+                 /* void termination */
+                 fn_p->field.fn_fields[ix].type->type_specific.arg_types[memtype->nfields] = builtin_type_void;
+
+                 /* pai: It's not clear why this args field has to be set.  Perhaps
+                  * it should be eliminated entirely. */
+                 fn_p->field.fn_fields[ix].args =
+                   (struct type **) obstack_alloc (&objfile->type_obstack,
+                          sizeof (struct type *) * (memtype->nfields + 1));
+                 for (i = 0; i < memtype->nfields; i++)
+                   fn_p->field.fn_fields[ix].args[i] = memtype->fields[i].type;
+                 /* null-terminated, unlike arg_types above e */
+                 fn_p->field.fn_fields[ix].args[memtype->nfields] = NULL;
+               }
+             /* For virtual functions, fill in the voffset field with the
+              * virtual table offset. (This is just copied over from the
+              * SOM record; not sure if it is what GDB expects here...).
+              * But if the function is a static method, set it to 1.
+              * 
+              * Note that we have to add 1 because 1 indicates a static
+              * method, and 0 indicates a non-static, non-virtual method */
+
+             if (static_member)
+               fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
+             else
+               fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
+
+             /* Also fill in the fcontext field with the current
+              * class. (The latter isn't quite right: should be the baseclass
+              * that defines the virtual function... Note we do have
+              * a variable "baseclass" that we could stuff into the fcontext
+              * field, but "baseclass" isn't necessarily right either,
+              * since the virtual function could have been defined more
+              * than one level up).
+              */
+
+             if (vtbl_offset != 0)
+               fn_p->field.fn_fields[ix].fcontext = type;
+             else
+               fn_p->field.fn_fields[ix].fcontext = NULL;
+
+             /* Other random fields pertaining to this method */
+             fn_p->field.fn_fields[ix].is_const = const_member;
+             fn_p->field.fn_fields[ix].is_volatile = volatile_member;  /* ?? */
+             switch (fieldp->dgenfield.visibility)
+               {
+               case 1:
+                 fn_p->field.fn_fields[ix].is_protected = 1;
+                 fn_p->field.fn_fields[ix].is_private = 0;
+                 break;
+               case 2:
+                 fn_p->field.fn_fields[ix].is_protected = 0;
+                 fn_p->field.fn_fields[ix].is_private = 1;
+                 break;
+               default:        /* public */
+                 fn_p->field.fn_fields[ix].is_protected = 0;
+                 fn_p->field.fn_fields[ix].is_private = 0;
+               }
+             fn_p->field.fn_fields[ix].is_stub = 0;
+
+             /* HP aCC emits both MEMFUNC and FUNCTION entries for a method;
+                if the class points to the FUNCTION, there is usually separate
+                code for the method; but if we have a MEMFUNC, the method has
+                been inlined (and there is usually no FUNCTION entry)
+                FIXME Not sure if this test is accurate. pai/1997-08-22 */
+             if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+                 (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
+               fn_p->field.fn_fields[ix].is_inlined = 1;
+             else
+               fn_p->field.fn_fields[ix].is_inlined = 0;
+
+             fn_p->field.fn_fields[ix].dummy = 0;
+
+             /* Bump the total count of the member functions */
+             n_fn_fields_total++;
+
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+           {
+             /* This case is for static data members of classes */
+
+             /* pai:: FIXME -- check that "staticmem" bit is set */
+
+             /* Get space to record this static member */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+             FIELD_BITSIZE (list->field) = -1;         /* indicates static member */
+             SET_FIELD_PHYSNAME (list->field, 0);      /* initialize to empty */
+             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+
+             FIELD_TYPE (list->field) = memtype;
+             list->attributes = 0;
+             switch (fieldp->dgenfield.visibility)
+               {
+               case 1:
+                 B_SET (&(list->attributes), ATTR_PROTECT);
+                 break;
+               case 2:
+                 B_SET (&(list->attributes), ATTR_PRIVATE);
+                 break;
+               }
+             nfields++;
+           }
+
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
+           {
+             /* FIELDs follow GENFIELDs for fields of anonymous unions.
+                Code below is replicated from the case for FIELDs further
+                below, except that fieldp is replaced by fn_fieldp */
+             if (!fn_fieldp->dfield.a_union)
+               warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dfield.name;
+             FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
+             if (fn_fieldp->dfield.bitlength % 8)
+               list->field.bitsize = fn_fieldp->dfield.bitlength;
+             else
+               list->field.bitsize = 0;
+
+             memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             switch (fn_fieldp->dfield.visibility)
+               {
+               case 1:
+                 B_SET (&(list->attributes), ATTR_PROTECT);
+                 break;
+               case 2:
+                 B_SET (&(list->attributes), ATTR_PRIVATE);
+                 break;
+               }
+             nfields++;
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+           {
+             /* Field of anonymous union; union is not inside a class */
+             if (!fn_fieldp->dsvar.a_union)
+               warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
+             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
+             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             /* No info to set visibility -- always public */
+             nfields++;
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
+           {
+             /* Field of anonymous union; union is not inside a class */
+             if (!fn_fieldp->ddvar.a_union)
+               warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
+             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
+             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
+             memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             /* No info to set visibility -- always public */
+             nfields++;
+           }
+         else
+           {                   /* Not a method, nor a static data member, nor an anon union field */
+
+             /* This case is for miscellaneous type entries (local enums,
+                local function templates, etc.) that can be present
+                inside a class. */
+
+             /* Enums -- will be handled by other code that takes care
+                of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so
+                it's not clear we could have handled them here at all. */
+             /* FUNC_TEMPLATE: is handled by other code (?). */
+             /* MEMACCESS: modified access for inherited member. Not
+                sure what to do with this, ignoriing it at present. */
+
+             /* What other entries can appear following a GENFIELD which
+                we do not handle above?  (MODIFIER, VFUNC handled above.) */
+
+             if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
+                 (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
+                 (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
+               warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
+                        fn_fieldp->dblock.kind);
+           }
+         /* walk to the next FIELD or GENFIELD */
+         field = fieldp->dgenfield.nextfield;
+
+       }
+      else if (fieldp->dblock.kind == DNTT_TYPE_FIELD)
+       {
+
+         /* Ordinary structure/union/class field */
+         struct type *anon_union_type;
+
+         /* Get space to record the next field/data-member. */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         list->field.name = VT (objfile) + fieldp->dfield.name;
+
+
+         /* A FIELD by itself (without a GENFIELD) can also be a static member */
+         if (fieldp->dfield.staticmem)
+           {
+             FIELD_BITPOS (list->field) = -1;
+             FIELD_BITSIZE (list->field) = 0;
+           }
+         else
+           /* Non-static data member */
+           {
+             FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
+             if (fieldp->dfield.bitlength % 8)
+               FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
+             else
+               FIELD_BITSIZE (list->field) = 0;
+           }
+
+         memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
+         FIELD_TYPE (list->field) = memtype;
+         list->attributes = 0;
+         switch (fieldp->dfield.visibility)
+           {
+           case 1:
+             B_SET (&(list->attributes), ATTR_PROTECT);
+             break;
+           case 2:
+             B_SET (&(list->attributes), ATTR_PRIVATE);
+             break;
+           }
+         nfields++;
+
+
+         /* Note 1: First, we have to check if the current field is an anonymous
+            union. If it is, then *its* fields are threaded along in the
+            nextfield chain. :-( This was supposed to help debuggers, but is
+            really just a nuisance since we deal with anonymous unions anyway by
+            checking that the name is null.  So anyway, we skip over the fields
+            of the anonymous union. pai/1997-08-22 */
+         /* Note 2: In addition, the bitoffsets for the fields of the anon union
+            are relative to the enclosing struct, *NOT* relative to the anon
+            union!  This is an even bigger nuisance -- we have to go in and munge
+            the anon union's type information appropriately. pai/1997-08-22 */
 
-      /* Figure out where it lives.  */
-      if (paramp->dfparam.regparam)
-       SYMBOL_CLASS (sym) = LOC_REGPARM;
-      else if (paramp->dfparam.indirect)
-       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+         /* Both tasks noted above are done by a separate function.  This takes us
+            to the next FIELD or GENFIELD, skipping anon unions, and recursively
+            processing intermediate types. */
+         field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
+
+       }
       else
-       SYMBOL_CLASS (sym) = LOC_ARG;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      if (paramp->dfparam.copyparam)
        {
-         SYMBOL_VALUE (sym) = paramp->dfparam.location;
-#ifdef HPREAD_ADJUST_STACK_ADDRESS
-         SYMBOL_VALUE (sym)
-           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
-#endif
-         /* This is likely a pass-by-invisible reference parameter,
-            Hack on the symbol class to make GDB happy.  */
-         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+         /* neither field nor genfield ?? is this possible?? */
+         /* pai:: FIXME walk to the next -- how? */
+         warning ("Internal error: unexpected DNTT kind %d encountered as field of struct",
+                  fieldp->dblock.kind);
+         warning ("Skipping remaining fields of struct");
+         break;                /* get out of loop of fields */
        }
-      else
-       SYMBOL_VALUE (sym) = paramp->dfparam.location;
-
-      /* Get its type.  */
-      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+    }
 
-      /* Add it to the list.  */
-      add_symbol_to_list (sym, symlist);
+  /* If it's a template, read in the instantiation list */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      ninstantiations = 0;
+      field = dn_bufp->dtemplate.expansions;
+      while (field.word && field.word != DNTTNIL)
+       {
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+         /* The expansions or nextexp should point to a tagdef */
+         if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
+           break;
+
+         i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
+         i_new->next = i_list;
+         i_list = i_new;
+         i_list->t = hpread_type_lookup (field, objfile);
+         ninstantiations++;
+
+         /* And the "type" field of that should point to a class */
+         field = fieldp->dtag.type;
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+         if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
+           break;
+
+         /* Get the next expansion */
+         field = fieldp->dclass.nextexp;
+       }
+    }
+  TYPE_NINSTANTIATIONS (type) = ninstantiations;
+  if (ninstantiations > 0)
+    TYPE_INSTANTIATIONS (type) = (struct type **)
+      obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations);
+  for (n = ninstantiations; i_list; i_list = i_list->next)
+    {
+      n -= 1;
+      TYPE_INSTANTIATION (type, n) = i_list->t;
     }
 
-  /* Note how many parameters we found.  */
-  TYPE_NFIELDS (type) = nsyms;
+
+  /* Copy the field-list to GDB's symbol table */
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_N_BASECLASSES (type) = n_base_classes;
   TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack,
-                  sizeof (struct field) * nsyms);
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+  /* Copy the saved-up fields into the field vector.  */
+  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+    {
+      n -= 1;
+      TYPE_FIELD (type, n) = tmp_list->field;
+    }
 
-  /* Find the symbols for the values and put them into the type.
-     The symbols can be found in the symlist that we put them on
-     to cause them to be defined.  osyms contains the old value
-     of that symlist; everything up to there was defined by us.  */
-  /* Note that we preserve the order of the parameters, so
-     that in something like "enum {FOO, LAST_THING=FOO}" we print
-     FOO, not LAST_THING.  */
-  for (syms = *symlist, n = 0; syms; syms = syms->next)
+  /* Copy the "function-field-list" (i.e., the list of member
+   * functions in the class) to GDB's symbol table 
+   */
+  TYPE_NFN_FIELDS (type) = n_fn_fields;
+  TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
+  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
+  for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
     {
-      int j = 0;
-      if (syms == osyms)
-       j = o_nsyms;
-      for (; j < syms->nsyms; j++, n++)
+      n -= 1;
+      TYPE_FN_FIELDLIST (type, n) = fn_list->field;
+    }
+
+  /* pai:: FIXME -- perhaps each bitvector should be created individually */
+  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+    {
+      n -= 1;
+      if (tmp_list->attributes)
        {
-         struct symbol *xsym = syms->symbol[j];
-         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
-         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
-         TYPE_FIELD_BITSIZE (type, n) = 0;
+         need_bitvectors = 1;
+         break;
        }
-      if (syms == osyms)
-       break;
     }
-  return type;
-}
-
-/* Read in and internalize a structure definition.  */
 
-static struct type *
-hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
-                        struct objfile *objfile)
-{
-  struct nextfield
+  if (need_bitvectors)
     {
-      struct nextfield *next;
-      struct field field;
-    };
+      /* pai:: this step probably redundant */
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
 
-  struct type *type;
-  struct nextfield *list = 0;
-  struct nextfield *new;
-  int n, nfields = 0;
-  dnttpointer field;
-  union dnttentry *fieldp;
+      TYPE_FIELD_VIRTUAL_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
 
-  /* Is it something we've already dealt with?  */
-  type = hpread_alloc_type (hp_type, objfile);
-  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
-      (TYPE_CODE (type) == TYPE_CODE_UNION))
-    return type;
+      TYPE_FIELD_PRIVATE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
 
-  /* Get the basic type correct.  */
-  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+      TYPE_FIELD_PROTECTED_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+      /* this field vector isn't actually used with HP aCC */
+      TYPE_FIELD_IGNORE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+      while (nfields-- > 0)
+       {
+         if (B_TST (&(list->attributes), ATTR_VIRTUAL))
+           SET_TYPE_FIELD_VIRTUAL (type, nfields);
+         if (B_TST (&(list->attributes), ATTR_PRIVATE))
+           SET_TYPE_FIELD_PRIVATE (type, nfields);
+         if (B_TST (&(list->attributes), ATTR_PROTECT))
+           SET_TYPE_FIELD_PROTECTED (type, nfields);
+
+         list = list->next;
+       }
+    }
+  else
     {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
-      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+      TYPE_FIELD_VIRTUAL_BITS (type) = NULL;
+      TYPE_FIELD_PROTECTED_BITS (type) = NULL;
+      TYPE_FIELD_PRIVATE_BITS (type) = NULL;
     }
-  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+
+  if (has_vtable (type))
     {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-      TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+      /* Allocate space for class runtime information */
+      TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info));
+      /* Set flag for vtable */
+      TYPE_VTABLE (type) = 1;
+      /* The first non-virtual base class with a vtable. */
+      TYPE_PRIMARY_BASE (type) = primary_base_class (type);
+      /* The virtual base list. */
+      TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type);
     }
   else
-    return type;
+    TYPE_RUNTIME_PTR (type) = NULL;
 
+  /* If this is a local type (C++ - declared inside a function), record file name & line # */
+  if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */ ))
+    {
+      TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
+      TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
+      strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
+      if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
+       TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
+      else
+       TYPE_LOCALTYPE_LINE (type) = 0;
+    }
+  else
+    TYPE_LOCALTYPE_PTR (type) = NULL;
 
-  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+  /* Clear the global saying what template we are in the middle of processing */
+  current_template = NULL;
 
-  /* Read in and internalize all the fields.  */
-  field = dn_bufp->dstruct.firstfield;
-  while (field.word != DNTTNIL && field.dnttp.extension)
-    {
-      fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+  /* Fix up any cv-qualified versions of this type.  */
+  finish_cv_type (type);
 
-      /* Get space to record the next field's data.  */
-      new = (struct nextfield *) alloca (sizeof (struct nextfield));
-      new->next = list;
-      list = new;
+  return type;
+}
 
-      list->field.name = VT (objfile) + fieldp->dfield.name;
-      FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
-      if (fieldp->dfield.bitlength % 8)
-       FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
-      else
-       FIELD_BITSIZE (list->field) = 0;
-      nfields++;
-      field = fieldp->dfield.nextfield;
-      FIELD_TYPE (list->field) = hpread_type_lookup (fieldp->dfield.type,
-                                                    objfile);
-    }
+/* Adjust the physnames for each static member of a struct
+   or class type to be something like "A::x"; then various
+   other pieces of code that do a lookup_symbol on the phyname
+   work correctly.
+   TYPE is a pointer to the struct/class type
+   NAME is a char * (string) which is the class/struct name
+   Void return */
 
-  TYPE_NFIELDS (type) = nfields;
-  TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+static void
+fix_static_member_physnames (struct type *type, char *class_name,
+                            struct objfile *objfile)
+{
+  int i;
 
-  /* Copy the saved-up fields into the field vector.  */
-  for (n = nfields; list; list = list->next)
-    {
-      n -= 1;
-      TYPE_FIELD (type, n) = list->field;
-    }
+  /* We fix the member names only for classes or structs */
+  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
+    return;
+
+  for (i = 0; i < TYPE_NFIELDS (type); i++)
+    if (TYPE_FIELD_STATIC (type, i))
+      {
+       if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
+         return;               /* physnames are already set */
+
+       SET_FIELD_PHYSNAME (type->fields[i],
+                           obstack_alloc (&objfile->type_obstack,
+            strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
+       strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
+       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
+       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
+      }
+}
+
+/* Fix-up the type structure for a CLASS so that the type entry
+ * for a method (previously marked with a null type in hpread_read_struct_type()
+ * is set correctly to METHOD.
+ * OBJFILE is as for other such functions. 
+ * Void return. */
+
+static void
+fixup_class_method_type (struct type *class, struct type *method,
+                        struct objfile *objfile)
+{
+  int i, j, k;
+
+  if (!class || !method || !objfile)
+    return;
+
+  /* Only for types that have methods */
+  if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
+      (TYPE_CODE (class) != TYPE_CODE_UNION))
+    return;
+
+  /* Loop over all methods and find the one marked with a NULL type */
+  for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
+    for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
+      if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
+       {
+         /* Set the method type */
+         TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
+         /* The argument list */
+         (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types
+           = (struct type **) obstack_alloc (&objfile->type_obstack,
+                           sizeof (struct type *) * (method->nfields + 1));
+         for (k = 0; k < method->nfields; k++)
+           (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[k] = method->fields[k].type;
+         /* void termination */
+         (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[method->nfields] = builtin_type_void;
+
+         /* pai: It's not clear why this args field has to be set.  Perhaps
+          * it should be eliminated entirely. */
+         (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args
+           = (struct type **) obstack_alloc (&objfile->type_obstack,
+                           sizeof (struct type *) * (method->nfields + 1));
+         for (k = 0; k < method->nfields; k++)
+           (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[k] = method->fields[k].type;
+         /* null-terminated, unlike arg_types above */
+         (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[method->nfields] = NULL;
+
+         /* Break out of both loops -- only one method to fix up in a class */
+         goto finish;
+       }
+
+finish:
+  TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
+}
+
+
+/* If we're in the middle of processing a template, get a pointer
+ * to the Nth template argument.
+ * An example may make this clearer:
+ *   template <class T1, class T2> class q2 {
+ *     public:
+ *     T1 a;
+ *     T2 b;
+ *   };
+ * The type for "a" will be "first template arg" and
+ * the type for "b" will be "second template arg".
+ * We need to look these up in order to fill in "a" and "b"'s type.
+ * This is called from hpread_type_lookup().
+ */
+static struct type *
+hpread_get_nth_template_arg (struct objfile *objfile, int n)
+{
+  if (current_template != NULL)
+    return TYPE_TEMPLATE_ARG (current_template, n).type;
+  else
+    return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
+}
+
+/* Read in and internalize a TEMPL_ARG (template arg) symbol.  */
+
+static struct type *
+hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                           struct objfile *objfile, char *name)
+{
+  struct type *type;
+
+  /* See if it's something we've already deal with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
+    return type;
+
+  /* Nope.  Fill in the appropriate fields.  */
+  TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
+  TYPE_LENGTH (type) = 0;
+  TYPE_NFIELDS (type) = 0;
+  TYPE_NAME (type) = name;
   return type;
 }
 
@@ -1487,33 +4558,51 @@ hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp,
                        struct objfile *objfile)
 {
   struct type *type;
-  union dnttentry save;
-  save = *dn_bufp;
 
-  /* Why no check here?  Because it kept us from properly determining
-     the size of the array!  */
+  /* Allocate an array type symbol.
+   * Why no check for already-read here, like in the other
+   * hpread_read_xxx_type routines?  Because it kept us 
+   * from properly determining the size of the array!  
+   */
   type = hpread_alloc_type (hp_type, objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ARRAY;
 
-  /* values are not normalized.  */
-  if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes)
-       || (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
-    internal_error (__FILE__, __LINE__, "failed internal consistency check");
+  /* Although the hp-symtab.h does not *require* this to be the case,
+   * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent.
+   * I.e., express both array-length and element-length in bits,
+   * or express both array-length and element-length in bytes.
+   */
+  if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
+       (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
+    {
+      warning ("error in hpread_array_type.\n");
+      return NULL;
+    }
   else if (dn_bufp->darray.arraylength == 0x7fffffff)
     {
       /* The HP debug format represents char foo[]; as an array with
-         length 0x7fffffff.  Internally GDB wants to represent this
-         as an array of length zero.  */
+       * length 0x7fffffff.  Internally GDB wants to represent this
+       *  as an array of length zero.  
+       */
       TYPE_LENGTH (type) = 0;
     }
-  else
+  else if (dn_bufp->darray.arrayisbytes)
+    TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
+  else                         /* arraylength is in bits */
     TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
 
-  TYPE_NFIELDS (type) = 1;
   TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
                                                objfile);
-  dn_bufp = &save;
+
+  /* The one "field" is used to store the subscript type */
+  /* Since C and C++ multi-dimensional arrays are simply represented
+   * as: array of array of ..., we only need one subscript-type
+   * per array. This subscript type is typically a subrange of integer.
+   * If this gets extended to support languages like Pascal, then
+   * we need to fix this to represent multi-dimensional arrays properly.
+   */
+  TYPE_NFIELDS (type) = 1;
   TYPE_FIELDS (type) = (struct field *)
     obstack_alloc (&objfile->type_obstack, sizeof (struct field));
   TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
@@ -1555,75 +4644,204 @@ hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp,
   return type;
 }
 
+/* struct type * hpread_type_lookup(hp_type, objfile)
+ *   Arguments:
+ *     hp_type: A pointer into the DNTT specifying what type we
+ *              are about to "look up"., or else [for fundamental types
+ *              like int, float, ...] an "immediate" structure describing
+ *              the type.
+ *     objfile: ?
+ *   Return value: A pointer to a "struct type" (representation of a
+ *                 type in GDB's internal symbol table - see gdbtypes.h)
+ *   Routine description:
+ *     There are a variety of places when scanning the DNTT when we
+ *     need to interpret a "type" field. The simplest and most basic 
+ *     example is when we're processing the symbol table record
+ *     for a data symbol (a SVAR or DVAR record). That has
+ *     a "type" field specifying the type of the data symbol. That
+ *     "type" field is either an "immediate" type specification (for the
+ *     fundamental types) or a DNTT pointer (for more complicated types). 
+ *     For the more complicated types, we may or may not have already
+ *     processed the pointed-to type. (Multiple data symbols can of course
+ *     share the same type).
+ *     The job of hpread_type_lookup() is to process this "type" field.
+ *     Most of the real work is done in subroutines. Here we interpret
+ *     the immediate flag. If not immediate, chase the DNTT pointer to
+ *     find our way to the SOM record describing the type, switch on
+ *     the SOM kind, and then call an appropriate subroutine depending
+ *     on what kind of type we are constructing. (e.g., an array type,
+ *     a struct/class type, etc).
+ */
 static struct type *
 hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
 {
   union dnttentry *dn_bufp;
+  struct type *tmp_type;
 
   /* First see if it's a simple builtin type.  */
   if (hp_type.dntti.immediate)
-    return lookup_fundamental_type (objfile, hpread_type_translate (hp_type));
+    {
+      /* If this is a template argument, the argument number is
+       * encoded in the bitlength. All other cases, just return
+       * GDB's representation of this fundamental type.
+       */
+      if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
+       return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength);
+      else
+       return lookup_fundamental_type (objfile,
+                                       hpread_type_translate (hp_type));
+    }
 
   /* Not a builtin type.  We'll have to read it in.  */
   if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
     dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
   else
+    /* This is a fancy way of returning NULL */
     return lookup_fundamental_type (objfile, FT_VOID);
 
   switch (dn_bufp->dblock.kind)
     {
     case DNTT_TYPE_SRCFILE:
     case DNTT_TYPE_MODULE:
-    case DNTT_TYPE_FUNCTION:
     case DNTT_TYPE_ENTRY:
     case DNTT_TYPE_BEGIN:
     case DNTT_TYPE_END:
     case DNTT_TYPE_IMPORT:
     case DNTT_TYPE_LABEL:
-    case DNTT_TYPE_WITH:
-    case DNTT_TYPE_COMMON:
     case DNTT_TYPE_FPARAM:
     case DNTT_TYPE_SVAR:
     case DNTT_TYPE_DVAR:
     case DNTT_TYPE_CONST:
-      /* Opps.  Something went very wrong.  */
+    case DNTT_TYPE_MEMENUM:
+    case DNTT_TYPE_VARIANT:
+    case DNTT_TYPE_FILE:
+    case DNTT_TYPE_WITH:
+    case DNTT_TYPE_COMMON:
+    case DNTT_TYPE_COBSTRUCT:
+    case DNTT_TYPE_XREF:
+    case DNTT_TYPE_SA:
+    case DNTT_TYPE_MACRO:
+    case DNTT_TYPE_BLOCKDATA:
+    case DNTT_TYPE_CLASS_SCOPE:
+    case DNTT_TYPE_MEMACCESS:
+    case DNTT_TYPE_INHERITANCE:
+    case DNTT_TYPE_OBJECT_ID:
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+      /* These are not types - something went wrong.  */
+      /* This is a fancy way of returning NULL */
       return lookup_fundamental_type (objfile, FT_VOID);
 
+    case DNTT_TYPE_FUNCTION:
+      /* We wind up here when dealing with class member functions 
+       * (called from hpread_read_struct_type(), i.e. when processing
+       * the class definition itself).
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_DOC_FUNCTION:
+      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
     case DNTT_TYPE_TYPEDEF:
       {
+       /* A typedef - chase it down by making a recursive call */
        struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
                                                      objfile);
-       char *suffix;
-       suffix = VT (objfile) + dn_bufp->dtype.name;
 
-       TYPE_CPLUS_SPECIFIC (structtype)
-         = (struct cplus_struct_type *) &cplus_struct_default;
-       TYPE_NAME (structtype) = suffix;
+       /* The following came from the base hpread.c that we inherited.
+        * It is WRONG so I have commented it out. - RT
+        *...
+
+        char *suffix;
+        suffix = VT (objfile) + dn_bufp->dtype.name;
+        TYPE_NAME (structtype) = suffix;
+
+        * ... further explanation ....
+        *
+        * What we have here is a typedef pointing to a typedef.
+        * E.g.,
+        * typedef int foo;
+        * typedef foo fum;
+        *
+        * What we desire to build is (these are pictures
+        * of "struct type"'s): 
+        *
+        *  +---------+     +----------+     +------------+
+        *  | typedef |     | typedef  |     | fund. type |
+        *  |     type| ->  |      type| ->  |            |
+        *  | "fum"   |     | "foo"    |     | "int"      |
+        *  +---------+     +----------+     +------------+
+        *
+        * What this commented-out code is doing is smashing the
+        * name of pointed-to-type to be the same as the pointed-from
+        * type. So we wind up with something like:
+        *
+        *  +---------+     +----------+     +------------+
+        *  | typedef |     | typedef  |     | fund. type |
+        *  |     type| ->  |      type| ->  |            |
+        *  | "fum"   |     | "fum"    |     | "fum"      |
+        *  +---------+     +----------+     +------------+
+        * 
+        */
+
        return structtype;
       }
 
     case DNTT_TYPE_TAGDEF:
       {
        /* Just a little different from above.  We have to tack on
-          an identifier of some kind (struct, union, enum, etc).  */
+        * an identifier of some kind (struct, union, enum, class, etc).  
+        */
        struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
                                                      objfile);
        char *prefix, *suffix;
        suffix = VT (objfile) + dn_bufp->dtype.name;
 
        /* Lookup the next type in the list.  It should be a structure,
-          union, or enum type.  We will need to attach that to our name.  */
+        * union, class, enum, or template type.  
+        * We will need to attach that to our name.  
+        */
        if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
          dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
        else
-         internal_error (__FILE__, __LINE__, "failed internal consistency check");
+         {
+           complain (&hpread_type_lookup_complaint);
+           return NULL;
+         }
 
        if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
-         prefix = "struct ";
+         {
+           prefix = "struct ";
+         }
        else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
-         prefix = "union ";
+         {
+           prefix = "union ";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+         {
+           /* Further field for CLASS saying how it was really declared */
+           /* 0==class, 1==union, 2==struct */
+           if (dn_bufp->dclass.class_decl == 0)
+             prefix = "class ";
+           else if (dn_bufp->dclass.class_decl == 1)
+             prefix = "union ";
+           else if (dn_bufp->dclass.class_decl == 2)
+             prefix = "struct ";
+           else
+             prefix = "";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM)
+         {
+           prefix = "enum ";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+         {
+           prefix = "template ";
+         }
        else
-         prefix = "enum ";
+         {
+           prefix = "";
+         }
 
        /* Build the correct name.  */
        structtype->name
@@ -1633,18 +4851,34 @@ hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
        TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
        TYPE_TAG_NAME (structtype) = suffix;
 
-       TYPE_CPLUS_SPECIFIC (structtype)
-         = (struct cplus_struct_type *) &cplus_struct_default;
+       /* For classes/structs, we have to set the static member "physnames"
+          to point to strings like "Class::Member" */
+       if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
+         fix_static_member_physnames (structtype, suffix, objfile);
 
        return structtype;
       }
+
     case DNTT_TYPE_POINTER:
-      return lookup_pointer_type (hpread_type_lookup (dn_bufp->dptr.pointsto,
-                                                     objfile));
+      /* Pointer type - call a routine in gdbtypes.c that constructs
+       * the appropriate GDB type.
+       */
+      return make_pointer_type (
+                                hpread_type_lookup (dn_bufp->dptr.pointsto,
+                                                    objfile),
+                                NULL);
+
+    case DNTT_TYPE_REFERENCE:
+      /* C++ reference type - call a routine in gdbtypes.c that constructs
+       * the appropriate GDB type.
+       */
+      return make_reference_type (
+                          hpread_type_lookup (dn_bufp->dreference.pointsto,
+                                              objfile),
+                                  NULL);
+
     case DNTT_TYPE_ENUM:
       return hpread_read_enum_type (hp_type, dn_bufp, objfile);
-    case DNTT_TYPE_MEMENUM:
-      return lookup_fundamental_type (objfile, FT_VOID);
     case DNTT_TYPE_SET:
       return hpread_read_set_type (hp_type, dn_bufp, objfile);
     case DNTT_TYPE_SUBRANGE:
@@ -1656,17 +4890,146 @@ hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
       return hpread_read_struct_type (hp_type, dn_bufp, objfile);
     case DNTT_TYPE_FIELD:
       return hpread_type_lookup (dn_bufp->dfield.type, objfile);
-    case DNTT_TYPE_VARIANT:
-    case DNTT_TYPE_FILE:
-      return lookup_fundamental_type (objfile, FT_VOID);
+
     case DNTT_TYPE_FUNCTYPE:
-      return lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
-                                                      objfile));
-    case DNTT_TYPE_COBSTRUCT:
-    case DNTT_TYPE_XREF:
-    case DNTT_TYPE_SA:
-    case DNTT_TYPE_MACRO:
+      /* Here we want to read the function SOMs and return a 
+       * type for it. We get here, for instance, when processing
+       * pointer-to-function type.
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_PTRMEM:
+      /* Declares a C++ pointer-to-data-member type. 
+       * The "pointsto" field defines the class,
+       * while the "memtype" field defines the pointed-to-type.
+       */
+      {
+       struct type *ptrmemtype;
+       struct type *class_type;
+       struct type *memtype;
+       memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+                                     objfile),
+         class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+                                          objfile),
+         ptrmemtype = alloc_type (objfile);
+       smash_to_member_type (ptrmemtype, class_type, memtype);
+       return make_pointer_type (ptrmemtype, NULL);
+      }
+      break;
+
+    case DNTT_TYPE_PTRMEMFUNC:
+      /* Defines a C++ pointer-to-function-member type. 
+       * The "pointsto" field defines the class,
+       * while the "memtype" field defines the pointed-to-type.
+       */
+      {
+       struct type *ptrmemtype;
+       struct type *class_type;
+       struct type *functype;
+       struct type *retvaltype;
+       int nargs;
+       int i;
+       struct type **args_type;
+       class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+                                        objfile);
+       functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+                                      objfile);
+       retvaltype = TYPE_TARGET_TYPE (functype);
+       nargs = TYPE_NFIELDS (functype);
+       args_type = (struct type **) xmalloc ((nargs + 1) * sizeof (struct type *));
+       for (i = 0; i < nargs; i++)
+         {
+           args_type[i] = TYPE_FIELD_TYPE (functype, i);
+         }
+       args_type[nargs] = NULL;
+       ptrmemtype = alloc_type (objfile);
+       smash_to_method_type (ptrmemtype, class_type, retvaltype, args_type);
+       return make_pointer_type (ptrmemtype, NULL);
+      }
+      break;
+
+    case DNTT_TYPE_CLASS:
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+    case DNTT_TYPE_GENFIELD:
+      /* Chase pointer from GENFIELD to FIELD, and make recursive
+       * call on that.
+       */
+      return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
+
+    case DNTT_TYPE_VFUNC:
+      /* C++ virtual function.
+       * We get here in the course of processing a class type which
+       * contains virtual functions. Just go through another level
+       * of indirection to get to the pointed-to function SOM.
+       */
+      return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
+
+    case DNTT_TYPE_MODIFIER:
+      /* Check the modifiers and then just make a recursive call on
+       * the "type" pointed to by the modifier DNTT.
+       * 
+       * pai:: FIXME -- do we ever want to handle "m_duplicate" and
+       * "m_void" modifiers?  Is static_flag really needed here?
+       * (m_static used for methods of classes, elsewhere).
+       */
+      tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
+                              dn_bufp->dmodifier.m_volatile,
+                     hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
+                              0);
+      return tmp_type;
+
+
+    case DNTT_TYPE_MEMFUNC:
+      /* Member function. Treat like a function.
+       * I think we get here in the course of processing a 
+       * pointer-to-member-function type...
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_DOC_MEMFUNC:
+      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_TEMPLATE:
+      /* Template - sort of the header for a template definition,
+       * which like a class, points to a member list and also points
+       * to a TEMPLATE_ARG list of type-arguments.
+       */
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+    case DNTT_TYPE_TEMPLATE_ARG:
+      {
+       char *name;
+       /* The TEMPLATE record points to an argument list of
+        * TEMPLATE_ARG records, each of which describes one
+        * of the type-arguments. 
+        */
+       name = VT (objfile) + dn_bufp->dtempl_arg.name;
+       return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
+      }
+
+    case DNTT_TYPE_FUNC_TEMPLATE:
+      /* We wind up here when processing a TEMPLATE type, 
+       * if the template has member function(s).
+       * Treat it like a FUNCTION.
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_LINK:
+      /* The LINK record is used to link up templates with instantiations.
+       * There is no type associated with the LINK record per se.
+       */
+      return lookup_fundamental_type (objfile, FT_VOID);
+
+      /* Also not yet handled... */
+      /* case DNTT_TYPE_DYN_ARRAY_DESC: */
+      /* case DNTT_TYPE_DESC_SUBRANGE: */
+      /* case DNTT_TYPE_BEGIN_EXT: */
+      /* case DNTT_TYPE_INLN: */
+      /* case DNTT_TYPE_INLN_LIST: */
+      /* case DNTT_TYPE_ALIAS: */
     default:
+      /* A fancy way of returning NULL */
       return lookup_fundamental_type (objfile, FT_VOID);
     }
 }
@@ -1686,81 +5049,249 @@ hpread_record_lines (struct subfile *subfile, sltpointer s_idx,
          || sl_bufp->snorm.sltdesc == SLT_EXIT)
        record_line (subfile, sl_bufp->snorm.line,
                     sl_bufp->snorm.address + offset);
+      else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+       record_line (subfile, sl_bufp->snormoff.line,
+                    sl_bufp->snormoff.address + offset);
       s_idx++;
     }
   return e_idx;
 }
 
-/* Internalize one native debug symbol.  */
+/* Given a function "f" which is a member of a class, find
+ * the classname that it is a member of. Used to construct
+ * the name (e.g., "c::f") which GDB will put in the
+ * "demangled name" field of the function's symbol.
+ * Called from hpread_process_one_debug_symbol()
+ * If "f" is not a member function, return NULL.
+ */
+char *
+class_of (struct type *functype)
+{
+  struct type *first_param_type;
+  char *first_param_name;
+  struct type *pointed_to_type;
+  char *class_name;
+
+  /* Check that the function has a first argument "this",
+   * and that "this" is a pointer to a class. If not,
+   * functype is not a member function, so return NULL.
+   */
+  if (TYPE_NFIELDS (functype) == 0)
+    return NULL;
+  first_param_name = TYPE_FIELD_NAME (functype, 0);
+  if (first_param_name == NULL)
+    return NULL;               /* paranoia */
+  if (strcmp (first_param_name, "this"))
+    return NULL;
+  first_param_type = TYPE_FIELD_TYPE (functype, 0);
+  if (first_param_type == NULL)
+    return NULL;               /* paranoia */
+  if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR)
+    return NULL;
+
+  /* Get the thing that "this" points to, check that
+   * it's a class, and get its class name.
+   */
+  pointed_to_type = TYPE_TARGET_TYPE (first_param_type);
+  if (pointed_to_type == NULL)
+    return NULL;               /* paranoia */
+  if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS)
+    return NULL;
+  class_name = TYPE_NAME (pointed_to_type);
+  if (class_name == NULL)
+    return NULL;               /* paranoia */
+
+  /* The class name may be of the form "class c", in which case
+   * we want to strip off the leading "class ".
+   */
+  if (strncmp (class_name, "class ", 6) == 0)
+    class_name += 6;
+
+  return class_name;
+}
+
+/* Internalize one native debug symbol. 
+ * Called in a loop from hpread_expand_symtab(). 
+ * Arguments:
+ *   dn_bufp: 
+ *   name: 
+ *   section_offsets:
+ *   objfile:
+ *   text_offset: 
+ *   text_size: 
+ *   filename: 
+ *   index:             Index of this symbol
+ *   at_module_boundary_p Pointer to boolean flag to control caller's loop.
+ */
 
 static void
 hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
                                 struct section_offsets *section_offsets,
                                 struct objfile *objfile, CORE_ADDR text_offset,
-                                int text_size, char *filename, int index)
+                                int text_size, char *filename, int index,
+                                int *at_module_boundary_p)
 {
   unsigned long desc;
   int type;
   CORE_ADDR valu;
   int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+  int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
   union dnttentry *dn_temp;
   dnttpointer hp_type;
   struct symbol *sym;
   struct context_stack *new;
+  char *class_scope_name;
 
-  /* Allocate one GDB debug symbol and fill in some default values.  */
+  /* Allocate one GDB debug symbol and fill in some default values. */
   sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
                                         sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
   SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
   SYMBOL_LANGUAGE (sym) = language_auto;
-  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
   SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
   SYMBOL_LINE (sym) = 0;
   SYMBOL_VALUE (sym) = 0;
   SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 
+  /* Just a trick in case the SOM debug symbol is a type definition.
+   * There are routines that are set up to build a GDB type symbol, given
+   * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type".
+   * This allows us to call those same routines.
+   */
   hp_type.dnttp.extension = 1;
   hp_type.dnttp.immediate = 0;
   hp_type.dnttp.global = 0;
   hp_type.dnttp.index = index;
 
+  /* This "type" is the type of SOM record.
+   * Switch on SOM type.
+   */
   type = dn_bufp->dblock.kind;
-
   switch (type)
     {
     case DNTT_TYPE_SRCFILE:
-      /* This type of symbol indicates from which source file or include file
-         the following data comes. If there are no modules it also may
-         indicate the start of a new source file, in which case we must
-         finish the symbol table of the previous source file
-         (if any) and start accumulating a new symbol table.  */
+      /* This type of symbol indicates from which source file or
+       * include file any following data comes. It may indicate:
+       *
+       * o   The start of an entirely new source file (and thus
+       *     a new module)
+       *
+       * o   The start of a different source file due to #include
+       *
+       * o   The end of an include file and the return to the original
+       *     file. Thus if "foo.c" includes "bar.h", we see first
+       *     a SRCFILE for foo.c, then one for bar.h, and then one for
+       *     foo.c again.
+       *
+       * If it indicates the start of a new module then we must
+       * finish the symbol table of the previous module 
+       * (if any) and start accumulating a new symbol table.  
+       */
 
       valu = text_offset;
       if (!last_source_file)
        {
+         /*
+          * A note on "last_source_file": this is a char* pointing
+          * to the actual file name.  "start_symtab" sets it,
+          * "end_symtab" clears it.
+          *
+          * So if "last_source_file" is NULL, then either this is
+          * the first record we are looking at, or a previous call
+          * to "end_symtab()" was made to close out the previous
+          * module.  Since we're now quitting the scan loop when we
+          * see a MODULE END record, we should never get here, except
+          * in the case that we're not using the quick look-up tables
+          * and have to use the old system as a fall-back.
+          */
          start_symtab (name, NULL, valu);
          record_debugformat ("HP");
          SL_INDEX (objfile) = dn_bufp->dsfile.address;
        }
+
+      else
+       {
+         /* Either a new include file, or a SRCFILE record
+          * saying we are back in the main source (or out of
+          * a nested include file) again.
+          */
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dsfile.address,
+                                                   objfile, offset);
+       }
+
+      /* A note on "start_subfile".  This routine will check
+       * the name we pass it and look for an existing subfile
+       * of that name.  There's thus only one sub-file for the
+       * actual source (e.g. for "foo.c" in foo.c), despite the
+       * fact that we'll see lots of SRCFILE entries for foo.c
+       * inside foo.c.
+       */
+      start_subfile (name, NULL);
+      break;
+
+    case DNTT_TYPE_MODULE:
+      /*
+       * We no longer ignore DNTT_TYPE_MODULE symbols.  The module 
+       * represents the meaningful semantic structure of a compilation
+       * unit.  We expect to start the psymtab-to-symtab expansion
+       * looking at a MODULE entry, and to end it at the corresponding
+       * END MODULE entry.
+       *
+       *--Begin outdated comments
+       * 
+       * This record signifies the start of a new source module
+       * In C/C++ there is no explicit "module" construct in the language,
+       * but each compilation unit is implicitly a module and they
+       * do emit the DNTT_TYPE_MODULE records.
+       * The end of the module is marked by a matching DNTT_TYPE_END record.
+       *
+       * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record 
+       * is it notices the DNTT_TYPE_END record for the previous 
+       * module (see comments under DNTT_TYPE_END case), and then treats
+       * the next DNTT_TYPE_SRCFILE record as if it were the module-start record.
+       * (i.e., it makes a start_symtab() call).
+       * This scheme seems a little convoluted, but I'll leave it 
+       * alone on the principle "if it ain't broke don't fix
+       * it". (RT).
+       *
+       *-- End outdated comments
+       */
+
+      valu = text_offset;
+      if (!last_source_file)
+       {
+         /* Start of a new module. We know this because "last_source_file"
+          * is NULL, which can only happen the first time or if we just 
+          * made a call to end_symtab() to close out the previous module.
+          */
+         start_symtab (name, NULL, valu);
+         SL_INDEX (objfile) = dn_bufp->dmodule.address;
+       }
       else
        {
-         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                                   SL_INDEX (objfile),
-                                                   dn_bufp->dsfile.address,
-                                                   objfile, offset);
+         /* This really shouldn't happen if we're using the quick
+          * look-up tables, as it would mean we'd scanned past an
+          * END MODULE entry.  But if we're not using the tables,
+          * we started the module on the SRCFILE entry, so it's ok.
+          * For now, accept this.
+          */
+         /* warning( "Error expanding psymtab, missed module end, found entry for %s",
+          *           name );
+          */
+         *at_module_boundary_p = -1;
        }
-      start_subfile (name, NULL);
-      break;
 
-    case DNTT_TYPE_MODULE:
-      /* No need to do anything with these DNTT_TYPE_MODULE symbols anymore.  */
+      start_subfile (name, NULL);
       break;
 
     case DNTT_TYPE_FUNCTION:
     case DNTT_TYPE_ENTRY:
       /* A function or secondary entry point.  */
       valu = dn_bufp->dfunc.lowaddr + offset;
+
+      /* Record lines up to this point. */
       SL_INDEX (objfile) = hpread_record_lines (current_subfile,
                                                SL_INDEX (objfile),
                                                dn_bufp->dfunc.address,
@@ -1774,53 +5305,312 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
        complain (&lbrac_unmatched_complaint, (char *) symnum);
       new = push_context (0, valu);
 
+      /* Built a type for the function. This includes processing
+       * the symbol records for the function parameters.
+       */
       SYMBOL_CLASS (sym) = LOC_BLOCK;
-      SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile);
+      SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
+
+      /* The "SYMBOL_NAME" field is expected to be the mangled name
+       * (if any), which we get from the "alias" field of the SOM record
+       * if that exists.
+       */
+      if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+         dn_bufp->dfunc.alias &&       /* has an alias */
+         *(char *) (VT (objfile) + dn_bufp->dfunc.alias))      /* not a null string */
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
+      else
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+      /* Special hack to get around HP compilers' insistence on
+       * reporting "main" as "_MAIN_" for C/C++ */
+      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+         (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+      /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to
+       * be the demangled name.
+       */
+      if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+          * calling the demangler in libiberty (cplus_demangle()) to
+          * do the job. This generally does the job, even though
+          * it's intended for the GNU compiler and not the aCC compiler
+          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+          * Generally, we don't want params when we display
+          * a demangled name, but when I took out the DMGL_PARAMS,
+          * some things broke, so I'm leaving it in here, and
+          * working around the issue in stack.c. - RT
+          */
+         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
+             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+           {
+
+             /* Well, the symbol name is mangled, but the
+              * demangler in libiberty failed so the demangled
+              * field is still NULL. Try to
+              * do the job ourselves based on the "name" field
+              * in the SOM record. A complication here is that
+              * the name field contains only the function name
+              * (like "f"), whereas we want the class qualification
+              * (as in "c::f"). Try to reconstruct that.
+              */
+             char *basename;
+             char *classname;
+             char *dem_name;
+             basename = VT (objfile) + dn_bufp->dfunc.name;
+             classname = class_of (SYMBOL_TYPE (sym));
+             if (classname)
+               {
+                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+                 strcpy (dem_name, classname);
+                 strcat (dem_name, "::");
+                 strcat (dem_name, basename);
+                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+                 SYMBOL_LANGUAGE (sym) = language_cplus;
+               }
+           }
+       }
+
+      /* Add the function symbol to the list of symbols in this blockvector */
       if (dn_bufp->dfunc.global)
        add_symbol_to_list (sym, &global_symbols);
       else
        add_symbol_to_list (sym, &file_symbols);
       new->name = sym;
 
-      /* Search forward to the next scope beginning.  */
-      while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+      /* Search forward to the next BEGIN and also read
+       * in the line info up to that point. 
+       * Not sure why this is needed.
+       * In HP FORTRAN this code is harmful since there   
+       * may not be a BEGIN after the FUNCTION.
+       * So I made it C/C++ specific. - RT
+       */
+      if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
+         dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
        {
-         dn_bufp = hpread_get_lntt (++index, objfile);
-         if (dn_bufp->dblock.extension)
-           continue;
+         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+           {
+             dn_bufp = hpread_get_lntt (++index, objfile);
+             if (dn_bufp->dblock.extension)
+               continue;
+           }
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
        }
+      record_line (current_subfile, SYMBOL_LINE (sym), valu);
+      break;
+
+    case DNTT_TYPE_DOC_FUNCTION:
+      valu = dn_bufp->ddocfunc.lowaddr + offset;
+
+      /* Record lines up to this point. */
       SL_INDEX (objfile) = hpread_record_lines (current_subfile,
                                                SL_INDEX (objfile),
-                                               dn_bufp->dbegin.address,
+                                               dn_bufp->ddocfunc.address,
                                                objfile, offset);
-      SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+
+      WITHIN_FUNCTION (objfile) = 1;
+      CURRENT_FUNCTION_VALUE (objfile) = valu;
+      /* Stack must be empty now.  */
+      if (context_stack_depth != 0)
+       complain (&lbrac_unmatched_complaint, (char *) symnum);
+      new = push_context (0, valu);
+
+      /* Built a type for the function. This includes processing
+       * the symbol records for the function parameters.
+       */
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
+
+      /* The "SYMBOL_NAME" field is expected to be the mangled name
+       * (if any), which we get from the "alias" field of the SOM record
+       * if that exists.
+       */
+      if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+         dn_bufp->ddocfunc.alias &&    /* has an alias */
+         *(char *) (VT (objfile) + dn_bufp->ddocfunc.alias))   /* not a null string */
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
+      else
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+      /* Special hack to get around HP compilers' insistence on
+       * reporting "main" as "_MAIN_" for C/C++ */
+      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+         (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+
+         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+          * calling the demangler in libiberty (cplus_demangle()) to
+          * do the job. This generally does the job, even though
+          * it's intended for the GNU compiler and not the aCC compiler
+          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+          * Generally, we don't want params when we display
+          * a demangled name, but when I took out the DMGL_PARAMS,
+          * some things broke, so I'm leaving it in here, and
+          * working around the issue in stack.c. - RT 
+          */
+         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
+             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+           {
+
+             /* Well, the symbol name is mangled, but the
+              * demangler in libiberty failed so the demangled
+              * field is still NULL. Try to
+              * do the job ourselves based on the "name" field
+              * in the SOM record. A complication here is that
+              * the name field contains only the function name
+              * (like "f"), whereas we want the class qualification
+              * (as in "c::f"). Try to reconstruct that.
+              */
+             char *basename;
+             char *classname;
+             char *dem_name;
+             basename = VT (objfile) + dn_bufp->ddocfunc.name;
+             classname = class_of (SYMBOL_TYPE (sym));
+             if (classname)
+               {
+                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+                 strcpy (dem_name, classname);
+                 strcat (dem_name, "::");
+                 strcat (dem_name, basename);
+                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+                 SYMBOL_LANGUAGE (sym) = language_cplus;
+               }
+           }
+       }
+
+      /* Add the function symbol to the list of symbols in this blockvector */
+      if (dn_bufp->ddocfunc.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      new->name = sym;
+
+      /* Search forward to the next BEGIN and also read
+       * in the line info up to that point. 
+       * Not sure why this is needed.
+       * In HP FORTRAN this code is harmful since there   
+       * may not be a BEGIN after the FUNCTION.
+       * So I made it C/C++ specific. - RT
+       */
+      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
+         dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+           {
+             dn_bufp = hpread_get_lntt (++index, objfile);
+             if (dn_bufp->dblock.extension)
+               continue;
+           }
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+       }
       record_line (current_subfile, SYMBOL_LINE (sym), valu);
       break;
 
     case DNTT_TYPE_BEGIN:
-      /* Begin a new scope.  */
-      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
-                                               SL_INDEX (objfile),
-                                               dn_bufp->dbegin.address,
-                                               objfile, offset);
-      valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
-      valu += offset;          /* Relocate for dynamic loading */
-      desc = hpread_get_depth (dn_bufp->dbegin.address, objfile);
-      new = push_context (desc, valu);
+      /* Begin a new scope. */
+      if (context_stack_depth == 1 /* this means we're at function level */  &&
+         context_stack[0].name != NULL /* this means it's a function */  &&
+         context_stack[0].depth == 0   /* this means it's the first BEGIN 
+                                          we've seen after the FUNCTION */
+       )
+       {
+         /* This is the first BEGIN after a FUNCTION.
+          * We ignore this one, since HP compilers always insert
+          * at least one BEGIN, i.e. it's:
+          * 
+          *     FUNCTION
+          *     argument symbols
+          *     BEGIN
+          *     local symbols
+          *        (possibly nested BEGIN ... END's if there are inner { } blocks)
+          *     END
+          *     END
+          *
+          * By ignoring this first BEGIN, the local symbols get treated
+          * as belonging to the function scope, and "print func::local_sym"
+          * works (which is what we want).
+          */
+
+         /* All we do here is increase the depth count associated with
+          * the FUNCTION entry in the context stack. This ensures that
+          * the next BEGIN we see (if any), representing a real nested { }
+          * block, will get processed.
+          */
+
+         context_stack[0].depth++;
+
+       }
+      else
+       {
+
+         /* Record lines up to this SLT pointer. */
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         /* Calculate start address of new scope */
+         valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
+         valu += offset;       /* Relocate for dynamic loading */
+         /* We use the scope start DNTT index as nesting depth identifier! */
+         desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
+         new = push_context (desc, valu);
+       }
       break;
 
     case DNTT_TYPE_END:
       /* End a scope.  */
+
+      /* Valid end kinds are:
+       *  MODULE
+       *  FUNCTION
+       *  WITH
+       *  COMMON
+       *  BEGIN
+       *  CLASS_SCOPE
+       */
+
       SL_INDEX (objfile) = hpread_record_lines (current_subfile,
                                                SL_INDEX (objfile),
-                                               dn_bufp->dend.address + 1,
+                                               dn_bufp->dend.address,
                                                objfile, offset);
       switch (dn_bufp->dend.endkind)
        {
        case DNTT_TYPE_MODULE:
-         /* Ending a module ends the symbol table for that module.  */
+         /* Ending a module ends the symbol table for that module.  
+          * Calling end_symtab() has the side effect of clearing the
+          * last_source_file pointer, which in turn signals 
+          * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE
+          * record as a module-begin.
+          */
          valu = text_offset + text_size + offset;
-         (void) end_symtab (valu, objfile, SECT_OFF_TEXT (objfile));
+
+         /* Tell our caller that we're done with expanding the
+          * debug information for a module.
+          */
+         *at_module_boundary_p = 1;
+
+         /* Don't do this, as our caller will do it!
+
+          *      (void) end_symtab (valu, objfile, 0);
+          */
          break;
 
        case DNTT_TYPE_FUNCTION:
@@ -1828,14 +5618,65 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
          dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
                                     objfile);
          valu = dn_temp->dfunc.hiaddr + offset;
+         /* Insert func params into local list */
+         merge_symbol_lists (&param_symbols, &local_symbols);
          new = pop_context ();
          /* Make a block for the local symbols within.  */
          finish_block (new->name, &local_symbols, new->old_blocks,
                        new->start_addr, valu, objfile);
-         WITHIN_FUNCTION (objfile) = 0;
+         WITHIN_FUNCTION (objfile) = 0;        /* This may have to change for Pascal */
+         local_symbols = new->locals;
+         param_symbols = new->params;
          break;
+
        case DNTT_TYPE_BEGIN:
-         /* Just ending a local scope.  */
+         if (context_stack_depth == 1 &&
+             context_stack[0].name != NULL &&
+             context_stack[0].depth == 1)
+           {
+             /* This is the END corresponding to the
+              * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above.
+              */
+             context_stack[0].depth--;
+           }
+         else
+           {
+             /* Ending a local scope.  */
+             valu = hpread_get_location (dn_bufp->dend.address, objfile);
+             /* Why in the hell is this needed?  */
+             valu += offset + 9;       /* Relocate for dynamic loading */
+             new = pop_context ();
+             desc = dn_bufp->dend.beginscope.dnttp.index;
+             if (desc != new->depth)
+               complain (&lbrac_mismatch_complaint, (char *) symnum);
+
+             /* Make a block for the local symbols within.  */
+             finish_block (new->name, &local_symbols, new->old_blocks,
+                           new->start_addr, valu, objfile);
+             local_symbols = new->locals;
+             param_symbols = new->params;
+           }
+         break;
+
+       case DNTT_TYPE_WITH:
+         /* Since we ignore the DNTT_TYPE_WITH that starts the scope,
+          * we can ignore the DNTT_TYPE_END that ends it.
+          */
+         break;
+
+       case DNTT_TYPE_COMMON:
+         /* End a FORTRAN common block. We don't currently handle these */
+         complain (&hpread_unhandled_end_common_complaint);
+         break;
+
+       case DNTT_TYPE_CLASS_SCOPE:
+
+         /* pai: FIXME Not handling nested classes for now -- must
+            * maintain a stack */
+         class_scope_name = NULL;
+
+#if 0
+         /* End a class scope */
          valu = hpread_get_location (dn_bufp->dend.address, objfile);
          /* Why in the hell is this needed?  */
          valu += offset + 9;   /* Relocate for dynamic loading */
@@ -1847,18 +5688,55 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
          finish_block (new->name, &local_symbols, new->old_blocks,
                        new->start_addr, valu, objfile);
          local_symbols = new->locals;
+         param_symbols = new->params;
+#endif
+         break;
+
+       default:
+         complain (&hpread_unexpected_end_complaint);
          break;
        }
       break;
+
+      /* DNTT_TYPE_IMPORT is not handled */
+
     case DNTT_TYPE_LABEL:
       SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
       break;
+
     case DNTT_TYPE_FPARAM:
       /* Function parameters.  */
+      /* Note 1: This code was present in the 4.16 sources, and then
+         removed, because fparams are handled in
+         hpread_read_function_type().  However, while fparam symbols
+         are indeed handled twice, this code here cannot be removed
+         because then they don't get added to the local symbol list of
+         the function's code block, which leads to a failure to look
+         up locals, "this"-relative member names, etc.  So I've put
+         this code back in. pai/1997-07-21 */
+      /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols
+         in hpread_read_function_type(), so FPARAMS had to be handled
+         here.  I changed the location to be the appropriate argument
+         kinds rather than LOC_LOCAL. pai/1997-08-08 */
+      /* Note 3: Well, the fix in Note 2 above broke argument printing
+         in traceback frames, and further it makes assumptions about the
+         order of the FPARAM entries from HP compilers (cc and aCC in particular
+         generate them in reverse orders -- fixing one breaks for the other).
+         So I've added code in hpread_read_function_type() to add fparams
+         to a param_symbols list for the current context level.  These are
+         then merged into local_symbols when a function end is reached.
+         pai/1997-08-11 */
+
+      break;                   /* do nothing; handled in hpread_read_function_type() */
+
+#if 0                          /* Old code */
       if (dn_bufp->dfparam.regparam)
        SYMBOL_CLASS (sym) = LOC_REGISTER;
+      else if (dn_bufp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
       else
-       SYMBOL_CLASS (sym) = LOC_LOCAL;
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       if (dn_bufp->dfparam.copyparam)
        {
          SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
@@ -1870,26 +5748,81 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
       else
        SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
-      add_symbol_to_list (sym, &local_symbols);
+      add_symbol_to_list (sym, &fparam_symbols);
       break;
+#endif
+
     case DNTT_TYPE_SVAR:
       /* Static variables.  */
       SYMBOL_CLASS (sym) = LOC_STATIC;
-      SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location;
+
+      /* Note: There is a case that arises with globals in shared
+       * libraries where we need to set the address to LOC_INDIRECT.
+       * This case is if you have a global "g" in one library, and
+       * it is referenced "extern <type> g;" in another library.
+       * If we're processing the symbols for the referencing library,
+       * we'll see a global "g", but in this case the address given
+       * in the symbol table contains a pointer to the real "g".
+       * We use the storage class LOC_INDIRECT to indicate this. RT
+       */
+      if (is_in_import_list (SYMBOL_NAME (sym), objfile))
+       SYMBOL_CLASS (sym) = LOC_INDIRECT;
+
+      SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
+
       if (dn_bufp->dsvar.global)
        add_symbol_to_list (sym, &global_symbols);
+
       else if (WITHIN_FUNCTION (objfile))
        add_symbol_to_list (sym, &local_symbols);
+
       else
        add_symbol_to_list (sym, &file_symbols);
+
+      if (dn_bufp->dsvar.thread_specific)
+       {
+         /* Thread-local variable.
+          */
+         SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+         SYMBOL_BASEREG (sym) = CR27_REGNUM;
+
+         if (objfile->flags & OBJF_SHARED)
+           {
+             /*
+              * This variable is not only thread local but
+              * in a shared library.
+              *
+              * Alas, the shared lib structures are private
+              * to "somsolib.c".  But C lets us point to one.
+              */
+             struct so_list *so;
+
+             if (objfile->obj_private == NULL)
+               error ("Internal error in reading shared library information.");
+
+             so = ((obj_private_data_t *) (objfile->obj_private))->so_info;
+             if (so == NULL)
+               error ("Internal error in reading shared library information.");
+
+             /* Thread-locals in shared libraries do NOT have the
+              * standard offset ("data_offset"), so we re-calculate
+              * where to look for this variable, using a call-back
+              * to interpret the private shared-library data.
+              */
+             SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location +
+               so_lib_thread_start_addr (so);
+           }
+       }
       break;
+
     case DNTT_TYPE_DVAR:
       /* Dynamic variables.  */
       if (dn_bufp->ddvar.regvar)
        SYMBOL_CLASS (sym) = LOC_REGISTER;
       else
        SYMBOL_CLASS (sym) = LOC_LOCAL;
+
       SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
 #ifdef HPREAD_ADJUST_STACK_ADDRESS
       SYMBOL_VALUE (sym)
@@ -1903,6 +5836,7 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
       else
        add_symbol_to_list (sym, &file_symbols);
       break;
+
     case DNTT_TYPE_CONST:
       /* A constant (pascal?).  */
       SYMBOL_CLASS (sym) = LOC_CONST;
@@ -1915,7 +5849,11 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
       else
        add_symbol_to_list (sym, &file_symbols);
       break;
+
     case DNTT_TYPE_TYPEDEF:
+      /* A typedef. We do want to process these, since a name is
+       * added to the namespace for the typedef'ed name.
+       */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
       if (dn_bufp->dtype.global)
@@ -1925,51 +5863,490 @@ hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
       else
        add_symbol_to_list (sym, &file_symbols);
       break;
+
     case DNTT_TYPE_TAGDEF:
-      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
-      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
-      TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
-      TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
-      if (dn_bufp->dtype.global)
-       add_symbol_to_list (sym, &global_symbols);
-      else if (WITHIN_FUNCTION (objfile))
-       add_symbol_to_list (sym, &local_symbols);
-      else
-       add_symbol_to_list (sym, &file_symbols);
+      {
+       int global = dn_bufp->dtag.global;
+       /* Structure, union, enum, template, or class tag definition */
+       /* We do want to process these, since a name is
+        * added to the namespace for the tag name (and if C++ class,
+        * for the typename also).
+        */
+       SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+       /* The tag contains in its "type" field a pointer to the
+        * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM, 
+        * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE
+        * record that actually defines the type.
+        */
+       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+       TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
+       TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
+       if (dn_bufp->dtag.global)
+         add_symbol_to_list (sym, &global_symbols);
+       else if (WITHIN_FUNCTION (objfile))
+         add_symbol_to_list (sym, &local_symbols);
+       else
+         add_symbol_to_list (sym, &file_symbols);
+
+       /* If this is a C++ class, then we additionally 
+        * need to define a typedef for the
+        * class type. E.g., so that the name "c" becomes visible as
+        * a type name when the user says "class c { ... }".
+        * In order to figure this out, we need to chase down the "type"
+        * field to get to the DNTT_TYPE_CLASS record. 
+        *
+        * We also add the typename for ENUM. Though this isn't
+        * strictly correct, it is necessary because of the debug info
+        * generated by the aCC compiler, in which we cannot
+        * distinguish between:
+        *   enum e { ... };
+        * and
+        *   typedef enum { ... } e;
+        * I.e., the compiler emits the same debug info for the above
+        * two cases, in both cases "e" appearing as a tagdef.
+        * Therefore go ahead and generate the typename so that
+        * "ptype e" will work in the above cases.
+        *
+        * We also add the typename for TEMPLATE, so as to allow "ptype t"
+        * when "t" is a template name. 
+        */
+       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+         dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
+       else
+         {
+           complain (&hpread_tagdef_complaint);
+           return;
+         }
+       if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+           dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+           dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+         {
+           struct symbol *newsym;
+
+           newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                                   sizeof (struct symbol));
+           memset (newsym, 0, sizeof (struct symbol));
+           SYMBOL_NAME (newsym) = name;
+           SYMBOL_LANGUAGE (newsym) = language_auto;
+           SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE;
+           SYMBOL_LINE (newsym) = 0;
+           SYMBOL_VALUE (newsym) = 0;
+           SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
+           SYMBOL_TYPE (newsym) = sym->type;
+           if (global)
+             add_symbol_to_list (newsym, &global_symbols);
+           else if (WITHIN_FUNCTION (objfile))
+             add_symbol_to_list (newsym, &local_symbols);
+           else
+             add_symbol_to_list (newsym, &file_symbols);
+         }
+      }
       break;
+
     case DNTT_TYPE_POINTER:
-      SYMBOL_TYPE (sym) = lookup_pointer_type (hpread_type_lookup
-                                              (dn_bufp->dptr.pointsto,
-                                               objfile));
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares a pointer type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
       break;
+
     case DNTT_TYPE_ENUM:
-      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
-      SYMBOL_TYPE (sym) = hpread_read_enum_type (hp_type, dn_bufp, objfile);
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares an enum type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
       break;
+
     case DNTT_TYPE_MEMENUM:
+      /* Member of enum */
+      /* Ignored at this level, but hpread_read_enum_type() will take
+       * care of walking the list of enumeration members.
+       */
       break;
+
     case DNTT_TYPE_SET:
-      SYMBOL_TYPE (sym) = hpread_read_set_type (hp_type, dn_bufp, objfile);
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares a set type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
       break;
+
     case DNTT_TYPE_SUBRANGE:
-      SYMBOL_TYPE (sym) = hpread_read_subrange_type (hp_type, dn_bufp,
-                                                    objfile);
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares a subrange type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
       break;
+
     case DNTT_TYPE_ARRAY:
-      SYMBOL_TYPE (sym) = hpread_read_array_type (hp_type, dn_bufp, objfile);
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares an array type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
       break;
+
     case DNTT_TYPE_STRUCT:
     case DNTT_TYPE_UNION:
-      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
-      SYMBOL_TYPE (sym) = hpread_read_struct_type (hp_type, dn_bufp, objfile);
-      add_symbol_to_list (sym, &file_symbols);
+      /* Declares an struct/union type. 
+       * Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_FIELD:
+      /* Structure/union/class field */
+      /* Ignored at this level, but hpread_read_struct_type() will take
+       * care of walking the list of structure/union/class members.
+       */
+      break;
+
+      /* DNTT_TYPE_VARIANT is not handled by GDB */
+
+      /* DNTT_TYPE_FILE is not handled by GDB */
+
+    case DNTT_TYPE_FUNCTYPE:
+      /* Function type */
+      /* Ignored at this level, handled within hpread_type_lookup() */
+      break;
+
+    case DNTT_TYPE_WITH:
+      /* This is emitted within methods to indicate "with <class>" 
+       * scoping rules (i.e., indicate that the class data members
+       * are directly visible).
+       * However, since GDB already infers this by looking at the
+       * "this" argument, interpreting the DNTT_TYPE_WITH 
+       * symbol record is unnecessary.
+       */
+      break;
+
+    case DNTT_TYPE_COMMON:
+      /* FORTRAN common. Not yet handled. */
+      complain (&hpread_unhandled_common_complaint);
+      break;
+
+      /* DNTT_TYPE_COBSTRUCT is not handled by GDB.  */
+      /* DNTT_TYPE_XREF is not handled by GDB.  */
+      /* DNTT_TYPE_SA is not handled by GDB.  */
+      /* DNTT_TYPE_MACRO is not handled by GDB */
+
+    case DNTT_TYPE_BLOCKDATA:
+      /* Not sure what this is - part of FORTRAN support maybe? 
+       * Anyway, not yet handled.
+       */
+      complain (&hpread_unhandled_blockdata_complaint);
+      break;
+
+    case DNTT_TYPE_CLASS_SCOPE:
+
+
+
+      /* The compiler brackets member functions with a CLASS_SCOPE/END
+       * pair of records, presumably to put them in a different scope
+       * from the module scope where they are normally defined.
+       * E.g., in the situation:
+       *   void f() { ... }
+       *   void c::f() { ...}
+       * The member function "c::f" will be bracketed by a CLASS_SCOPE/END.
+       * This causes "break f" at the module level to pick the
+       * the file-level function f(), not the member function
+       * (which needs to be referenced via "break c::f"). 
+       * 
+       * Here we record the class name to generate the demangled names of
+       * member functions later.
+       *
+       * FIXME Not being used now for anything -- cplus_demangle seems
+       * enough for getting the class-qualified names of functions. We
+       * may need this for handling nested classes and types.  */
+
+      /* pai: FIXME Not handling nested classes for now -- need to
+       * maintain a stack */
+
+      dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
+      if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
+       class_scope_name = VT (objfile) + dn_temp->dtag.name;
+      else
+       class_scope_name = NULL;
+
+#if 0
+
+      /* Begin a new scope.  */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                             dn_bufp->dclass_scope.address,
+                                               objfile, offset);
+      valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
+      valu += offset;          /* Relocate for dynamic loading */
+      desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
+      /* We use the scope start DNTT index as the nesting depth identifier! */
+      new = push_context (desc, valu);
+#endif
+      break;
+
+    case DNTT_TYPE_REFERENCE:
+      /* Declares a C++ reference type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_PTRMEM:
+      /* Declares a C++ pointer-to-data-member type. This does not
+       * need to be handled at this level; being a type description it
+       * is instead handled at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_PTRMEMFUNC:
+      /* Declares a C++ pointer-to-function-member type. This does not
+       * need to be handled at this level; being a type description it
+       * is instead handled at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_CLASS:
+      /* Declares a class type. 
+       * Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_GENFIELD:
+      /* I believe this is used for class member functions */
+      /* Ignored at this level, but hpread_read_struct_type() will take
+       * care of walking the list of class members.
+       */
+      break;
+
+    case DNTT_TYPE_VFUNC:
+      /* Virtual function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_MEMACCESS:
+      /* DDE ignores this symbol table record.
+       * It has something to do with "modified access" to class members.
+       * I'll assume we can safely ignore it too.
+       */
+      break;
+
+    case DNTT_TYPE_INHERITANCE:
+      /* These don't have to be handled here, since they are handled
+       * within hpread_read_struct_type() in the process of constructing
+       * a class type.
+       */
+      break;
+
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+      /* These can safely be ignored, as GDB doesn't need this
+       * info. DDE only uses it in "describe". We may later want
+       * to extend GDB's "ptype" to give this info, but for now
+       * it seems safe enough to ignore it.
+       */
+      break;
+
+    case DNTT_TYPE_MODIFIER:
+      /* Intended to supply "modified access" to a type */
+      /* From the way DDE handles this, it looks like it always
+       * modifies a type. Therefore it is safe to ignore it at this
+       * level, and handle it in hpread_type_lookup().
+       */
+      break;
+
+    case DNTT_TYPE_OBJECT_ID:
+      /* Just ignore this - that's all DDE does */
+      break;
+
+    case DNTT_TYPE_MEMFUNC:
+      /* Member function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_DOC_MEMFUNC:
+      /* Member function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_TEMPLATE:
+      /* Template - sort of the header for a template definition,
+       * which like a class, points to a member list and also points
+       * to a TEMPLATE_ARG list of type-arguments.
+       * We do not need to process TEMPLATE records at this level though.
+       */
+      break;
+
+    case DNTT_TYPE_TEMPLATE_ARG:
+      /* The TEMPLATE record points to an argument list of
+       * TEMPLATE_ARG records, each of which describes one
+       * of the type-arguments.
+       * We do not need to process TEMPLATE_ARG records at this level though.
+       */
+      break;
+
+    case DNTT_TYPE_FUNC_TEMPLATE:
+      /* This will get emitted for member functions of templates.
+       * But we don't need to process this record at this level though,
+       * we will process it in the course of processing a TEMPLATE
+       * record.
+       */
+      break;
+
+    case DNTT_TYPE_LINK:
+      /* The LINK record is used to link up templates with instantiations. */
+      /* It is not clear why this is needed, and furthermore aCC does
+       * not appear to generate this, so I think we can safely ignore it. - RT
+       */
       break;
+
+      /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */
+      /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */
+      /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */
+      /* DNTT_TYPE_INLN is not handled by GDB */
+      /* DNTT_TYPE_INLN_LIST is not handled by GDB */
+      /* DNTT_TYPE_ALIAS is not handled by GDB */
+
     default:
       break;
     }
 }
+
+/* Get nesting depth for a DNTT entry.
+ * DN_BUFP points to a DNTT entry.
+ * OBJFILE is the object file.
+ * REPORT_NESTED is a flag; if 0, real nesting depth is
+ * reported, if it is 1, the function simply returns a 
+ * non-zero value if the nesting depth is anything > 0.
+ * 
+ * Return value is an integer.  0 => not a local type / name
+ * positive return => type or name is local to some 
+ * block or function.
+ */
+
+
+/* elz: ATTENTION: FIXME: NOTE: WARNING!!!!
+   this function now returns 0 right away. It was taking too much time
+   at start up. Now, though, the local types are not handled correctly.
+ */
+
+
+static int
+hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile,
+                       int report_nested)
+{
+  register int index;
+  register union dnttentry *dn_tmp;
+  register short depth = 0;
+/****************************/
+  return 0;
+/****************************/
+
+  index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
+
+  while (--index >= 0)
+    {
+      dn_tmp = hpread_get_lntt (index, objfile);
+      switch (dn_tmp->dblock.kind)
+       {
+       case DNTT_TYPE_MODULE:
+         return depth;
+       case DNTT_TYPE_END:
+         /* index is signed int; dnttp.index is 29-bit unsigned int! */
+         index = (int) dn_tmp->dend.beginscope.dnttp.index;
+         break;
+       case DNTT_TYPE_BEGIN:
+       case DNTT_TYPE_FUNCTION:
+       case DNTT_TYPE_DOC_FUNCTION:
+       case DNTT_TYPE_WITH:
+       case DNTT_TYPE_COMMON:
+       case DNTT_TYPE_CLASS_SCOPE:
+         depth++;
+         if (report_nested)
+           return 1;
+         break;
+       default:
+         break;
+       }
+    }
+  return depth;
+}
+
+/* Adjust the bitoffsets for all fields of an anonymous union of
+   type TYPE by negative BITS.  This handles HP aCC's hideous habit
+   of giving members of anonymous unions bit offsets relative to the
+   enclosing structure instead of relative to the union itself. */
+
+static void
+hpread_adjust_bitoffsets (struct type *type, int bits)
+{
+  register int i;
+
+  /* This is done only for unions; caller had better check that
+     it is an anonymous one. */
+  if (TYPE_CODE (type) != TYPE_CODE_UNION)
+    return;
+
+  /* Adjust each field; since this is a union, there are no base
+     classes. Also no static membes.  Also, no need for recursion as
+     the members of this union if themeselves structs or unions, have
+     the correct bitoffsets; if an anonymous union is a member of this
+     anonymous union, the code in hpread_read_struct_type() will
+     adjust for that. */
+
+  for (i = 0; i < TYPE_NFIELDS (type); i++)
+    TYPE_FIELD_BITPOS (type, i) -= bits;
+}
+
+/* Because of quirks in HP compilers' treatment of anonymous unions inside
+   classes, we have to chase through a chain of threaded FIELD entries.
+   If we encounter an anonymous union in the chain, we must recursively skip over
+   that too.
+
+   This function does a "next" in the chain of FIELD entries, but transparently
+   skips over anonymous unions' fields (recursively).
+
+   Inputs are the number of times to do "next" at the top level, the dnttpointer
+   (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it,
+   and the ubiquitous objfile parameter. (Note: FIELDP is a **.)  Return value
+   is a dnttpointer for the new field after all the skipped ones */
+
+static dnttpointer
+hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field,
+                                      union dnttentry **fieldp,
+                                      struct objfile *objfile)
+{
+  struct type *anon_type;
+  register int i;
+  int bitoffset;
+  char *name;
+
+  for (i = 0; i < skip_fields; i++)
+    {
+      /* Get type of item we're looking at now; recursively processes the types
+         of these intermediate items we skip over, so they aren't lost. */
+      anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
+      anon_type = CHECK_TYPEDEF (anon_type);
+      bitoffset = (*fieldp)->dfield.bitoffset;
+      name = VT (objfile) + (*fieldp)->dfield.name;
+      /* First skip over one item to avoid stack death on recursion */
+      field = (*fieldp)->dfield.nextfield;
+      *fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+      /* Do we have another anonymous union? If so, adjust the bitoffsets
+         of its members and skip over its members. */
+      if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
+         (!name || STREQ (name, "")))
+       {
+         hpread_adjust_bitoffsets (anon_type, bitoffset);
+         field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
+       }
+    }
+  return field;
+}
diff --git a/gdb/hpread.h b/gdb/hpread.h
deleted file mode 100644 (file)
index 85e6a30..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* hpread.h
- * Common include file for:
- *   hp_symtab_read.c
- *   hp_psymtab_read.c
- */
-
-/* Copyright 1993, 1996, 1998, 2000 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
-
-   Written by the Center for Software Science at the University of Utah
-   and by Cygnus Support.  */
-
-#include "defs.h"
-#include "bfd.h"
-#include "gdb_string.h"
-#include "hp-symtab.h"
-#include "syms.h"
-#include "symtab.h"
-#include "symfile.h"
-#include "objfiles.h"
-#include "buildsym.h"
-#include "complaints.h"
-#include "gdb-stabs.h"
-#include "gdbtypes.h"
-#include "demangle.h"
-
-/* Private information attached to an objfile which we use to find
-   and internalize the HP C debug symbols within that objfile.  */
-
-struct hpread_symfile_info
-  {
-    /* The contents of each of the debug sections (there are 4 of them).  */
-    char *gntt;
-    char *lntt;
-    char *slt;
-    char *vt;
-
-    /* We keep the size of the $VT$ section for range checking.  */
-    unsigned int vt_size;
-
-    /* Some routines still need to know the number of symbols in the
-       main debug sections ($LNTT$ and $GNTT$). */
-    unsigned int lntt_symcount;
-    unsigned int gntt_symcount;
-
-    /* To keep track of all the types we've processed.  */
-    struct type **type_vector;
-    int type_vector_length;
-
-    /* Keeps track of the beginning of a range of source lines.  */
-    sltpointer sl_index;
-
-    /* Some state variables we'll need.  */
-    int within_function;
-
-    /* Keep track of the current function's address.  We may need to look
-       up something based on this address.  */
-    unsigned int current_function_value;
-  };
-
-/* Accessor macros to get at the fields.  */
-#define HPUX_SYMFILE_INFO(o) \
-  ((struct hpread_symfile_info *)((o)->sym_private))
-#define GNTT(o)                 (HPUX_SYMFILE_INFO(o)->gntt)
-#define LNTT(o)                 (HPUX_SYMFILE_INFO(o)->lntt)
-#define SLT(o)                  (HPUX_SYMFILE_INFO(o)->slt)
-#define VT(o)                   (HPUX_SYMFILE_INFO(o)->vt)
-#define VT_SIZE(o)              (HPUX_SYMFILE_INFO(o)->vt_size)
-#define LNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->lntt_symcount)
-#define GNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->gntt_symcount)
-#define TYPE_VECTOR(o)          (HPUX_SYMFILE_INFO(o)->type_vector)
-#define TYPE_VECTOR_LENGTH(o)   (HPUX_SYMFILE_INFO(o)->type_vector_length)
-#define SL_INDEX(o)             (HPUX_SYMFILE_INFO(o)->sl_index)
-#define WITHIN_FUNCTION(o)      (HPUX_SYMFILE_INFO(o)->within_function)
-#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
-
-/* Given the native debug symbol SYM, set NAMEP to the name associated
-   with the debug symbol.  Note we may be called with a debug symbol which
-   has no associated name, in that case we return an empty string.
-
-   Also note we "know" that the name for any symbol is always in the
-   same place.  Hence we don't have to conditionalize on the symbol type.  */
-#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
-  if (! hpread_has_name ((SYM)->dblock.kind)) \
-    *NAMEP = ""; \
-  else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
-    { \
-      complain (&string_table_offset_complaint, (char *) symnum); \
-      *NAMEP = ""; \
-    } \
-  else \
-    *NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
-\f
-/* We put a pointer to this structure in the read_symtab_private field
-   of the psymtab.  */
-
-struct symloc
-  {
-    /* The offset within the file symbol table of first local symbol for
-       this file.  */
-
-    int ldsymoff;
-
-    /* Length (in bytes) of the section of the symbol table devoted to
-       this file's symbols (actually, the section bracketed may contain
-       more than just this file's symbols).  If ldsymlen is 0, the only
-       reason for this thing's existence is the dependency list.
-       Nothing else will happen when it is read in.  */
-
-    int ldsymlen;
-  };
-
-#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
-#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
-#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
-\f
-/* FIXME: Shouldn't this stuff be in a .h file somewhere?  */
-/* Complaints about the symbols we have encountered.  */
-extern struct complaint string_table_offset_complaint;
-extern struct complaint lbrac_unmatched_complaint;
-extern struct complaint lbrac_mismatch_complaint;
-
-extern union sltentry *hpread_get_slt (int, struct objfile *);
-
-extern union dnttentry *hpread_get_lntt (int, struct objfile *);
-
-int hpread_has_name (enum dntt_entry_type);
-
-/* end of hpread.h */