/* DWARF debugging format support for GDB.

   Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.

   Written by Fred Fish at Cygnus Support.  Portions based on dbxread.c,
   mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.

   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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/*
   If you are looking for DWARF-2 support, you are in the wrong file.
   Go look in dwarf2read.c.  This file is for the original DWARF,
   also known as DWARF-1.

   DWARF-1 is slowly headed for obsoletion.

   In gcc 3.4.0, support for dwarf-1 has been removed.

   In gcc 3.3.2, these targets prefer dwarf-1:

     i[34567]86-sequent-ptx4*
     i[34567]86-sequent-sysv4*
     mips-sni-sysv4
     sparc-hal-solaris2*

   In gcc 3.2.2, these targets prefer dwarf-1:

     i[34567]86-dg-dgux*
     i[34567]86-sequent-ptx4*
     i[34567]86-sequent-sysv4*
     m88k-dg-dgux*
     mips-sni-sysv4
     sparc-hal-solaris2*

   In gcc 2.95.3, these targets prefer dwarf-1:

     i[34567]86-dg-dgux*
     i[34567]86-ncr-sysv4*
     i[34567]86-sequent-ptx4*
     i[34567]86-sequent-sysv4*
     i[34567]86-*-osf1*
     i[34567]86-*-sco3.2v5*
     i[34567]86-*-sysv4*
     i860-alliant-*
     i860-*-sysv4*
     m68k-atari-sysv4*
     m68k-cbm-sysv4*
     m68k-*-sysv4*
     m88k-dg-dgux*
     m88k-*-sysv4*
     mips-sni-sysv4
     mips-*-gnu*
     sh-*-elf*
     sh-*-rtemself*
     sparc-hal-solaris2*
     sparc-*-sysv4*

   Some non-gcc compilers produce dwarf-1: 

     PR gdb/1179 was from a user with Diab C++ 4.3.
     On 2003-07-25 the gdb list received a report from a user
      with Diab Compiler 4.4b.
     Other users have also reported using Diab compilers with dwarf-1.

     Diab Compiler Suite 5.0.1 supports dwarf-2/dwarf-3 for C and C++.
     (Diab(tm) Compiler Suite 5.0.1 Release Notes, DOC-14691-ZD-00,
     Wind River Systems, 2002-07-31).

     On 2003-06-09 the gdb list received a report from a user
       with Absoft ProFortran f77 which is dwarf-1.

     Absoft ProFortran Linux[sic] Fortran User Guide (no version,
     but copyright dates are 1991-2001) says that Absoft ProFortran
     supports -gdwarf1 and -gdwarf2.

   -- chastain 2004-04-24
*/

/*

   FIXME: Do we need to generate dependencies in partial symtabs?
   (Perhaps we don't need to).

   FIXME: Resolve minor differences between what information we put in the
   partial symbol table and what dbxread puts in.  For example, we don't yet
   put enum constants there.  And dbxread seems to invent a lot of typedefs
   we never see.  Use the new printpsym command to see the partial symbol table
   contents.

   FIXME: Figure out a better way to tell gdb about the name of the function
   contain the user's entry point (I.E. main())

   FIXME: See other FIXME's and "ifdef 0" scattered throughout the code for
   other things to work on, if you get bored. :-)

 */

#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "elf/dwarf.h"
#include "buildsym.h"
#include "demangle.h"
#include "expression.h"		/* Needed for enum exp_opcode in language.h, sigh... */
#include "language.h"
#include "complaints.h"

#include <fcntl.h>
#include "gdb_string.h"

/* Some macros to provide DIE info for complaints. */

#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0)
#define DIE_NAME (curdie!=NULL && curdie->at_name!=NULL) ? curdie->at_name : ""

/* Complaints that can be issued during DWARF debug info reading. */

static void
bad_die_ref_complaint (int arg1, const char *arg2, int arg3)
{
  complaint (&symfile_complaints,
	     _("DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit"),
	     arg1, arg2, arg3);
}

static void
unknown_attribute_form_complaint (int arg1, const char *arg2, int arg3)
{
  complaint (&symfile_complaints,
	     _("DIE @ 0x%x \"%s\", unknown attribute form (0x%x)"), arg1, arg2,
	     arg3);
}

static void
dup_user_type_definition_complaint (int arg1, const char *arg2)
{
  complaint (&symfile_complaints,
	     _("DIE @ 0x%x \"%s\", internal error: duplicate user type definition"),
	     arg1, arg2);
}

static void
bad_array_element_type_complaint (int arg1, const char *arg2, int arg3)
{
  complaint (&symfile_complaints,
	     _("DIE @ 0x%x \"%s\", bad array element type attribute 0x%x"), arg1,
	     arg2, arg3);
}

typedef unsigned int DIE_REF;	/* Reference to a DIE */

#ifndef GCC_PRODUCER
#define GCC_PRODUCER "GNU C "
#endif

#ifndef GPLUS_PRODUCER
#define GPLUS_PRODUCER "GNU C++ "
#endif

#ifndef LCC_PRODUCER
#define LCC_PRODUCER "NCR C/C++"
#endif

/* Flags to target_to_host() that tell whether or not the data object is
   expected to be signed.  Used, for example, when fetching a signed
   integer in the target environment which is used as a signed integer
   in the host environment, and the two environments have different sized
   ints.  In this case, *somebody* has to sign extend the smaller sized
   int. */

#define GET_UNSIGNED	0	/* No sign extension required */
#define GET_SIGNED	1	/* Sign extension required */

/* Defines for things which are specified in the document "DWARF Debugging
   Information Format" published by UNIX International, Programming Languages
   SIG.  These defines are based on revision 1.0.0, Jan 20, 1992. */

#define SIZEOF_DIE_LENGTH	4
#define SIZEOF_DIE_TAG		2
#define SIZEOF_ATTRIBUTE	2
#define SIZEOF_FORMAT_SPECIFIER	1
#define SIZEOF_FMT_FT		2
#define SIZEOF_LINETBL_LENGTH	4
#define SIZEOF_LINETBL_LINENO	4
#define SIZEOF_LINETBL_STMT	2
#define SIZEOF_LINETBL_DELTA	4
#define SIZEOF_LOC_ATOM_CODE	1

#define FORM_FROM_ATTR(attr)	((attr) & 0xF)	/* Implicitly specified */

/* Macros that return the sizes of various types of data in the target
   environment.

   FIXME:  Currently these are just compile time constants (as they are in
   other parts of gdb as well).  They need to be able to get the right size
   either from the bfd or possibly from the DWARF info.  It would be nice if
   the DWARF producer inserted DIES that describe the fundamental types in
   the target environment into the DWARF info, similar to the way dbx stabs
   producers produce information about their fundamental types. */

#define TARGET_FT_POINTER_SIZE(objfile)	(TARGET_PTR_BIT / TARGET_CHAR_BIT)
#define TARGET_FT_LONG_SIZE(objfile)	(TARGET_LONG_BIT / TARGET_CHAR_BIT)

/* The Amiga SVR4 header file <dwarf.h> defines AT_element_list as a
   FORM_BLOCK2, and this is the value emitted by the AT&T compiler.
   However, the Issue 2 DWARF specification from AT&T defines it as
   a FORM_BLOCK4, as does the latest specification from UI/PLSIG.
   For backwards compatibility with the AT&T compiler produced executables
   we define AT_short_element_list for this variant. */

#define	AT_short_element_list	 (0x00f0|FORM_BLOCK2)

/* The DWARF debugging information consists of two major pieces,
   one is a block of DWARF Information Entries (DIE's) and the other
   is a line number table.  The "struct dieinfo" structure contains
   the information for a single DIE, the one currently being processed.

   In order to make it easier to randomly access the attribute fields
   of the current DIE, which are specifically unordered within the DIE,
   each DIE is scanned and an instance of the "struct dieinfo"
   structure is initialized.

   Initialization is done in two levels.  The first, done by basicdieinfo(),
   just initializes those fields that are vital to deciding whether or not
   to use this DIE, how to skip past it, etc.  The second, done by the
   function completedieinfo(), fills in the rest of the information.

   Attributes which have block forms are not interpreted at the time
   the DIE is scanned, instead we just save pointers to the start
   of their value fields.

   Some fields have a flag <name>_p that is set when the value of the
   field is valid (I.E. we found a matching attribute in the DIE).  Since
   we may want to test for the presence of some attributes in the DIE,
   such as AT_low_pc, without restricting the values of the field,
   we need someway to note that we found such an attribute.

 */

typedef char BLOCK;

struct dieinfo
  {
    char *die;			/* Pointer to the raw DIE data */
    unsigned long die_length;	/* Length of the raw DIE data */
    DIE_REF die_ref;		/* Offset of this DIE */
    unsigned short die_tag;	/* Tag for this DIE */
    unsigned long at_padding;
    unsigned long at_sibling;
    BLOCK *at_location;
    char *at_name;
    unsigned short at_fund_type;
    BLOCK *at_mod_fund_type;
    unsigned long at_user_def_type;
    BLOCK *at_mod_u_d_type;
    unsigned short at_ordering;
    BLOCK *at_subscr_data;
    unsigned long at_byte_size;
    unsigned short at_bit_offset;
    unsigned long at_bit_size;
    BLOCK *at_element_list;
    unsigned long at_stmt_list;
    CORE_ADDR at_low_pc;
    CORE_ADDR at_high_pc;
    unsigned long at_language;
    unsigned long at_member;
    unsigned long at_discr;
    BLOCK *at_discr_value;
    BLOCK *at_string_length;
    char *at_comp_dir;
    char *at_producer;
    unsigned long at_start_scope;
    unsigned long at_stride_size;
    unsigned long at_src_info;
    char *at_prototyped;
    unsigned int has_at_low_pc:1;
    unsigned int has_at_stmt_list:1;
    unsigned int has_at_byte_size:1;
    unsigned int short_element_list:1;

    /* Kludge to identify register variables */

    unsigned int isreg;

    /* Kludge to identify optimized out variables */

    unsigned int optimized_out;

    /* Kludge to identify basereg references.
       Nonzero if we have an offset relative to a basereg.  */

    unsigned int offreg;

    /* Kludge to identify which base register is it relative to.  */

    unsigned int basereg;
  };

static int diecount;		/* Approximate count of dies for compilation unit */
static struct dieinfo *curdie;	/* For warnings and such */

static char *dbbase;		/* Base pointer to dwarf info */
static int dbsize;		/* Size of dwarf info in bytes */
static int dbroff;		/* Relative offset from start of .debug section */
static char *lnbase;		/* Base pointer to line section */

/* This value is added to each symbol value.  FIXME:  Generalize to 
   the section_offsets structure used by dbxread (once this is done,
   pass the appropriate section number to end_symtab).  */
static CORE_ADDR baseaddr;	/* Add to each symbol value */

/* The section offsets used in the current psymtab or symtab.  FIXME,
   only used to pass one value (baseaddr) at the moment.  */
static struct section_offsets *base_section_offsets;

/* We put a pointer to this structure in the read_symtab_private field
   of the psymtab.  */

struct dwfinfo
  {
    /* Always the absolute file offset to the start of the ".debug"
       section for the file containing the DIE's being accessed.  */
    file_ptr dbfoff;
    /* Relative offset from the start of the ".debug" section to the
       first DIE to be accessed.  When building the partial symbol
       table, this value will be zero since we are accessing the
       entire ".debug" section.  When expanding a partial symbol
       table entry, this value will be the offset to the first
       DIE for the compilation unit containing the symbol that
       triggers the expansion.  */
    int dbroff;
    /* The size of the chunk of DIE's being examined, in bytes.  */
    int dblength;
    /* The absolute file offset to the line table fragment.  Ignored
       when building partial symbol tables, but used when expanding
       them, and contains the absolute file offset to the fragment
       of the ".line" section containing the line numbers for the
       current compilation unit.  */
    file_ptr lnfoff;
  };

#define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
#define DBROFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbroff)
#define DBLENGTH(p) (((struct dwfinfo *)((p)->read_symtab_private))->dblength)
#define LNFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->lnfoff)

/* The generic symbol table building routines have separate lists for
   file scope symbols and all all other scopes (local scopes).  So
   we need to select the right one to pass to add_symbol_to_list().
   We do it by keeping a pointer to the correct list in list_in_scope.

   FIXME:  The original dwarf code just treated the file scope as the first
   local scope, and all other local scopes as nested local scopes, and worked
   fine.  Check to see if we really need to distinguish these in buildsym.c */

struct pending **list_in_scope = &file_symbols;

/* DIES which have user defined types or modified user defined types refer to
   other DIES for the type information.  Thus we need to associate the offset
   of a DIE for a user defined type with a pointer to the type information.

   Originally this was done using a simple but expensive algorithm, with an
   array of unsorted structures, each containing an offset/type-pointer pair.
   This array was scanned linearly each time a lookup was done.  The result
   was that gdb was spending over half it's startup time munging through this
   array of pointers looking for a structure that had the right offset member.

   The second attempt used the same array of structures, but the array was
   sorted using qsort each time a new offset/type was recorded, and a binary
   search was used to find the type pointer for a given DIE offset.  This was
   even slower, due to the overhead of sorting the array each time a new
   offset/type pair was entered.

   The third attempt uses a fixed size array of type pointers, indexed by a
   value derived from the DIE offset.  Since the minimum DIE size is 4 bytes,
   we can divide any DIE offset by 4 to obtain a unique index into this fixed
   size array.  Since each element is a 4 byte pointer, it takes exactly as
   much memory to hold this array as to hold the DWARF info for a given
   compilation unit.  But it gets freed as soon as we are done with it.
   This has worked well in practice, as a reasonable tradeoff between memory
   consumption and speed, without having to resort to much more complicated
   algorithms. */

static struct type **utypes;	/* Pointer to array of user type pointers */
static int numutypes;		/* Max number of user type pointers */

/* Maintain an array of referenced fundamental types for the current
   compilation unit being read.  For DWARF version 1, we have to construct
   the fundamental types on the fly, since no information about the
   fundamental types is supplied.  Each such fundamental type is created by
   calling a language dependent routine to create the type, and then a
   pointer to that type is then placed in the array at the index specified
   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
   FT_NUM_MEMBERS compile time constant, which is the number of predefined
   fundamental types gdb knows how to construct. */

static struct type *ftypes[FT_NUM_MEMBERS];	/* Fundamental types */

/* Record the language for the compilation unit which is currently being
   processed.  We know it once we have seen the TAG_compile_unit DIE,
   and we need it while processing the DIE's for that compilation unit.
   It is eventually saved in the symtab structure, but we don't finalize
   the symtab struct until we have processed all the DIE's for the
   compilation unit.  We also need to get and save a pointer to the 
   language struct for this language, so we can call the language
   dependent routines for doing things such as creating fundamental
   types. */

static enum language cu_language;
static const struct language_defn *cu_language_defn;

/* Forward declarations of static functions so we don't have to worry
   about ordering within this file.  */

static void free_utypes (void *);

static int attribute_size (unsigned int);

static CORE_ADDR target_to_host (char *, int, int, struct objfile *);

static void add_enum_psymbol (struct dieinfo *, struct objfile *);

static void handle_producer (char *);

static void read_file_scope (struct dieinfo *, char *, char *,
			     struct objfile *);

static void read_func_scope (struct dieinfo *, char *, char *,
			     struct objfile *);

static void read_lexical_block_scope (struct dieinfo *, char *, char *,
				      struct objfile *);

static void scan_partial_symbols (char *, char *, struct objfile *);

static void scan_compilation_units (char *, char *, file_ptr, file_ptr,
				    struct objfile *);

static void add_partial_symbol (struct dieinfo *, struct objfile *);

static void basicdieinfo (struct dieinfo *, char *, struct objfile *);

static void completedieinfo (struct dieinfo *, struct objfile *);

static void dwarf_psymtab_to_symtab (struct partial_symtab *);

static void psymtab_to_symtab_1 (struct partial_symtab *);

static void read_ofile_symtab (struct partial_symtab *);

static void process_dies (char *, char *, struct objfile *);

static void read_structure_scope (struct dieinfo *, char *, char *,
				  struct objfile *);

static struct type *decode_array_element_type (char *);

static struct type *decode_subscript_data_item (char *, char *);

static void dwarf_read_array_type (struct dieinfo *);

static void read_tag_pointer_type (struct dieinfo *dip);

static void read_tag_string_type (struct dieinfo *dip);

static void read_subroutine_type (struct dieinfo *, char *, char *);

static void read_enumeration (struct dieinfo *, char *, char *,
			      struct objfile *);

static struct type *struct_type (struct dieinfo *, char *, char *,
				 struct objfile *);

static struct type *enum_type (struct dieinfo *, struct objfile *);

static void decode_line_numbers (char *);

static struct type *decode_die_type (struct dieinfo *);

static struct type *decode_mod_fund_type (char *);

static struct type *decode_mod_u_d_type (char *);

static struct type *decode_modified_type (char *, unsigned int, int);

static struct type *decode_fund_type (unsigned int);

static char *create_name (char *, struct obstack *);

static struct type *lookup_utype (DIE_REF);

static struct type *alloc_utype (DIE_REF, struct type *);

static struct symbol *new_symbol (struct dieinfo *, struct objfile *);

static void synthesize_typedef (struct dieinfo *, struct objfile *,
				struct type *);

static int locval (struct dieinfo *);

static void set_cu_language (struct dieinfo *);

static struct type *dwarf_fundamental_type (struct objfile *, int);


/*

   LOCAL FUNCTION

   dwarf_fundamental_type -- lookup or create a fundamental type

   SYNOPSIS

   struct type *
   dwarf_fundamental_type (struct objfile *objfile, int typeid)

   DESCRIPTION

   DWARF version 1 doesn't supply any fundamental type information,
   so gdb has to construct such types.  It has a fixed number of
   fundamental types that it knows how to construct, which is the
   union of all types that it knows how to construct for all languages
   that it knows about.  These are enumerated in gdbtypes.h.

   As an example, assume we find a DIE that references a DWARF
   fundamental type of FT_integer.  We first look in the ftypes
   array to see if we already have such a type, indexed by the
   gdb internal value of FT_INTEGER.  If so, we simply return a
   pointer to that type.  If not, then we ask an appropriate
   language dependent routine to create a type FT_INTEGER, using
   defaults reasonable for the current target machine, and install
   that type in ftypes for future reference.

   RETURNS

   Pointer to a fundamental type.

 */

static struct type *
dwarf_fundamental_type (struct objfile *objfile, int typeid)
{
  if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
    {
      error (_("internal error - invalid fundamental type id %d"), typeid);
    }

  /* Look for this particular type in the fundamental type vector.  If one is
     not found, create and install one appropriate for the current language
     and the current target machine. */

  if (ftypes[typeid] == NULL)
    {
      ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
    }

  return (ftypes[typeid]);
}

/*

   LOCAL FUNCTION

   set_cu_language -- set local copy of language for compilation unit

   SYNOPSIS

   void
   set_cu_language (struct dieinfo *dip)

   DESCRIPTION

   Decode the language attribute for a compilation unit DIE and
   remember what the language was.  We use this at various times
   when processing DIE's for a given compilation unit.

   RETURNS

   No return value.

 */

static void
set_cu_language (struct dieinfo *dip)
{
  switch (dip->at_language)
    {
    case LANG_C89:
    case LANG_C:
      cu_language = language_c;
      break;
    case LANG_C_PLUS_PLUS:
      cu_language = language_cplus;
      break;
    case LANG_MODULA2:
      cu_language = language_m2;
      break;
    case LANG_FORTRAN77:
    case LANG_FORTRAN90:
      cu_language = language_fortran;
      break;
    case LANG_ADA83:
    case LANG_COBOL74:
    case LANG_COBOL85:
    case LANG_PASCAL83:
      /* We don't know anything special about these yet. */
      cu_language = language_unknown;
      break;
    default:
      /* If no at_language, try to deduce one from the filename */
      cu_language = deduce_language_from_filename (dip->at_name);
      break;
    }
  cu_language_defn = language_def (cu_language);
}

/*

   GLOBAL FUNCTION

   dwarf_build_psymtabs -- build partial symtabs from DWARF debug info

   SYNOPSIS

   void dwarf_build_psymtabs (struct objfile *objfile,
   int mainline, file_ptr dbfoff, unsigned int dbfsize,
   file_ptr lnoffset, unsigned int lnsize)

   DESCRIPTION

   This function is called upon to build partial symtabs from files
   containing DIE's (Dwarf Information Entries) and DWARF line numbers.

   It is passed a bfd* containing the DIES
   and line number information, the corresponding filename for that
   file, a base address for relocating the symbols, a flag indicating
   whether or not this debugging information is from a "main symbol
   table" rather than a shared library or dynamically linked file,
   and file offset/size pairs for the DIE information and line number
   information.

   RETURNS

   No return value.

 */

void
dwarf_build_psymtabs (struct objfile *objfile, int mainline, file_ptr dbfoff,
		      unsigned int dbfsize, file_ptr lnoffset,
		      unsigned int lnsize)
{
  bfd *abfd = objfile->obfd;
  struct cleanup *back_to;

  current_objfile = objfile;
  dbsize = dbfsize;
  dbbase = xmalloc (dbsize);
  dbroff = 0;
  if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) ||
      (bfd_bread (dbbase, dbsize, abfd) != dbsize))
    {
      xfree (dbbase);
      error (_("can't read DWARF data from '%s'"), bfd_get_filename (abfd));
    }
  back_to = make_cleanup (xfree, dbbase);

  /* If we are reinitializing, or if we have never loaded syms yet, init.
     Since we have no idea how many DIES we are looking at, we just guess
     some arbitrary value. */

  if (mainline
      || (objfile->global_psymbols.size == 0
	  && objfile->static_psymbols.size == 0))
    {
      init_psymbol_list (objfile, 1024);
    }

  /* Save the relocation factor where everybody can see it.  */

  base_section_offsets = objfile->section_offsets;
  baseaddr = ANOFFSET (objfile->section_offsets, 0);

  /* Follow the compilation unit sibling chain, building a partial symbol
     table entry for each one.  Save enough information about each compilation
     unit to locate the full DWARF information later. */

  scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile);

  do_cleanups (back_to);
  current_objfile = NULL;
}

/*

   LOCAL FUNCTION

   read_lexical_block_scope -- process all dies in a lexical block

   SYNOPSIS

   static void read_lexical_block_scope (struct dieinfo *dip,
   char *thisdie, char *enddie)

   DESCRIPTION

   Process all the DIES contained within a lexical block scope.
   Start a new scope, process the dies, and then close the scope.

 */

static void
read_lexical_block_scope (struct dieinfo *dip, char *thisdie, char *enddie,
			  struct objfile *objfile)
{
  struct context_stack *new;

  push_context (0, dip->at_low_pc);
  process_dies (thisdie + dip->die_length, enddie, objfile);
  new = pop_context ();
  if (local_symbols != NULL)
    {
      finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
		    dip->at_high_pc, objfile);
    }
  local_symbols = new->locals;
}

/*

   LOCAL FUNCTION

   lookup_utype -- look up a user defined type from die reference

   SYNOPSIS

   static type *lookup_utype (DIE_REF die_ref)

   DESCRIPTION

   Given a DIE reference, lookup the user defined type associated with
   that DIE, if it has been registered already.  If not registered, then
   return NULL.  Alloc_utype() can be called to register an empty
   type for this reference, which will be filled in later when the
   actual referenced DIE is processed.
 */

static struct type *
lookup_utype (DIE_REF die_ref)
{
  struct type *type = NULL;
  int utypeidx;

  utypeidx = (die_ref - dbroff) / 4;
  if ((utypeidx < 0) || (utypeidx >= numutypes))
    {
      bad_die_ref_complaint (DIE_ID, DIE_NAME, die_ref);
    }
  else
    {
      type = *(utypes + utypeidx);
    }
  return (type);
}


/*

   LOCAL FUNCTION

   alloc_utype  -- add a user defined type for die reference

   SYNOPSIS

   static type *alloc_utype (DIE_REF die_ref, struct type *utypep)

   DESCRIPTION

   Given a die reference DIE_REF, and a possible pointer to a user
   defined type UTYPEP, register that this reference has a user
   defined type and either use the specified type in UTYPEP or
   make a new empty type that will be filled in later.

   We should only be called after calling lookup_utype() to verify that
   there is not currently a type registered for DIE_REF.
 */

static struct type *
alloc_utype (DIE_REF die_ref, struct type *utypep)
{
  struct type **typep;
  int utypeidx;

  utypeidx = (die_ref - dbroff) / 4;
  typep = utypes + utypeidx;
  if ((utypeidx < 0) || (utypeidx >= numutypes))
    {
      utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
      bad_die_ref_complaint (DIE_ID, DIE_NAME, die_ref);
    }
  else if (*typep != NULL)
    {
      utypep = *typep;
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", internal error: duplicate user type allocation"),
		 DIE_ID, DIE_NAME);
    }
  else
    {
      if (utypep == NULL)
	{
	  utypep = alloc_type (current_objfile);
	}
      *typep = utypep;
    }
  return (utypep);
}

/*

   LOCAL FUNCTION

   free_utypes -- free the utypes array and reset pointer & count

   SYNOPSIS

   static void free_utypes (void *dummy)

   DESCRIPTION

   Called via do_cleanups to free the utypes array, reset the pointer to NULL,
   and set numutypes back to zero.  This ensures that the utypes does not get
   referenced after being freed.
 */

static void
free_utypes (void *dummy)
{
  xfree (utypes);
  utypes = NULL;
  numutypes = 0;
}


/*

   LOCAL FUNCTION

   decode_die_type -- return a type for a specified die

   SYNOPSIS

   static struct type *decode_die_type (struct dieinfo *dip)

   DESCRIPTION

   Given a pointer to a die information structure DIP, decode the
   type of the die and return a pointer to the decoded type.  All
   dies without specific types default to type int.
 */

static struct type *
decode_die_type (struct dieinfo *dip)
{
  struct type *type = NULL;

  if (dip->at_fund_type != 0)
    {
      type = decode_fund_type (dip->at_fund_type);
    }
  else if (dip->at_mod_fund_type != NULL)
    {
      type = decode_mod_fund_type (dip->at_mod_fund_type);
    }
  else if (dip->at_user_def_type)
    {
      type = lookup_utype (dip->at_user_def_type);
      if (type == NULL)
	{
	  type = alloc_utype (dip->at_user_def_type, NULL);
	}
    }
  else if (dip->at_mod_u_d_type)
    {
      type = decode_mod_u_d_type (dip->at_mod_u_d_type);
    }
  else
    {
      type = dwarf_fundamental_type (current_objfile, FT_VOID);
    }
  return (type);
}

/*

   LOCAL FUNCTION

   struct_type -- compute and return the type for a struct or union

   SYNOPSIS

   static struct type *struct_type (struct dieinfo *dip, char *thisdie,
   char *enddie, struct objfile *objfile)

   DESCRIPTION

   Given pointer to a die information structure for a die which
   defines a union or structure (and MUST define one or the other),
   and pointers to the raw die data that define the range of dies which
   define the members, compute and return the user defined type for the
   structure or union.
 */

static struct type *
struct_type (struct dieinfo *dip, char *thisdie, char *enddie,
	     struct objfile *objfile)
{
  struct type *type;
  struct nextfield
    {
      struct nextfield *next;
      struct field field;
    };
  struct nextfield *list = NULL;
  struct nextfield *new;
  int nfields = 0;
  int n;
  struct dieinfo mbr;
  char *nextdie;
  int anonymous_size;

  type = lookup_utype (dip->die_ref);
  if (type == NULL)
    {
      /* No forward references created an empty type, so install one now */
      type = alloc_utype (dip->die_ref, NULL);
    }
  INIT_CPLUS_SPECIFIC (type);
  switch (dip->die_tag)
    {
    case TAG_class_type:
      TYPE_CODE (type) = TYPE_CODE_CLASS;
      break;
    case TAG_structure_type:
      TYPE_CODE (type) = TYPE_CODE_STRUCT;
      break;
    case TAG_union_type:
      TYPE_CODE (type) = TYPE_CODE_UNION;
      break;
    default:
      /* Should never happen */
      TYPE_CODE (type) = TYPE_CODE_UNDEF;
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", missing class, structure, or union tag"),
		 DIE_ID, DIE_NAME);
      break;
    }
  /* Some compilers try to be helpful by inventing "fake" names for
     anonymous enums, structures, and unions, like "~0fake" or ".0fake".
     Thanks, but no thanks... */
  if (dip->at_name != NULL
      && *dip->at_name != '~'
      && *dip->at_name != '.')
    {
      TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
				       "", "", dip->at_name);
    }
  /* Use whatever size is known.  Zero is a valid size.  We might however
     wish to check has_at_byte_size to make sure that some byte size was
     given explicitly, but DWARF doesn't specify that explicit sizes of
     zero have to present, so complaining about missing sizes should 
     probably not be the default. */
  TYPE_LENGTH (type) = dip->at_byte_size;
  thisdie += dip->die_length;
  while (thisdie < enddie)
    {
      basicdieinfo (&mbr, thisdie, objfile);
      completedieinfo (&mbr, objfile);
      if (mbr.die_length <= SIZEOF_DIE_LENGTH)
	{
	  break;
	}
      else if (mbr.at_sibling != 0)
	{
	  nextdie = dbbase + mbr.at_sibling - dbroff;
	}
      else
	{
	  nextdie = thisdie + mbr.die_length;
	}
      switch (mbr.die_tag)
	{
	case TAG_member:
	  /* Static fields can be either TAG_global_variable (GCC) or else
	     TAG_member with no location (Diab).  We could treat the latter like
	     the former... but since we don't support the former, just avoid
	     crashing on the latter for now.  */
	  if (mbr.at_location == NULL)
	    break;

	  /* Get space to record the next field's data.  */
	  new = (struct nextfield *) alloca (sizeof (struct nextfield));
	  new->next = list;
	  list = new;
	  /* Save the data.  */
	  list->field.name =
	    obsavestring (mbr.at_name, strlen (mbr.at_name),
			  &objfile->objfile_obstack);
	  FIELD_TYPE (list->field) = decode_die_type (&mbr);
	  FIELD_BITPOS (list->field) = 8 * locval (&mbr);
	  FIELD_STATIC_KIND (list->field) = 0;
	  /* Handle bit fields. */
	  FIELD_BITSIZE (list->field) = mbr.at_bit_size;
	  if (BITS_BIG_ENDIAN)
	    {
	      /* For big endian bits, the at_bit_offset gives the
	         additional bit offset from the MSB of the containing
	         anonymous object to the MSB of the field.  We don't
	         have to do anything special since we don't need to
	         know the size of the anonymous object. */
	      FIELD_BITPOS (list->field) += mbr.at_bit_offset;
	    }
	  else
	    {
	      /* For little endian bits, we need to have a non-zero
	         at_bit_size, so that we know we are in fact dealing
	         with a bitfield.  Compute the bit offset to the MSB
	         of the anonymous object, subtract off the number of
	         bits from the MSB of the field to the MSB of the
	         object, and then subtract off the number of bits of
	         the field itself.  The result is the bit offset of
	         the LSB of the field. */
	      if (mbr.at_bit_size > 0)
		{
		  if (mbr.has_at_byte_size)
		    {
		      /* The size of the anonymous object containing
		         the bit field is explicit, so use the
		         indicated size (in bytes). */
		      anonymous_size = mbr.at_byte_size;
		    }
		  else
		    {
		      /* The size of the anonymous object containing
		         the bit field matches the size of an object
		         of the bit field's type.  DWARF allows
		         at_byte_size to be left out in such cases, as
		         a debug information size optimization. */
		      anonymous_size = TYPE_LENGTH (list->field.type);
		    }
		  FIELD_BITPOS (list->field) +=
		    anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;
		}
	    }
	  nfields++;
	  break;
	default:
	  process_dies (thisdie, nextdie, objfile);
	  break;
	}
      thisdie = nextdie;
    }
  /* Now create the vector of fields, and record how big it is.  We may
     not even have any fields, if this DIE was generated due to a reference
     to an anonymous structure or union.  In this case, TYPE_FLAG_STUB is
     set, which clues gdb in to the fact that it needs to search elsewhere
     for the full structure definition. */
  if (nfields == 0)
    {
      TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
    }
  else
    {
      TYPE_NFIELDS (type) = nfields;
      TYPE_FIELDS (type) = (struct field *)
	TYPE_ALLOC (type, sizeof (struct field) * nfields);
      /* Copy the saved-up fields into the field vector.  */
      for (n = nfields; list; list = list->next)
	{
	  TYPE_FIELD (type, --n) = list->field;
	}
    }
  return (type);
}

/*

   LOCAL FUNCTION

   read_structure_scope -- process all dies within struct or union

   SYNOPSIS

   static void read_structure_scope (struct dieinfo *dip,
   char *thisdie, char *enddie, struct objfile *objfile)

   DESCRIPTION

   Called when we find the DIE that starts a structure or union
   scope (definition) to process all dies that define the members
   of the structure or union.  DIP is a pointer to the die info
   struct for the DIE that names the structure or union.

   NOTES

   Note that we need to call struct_type regardless of whether or not
   the DIE has an at_name attribute, since it might be an anonymous
   structure or union.  This gets the type entered into our set of
   user defined types.

   However, if the structure is incomplete (an opaque struct/union)
   then suppress creating a symbol table entry for it since gdb only
   wants to find the one with the complete definition.  Note that if
   it is complete, we just call new_symbol, which does it's own
   checking about whether the struct/union is anonymous or not (and
   suppresses creating a symbol table entry itself).

 */

static void
read_structure_scope (struct dieinfo *dip, char *thisdie, char *enddie,
		      struct objfile *objfile)
{
  struct type *type;
  struct symbol *sym;

  type = struct_type (dip, thisdie, enddie, objfile);
  if (!TYPE_STUB (type))
    {
      sym = new_symbol (dip, objfile);
      if (sym != NULL)
	{
	  SYMBOL_TYPE (sym) = type;
	  if (cu_language == language_cplus)
	    {
	      synthesize_typedef (dip, objfile, type);
	    }
	}
    }
}

/*

   LOCAL FUNCTION

   decode_array_element_type -- decode type of the array elements

   SYNOPSIS

   static struct type *decode_array_element_type (char *scan, char *end)

   DESCRIPTION

   As the last step in decoding the array subscript information for an
   array DIE, we need to decode the type of the array elements.  We are
   passed a pointer to this last part of the subscript information and
   must return the appropriate type.  If the type attribute is not
   recognized, just warn about the problem and return type int.
 */

static struct type *
decode_array_element_type (char *scan)
{
  struct type *typep;
  DIE_REF die_ref;
  unsigned short attribute;
  unsigned short fundtype;
  int nbytes;

  attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED,
			      current_objfile);
  scan += SIZEOF_ATTRIBUTE;
  nbytes = attribute_size (attribute);
  if (nbytes == -1)
    {
      bad_array_element_type_complaint (DIE_ID, DIE_NAME, attribute);
      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
    }
  else
    {
      switch (attribute)
	{
	case AT_fund_type:
	  fundtype = target_to_host (scan, nbytes, GET_UNSIGNED,
				     current_objfile);
	  typep = decode_fund_type (fundtype);
	  break;
	case AT_mod_fund_type:
	  typep = decode_mod_fund_type (scan);
	  break;
	case AT_user_def_type:
	  die_ref = target_to_host (scan, nbytes, GET_UNSIGNED,
				    current_objfile);
	  typep = lookup_utype (die_ref);
	  if (typep == NULL)
	    {
	      typep = alloc_utype (die_ref, NULL);
	    }
	  break;
	case AT_mod_u_d_type:
	  typep = decode_mod_u_d_type (scan);
	  break;
	default:
	  bad_array_element_type_complaint (DIE_ID, DIE_NAME, attribute);
	  typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
	  break;
	}
    }
  return (typep);
}

/*

   LOCAL FUNCTION

   decode_subscript_data_item -- decode array subscript item

   SYNOPSIS

   static struct type *
   decode_subscript_data_item (char *scan, char *end)

   DESCRIPTION

   The array subscripts and the data type of the elements of an
   array are described by a list of data items, stored as a block
   of contiguous bytes.  There is a data item describing each array
   dimension, and a final data item describing the element type.
   The data items are ordered the same as their appearance in the
   source (I.E. leftmost dimension first, next to leftmost second,
   etc).

   The data items describing each array dimension consist of four
   parts: (1) a format specifier, (2) type type of the subscript
   index, (3) a description of the low bound of the array dimension,
   and (4) a description of the high bound of the array dimension.

   The last data item is the description of the type of each of
   the array elements.

   We are passed a pointer to the start of the block of bytes
   containing the remaining data items, and a pointer to the first
   byte past the data.  This function recursively decodes the
   remaining data items and returns a type.

   If we somehow fail to decode some data, we complain about it
   and return a type "array of int".

   BUGS
   FIXME:  This code only implements the forms currently used
   by the AT&T and GNU C compilers.

   The end pointer is supplied for error checking, maybe we should
   use it for that...
 */

static struct type *
decode_subscript_data_item (char *scan, char *end)
{
  struct type *typep = NULL;	/* Array type we are building */
  struct type *nexttype;	/* Type of each element (may be array) */
  struct type *indextype;	/* Type of this index */
  struct type *rangetype;
  unsigned int format;
  unsigned short fundtype;
  unsigned long lowbound;
  unsigned long highbound;
  int nbytes;

  format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED,
			   current_objfile);
  scan += SIZEOF_FORMAT_SPECIFIER;
  switch (format)
    {
    case FMT_ET:
      typep = decode_array_element_type (scan);
      break;
    case FMT_FT_C_C:
      fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED,
				 current_objfile);
      indextype = decode_fund_type (fundtype);
      scan += SIZEOF_FMT_FT;
      nbytes = TARGET_FT_LONG_SIZE (current_objfile);
      lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
      scan += nbytes;
      highbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
      scan += nbytes;
      nexttype = decode_subscript_data_item (scan, end);
      if (nexttype == NULL)
	{
	  /* Munged subscript data or other problem, fake it. */
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", can't decode subscript data items"),
		     DIE_ID, DIE_NAME);
	  nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
	}
      rangetype = create_range_type ((struct type *) NULL, indextype,
				     lowbound, highbound);
      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
      break;
    case FMT_FT_C_X:
    case FMT_FT_X_C:
    case FMT_FT_X_X:
    case FMT_UT_C_C:
    case FMT_UT_C_X:
    case FMT_UT_X_C:
    case FMT_UT_X_X:
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet"),
		 DIE_ID, DIE_NAME, format);
      nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
      rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
      break;
    default:
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", unknown array subscript format %x"), DIE_ID,
		 DIE_NAME, format);
      nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
      rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
      break;
    }
  return (typep);
}

/*

   LOCAL FUNCTION

   dwarf_read_array_type -- read TAG_array_type DIE

   SYNOPSIS

   static void dwarf_read_array_type (struct dieinfo *dip)

   DESCRIPTION

   Extract all information from a TAG_array_type DIE and add to
   the user defined type vector.
 */

static void
dwarf_read_array_type (struct dieinfo *dip)
{
  struct type *type;
  struct type *utype;
  char *sub;
  char *subend;
  unsigned short blocksz;
  int nbytes;

  if (dip->at_ordering != ORD_row_major)
    {
      /* FIXME:  Can gdb even handle column major arrays? */
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", array not row major; not handled correctly"),
		 DIE_ID, DIE_NAME);
    }
  sub = dip->at_subscr_data;
  if (sub != NULL)
    {
      nbytes = attribute_size (AT_subscr_data);
      blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile);
      subend = sub + nbytes + blocksz;
      sub += nbytes;
      type = decode_subscript_data_item (sub, subend);
      utype = lookup_utype (dip->die_ref);
      if (utype == NULL)
	{
	  /* Install user defined type that has not been referenced yet. */
	  alloc_utype (dip->die_ref, type);
	}
      else if (TYPE_CODE (utype) == TYPE_CODE_UNDEF)
	{
	  /* Ick!  A forward ref has already generated a blank type in our
	     slot, and this type probably already has things pointing to it
	     (which is what caused it to be created in the first place).
	     If it's just a place holder we can plop our fully defined type
	     on top of it.  We can't recover the space allocated for our
	     new type since it might be on an obstack, but we could reuse
	     it if we kept a list of them, but it might not be worth it
	     (FIXME). */
	  *utype = *type;
	}
      else
	{
	  /* Double ick!  Not only is a type already in our slot, but
	     someone has decorated it.  Complain and leave it alone. */
	  dup_user_type_definition_complaint (DIE_ID, DIE_NAME);
	}
    }
}

/*

   LOCAL FUNCTION

   read_tag_pointer_type -- read TAG_pointer_type DIE

   SYNOPSIS

   static void read_tag_pointer_type (struct dieinfo *dip)

   DESCRIPTION

   Extract all information from a TAG_pointer_type DIE and add to
   the user defined type vector.
 */

static void
read_tag_pointer_type (struct dieinfo *dip)
{
  struct type *type;
  struct type *utype;

  type = decode_die_type (dip);
  utype = lookup_utype (dip->die_ref);
  if (utype == NULL)
    {
      utype = lookup_pointer_type (type);
      alloc_utype (dip->die_ref, utype);
    }
  else
    {
      TYPE_TARGET_TYPE (utype) = type;
      TYPE_POINTER_TYPE (type) = utype;

      /* We assume the machine has only one representation for pointers!  */
      /* FIXME:  Possably a poor assumption  */
      TYPE_LENGTH (utype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
      TYPE_CODE (utype) = TYPE_CODE_PTR;
    }
}

/*

   LOCAL FUNCTION

   read_tag_string_type -- read TAG_string_type DIE

   SYNOPSIS

   static void read_tag_string_type (struct dieinfo *dip)

   DESCRIPTION

   Extract all information from a TAG_string_type DIE and add to
   the user defined type vector.  It isn't really a user defined
   type, but it behaves like one, with other DIE's using an
   AT_user_def_type attribute to reference it.
 */

static void
read_tag_string_type (struct dieinfo *dip)
{
  struct type *utype;
  struct type *indextype;
  struct type *rangetype;
  unsigned long lowbound = 0;
  unsigned long highbound;

  if (dip->has_at_byte_size)
    {
      /* A fixed bounds string */
      highbound = dip->at_byte_size - 1;
    }
  else
    {
      /* A varying length string.  Stub for now.  (FIXME) */
      highbound = 1;
    }
  indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
  rangetype = create_range_type ((struct type *) NULL, indextype, lowbound,
				 highbound);

  utype = lookup_utype (dip->die_ref);
  if (utype == NULL)
    {
      /* No type defined, go ahead and create a blank one to use. */
      utype = alloc_utype (dip->die_ref, (struct type *) NULL);
    }
  else
    {
      /* Already a type in our slot due to a forward reference. Make sure it
         is a blank one.  If not, complain and leave it alone. */
      if (TYPE_CODE (utype) != TYPE_CODE_UNDEF)
	{
	  dup_user_type_definition_complaint (DIE_ID, DIE_NAME);
	  return;
	}
    }

  /* Create the string type using the blank type we either found or created. */
  utype = create_string_type (utype, rangetype);
}

/*

   LOCAL FUNCTION

   read_subroutine_type -- process TAG_subroutine_type dies

   SYNOPSIS

   static void read_subroutine_type (struct dieinfo *dip, char thisdie,
   char *enddie)

   DESCRIPTION

   Handle DIES due to C code like:

   struct foo {
   int (*funcp)(int a, long l);  (Generates TAG_subroutine_type DIE)
   int b;
   };

   NOTES

   The parameter DIES are currently ignored.  See if gdb has a way to
   include this info in it's type system, and decode them if so.  Is
   this what the type structure's "arg_types" field is for?  (FIXME)
 */

static void
read_subroutine_type (struct dieinfo *dip, char *thisdie, char *enddie)
{
  struct type *type;		/* Type that this function returns */
  struct type *ftype;		/* Function that returns above type */

  /* Decode the type that this subroutine returns */

  type = decode_die_type (dip);

  /* Check to see if we already have a partially constructed user
     defined type for this DIE, from a forward reference. */

  ftype = lookup_utype (dip->die_ref);
  if (ftype == NULL)
    {
      /* This is the first reference to one of these types.  Make
         a new one and place it in the user defined types. */
      ftype = lookup_function_type (type);
      alloc_utype (dip->die_ref, ftype);
    }
  else if (TYPE_CODE (ftype) == TYPE_CODE_UNDEF)
    {
      /* We have an existing partially constructed type, so bash it
         into the correct type. */
      TYPE_TARGET_TYPE (ftype) = type;
      TYPE_LENGTH (ftype) = 1;
      TYPE_CODE (ftype) = TYPE_CODE_FUNC;
    }
  else
    {
      dup_user_type_definition_complaint (DIE_ID, DIE_NAME);
    }
}

/*

   LOCAL FUNCTION

   read_enumeration -- process dies which define an enumeration

   SYNOPSIS

   static void read_enumeration (struct dieinfo *dip, char *thisdie,
   char *enddie, struct objfile *objfile)

   DESCRIPTION

   Given a pointer to a die which begins an enumeration, process all
   the dies that define the members of the enumeration.

   NOTES

   Note that we need to call enum_type regardless of whether or not we
   have a symbol, since we might have an enum without a tag name (thus
   no symbol for the tagname).
 */

static void
read_enumeration (struct dieinfo *dip, char *thisdie, char *enddie,
		  struct objfile *objfile)
{
  struct type *type;
  struct symbol *sym;

  type = enum_type (dip, objfile);
  sym = new_symbol (dip, objfile);
  if (sym != NULL)
    {
      SYMBOL_TYPE (sym) = type;
      if (cu_language == language_cplus)
	{
	  synthesize_typedef (dip, objfile, type);
	}
    }
}

/*

   LOCAL FUNCTION

   enum_type -- decode and return a type for an enumeration

   SYNOPSIS

   static type *enum_type (struct dieinfo *dip, struct objfile *objfile)

   DESCRIPTION

   Given a pointer to a die information structure for the die which
   starts an enumeration, process all the dies that define the members
   of the enumeration and return a type pointer for the enumeration.

   At the same time, for each member of the enumeration, create a
   symbol for it with domain VAR_DOMAIN and class LOC_CONST,
   and give it the type of the enumeration itself.

   NOTES

   Note that the DWARF specification explicitly mandates that enum
   constants occur in reverse order from the source program order,
   for "consistency" and because this ordering is easier for many
   compilers to generate. (Draft 6, sec 3.8.5, Enumeration type
   Entries).  Because gdb wants to see the enum members in program
   source order, we have to ensure that the order gets reversed while
   we are processing them.
 */

static struct type *
enum_type (struct dieinfo *dip, struct objfile *objfile)
{
  struct type *type;
  struct nextfield
    {
      struct nextfield *next;
      struct field field;
    };
  struct nextfield *list = NULL;
  struct nextfield *new;
  int nfields = 0;
  int n;
  char *scan;
  char *listend;
  unsigned short blocksz;
  struct symbol *sym;
  int nbytes;
  int unsigned_enum = 1;

  type = lookup_utype (dip->die_ref);
  if (type == NULL)
    {
      /* No forward references created an empty type, so install one now */
      type = alloc_utype (dip->die_ref, NULL);
    }
  TYPE_CODE (type) = TYPE_CODE_ENUM;
  /* Some compilers try to be helpful by inventing "fake" names for
     anonymous enums, structures, and unions, like "~0fake" or ".0fake".
     Thanks, but no thanks... */
  if (dip->at_name != NULL
      && *dip->at_name != '~'
      && *dip->at_name != '.')
    {
      TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
				       "", "", dip->at_name);
    }
  if (dip->at_byte_size != 0)
    {
      TYPE_LENGTH (type) = dip->at_byte_size;
    }
  scan = dip->at_element_list;
  if (scan != NULL)
    {
      if (dip->short_element_list)
	{
	  nbytes = attribute_size (AT_short_element_list);
	}
      else
	{
	  nbytes = attribute_size (AT_element_list);
	}
      blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
      listend = scan + nbytes + blocksz;
      scan += nbytes;
      while (scan < listend)
	{
	  new = (struct nextfield *) alloca (sizeof (struct nextfield));
	  new->next = list;
	  list = new;
	  FIELD_TYPE (list->field) = NULL;
	  FIELD_BITSIZE (list->field) = 0;
	  FIELD_STATIC_KIND (list->field) = 0;
	  FIELD_BITPOS (list->field) =
	    target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
			    objfile);
	  scan += TARGET_FT_LONG_SIZE (objfile);
	  list->field.name = obsavestring (scan, strlen (scan),
					   &objfile->objfile_obstack);
	  scan += strlen (scan) + 1;
	  nfields++;
	  /* Handcraft a new symbol for this enum member. */
	  sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
						 sizeof (struct symbol));
	  memset (sym, 0, sizeof (struct symbol));
	  DEPRECATED_SYMBOL_NAME (sym) = create_name (list->field.name,
					   &objfile->objfile_obstack);
	  SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
	  SYMBOL_CLASS (sym) = LOC_CONST;
	  SYMBOL_TYPE (sym) = type;
	  SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field);
	  if (SYMBOL_VALUE (sym) < 0)
	    unsigned_enum = 0;
	  add_symbol_to_list (sym, list_in_scope);
	}
      /* Now create the vector of fields, and record how big it is. This is
         where we reverse the order, by pulling the members off the list in
         reverse order from how they were inserted.  If we have no fields
         (this is apparently possible in C++) then skip building a field
         vector. */
      if (nfields > 0)
	{
	  if (unsigned_enum)
	    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
	  TYPE_NFIELDS (type) = nfields;
	  TYPE_FIELDS (type) = (struct field *)
	    obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nfields);
	  /* Copy the saved-up fields into the field vector.  */
	  for (n = 0; (n < nfields) && (list != NULL); list = list->next)
	    {
	      TYPE_FIELD (type, n++) = list->field;
	    }
	}
    }
  return (type);
}

/*

   LOCAL FUNCTION

   read_func_scope -- process all dies within a function scope

   DESCRIPTION

   Process all dies within a given function scope.  We are passed
   a die information structure pointer DIP for the die which
   starts the function scope, and pointers into the raw die data
   that define the dies within the function scope.

   For now, we ignore lexical block scopes within the function.
   The problem is that AT&T cc does not define a DWARF lexical
   block scope for the function itself, while gcc defines a
   lexical block scope for the function.  We need to think about
   how to handle this difference, or if it is even a problem.
   (FIXME)
 */

static void
read_func_scope (struct dieinfo *dip, char *thisdie, char *enddie,
		 struct objfile *objfile)
{
  struct context_stack *new;

  /* AT_name is absent if the function is described with an
     AT_abstract_origin tag.
     Ignore the function description for now to avoid GDB core dumps.
     FIXME: Add code to handle AT_abstract_origin tags properly.  */
  if (dip->at_name == NULL)
    {
      complaint (&symfile_complaints, _("DIE @ 0x%x, AT_name tag missing"),
		 DIE_ID);
      return;
    }

  new = push_context (0, dip->at_low_pc);
  new->name = new_symbol (dip, objfile);
  list_in_scope = &local_symbols;
  process_dies (thisdie + dip->die_length, enddie, objfile);
  new = pop_context ();
  /* Make a block for the local symbols within.  */
  finish_block (new->name, &local_symbols, new->old_blocks,
		new->start_addr, dip->at_high_pc, objfile);
  list_in_scope = &file_symbols;
}


/*

   LOCAL FUNCTION

   handle_producer -- process the AT_producer attribute

   DESCRIPTION

   Perform any operations that depend on finding a particular
   AT_producer attribute.

 */

static void
handle_producer (char *producer)
{

  /* If this compilation unit was compiled with g++ or gcc, then set the
     processing_gcc_compilation flag. */

  if (DEPRECATED_STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
    {
      char version = producer[strlen (GCC_PRODUCER)];
      processing_gcc_compilation = (version == '2' ? 2 : 1);
    }
  else
    {
      processing_gcc_compilation =
	strncmp (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) == 0;
    }

  /* Select a demangling style if we can identify the producer and if
     the current style is auto.  We leave the current style alone if it
     is not auto.  We also leave the demangling style alone if we find a
     gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */

  if (AUTO_DEMANGLING)
    {
      if (DEPRECATED_STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))
	{
#if 0
	  /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
	     know whether it will use the old style or v3 mangling.  */
	  set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
#endif
	}
      else if (DEPRECATED_STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))
	{
	  set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);
	}
    }
}


/*

   LOCAL FUNCTION

   read_file_scope -- process all dies within a file scope

   DESCRIPTION

   Process all dies within a given file scope.  We are passed a
   pointer to the die information structure for the die which
   starts the file scope, and pointers into the raw die data which
   mark the range of dies within the file scope.

   When the partial symbol table is built, the file offset for the line
   number table for each compilation unit is saved in the partial symbol
   table entry for that compilation unit.  As the symbols for each
   compilation unit are read, the line number table is read into memory
   and the variable lnbase is set to point to it.  Thus all we have to
   do is use lnbase to access the line number table for the current
   compilation unit.
 */

static void
read_file_scope (struct dieinfo *dip, char *thisdie, char *enddie,
		 struct objfile *objfile)
{
  struct cleanup *back_to;
  struct symtab *symtab;

  set_cu_language (dip);
  if (dip->at_producer != NULL)
    {
      handle_producer (dip->at_producer);
    }
  numutypes = (enddie - thisdie) / 4;
  utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
  back_to = make_cleanup (free_utypes, NULL);
  memset (utypes, 0, numutypes * sizeof (struct type *));
  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
  start_symtab (dip->at_name, dip->at_comp_dir, dip->at_low_pc);
  record_debugformat ("DWARF 1");
  decode_line_numbers (lnbase);
  process_dies (thisdie + dip->die_length, enddie, objfile);

  symtab = end_symtab (dip->at_high_pc, objfile, 0);
  if (symtab != NULL)
    {
      symtab->language = cu_language;
    }
  do_cleanups (back_to);
}

/*

   LOCAL FUNCTION

   process_dies -- process a range of DWARF Information Entries

   SYNOPSIS

   static void process_dies (char *thisdie, char *enddie,
   struct objfile *objfile)

   DESCRIPTION

   Process all DIE's in a specified range.  May be (and almost
   certainly will be) called recursively.
 */

static void
process_dies (char *thisdie, char *enddie, struct objfile *objfile)
{
  char *nextdie;
  struct dieinfo di;

  while (thisdie < enddie)
    {
      basicdieinfo (&di, thisdie, objfile);
      if (di.die_length < SIZEOF_DIE_LENGTH)
	{
	  break;
	}
      else if (di.die_tag == TAG_padding)
	{
	  nextdie = thisdie + di.die_length;
	}
      else
	{
	  completedieinfo (&di, objfile);
	  if (di.at_sibling != 0)
	    {
	      nextdie = dbbase + di.at_sibling - dbroff;
	    }
	  else
	    {
	      nextdie = thisdie + di.die_length;
	    }
	  /* I think that these are always text, not data, addresses.  */
	  di.at_low_pc = SMASH_TEXT_ADDRESS (di.at_low_pc);
	  di.at_high_pc = SMASH_TEXT_ADDRESS (di.at_high_pc);
	  switch (di.die_tag)
	    {
	    case TAG_compile_unit:
	      /* Skip Tag_compile_unit if we are already inside a compilation
	         unit, we are unable to handle nested compilation units
	         properly (FIXME).  */
	      if (current_subfile == NULL)
		read_file_scope (&di, thisdie, nextdie, objfile);
	      else
		nextdie = thisdie + di.die_length;
	      break;
	    case TAG_global_subroutine:
	    case TAG_subroutine:
	      if (di.has_at_low_pc)
		{
		  read_func_scope (&di, thisdie, nextdie, objfile);
		}
	      break;
	    case TAG_lexical_block:
	      read_lexical_block_scope (&di, thisdie, nextdie, objfile);
	      break;
	    case TAG_class_type:
	    case TAG_structure_type:
	    case TAG_union_type:
	      read_structure_scope (&di, thisdie, nextdie, objfile);
	      break;
	    case TAG_enumeration_type:
	      read_enumeration (&di, thisdie, nextdie, objfile);
	      break;
	    case TAG_subroutine_type:
	      read_subroutine_type (&di, thisdie, nextdie);
	      break;
	    case TAG_array_type:
	      dwarf_read_array_type (&di);
	      break;
	    case TAG_pointer_type:
	      read_tag_pointer_type (&di);
	      break;
	    case TAG_string_type:
	      read_tag_string_type (&di);
	      break;
	    default:
	      new_symbol (&di, objfile);
	      break;
	    }
	}
      thisdie = nextdie;
    }
}

/*

   LOCAL FUNCTION

   decode_line_numbers -- decode a line number table fragment

   SYNOPSIS

   static void decode_line_numbers (char *tblscan, char *tblend,
   long length, long base, long line, long pc)

   DESCRIPTION

   Translate the DWARF line number information to gdb form.

   The ".line" section contains one or more line number tables, one for
   each ".line" section from the objects that were linked.

   The AT_stmt_list attribute for each TAG_source_file entry in the
   ".debug" section contains the offset into the ".line" section for the
   start of the table for that file.

   The table itself has the following structure:

   <table length><base address><source statement entry>
   4 bytes       4 bytes       10 bytes

   The table length is the total size of the table, including the 4 bytes
   for the length information.

   The base address is the address of the first instruction generated
   for the source file.

   Each source statement entry has the following structure:

   <line number><statement position><address delta>
   4 bytes      2 bytes             4 bytes

   The line number is relative to the start of the file, starting with
   line 1.

   The statement position either -1 (0xFFFF) or the number of characters
   from the beginning of the line to the beginning of the statement.

   The address delta is the difference between the base address and
   the address of the first instruction for the statement.

   Note that we must copy the bytes from the packed table to our local
   variables before attempting to use them, to avoid alignment problems
   on some machines, particularly RISC processors.

   BUGS

   Does gdb expect the line numbers to be sorted?  They are now by
   chance/luck, but are not required to be.  (FIXME)

   The line with number 0 is unused, gdb apparently can discover the
   span of the last line some other way. How?  (FIXME)
 */

static void
decode_line_numbers (char *linetable)
{
  char *tblscan;
  char *tblend;
  unsigned long length;
  unsigned long base;
  unsigned long line;
  unsigned long pc;

  if (linetable != NULL)
    {
      tblscan = tblend = linetable;
      length = target_to_host (tblscan, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED,
			       current_objfile);
      tblscan += SIZEOF_LINETBL_LENGTH;
      tblend += length;
      base = target_to_host (tblscan, TARGET_FT_POINTER_SIZE (objfile),
			     GET_UNSIGNED, current_objfile);
      tblscan += TARGET_FT_POINTER_SIZE (objfile);
      base += baseaddr;
      while (tblscan < tblend)
	{
	  line = target_to_host (tblscan, SIZEOF_LINETBL_LINENO, GET_UNSIGNED,
				 current_objfile);
	  tblscan += SIZEOF_LINETBL_LINENO + SIZEOF_LINETBL_STMT;
	  pc = target_to_host (tblscan, SIZEOF_LINETBL_DELTA, GET_UNSIGNED,
			       current_objfile);
	  tblscan += SIZEOF_LINETBL_DELTA;
	  pc += base;
	  if (line != 0)
	    {
	      record_line (current_subfile, line, pc);
	    }
	}
    }
}

/*

   LOCAL FUNCTION

   locval -- compute the value of a location attribute

   SYNOPSIS

   static int locval (struct dieinfo *dip)

   DESCRIPTION

   Given pointer to a string of bytes that define a location, compute
   the location and return the value.
   A location description containing no atoms indicates that the
   object is optimized out. The optimized_out flag is set for those,
   the return value is meaningless.

   When computing values involving the current value of the frame pointer,
   the value zero is used, which results in a value relative to the frame
   pointer, rather than the absolute value.  This is what GDB wants
   anyway.

   When the result is a register number, the isreg flag is set, otherwise
   it is cleared.  This is a kludge until we figure out a better
   way to handle the problem.  Gdb's design does not mesh well with the
   DWARF notion of a location computing interpreter, which is a shame
   because the flexibility goes unused.

   NOTES

   Note that stack[0] is unused except as a default error return.
   Note that stack overflow is not yet handled.
 */

static int
locval (struct dieinfo *dip)
{
  unsigned short nbytes;
  unsigned short locsize;
  auto long stack[64];
  int stacki;
  char *loc;
  char *end;
  int loc_atom_code;
  int loc_value_size;

  loc = dip->at_location;
  nbytes = attribute_size (AT_location);
  locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile);
  loc += nbytes;
  end = loc + locsize;
  stacki = 0;
  stack[stacki] = 0;
  dip->isreg = 0;
  dip->offreg = 0;
  dip->optimized_out = 1;
  loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
  while (loc < end)
    {
      dip->optimized_out = 0;
      loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
				      current_objfile);
      loc += SIZEOF_LOC_ATOM_CODE;
      switch (loc_atom_code)
	{
	case 0:
	  /* error */
	  loc = end;
	  break;
	case OP_REG:
	  /* push register (number) */
	  stack[++stacki]
	    = DWARF_REG_TO_REGNUM (target_to_host (loc, loc_value_size,
						   GET_UNSIGNED,
						   current_objfile));
	  loc += loc_value_size;
	  dip->isreg = 1;
	  break;
	case OP_BASEREG:
	  /* push value of register (number) */
	  /* Actually, we compute the value as if register has 0, so the
	     value ends up being the offset from that register.  */
	  dip->offreg = 1;
	  dip->basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
					 current_objfile);
	  loc += loc_value_size;
	  stack[++stacki] = 0;
	  break;
	case OP_ADDR:
	  /* push address (relocated address) */
	  stack[++stacki] = target_to_host (loc, loc_value_size,
					    GET_UNSIGNED, current_objfile);
	  loc += loc_value_size;
	  break;
	case OP_CONST:
	  /* push constant (number)   FIXME: signed or unsigned! */
	  stack[++stacki] = target_to_host (loc, loc_value_size,
					    GET_SIGNED, current_objfile);
	  loc += loc_value_size;
	  break;
	case OP_DEREF2:
	  /* pop, deref and push 2 bytes (as a long) */
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%lx not handled"),
		     DIE_ID, DIE_NAME, stack[stacki]);
	  break;
	case OP_DEREF4:	/* pop, deref and push 4 bytes (as a long) */
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%lx not handled"),
		     DIE_ID, DIE_NAME, stack[stacki]);
	  break;
	case OP_ADD:		/* pop top 2 items, add, push result */
	  stack[stacki - 1] += stack[stacki];
	  stacki--;
	  break;
	}
    }
  return (stack[stacki]);
}

/*

   LOCAL FUNCTION

   read_ofile_symtab -- build a full symtab entry from chunk of DIE's

   SYNOPSIS

   static void read_ofile_symtab (struct partial_symtab *pst)

   DESCRIPTION

   When expanding a partial symbol table entry to a full symbol table
   entry, this is the function that gets called to read in the symbols
   for the compilation unit.  A pointer to the newly constructed symtab,
   which is now the new first one on the objfile's symtab list, is
   stashed in the partial symbol table entry.
 */

static void
read_ofile_symtab (struct partial_symtab *pst)
{
  struct cleanup *back_to;
  unsigned long lnsize;
  file_ptr foffset;
  bfd *abfd;
  char lnsizedata[SIZEOF_LINETBL_LENGTH];

  abfd = pst->objfile->obfd;
  current_objfile = pst->objfile;

  /* Allocate a buffer for the entire chunk of DIE's for this compilation
     unit, seek to the location in the file, and read in all the DIE's. */

  diecount = 0;
  dbsize = DBLENGTH (pst);
  dbbase = xmalloc (dbsize);
  dbroff = DBROFF (pst);
  foffset = DBFOFF (pst) + dbroff;
  base_section_offsets = pst->section_offsets;
  baseaddr = ANOFFSET (pst->section_offsets, 0);
  if (bfd_seek (abfd, foffset, SEEK_SET) ||
      (bfd_bread (dbbase, dbsize, abfd) != dbsize))
    {
      xfree (dbbase);
      error (_("can't read DWARF data"));
    }
  back_to = make_cleanup (xfree, dbbase);

  /* If there is a line number table associated with this compilation unit
     then read the size of this fragment in bytes, from the fragment itself.
     Allocate a buffer for the fragment and read it in for future 
     processing. */

  lnbase = NULL;
  if (LNFOFF (pst))
    {
      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
	  (bfd_bread (lnsizedata, sizeof (lnsizedata), abfd)
	   != sizeof (lnsizedata)))
	{
	  error (_("can't read DWARF line number table size"));
	}
      lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
			       GET_UNSIGNED, pst->objfile);
      lnbase = xmalloc (lnsize);
      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
	  (bfd_bread (lnbase, lnsize, abfd) != lnsize))
	{
	  xfree (lnbase);
	  error (_("can't read DWARF line numbers"));
	}
      make_cleanup (xfree, lnbase);
    }

  process_dies (dbbase, dbbase + dbsize, pst->objfile);
  do_cleanups (back_to);
  current_objfile = NULL;
  pst->symtab = pst->objfile->symtabs;
}

/*

   LOCAL FUNCTION

   psymtab_to_symtab_1 -- do grunt work for building a full symtab entry

   SYNOPSIS

   static void psymtab_to_symtab_1 (struct partial_symtab *pst)

   DESCRIPTION

   Called once for each partial symbol table entry that needs to be
   expanded into a full symbol table entry.

 */

static void
psymtab_to_symtab_1 (struct partial_symtab *pst)
{
  int i;
  struct cleanup *old_chain;

  if (pst != NULL)
    {
      if (pst->readin)
	{
	  warning (_("psymtab for %s already read in.  Shouldn't happen."),
		   pst->filename);
	}
      else
	{
	  /* 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)
		    {
		      /* FIXME: i18n: Need to make this a single
			 string.  */
		      fputs_filtered (" ", gdb_stdout);
		      wrap_here ("");
		      fputs_filtered ("and ", gdb_stdout);
		      wrap_here ("");
		      printf_filtered ("%s...",
				       pst->dependencies[i]->filename);
		      wrap_here ("");
		      gdb_flush (gdb_stdout);	/* Flush output */
		    }
		  psymtab_to_symtab_1 (pst->dependencies[i]);
		}
	    }
	  if (DBLENGTH (pst))	/* Otherwise it's a dummy */
	    {
	      buildsym_init ();
	      old_chain = make_cleanup (really_free_pendings, 0);
	      read_ofile_symtab (pst);
	      if (info_verbose)
		{
		  printf_filtered (_("%d DIE's, sorting..."), diecount);
		  wrap_here ("");
		  gdb_flush (gdb_stdout);
		}
	      do_cleanups (old_chain);
	    }
	  pst->readin = 1;
	}
    }
}

/*

   LOCAL FUNCTION

   dwarf_psymtab_to_symtab -- build a full symtab entry from partial one

   SYNOPSIS

   static void dwarf_psymtab_to_symtab (struct partial_symtab *pst)

   DESCRIPTION

   This is the DWARF support entry point for building a full symbol
   table entry from a partial symbol table entry.  We are passed a
   pointer to the partial symbol table entry that needs to be expanded.

 */

static void
dwarf_psymtab_to_symtab (struct partial_symtab *pst)
{

  if (pst != NULL)
    {
      if (pst->readin)
	{
	  warning (_("psymtab for %s already read in.  Shouldn't happen."),
		   pst->filename);
	}
      else
	{
	  if (DBLENGTH (pst) || pst->number_of_dependencies)
	    {
	      /* Print the message now, before starting serious work, to avoid
	         disconcerting pauses.  */
	      if (info_verbose)
		{
		  printf_filtered (_("Reading in symbols for %s..."),
				   pst->filename);
		  gdb_flush (gdb_stdout);
		}

	      psymtab_to_symtab_1 (pst);

#if 0				/* FIXME:  Check to see what dbxread is doing here and see if
				   we need to do an equivalent or is this something peculiar to
				   stabs/a.out format.
				   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);
#endif

	      /* Finish up the verbose info message.  */
	      if (info_verbose)
		{
		  printf_filtered (_("done.\n"));
		  gdb_flush (gdb_stdout);
		}
	    }
	}
    }
}

/*

   LOCAL FUNCTION

   add_enum_psymbol -- add enumeration members to partial symbol table

   DESCRIPTION

   Given pointer to a DIE that is known to be for an enumeration,
   extract the symbolic names of the enumeration members and add
   partial symbols for them.
 */

static void
add_enum_psymbol (struct dieinfo *dip, struct objfile *objfile)
{
  char *scan;
  char *listend;
  unsigned short blocksz;
  int nbytes;

  scan = dip->at_element_list;
  if (scan != NULL)
    {
      if (dip->short_element_list)
	{
	  nbytes = attribute_size (AT_short_element_list);
	}
      else
	{
	  nbytes = attribute_size (AT_element_list);
	}
      blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
      scan += nbytes;
      listend = scan + blocksz;
      while (scan < listend)
	{
	  scan += TARGET_FT_LONG_SIZE (objfile);
	  add_psymbol_to_list (scan, strlen (scan), VAR_DOMAIN, LOC_CONST,
			       &objfile->static_psymbols, 0, 0, cu_language,
			       objfile);
	  scan += strlen (scan) + 1;
	}
    }
}

/*

   LOCAL FUNCTION

   add_partial_symbol -- add symbol to partial symbol table

   DESCRIPTION

   Given a DIE, if it is one of the types that we want to
   add to a partial symbol table, finish filling in the die info
   and then add a partial symbol table entry for it.

   NOTES

   The caller must ensure that the DIE has a valid name attribute.
 */

static void
add_partial_symbol (struct dieinfo *dip, struct objfile *objfile)
{
  switch (dip->die_tag)
    {
    case TAG_global_subroutine:
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   VAR_DOMAIN, LOC_BLOCK,
			   &objfile->global_psymbols,
			   0, dip->at_low_pc, cu_language, objfile);
      break;
    case TAG_global_variable:
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   VAR_DOMAIN, LOC_STATIC,
			   &objfile->global_psymbols,
			   0, 0, cu_language, objfile);
      break;
    case TAG_subroutine:
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   VAR_DOMAIN, LOC_BLOCK,
			   &objfile->static_psymbols,
			   0, dip->at_low_pc, cu_language, objfile);
      break;
    case TAG_local_variable:
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   VAR_DOMAIN, LOC_STATIC,
			   &objfile->static_psymbols,
			   0, 0, cu_language, objfile);
      break;
    case TAG_typedef:
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   VAR_DOMAIN, LOC_TYPEDEF,
			   &objfile->static_psymbols,
			   0, 0, cu_language, objfile);
      break;
    case TAG_class_type:
    case TAG_structure_type:
    case TAG_union_type:
    case TAG_enumeration_type:
      /* Do not add opaque aggregate definitions to the psymtab.  */
      if (!dip->has_at_byte_size)
	break;
      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			   STRUCT_DOMAIN, LOC_TYPEDEF,
			   &objfile->static_psymbols,
			   0, 0, cu_language, objfile);
      if (cu_language == language_cplus)
	{
	  /* For C++, these implicitly act as typedefs as well. */
	  add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
			       VAR_DOMAIN, LOC_TYPEDEF,
			       &objfile->static_psymbols,
			       0, 0, cu_language, objfile);
	}
      break;
    }
}
/* *INDENT-OFF* */
/*

LOCAL FUNCTION

	scan_partial_symbols -- scan DIE's within a single compilation unit

DESCRIPTION

	Process the DIE's within a single compilation unit, looking for
	interesting DIE's that contribute to the partial symbol table entry
	for this compilation unit.

NOTES

	There are some DIE's that may appear both at file scope and within
	the scope of a function.  We are only interested in the ones at file
	scope, and the only way to tell them apart is to keep track of the
	scope.  For example, consider the test case:

		static int i;
		main () { int j; }

	for which the relevant DWARF segment has the structure:
	
		0x51:
		0x23   global subrtn   sibling     0x9b
		                       name        main
		                       fund_type   FT_integer
		                       low_pc      0x800004cc
		                       high_pc     0x800004d4
		                            
		0x74:
		0x23   local var       sibling     0x97
		                       name        j
		                       fund_type   FT_integer
		                       location    OP_BASEREG 0xe
		                                   OP_CONST 0xfffffffc
		                                   OP_ADD
		0x97:
		0x4         
		
		0x9b:
		0x1d   local var       sibling     0xb8
		                       name        i
		                       fund_type   FT_integer
		                       location    OP_ADDR 0x800025dc
		                            
		0xb8:
		0x4         

	We want to include the symbol 'i' in the partial symbol table, but
	not the symbol 'j'.  In essence, we want to skip all the dies within
	the scope of a TAG_global_subroutine DIE.

	Don't attempt to add anonymous structures or unions since they have
	no name.  Anonymous enumerations however are processed, because we
	want to extract their member names (the check for a tag name is
	done later).

	Also, for variables and subroutines, check that this is the place
	where the actual definition occurs, rather than just a reference
	to an external.
 */
/* *INDENT-ON* */



static void
scan_partial_symbols (char *thisdie, char *enddie, struct objfile *objfile)
{
  char *nextdie;
  char *temp;
  struct dieinfo di;

  while (thisdie < enddie)
    {
      basicdieinfo (&di, thisdie, objfile);
      if (di.die_length < SIZEOF_DIE_LENGTH)
	{
	  break;
	}
      else
	{
	  nextdie = thisdie + di.die_length;
	  /* To avoid getting complete die information for every die, we
	     only do it (below) for the cases we are interested in. */
	  switch (di.die_tag)
	    {
	    case TAG_global_subroutine:
	    case TAG_subroutine:
	      completedieinfo (&di, objfile);
	      if (di.at_name && (di.has_at_low_pc || di.at_location))
		{
		  add_partial_symbol (&di, objfile);
		  /* If there is a sibling attribute, adjust the nextdie
		     pointer to skip the entire scope of the subroutine.
		     Apply some sanity checking to make sure we don't 
		     overrun or underrun the range of remaining DIE's */
		  if (di.at_sibling != 0)
		    {
		      temp = dbbase + di.at_sibling - dbroff;
		      if ((temp < thisdie) || (temp >= enddie))
			{
			  bad_die_ref_complaint (DIE_ID, DIE_NAME,
						 di.at_sibling);
			}
		      else
			{
			  nextdie = temp;
			}
		    }
		}
	      break;
	    case TAG_global_variable:
	    case TAG_local_variable:
	      completedieinfo (&di, objfile);
	      if (di.at_name && (di.has_at_low_pc || di.at_location))
		{
		  add_partial_symbol (&di, objfile);
		}
	      break;
	    case TAG_typedef:
	    case TAG_class_type:
	    case TAG_structure_type:
	    case TAG_union_type:
	      completedieinfo (&di, objfile);
	      if (di.at_name)
		{
		  add_partial_symbol (&di, objfile);
		}
	      break;
	    case TAG_enumeration_type:
	      completedieinfo (&di, objfile);
	      if (di.at_name)
		{
		  add_partial_symbol (&di, objfile);
		}
	      add_enum_psymbol (&di, objfile);
	      break;
	    }
	}
      thisdie = nextdie;
    }
}

/*

   LOCAL FUNCTION

   scan_compilation_units -- build a psymtab entry for each compilation

   DESCRIPTION

   This is the top level dwarf parsing routine for building partial
   symbol tables.

   It scans from the beginning of the DWARF table looking for the first
   TAG_compile_unit DIE, and then follows the sibling chain to locate
   each additional TAG_compile_unit DIE.

   For each TAG_compile_unit DIE it creates a partial symtab structure,
   calls a subordinate routine to collect all the compilation unit's
   global DIE's, file scope DIEs, typedef DIEs, etc, and then links the
   new partial symtab structure into the partial symbol table.  It also
   records the appropriate information in the partial symbol table entry
   to allow the chunk of DIE's and line number table for this compilation
   unit to be located and re-read later, to generate a complete symbol
   table entry for the compilation unit.

   Thus it effectively partitions up a chunk of DIE's for multiple
   compilation units into smaller DIE chunks and line number tables,
   and associates them with a partial symbol table entry.

   NOTES

   If any compilation unit has no line number table associated with
   it for some reason (a missing at_stmt_list attribute, rather than
   just one with a value of zero, which is valid) then we ensure that
   the recorded file offset is zero so that the routine which later
   reads line number table fragments knows that there is no fragment
   to read.

   RETURNS

   Returns no value.

 */

static void
scan_compilation_units (char *thisdie, char *enddie, file_ptr dbfoff,
			file_ptr lnoffset, struct objfile *objfile)
{
  char *nextdie;
  struct dieinfo di;
  struct partial_symtab *pst;
  int culength;
  int curoff;
  file_ptr curlnoffset;

  while (thisdie < enddie)
    {
      basicdieinfo (&di, thisdie, objfile);
      if (di.die_length < SIZEOF_DIE_LENGTH)
	{
	  break;
	}
      else if (di.die_tag != TAG_compile_unit)
	{
	  nextdie = thisdie + di.die_length;
	}
      else
	{
	  completedieinfo (&di, objfile);
	  set_cu_language (&di);
	  if (di.at_sibling != 0)
	    {
	      nextdie = dbbase + di.at_sibling - dbroff;
	    }
	  else
	    {
	      nextdie = thisdie + di.die_length;
	    }
	  curoff = thisdie - dbbase;
	  culength = nextdie - thisdie;
	  curlnoffset = di.has_at_stmt_list ? lnoffset + di.at_stmt_list : 0;

	  /* First allocate a new partial symbol table structure */

	  pst = start_psymtab_common (objfile, base_section_offsets,
				      di.at_name, di.at_low_pc,
				      objfile->global_psymbols.next,
				      objfile->static_psymbols.next);

	  pst->texthigh = di.at_high_pc;
	  pst->read_symtab_private = (char *)
	    obstack_alloc (&objfile->objfile_obstack,
			   sizeof (struct dwfinfo));
	  DBFOFF (pst) = dbfoff;
	  DBROFF (pst) = curoff;
	  DBLENGTH (pst) = culength;
	  LNFOFF (pst) = curlnoffset;
	  pst->read_symtab = dwarf_psymtab_to_symtab;

	  /* Now look for partial symbols */

	  scan_partial_symbols (thisdie + di.die_length, nextdie, objfile);

	  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);
	  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);
	}
      thisdie = nextdie;
    }
}

/*

   LOCAL FUNCTION

   new_symbol -- make a symbol table entry for a new symbol

   SYNOPSIS

   static struct symbol *new_symbol (struct dieinfo *dip,
   struct objfile *objfile)

   DESCRIPTION

   Given a pointer to a DWARF information entry, figure out if we need
   to make a symbol table entry for it, and if so, create a new entry
   and return a pointer to it.
 */

static struct symbol *
new_symbol (struct dieinfo *dip, struct objfile *objfile)
{
  struct symbol *sym = NULL;

  if (dip->at_name != NULL)
    {
      sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
					     sizeof (struct symbol));
      OBJSTAT (objfile, n_syms++);
      memset (sym, 0, sizeof (struct symbol));
      /* default assumptions */
      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
      SYMBOL_CLASS (sym) = LOC_STATIC;
      SYMBOL_TYPE (sym) = decode_die_type (dip);

      /* If this symbol is from a C++ compilation, then attempt to cache the
         demangled form for future reference.  This is a typical time versus
         space tradeoff, that was decided in favor of time because it sped up
         C++ symbol lookups by a factor of about 20. */

      SYMBOL_LANGUAGE (sym) = cu_language;
      SYMBOL_SET_NAMES (sym, dip->at_name, strlen (dip->at_name), objfile);
      switch (dip->die_tag)
	{
	case TAG_label:
	  SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
	  SYMBOL_CLASS (sym) = LOC_LABEL;
	  break;
	case TAG_global_subroutine:
	case TAG_subroutine:
	  SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
	  SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
	  if (dip->at_prototyped)
	    TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
	  SYMBOL_CLASS (sym) = LOC_BLOCK;
	  if (dip->die_tag == TAG_global_subroutine)
	    {
	      add_symbol_to_list (sym, &global_symbols);
	    }
	  else
	    {
	      add_symbol_to_list (sym, list_in_scope);
	    }
	  break;
	case TAG_global_variable:
	  if (dip->at_location != NULL)
	    {
	      SYMBOL_VALUE_ADDRESS (sym) = locval (dip);
	      add_symbol_to_list (sym, &global_symbols);
	      SYMBOL_CLASS (sym) = LOC_STATIC;
	      SYMBOL_VALUE (sym) += baseaddr;
	    }
	  break;
	case TAG_local_variable:
	  if (dip->at_location != NULL)
	    {
	      int loc = locval (dip);
	      if (dip->optimized_out)
		{
		  SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
		}
	      else if (dip->isreg)
		{
		  SYMBOL_CLASS (sym) = LOC_REGISTER;
		}
	      else if (dip->offreg)
		{
		  SYMBOL_CLASS (sym) = LOC_BASEREG;
		  SYMBOL_BASEREG (sym) = dip->basereg;
		}
	      else
		{
		  SYMBOL_CLASS (sym) = LOC_STATIC;
		  SYMBOL_VALUE (sym) += baseaddr;
		}
	      if (SYMBOL_CLASS (sym) == LOC_STATIC)
		{
		  /* LOC_STATIC address class MUST use SYMBOL_VALUE_ADDRESS,
		     which may store to a bigger location than SYMBOL_VALUE. */
		  SYMBOL_VALUE_ADDRESS (sym) = loc;
		}
	      else
		{
		  SYMBOL_VALUE (sym) = loc;
		}
	      add_symbol_to_list (sym, list_in_scope);
	    }
	  break;
	case TAG_formal_parameter:
	  if (dip->at_location != NULL)
	    {
	      SYMBOL_VALUE (sym) = locval (dip);
	    }
	  add_symbol_to_list (sym, list_in_scope);
	  if (dip->isreg)
	    {
	      SYMBOL_CLASS (sym) = LOC_REGPARM;
	    }
	  else if (dip->offreg)
	    {
	      SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
	      SYMBOL_BASEREG (sym) = dip->basereg;
	    }
	  else
	    {
	      SYMBOL_CLASS (sym) = LOC_ARG;
	    }
	  break;
	case TAG_unspecified_parameters:
	  /* From varargs functions; gdb doesn't seem to have any interest in
	     this information, so just ignore it for now. (FIXME?) */
	  break;
	case TAG_class_type:
	case TAG_structure_type:
	case TAG_union_type:
	case TAG_enumeration_type:
	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
	  add_symbol_to_list (sym, list_in_scope);
	  break;
	case TAG_typedef:
	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
	  add_symbol_to_list (sym, list_in_scope);
	  break;
	default:
	  /* Not a tag we recognize.  Hopefully we aren't processing trash
	     data, but since we must specifically ignore things we don't
	     recognize, there is nothing else we should do at this point. */
	  break;
	}
    }
  return (sym);
}

/*

   LOCAL FUNCTION

   synthesize_typedef -- make a symbol table entry for a "fake" typedef

   SYNOPSIS

   static void synthesize_typedef (struct dieinfo *dip,
   struct objfile *objfile,
   struct type *type);

   DESCRIPTION

   Given a pointer to a DWARF information entry, synthesize a typedef
   for the name in the DIE, using the specified type.

   This is used for C++ class, structs, unions, and enumerations to
   set up the tag name as a type.

 */

static void
synthesize_typedef (struct dieinfo *dip, struct objfile *objfile,
		    struct type *type)
{
  struct symbol *sym = NULL;

  if (dip->at_name != NULL)
    {
      sym = (struct symbol *)
	obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
      OBJSTAT (objfile, n_syms++);
      memset (sym, 0, sizeof (struct symbol));
      DEPRECATED_SYMBOL_NAME (sym) = create_name (dip->at_name,
				       &objfile->objfile_obstack);
      SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
      SYMBOL_TYPE (sym) = type;
      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
      add_symbol_to_list (sym, list_in_scope);
    }
}

/*

   LOCAL FUNCTION

   decode_mod_fund_type -- decode a modified fundamental type

   SYNOPSIS

   static struct type *decode_mod_fund_type (char *typedata)

   DESCRIPTION

   Decode a block of data containing a modified fundamental
   type specification.  TYPEDATA is a pointer to the block,
   which starts with a length containing the size of the rest
   of the block.  At the end of the block is a fundmental type
   code value that gives the fundamental type.  Everything
   in between are type modifiers.

   We simply compute the number of modifiers and call the general
   function decode_modified_type to do the actual work.
 */

static struct type *
decode_mod_fund_type (char *typedata)
{
  struct type *typep = NULL;
  unsigned short modcount;
  int nbytes;

  /* Get the total size of the block, exclusive of the size itself */

  nbytes = attribute_size (AT_mod_fund_type);
  modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
  typedata += nbytes;

  /* Deduct the size of the fundamental type bytes at the end of the block. */

  modcount -= attribute_size (AT_fund_type);

  /* Now do the actual decoding */

  typep = decode_modified_type (typedata, modcount, AT_mod_fund_type);
  return (typep);
}

/*

   LOCAL FUNCTION

   decode_mod_u_d_type -- decode a modified user defined type

   SYNOPSIS

   static struct type *decode_mod_u_d_type (char *typedata)

   DESCRIPTION

   Decode a block of data containing a modified user defined
   type specification.  TYPEDATA is a pointer to the block,
   which consists of a two byte length, containing the size
   of the rest of the block.  At the end of the block is a
   four byte value that gives a reference to a user defined type.
   Everything in between are type modifiers.

   We simply compute the number of modifiers and call the general
   function decode_modified_type to do the actual work.
 */

static struct type *
decode_mod_u_d_type (char *typedata)
{
  struct type *typep = NULL;
  unsigned short modcount;
  int nbytes;

  /* Get the total size of the block, exclusive of the size itself */

  nbytes = attribute_size (AT_mod_u_d_type);
  modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
  typedata += nbytes;

  /* Deduct the size of the reference type bytes at the end of the block. */

  modcount -= attribute_size (AT_user_def_type);

  /* Now do the actual decoding */

  typep = decode_modified_type (typedata, modcount, AT_mod_u_d_type);
  return (typep);
}

/*

   LOCAL FUNCTION

   decode_modified_type -- decode modified user or fundamental type

   SYNOPSIS

   static struct type *decode_modified_type (char *modifiers,
   unsigned short modcount, int mtype)

   DESCRIPTION

   Decode a modified type, either a modified fundamental type or
   a modified user defined type.  MODIFIERS is a pointer to the
   block of bytes that define MODCOUNT modifiers.  Immediately
   following the last modifier is a short containing the fundamental
   type or a long containing the reference to the user defined
   type.  Which one is determined by MTYPE, which is either
   AT_mod_fund_type or AT_mod_u_d_type to indicate what modified
   type we are generating.

   We call ourself recursively to generate each modified type,`
   until MODCOUNT reaches zero, at which point we have consumed
   all the modifiers and generate either the fundamental type or
   user defined type.  When the recursion unwinds, each modifier
   is applied in turn to generate the full modified type.

   NOTES

   If we find a modifier that we don't recognize, and it is not one
   of those reserved for application specific use, then we issue a
   warning and simply ignore the modifier.

   BUGS

   We currently ignore MOD_const and MOD_volatile.  (FIXME)

 */

static struct type *
decode_modified_type (char *modifiers, unsigned int modcount, int mtype)
{
  struct type *typep = NULL;
  unsigned short fundtype;
  DIE_REF die_ref;
  char modifier;
  int nbytes;

  if (modcount == 0)
    {
      switch (mtype)
	{
	case AT_mod_fund_type:
	  nbytes = attribute_size (AT_fund_type);
	  fundtype = target_to_host (modifiers, nbytes, GET_UNSIGNED,
				     current_objfile);
	  typep = decode_fund_type (fundtype);
	  break;
	case AT_mod_u_d_type:
	  nbytes = attribute_size (AT_user_def_type);
	  die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED,
				    current_objfile);
	  typep = lookup_utype (die_ref);
	  if (typep == NULL)
	    {
	      typep = alloc_utype (die_ref, NULL);
	    }
	  break;
	default:
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)"),
		     DIE_ID, DIE_NAME, mtype);
	  typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
	  break;
	}
    }
  else
    {
      modifier = *modifiers++;
      typep = decode_modified_type (modifiers, --modcount, mtype);
      switch (modifier)
	{
	case MOD_pointer_to:
	  typep = lookup_pointer_type (typep);
	  break;
	case MOD_reference_to:
	  typep = lookup_reference_type (typep);
	  break;
	case MOD_const:
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", type modifier 'const' ignored"), DIE_ID,
		     DIE_NAME);	/* FIXME */
	  break;
	case MOD_volatile:
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", type modifier 'volatile' ignored"),
		     DIE_ID, DIE_NAME);	/* FIXME */
	  break;
	default:
	  if (!(MOD_lo_user <= (unsigned char) modifier))
#if 0
/* This part of the test would always be true, and it triggers a compiler
   warning.  */
		&& (unsigned char) modifier <= MOD_hi_user))
#endif
	    {
	      complaint (&symfile_complaints,
			 _("DIE @ 0x%x \"%s\", unknown type modifier %u"), DIE_ID,
			 DIE_NAME, modifier);
	    }
	  break;
	}
    }
  return (typep);
}

/*

   LOCAL FUNCTION

   decode_fund_type -- translate basic DWARF type to gdb base type

   DESCRIPTION

   Given an integer that is one of the fundamental DWARF types,
   translate it to one of the basic internal gdb types and return
   a pointer to the appropriate gdb type (a "struct type *").

   NOTES

   For robustness, if we are asked to translate a fundamental
   type that we are unprepared to deal with, we return int so
   callers can always depend upon a valid type being returned,
   and so gdb may at least do something reasonable by default.
   If the type is not in the range of those types defined as
   application specific types, we also issue a warning.
 */

static struct type *
decode_fund_type (unsigned int fundtype)
{
  struct type *typep = NULL;

  switch (fundtype)
    {

    case FT_void:
      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
      break;

    case FT_boolean:		/* Was FT_set in AT&T version */
      typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN);
      break;

    case FT_pointer:		/* (void *) */
      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
      typep = lookup_pointer_type (typep);
      break;

    case FT_char:
      typep = dwarf_fundamental_type (current_objfile, FT_CHAR);
      break;

    case FT_signed_char:
      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR);
      break;

    case FT_unsigned_char:
      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
      break;

    case FT_short:
      typep = dwarf_fundamental_type (current_objfile, FT_SHORT);
      break;

    case FT_signed_short:
      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT);
      break;

    case FT_unsigned_short:
      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
      break;

    case FT_integer:
      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
      break;

    case FT_signed_integer:
      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
      break;

    case FT_unsigned_integer:
      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
      break;

    case FT_long:
      typep = dwarf_fundamental_type (current_objfile, FT_LONG);
      break;

    case FT_signed_long:
      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG);
      break;

    case FT_unsigned_long:
      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
      break;

    case FT_long_long:
      typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG);
      break;

    case FT_signed_long_long:
      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG);
      break;

    case FT_unsigned_long_long:
      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
      break;

    case FT_float:
      typep = dwarf_fundamental_type (current_objfile, FT_FLOAT);
      break;

    case FT_dbl_prec_float:
      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
      break;

    case FT_ext_prec_float:
      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
      break;

    case FT_complex:
      typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX);
      break;

    case FT_dbl_prec_complex:
      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
      break;

    case FT_ext_prec_complex:
      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX);
      break;

    }

  if (typep == NULL)
    {
      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
      if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user))
	{
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x"),
		     DIE_ID, DIE_NAME, fundtype);
	}
    }

  return (typep);
}

/*

   LOCAL FUNCTION

   create_name -- allocate a fresh copy of a string on an obstack

   DESCRIPTION

   Given a pointer to a string and a pointer to an obstack, allocates
   a fresh copy of the string on the specified obstack.

 */

static char *
create_name (char *name, struct obstack *obstackp)
{
  int length;
  char *newname;

  length = strlen (name) + 1;
  newname = (char *) obstack_alloc (obstackp, length);
  strcpy (newname, name);
  return (newname);
}

/*

   LOCAL FUNCTION

   basicdieinfo -- extract the minimal die info from raw die data

   SYNOPSIS

   void basicdieinfo (char *diep, struct dieinfo *dip,
   struct objfile *objfile)

   DESCRIPTION

   Given a pointer to raw DIE data, and a pointer to an instance of a
   die info structure, this function extracts the basic information
   from the DIE data required to continue processing this DIE, along
   with some bookkeeping information about the DIE.

   The information we absolutely must have includes the DIE tag,
   and the DIE length.  If we need the sibling reference, then we
   will have to call completedieinfo() to process all the remaining
   DIE information.

   Note that since there is no guarantee that the data is properly
   aligned in memory for the type of access required (indirection
   through anything other than a char pointer), and there is no
   guarantee that it is in the same byte order as the gdb host,
   we call a function which deals with both alignment and byte
   swapping issues.  Possibly inefficient, but quite portable.

   We also take care of some other basic things at this point, such
   as ensuring that the instance of the die info structure starts
   out completely zero'd and that curdie is initialized for use
   in error reporting if we have a problem with the current die.

   NOTES

   All DIE's must have at least a valid length, thus the minimum
   DIE size is SIZEOF_DIE_LENGTH.  In order to have a valid tag, the
   DIE size must be at least SIZEOF_DIE_TAG larger, otherwise they
   are forced to be TAG_padding DIES.

   Padding DIES must be at least SIZEOF_DIE_LENGTH in length, implying
   that if a padding DIE is used for alignment and the amount needed is
   less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big
   enough to align to the next alignment boundry.

   We do some basic sanity checking here, such as verifying that the
   length of the die would not cause it to overrun the recorded end of
   the buffer holding the DIE info.  If we find a DIE that is either
   too small or too large, we force it's length to zero which should
   cause the caller to take appropriate action.
 */

static void
basicdieinfo (struct dieinfo *dip, char *diep, struct objfile *objfile)
{
  curdie = dip;
  memset (dip, 0, sizeof (struct dieinfo));
  dip->die = diep;
  dip->die_ref = dbroff + (diep - dbbase);
  dip->die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
				    objfile);
  if ((dip->die_length < SIZEOF_DIE_LENGTH) ||
      ((diep + dip->die_length) > (dbbase + dbsize)))
    {
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", malformed DIE, bad length (%ld bytes)"),
		 DIE_ID, DIE_NAME, dip->die_length);
      dip->die_length = 0;
    }
  else if (dip->die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG))
    {
      dip->die_tag = TAG_padding;
    }
  else
    {
      diep += SIZEOF_DIE_LENGTH;
      dip->die_tag = target_to_host (diep, SIZEOF_DIE_TAG, GET_UNSIGNED,
				     objfile);
    }
}

/*

   LOCAL FUNCTION

   completedieinfo -- finish reading the information for a given DIE

   SYNOPSIS

   void completedieinfo (struct dieinfo *dip, struct objfile *objfile)

   DESCRIPTION

   Given a pointer to an already partially initialized die info structure,
   scan the raw DIE data and finish filling in the die info structure
   from the various attributes found.

   Note that since there is no guarantee that the data is properly
   aligned in memory for the type of access required (indirection
   through anything other than a char pointer), and there is no
   guarantee that it is in the same byte order as the gdb host,
   we call a function which deals with both alignment and byte
   swapping issues.  Possibly inefficient, but quite portable.

   NOTES

   Each time we are called, we increment the diecount variable, which
   keeps an approximate count of the number of dies processed for
   each compilation unit.  This information is presented to the user
   if the info_verbose flag is set.

 */

static void
completedieinfo (struct dieinfo *dip, struct objfile *objfile)
{
  char *diep;			/* Current pointer into raw DIE data */
  char *end;			/* Terminate DIE scan here */
  unsigned short attr;		/* Current attribute being scanned */
  unsigned short form;		/* Form of the attribute */
  int nbytes;			/* Size of next field to read */

  diecount++;
  diep = dip->die;
  end = diep + dip->die_length;
  diep += SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG;
  while (diep < end)
    {
      attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile);
      diep += SIZEOF_ATTRIBUTE;
      nbytes = attribute_size (attr);
      if (nbytes == -1)
	{
	  complaint (&symfile_complaints,
		     _("DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes"),
		     DIE_ID, DIE_NAME);
	  diep = end;
	  continue;
	}
      switch (attr)
	{
	case AT_fund_type:
	  dip->at_fund_type = target_to_host (diep, nbytes, GET_UNSIGNED,
					      objfile);
	  break;
	case AT_ordering:
	  dip->at_ordering = target_to_host (diep, nbytes, GET_UNSIGNED,
					     objfile);
	  break;
	case AT_bit_offset:
	  dip->at_bit_offset = target_to_host (diep, nbytes, GET_UNSIGNED,
					       objfile);
	  break;
	case AT_sibling:
	  dip->at_sibling = target_to_host (diep, nbytes, GET_UNSIGNED,
					    objfile);
	  break;
	case AT_stmt_list:
	  dip->at_stmt_list = target_to_host (diep, nbytes, GET_UNSIGNED,
					      objfile);
	  dip->has_at_stmt_list = 1;
	  break;
	case AT_low_pc:
	  dip->at_low_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
					   objfile);
	  dip->at_low_pc += baseaddr;
	  dip->has_at_low_pc = 1;
	  break;
	case AT_high_pc:
	  dip->at_high_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
					    objfile);
	  dip->at_high_pc += baseaddr;
	  break;
	case AT_language:
	  dip->at_language = target_to_host (diep, nbytes, GET_UNSIGNED,
					     objfile);
	  break;
	case AT_user_def_type:
	  dip->at_user_def_type = target_to_host (diep, nbytes,
						  GET_UNSIGNED, objfile);
	  break;
	case AT_byte_size:
	  dip->at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED,
					      objfile);
	  dip->has_at_byte_size = 1;
	  break;
	case AT_bit_size:
	  dip->at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED,
					     objfile);
	  break;
	case AT_member:
	  dip->at_member = target_to_host (diep, nbytes, GET_UNSIGNED,
					   objfile);
	  break;
	case AT_discr:
	  dip->at_discr = target_to_host (diep, nbytes, GET_UNSIGNED,
					  objfile);
	  break;
	case AT_location:
	  dip->at_location = diep;
	  break;
	case AT_mod_fund_type:
	  dip->at_mod_fund_type = diep;
	  break;
	case AT_subscr_data:
	  dip->at_subscr_data = diep;
	  break;
	case AT_mod_u_d_type:
	  dip->at_mod_u_d_type = diep;
	  break;
	case AT_element_list:
	  dip->at_element_list = diep;
	  dip->short_element_list = 0;
	  break;
	case AT_short_element_list:
	  dip->at_element_list = diep;
	  dip->short_element_list = 1;
	  break;
	case AT_discr_value:
	  dip->at_discr_value = diep;
	  break;
	case AT_string_length:
	  dip->at_string_length = diep;
	  break;
	case AT_name:
	  dip->at_name = diep;
	  break;
	case AT_comp_dir:
	  /* For now, ignore any "hostname:" portion, since gdb doesn't
	     know how to deal with it.  (FIXME). */
	  dip->at_comp_dir = strrchr (diep, ':');
	  if (dip->at_comp_dir != NULL)
	    {
	      dip->at_comp_dir++;
	    }
	  else
	    {
	      dip->at_comp_dir = diep;
	    }
	  break;
	case AT_producer:
	  dip->at_producer = diep;
	  break;
	case AT_start_scope:
	  dip->at_start_scope = target_to_host (diep, nbytes, GET_UNSIGNED,
						objfile);
	  break;
	case AT_stride_size:
	  dip->at_stride_size = target_to_host (diep, nbytes, GET_UNSIGNED,
						objfile);
	  break;
	case AT_src_info:
	  dip->at_src_info = target_to_host (diep, nbytes, GET_UNSIGNED,
					     objfile);
	  break;
	case AT_prototyped:
	  dip->at_prototyped = diep;
	  break;
	default:
	  /* Found an attribute that we are unprepared to handle.  However
	     it is specifically one of the design goals of DWARF that
	     consumers should ignore unknown attributes.  As long as the
	     form is one that we recognize (so we know how to skip it),
	     we can just ignore the unknown attribute. */
	  break;
	}
      form = FORM_FROM_ATTR (attr);
      switch (form)
	{
	case FORM_DATA2:
	  diep += 2;
	  break;
	case FORM_DATA4:
	case FORM_REF:
	  diep += 4;
	  break;
	case FORM_DATA8:
	  diep += 8;
	  break;
	case FORM_ADDR:
	  diep += TARGET_FT_POINTER_SIZE (objfile);
	  break;
	case FORM_BLOCK2:
	  diep += 2 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
	  break;
	case FORM_BLOCK4:
	  diep += 4 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
	  break;
	case FORM_STRING:
	  diep += strlen (diep) + 1;
	  break;
	default:
	  unknown_attribute_form_complaint (DIE_ID, DIE_NAME, form);
	  diep = end;
	  break;
	}
    }
}

/*

   LOCAL FUNCTION

   target_to_host -- swap in target data to host

   SYNOPSIS

   target_to_host (char *from, int nbytes, int signextend,
   struct objfile *objfile)

   DESCRIPTION

   Given pointer to data in target format in FROM, a byte count for
   the size of the data in NBYTES, a flag indicating whether or not
   the data is signed in SIGNEXTEND, and a pointer to the current
   objfile in OBJFILE, convert the data to host format and return
   the converted value.

   NOTES

   FIXME:  If we read data that is known to be signed, and expect to
   use it as signed data, then we need to explicitly sign extend the
   result until the bfd library is able to do this for us.

   FIXME: Would a 32 bit target ever need an 8 byte result?

 */

static CORE_ADDR
target_to_host (char *from, int nbytes, int signextend,	/* FIXME:  Unused */
		struct objfile *objfile)
{
  CORE_ADDR rtnval;

  switch (nbytes)
    {
    case 8:
      rtnval = bfd_get_64 (objfile->obfd, (bfd_byte *) from);
      break;
    case 4:
      rtnval = bfd_get_32 (objfile->obfd, (bfd_byte *) from);
      break;
    case 2:
      rtnval = bfd_get_16 (objfile->obfd, (bfd_byte *) from);
      break;
    case 1:
      rtnval = bfd_get_8 (objfile->obfd, (bfd_byte *) from);
      break;
    default:
      complaint (&symfile_complaints,
		 _("DIE @ 0x%x \"%s\", no bfd support for %d byte data object"),
		 DIE_ID, DIE_NAME, nbytes);
      rtnval = 0;
      break;
    }
  return (rtnval);
}

/*

   LOCAL FUNCTION

   attribute_size -- compute size of data for a DWARF attribute

   SYNOPSIS

   static int attribute_size (unsigned int attr)

   DESCRIPTION

   Given a DWARF attribute in ATTR, compute the size of the first
   piece of data associated with this attribute and return that
   size.

   Returns -1 for unrecognized attributes.

 */

static int
attribute_size (unsigned int attr)
{
  int nbytes;			/* Size of next data for this attribute */
  unsigned short form;		/* Form of the attribute */

  form = FORM_FROM_ATTR (attr);
  switch (form)
    {
    case FORM_STRING:		/* A variable length field is next */
      nbytes = 0;
      break;
    case FORM_DATA2:		/* Next 2 byte field is the data itself */
    case FORM_BLOCK2:		/* Next 2 byte field is a block length */
      nbytes = 2;
      break;
    case FORM_DATA4:		/* Next 4 byte field is the data itself */
    case FORM_BLOCK4:		/* Next 4 byte field is a block length */
    case FORM_REF:		/* Next 4 byte field is a DIE offset */
      nbytes = 4;
      break;
    case FORM_DATA8:		/* Next 8 byte field is the data itself */
      nbytes = 8;
      break;
    case FORM_ADDR:		/* Next field size is target sizeof(void *) */
      nbytes = TARGET_FT_POINTER_SIZE (objfile);
      break;
    default:
      unknown_attribute_form_complaint (DIE_ID, DIE_NAME, form);
      nbytes = -1;
      break;
    }
  return (nbytes);
}
