GDB (API)
/home/stan/gdb/src/gdb/p-lang.c
Go to the documentation of this file.
00001 /* Pascal language support routines for GDB, the GNU debugger.
00002 
00003    Copyright (C) 2000-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 /* This file is derived from c-lang.c */
00021 
00022 #include "defs.h"
00023 #include "gdb_string.h"
00024 #include "symtab.h"
00025 #include "gdbtypes.h"
00026 #include "expression.h"
00027 #include "parser-defs.h"
00028 #include "language.h"
00029 #include "p-lang.h"
00030 #include "valprint.h"
00031 #include "value.h"
00032 #include <ctype.h>
00033 
00034 extern void _initialize_pascal_language (void);
00035 
00036 
00037 /* All GPC versions until now (2007-09-27) also define a symbol called
00038    '_p_initialize'.  Check for the presence of this symbol first.  */
00039 static const char GPC_P_INITIALIZE[] = "_p_initialize";
00040 
00041 /* The name of the symbol that GPC uses as the name of the main
00042    procedure (since version 20050212).  */
00043 static const char GPC_MAIN_PROGRAM_NAME_1[] = "_p__M0_main_program";
00044 
00045 /* Older versions of GPC (versions older than 20050212) were using
00046    a different name for the main procedure.  */
00047 static const char GPC_MAIN_PROGRAM_NAME_2[] = "pascal_main_program";
00048 
00049 /* Function returning the special symbol name used
00050    by GPC for the main procedure in the main program
00051    if it is found in minimal symbol list.
00052    This function tries to find minimal symbols generated by GPC
00053    so that it finds the even if the program was compiled
00054    without debugging information.
00055    According to information supplied by Waldeck Hebisch,
00056    this should work for all versions posterior to June 2000.  */
00057 
00058 const char *
00059 pascal_main_name (void)
00060 {
00061   struct minimal_symbol *msym;
00062 
00063   msym = lookup_minimal_symbol (GPC_P_INITIALIZE, NULL, NULL);
00064 
00065   /*  If '_p_initialize' was not found, the main program is likely not
00066      written in Pascal.  */
00067   if (msym == NULL)
00068     return NULL;
00069 
00070   msym = lookup_minimal_symbol (GPC_MAIN_PROGRAM_NAME_1, NULL, NULL);
00071   if (msym != NULL)
00072     {
00073       return GPC_MAIN_PROGRAM_NAME_1;
00074     }
00075 
00076   msym = lookup_minimal_symbol (GPC_MAIN_PROGRAM_NAME_2, NULL, NULL);
00077   if (msym != NULL)
00078     {
00079       return GPC_MAIN_PROGRAM_NAME_2;
00080     }
00081 
00082   /*  No known entry procedure found, the main program is probably
00083       not compiled with GPC.  */
00084   return NULL;
00085 }
00086 
00087 /* Determines if type TYPE is a pascal string type.
00088    Returns a positive value if the type is a known pascal string type.
00089    This function is used by p-valprint.c code to allow better string display.
00090    If it is a pascal string type, then it also sets info needed
00091    to get the length and the data of the string
00092    length_pos, length_size and string_pos are given in bytes.
00093    char_size gives the element size in bytes.
00094    FIXME: if the position or the size of these fields
00095    are not multiple of TARGET_CHAR_BIT then the results are wrong
00096    but this does not happen for Free Pascal nor for GPC.  */
00097 int
00098 is_pascal_string_type (struct type *type,int *length_pos,
00099                        int *length_size, int *string_pos,
00100                        struct type **char_type,
00101                        const char **arrayname)
00102 {
00103   if (type != NULL && TYPE_CODE (type) == TYPE_CODE_STRUCT)
00104     {
00105       /* Old Borland type pascal strings from Free Pascal Compiler.  */
00106       /* Two fields: length and st.  */
00107       if (TYPE_NFIELDS (type) == 2
00108           && TYPE_FIELD_NAME (type, 0)
00109           && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0
00110           && TYPE_FIELD_NAME (type, 1)
00111           && strcmp (TYPE_FIELD_NAME (type, 1), "st") == 0)
00112         {
00113           if (length_pos)
00114             *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT;
00115           if (length_size)
00116             *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
00117           if (string_pos)
00118             *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
00119           if (char_type)
00120             *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1));
00121           if (arrayname)
00122             *arrayname = TYPE_FIELD_NAME (type, 1);
00123          return 2;
00124         };
00125       /* GNU pascal strings.  */
00126       /* Three fields: Capacity, length and schema$ or _p_schema.  */
00127       if (TYPE_NFIELDS (type) == 3
00128           && TYPE_FIELD_NAME (type, 0)
00129           && strcmp (TYPE_FIELD_NAME (type, 0), "Capacity") == 0
00130           && TYPE_FIELD_NAME (type, 1)
00131           && strcmp (TYPE_FIELD_NAME (type, 1), "length") == 0)
00132         {
00133           if (length_pos)
00134             *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
00135           if (length_size)
00136             *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 1));
00137           if (string_pos)
00138             *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT;
00139           /* FIXME: how can I detect wide chars in GPC ??  */
00140           if (char_type)
00141             {
00142               *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 2));
00143 
00144               if (TYPE_CODE (*char_type) == TYPE_CODE_ARRAY)
00145                 *char_type = TYPE_TARGET_TYPE (*char_type);
00146             }
00147           if (arrayname)
00148             *arrayname = TYPE_FIELD_NAME (type, 2);
00149          return 3;
00150         };
00151     }
00152   return 0;
00153 }
00154 
00155 static void pascal_one_char (int, struct ui_file *, int *);
00156 
00157 /* Print the character C on STREAM as part of the contents of a literal
00158    string.
00159    In_quotes is reset to 0 if a char is written with #4 notation.  */
00160 
00161 static void
00162 pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
00163 {
00164   if (c == '\'' || ((unsigned int) c <= 0xff && (PRINT_LITERAL_FORM (c))))
00165     {
00166       if (!(*in_quotes))
00167         fputs_filtered ("'", stream);
00168       *in_quotes = 1;
00169       if (c == '\'')
00170         {
00171           fputs_filtered ("''", stream);
00172         }
00173       else
00174         fprintf_filtered (stream, "%c", c);
00175     }
00176   else
00177     {
00178       if (*in_quotes)
00179         fputs_filtered ("'", stream);
00180       *in_quotes = 0;
00181       fprintf_filtered (stream, "#%d", (unsigned int) c);
00182     }
00183 }
00184 
00185 static void pascal_emit_char (int c, struct type *type,
00186                               struct ui_file *stream, int quoter);
00187 
00188 /* Print the character C on STREAM as part of the contents of a literal
00189    string whose delimiter is QUOTER.  Note that that format for printing
00190    characters and strings is language specific.  */
00191 
00192 static void
00193 pascal_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
00194 {
00195   int in_quotes = 0;
00196 
00197   pascal_one_char (c, stream, &in_quotes);
00198   if (in_quotes)
00199     fputs_filtered ("'", stream);
00200 }
00201 
00202 void
00203 pascal_printchar (int c, struct type *type, struct ui_file *stream)
00204 {
00205   int in_quotes = 0;
00206 
00207   pascal_one_char (c, stream, &in_quotes);
00208   if (in_quotes)
00209     fputs_filtered ("'", stream);
00210 }
00211 
00212 /* Print the character string STRING, printing at most LENGTH characters.
00213    Printing stops early if the number hits print_max; repeat counts
00214    are printed as appropriate.  Print ellipses at the end if we
00215    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */
00216 
00217 void
00218 pascal_printstr (struct ui_file *stream, struct type *type,
00219                  const gdb_byte *string, unsigned int length,
00220                  const char *encoding, int force_ellipses,
00221                  const struct value_print_options *options)
00222 {
00223   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
00224   unsigned int i;
00225   unsigned int things_printed = 0;
00226   int in_quotes = 0;
00227   int need_comma = 0;
00228   int width;
00229 
00230   /* Preserve TYPE's original type, just set its LENGTH.  */
00231   check_typedef (type);
00232   width = TYPE_LENGTH (type);
00233 
00234   /* If the string was not truncated due to `set print elements', and
00235      the last byte of it is a null, we don't print that, in traditional C
00236      style.  */
00237   if ((!force_ellipses) && length > 0
00238         && extract_unsigned_integer (string + (length - 1) * width, width,
00239                                      byte_order) == 0)
00240     length--;
00241 
00242   if (length == 0)
00243     {
00244       fputs_filtered ("''", stream);
00245       return;
00246     }
00247 
00248   for (i = 0; i < length && things_printed < options->print_max; ++i)
00249     {
00250       /* Position of the character we are examining
00251          to see whether it is repeated.  */
00252       unsigned int rep1;
00253       /* Number of repetitions we have detected so far.  */
00254       unsigned int reps;
00255       unsigned long int current_char;
00256 
00257       QUIT;
00258 
00259       if (need_comma)
00260         {
00261           fputs_filtered (", ", stream);
00262           need_comma = 0;
00263         }
00264 
00265       current_char = extract_unsigned_integer (string + i * width, width,
00266                                                byte_order);
00267 
00268       rep1 = i + 1;
00269       reps = 1;
00270       while (rep1 < length
00271              && extract_unsigned_integer (string + rep1 * width, width,
00272                                           byte_order) == current_char)
00273         {
00274           ++rep1;
00275           ++reps;
00276         }
00277 
00278       if (reps > options->repeat_count_threshold)
00279         {
00280           if (in_quotes)
00281             {
00282               fputs_filtered ("', ", stream);
00283               in_quotes = 0;
00284             }
00285           pascal_printchar (current_char, type, stream);
00286           fprintf_filtered (stream, " <repeats %u times>", reps);
00287           i = rep1 - 1;
00288           things_printed += options->repeat_count_threshold;
00289           need_comma = 1;
00290         }
00291       else
00292         {
00293           if ((!in_quotes) && (PRINT_LITERAL_FORM (current_char)))
00294             {
00295               fputs_filtered ("'", stream);
00296               in_quotes = 1;
00297             }
00298           pascal_one_char (current_char, stream, &in_quotes);
00299           ++things_printed;
00300         }
00301     }
00302 
00303   /* Terminate the quotes if necessary.  */
00304   if (in_quotes)
00305     fputs_filtered ("'", stream);
00306 
00307   if (force_ellipses || i < length)
00308     fputs_filtered ("...", stream);
00309 }
00310 
00311 
00312 /* Table mapping opcodes into strings for printing operators
00313    and precedences of the operators.  */
00314 
00315 const struct op_print pascal_op_print_tab[] =
00316 {
00317   {",", BINOP_COMMA, PREC_COMMA, 0},
00318   {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
00319   {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
00320   {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
00321   {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
00322   {"=", BINOP_EQUAL, PREC_EQUAL, 0},
00323   {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
00324   {"<=", BINOP_LEQ, PREC_ORDER, 0},
00325   {">=", BINOP_GEQ, PREC_ORDER, 0},
00326   {">", BINOP_GTR, PREC_ORDER, 0},
00327   {"<", BINOP_LESS, PREC_ORDER, 0},
00328   {"shr", BINOP_RSH, PREC_SHIFT, 0},
00329   {"shl", BINOP_LSH, PREC_SHIFT, 0},
00330   {"+", BINOP_ADD, PREC_ADD, 0},
00331   {"-", BINOP_SUB, PREC_ADD, 0},
00332   {"*", BINOP_MUL, PREC_MUL, 0},
00333   {"/", BINOP_DIV, PREC_MUL, 0},
00334   {"div", BINOP_INTDIV, PREC_MUL, 0},
00335   {"mod", BINOP_REM, PREC_MUL, 0},
00336   {"@", BINOP_REPEAT, PREC_REPEAT, 0},
00337   {"-", UNOP_NEG, PREC_PREFIX, 0},
00338   {"not", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
00339   {"^", UNOP_IND, PREC_SUFFIX, 1},
00340   {"@", UNOP_ADDR, PREC_PREFIX, 0},
00341   {"sizeof", UNOP_SIZEOF, PREC_PREFIX, 0},
00342   {NULL, 0, 0, 0}
00343 };
00344 
00345 enum pascal_primitive_types {
00346   pascal_primitive_type_int,
00347   pascal_primitive_type_long,
00348   pascal_primitive_type_short,
00349   pascal_primitive_type_char,
00350   pascal_primitive_type_float,
00351   pascal_primitive_type_double,
00352   pascal_primitive_type_void,
00353   pascal_primitive_type_long_long,
00354   pascal_primitive_type_signed_char,
00355   pascal_primitive_type_unsigned_char,
00356   pascal_primitive_type_unsigned_short,
00357   pascal_primitive_type_unsigned_int,
00358   pascal_primitive_type_unsigned_long,
00359   pascal_primitive_type_unsigned_long_long,
00360   pascal_primitive_type_long_double,
00361   pascal_primitive_type_complex,
00362   pascal_primitive_type_double_complex,
00363   nr_pascal_primitive_types
00364 };
00365 
00366 static void
00367 pascal_language_arch_info (struct gdbarch *gdbarch,
00368                            struct language_arch_info *lai)
00369 {
00370   const struct builtin_type *builtin = builtin_type (gdbarch);
00371 
00372   lai->string_char_type = builtin->builtin_char;
00373   lai->primitive_type_vector
00374     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_pascal_primitive_types + 1,
00375                               struct type *);
00376   lai->primitive_type_vector [pascal_primitive_type_int]
00377     = builtin->builtin_int;
00378   lai->primitive_type_vector [pascal_primitive_type_long]
00379     = builtin->builtin_long;
00380   lai->primitive_type_vector [pascal_primitive_type_short]
00381     = builtin->builtin_short;
00382   lai->primitive_type_vector [pascal_primitive_type_char]
00383     = builtin->builtin_char;
00384   lai->primitive_type_vector [pascal_primitive_type_float]
00385     = builtin->builtin_float;
00386   lai->primitive_type_vector [pascal_primitive_type_double]
00387     = builtin->builtin_double;
00388   lai->primitive_type_vector [pascal_primitive_type_void]
00389     = builtin->builtin_void;
00390   lai->primitive_type_vector [pascal_primitive_type_long_long]
00391     = builtin->builtin_long_long;
00392   lai->primitive_type_vector [pascal_primitive_type_signed_char]
00393     = builtin->builtin_signed_char;
00394   lai->primitive_type_vector [pascal_primitive_type_unsigned_char]
00395     = builtin->builtin_unsigned_char;
00396   lai->primitive_type_vector [pascal_primitive_type_unsigned_short]
00397     = builtin->builtin_unsigned_short;
00398   lai->primitive_type_vector [pascal_primitive_type_unsigned_int]
00399     = builtin->builtin_unsigned_int;
00400   lai->primitive_type_vector [pascal_primitive_type_unsigned_long]
00401     = builtin->builtin_unsigned_long;
00402   lai->primitive_type_vector [pascal_primitive_type_unsigned_long_long]
00403     = builtin->builtin_unsigned_long_long;
00404   lai->primitive_type_vector [pascal_primitive_type_long_double]
00405     = builtin->builtin_long_double;
00406   lai->primitive_type_vector [pascal_primitive_type_complex]
00407     = builtin->builtin_complex;
00408   lai->primitive_type_vector [pascal_primitive_type_double_complex]
00409     = builtin->builtin_double_complex;
00410 
00411   lai->bool_type_symbol = "boolean";
00412   lai->bool_type_default = builtin->builtin_bool;
00413 }
00414 
00415 const struct language_defn pascal_language_defn =
00416 {
00417   "pascal",                     /* Language name */
00418   language_pascal,
00419   range_check_on,
00420   case_sensitive_on,
00421   array_row_major,
00422   macro_expansion_no,
00423   &exp_descriptor_standard,
00424   pascal_parse,
00425   pascal_error,
00426   null_post_parser,
00427   pascal_printchar,             /* Print a character constant */
00428   pascal_printstr,              /* Function to print string constant */
00429   pascal_emit_char,             /* Print a single char */
00430   pascal_print_type,            /* Print a type using appropriate syntax */
00431   pascal_print_typedef,         /* Print a typedef using appropriate syntax */
00432   pascal_val_print,             /* Print a value using appropriate syntax */
00433   pascal_value_print,           /* Print a top-level value */
00434   default_read_var_value,       /* la_read_var_value */
00435   NULL,                         /* Language specific skip_trampoline */
00436   "this",                       /* name_of_this */
00437   basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
00438   basic_lookup_transparent_type,/* lookup_transparent_type */
00439   NULL,                         /* Language specific symbol demangler */
00440   NULL,                         /* Language specific class_name_from_physname */
00441   pascal_op_print_tab,          /* expression operators for printing */
00442   1,                            /* c-style arrays */
00443   0,                            /* String lower bound */
00444   default_word_break_characters,
00445   default_make_symbol_completion_list,
00446   pascal_language_arch_info,
00447   default_print_array_index,
00448   default_pass_by_reference,
00449   default_get_string,
00450   NULL,                         /* la_get_symbol_name_cmp */
00451   iterate_over_symbols,
00452   LANG_MAGIC
00453 };
00454 
00455 void
00456 _initialize_pascal_language (void)
00457 {
00458   add_language (&pascal_language_defn);
00459 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines