/* C language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2013 Free Software Foundation, Inc.
+ Copyright (C) 1992-2017 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 "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 "exceptions.h"
+#include "gdbcore.h"
extern void _initialize_c_language (void);
character set name. */
static const char *
-charset_for_string_type (enum c_string_type str_type,
- struct gdbarch *gdbarch)
+charset_for_string_type (c_string_type str_type, struct gdbarch *gdbarch)
{
switch (str_type & ~C_CHAR)
{
characters of this type in target BYTE_ORDER to the host character
set. */
-static enum c_string_type
+static c_string_type
classify_type (struct type *elttype, struct gdbarch *gdbarch,
const char **encoding)
{
- enum c_string_type result;
+ c_string_type result;
/* We loop because ELTTYPE may be a typedef, and we want to
successively peel each typedef until we reach a type we
/* 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++. */
- CHECK_TYPEDEF (elttype);
+ elttype = check_typedef (elttype);
}
}
void
c_printchar (int c, struct type *type, struct ui_file *stream)
{
- enum c_string_type str_type;
+ c_string_type str_type;
str_type = classify_type (type, get_type_arch (type), NULL);
switch (str_type)
const char *user_encoding, int force_ellipses,
const struct value_print_options *options)
{
- enum c_string_type str_type;
+ c_string_type str_type;
const char *type_encoding;
const char *encoding;
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. If VALUE is an array with a known length,
- the function will not read past the end of the array. On
- completion, *LENGTH will be set to the size of the string read in
+ the pointer or array.
+
+ 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.
+
+ 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. */
/* I is now either a user-defined length, the number of non-null
characters, or FETCHLIMIT. */
*length = i * width;
- *buffer = xmalloc (*length);
+ *buffer = (gdb_byte *) xmalloc (*length);
memcpy (*buffer, contents, *length);
err = 0;
}
{
CORE_ADDR 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)
+ if (err != 0)
{
xfree (*buffer);
- if (err == EIO)
- throw_error (MEMORY_ERROR, "Address %s out of bounds",
- paddress (get_type_arch (type), addr));
- else
- error (_("Error reading string from inferior: %s"),
- safe_strerror (err));
+ memory_error (TARGET_XFER_E_IO, addr);
}
}
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."));
{
gdb_byte *buffer;
- buffer = alloca (TYPE_LENGTH (type));
+ buffer = (gdb_byte *) alloca (TYPE_LENGTH (type));
pack_long (buffer, type, value);
obstack_grow (output, buffer, TYPE_LENGTH (type));
}
/* If we saw a run of characters, convert them all. */
if (p > data)
convert_between_encodings (host_charset (), dest_charset,
- data, p - data, 1,
+ (gdb_byte *) data, p - data, 1,
output, translit_none);
/* If we saw an escape, convert it. */
if (p < limit)
struct obstack output;
struct cleanup *cleanup;
struct value *result;
- enum c_string_type dest_type;
+ c_string_type dest_type;
const char *dest_charset;
int satisfy_expected = 0;
++*pos;
limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1);
- dest_type
- = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst);
+ dest_type = ((enum c_string_type_values)
+ longest_to_int (exp->elts[*pos].longconst));
switch (dest_type & ~C_CHAR)
{
case C_STRING:
if (obstack_object_size (&output) != TYPE_LENGTH (type))
error (_("Could not convert character "
"constant to target character set"));
- value = unpack_long (type, obstack_base (&output));
+ value = unpack_long (type, (gdb_byte *) obstack_base (&output));
result = value_from_longest (type, value);
}
else
obstack_object_size (&output));
}
else
- result = value_cstring (obstack_base (&output),
+ result = value_cstring ((const char *) obstack_base (&output),
obstack_object_size (&output),
type);
}
{"/", 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},
{"sizeof ", UNOP_SIZEOF, 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 {
evaluate_subexp_c
};
+static const char *c_extensions[] =
+{
+ ".c", NULL
+};
+
const struct language_defn c_language_defn =
{
"c", /* Language name */
+ "C",
language_c,
range_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ c_extensions,
&exp_descriptor_c,
c_parse,
- c_error,
+ c_yyerror,
null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */
+ NULL,
NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */
c_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &c_varobj_ops,
+ c_get_compile_context,
+ c_compute_program,
LANG_MAGIC
};
lai->bool_type_default = builtin->builtin_bool;
}
+static const char *cplus_extensions[] =
+{
+ ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL
+};
+
const struct language_defn cplus_language_defn =
{
"c++", /* Language name */
+ "C++",
language_cplus,
range_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ cplus_extensions,
&exp_descriptor_c,
c_parse,
- c_error,
+ c_yyerror,
null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
"this", /* name_of_this */
cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
cp_lookup_transparent_type, /* lookup_transparent_type */
- cplus_demangle, /* Language specific symbol demangler */
+ 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 */
c_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &cplus_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
+static const char *asm_extensions[] =
+{
+ ".s", ".sx", ".S", NULL
+};
+
const struct language_defn asm_language_defn =
{
"asm", /* Language name */
+ "assembly",
language_asm,
range_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ asm_extensions,
&exp_descriptor_c,
c_parse,
- c_error,
+ c_yyerror,
null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */
+ NULL,
NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */
c_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
const struct language_defn minimal_language_defn =
{
"minimal", /* Language name */
+ "Minimal",
language_minimal,
range_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ NULL,
&exp_descriptor_c,
c_parse,
- c_error,
+ c_yyerror,
null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */
+ NULL,
NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */
c_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};