Change inferior thread list to be a thread map
[deliverable/binutils-gdb.git] / gdb / c-lang.c
index 8b5410f8a6b6eb0ef8fdbbc6b0345e4e3c01016b..1f40e885d99aac3e41227fd22e15f7ccb40d8ce2 100644 (file)
@@ -1,7 +1,6 @@
 /* C language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003,
-   2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1992-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "expression.h"
 #include "parser-defs.h"
 #include "language.h"
+#include "varobj.h"
 #include "c-lang.h"
+#include "c-support.h"
 #include "valprint.h"
 #include "macroscope.h"
-#include "gdb_assert.h"
 #include "charset.h"
-#include "gdb_string.h"
 #include "demangle.h"
 #include "cp-abi.h"
 #include "cp-support.h"
+#include "gdb_obstack.h"
+#include <ctype.h>
+#include "gdbcore.h"
+#include "gdbarch.h"
 
-extern void _initialize_c_language (void);
-static void c_emit_char (int c, struct ui_file * stream, int quoter);
+/* Given a C string type, STR_TYPE, return the corresponding target
+   character set name.  */
 
-/* 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
-c_emit_char (int c, struct ui_file *stream, int quoter)
+static const char *
+charset_for_string_type (c_string_type str_type, struct gdbarch *gdbarch)
 {
-  const char *escape;
-  int host_char;
-
-  c &= 0xFF;                   /* Avoid sign bit follies */
-
-  escape = c_target_char_has_backslash_escape (c);
-  if (escape)
+  switch (str_type & ~C_CHAR)
     {
-      if (quoter == '"' && strcmp (escape, "0") == 0)
-       /* Print nulls embedded in double quoted strings as \000 to
-          prevent ambiguity.  */
-       fprintf_filtered (stream, "\\000");
+    case C_STRING:
+      return target_charset (gdbarch);
+    case C_WIDE_STRING:
+      return target_wide_charset (gdbarch);
+    case C_STRING_16:
+      /* FIXME: UTF-16 is not always correct.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       return "UTF-16BE";
       else
-       fprintf_filtered (stream, "\\%s", escape);
-    }
-  else if (target_char_to_host (c, &host_char)
-           && host_char_print_literally (host_char))
-    {
-      if (host_char == '\\' || host_char == quoter)
-        fputs_filtered ("\\", stream);
-      fprintf_filtered (stream, "%c", host_char);
+       return "UTF-16LE";
+    case C_STRING_32:
+      /* FIXME: UTF-32 is not always correct.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       return "UTF-32BE";
+      else
+       return "UTF-32LE";
     }
-  else
-    fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+  internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
 }
 
-void
-c_printchar (int c, struct ui_file *stream)
-{
-  fputc_filtered ('\'', stream);
-  LA_EMIT_CHAR (c, stream, '\'');
-  fputc_filtered ('\'', stream);
-}
-
-/* Print the character string STRING, printing at most LENGTH characters.
-   LENGTH is -1 if the string is nul terminated.  Each character is WIDTH bytes
-   long.  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.  */
+/* Classify ELTTYPE according to what kind of character it is.  Return
+   the enum constant representing the character type.  Also set
+   *ENCODING to the name of the character set to use when converting
+   characters of this type in target BYTE_ORDER to the host character
+   set.  */
 
-void
-c_printstr (struct ui_file *stream, const gdb_byte *string,
-           unsigned int length, int width, int force_ellipses,
-           const struct value_print_options *options)
+static c_string_type
+classify_type (struct type *elttype, struct gdbarch *gdbarch,
+              const char **encoding)
 {
-  unsigned int i;
-  unsigned int things_printed = 0;
-  int in_quotes = 0;
-  int need_comma = 0;
-
-  /* If the string was not truncated due to `set print elements', and
-     the last byte of it is a null, we don't print that, in traditional C
-     style.  */
-  if (!force_ellipses
-      && length > 0
-      && (extract_unsigned_integer (string + (length - 1) * width, width)
-          == '\0'))
-    length--;
-
-  if (length == 0)
-    {
-      fputs_filtered ("\"\"", stream);
-      return;
-    }
+  c_string_type result;
 
-  for (i = 0; i < length && things_printed < options->print_max; ++i)
+  /* We loop because ELTTYPE may be a typedef, and we want to
+     successively peel each typedef until we reach a type we
+     understand.  We don't use CHECK_TYPEDEF because that will strip
+     all typedefs at once -- but in C, wchar_t is itself a typedef, so
+     that would do the wrong thing.  */
+  while (elttype)
     {
-      /* 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;
-      unsigned long current_char;
+      const char *name = TYPE_NAME (elttype);
 
-      QUIT;
-
-      if (need_comma)
+      if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name)
        {
-         fputs_filtered (", ", stream);
-         need_comma = 0;
+         result = C_CHAR;
+         goto done;
        }
 
-      current_char = extract_unsigned_integer (string + i * width, width);
+      if (!strcmp (name, "wchar_t"))
+       {
+         result = C_WIDE_CHAR;
+         goto done;
+       }
 
-      rep1 = i + 1;
-      reps = 1;
-      while (rep1 < length
-            && extract_unsigned_integer (string + rep1 * width, width)
-            == current_char)
+      if (!strcmp (name, "char16_t"))
        {
-         ++rep1;
-         ++reps;
+         result = C_CHAR_16;
+         goto done;
        }
 
-      if (reps > options->repeat_count_threshold)
+      if (!strcmp (name, "char32_t"))
        {
-         if (in_quotes)
-           {
-             if (options->inspect_it)
-               fputs_filtered ("\\\", ", stream);
-             else
-               fputs_filtered ("\", ", stream);
-             in_quotes = 0;
-           }
-         LA_PRINT_CHAR (current_char, stream);
-         fprintf_filtered (stream, _(" <repeats %u times>"), reps);
-         i = rep1 - 1;
-         things_printed += options->repeat_count_threshold;
-         need_comma = 1;
+         result = C_CHAR_32;
+         goto done;
        }
+
+      if (TYPE_CODE (elttype) != TYPE_CODE_TYPEDEF)
+       break;
+
+      /* Call for side effects.  */
+      check_typedef (elttype);
+
+      if (TYPE_TARGET_TYPE (elttype))
+       elttype = TYPE_TARGET_TYPE (elttype);
       else
        {
-         if (!in_quotes)
-           {
-             if (options->inspect_it)
-               fputs_filtered ("\\\"", stream);
-             else
-               fputs_filtered ("\"", stream);
-             in_quotes = 1;
-           }
-         LA_EMIT_CHAR (current_char, stream, '"');
-         ++things_printed;
+         /* Perhaps check_typedef did not update the target type.  In
+            this case, force the lookup again and hope it works out.
+            It never will for C, but it might for C++.  */
+         elttype = check_typedef (elttype);
        }
     }
 
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
+  /* Punt.  */
+  result = C_CHAR;
+
+ done:
+  if (encoding)
+    *encoding = charset_for_string_type (result, gdbarch);
+
+  return result;
+}
+
+/* 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.  */
+
+void
+c_emit_char (int c, struct type *type,
+            struct ui_file *stream, int quoter)
+{
+  const char *encoding;
+
+  classify_type (type, get_type_arch (type), &encoding);
+  generic_emit_char (c, type, stream, quoter, encoding);
+}
+
+void
+c_printchar (int c, struct type *type, struct ui_file *stream)
+{
+  c_string_type str_type;
+
+  str_type = classify_type (type, get_type_arch (type), NULL);
+  switch (str_type)
     {
-      if (options->inspect_it)
-       fputs_filtered ("\\\"", stream);
-      else
-       fputs_filtered ("\"", stream);
+    case C_CHAR:
+      break;
+    case C_WIDE_CHAR:
+      fputc_filtered ('L', stream);
+      break;
+    case C_CHAR_16:
+      fputc_filtered ('u', stream);
+      break;
+    case C_CHAR_32:
+      fputc_filtered ('U', stream);
+      break;
+    }
+
+  fputc_filtered ('\'', stream);
+  LA_EMIT_CHAR (c, type, stream, '\'');
+  fputc_filtered ('\'', stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH
+   characters.  LENGTH is -1 if the string is nul terminated.  Each
+   character is WIDTH bytes long.  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.  */
+
+void
+c_printstr (struct ui_file *stream, struct type *type, 
+           const gdb_byte *string, unsigned int length, 
+           const char *user_encoding, int force_ellipses,
+           const struct value_print_options *options)
+{
+  c_string_type str_type;
+  const char *type_encoding;
+  const char *encoding;
+
+  str_type = (classify_type (type, get_type_arch (type), &type_encoding)
+             & ~C_CHAR);
+  switch (str_type)
+    {
+    case C_STRING:
+      break;
+    case C_WIDE_STRING:
+      fputs_filtered ("L", stream);
+      break;
+    case C_STRING_16:
+      fputs_filtered ("u", stream);
+      break;
+    case C_STRING_32:
+      fputs_filtered ("U", stream);
+      break;
     }
 
-  if (force_ellipses || i < length)
-    fputs_filtered ("...", stream);
+  encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;
+
+  generic_printstr (stream, type, string, length, encoding, force_ellipses,
+                   '"', 1, options);
 }
 
 /* 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).
+   buffer in BUFFER, which should be freed by the caller.  If the in-
+   and out-parameter *LENGTH is specified at -1, the string is read
+   until a null character of the appropriate width is found, otherwise
+   the string is read to the length of characters specified.  The size
+   of a character is determined by the length of the target type of
+   the pointer or array.
 
-   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.
+   If VALUE is an array with a known length, and *LENGTH is -1,
+   the function will not read past the end of the array.  However, any
+   declared size of the array is ignored if *LENGTH > 0.
 
-   CHARSET is always set to the target charset.  */
+   On completion, *LENGTH will be set to the size of the string read in
+   characters.  (If a length of -1 is specified, the length returned
+   will not include the null character).  CHARSET is always set to the
+   target charset.  */
 
 void
-c_get_string (struct value *value, gdb_byte **buffer, int *length,
+c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+             int *length, struct type **char_type,
              const char **charset)
 {
   int err, width;
   unsigned int fetchlimit;
   struct type *type = check_typedef (value_type (value));
   struct type *element_type = TYPE_TARGET_TYPE (type);
+  int req_length = *length;
+  enum bfd_endian byte_order
+    = type_byte_order (type);
 
   if (element_type == NULL)
     goto error;
 
   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 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)
        {
@@ -230,67 +272,115 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
     /* 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.  */
+  if (! c_textual_element_type (element_type, 0))
     goto error;
-
+  classify_type (element_type, get_type_arch (element_type), charset);
   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 the string lives in GDB's memory instead 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.
+
+     An array is assumed to live in GDB's memory, so we take this path
+     here.
+
+     However, it's possible for the caller to request more array
+     elements than apparently exist -- this can happen when using the
+     C struct hack.  So, only do this if either no length was
+     specified, or the length is within the existing bounds.  This
+     avoids running off the end of the value's contents.  */
   if ((VALUE_LVAL (value) == not_lval
-       || VALUE_LVAL (value) == lval_internalvar)
-      && fetchlimit != UINT_MAX)
+       || VALUE_LVAL (value) == lval_internalvar
+       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+      && fetchlimit != UINT_MAX
+      && (*length < 0 || *length <= fetchlimit))
     {
       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.  */
+      /* If a length is specified, use that.  */
+      if (*length >= 0)
+       i  = *length;
+      else
+       /* Otherwise, look for a null character.  */
+       for (i = 0; i < fetchlimit; i++)
+         if (extract_unsigned_integer (contents + i * width,
+                                       width, byte_order) == 0)
+           break;
+  
+      /* I is now either a user-defined length, the number of non-null
+        characters, or FETCHLIMIT.  */
       *length = i * width;
-      *buffer = xmalloc (*length);
-      memcpy (*buffer, contents, *length);
+      buffer->reset ((gdb_byte *) xmalloc (*length));
+      memcpy (buffer->get (), contents, *length);
       err = 0;
     }
   else
     {
-      err = read_string (value_as_address (value), -1, width, fetchlimit,
-                        buffer, length);
-      if (err)
+      /* value_as_address does not return an address for an array when
+        c_style_arrays is false, so we handle that specially
+        here.  */
+      CORE_ADDR addr;
+      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
        {
-         xfree (buffer);
-         error (_("Error reading string from inferior: %s"),
-                safe_strerror (err));
+         if (VALUE_LVAL (value) != lval_memory)
+           error (_("Attempt to take address of value "
+                    "not located in memory."));
+         addr = value_address (value);
        }
+      else
+       addr = value_as_address (value);
+
+      /* Prior to the fix for PR 16196 read_string would ignore fetchlimit
+        if length > 0.  The old "broken" behaviour is the behaviour we want:
+        The caller may want to fetch 100 bytes from a variable length array
+        implemented using the common idiom of having an array of length 1 at
+        the end of a struct.  In this case we want to ignore the declared
+        size of the array.  However, it's counterintuitive to implement that
+        behaviour in read_string: what does fetchlimit otherwise mean if
+        length > 0.  Therefore we implement the behaviour we want here:
+        If *length > 0, don't specify a fetchlimit.  This preserves the
+        previous behaviour.  We could move this check above where we know
+        whether the array is declared with a fixed size, but we only want
+        to apply this behaviour when calling read_string.  PR 16286.  */
+      if (*length > 0)
+       fetchlimit = UINT_MAX;
+
+      err = read_string (addr, *length, width, fetchlimit,
+                        byte_order, buffer, length);
+      if (err != 0)
+       memory_error (TARGET_XFER_E_IO, addr);
     }
 
-  /* If the last character is null, subtract it from LENGTH.  */
-  if (*length > 0
-      && extract_unsigned_integer (*buffer + *length - width, width) == 0)
-    *length -= width;
+  /* If the LENGTH is specified at -1, we want to return the string
+     length up to the terminating null character.  If an actual length
+     was specified, we want to return the length of exactly what was
+     read.  */
+  if (req_length == -1)
+    /* If the last character is null, subtract it from LENGTH.  */
+    if (*length > 0
+       && extract_unsigned_integer (buffer->get () + *length - width,
+                                    width, byte_order) == 0)
+      *length -= width;
+  
+  /* The read_string function will return the number of bytes read.
+     If length returned from read_string was > 0, return the number of
+     characters read by dividing the number of bytes by width.  */
+  if (*length != 0)
+     *length = *length / width;
 
-  *charset = target_charset ();
+  *char_type = element_type;
 
   return;
 
  error:
   {
-    char *type_str;
-
-    type_str = type_to_string (type);
-    if (type_str)
+    std::string type_str = type_to_string (type);
+    if (!type_str.empty ())
       {
-       make_cleanup (xfree, type_str);
        error (_("Trying to read string with inappropriate type `%s'."),
-              type_str);
+              type_str.c_str ());
       }
     else
       error (_("Trying to read string with inappropriate type."));
@@ -298,8 +388,389 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
 }
 
 \f
-/* Preprocessing and parsing C and C++ expressions.  */
+/* Evaluating C and C++ expressions.  */
+
+/* Convert a UCN.  The digits of the UCN start at P and extend no
+   farther than LIMIT.  DEST_CHARSET is the name of the character set
+   into which the UCN should be converted.  The results are written to
+   OUTPUT.  LENGTH is the maximum length of the UCN, either 4 or 8.
+   Returns a pointer to just after the final digit of the UCN.  */
+
+static char *
+convert_ucn (char *p, char *limit, const char *dest_charset,
+            struct obstack *output, int length)
+{
+  unsigned long result = 0;
+  gdb_byte data[4];
+  int i;
+
+  for (i = 0; i < length && p < limit && ISXDIGIT (*p); ++i, ++p)
+    result = (result << 4) + host_hex_value (*p);
+
+  for (i = 3; i >= 0; --i)
+    {
+      data[i] = result & 0xff;
+      result >>= 8;
+    }
+
+  convert_between_encodings ("UTF-32BE", dest_charset, data,
+                            4, 4, output, translit_none);
+
+  return p;
+}
+
+/* Emit a character, VALUE, which was specified numerically, to
+   OUTPUT.  TYPE is the target character type.  */
+
+static void
+emit_numeric_character (struct type *type, unsigned long value,
+                       struct obstack *output)
+{
+  gdb_byte *buffer;
+
+  buffer = (gdb_byte *) alloca (TYPE_LENGTH (type));
+  pack_long (buffer, type, value);
+  obstack_grow (output, buffer, TYPE_LENGTH (type));
+}
+
+/* Convert an octal escape sequence.  TYPE is the target character
+   type.  The digits of the escape sequence begin at P and extend no
+   farther than LIMIT.  The result is written to OUTPUT.  Returns a
+   pointer to just after the final digit of the escape sequence.  */
+
+static char *
+convert_octal (struct type *type, char *p, 
+              char *limit, struct obstack *output)
+{
+  int i;
+  unsigned long value = 0;
+
+  for (i = 0;
+       i < 3 && p < limit && ISDIGIT (*p) && *p != '8' && *p != '9';
+       ++i)
+    {
+      value = 8 * value + host_hex_value (*p);
+      ++p;
+    }
+
+  emit_numeric_character (type, value, output);
+
+  return p;
+}
+
+/* Convert a hex escape sequence.  TYPE is the target character type.
+   The digits of the escape sequence begin at P and extend no farther
+   than LIMIT.  The result is written to OUTPUT.  Returns a pointer to
+   just after the final digit of the escape sequence.  */
+
+static char *
+convert_hex (struct type *type, char *p,
+            char *limit, struct obstack *output)
+{
+  unsigned long value = 0;
+
+  while (p < limit && ISXDIGIT (*p))
+    {
+      value = 16 * value + host_hex_value (*p);
+      ++p;
+    }
 
+  emit_numeric_character (type, value, output);
+
+  return p;
+}
+
+#define ADVANCE                                        \
+  do {                                         \
+    ++p;                                       \
+    if (p == limit)                            \
+      error (_("Malformed escape sequence"));  \
+  } while (0)
+
+/* Convert an escape sequence to a target format.  TYPE is the target
+   character type to use, and DEST_CHARSET is the name of the target
+   character set.  The backslash of the escape sequence is at *P, and
+   the escape sequence will not extend past LIMIT.  The results are
+   written to OUTPUT.  Returns a pointer to just past the final
+   character of the escape sequence.  */
+
+static char *
+convert_escape (struct type *type, const char *dest_charset,
+               char *p, char *limit, struct obstack *output)
+{
+  /* Skip the backslash.  */
+  ADVANCE;
+
+  switch (*p)
+    {
+    case '\\':
+      obstack_1grow (output, '\\');
+      ++p;
+      break;
+
+    case 'x':
+      ADVANCE;
+      if (!ISXDIGIT (*p))
+       error (_("\\x used with no following hex digits."));
+      p = convert_hex (type, p, limit, output);
+      break;
+
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+      p = convert_octal (type, p, limit, output);
+      break;
+
+    case 'u':
+    case 'U':
+      {
+       int length = *p == 'u' ? 4 : 8;
+
+       ADVANCE;
+       if (!ISXDIGIT (*p))
+         error (_("\\u used with no following hex digits"));
+       p = convert_ucn (p, limit, dest_charset, output, length);
+      }
+    }
+
+  return p;
+}
+
+/* Given a single string from a (C-specific) OP_STRING list, convert
+   it to a target string, handling escape sequences specially.  The
+   output is written to OUTPUT.  DATA is the input string, which has
+   length LEN.  DEST_CHARSET is the name of the target character set,
+   and TYPE is the type of target character to use.  */
+
+static void
+parse_one_string (struct obstack *output, char *data, int len,
+                 const char *dest_charset, struct type *type)
+{
+  char *limit;
+
+  limit = data + len;
+
+  while (data < limit)
+    {
+      char *p = data;
+
+      /* Look for next escape, or the end of the input.  */
+      while (p < limit && *p != '\\')
+       ++p;
+      /* If we saw a run of characters, convert them all.  */
+      if (p > data)
+       convert_between_encodings (host_charset (), dest_charset,
+                                  (gdb_byte *) data, p - data, 1,
+                                  output, translit_none);
+      /* If we saw an escape, convert it.  */
+      if (p < limit)
+       p = convert_escape (type, dest_charset, p, limit, output);
+      data = p;
+    }
+}
+
+/* Expression evaluator for the C language family.  Most operations
+   are delegated to evaluate_subexp_standard; see that function for a
+   description of the arguments.  */
+
+struct value *
+evaluate_subexp_c (struct type *expect_type, struct expression *exp,
+                  int *pos, enum noside noside)
+{
+  enum exp_opcode op = exp->elts[*pos].opcode;
+
+  switch (op)
+    {
+    case OP_STRING:
+      {
+       int oplen, limit;
+       struct type *type;
+       struct value *result;
+       c_string_type dest_type;
+       const char *dest_charset;
+       int satisfy_expected = 0;
+
+       auto_obstack output;
+
+       ++*pos;
+       oplen = longest_to_int (exp->elts[*pos].longconst);
+
+       ++*pos;
+       limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1);
+       dest_type = ((enum c_string_type_values)
+                    longest_to_int (exp->elts[*pos].longconst));
+       switch (dest_type & ~C_CHAR)
+         {
+         case C_STRING:
+           type = language_string_char_type (exp->language_defn,
+                                             exp->gdbarch);
+           break;
+         case C_WIDE_STRING:
+           type = lookup_typename (exp->language_defn, "wchar_t", NULL, 0);
+           break;
+         case C_STRING_16:
+           type = lookup_typename (exp->language_defn, "char16_t", NULL, 0);
+           break;
+         case C_STRING_32:
+           type = lookup_typename (exp->language_defn, "char32_t", NULL, 0);
+           break;
+         default:
+           internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
+         }
+
+       /* Ensure TYPE_LENGTH is valid for TYPE.  */
+       check_typedef (type);
+
+       /* If the caller expects an array of some integral type,
+          satisfy them.  If something odder is expected, rely on the
+          caller to cast.  */
+       if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+         {
+           struct type *element_type
+             = check_typedef (TYPE_TARGET_TYPE (expect_type));
+
+           if (TYPE_CODE (element_type) == TYPE_CODE_INT
+               || TYPE_CODE (element_type) == TYPE_CODE_CHAR)
+             {
+               type = element_type;
+               satisfy_expected = 1;
+             }
+         }
+
+       dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
+
+       ++*pos;
+       while (*pos < limit)
+         {
+           int len;
+
+           len = longest_to_int (exp->elts[*pos].longconst);
+
+           ++*pos;
+           if (noside != EVAL_SKIP)
+             parse_one_string (&output, &exp->elts[*pos].string, len,
+                               dest_charset, type);
+           *pos += BYTES_TO_EXP_ELEM (len);
+         }
+
+       /* Skip the trailing length and opcode.  */
+       *pos += 2;
+
+       if (noside == EVAL_SKIP)
+         {
+           /* Return a dummy value of the appropriate type.  */
+           if (expect_type != NULL)
+             result = allocate_value (expect_type);
+           else if ((dest_type & C_CHAR) != 0)
+             result = allocate_value (type);
+           else
+             result = value_cstring ("", 0, type);
+           return result;
+         }
+
+       if ((dest_type & C_CHAR) != 0)
+         {
+           LONGEST value;
+
+           if (obstack_object_size (&output) != TYPE_LENGTH (type))
+             error (_("Could not convert character "
+                      "constant to target character set"));
+           value = unpack_long (type, (gdb_byte *) obstack_base (&output));
+           result = value_from_longest (type, value);
+         }
+       else
+         {
+           int i;
+
+           /* Write the terminating character.  */
+           for (i = 0; i < TYPE_LENGTH (type); ++i)
+             obstack_1grow (&output, 0);
+
+           if (satisfy_expected)
+             {
+               LONGEST low_bound, high_bound;
+               int element_size = TYPE_LENGTH (type);
+
+               if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
+                                        &low_bound, &high_bound) < 0)
+                 {
+                   low_bound = 0;
+                   high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+                 }
+               if (obstack_object_size (&output) / element_size
+                   > (high_bound - low_bound + 1))
+                 error (_("Too many array elements"));
+
+               result = allocate_value (expect_type);
+               memcpy (value_contents_raw (result), obstack_base (&output),
+                       obstack_object_size (&output));
+             }
+           else
+             result = value_cstring ((const char *) obstack_base (&output),
+                                     obstack_object_size (&output),
+                                     type);
+         }
+       return result;
+      }
+      break;
+
+    default:
+      break;
+    }
+  return evaluate_subexp_standard (expect_type, exp, pos, noside);
+}
+\f
+/* la_watch_location_expression for C.  */
+
+gdb::unique_xmalloc_ptr<char>
+c_watch_location_expression (struct type *type, CORE_ADDR addr)
+{
+  type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
+  std::string name = type_to_string (type);
+  return gdb::unique_xmalloc_ptr<char>
+    (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr)));
+}
+
+/* See c-lang.h.  */
+
+bool
+c_is_string_type_p (struct type *type)
+{
+  type = check_typedef (type);
+  while (TYPE_CODE (type) == TYPE_CODE_REF)
+    {
+      type = TYPE_TARGET_TYPE (type);
+      type = check_typedef (type);
+    }
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      {
+       /* See if target type looks like a string.  */
+       struct type *array_target_type = TYPE_TARGET_TYPE (type);
+       return (TYPE_LENGTH (type) > 0
+               && TYPE_LENGTH (array_target_type) > 0
+               && c_textual_element_type (array_target_type, 0));
+      }
+    case TYPE_CODE_STRING:
+      return true;
+    case TYPE_CODE_PTR:
+      {
+       struct type *element_type = TYPE_TARGET_TYPE (type);
+       return c_textual_element_type (element_type, 0);
+      }
+    default:
+      break;
+    }
+
+  return false;
+}
 
 \f
 /* Table mapping opcodes into strings for printing operators
@@ -328,15 +799,17 @@ const struct op_print c_op_print_tab[] =
   {"/", BINOP_DIV, PREC_MUL, 0},
   {"%", BINOP_REM, PREC_MUL, 0},
   {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+  {"+", UNOP_PLUS, PREC_PREFIX, 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},
+  {"alignof ", UNOP_ALIGNOF, PREC_PREFIX, 0},
   {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
   {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
-  {NULL, 0, 0, 0}
+  {NULL, OP_NULL, PREC_PREFIX, 0}
 };
 \f
 enum c_primitive_types {
@@ -368,6 +841,7 @@ c_language_arch_info (struct gdbarch *gdbarch,
                      struct language_arch_info *lai)
 {
   const struct builtin_type *builtin = builtin_type (gdbarch);
+
   lai->string_char_type = builtin->builtin_char;
   lai->primitive_type_vector
     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_c_primitive_types + 1,
@@ -396,18 +870,33 @@ c_language_arch_info (struct gdbarch *gdbarch,
   lai->bool_type_default = builtin->builtin_int;
 }
 
-const struct language_defn c_language_defn =
+const struct exp_descriptor exp_descriptor_c = 
+{
+  print_subexp_standard,
+  operator_length_standard,
+  operator_check_standard,
+  op_name_standard,
+  dump_subexp_body_standard,
+  evaluate_subexp_c
+};
+
+static const char *c_extensions[] =
+{
+  ".c", NULL
+};
+
+extern const struct language_defn c_language_defn =
 {
   "c",                         /* Language name */
+  "C",
   language_c,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
-  &exp_descriptor_standard,
+  c_extensions,
+  &exp_descriptor_c,
   c_parse,
-  c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
@@ -416,22 +905,33 @@ const struct language_defn c_language_defn =
   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 */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
-  NULL,                                /* Language specific class_name_from_physname */
+  NULL,
+  NULL,                                /* Language specific
+                                  class_name_from_physname */
   c_op_print_tab,              /* expression operators for printing */
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
-  default_make_symbol_completion_list,
+  default_collect_symbol_completion_matches,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
-  c_get_string,
-  LANG_MAGIC
+  c_watch_location_expression,
+  NULL,                                /* la_get_symbol_name_matcher */
+  iterate_over_symbols,
+  default_search_name_hash,
+  &c_varobj_ops,
+  c_get_compile_context,
+  c_compute_program,
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
 enum cplus_primitive_types {
@@ -456,6 +956,9 @@ enum cplus_primitive_types {
   cplus_primitive_type_decfloat,
   cplus_primitive_type_decdouble,
   cplus_primitive_type_declong,
+  cplus_primitive_type_char16_t,
+  cplus_primitive_type_char32_t,
+  cplus_primitive_type_wchar_t,
   nr_cplus_primitive_types
 };
 
@@ -464,6 +967,7 @@ cplus_language_arch_info (struct gdbarch *gdbarch,
                          struct language_arch_info *lai)
 {
   const struct builtin_type *builtin = builtin_type (gdbarch);
+
   lai->string_char_type = builtin->builtin_char;
   lai->primitive_type_vector
     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_cplus_primitive_types + 1,
@@ -510,23 +1014,34 @@ cplus_language_arch_info (struct gdbarch *gdbarch,
     = builtin->builtin_decdouble;
   lai->primitive_type_vector [cplus_primitive_type_declong]
     = builtin->builtin_declong;
+  lai->primitive_type_vector [cplus_primitive_type_char16_t]
+    = builtin->builtin_char16;
+  lai->primitive_type_vector [cplus_primitive_type_char32_t]
+    = builtin->builtin_char32;
+  lai->primitive_type_vector [cplus_primitive_type_wchar_t]
+    = builtin->builtin_wchar;
 
   lai->bool_type_symbol = "bool";
   lai->bool_type_default = builtin->builtin_bool;
 }
 
-const struct language_defn cplus_language_defn =
+static const char *cplus_extensions[] =
+{
+  ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL
+};
+
+extern const struct language_defn cplus_language_defn =
 {
   "c++",                       /* Language name */
+  "C++",
   language_cplus,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
-  &exp_descriptor_standard,
+  cplus_extensions,
+  &exp_descriptor_c,
   c_parse,
-  c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
@@ -535,36 +1050,52 @@ const struct language_defn cplus_language_defn =
   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 */
+  default_read_var_value,      /* la_read_var_value */
   cplus_skip_trampoline,       /* Language specific skip_trampoline */
   "this",                       /* name_of_this */
+  false,                       /* la_store_sym_names_in_linkage_form_p */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
   cp_lookup_transparent_type,   /* lookup_transparent_type */
-  cplus_demangle,              /* Language specific symbol demangler */
-  cp_class_name_from_physname,  /* Language specific class_name_from_physname */
+  gdb_demangle,                        /* Language specific symbol demangler */
+  gdb_sniff_from_mangled_name,
+  cp_class_name_from_physname,  /* Language specific
+                                  class_name_from_physname */
   c_op_print_tab,              /* expression operators for printing */
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
-  default_make_symbol_completion_list,
+  default_collect_symbol_completion_matches,
   cplus_language_arch_info,
   default_print_array_index,
   cp_pass_by_reference,
-  c_get_string,
-  LANG_MAGIC
+  c_watch_location_expression,
+  cp_get_symbol_name_matcher,
+  iterate_over_symbols,
+  cp_search_name_hash,
+  &cplus_varobj_ops,
+  cplus_get_compile_context,
+  cplus_compute_program,
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
-const struct language_defn asm_language_defn =
+static const char *asm_extensions[] =
+{
+  ".s", ".sx", ".S", NULL
+};
+
+extern const struct language_defn asm_language_defn =
 {
   "asm",                       /* Language name */
+  "assembly",
   language_asm,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
-  &exp_descriptor_standard,
+  asm_extensions,
+  &exp_descriptor_c,
   c_parse,
-  c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
@@ -573,22 +1104,33 @@ const struct language_defn asm_language_defn =
   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 */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
-  NULL,                                /* Language specific class_name_from_physname */
+  NULL,
+  NULL,                                /* Language specific
+                                  class_name_from_physname */
   c_op_print_tab,              /* expression operators for printing */
   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_collect_symbol_completion_matches,
+  c_language_arch_info,                /* FIXME: la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
-  c_get_string,
-  LANG_MAGIC
+  c_watch_location_expression,
+  NULL,                                /* la_get_symbol_name_matcher */
+  iterate_over_symbols,
+  default_search_name_hash,
+  &default_varobj_ops,
+  NULL,
+  NULL,
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
 /* The following language_defn does not represent a real language.
@@ -596,18 +1138,18 @@ const struct language_defn asm_language_defn =
    to do some simple operations when debugging applications that use
    a language currently not supported by GDB.  */
 
-const struct language_defn minimal_language_defn =
+extern const struct language_defn minimal_language_defn =
 {
   "minimal",                   /* Language name */
+  "Minimal",
   language_minimal,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
-  &exp_descriptor_standard,
+  NULL,
+  &exp_descriptor_c,
   c_parse,
-  c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
@@ -616,29 +1158,31 @@ const struct language_defn minimal_language_defn =
   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 */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
-  NULL,                                /* Language specific class_name_from_physname */
+  NULL,
+  NULL,                                /* Language specific
+                                  class_name_from_physname */
   c_op_print_tab,              /* expression operators for printing */
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
-  default_make_symbol_completion_list,
+  default_collect_symbol_completion_matches,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
-  c_get_string,
-  LANG_MAGIC
+  c_watch_location_expression,
+  NULL,                                /* la_get_symbol_name_matcher */
+  iterate_over_symbols,
+  default_search_name_hash,
+  &default_varobj_ops,
+  NULL,
+  NULL,
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
-
-void
-_initialize_c_language (void)
-{
-  add_language (&c_language_defn);
-  add_language (&cplus_language_defn);
-  add_language (&asm_language_defn);
-  add_language (&minimal_language_defn);
-}
This page took 0.035263 seconds and 4 git commands to generate.