* c-exp.y (c_create_fundamental_type): New function to create
authorFred Fish <fnf@specifix.com>
Thu, 3 Dec 1992 20:28:16 +0000 (20:28 +0000)
committerFred Fish <fnf@specifix.com>
Thu, 3 Dec 1992 20:28:16 +0000 (20:28 +0000)
language specific fundamental types for C.
* m2-exp.y (m2_create_fundamental_type):  New function to create
language specific fundamental types for Modula 2.
* c-exp.y (c_language_defn, cplus_language_defn):  Add
c_create_fundamental_type to language struct initializers.
* m2-exp.y (m2_language_defn):  Add m2_create_fundamental_type
to language struct initializers.
* dwarfread.c (expression.h, language.h):  Include.
* dwarfread.c (ftypes):  New array to hold fundamental types
for current compilation unit.
* dwarfread.c (cu_language_defn):  New pointer to language
struct for language of current compilation unit.
* dwarfread.c (dwarf_fundamental_type):  New function to
create/lookup fundamental types.
* dwarfread.c (set_cu_language):  Initialize cu_language_defn.
* dwarfread.c (throughout):  Replace lookup_fundamental_type
with dwarf_fundamental_type.
* dwarfread.c (read_file_scope):  Zero out ftypes for each new
compilation unit (may be different language or different objfile).
* gdbtypes.c (lookup_fundamental_type):  Move actual type
creations into language specific fundamental type creation
functions and call via create_fundamental_type.  Add comment
about this function being obsolescent.
* gdbtypes.h (FT_BYTE, FT_UNSIGNED_BYTE):  New types, true byte
sized signed and unsigned integers.
* gdbtypes.h (FT_NUM_MEMBERS):  Increment, new types added.
* language.c (language_def):  New function to lookup a language
struct given it's enumeration.
* language.h (struct language_defn):  Add la_fund_type, a pointer
to a function that creates fundamental types for this language.
* language.h (create_fundamental_type):  New macro to create
fundamental types based on the current language.
* language.h (language_def):  Add prototype.
* language.c (unk_lang_create_fundamental_type):  New function
for initializing language structs, calls error if called.
* language.c (unk_language_defn, auto_language_defn,
local_language_defn):  Use unk_lang_create_fundamental_type.
**** start-sanitize-chill ****
ch-exp.y (chill_create_fundamental_type):  New function.
ch-exp.y (chill_language_defn):  Add chill_create_fundamental_type.
ch-exp.y (_initialize_chill_exp):  BOOL types are only one byte.
**** end-sanitize-chill ****

gdb/ChangeLog
gdb/c-exp.y
gdb/ch-exp.y
gdb/dwarfread.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/language.c
gdb/language.h
gdb/m2-exp.y

index 0dc5111..b32f4b4 100644 (file)
@@ -1,3 +1,49 @@
+Thu Dec  3 12:00:06 1992  Fred Fish  (fnf@cygnus.com)
+
+       * c-exp.y (c_create_fundamental_type):  New function to create
+       language specific fundamental types for C.
+       * m2-exp.y (m2_create_fundamental_type):  New function to create
+       language specific fundamental types for Modula 2.
+       * c-exp.y (c_language_defn, cplus_language_defn):  Add
+       c_create_fundamental_type to language struct initializers.
+       * m2-exp.y (m2_language_defn):  Add m2_create_fundamental_type
+       to language struct initializers.
+       * dwarfread.c (expression.h, language.h):  Include.
+       * dwarfread.c (ftypes):  New array to hold fundamental types
+       for current compilation unit.
+       * dwarfread.c (cu_language_defn):  New pointer to language
+       struct for language of current compilation unit.
+       * dwarfread.c (dwarf_fundamental_type):  New function to
+       create/lookup fundamental types.
+       * dwarfread.c (set_cu_language):  Initialize cu_language_defn.
+       * dwarfread.c (throughout):  Replace lookup_fundamental_type
+       with dwarf_fundamental_type.
+       * dwarfread.c (read_file_scope):  Zero out ftypes for each new
+       compilation unit (may be different language or different objfile).
+       * gdbtypes.c (lookup_fundamental_type):  Move actual type
+       creations into language specific fundamental type creation
+       functions and call via create_fundamental_type.  Add comment
+       about this function being obsolescent.
+       * gdbtypes.h (FT_BYTE, FT_UNSIGNED_BYTE):  New types, true byte
+       sized signed and unsigned integers.
+       * gdbtypes.h (FT_NUM_MEMBERS):  Increment, new types added.
+       * language.c (language_def):  New function to lookup a language
+       struct given it's enumeration.
+       * language.h (struct language_defn):  Add la_fund_type, a pointer
+       to a function that creates fundamental types for this language.
+       * language.h (create_fundamental_type):  New macro to create
+       fundamental types based on the current language.
+       * language.h (language_def):  Add prototype.
+       * language.c (unk_lang_create_fundamental_type):  New function
+       for initializing language structs, calls error if called.
+       * language.c (unk_language_defn, auto_language_defn, 
+       local_language_defn):  Use unk_lang_create_fundamental_type.    
+       **** start-sanitize-chill ****
+       ch-exp.y (chill_create_fundamental_type):  New function.
+       ch-exp.y (chill_language_defn):  Add chill_create_fundamental_type.
+       ch-exp.y (_initialize_chill_exp):  BOOL types are only one byte.
+       **** end-sanitize-chill ****
+
        **** start-sanitize-chill ****
 Tue Dec  1 17:07:31 1992  Fred Fish  (fnf@cygnus.com)
 
index c368aa9..25567a7 100644 (file)
@@ -1666,6 +1666,148 @@ c_printstr (stream, string, length, force_ellipses)
     fputs_filtered ("...", stream);
 }
 
+/* Create a fundamental C type using default reasonable for the current
+   target machine.
+
+   Some object/debugging file formats (DWARF version 1, COFF, etc) do not
+   define fundamental types such as "int" or "double".  Others (stabs or
+   DWARF version 2, etc) do define fundamental types.  For the formats which
+   don't provide fundamental types, gdb can create such types using this
+   function.
+
+   FIXME:  Some compilers distinguish explicitly signed integral types
+   (signed short, signed int, signed long) from "regular" integral types
+   (short, int, long) in the debugging information.  There is some dis-
+   agreement as to how useful this feature is.  In particular, gcc does
+   not support this.  Also, only some debugging formats allow the
+   distinction to be passed on to a debugger.  For now, we always just
+   use "short", "int", or "long" as the type name, for both the implicit
+   and explicitly signed types.  This also makes life easier for the
+   gdb test suite since we don't have to account for the differences
+   in output depending upon what the compiler and debugging format
+   support.  We will probably have to re-examine the issue when gdb
+   starts taking it's fundamental type information directly from the
+   debugging information supplied by the compiler.  fnf@cygnus.com */
+
+static struct type *
+c_create_fundamental_type (objfile, typeid)
+     struct objfile *objfile;
+     int typeid;
+{
+  register struct type *type = NULL;
+  register int nbytes;
+
+  switch (typeid)
+    {
+      default:
+       /* FIXME:  For now, if we are asked to produce a type not in this
+          language, create the equivalent of a C integer type with the
+          name "<?type?>".  When all the dust settles from the type
+          reconstruction work, this should probably become an error. */
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "<?type?>", objfile);
+        warning ("internal error: no C/C++ fundamental type %d", typeid);
+       break;
+      case FT_VOID:
+       type = init_type (TYPE_CODE_VOID,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "void", objfile);
+       break;
+      case FT_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "char", objfile);
+       break;
+      case FT_SIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "signed char", objfile);
+       break;
+      case FT_UNSIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+       break;
+      case FT_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         0, "short", objfile);
+       break;
+      case FT_SIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "short", objfile);  /* FIXME-fnf */
+       break;
+      case FT_UNSIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+       break;
+      case FT_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "int", objfile);
+       break;
+      case FT_SIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+       break;
+      case FT_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long", objfile);
+       break;
+      case FT_SIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+       break;
+      case FT_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long long", objfile);
+       break;
+      case FT_SIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "signed long long", objfile);
+       break;
+      case FT_UNSIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+       break;
+      case FT_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                         0, "float", objfile);
+       break;
+      case FT_DBL_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "double", objfile);
+       break;
+      case FT_EXT_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "long double", objfile);
+       break;
+      }
+  return (type);
+}
+
 \f
 /* Table mapping opcodes into strings for printing operators
    and precedences of the operators.  */
@@ -1759,7 +1901,8 @@ const struct language_defn c_language_defn = {
   c_error,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
-  &BUILTIN_TYPE_LONGEST,        /* longest signed   integral type */
+  c_create_fundamental_type,   /* Create fundamental type in this language */
+  &BUILTIN_TYPE_LONGEST,       /* longest signed   integral type */
   &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
   &builtin_type_double,                /* longest floating point type */ /*FIXME*/
   {"",     "",    "",  ""},    /* Binary format info */
@@ -1780,6 +1923,7 @@ const struct language_defn cplus_language_defn = {
   c_error,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
+  c_create_fundamental_type,   /* Create fundamental type in this language */
   &BUILTIN_TYPE_LONGEST,        /* longest signed   integral type */
   &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
   &builtin_type_double,                /* longest floating point type */ /*FIXME*/
index dc60729..96dbda4 100644 (file)
@@ -1431,6 +1431,70 @@ chill_printstr (stream, string, length, force_ellipses)
     }
 }
 
+static struct type *
+chill_create_fundamental_type (objfile, typeid)
+     struct objfile *objfile;
+     int typeid;
+{
+  register struct type *type = NULL;
+  register int nbytes;
+
+  switch (typeid)
+    {
+      default:
+       /* FIXME:  For now, if we are asked to produce a type not in this
+          language, create the equivalent of a C integer type with the
+          name "<?type?>".  When all the dust settles from the type
+          reconstruction work, this should probably become an error. */
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "<?type?>", objfile);
+        warning ("internal error: no chill fundamental type %d", typeid);
+       break;
+      case FT_BOOLEAN:
+       type = init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "BOOL", objfile);
+       break;
+      case FT_CHAR:
+       type = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "CHAR", objfile);
+       break;
+      case FT_BYTE:
+       type = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "BYTE", objfile);
+       break;
+      case FT_UNSIGNED_BYTE:
+       type = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
+       break;
+      case FT_INTEGER:
+       type = init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "INT", objfile);
+       break;
+      case FT_UNSIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "UINT", objfile);
+       break;
+      case FT_LONG:
+       type = init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "LONG", objfile);
+       break;
+      case FT_UNSIGNED_LONG:
+       type = init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "ULONG", objfile);
+       break;
+      case FT_FLOAT:
+       type = init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                         0, "REAL", objfile);
+       break;
+      case FT_DBL_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "LONG REAL", objfile);
+       break;
+      }
+  return (type);
+}
+
 \f
 /* Table of operators and their precedences for printing expressions.  */
 
@@ -1483,6 +1547,7 @@ const struct language_defn chill_language_defn = {
   chill_error,                 /* parser error function */
   chill_printchar,             /* print a character constant */
   chill_printstr,              /* function to print a string constant */
+  chill_create_fundamental_type,/* Create fundamental type in this language */
   &BUILTIN_TYPE_LONGEST,       /* longest signed   integral type */
   &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
   &builtin_type_chill_real,    /* longest floating point type */
@@ -1500,7 +1565,7 @@ void
 _initialize_chill_exp ()
 {
   builtin_type_chill_bool =
-    init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
+    init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
               TYPE_FLAG_UNSIGNED,
               "BOOL", (struct objfile *) NULL);
   builtin_type_chill_char =
index ef54045..1ca2cbc 100644 (file)
@@ -50,6 +50,8 @@ other things to work on, if you get bored. :-)
 #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 <varargs.h>
 #include <fcntl.h>
@@ -311,19 +313,38 @@ struct pending **list_in_scope = &file_symbols;
    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. */
+   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. */
+   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.  */
@@ -456,6 +477,66 @@ record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,
 static void
 set_cu_language PARAMS ((struct dieinfo *));
 
+static struct type *
+dwarf_fundamental_type PARAMS ((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 (objfile, typeid)
+     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
@@ -510,6 +591,7 @@ set_cu_language (dip)
        cu_language = language_unknown;
        break;
     }
+  cu_language_defn = language_def (cu_language);
 }
 
 /*
@@ -787,7 +869,7 @@ alloc_utype (die_ref, utypep)
   typep = utypes + utypeidx;
   if ((utypeidx < 0) || (utypeidx >= numutypes))
     {
-      utypep = lookup_fundamental_type (current_objfile, FT_INTEGER);
+      utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
       dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref);
     }
   else if (*typep != NULL)
@@ -850,7 +932,7 @@ decode_die_type (dip)
     }
   else
     {
-      type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+      type = dwarf_fundamental_type (current_objfile, FT_INTEGER);
     }
   return (type);
 }
@@ -1129,7 +1211,7 @@ decode_array_element_type (scan)
   if ((nbytes = attribute_size (attribute)) == -1)
     {
       SQUAWK (("bad array element type attribute 0x%x", attribute));
-      typep = lookup_fundamental_type (current_objfile, FT_INTEGER);
+      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
     }
   else
     {
@@ -1156,7 +1238,7 @@ decode_array_element_type (scan)
            break;
          default:
            SQUAWK (("bad array element type attribute 0x%x", attribute));
-           typep = lookup_fundamental_type (current_objfile, FT_INTEGER);
+           typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
            break;
          }
     }
@@ -1309,7 +1391,7 @@ dwarf_read_array_type (dip)
            }
          TYPE_CODE (utype) = TYPE_CODE_ARRAY;
          TYPE_TARGET_TYPE (utype) = 
-           lookup_fundamental_type (current_objfile, FT_INTEGER);
+           dwarf_fundamental_type (current_objfile, FT_INTEGER);
          TYPE_LENGTH (utype) = 1 * TYPE_LENGTH (TYPE_TARGET_TYPE (utype));
        }
       else
@@ -1761,6 +1843,7 @@ read_file_scope (dip, thisdie, enddie, objfile)
   utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
   back_to = make_cleanup (free, utypes);
   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);
   decode_line_numbers (lnbase);
   process_dies (thisdie + dip -> die_length, enddie, objfile);
@@ -3073,7 +3156,7 @@ decode_modified_type (modifiers, modcount, mtype)
          break;
        default:
          SQUAWK (("botched modified type decoding (mtype 0x%x)", mtype));
-         typep = lookup_fundamental_type (current_objfile, FT_INTEGER);
+         typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
          break;
        }
     }
@@ -3138,100 +3221,100 @@ decode_fund_type (fundtype)
     {
 
     case FT_void:
-      typep = lookup_fundamental_type (current_objfile, FT_VOID);
+      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
       break;
     
     case FT_boolean:           /* Was FT_set in AT&T version */
-      typep = lookup_fundamental_type (current_objfile, FT_BOOLEAN);
+      typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN);
       break;
 
     case FT_pointer:           /* (void *) */
-      typep = lookup_fundamental_type (current_objfile, FT_VOID);
+      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
       typep = lookup_pointer_type (typep);
       break;
     
     case FT_char:
-      typep = lookup_fundamental_type (current_objfile, FT_CHAR);
+      typep = dwarf_fundamental_type (current_objfile, FT_CHAR);
       break;
     
     case FT_signed_char:
-      typep = lookup_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR);
       break;
 
     case FT_unsigned_char:
-      typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
       break;
     
     case FT_short:
-      typep = lookup_fundamental_type (current_objfile, FT_SHORT);
+      typep = dwarf_fundamental_type (current_objfile, FT_SHORT);
       break;
 
     case FT_signed_short:
-      typep = lookup_fundamental_type (current_objfile, FT_SIGNED_SHORT);
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT);
       break;
     
     case FT_unsigned_short:
-      typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
       break;
     
     case FT_integer:
-      typep = lookup_fundamental_type (current_objfile, FT_INTEGER);
+      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
       break;
 
     case FT_signed_integer:
-      typep = lookup_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
       break;
     
     case FT_unsigned_integer:
-      typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
       break;
     
     case FT_long:
-      typep = lookup_fundamental_type (current_objfile, FT_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_LONG);
       break;
 
     case FT_signed_long:
-      typep = lookup_fundamental_type (current_objfile, FT_SIGNED_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG);
       break;
     
     case FT_unsigned_long:
-      typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
       break;
     
     case FT_long_long:
-      typep = lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG);
       break;
 
     case FT_signed_long_long:
-      typep = lookup_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG);
       break;
 
     case FT_unsigned_long_long:
-      typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
       break;
 
     case FT_float:
-      typep = lookup_fundamental_type (current_objfile, FT_FLOAT);
+      typep = dwarf_fundamental_type (current_objfile, FT_FLOAT);
       break;
     
     case FT_dbl_prec_float:
-      typep = lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
       break;
     
     case FT_ext_prec_float:
-      typep = lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
       break;
     
     case FT_complex:
-      typep = lookup_fundamental_type (current_objfile, FT_COMPLEX);
+      typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX);
       break;
     
     case FT_dbl_prec_complex:
-      typep = lookup_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
+      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
       break;
     
     case FT_ext_prec_complex:
-      typep = lookup_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX);
+      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX);
       break;
     
     }
@@ -3239,7 +3322,7 @@ decode_fund_type (fundtype)
   if ((typep == NULL) && !(FT_lo_user <= fundtype && fundtype <= FT_hi_user))
     {
       SQUAWK (("unexpected fundamental type 0x%x", fundtype));
-      typep = lookup_fundamental_type (current_objfile, FT_VOID);
+      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
     }
     
   return (typep);
index 2090eda..53f651e 100644 (file)
@@ -910,28 +910,24 @@ init_type (code, length, flags, name, objfile)
    define fundamental types.
 
    For the formats which don't provide fundamental types, gdb can create
-   such types, using defaults reasonable for the current target machine.
-
-   FIXME:  Some compilers distinguish explicitly signed integral types
-   (signed short, signed int, signed long) from "regular" integral types
-   (short, int, long) in the debugging information.  There is some dis-
-   agreement as to how useful this feature is.  In particular, gcc does
-   not support this.  Also, only some debugging formats allow the
-   distinction to be passed on to a debugger.  For now, we always just
-   use "short", "int", or "long" as the type name, for both the implicit
-   and explicitly signed types.  This also makes life easier for the
-   gdb test suite since we don't have to account for the differences
-   in output depending upon what the compiler and debugging format
-   support.  We will probably have to re-examine the issue when gdb
-   starts taking it's fundamental type information directly from the
-   debugging information supplied by the compiler.  fnf@cygnus.com */
+   such types, using defaults reasonable for the current language and
+   the current target machine.
+
+   NOTE:  This routine is obsolescent.  Each debugging format reader
+   should manage it's own fundamental types, either creating them from
+   suitable defaults or reading them from the debugging information,
+   whichever is appropriate.  The DWARF reader has already been
+   fixed to do this.  Once the other readers are fixed, this routine
+   will go away.  Also note that fundamental types should be managed
+   on a compilation unit basis in a multi-language environment, not
+   on a linkage unit basis as is done here. */
+
 
 struct type *
 lookup_fundamental_type (objfile, typeid)
      struct objfile *objfile;
      int typeid;
 {
-  register struct type *type = NULL;
   register struct type **typep;
   register int nbytes;
 
@@ -939,187 +935,28 @@ lookup_fundamental_type (objfile, typeid)
     {
       error ("internal error - invalid fundamental type id %d", typeid);
     }
-  else
+
+  /* If this is the first time we need a fundamental type for this objfile
+     then we need to initialize the vector of type pointers. */
+  
+  if (objfile -> fundamental_types == NULL)
     {
-      /* If this is the first time we */
-      if (objfile -> fundamental_types == NULL)
-       {
-         nbytes = FT_NUM_MEMBERS * sizeof (struct type *);
-         objfile -> fundamental_types = (struct type **)
-           obstack_alloc (&objfile -> type_obstack, nbytes);
-         memset ((char *) objfile -> fundamental_types, 0, nbytes);
-       }
-      typep = objfile -> fundamental_types + typeid;
-      if ((type = *typep) == NULL)
-       {
-         switch (typeid)
-           {
-             default:
-               error ("internal error: unhandled type id %d", typeid);
-               break;
-             case FT_VOID:
-               type = init_type (TYPE_CODE_VOID,
-                                 TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "void", objfile);
-               break;
-             case FT_BOOLEAN:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_INT_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "boolean", objfile);
-               break;
-             case FT_STRING:
-               type = init_type (TYPE_CODE_PASCAL_ARRAY,
-                                 TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "string", objfile);
-               break;
-             case FT_CHAR:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "char", objfile);
-               break;
-             case FT_SIGNED_CHAR:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_SIGNED,
-                                 "signed char", objfile);
-               break;
-             case FT_UNSIGNED_CHAR:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "unsigned char", objfile);
-               break;
-             case FT_SHORT:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "short", objfile);
-               break;
-             case FT_SIGNED_SHORT:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_SIGNED,
-                                 "short", objfile);    /* FIXME -fnf */
-               break;
-             case FT_UNSIGNED_SHORT:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "unsigned short", objfile);
-               break;
-             case FT_INTEGER:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_INT_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "int", objfile);
-               break;
-             case FT_SIGNED_INTEGER:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_INT_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_SIGNED,
-                                 "int", objfile);      /* FIXME -fnf */
-               break;
-             case FT_UNSIGNED_INTEGER:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_INT_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "unsigned int", objfile);
-               break;
-             case FT_FIXED_DECIMAL:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_INT_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "fixed decimal", objfile);
-               break;
-             case FT_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "long", objfile);
-               break;
-             case FT_SIGNED_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_SIGNED,
-                                 "long", objfile);     /* FIXME -fnf */
-               break;
-             case FT_UNSIGNED_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "unsigned long", objfile);
-               break;
-             case FT_LONG_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "long long", objfile);
-               break;
-             case FT_SIGNED_LONG_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_SIGNED,
-                                 "signed long long", objfile);
-               break;
-             case FT_UNSIGNED_LONG_LONG:
-               type = init_type (TYPE_CODE_INT,
-                                 TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                                 TYPE_FLAG_UNSIGNED,
-                                 "unsigned long long", objfile);
-               break;
-             case FT_FLOAT:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "float", objfile);
-               break;
-             case FT_DBL_PREC_FLOAT:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "double", objfile);
-               break;
-             case FT_FLOAT_DECIMAL:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "floating decimal", objfile);
-               break;
-             case FT_EXT_PREC_FLOAT:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "long double", objfile);
-               break;
-             case FT_COMPLEX:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "complex", objfile);
-               break;
-             case FT_DBL_PREC_COMPLEX:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "double complex", objfile);
-               break;
-             case FT_EXT_PREC_COMPLEX:
-               type = init_type (TYPE_CODE_FLT,
-                                 TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
-                                 0,
-                                 "long double complex", objfile);
-               break;
-           }
-         /* Install the newly created type in the objfile's fundamental_types
-            vector. */
-         *typep = type;
-       }
+      nbytes = FT_NUM_MEMBERS * sizeof (struct type *);
+      objfile -> fundamental_types = (struct type **)
+       obstack_alloc (&objfile -> type_obstack, nbytes);
+      memset ((char *) objfile -> fundamental_types, 0, nbytes);
     }
-  return (type);
+
+  /* Look for this particular type in the fundamental type vector.  If one is
+     not found, create and install one appropriate for the current language. */
+
+  typep = objfile -> fundamental_types + typeid;
+  if (*typep == NULL)
+    {
+      *typep = create_fundamental_type (objfile, typeid);
+    }
+
+  return (*typep);
 }
 
 #if MAINTENANCE_CMDS
index deb8701..9c7bf11 100644 (file)
@@ -51,8 +51,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define FT_STRING              23
 #define FT_FIXED_DECIMAL       24
 #define FT_FLOAT_DECIMAL       25
+#define FT_BYTE                        26
+#define FT_UNSIGNED_BYTE       27
 
-#define FT_NUM_MEMBERS         26
+#define FT_NUM_MEMBERS         28      /* Highest FT_* above, plus one. */
 
 /* Different kinds of data types are distinguished by the `code' field.  */
 
@@ -80,7 +82,7 @@ enum type_code
 
   /* Modula-2 */
   TYPE_CODE_CHAR,              /* *real* character type */
-  TYPE_CODE_BOOL               /* Builtin BOOLEAN type */
+  TYPE_CODE_BOOL               /* BOOLEAN type */
 };
 
 /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
index 5a6c689..2c964d1 100644 (file)
@@ -1022,6 +1022,22 @@ range_error (va_alist)
 \f
 /* This page contains miscellaneous functions */
 
+/* Return the language struct for a given language enum. */
+
+const struct language_defn *
+language_def(lang)
+   enum language lang;
+{
+  int i;
+
+  for (i = 0; i < languages_size; i++) {
+    if (languages[i]->la_language == lang) {
+      return languages[i];
+    }
+  }
+  return NULL;
+}
+
 /* Return the language as a string */
 char *
 language_str(lang)
@@ -1116,6 +1132,14 @@ unk_lang_printstr (stream, string, length, force_ellipses)
   error ("internal error - unimplemented function unk_lang_printstr called.");
 }
 
+static struct type *
+unk_lang_create_fundamental_type (objfile, typeid)
+     struct objfile *objfile;
+     int typeid;
+{
+  error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
+}
+
 static struct type ** const (unknown_builtin_types[]) = { 0 };
 static const struct op_print unk_op_print_tab[] = { 0 };
 
@@ -1129,6 +1153,7 @@ const struct language_defn unknown_language_defn = {
   unk_lang_error,
   unk_lang_printchar,          /* Print character constant */
   unk_lang_printstr,
+  unk_lang_create_fundamental_type,
   &builtin_type_error,         /* longest signed   integral type */
   &builtin_type_error,         /* longest unsigned integral type */
   &builtin_type_error,         /* longest floating point type */
@@ -1151,6 +1176,7 @@ const struct language_defn auto_language_defn = {
   unk_lang_error,
   unk_lang_printchar,          /* Print character constant */
   unk_lang_printstr,
+  unk_lang_create_fundamental_type,
   &builtin_type_error,         /* longest signed   integral type */
   &builtin_type_error,         /* longest unsigned integral type */
   &builtin_type_error,         /* longest floating point type */
@@ -1172,6 +1198,7 @@ const struct language_defn local_language_defn = {
   unk_lang_error,
   unk_lang_printchar,          /* Print character constant */
   unk_lang_printstr,
+  unk_lang_create_fundamental_type,
   &builtin_type_error,         /* longest signed   integral type */
   &builtin_type_error,         /* longest unsigned integral type */
   &builtin_type_error,         /* longest floating point type */
index 862323a..f25a35c 100644 (file)
@@ -108,6 +108,7 @@ struct language_defn {
   void           (*la_error) PARAMS ((char *)); /* Parser error function */
   void          (*la_printchar) PARAMS ((int, FILE *));
   void          (*la_printstr) PARAMS ((FILE *, char *, unsigned int, int));
+  struct type   *(*la_fund_type) PARAMS ((struct objfile *, int));
   struct type   **la_longest_int;      /* Longest signed integral type */
   struct type   **la_longest_unsigned_int; /* Longest uns integral type */
   struct type   **la_longest_float;    /* Longest floating point type */
@@ -176,6 +177,9 @@ set_language PARAMS ((enum language));
 #define        longest_unsigned_int()  (*current_language->la_longest_unsigned_int)
 #define        longest_float()         (*current_language->la_longest_float)
 
+#define create_fundamental_type(objfile,typeid) \
+  (current_language->la_fund_type(objfile, typeid))
+
 /* Return a format string for printf that will print a number in one of
    the local (language-specific) formats.  Result is static and is
    overwritten by the next call.  Takes printf options like "08" or "l"
@@ -320,6 +324,9 @@ value_true PARAMS ((struct value *));
 
 /* Misc:  The string representing a particular enum language.  */
 
+extern const struct language_defn *
+language_def PARAMS ((enum language));
+
 extern char *
 language_str PARAMS ((enum language));
 
index 6edc059..e1eb3f9 100644 (file)
@@ -1341,6 +1341,164 @@ m2_printstr (stream, string, length, force_ellipses)
     fputs_filtered ("...", stream);
 }
 
+/* FIXME:  This is a copy of c_create_fundamental_type(), before
+   all the non-C types were stripped from it.  Needs to be fixed
+   by an experienced Modula programmer. */
+
+static struct type *
+m2_create_fundamental_type (objfile, typeid)
+     struct objfile *objfile;
+     int typeid;
+{
+  register struct type *type = NULL;
+  register int nbytes;
+
+  switch (typeid)
+    {
+      default:
+       /* FIXME:  For now, if we are asked to produce a type not in this
+          language, create the equivalent of a C integer type with the
+          name "<?type?>".  When all the dust settles from the type
+          reconstruction work, this should probably become an error. */
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "<?type?>", objfile);
+        warning ("internal error: no Modula fundamental type %d", typeid);
+       break;
+      case FT_VOID:
+       type = init_type (TYPE_CODE_VOID,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "void", objfile);
+       break;
+      case FT_BOOLEAN:
+       type = init_type (TYPE_CODE_BOOL,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "boolean", objfile);
+       break;
+      case FT_STRING:
+       type = init_type (TYPE_CODE_PASCAL_ARRAY,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "string", objfile);
+       break;
+      case FT_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "char", objfile);
+       break;
+      case FT_SIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "signed char", objfile);
+       break;
+      case FT_UNSIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+       break;
+      case FT_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         0, "short", objfile);
+       break;
+      case FT_SIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "short", objfile);  /* FIXME-fnf */
+       break;
+      case FT_UNSIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+       break;
+      case FT_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "int", objfile);
+       break;
+      case FT_SIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+       break;
+      case FT_FIXED_DECIMAL:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "fixed decimal", objfile);
+       break;
+      case FT_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long", objfile);
+       break;
+      case FT_SIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+       break;
+      case FT_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long long", objfile);
+       break;
+      case FT_SIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_SIGNED, "signed long long", objfile);
+       break;
+      case FT_UNSIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+       break;
+      case FT_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                         0, "float", objfile);
+       break;
+      case FT_DBL_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "double", objfile);
+       break;
+      case FT_FLOAT_DECIMAL:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "floating decimal", objfile);
+       break;
+      case FT_EXT_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "long double", objfile);
+       break;
+      case FT_COMPLEX:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
+                         0, "complex", objfile);
+       break;
+      case FT_DBL_PREC_COMPLEX:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
+                         0, "double complex", objfile);
+       break;
+      case FT_EXT_PREC_COMPLEX:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
+                         0, "long double complex", objfile);
+       break;
+      }
+  return (type);
+}
+
 \f
 /* Table of operators and their precedences for printing expressions.  */
 
@@ -1396,6 +1554,7 @@ const struct language_defn m2_language_defn = {
   m2_error,                    /* parser error function */
   m2_printchar,                        /* Print character constant */
   m2_printstr,                 /* function to print string constant */
+  m2_create_fundamental_type,  /* Create fundamental type in this language */
   &builtin_type_m2_int,                /* longest signed   integral type */
   &builtin_type_m2_card,       /* longest unsigned integral type */
   &builtin_type_m2_real,       /* longest floating point type */