gdb/
[deliverable/binutils-gdb.git] / gdb / c-lang.c
index e3151b9345dfa249bf060a7b4794937fb45c8e21..8b5410f8a6b6eb0ef8fdbbc6b0345e4e3c01016b 100644 (file)
@@ -1,7 +1,7 @@
 /* C language support routines for GDB, the GNU debugger.
 
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003,
-   2004, 2005, 2007 Free Software Foundation, Inc.
+   2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -86,7 +86,8 @@ c_printchar (int c, struct ui_file *stream)
 
 void
 c_printstr (struct ui_file *stream, const gdb_byte *string,
-           unsigned int length, int width, int force_ellipses)
+           unsigned int length, int width, int force_ellipses,
+           const struct value_print_options *options)
 {
   unsigned int i;
   unsigned int things_printed = 0;
@@ -108,7 +109,7 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
       return;
     }
 
-  for (i = 0; i < length && things_printed < print_max; ++i)
+  for (i = 0; i < length && things_printed < options->print_max; ++i)
     {
       /* Position of the character we are examining
          to see whether it is repeated.  */
@@ -137,11 +138,11 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
          ++reps;
        }
 
-      if (reps > repeat_count_threshold)
+      if (reps > options->repeat_count_threshold)
        {
          if (in_quotes)
            {
-             if (inspect_it)
+             if (options->inspect_it)
                fputs_filtered ("\\\", ", stream);
              else
                fputs_filtered ("\", ", stream);
@@ -150,14 +151,14 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
          LA_PRINT_CHAR (current_char, stream);
          fprintf_filtered (stream, _(" <repeats %u times>"), reps);
          i = rep1 - 1;
-         things_printed += repeat_count_threshold;
+         things_printed += options->repeat_count_threshold;
          need_comma = 1;
        }
       else
        {
          if (!in_quotes)
            {
-             if (inspect_it)
+             if (options->inspect_it)
                fputs_filtered ("\\\"", stream);
              else
                fputs_filtered ("\"", stream);
@@ -171,7 +172,7 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
   /* Terminate the quotes if necessary.  */
   if (in_quotes)
     {
-      if (inspect_it)
+      if (options->inspect_it)
        fputs_filtered ("\\\"", stream);
       else
        fputs_filtered ("\"", stream);
@@ -180,127 +181,125 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
   if (force_ellipses || i < length)
     fputs_filtered ("...", stream);
 }
-\f
-/* Preprocessing and parsing C and C++ expressions.  */
-
 
-/* When we find that lexptr (the global var defined in parse.c) is
-   pointing at a macro invocation, we expand the invocation, and call
-   scan_macro_expansion to save the old lexptr here and point lexptr
-   into the expanded text.  When we reach the end of that, we call
-   end_macro_expansion to pop back to the value we saved here.  The
-   macro expansion code promises to return only fully-expanded text,
-   so we don't need to "push" more than one level.
+/* Obtain a C string from the inferior storing it in a newly allocated
+   buffer in BUFFER, which should be freed by the caller.  The string is
+   read until a null character is found. If VALUE is an array with known
+   length, the function will not read past the end of the array.  LENGTH
+   will contain the size of the string in bytes (not counting the null
+   character).
 
-   This is disgusting, of course.  It would be cleaner to do all macro
-   expansion beforehand, and then hand that to lexptr.  But we don't
-   really know where the expression ends.  Remember, in a command like
-
-     (gdb) break *ADDRESS if CONDITION
-
-   we evaluate ADDRESS in the scope of the current frame, but we
-   evaluate CONDITION in the scope of the breakpoint's location.  So
-   it's simply wrong to try to macro-expand the whole thing at once.  */
-static char *macro_original_text;
-static char *macro_expanded_text;
+   Assumes strings are terminated by a null character.  The size of a character
+   is determined by the length of the target type of the pointer or array.
+   This means that a null byte present in a multi-byte character will not
+   terminate the string unless the whole character is null.
 
+   CHARSET is always set to the target charset.  */
 
 void
-scan_macro_expansion (char *expansion)
-{
-  /* We'd better not be trying to push the stack twice.  */
-  gdb_assert (! macro_original_text);
-  gdb_assert (! macro_expanded_text);
-
-  /* Save the old lexptr value, so we can return to it when we're done
-     parsing the expanded text.  */
-  macro_original_text = lexptr;
-  lexptr = expansion;
-
-  /* Save the expanded text, so we can free it when we're finished.  */
-  macro_expanded_text = expansion;
-}
-
-
-int
-scanning_macro_expansion (void)
-{
-  return macro_original_text != 0;
-}
-
-
-void 
-finished_macro_expansion (void)
-{
-  /* There'd better be something to pop back to, and we better have
-     saved a pointer to the start of the expanded text.  */
-  gdb_assert (macro_original_text);
-  gdb_assert (macro_expanded_text);
-
-  /* Pop back to the original text.  */
-  lexptr = macro_original_text;
-  macro_original_text = 0;
-
-  /* Free the expanded text.  */
-  xfree (macro_expanded_text);
-  macro_expanded_text = 0;
-}
-
-
-static void
-scan_macro_cleanup (void *dummy)
-{
-  if (macro_original_text)
-    finished_macro_expansion ();
-}
-
-
-/* We set these global variables before calling c_parse, to tell it
-   how it to find macro definitions for the expression at hand.  */
-macro_lookup_ftype *expression_macro_lookup_func;
-void *expression_macro_lookup_baton;
-
-
-static struct macro_definition *
-null_macro_lookup (const char *name, void *baton)
+c_get_string (struct value *value, gdb_byte **buffer, int *length,
+             const char **charset)
 {
-  return 0;
-}
+  int err, width;
+  unsigned int fetchlimit;
+  struct type *type = check_typedef (value_type (value));
+  struct type *element_type = TYPE_TARGET_TYPE (type);
 
+  if (element_type == NULL)
+    goto error;
 
-static int
-c_preprocess_and_parse (void)
-{
-  /* Set up a lookup function for the macro expander.  */
-  struct macro_scope *scope = 0;
-  struct cleanup *back_to = make_cleanup (free_current_contents, &scope);
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    {
+      /* If we know the size of the array, we can use it as a limit on the
+        number of characters to be fetched.  */
+      if (TYPE_NFIELDS (type) == 1
+         && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
+       {
+         LONGEST low_bound, high_bound;
 
-  if (expression_context_block)
-    scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
+         get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
+                              &low_bound, &high_bound);
+         fetchlimit = high_bound - low_bound + 1;
+       }
+      else
+       fetchlimit = UINT_MAX;
+    }
+  else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    fetchlimit = UINT_MAX;
   else
-    scope = default_macro_scope ();
-
-  if (scope)
+    /* We work only with arrays and pointers.  */
+    goto error;
+
+  element_type = check_typedef (element_type);
+  if (TYPE_CODE (element_type) != TYPE_CODE_INT
+      && TYPE_CODE (element_type) != TYPE_CODE_CHAR)
+    /* If the elements are not integers or characters, we don't consider it
+       a string.  */
+    goto error;
+
+  width = TYPE_LENGTH (element_type);
+
+  /* If the string lives in GDB's memory intead of the inferior's, then we
+     just need to copy it to BUFFER.  Also, since such strings are arrays
+     with known size, FETCHLIMIT will hold the size of the array.  */
+  if ((VALUE_LVAL (value) == not_lval
+       || VALUE_LVAL (value) == lval_internalvar)
+      && fetchlimit != UINT_MAX)
     {
-      expression_macro_lookup_func = standard_macro_lookup;
-      expression_macro_lookup_baton = (void *) scope;
+      int i;
+      const gdb_byte *contents = value_contents (value);
+
+      /* Look for a null character.  */
+      for (i = 0; i < fetchlimit; i++)
+       if (extract_unsigned_integer (contents + i * width, width) == 0)
+         break;
+
+      /* I is now either the number of non-null characters, or FETCHLIMIT.  */
+      *length = i * width;
+      *buffer = xmalloc (*length);
+      memcpy (*buffer, contents, *length);
+      err = 0;
     }
   else
     {
-      expression_macro_lookup_func = null_macro_lookup;
-      expression_macro_lookup_baton = 0;      
+      err = read_string (value_as_address (value), -1, width, fetchlimit,
+                        buffer, length);
+      if (err)
+       {
+         xfree (buffer);
+         error (_("Error reading string from inferior: %s"),
+                safe_strerror (err));
+       }
     }
 
-  gdb_assert (! macro_original_text);
-  make_cleanup (scan_macro_cleanup, 0);
+  /* If the last character is null, subtract it from LENGTH.  */
+  if (*length > 0
+      && extract_unsigned_integer (*buffer + *length - width, width) == 0)
+    *length -= width;
+
+  *charset = target_charset ();
 
+  return;
+
+ error:
   {
-    int result = c_parse ();
-    do_cleanups (back_to);
-    return result;
+    char *type_str;
+
+    type_str = type_to_string (type);
+    if (type_str)
+      {
+       make_cleanup (xfree, type_str);
+       error (_("Trying to read string with inappropriate type `%s'."),
+              type_str);
+      }
+    else
+      error (_("Trying to read string with inappropriate type."));
   }
 }
 
+\f
+/* Preprocessing and parsing C and C++ expressions.  */
+
 
 \f
 /* Table mapping opcodes into strings for printing operators
@@ -358,6 +357,9 @@ enum c_primitive_types {
   c_primitive_type_long_double,
   c_primitive_type_complex,
   c_primitive_type_double_complex,
+  c_primitive_type_decfloat,
+  c_primitive_type_decdouble,
+  c_primitive_type_declong,
   nr_c_primitive_types
 };
 
@@ -387,6 +389,11 @@ c_language_arch_info (struct gdbarch *gdbarch,
   lai->primitive_type_vector [c_primitive_type_long_double] = builtin->builtin_long_double;
   lai->primitive_type_vector [c_primitive_type_complex] = builtin->builtin_complex;
   lai->primitive_type_vector [c_primitive_type_double_complex] = builtin->builtin_double_complex;
+  lai->primitive_type_vector [c_primitive_type_decfloat] = builtin->builtin_decfloat;
+  lai->primitive_type_vector [c_primitive_type_decdouble] = builtin->builtin_decdouble;
+  lai->primitive_type_vector [c_primitive_type_declong] = builtin->builtin_declong;
+
+  lai->bool_type_default = builtin->builtin_int;
 }
 
 const struct language_defn c_language_defn =
@@ -397,18 +404,20 @@ const struct language_defn c_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
+  c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -417,9 +426,11 @@ const struct language_defn c_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
+  c_get_string,
   LANG_MAGIC
 };
 
@@ -442,6 +453,9 @@ enum cplus_primitive_types {
   cplus_primitive_type_complex,
   cplus_primitive_type_double_complex,
   cplus_primitive_type_bool,
+  cplus_primitive_type_decfloat,
+  cplus_primitive_type_decdouble,
+  cplus_primitive_type_declong,
   nr_cplus_primitive_types
 };
 
@@ -490,6 +504,15 @@ cplus_language_arch_info (struct gdbarch *gdbarch,
     = builtin->builtin_double_complex;
   lai->primitive_type_vector [cplus_primitive_type_bool]
     = builtin->builtin_bool;
+  lai->primitive_type_vector [cplus_primitive_type_decfloat]
+    = builtin->builtin_decfloat;
+  lai->primitive_type_vector [cplus_primitive_type_decdouble]
+    = builtin->builtin_decdouble;
+  lai->primitive_type_vector [cplus_primitive_type_declong]
+    = builtin->builtin_declong;
+
+  lai->bool_type_symbol = "bool";
+  lai->bool_type_default = builtin->builtin_bool;
 }
 
 const struct language_defn cplus_language_defn =
@@ -500,18 +523,20 @@ const struct language_defn cplus_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
+  c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   cplus_skip_trampoline,       /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                       /* name_of_this */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
   cp_lookup_transparent_type,   /* lookup_transparent_type */
   cplus_demangle,              /* Language specific symbol demangler */
@@ -520,9 +545,11 @@ const struct language_defn cplus_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   cplus_language_arch_info,
   default_print_array_index,
   cp_pass_by_reference,
+  c_get_string,
   LANG_MAGIC
 };
 
@@ -534,18 +561,20 @@ const struct language_defn asm_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
+  c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -554,9 +583,11 @@ const struct language_defn asm_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info, /* FIXME: la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
+  c_get_string,
   LANG_MAGIC
 };
 
@@ -573,18 +604,20 @@ const struct language_defn minimal_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
+  c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -593,9 +626,11 @@ const struct language_defn minimal_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
+  c_get_string,
   LANG_MAGIC
 };
 
This page took 0.028465 seconds and 4 git commands to generate.