Add support for the Rust language
This patch adds support for the Rust language. 2016-05-17 Tom Tromey <tom@tromey.com> Manish Goregaokar <manishsmail@gmail.com> * symtab.c (symbol_find_demangled_name): Handle Rust. * symfile.c (init_filename_language_table): Treat ".rs" as Rust. * std-operator.def (STRUCTOP_ANONYMOUS, OP_RUST_ARRAY): New constants. * rust-lang.h: New file. * rust-lang.c: New file. * rust-exp.y: New file. * dwarf2read.c (read_file_scope): Add Rust producer sniffing. (dwarf2_compute_name, read_func_scope, read_structure_type) (read_base_type, read_subrange_type, set_cu_language) (new_symbol_full, determine_prefix): Handle Rust. * defs.h (enum language) <language_rust>: New constant. * Makefile.in (SFILES): Add rust-exp.y, rust-lang.c. (COMMON_OBS): Add rust-exp.o, rust-lang.o. 2016-05-17 Tom Tromey <tom@tromey.com> * gdb.base/default.exp (set language): Add rust.
This commit is contained in:
parent
00272ec4b0
commit
c44af4ebc0
12 changed files with 4904 additions and 7 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
2016-05-17 Tom Tromey <tom@tromey.com>
|
||||||
|
Manish Goregaokar <manishsmail@gmail.com>
|
||||||
|
|
||||||
|
* symtab.c (symbol_find_demangled_name): Handle Rust.
|
||||||
|
* symfile.c (init_filename_language_table): Treat ".rs" as Rust.
|
||||||
|
* std-operator.def (STRUCTOP_ANONYMOUS, OP_RUST_ARRAY): New
|
||||||
|
constants.
|
||||||
|
* rust-lang.h: New file.
|
||||||
|
* rust-lang.c: New file.
|
||||||
|
* rust-exp.y: New file.
|
||||||
|
* dwarf2read.c (read_file_scope): Add Rust producer sniffing.
|
||||||
|
(dwarf2_compute_name, read_func_scope, read_structure_type)
|
||||||
|
(read_base_type, read_subrange_type, set_cu_language)
|
||||||
|
(new_symbol_full, determine_prefix): Handle Rust.
|
||||||
|
* defs.h (enum language) <language_rust>: New constant.
|
||||||
|
* Makefile.in (SFILES): Add rust-exp.y, rust-lang.c.
|
||||||
|
(COMMON_OBS): Add rust-exp.o, rust-lang.o.
|
||||||
|
|
||||||
2016-05-17 Tom Tromey <tom@tromey.com>
|
2016-05-17 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* valprint.h (struct generic_val_print_array) <array_start,
|
* valprint.h (struct generic_val_print_array) <array_start,
|
||||||
|
|
|
@ -869,6 +869,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
|
||||||
proc-service.list progspace.c \
|
proc-service.list progspace.c \
|
||||||
prologue-value.c psymtab.c \
|
prologue-value.c psymtab.c \
|
||||||
regcache.c reggroups.c remote.c remote-fileio.c remote-notif.c reverse.c \
|
regcache.c reggroups.c remote.c remote-fileio.c remote-notif.c reverse.c \
|
||||||
|
rust-exp.y rust-lang.c \
|
||||||
selftest.c sentinel-frame.c \
|
selftest.c sentinel-frame.c \
|
||||||
serial.c ser-base.c ser-unix.c ser-event.c skip.c \
|
serial.c ser-base.c ser-unix.c ser-event.c skip.c \
|
||||||
solib.c solib-target.c source.c \
|
solib.c solib-target.c source.c \
|
||||||
|
@ -1074,6 +1075,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
|
||||||
gnu-v2-abi.o gnu-v3-abi.o cp-abi.o cp-support.o \
|
gnu-v2-abi.o gnu-v3-abi.o cp-abi.o cp-support.o \
|
||||||
cp-namespace.o d-namespace.o \
|
cp-namespace.o d-namespace.o \
|
||||||
reggroups.o \
|
reggroups.o \
|
||||||
|
rust-exp.o rust-lang.o \
|
||||||
trad-frame.o \
|
trad-frame.o \
|
||||||
tramp-frame.o \
|
tramp-frame.o \
|
||||||
solib.o solib-target.o \
|
solib.o solib-target.o \
|
||||||
|
|
|
@ -212,6 +212,7 @@ enum language
|
||||||
language_pascal, /* Pascal */
|
language_pascal, /* Pascal */
|
||||||
language_ada, /* Ada */
|
language_ada, /* Ada */
|
||||||
language_opencl, /* OpenCL */
|
language_opencl, /* OpenCL */
|
||||||
|
language_rust, /* Rust */
|
||||||
language_minimal, /* All other languages, minimal support only */
|
language_minimal, /* All other languages, minimal support only */
|
||||||
nr_languages
|
nr_languages
|
||||||
};
|
};
|
||||||
|
|
|
@ -8462,7 +8462,8 @@ dwarf2_compute_name (const char *name,
|
||||||
/* These are the only languages we know how to qualify names in. */
|
/* These are the only languages we know how to qualify names in. */
|
||||||
if (name != NULL
|
if (name != NULL
|
||||||
&& (cu->language == language_cplus || cu->language == language_java
|
&& (cu->language == language_cplus || cu->language == language_java
|
||||||
|| cu->language == language_fortran || cu->language == language_d))
|
|| cu->language == language_fortran || cu->language == language_d
|
||||||
|
|| cu->language == language_rust))
|
||||||
{
|
{
|
||||||
if (die_needs_namespace (die, cu))
|
if (die_needs_namespace (die, cu))
|
||||||
{
|
{
|
||||||
|
@ -11475,7 +11476,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
/* For C++, set the block's scope. */
|
/* For C++, set the block's scope. */
|
||||||
if ((cu->language == language_cplus
|
if ((cu->language == language_cplus
|
||||||
|| cu->language == language_fortran
|
|| cu->language == language_fortran
|
||||||
|| cu->language == language_d)
|
|| cu->language == language_d
|
||||||
|
|| cu->language == language_rust)
|
||||||
&& cu->processing_has_namespace_info)
|
&& cu->processing_has_namespace_info)
|
||||||
block_set_scope (block, determine_prefix (die, cu),
|
block_set_scope (block, determine_prefix (die, cu),
|
||||||
&objfile->objfile_obstack);
|
&objfile->objfile_obstack);
|
||||||
|
@ -13147,7 +13149,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
{
|
{
|
||||||
if (cu->language == language_cplus
|
if (cu->language == language_cplus
|
||||||
|| cu->language == language_java
|
|| cu->language == language_java
|
||||||
|| cu->language == language_d)
|
|| cu->language == language_d
|
||||||
|
|| cu->language == language_rust)
|
||||||
{
|
{
|
||||||
const char *full_name = dwarf2_full_name (name, die, cu);
|
const char *full_name = dwarf2_full_name (name, die, cu);
|
||||||
|
|
||||||
|
@ -14776,7 +14779,8 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
case DW_ATE_unsigned_char:
|
case DW_ATE_unsigned_char:
|
||||||
if (cu->language == language_ada || cu->language == language_m2
|
if (cu->language == language_ada || cu->language == language_m2
|
||||||
|| cu->language == language_pascal
|
|| cu->language == language_pascal
|
||||||
|| cu->language == language_fortran)
|
|| cu->language == language_fortran
|
||||||
|
|| cu->language == language_rust)
|
||||||
code = TYPE_CODE_CHAR;
|
code = TYPE_CODE_CHAR;
|
||||||
type_flags |= TYPE_FLAG_UNSIGNED;
|
type_flags |= TYPE_FLAG_UNSIGNED;
|
||||||
break;
|
break;
|
||||||
|
@ -14950,6 +14954,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
case language_d:
|
case language_d:
|
||||||
case language_java:
|
case language_java:
|
||||||
case language_objc:
|
case language_objc:
|
||||||
|
case language_rust:
|
||||||
low.data.const_val = 0;
|
low.data.const_val = 0;
|
||||||
low_default_is_valid = (cu->header.version >= 4);
|
low_default_is_valid = (cu->header.version >= 4);
|
||||||
break;
|
break;
|
||||||
|
@ -17038,6 +17043,10 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
|
||||||
case DW_LANG_ObjC:
|
case DW_LANG_ObjC:
|
||||||
cu->language = language_objc;
|
cu->language = language_objc;
|
||||||
break;
|
break;
|
||||||
|
case DW_LANG_Rust:
|
||||||
|
case DW_LANG_Rust_old:
|
||||||
|
cu->language = language_rust;
|
||||||
|
break;
|
||||||
case DW_LANG_Cobol74:
|
case DW_LANG_Cobol74:
|
||||||
case DW_LANG_Cobol85:
|
case DW_LANG_Cobol85:
|
||||||
default:
|
default:
|
||||||
|
@ -18601,7 +18610,8 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
|
||||||
if (cu->language == language_cplus
|
if (cu->language == language_cplus
|
||||||
|| cu->language == language_java
|
|| cu->language == language_java
|
||||||
|| cu->language == language_ada
|
|| cu->language == language_ada
|
||||||
|| cu->language == language_d)
|
|| cu->language == language_d
|
||||||
|
|| cu->language == language_rust)
|
||||||
{
|
{
|
||||||
/* The symbol's name is already allocated along
|
/* The symbol's name is already allocated along
|
||||||
with this objfile, so we don't need to
|
with this objfile, so we don't need to
|
||||||
|
@ -19274,7 +19284,8 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
char *retval;
|
char *retval;
|
||||||
|
|
||||||
if (cu->language != language_cplus && cu->language != language_java
|
if (cu->language != language_cplus && cu->language != language_java
|
||||||
&& cu->language != language_fortran && cu->language != language_d)
|
&& cu->language != language_fortran && cu->language != language_d
|
||||||
|
&& cu->language != language_rust)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
retval = anonymous_struct_prefix (die, cu);
|
retval = anonymous_struct_prefix (die, cu);
|
||||||
|
|
2752
gdb/rust-exp.y
Normal file
2752
gdb/rust-exp.y
Normal file
File diff suppressed because it is too large
Load diff
2050
gdb/rust-lang.c
Normal file
2050
gdb/rust-lang.c
Normal file
File diff suppressed because it is too large
Load diff
50
gdb/rust-lang.h
Normal file
50
gdb/rust-lang.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* Rust language support definitions for GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef RUST_LANG_H
|
||||||
|
#define RUST_LANG_H
|
||||||
|
|
||||||
|
struct parser_state;
|
||||||
|
struct type;
|
||||||
|
|
||||||
|
/* The la_parser implementation for Rust. */
|
||||||
|
extern int rust_parse (struct parser_state *);
|
||||||
|
|
||||||
|
/* The la_error implementation for Rust. */
|
||||||
|
extern void rustyyerror (char *);
|
||||||
|
|
||||||
|
/* Return true if TYPE is a tuple type; otherwise false. */
|
||||||
|
extern int rust_tuple_type_p (struct type *type);
|
||||||
|
|
||||||
|
/* Return true if TYPE is a tuple struct type; otherwise false. */
|
||||||
|
extern int rust_tuple_struct_type_p (struct type *type);
|
||||||
|
|
||||||
|
/* Given a block, find the name of the block's crate. The name must
|
||||||
|
be freed by the caller. Returns NULL if no crate name can be
|
||||||
|
found. */
|
||||||
|
extern char *rust_crate_for_block (const struct block *block);
|
||||||
|
|
||||||
|
/* Create a new slice type. NAME is the name of the type. ELT_TYPE
|
||||||
|
is the type of the elements of the slice. USIZE_TYPE is the Rust
|
||||||
|
"usize" type to use. The new type is allocated whereever ELT_TYPE
|
||||||
|
is allocated. */
|
||||||
|
struct type *rust_slice_type (const char *name, struct type *elt_type,
|
||||||
|
struct type *usize_type);
|
||||||
|
|
||||||
|
#endif /* RUST_LANG_H */
|
|
@ -266,6 +266,9 @@ OP (OP_M2_STRING) /* Modula-2 string constants */
|
||||||
OP (STRUCTOP_STRUCT)
|
OP (STRUCTOP_STRUCT)
|
||||||
OP (STRUCTOP_PTR)
|
OP (STRUCTOP_PTR)
|
||||||
|
|
||||||
|
/* Anonymous field access, e.g. "foo.3". Used in Rust. */
|
||||||
|
OP (STRUCTOP_ANONYMOUS)
|
||||||
|
|
||||||
/* C++: OP_THIS is just a placeholder for the class instance variable.
|
/* C++: OP_THIS is just a placeholder for the class instance variable.
|
||||||
It just comes in a tight (OP_THIS, OP_THIS) pair. */
|
It just comes in a tight (OP_THIS, OP_THIS) pair. */
|
||||||
OP (OP_THIS)
|
OP (OP_THIS)
|
||||||
|
@ -312,3 +315,7 @@ OP (OP_DECLTYPE)
|
||||||
|
|
||||||
/* The typeid operator. This has one expression argument. */
|
/* The typeid operator. This has one expression argument. */
|
||||||
OP (OP_TYPEID)
|
OP (OP_TYPEID)
|
||||||
|
|
||||||
|
/* This is used for the Rust [expr; N] form of array construction. It
|
||||||
|
takes two expression arguments. */
|
||||||
|
OP (OP_RUST_ARRAY)
|
||||||
|
|
|
@ -2864,6 +2864,7 @@ init_filename_language_table (void)
|
||||||
add_filename_language (".a", language_ada);
|
add_filename_language (".a", language_ada);
|
||||||
add_filename_language (".ada", language_ada);
|
add_filename_language (".ada", language_ada);
|
||||||
add_filename_language (".dg", language_ada);
|
add_filename_language (".dg", language_ada);
|
||||||
|
add_filename_language (".rs", language_rust);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -763,6 +763,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gsymbol->language == language_cplus
|
if (gsymbol->language == language_cplus
|
||||||
|
|| gsymbol->language == language_rust
|
||||||
|| gsymbol->language == language_auto)
|
|| gsymbol->language == language_auto)
|
||||||
{
|
{
|
||||||
demangled =
|
demangled =
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2016-05-17 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
* gdb.base/default.exp (set language): Add rust.
|
||||||
|
|
||||||
2016-05-17 Tom Tromey <tom@tromey.com>
|
2016-05-17 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* gdb.gdb/unittest.exp: New file.
|
* gdb.gdb/unittest.exp: New file.
|
||||||
|
|
|
@ -511,7 +511,7 @@ gdb_test "set history size" "Argument required .integer to set it to.*" "set his
|
||||||
#test set history
|
#test set history
|
||||||
gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set history"
|
gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set history"
|
||||||
#test set language
|
#test set language
|
||||||
gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, c, c.., asm, minimal, d, fortran, objective-c, go, java, modula-2, opencl, pascal." "set language"
|
gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, c, c.., asm, minimal, d, fortran, objective-c, go, java, modula-2, opencl, pascal, rust." "set language"
|
||||||
#test set listsize
|
#test set listsize
|
||||||
gdb_test "set listsize" "Argument required .integer to set it to.*" "set listsize"
|
gdb_test "set listsize" "Argument required .integer to set it to.*" "set listsize"
|
||||||
#test set print "p" abbreviation
|
#test set print "p" abbreviation
|
||||||
|
|
Loading…
Reference in a new issue