/* C language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2013 Free Software Foundation, Inc.
+ Copyright (C) 1992-2019 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "expression.h"
-#include "parser-defs.h"
-#include "language.h"
-#include "varobj.h"
+
+/* Standard C includes. */
+#include <ctype.h>
+
+/* Local non-gdb includes. */
#include "c-lang.h"
-#include "valprint.h"
-#include "macroscope.h"
-#include "gdb_assert.h"
+#include "c-support.h"
#include "charset.h"
-#include <string.h>
-#include "demangle.h"
#include "cp-abi.h"
#include "cp-support.h"
+#include "demangle.h"
+#include "expression.h"
#include "gdb_obstack.h"
-#include <ctype.h>
-#include "exceptions.h"
#include "gdbcore.h"
-
-extern void _initialize_c_language (void);
+#include "gdbtypes.h"
+#include "language.h"
+#include "macroscope.h"
+#include "parser-defs.h"
+#include "symtab.h"
+#include "valprint.h"
+#include "varobj.h"
/* Given a C string type, STR_TYPE, return the corresponding target
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. */
void
-c_get_string (struct value *value, gdb_byte **buffer,
+c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
int *length, struct type **char_type,
const char **charset)
{
/* 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
{
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)
- {
- xfree (*buffer);
- memory_error (err, addr);
- }
+ if (err != 0)
+ memory_error (TARGET_XFER_E_IO, addr);
}
/* If the LENGTH is specified at -1, we want to return the string
if (req_length == -1)
/* If the last character is null, subtract it from LENGTH. */
if (*length > 0
- && extract_unsigned_integer (*buffer + *length - width,
+ && extract_unsigned_integer (buffer->get () + *length - width,
width, byte_order) == 0)
*length -= width;
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 data[4];
int i;
- for (i = 0; i < length && p < limit && isxdigit (*p); ++i, ++p)
+ for (i = 0; i < length && p < limit && ISXDIGIT (*p); ++i, ++p)
result = (result << 4) + host_hex_value (*p);
for (i = 3; i >= 0; --i)
{
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));
}
unsigned long value = 0;
for (i = 0;
- i < 3 && p < limit && isdigit (*p) && *p != '8' && *p != '9';
+ i < 3 && p < limit && ISDIGIT (*p) && *p != '8' && *p != '9';
++i)
{
value = 8 * value + host_hex_value (*p);
{
unsigned long value = 0;
- while (p < limit && isxdigit (*p))
+ while (p < limit && ISXDIGIT (*p))
{
value = 16 * value + host_hex_value (*p);
++p;
case 'x':
ADVANCE;
- if (!isxdigit (*p))
+ if (!ISXDIGIT (*p))
error (_("\\x used with no following hex digits."));
p = convert_hex (type, p, limit, output);
break;
int length = *p == 'u' ? 4 : 8;
ADVANCE;
- if (!isxdigit (*p))
+ if (!ISXDIGIT (*p))
error (_("\\u used with no following hex digits"));
p = convert_ucn (p, limit, dest_charset, output, length);
}
{
int oplen, limit;
struct type *type;
- 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;
- obstack_init (&output);
- cleanup = make_cleanup_obstack_free (&output);
+ 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) 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:
result = allocate_value (type);
else
result = value_cstring ("", 0, type);
- do_cleanups (cleanup);
return result;
}
obstack_object_size (&output));
}
else
- result = value_cstring (obstack_base (&output),
+ result = value_cstring ((const char *) obstack_base (&output),
obstack_object_size (&output),
type);
}
- do_cleanups (cleanup);
return result;
}
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)));
+}
\f
/* Table mapping opcodes into strings for printing operators
{"*", 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 {
evaluate_subexp_c
};
-const struct language_defn c_language_defn =
+static const char *c_extensions[] =
+{
+ ".c", NULL
+};
+
+extern const struct language_defn c_language_defn =
{
"c", /* Language name */
"C",
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ 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 */
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,
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,
- NULL, /* la_get_symbol_name_cmp */
+ 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,
LANG_MAGIC
};
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
};
= 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++",
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ 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 */
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 */
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,
- NULL, /* la_get_symbol_name_cmp */
+ 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,
LANG_MAGIC
};
-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",
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ 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 */
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,
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, /* FIXME: la_language_arch_info. */
default_print_array_index,
default_pass_by_reference,
c_get_string,
- NULL, /* la_get_symbol_name_cmp */
+ c_watch_location_expression,
+ NULL, /* la_get_symbol_name_matcher */
iterate_over_symbols,
+ default_search_name_hash,
&default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
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",
case_sensitive_on,
array_row_major,
macro_expansion_c,
+ NULL,
&exp_descriptor_c,
c_parse,
- c_error,
null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
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,
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,
- NULL, /* la_get_symbol_name_cmp */
+ c_watch_location_expression,
+ NULL, /* la_get_symbol_name_matcher */
iterate_over_symbols,
+ default_search_name_hash,
&default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
-
-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);
-}