mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-21 10:02:26 +00:00
* c-exp.y, m2-exp.y: Migrate code that has nothing to do with
expression parsing into c-lang.c and m2-lang.c respectively. * c-lang.c, m2-lang.c: New files, code migrated from c-exp.y and m2-exp.y respectively. * c-lang.h, m2-lang.h: New files, internal interfaces between c-* and m2-* files respectively. * Makefile.in (SFILES_MAINDIR): Add c-lang.c, m2-lang.c. * Makefile.in (HFILES): Add c-lang.h, m2-lang.h. * Makefile.in (OBS): Add c-lang.o, m2-lang.o. * expression.h (struct block): Forward declaration for prototypes. * language.h (struct objfile): Forward declaration for prototypes. **** start-sanitize-chill **** * Makefile.in (SFILES_MAINDIR): Add ch-lang.c. * Makefile.in (HFILES): Add ch-lang.h. * Makefile.in (OBS): Add ch-lang.o. * ch-exp.y: Migrate code that has nothing to do with expression parsing into ch-lang.c. * ch-lang.c: New file, code migrated from c-exp.y. * ch-lang.h: New file, internal interface between ch-* files. **** end-sanitize-chill ****
This commit is contained in:
parent
160be0ded9
commit
22e3975901
@ -16,7 +16,7 @@
|
||||
Do-first:
|
||||
|
||||
if ( echo $* | grep keep\-chill > /dev/null ) ; then
|
||||
keep_these_too="ch-exp.y"
|
||||
keep_these_too="ch-exp.y ch-lang.c ch-lang.h"
|
||||
fi
|
||||
|
||||
# All files listed between the "Things-to-keep:" line and the
|
||||
@ -55,6 +55,8 @@ breakpoint.h
|
||||
buildsym.c
|
||||
buildsym.h
|
||||
c-exp.y
|
||||
c-lang.c
|
||||
c-lang.h
|
||||
call-cmds.h
|
||||
coffread.c
|
||||
command.c
|
||||
@ -129,6 +131,8 @@ kdb-start.c
|
||||
language.c
|
||||
language.h
|
||||
m2-exp.y
|
||||
m2-lang.c
|
||||
m2-lang.h
|
||||
m68k-pinsn.c
|
||||
m68k-stub.c
|
||||
m68k-tdep.c
|
||||
@ -391,6 +395,9 @@ else
|
||||
-e 's/ch-exp.y//g' \
|
||||
-e 's/ch-exp.tab.c//g' \
|
||||
-e 's/ch-exp.tab.o//g' \
|
||||
-e 's/ch-lang.h//g' \
|
||||
-e 's/ch-lang.c//g' \
|
||||
-e 's/ch-lang.o//g' \
|
||||
< Makefile.in > new
|
||||
if [ -n "${safe}" -a ! -f .Recover/Makefile.in ] ; then
|
||||
echo Caching Makefile.in in .Recover...
|
||||
|
@ -1,5 +1,26 @@
|
||||
Tue Dec 8 13:30:58 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* c-exp.y, m2-exp.y: Migrate code that has nothing to do with
|
||||
expression parsing into c-lang.c and m2-lang.c respectively.
|
||||
* c-lang.c, m2-lang.c: New files, code migrated from c-exp.y and
|
||||
m2-exp.y respectively.
|
||||
* c-lang.h, m2-lang.h: New files, internal interfaces between c-*
|
||||
and m2-* files respectively.
|
||||
* Makefile.in (SFILES_MAINDIR): Add c-lang.c, m2-lang.c.
|
||||
* Makefile.in (HFILES): Add c-lang.h, m2-lang.h.
|
||||
* Makefile.in (OBS): Add c-lang.o, m2-lang.o.
|
||||
* expression.h (struct block): Forward declaration for prototypes.
|
||||
* language.h (struct objfile): Forward declaration for prototypes.
|
||||
**** start-sanitize-chill ****
|
||||
* Makefile.in (SFILES_MAINDIR): Add ch-lang.c.
|
||||
* Makefile.in (HFILES): Add ch-lang.h.
|
||||
* Makefile.in (OBS): Add ch-lang.o.
|
||||
* ch-exp.y: Migrate code that has nothing to do with expression
|
||||
parsing into ch-lang.c.
|
||||
* ch-lang.c: New file, code migrated from c-exp.y.
|
||||
* ch-lang.h: New file, internal interface between ch-* files.
|
||||
**** end-sanitize-chill ****
|
||||
|
||||
Changes for Amiga Unix from rhealey@ub.d.umn.edu.
|
||||
* config/amix.mh (NAT_FILE): Add, set to nm-sysv4.h.
|
||||
* config/amix.mh (NATDEPFILES): Add.
|
||||
|
@ -201,7 +201,7 @@ SFILES_MAINDIR = \
|
||||
mem-break.c target.c \
|
||||
dbxread.c coffread.c elfread.c dwarfread.c xcoffread.c stabsread.c \
|
||||
ieee-float.c language.c parse.c buildsym.c objfiles.c \
|
||||
minsyms.c mipsread.c maint.c ch-exp.y
|
||||
minsyms.c mipsread.c maint.c ch-exp.y c-lang.c ch-lang.c m2-lang.c
|
||||
|
||||
# Source files in subdirectories (which will be handled separately by
|
||||
# 'make gdb.tar.Z').
|
||||
@ -270,7 +270,7 @@ HFILES= breakpoint.h buildsym.h call-cmds.h command.h defs.h \
|
||||
nm-sun2.h nm-sun3.h nm-sun386.h nm-sun4os4.h nm-trash.h \
|
||||
nm-ultra3.h nm-hppab.h nm-hppah.h nm-umax.h nm-sysv4.h \
|
||||
nm-apollo68b.h nm-apollo68v.h nm-vax.h nm-hp300bsd.h \
|
||||
nm-hp300hpux.h
|
||||
nm-hp300hpux.h c-lang.h ch-lang.h m2-lang.h
|
||||
|
||||
REMOTE_EXAMPLES = m68k-stub.c i386-stub.c sparc-stub.c rem-multi.shar
|
||||
|
||||
@ -310,7 +310,7 @@ OBS = version.o main.o blockframe.o breakpoint.o findvar.o stack.o source.o \
|
||||
ieee-float.o putenv.o parse.o language.o $(YYOBJ) \
|
||||
buildsym.o objfiles.o minsyms.o maint.o demangle.o \
|
||||
dbxread.o coffread.o elfread.o dwarfread.o xcoffread.o mipsread.o \
|
||||
stabsread.o core.o
|
||||
stabsread.o core.o c-lang.o ch-lang.o m2-lang.o
|
||||
|
||||
RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES)
|
||||
|
||||
|
511
gdb/c-exp.y
511
gdb/c-exp.y
@ -36,19 +36,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "frame.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "value.h"
|
||||
#include "language.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "c-lang.h"
|
||||
|
||||
/* These MUST be included in any grammar file!!!! Please choose unique names!
|
||||
Note that this are a combined list of variables that can be produced
|
||||
@ -1508,505 +1501,3 @@ yyerror (msg)
|
||||
{
|
||||
error (msg ? msg : "Invalid syntax in expression.");
|
||||
}
|
||||
|
||||
/* Print the character C on STREAM as part of the contents of a literal
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific. */
|
||||
|
||||
static void
|
||||
emit_char (c, stream, quoter)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
int quoter;
|
||||
{
|
||||
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\\' || c == quoter)
|
||||
{
|
||||
fputs_filtered ("\\", stream);
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs_filtered ("\\n", stream);
|
||||
break;
|
||||
case '\b':
|
||||
fputs_filtered ("\\b", stream);
|
||||
break;
|
||||
case '\t':
|
||||
fputs_filtered ("\\t", stream);
|
||||
break;
|
||||
case '\f':
|
||||
fputs_filtered ("\\f", stream);
|
||||
break;
|
||||
case '\r':
|
||||
fputs_filtered ("\\r", stream);
|
||||
break;
|
||||
case '\033':
|
||||
fputs_filtered ("\\e", stream);
|
||||
break;
|
||||
case '\007':
|
||||
fputs_filtered ("\\a", stream);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
c_printchar (c, stream)
|
||||
int c;
|
||||
FILE *stream;
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
emit_char (c, stream, '\'');
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
static void
|
||||
c_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_quotes = 0;
|
||||
int need_comma = 0;
|
||||
extern int inspect_it;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\", ", stream);
|
||||
else
|
||||
fputs_filtered ("\", ", stream);
|
||||
in_quotes = 0;
|
||||
}
|
||||
c_printchar (string[i], stream);
|
||||
fprintf_filtered (stream, " <repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_comma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
in_quotes = 1;
|
||||
}
|
||||
emit_char (string[i], stream, '"');
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
|
||||
if (force_ellipses || i < length)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* Table mapping opcodes into strings for printing operators
|
||||
and precedences of the operators. */
|
||||
|
||||
const static struct op_print c_op_print_tab[] =
|
||||
{
|
||||
{",", BINOP_COMMA, PREC_COMMA, 0},
|
||||
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
|
||||
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
|
||||
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
|
||||
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{">>", BINOP_RSH, PREC_SHIFT, 0},
|
||||
{"<<", BINOP_LSH, PREC_SHIFT, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"%", BINOP_REM, PREC_MUL, 0},
|
||||
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
|
||||
{"*", UNOP_IND, PREC_PREFIX, 0},
|
||||
{"&", UNOP_ADDR, PREC_PREFIX, 0},
|
||||
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
|
||||
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
|
||||
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
|
||||
/* C++ */
|
||||
{"::", BINOP_SCOPE, PREC_PREFIX, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* These variables point to the objects
|
||||
representing the predefined C data types. */
|
||||
|
||||
struct type *builtin_type_void;
|
||||
struct type *builtin_type_char;
|
||||
struct type *builtin_type_short;
|
||||
struct type *builtin_type_int;
|
||||
struct type *builtin_type_long;
|
||||
struct type *builtin_type_long_long;
|
||||
struct type *builtin_type_signed_char;
|
||||
struct type *builtin_type_unsigned_char;
|
||||
struct type *builtin_type_unsigned_short;
|
||||
struct type *builtin_type_unsigned_int;
|
||||
struct type *builtin_type_unsigned_long;
|
||||
struct type *builtin_type_unsigned_long_long;
|
||||
struct type *builtin_type_float;
|
||||
struct type *builtin_type_double;
|
||||
struct type *builtin_type_long_double;
|
||||
struct type *builtin_type_complex;
|
||||
struct type *builtin_type_double_complex;
|
||||
|
||||
struct type ** const (c_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_int,
|
||||
&builtin_type_long,
|
||||
&builtin_type_short,
|
||||
&builtin_type_char,
|
||||
&builtin_type_float,
|
||||
&builtin_type_double,
|
||||
&builtin_type_void,
|
||||
&builtin_type_long_long,
|
||||
&builtin_type_signed_char,
|
||||
&builtin_type_unsigned_char,
|
||||
&builtin_type_unsigned_short,
|
||||
&builtin_type_unsigned_int,
|
||||
&builtin_type_unsigned_long,
|
||||
&builtin_type_unsigned_long_long,
|
||||
&builtin_type_long_double,
|
||||
&builtin_type_complex,
|
||||
&builtin_type_double_complex,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn c_language_defn = {
|
||||
"c", /* Language name */
|
||||
language_c,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
c_parse,
|
||||
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*/
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%o", "0", "o", ""}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%x", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
const struct language_defn cplus_language_defn = {
|
||||
"c++", /* Language name */
|
||||
language_cplus,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
c_parse,
|
||||
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*/
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%o", "0", "o", ""}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%x", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_c_exp ()
|
||||
{
|
||||
builtin_type_void =
|
||||
init_type (TYPE_CODE_VOID, 1,
|
||||
0,
|
||||
"void", (struct objfile *) NULL);
|
||||
builtin_type_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"char", (struct objfile *) NULL);
|
||||
builtin_type_signed_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_SIGNED,
|
||||
"signed char", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned char", (struct objfile *) NULL);
|
||||
builtin_type_short =
|
||||
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"short", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_short =
|
||||
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned short", (struct objfile *) NULL);
|
||||
builtin_type_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"int", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned int", (struct objfile *) NULL);
|
||||
builtin_type_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned long", (struct objfile *) NULL);
|
||||
builtin_type_long_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long long", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_long_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned long long", (struct objfile *) NULL);
|
||||
builtin_type_float =
|
||||
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"float", (struct objfile *) NULL);
|
||||
builtin_type_double =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"double", (struct objfile *) NULL);
|
||||
builtin_type_long_double =
|
||||
init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long double", (struct objfile *) NULL);
|
||||
builtin_type_complex =
|
||||
init_type (TYPE_CODE_FLT, TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"complex", (struct objfile *) NULL);
|
||||
builtin_type_double_complex =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"double complex", (struct objfile *) NULL);
|
||||
|
||||
add_language (&c_language_defn);
|
||||
add_language (&cplus_language_defn);
|
||||
}
|
||||
|
528
gdb/c-lang.c
Normal file
528
gdb/c-lang.c
Normal file
@ -0,0 +1,528 @@
|
||||
/* C language support routines for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "c-lang.h"
|
||||
|
||||
/* Print the character C on STREAM as part of the contents of a literal
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific. */
|
||||
|
||||
static void
|
||||
emit_char (c, stream, quoter)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
int quoter;
|
||||
{
|
||||
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\\' || c == quoter)
|
||||
{
|
||||
fputs_filtered ("\\", stream);
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs_filtered ("\\n", stream);
|
||||
break;
|
||||
case '\b':
|
||||
fputs_filtered ("\\b", stream);
|
||||
break;
|
||||
case '\t':
|
||||
fputs_filtered ("\\t", stream);
|
||||
break;
|
||||
case '\f':
|
||||
fputs_filtered ("\\f", stream);
|
||||
break;
|
||||
case '\r':
|
||||
fputs_filtered ("\\r", stream);
|
||||
break;
|
||||
case '\033':
|
||||
fputs_filtered ("\\e", stream);
|
||||
break;
|
||||
case '\007':
|
||||
fputs_filtered ("\\a", stream);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
c_printchar (c, stream)
|
||||
int c;
|
||||
FILE *stream;
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
emit_char (c, stream, '\'');
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
static void
|
||||
c_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_quotes = 0;
|
||||
int need_comma = 0;
|
||||
extern int inspect_it;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\", ", stream);
|
||||
else
|
||||
fputs_filtered ("\", ", stream);
|
||||
in_quotes = 0;
|
||||
}
|
||||
c_printchar (string[i], stream);
|
||||
fprintf_filtered (stream, " <repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_comma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
in_quotes = 1;
|
||||
}
|
||||
emit_char (string[i], stream, '"');
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
|
||||
if (force_ellipses || i < length)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* Table mapping opcodes into strings for printing operators
|
||||
and precedences of the operators. */
|
||||
|
||||
const static struct op_print c_op_print_tab[] =
|
||||
{
|
||||
{",", BINOP_COMMA, PREC_COMMA, 0},
|
||||
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
|
||||
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
|
||||
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
|
||||
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{">>", BINOP_RSH, PREC_SHIFT, 0},
|
||||
{"<<", BINOP_LSH, PREC_SHIFT, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"%", BINOP_REM, PREC_MUL, 0},
|
||||
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
|
||||
{"*", UNOP_IND, PREC_PREFIX, 0},
|
||||
{"&", UNOP_ADDR, PREC_PREFIX, 0},
|
||||
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
|
||||
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
|
||||
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
|
||||
/* C++ */
|
||||
{"::", BINOP_SCOPE, PREC_PREFIX, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* These variables point to the objects
|
||||
representing the predefined C data types. */
|
||||
|
||||
struct type *builtin_type_void;
|
||||
struct type *builtin_type_char;
|
||||
struct type *builtin_type_short;
|
||||
struct type *builtin_type_int;
|
||||
struct type *builtin_type_long;
|
||||
struct type *builtin_type_long_long;
|
||||
struct type *builtin_type_signed_char;
|
||||
struct type *builtin_type_unsigned_char;
|
||||
struct type *builtin_type_unsigned_short;
|
||||
struct type *builtin_type_unsigned_int;
|
||||
struct type *builtin_type_unsigned_long;
|
||||
struct type *builtin_type_unsigned_long_long;
|
||||
struct type *builtin_type_float;
|
||||
struct type *builtin_type_double;
|
||||
struct type *builtin_type_long_double;
|
||||
struct type *builtin_type_complex;
|
||||
struct type *builtin_type_double_complex;
|
||||
|
||||
struct type ** const (c_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_int,
|
||||
&builtin_type_long,
|
||||
&builtin_type_short,
|
||||
&builtin_type_char,
|
||||
&builtin_type_float,
|
||||
&builtin_type_double,
|
||||
&builtin_type_void,
|
||||
&builtin_type_long_long,
|
||||
&builtin_type_signed_char,
|
||||
&builtin_type_unsigned_char,
|
||||
&builtin_type_unsigned_short,
|
||||
&builtin_type_unsigned_int,
|
||||
&builtin_type_unsigned_long,
|
||||
&builtin_type_unsigned_long_long,
|
||||
&builtin_type_long_double,
|
||||
&builtin_type_complex,
|
||||
&builtin_type_double_complex,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn c_language_defn = {
|
||||
"c", /* Language name */
|
||||
language_c,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
c_parse,
|
||||
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*/
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%o", "0", "o", ""}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%x", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
const struct language_defn cplus_language_defn = {
|
||||
"c++", /* Language name */
|
||||
language_cplus,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
c_parse,
|
||||
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*/
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%o", "0", "o", ""}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%x", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_c_exp ()
|
||||
{
|
||||
builtin_type_void =
|
||||
init_type (TYPE_CODE_VOID, 1,
|
||||
0,
|
||||
"void", (struct objfile *) NULL);
|
||||
builtin_type_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"char", (struct objfile *) NULL);
|
||||
builtin_type_signed_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_SIGNED,
|
||||
"signed char", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_char =
|
||||
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned char", (struct objfile *) NULL);
|
||||
builtin_type_short =
|
||||
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"short", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_short =
|
||||
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned short", (struct objfile *) NULL);
|
||||
builtin_type_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"int", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned int", (struct objfile *) NULL);
|
||||
builtin_type_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned long", (struct objfile *) NULL);
|
||||
builtin_type_long_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long long", (struct objfile *) NULL);
|
||||
builtin_type_unsigned_long_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"unsigned long long", (struct objfile *) NULL);
|
||||
builtin_type_float =
|
||||
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"float", (struct objfile *) NULL);
|
||||
builtin_type_double =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"double", (struct objfile *) NULL);
|
||||
builtin_type_long_double =
|
||||
init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"long double", (struct objfile *) NULL);
|
||||
builtin_type_complex =
|
||||
init_type (TYPE_CODE_FLT, TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"complex", (struct objfile *) NULL);
|
||||
builtin_type_double_complex =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"double complex", (struct objfile *) NULL);
|
||||
|
||||
add_language (&c_language_defn);
|
||||
add_language (&cplus_language_defn);
|
||||
}
|
24
gdb/c-lang.h
Normal file
24
gdb/c-lang.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* C language support definitions for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
extern int
|
||||
c_parse PARAMS ((void)); /* Defined in c-exp.y */
|
||||
|
||||
extern void
|
||||
c_error PARAMS ((char *)); /* Defined in c-exp.y */
|
294
gdb/ch-exp.y
294
gdb/ch-exp.y
@ -53,19 +53,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "frame.h"
|
||||
#include "expression.h"
|
||||
#include "language.h"
|
||||
#include "value.h"
|
||||
#include "parser-defs.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "ch-lang.h"
|
||||
|
||||
/* These MUST be included in any grammar file!!!! Please choose unique names!
|
||||
Note that this are a combined list of variables that can be produced
|
||||
@ -105,7 +98,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
static int
|
||||
yylex PARAMS ((void));
|
||||
|
||||
static void
|
||||
void
|
||||
yyerror PARAMS ((char *));
|
||||
|
||||
int
|
||||
@ -1287,7 +1280,7 @@ yylex ()
|
||||
return (ILLEGAL_TOKEN);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
yyerror (msg)
|
||||
char *msg; /* unused */
|
||||
{
|
||||
@ -1301,284 +1294,3 @@ yyerror (msg)
|
||||
error ("Invalid syntax in expression");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
chill_printchar (c, stream)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
{
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
fprintf_filtered (stream, "'%c'", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "C'%.2x'", (unsigned int) c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
|
||||
Note that gdb maintains the length of strings without counting the
|
||||
terminating null byte, while chill strings are typically written with
|
||||
an explicit null byte. So we always assume an implied null byte
|
||||
until gdb is able to maintain non-null terminated strings as well
|
||||
as null terminated strings (FIXME).
|
||||
*/
|
||||
|
||||
static void
|
||||
chill_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_literal_form = 0;
|
||||
int in_control_form = 0;
|
||||
int need_slashslash = 0;
|
||||
unsigned int c;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
chill_printchar ('\0', stream);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_slashslash)
|
||||
{
|
||||
fputs_filtered ("//", stream);
|
||||
need_slashslash = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
c = string[i];
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_control_form || in_literal_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_control_form = in_literal_form = 0;
|
||||
}
|
||||
chill_printchar (c, stream);
|
||||
fprintf_filtered (stream, "<repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_slashslash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (!in_literal_form)
|
||||
{
|
||||
if (in_control_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_control_form = 0;
|
||||
}
|
||||
fputs_filtered ("'", stream);
|
||||
in_literal_form = 1;
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_control_form)
|
||||
{
|
||||
if (in_literal_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_literal_form = 0;
|
||||
}
|
||||
fputs_filtered ("c'", stream);
|
||||
in_control_form = 1;
|
||||
}
|
||||
fprintf_filtered (stream, "%.2x", c);
|
||||
}
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_literal_form || in_control_form)
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
if (force_ellipses || (i < length))
|
||||
{
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
}
|
||||
|
||||
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, 1, TYPE_FLAG_UNSIGNED, "BOOL", objfile);
|
||||
break;
|
||||
case FT_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
|
||||
break;
|
||||
case FT_SIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_SIGNED, "BYTE", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
|
||||
break;
|
||||
case FT_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_SIGNED, "INT", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
|
||||
break;
|
||||
case FT_INTEGER: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_SIGNED, "LONG", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_INTEGER: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, "ULONG", objfile);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 4, 0, "REAL", objfile);
|
||||
break;
|
||||
case FT_DBL_PREC_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 8, 0, "LONG_REAL", objfile);
|
||||
break;
|
||||
}
|
||||
return (type);
|
||||
}
|
||||
|
||||
|
||||
/* Table of operators and their precedences for printing expressions. */
|
||||
|
||||
const static struct op_print chill_op_print_tab[] = {
|
||||
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"MOD", BINOP_REM, PREC_MUL, 0},
|
||||
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/* The built-in types of Chill. */
|
||||
|
||||
struct type *builtin_type_chill_bool;
|
||||
struct type *builtin_type_chill_char;
|
||||
struct type *builtin_type_chill_long;
|
||||
struct type *builtin_type_chill_ulong;
|
||||
struct type *builtin_type_chill_real;
|
||||
|
||||
struct type ** const (chill_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_chill_bool,
|
||||
&builtin_type_chill_char,
|
||||
&builtin_type_chill_long,
|
||||
&builtin_type_chill_ulong,
|
||||
&builtin_type_chill_real,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn chill_language_defn = {
|
||||
"chill",
|
||||
language_chill,
|
||||
chill_builtin_types,
|
||||
range_check_on,
|
||||
type_check_on,
|
||||
chill_parse, /* parser */
|
||||
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 */
|
||||
{"", "B'", "", ""}, /* Binary format info */
|
||||
{"O'%o", "O'", "o", ""}, /* Octal format info */
|
||||
{"D'%d", "D'", "d", ""}, /* Decimal format info */
|
||||
{"H'%x", "H'", "x", ""}, /* Hex format info */
|
||||
chill_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
/* Initialization for Chill */
|
||||
|
||||
void
|
||||
_initialize_chill_exp ()
|
||||
{
|
||||
builtin_type_chill_bool =
|
||||
init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"BOOL", (struct objfile *) NULL);
|
||||
builtin_type_chill_char =
|
||||
init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CHAR", (struct objfile *) NULL);
|
||||
builtin_type_chill_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_ulong =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"ULONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_real =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG_REAL", (struct objfile *) NULL);
|
||||
|
||||
add_language (&chill_language_defn);
|
||||
}
|
||||
|
306
gdb/ch-lang.c
Normal file
306
gdb/ch-lang.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* Chill language support routines for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "ch-lang.h"
|
||||
|
||||
static void
|
||||
chill_printchar (c, stream)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
{
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
fprintf_filtered (stream, "'%c'", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "C'%.2x'", (unsigned int) c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
|
||||
Note that gdb maintains the length of strings without counting the
|
||||
terminating null byte, while chill strings are typically written with
|
||||
an explicit null byte. So we always assume an implied null byte
|
||||
until gdb is able to maintain non-null terminated strings as well
|
||||
as null terminated strings (FIXME).
|
||||
*/
|
||||
|
||||
static void
|
||||
chill_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_literal_form = 0;
|
||||
int in_control_form = 0;
|
||||
int need_slashslash = 0;
|
||||
unsigned int c;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
chill_printchar ('\0', stream);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_slashslash)
|
||||
{
|
||||
fputs_filtered ("//", stream);
|
||||
need_slashslash = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
c = string[i];
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_control_form || in_literal_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_control_form = in_literal_form = 0;
|
||||
}
|
||||
chill_printchar (c, stream);
|
||||
fprintf_filtered (stream, "<repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_slashslash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (!in_literal_form)
|
||||
{
|
||||
if (in_control_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_control_form = 0;
|
||||
}
|
||||
fputs_filtered ("'", stream);
|
||||
in_literal_form = 1;
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_control_form)
|
||||
{
|
||||
if (in_literal_form)
|
||||
{
|
||||
fputs_filtered ("'//", stream);
|
||||
in_literal_form = 0;
|
||||
}
|
||||
fputs_filtered ("c'", stream);
|
||||
in_control_form = 1;
|
||||
}
|
||||
fprintf_filtered (stream, "%.2x", c);
|
||||
}
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_literal_form || in_control_form)
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
if (force_ellipses || (i < length))
|
||||
{
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
}
|
||||
|
||||
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, 1, TYPE_FLAG_UNSIGNED, "BOOL", objfile);
|
||||
break;
|
||||
case FT_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
|
||||
break;
|
||||
case FT_SIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_SIGNED, "BYTE", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
|
||||
break;
|
||||
case FT_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_SIGNED, "INT", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
|
||||
break;
|
||||
case FT_INTEGER: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_SIGNED, "LONG", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_INTEGER: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, "ULONG", objfile);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 4, 0, "REAL", objfile);
|
||||
break;
|
||||
case FT_DBL_PREC_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 8, 0, "LONG_REAL", objfile);
|
||||
break;
|
||||
}
|
||||
return (type);
|
||||
}
|
||||
|
||||
|
||||
/* Table of operators and their precedences for printing expressions. */
|
||||
|
||||
const static struct op_print chill_op_print_tab[] = {
|
||||
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"MOD", BINOP_REM, PREC_MUL, 0},
|
||||
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/* The built-in types of Chill. */
|
||||
|
||||
struct type *builtin_type_chill_bool;
|
||||
struct type *builtin_type_chill_char;
|
||||
struct type *builtin_type_chill_long;
|
||||
struct type *builtin_type_chill_ulong;
|
||||
struct type *builtin_type_chill_real;
|
||||
|
||||
struct type ** const (chill_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_chill_bool,
|
||||
&builtin_type_chill_char,
|
||||
&builtin_type_chill_long,
|
||||
&builtin_type_chill_ulong,
|
||||
&builtin_type_chill_real,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn chill_language_defn = {
|
||||
"chill",
|
||||
language_chill,
|
||||
chill_builtin_types,
|
||||
range_check_on,
|
||||
type_check_on,
|
||||
chill_parse, /* parser */
|
||||
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 */
|
||||
{"", "B'", "", ""}, /* Binary format info */
|
||||
{"O'%o", "O'", "o", ""}, /* Octal format info */
|
||||
{"D'%d", "D'", "d", ""}, /* Decimal format info */
|
||||
{"H'%x", "H'", "x", ""}, /* Hex format info */
|
||||
chill_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
/* Initialization for Chill */
|
||||
|
||||
void
|
||||
_initialize_chill_exp ()
|
||||
{
|
||||
builtin_type_chill_bool =
|
||||
init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"BOOL", (struct objfile *) NULL);
|
||||
builtin_type_chill_char =
|
||||
init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CHAR", (struct objfile *) NULL);
|
||||
builtin_type_chill_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_ulong =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"ULONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_real =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG_REAL", (struct objfile *) NULL);
|
||||
|
||||
add_language (&chill_language_defn);
|
||||
}
|
24
gdb/ch-lang.h
Normal file
24
gdb/ch-lang.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Chill language support definitions for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
extern int
|
||||
chill_parse PARAMS ((void)); /* Defined in ch-exp.y */
|
||||
|
||||
extern void
|
||||
chill_error PARAMS ((char *)); /* Defined in ch-exp.y */
|
@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef __STDC__ /* Forward decls for prototypes */
|
||||
struct value;
|
||||
struct objfile;
|
||||
/* enum exp_opcode; ANSI's `wisdom' didn't include forward enum decls. */
|
||||
#endif
|
||||
|
||||
|
443
gdb/m2-exp.y
443
gdb/m2-exp.y
@ -38,19 +38,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "frame.h"
|
||||
#include "expression.h"
|
||||
#include "language.h"
|
||||
#include "value.h"
|
||||
#include "parser-defs.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "m2-lang.h"
|
||||
|
||||
/* These MUST be included in any grammar file!!!! Please choose unique names!
|
||||
Note that this are a combined list of variables that can be produced
|
||||
@ -98,7 +91,7 @@ parse_number PARAMS ((int));
|
||||
static int
|
||||
yylex PARAMS ((void));
|
||||
|
||||
static void
|
||||
void
|
||||
yyerror PARAMS ((char *));
|
||||
|
||||
int
|
||||
@ -1164,7 +1157,7 @@ make_qualname(mod,ident)
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static void
|
||||
void
|
||||
yyerror(msg)
|
||||
char *msg; /* unused */
|
||||
{
|
||||
@ -1175,433 +1168,3 @@ yyerror(msg)
|
||||
error("Invalid syntax in expression");
|
||||
}
|
||||
|
||||
|
||||
/* Print the character C on STREAM as part of the contents of a literal
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific.
|
||||
FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version.
|
||||
*/
|
||||
|
||||
static void
|
||||
emit_char (c, stream, quoter)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
int quoter;
|
||||
{
|
||||
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\\' || c == quoter)
|
||||
{
|
||||
fputs_filtered ("\\", stream);
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs_filtered ("\\n", stream);
|
||||
break;
|
||||
case '\b':
|
||||
fputs_filtered ("\\b", stream);
|
||||
break;
|
||||
case '\t':
|
||||
fputs_filtered ("\\t", stream);
|
||||
break;
|
||||
case '\f':
|
||||
fputs_filtered ("\\f", stream);
|
||||
break;
|
||||
case '\r':
|
||||
fputs_filtered ("\\r", stream);
|
||||
break;
|
||||
case '\033':
|
||||
fputs_filtered ("\\e", stream);
|
||||
break;
|
||||
case '\007':
|
||||
fputs_filtered ("\\a", stream);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version. */
|
||||
|
||||
static void
|
||||
m2_printchar (c, stream)
|
||||
int c;
|
||||
FILE *stream;
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
emit_char (c, stream, '\'');
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
|
||||
FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version. */
|
||||
|
||||
static void
|
||||
m2_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_quotes = 0;
|
||||
int need_comma = 0;
|
||||
extern int inspect_it;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\", ", stream);
|
||||
else
|
||||
fputs_filtered ("\", ", stream);
|
||||
in_quotes = 0;
|
||||
}
|
||||
m2_printchar (string[i], stream);
|
||||
fprintf_filtered (stream, " <repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_comma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
in_quotes = 1;
|
||||
}
|
||||
emit_char (string[i], stream, '"');
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
|
||||
if (force_ellipses || i < length)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* Table of operators and their precedences for printing expressions. */
|
||||
|
||||
const static struct op_print m2_op_print_tab[] = {
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"+", UNOP_PLUS, PREC_PREFIX, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"DIV", BINOP_INTDIV, PREC_MUL, 0},
|
||||
{"MOD", BINOP_REM, PREC_MUL, 0},
|
||||
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{"^", UNOP_IND, PREC_PREFIX, 0},
|
||||
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* The built-in types of Modula-2. */
|
||||
|
||||
struct type *builtin_type_m2_char;
|
||||
struct type *builtin_type_m2_int;
|
||||
struct type *builtin_type_m2_card;
|
||||
struct type *builtin_type_m2_real;
|
||||
struct type *builtin_type_m2_bool;
|
||||
|
||||
struct type ** const (m2_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_m2_char,
|
||||
&builtin_type_m2_int,
|
||||
&builtin_type_m2_card,
|
||||
&builtin_type_m2_real,
|
||||
&builtin_type_m2_bool,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn m2_language_defn = {
|
||||
"modula-2",
|
||||
language_m2,
|
||||
m2_builtin_types,
|
||||
range_check_on,
|
||||
type_check_on,
|
||||
m2_parse, /* parser */
|
||||
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 */
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"%oB", "", "o", "B"}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0%XH", "0", "X", "H"}, /* Hex format info */
|
||||
m2_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
/* Initialization for Modula-2 */
|
||||
|
||||
void
|
||||
_initialize_m2_exp ()
|
||||
{
|
||||
/* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
|
||||
builtin_type_m2_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"INTEGER", (struct objfile *) NULL);
|
||||
builtin_type_m2_card =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CARDINAL", (struct objfile *) NULL);
|
||||
builtin_type_m2_real =
|
||||
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"REAL", (struct objfile *) NULL);
|
||||
builtin_type_m2_char =
|
||||
init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CHAR", (struct objfile *) NULL);
|
||||
builtin_type_m2_bool =
|
||||
init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"BOOLEAN", (struct objfile *) NULL);
|
||||
|
||||
TYPE_NFIELDS(builtin_type_m2_bool) = 2;
|
||||
TYPE_FIELDS(builtin_type_m2_bool) =
|
||||
(struct field *) malloc (sizeof (struct field) * 2);
|
||||
TYPE_FIELD_BITPOS(builtin_type_m2_bool,0) = 0;
|
||||
TYPE_FIELD_NAME(builtin_type_m2_bool,0) = (char *)malloc(6);
|
||||
strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,0),"FALSE");
|
||||
TYPE_FIELD_BITPOS(builtin_type_m2_bool,1) = 1;
|
||||
TYPE_FIELD_NAME(builtin_type_m2_bool,1) = (char *)malloc(5);
|
||||
strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,1),"TRUE");
|
||||
|
||||
add_language (&m2_language_defn);
|
||||
}
|
||||
|
456
gdb/m2-lang.c
Normal file
456
gdb/m2-lang.c
Normal file
@ -0,0 +1,456 @@
|
||||
/* Modula 2 language support routines for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "m2-lang.h"
|
||||
|
||||
/* Print the character C on STREAM as part of the contents of a literal
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific.
|
||||
FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version.
|
||||
*/
|
||||
|
||||
static void
|
||||
emit_char (c, stream, quoter)
|
||||
register int c;
|
||||
FILE *stream;
|
||||
int quoter;
|
||||
{
|
||||
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\\' || c == quoter)
|
||||
{
|
||||
fputs_filtered ("\\", stream);
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs_filtered ("\\n", stream);
|
||||
break;
|
||||
case '\b':
|
||||
fputs_filtered ("\\b", stream);
|
||||
break;
|
||||
case '\t':
|
||||
fputs_filtered ("\\t", stream);
|
||||
break;
|
||||
case '\f':
|
||||
fputs_filtered ("\\f", stream);
|
||||
break;
|
||||
case '\r':
|
||||
fputs_filtered ("\\r", stream);
|
||||
break;
|
||||
case '\033':
|
||||
fputs_filtered ("\\e", stream);
|
||||
break;
|
||||
case '\007':
|
||||
fputs_filtered ("\\a", stream);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version. */
|
||||
|
||||
static void
|
||||
m2_printchar (c, stream)
|
||||
int c;
|
||||
FILE *stream;
|
||||
{
|
||||
fputs_filtered ("'", stream);
|
||||
emit_char (c, stream, '\'');
|
||||
fputs_filtered ("'", stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
|
||||
FIXME: This is a copy of the same function from c-exp.y. It should
|
||||
be replaced with a true Modula version. */
|
||||
|
||||
static void
|
||||
m2_printstr (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_quotes = 0;
|
||||
int need_comma = 0;
|
||||
extern int inspect_it;
|
||||
extern int repeat_count_threshold;
|
||||
extern int print_max;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\", ", stream);
|
||||
else
|
||||
fputs_filtered ("\", ", stream);
|
||||
in_quotes = 0;
|
||||
}
|
||||
m2_printchar (string[i], stream);
|
||||
fprintf_filtered (stream, " <repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_comma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
in_quotes = 1;
|
||||
}
|
||||
emit_char (string[i], stream, '"');
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
|
||||
if (force_ellipses || i < length)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* Table of operators and their precedences for printing expressions. */
|
||||
|
||||
const static struct op_print m2_op_print_tab[] = {
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"+", UNOP_PLUS, PREC_PREFIX, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"DIV", BINOP_INTDIV, PREC_MUL, 0},
|
||||
{"MOD", BINOP_REM, PREC_MUL, 0},
|
||||
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{"^", UNOP_IND, PREC_PREFIX, 0},
|
||||
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* The built-in types of Modula-2. */
|
||||
|
||||
struct type *builtin_type_m2_char;
|
||||
struct type *builtin_type_m2_int;
|
||||
struct type *builtin_type_m2_card;
|
||||
struct type *builtin_type_m2_real;
|
||||
struct type *builtin_type_m2_bool;
|
||||
|
||||
struct type ** const (m2_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_m2_char,
|
||||
&builtin_type_m2_int,
|
||||
&builtin_type_m2_card,
|
||||
&builtin_type_m2_real,
|
||||
&builtin_type_m2_bool,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn m2_language_defn = {
|
||||
"modula-2",
|
||||
language_m2,
|
||||
m2_builtin_types,
|
||||
range_check_on,
|
||||
type_check_on,
|
||||
m2_parse, /* parser */
|
||||
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 */
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"%oB", "", "o", "B"}, /* Octal format info */
|
||||
{"%d", "", "d", ""}, /* Decimal format info */
|
||||
{"0%XH", "0", "X", "H"}, /* Hex format info */
|
||||
m2_op_print_tab, /* expression operators for printing */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
/* Initialization for Modula-2 */
|
||||
|
||||
void
|
||||
_initialize_m2_exp ()
|
||||
{
|
||||
/* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
|
||||
builtin_type_m2_int =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"INTEGER", (struct objfile *) NULL);
|
||||
builtin_type_m2_card =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CARDINAL", (struct objfile *) NULL);
|
||||
builtin_type_m2_real =
|
||||
init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"REAL", (struct objfile *) NULL);
|
||||
builtin_type_m2_char =
|
||||
init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CHAR", (struct objfile *) NULL);
|
||||
builtin_type_m2_bool =
|
||||
init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"BOOLEAN", (struct objfile *) NULL);
|
||||
|
||||
TYPE_NFIELDS(builtin_type_m2_bool) = 2;
|
||||
TYPE_FIELDS(builtin_type_m2_bool) =
|
||||
(struct field *) malloc (sizeof (struct field) * 2);
|
||||
TYPE_FIELD_BITPOS(builtin_type_m2_bool,0) = 0;
|
||||
TYPE_FIELD_NAME(builtin_type_m2_bool,0) = (char *)malloc(6);
|
||||
strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,0),"FALSE");
|
||||
TYPE_FIELD_BITPOS(builtin_type_m2_bool,1) = 1;
|
||||
TYPE_FIELD_NAME(builtin_type_m2_bool,1) = (char *)malloc(5);
|
||||
strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,1),"TRUE");
|
||||
|
||||
add_language (&m2_language_defn);
|
||||
}
|
24
gdb/m2-lang.h
Normal file
24
gdb/m2-lang.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Modula 2 language support definitions for GDB, the GNU debugger.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
extern int
|
||||
m2_parse PARAMS ((void)); /* Defined in m2-exp.y */
|
||||
|
||||
extern void
|
||||
m2_error PARAMS ((char *)); /* Defined in m2-exp.y */
|
Loading…
x
Reference in New Issue
Block a user