2002-09-18 Michael Snyder <msnyder@redhat.com>
Preliminary support for Objective-C: * defs.h (language_objc): New enum value. (puts_filtered_tabular): Declaration only, exported from utils.c. (skip_quoted): Delete, declared in completer.h. * c-exp.y: Include completer.h. * p-exp.y: Ditto. * jv-exp.y: Ditto. * expression.h (OP_MSGCALL, OP_SELECTOR, OP_SELF, OP_NSSTRING): New operator enum values. * language.h (CAST_IS_CONVERSION): Test for language_objc. * language.c (binop_result_type): Handle language_objc case. (integral_type, character_type, string_type, boolean_type, structured_type, binop_type_check): Ditto. * symtab.h (SYMBOL_OBJC_DEMANGLED_NAME): Define. (struct objc_specific): Add to general_symbol_info. (SYMBOL_INIT_LANGUAGE_SPECIFIC): Add objc initialization. (SYMBOL_DEMANGLED_NAME): Handle objc case. * parser-defs.h (struct objc_class_str): New struct type. (start_msglist, end_msglist, add_msglist): Declaration only, exported from objc-lang.c. * value.h (value_of_local, value_nsstring, call_function_by_hand_expecting_type): Exported from valops.c. * valops.c (find_function_addr): Export. (call_function_by_hand_expecting_type): New function. (value_of_local): New function. * symfile.c (init_filename_language_table): Add ".m" extension for Objective-C. * utils.c (puts_filtered_tabular): New function. (fprintf_symbol_filtered): Add objc demangling support (disabled). (set/show demangle): Extend help-string to refer to ObjC. * elfread.c (elf_symtab_read): Skip Objective-C special symbols. * stabsread.c (symbol_reference_defined): Objective-C symbols may contain colons: make allowances when scanning stabs strings for colons. (objc_find_colon): New function. * printcmd.c (address_info): If language == objc then print "self" instead of "this". * parse.c (length_of_subexp): Handle new operators OP_MSGCALL, OP_NSSTRING, and OP_SELF. (prefixify_subexp): Ditto. * source.c (print_source_lines): Mention objc in comment. * breakpoint.c (parse_breakpoint_sals): Recognize Objective-C method names.
This commit is contained in:
parent
b9caf5053f
commit
3b4efeaa2d
21 changed files with 446 additions and 184 deletions
|
@ -1,3 +1,49 @@
|
|||
2002-09-18 Michael Snyder <msnyder@redhat.com>
|
||||
|
||||
Preliminary support for Objective-C:
|
||||
* defs.h (language_objc): New enum value.
|
||||
(puts_filtered_tabular): Declaration only, exported from utils.c.
|
||||
(skip_quoted): Delete, declared in completer.h.
|
||||
* c-exp.y: Include completer.h.
|
||||
* p-exp.y: Ditto.
|
||||
* jv-exp.y: Ditto.
|
||||
* expression.h (OP_MSGCALL, OP_SELECTOR, OP_SELF, OP_NSSTRING):
|
||||
New operator enum values.
|
||||
* language.h (CAST_IS_CONVERSION): Test for language_objc.
|
||||
* language.c (binop_result_type): Handle language_objc case.
|
||||
(integral_type, character_type, string_type, boolean_type,
|
||||
structured_type, binop_type_check): Ditto.
|
||||
* symtab.h (SYMBOL_OBJC_DEMANGLED_NAME): Define.
|
||||
(struct objc_specific): Add to general_symbol_info.
|
||||
(SYMBOL_INIT_LANGUAGE_SPECIFIC): Add objc initialization.
|
||||
(SYMBOL_DEMANGLED_NAME): Handle objc case.
|
||||
* parser-defs.h (struct objc_class_str): New struct type.
|
||||
(start_msglist, end_msglist, add_msglist): Declaration only,
|
||||
exported from objc-lang.c.
|
||||
* value.h (value_of_local, value_nsstring,
|
||||
call_function_by_hand_expecting_type): Exported from valops.c.
|
||||
* valops.c (find_function_addr): Export.
|
||||
(call_function_by_hand_expecting_type): New function.
|
||||
(value_of_local): New function.
|
||||
* symfile.c (init_filename_language_table): Add ".m" extension
|
||||
for Objective-C.
|
||||
* utils.c (puts_filtered_tabular): New function.
|
||||
(fprintf_symbol_filtered): Add objc demangling support (disabled).
|
||||
(set/show demangle): Extend help-string to refer to ObjC.
|
||||
* elfread.c (elf_symtab_read): Skip Objective-C special symbols.
|
||||
* stabsread.c (symbol_reference_defined): Objective-C symbols
|
||||
may contain colons: make allowances when scanning stabs strings
|
||||
for colons.
|
||||
(objc_find_colon): New function.
|
||||
* printcmd.c (address_info): If language == objc then print
|
||||
"self" instead of "this".
|
||||
* parse.c (length_of_subexp): Handle new operators OP_MSGCALL,
|
||||
OP_NSSTRING, and OP_SELF.
|
||||
(prefixify_subexp): Ditto.
|
||||
* source.c (print_source_lines): Mention objc in comment.
|
||||
* breakpoint.c (parse_breakpoint_sals): Recognize Objective-C
|
||||
method names.
|
||||
|
||||
2002-09-18 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* complaints.h: Update copyright.
|
||||
|
|
|
@ -4618,13 +4618,16 @@ parse_breakpoint_sals (char **address,
|
|||
current_source_symtab (which is decode_line_1's default). This
|
||||
should produce the results we want almost all of the time while
|
||||
leaving default_breakpoint_* alone. */
|
||||
/* Also ignore objc method name. FIXME better comment? */
|
||||
if (default_breakpoint_valid
|
||||
&& (!current_source_symtab
|
||||
|| (strchr ("+-", (*address)[0]) != NULL)))
|
||||
|| ((strchr ("+-", (*address)[0]) != NULL)
|
||||
&& ((*address)[1] != '['))))
|
||||
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
|
||||
default_breakpoint_line, addr_string);
|
||||
else
|
||||
*sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
|
||||
*sals = decode_line_1 (address, 1, (struct symtab *) NULL,
|
||||
0, addr_string);
|
||||
}
|
||||
/* For any SAL that didn't have a canonical string, fill one in. */
|
||||
if (sals->nelts > 0 && *addr_string == NULL)
|
||||
|
|
|
@ -49,6 +49,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "bfd.h" /* Required by objfiles.h. */
|
||||
#include "symfile.h" /* Required by objfiles.h. */
|
||||
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
|
||||
#include "completer.h" /* For skip_quoted(). */
|
||||
|
||||
/* Flag indicating we're dealing with HP-compiled objects */
|
||||
extern int hp_som_som_object_present;
|
||||
|
|
|
@ -208,6 +208,7 @@ enum language
|
|||
language_auto, /* Placeholder for automatic setting */
|
||||
language_c, /* C */
|
||||
language_cplus, /* C++ */
|
||||
language_objc, /* Objective-C */
|
||||
language_java, /* Java */
|
||||
/* OBSOLETE language_chill, */ /* Chill */
|
||||
language_fortran, /* Fortran */
|
||||
|
@ -445,6 +446,8 @@ extern void puts_filtered (const char *);
|
|||
|
||||
extern void puts_unfiltered (const char *);
|
||||
|
||||
extern void puts_filtered_tabular (char *string, int width, int right);
|
||||
|
||||
extern void puts_debug (char *prefix, char *string, char *suffix);
|
||||
|
||||
extern void vprintf_filtered (const char *, va_list) ATTR_FORMAT (printf, 1, 0);
|
||||
|
@ -531,8 +534,6 @@ extern void print_transfer_performance (struct ui_file *stream,
|
|||
|
||||
typedef void initialize_file_ftype (void);
|
||||
|
||||
extern char *skip_quoted (char *);
|
||||
|
||||
extern char *gdb_readline (char *);
|
||||
|
||||
extern char *gdb_readline_wrapper (char *);
|
||||
|
|
|
@ -349,7 +349,13 @@ elf_symtab_read (struct objfile *objfile, int dynamic)
|
|||
}
|
||||
else if (sym->section->flags & SEC_CODE)
|
||||
{
|
||||
if (sym->flags & BSF_GLOBAL)
|
||||
if (sym->name[0] == '.'
|
||||
&& (strncmp (sym->name + 1, "objc_", 4) == 0))
|
||||
{
|
||||
/* Looks like an Objective-C special symbol */
|
||||
continue;
|
||||
}
|
||||
else if (sym->flags & BSF_GLOBAL)
|
||||
{
|
||||
ms_type = mst_text;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,12 @@ enum exp_opcode
|
|||
making three exp_elements. */
|
||||
OP_FUNCALL,
|
||||
|
||||
/* OP_MSGCALL is followed by a string in the next exp_element and then an
|
||||
integer. The string is the selector string. The integer is the number
|
||||
of arguments to the message call. That many plus one values are used,
|
||||
the first one being the object pointer. This is an Objective C message */
|
||||
OP_MSGCALL,
|
||||
|
||||
/* This is EXACTLY like OP_FUNCALL but is semantically different.
|
||||
In F77, array subscript expressions, substring expressions
|
||||
and function calls are all exactly the same syntactically. They may
|
||||
|
@ -273,11 +279,18 @@ enum exp_opcode
|
|||
STRUCTOP_STRUCT,
|
||||
STRUCTOP_PTR,
|
||||
|
||||
/* 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. */
|
||||
OP_THIS,
|
||||
|
||||
/* Objective C: "@selector" pseudo-operator */
|
||||
OP_SELECTOR,
|
||||
|
||||
/* Objective C: OP_SELF is just a placeholder for the class instance
|
||||
variable. It just comes in a tight (OP_SELF, OP_SELF) pair. */
|
||||
OP_SELF,
|
||||
|
||||
/* OP_SCOPE surrounds a type name and a field name. The type
|
||||
name is encoded as one element, but the field name stays as
|
||||
a string, which, of course, is variable length. */
|
||||
|
@ -305,7 +318,10 @@ enum exp_opcode
|
|||
OP_NAME,
|
||||
|
||||
/* An unparsed expression. Used for Scheme (for now at least) */
|
||||
OP_EXPRSTRING
|
||||
OP_EXPRSTRING,
|
||||
|
||||
/* An Objective C Foundation Class NSString constant */
|
||||
OP_NSSTRING
|
||||
};
|
||||
|
||||
union exp_element
|
||||
|
@ -350,7 +366,7 @@ extern struct block *innermost_block;
|
|||
|
||||
/* From eval.c */
|
||||
|
||||
/* Values of NOSIDE argument to eval_subexp. */
|
||||
/* Values of NOSIDE argument to evaluate_subexp. */
|
||||
|
||||
enum noside
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "bfd.h" /* Required by objfiles.h. */
|
||||
#include "symfile.h" /* Required by objfiles.h. */
|
||||
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
|
||||
#include "completer.h" /* For skip_quoted(). */
|
||||
|
||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
||||
as well as gratuitiously global symbol names, so we can have multiple
|
||||
|
|
|
@ -549,6 +549,7 @@ binop_result_type (struct value *v1, struct value *v2)
|
|||
{
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
if (TYPE_CODE (t1) == TYPE_CODE_FLT)
|
||||
return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
|
||||
VALUE_TYPE (v2) : VALUE_TYPE (v1);
|
||||
|
@ -786,6 +787,7 @@ integral_type (struct type *type)
|
|||
{
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
return (TYPE_CODE (type) != TYPE_CODE_INT) &&
|
||||
(TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
|
||||
case language_m2:
|
||||
|
@ -828,6 +830,7 @@ character_type (struct type *type)
|
|||
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
return (TYPE_CODE (type) == TYPE_CODE_INT) &&
|
||||
TYPE_LENGTH (type) == sizeof (char)
|
||||
? 1 : 0;
|
||||
|
@ -850,6 +853,7 @@ string_type (struct type *type)
|
|||
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
/* C does not have distinct string type. */
|
||||
return (0);
|
||||
default:
|
||||
|
@ -868,6 +872,7 @@ boolean_type (struct type *type)
|
|||
{
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
/* Might be more cleanly handled by having a
|
||||
TYPE_CODE_INT_NOT_BOOL for (OBSOLETE) CHILL and such
|
||||
languages, or a TYPE_CODE_INT_OR_BOOL for C. */
|
||||
|
@ -904,6 +909,7 @@ structured_type (struct type *type)
|
|||
{
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
|
||||
(TYPE_CODE (type) == TYPE_CODE_UNION) ||
|
||||
(TYPE_CODE (type) == TYPE_CODE_ARRAY);
|
||||
|
@ -1124,6 +1130,7 @@ binop_type_check (struct value *arg1, struct value *arg2, int op)
|
|||
#ifdef _LANG_c
|
||||
case language_c:
|
||||
case language_cplus:
|
||||
case language_objc:
|
||||
switch (op)
|
||||
{
|
||||
case BINOP_DIV:
|
||||
|
|
|
@ -288,7 +288,8 @@ language_mode;
|
|||
/* "cast" really means conversion */
|
||||
/* FIXME -- should be a setting in language_defn */
|
||||
#define CAST_IS_CONVERSION (current_language->la_language == language_c || \
|
||||
current_language->la_language == language_cplus)
|
||||
current_language->la_language == language_cplus || \
|
||||
current_language->la_language == language_objc)
|
||||
|
||||
extern void language_info (int);
|
||||
|
||||
|
|
289
gdb/objc-exp.y
289
gdb/objc-exp.y
|
@ -18,22 +18,21 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Parse a C expression from text in a string,
|
||||
and return the result as a struct expression pointer.
|
||||
That structure contains arithmetic operations in reverse polish,
|
||||
with constants represented by operations that are followed by special data.
|
||||
See expression.h for the details of the format.
|
||||
What is important here is that it can be built up sequentially
|
||||
during the process of parsing; the lower levels of the tree always
|
||||
come first in the result.
|
||||
/* Parse a C expression from text in a string, and return the result
|
||||
as a struct expression pointer. That structure contains arithmetic
|
||||
operations in reverse polish, with constants represented by
|
||||
operations that are followed by special data. See expression.h for
|
||||
the details of the format. What is important here is that it can
|
||||
be built up sequentially during the process of parsing; the lower
|
||||
levels of the tree always come first in the result.
|
||||
|
||||
Note that malloc's and realloc's in this file are transformed to
|
||||
xmalloc and xrealloc respectively by the same sed command in the
|
||||
makefile that remaps any other malloc/realloc inserted by the parser
|
||||
generator. Doing this with #defines and trying to control the interaction
|
||||
with include files (<malloc.h> and <stdlib.h> for example) just became
|
||||
too messy, particularly when such includes can be inserted at random
|
||||
times by the parser generator. */
|
||||
makefile that remaps any other malloc/realloc inserted by the
|
||||
parser generator. Doing this with #defines and trying to control
|
||||
the interaction with include files (<malloc.h> and <stdlib.h> for
|
||||
example) just became too messy, particularly when such includes can
|
||||
be inserted at random times by the parser generator. */
|
||||
|
||||
%{
|
||||
|
||||
|
@ -42,7 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include <ctype.h>
|
||||
#include "expression.h"
|
||||
|
||||
#include "objc-lang.h" /* for objc language constructs */
|
||||
#include "objc-lang.h" /* For objc language constructs. */
|
||||
|
||||
#include "value.h"
|
||||
#include "parser-defs.h"
|
||||
|
@ -50,16 +49,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "c-lang.h"
|
||||
#include "bfd.h" /* Required by objfiles.h. */
|
||||
#include "symfile.h" /* Required by objfiles.h. */
|
||||
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
|
||||
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols. */
|
||||
#include "top.h"
|
||||
#include "completer.h" /* For skip_quoted(). */
|
||||
|
||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
||||
as well as gratuitiously global symbol names, so we can have multiple
|
||||
yacc generated parsers in gdb. Note that these are only the variables
|
||||
produced by yacc. If other parser generators (bison, byacc, etc) produce
|
||||
additional global names that conflict at link time, then those parser
|
||||
generators need to be fixed instead of adding those names to this list. */
|
||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
|
||||
etc), as well as gratuitiously global symbol names, so we can have
|
||||
multiple yacc generated parsers in gdb. Note that these are only
|
||||
the variables produced by yacc. If other parser generators (bison,
|
||||
byacc, etc) produce additional global names that conflict at link
|
||||
time, then those parser generators need to be fixed instead of
|
||||
adding those names to this list. */
|
||||
|
||||
#define yymaxdepth objc_maxdepth
|
||||
#define yyparse objc_parse
|
||||
|
@ -103,7 +103,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#define yycheck objc_yycheck
|
||||
|
||||
#ifndef YYDEBUG
|
||||
#define YYDEBUG 0 /* Default to no yydebug support */
|
||||
#define YYDEBUG 0 /* Default to no yydebug support. */
|
||||
#endif
|
||||
|
||||
int
|
||||
|
@ -148,7 +148,7 @@ yyerror PARAMS ((char *));
|
|||
}
|
||||
|
||||
%{
|
||||
/* YYSTYPE gets defined by %union */
|
||||
/* YYSTYPE gets defined by %union. */
|
||||
static int
|
||||
parse_number PARAMS ((char *, int, int, YYSTYPE *));
|
||||
%}
|
||||
|
@ -167,13 +167,12 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
|
|||
%token <typed_val_int> INT
|
||||
%token <typed_val_float> FLOAT
|
||||
|
||||
/* Both NAME and TYPENAME tokens represent symbols in the input,
|
||||
and both convey their data as strings.
|
||||
But a TYPENAME is a string that happens to be defined as a typedef
|
||||
or builtin type name (such as int or char)
|
||||
and a NAME is any other symbol.
|
||||
Contexts where this distinction is not important can use the
|
||||
nonterminal "name", which matches either NAME or TYPENAME. */
|
||||
/* Both NAME and TYPENAME tokens represent symbols in the input, and
|
||||
both convey their data as strings. But a TYPENAME is a string that
|
||||
happens to be defined as a typedef or builtin type name (such as
|
||||
int or char) and a NAME is any other symbol. Contexts where this
|
||||
distinction is not important can use the nonterminal "name", which
|
||||
matches either NAME or TYPENAME. */
|
||||
|
||||
%token <sval> STRING
|
||||
%token <sval> NSSTRING /* ObjC Foundation "NSString" literal */
|
||||
|
@ -196,8 +195,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
|
|||
%token TEMPLATE
|
||||
%token ERROR
|
||||
|
||||
/* Special type cases, put in to allow the parser to distinguish different
|
||||
legal basetypes. */
|
||||
/* Special type cases, put in to allow the parser to distinguish
|
||||
different legal basetypes. */
|
||||
%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
|
||||
|
||||
%token <voidval> VARIABLE
|
||||
|
@ -386,9 +385,9 @@ msgarglist : msgarg
|
|||
|
||||
msgarg : name ':' exp
|
||||
{ add_msglist(&$1, 1); }
|
||||
| ':' exp /* unnamed arg */
|
||||
| ':' exp /* Unnamed arg. */
|
||||
{ add_msglist(0, 1); }
|
||||
| ',' exp /* variable number of args */
|
||||
| ',' exp /* Variable number of args. */
|
||||
{ add_msglist(0, 0); }
|
||||
;
|
||||
|
||||
|
@ -564,7 +563,7 @@ exp : variable
|
|||
;
|
||||
|
||||
exp : VARIABLE
|
||||
/* Already written by write_dollar_variable. */
|
||||
/* Already written by write_dollar_variable. */
|
||||
;
|
||||
|
||||
exp : SELECTOR
|
||||
|
@ -582,11 +581,12 @@ exp : SIZEOF '(' type ')' %prec UNARY
|
|||
;
|
||||
|
||||
exp : STRING
|
||||
{ /* C strings are converted into array constants with
|
||||
an explicit null byte added at the end. Thus
|
||||
the array upper bound is the string length.
|
||||
There is no such thing in C as a completely empty
|
||||
string. */
|
||||
{ /* C strings are converted into array
|
||||
constants with an explicit null byte
|
||||
added at the end. Thus the array upper
|
||||
bound is the string length. There is no
|
||||
such thing in C as a completely empty
|
||||
string. */
|
||||
char *sp = $1.ptr; int count = $1.length;
|
||||
while (count-- > 0)
|
||||
{
|
||||
|
@ -606,7 +606,7 @@ exp : STRING
|
|||
;
|
||||
|
||||
exp : NSSTRING /* ObjC NextStep NSString constant
|
||||
* of the form '@' '"' string '"'
|
||||
* of the form '@' '"' string '"'.
|
||||
*/
|
||||
{ write_exp_elt_opcode (OP_NSSTRING);
|
||||
write_exp_string ($1);
|
||||
|
@ -798,11 +798,11 @@ variable: name_not_typename
|
|||
|
||||
|
||||
ptype : typebase
|
||||
/* "const" and "volatile" are curently ignored. A type qualifier
|
||||
before the type is currently handled in the typebase rule.
|
||||
The reason for recognizing these here (shift/reduce conflicts)
|
||||
might be obsolete now that some pointer to member rules have
|
||||
been deleted. */
|
||||
/* "const" and "volatile" are curently ignored. A type
|
||||
qualifier before the type is currently handled in the
|
||||
typebase rule. The reason for recognizing these here
|
||||
(shift/reduce conflicts) might be obsolete now that some
|
||||
pointer to member rules have been deleted. */
|
||||
| typebase CONST_KEYWORD
|
||||
| typebase VOLATILE_KEYWORD
|
||||
| typebase abs_decl
|
||||
|
@ -857,8 +857,8 @@ func_mod: '(' ')'
|
|||
;
|
||||
|
||||
/* We used to try to recognize more pointer to member types here, but
|
||||
that didn't work (shift/reduce conflicts meant that these rules never
|
||||
got executed). The problem is that
|
||||
that didn't work (shift/reduce conflicts meant that these rules
|
||||
never got executed). The problem is that
|
||||
int (foo::bar::baz::bizzle)
|
||||
is a function type but
|
||||
int (foo::bar::baz::bizzle::*)
|
||||
|
@ -869,7 +869,7 @@ type : ptype
|
|||
{ $$ = lookup_member_type (builtin_type_int, $1); }
|
||||
;
|
||||
|
||||
typebase /* Implements (approximately): (type-qualifier)* type-specifier */
|
||||
typebase /* Implements (approximately): (type-qualifier)* type-specifier. */
|
||||
: TYPENAME
|
||||
{ $$ = $1.type; }
|
||||
| CLASSNAME
|
||||
|
@ -930,9 +930,9 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
|
|||
{ $$ = lookup_template_type(copy_name($2), $4,
|
||||
expression_context_block);
|
||||
}
|
||||
/* "const" and "volatile" are curently ignored. A type qualifier
|
||||
after the type is handled in the ptype rule. I think these could
|
||||
be too. */
|
||||
/* "const" and "volatile" are curently ignored. A type
|
||||
qualifier after the type is handled in the ptype rule. I
|
||||
think these could be too. */
|
||||
| CONST_KEYWORD typebase { $$ = $2; }
|
||||
| VOLATILE_KEYWORD typebase { $$ = $2; }
|
||||
;
|
||||
|
@ -961,7 +961,7 @@ typename: TYPENAME
|
|||
nonempty_typelist
|
||||
: type
|
||||
{ $$ = (struct type **) malloc (sizeof (struct type *) * 2);
|
||||
$<ivec>$[0] = 1; /* Number of types in vector */
|
||||
$<ivec>$[0] = 1; /* Number of types in vector. */
|
||||
$$[1] = $1;
|
||||
}
|
||||
| nonempty_typelist ',' type
|
||||
|
@ -980,22 +980,22 @@ name : NAME { $$ = $1.stoken; }
|
|||
|
||||
name_not_typename : NAME
|
||||
| BLOCKNAME
|
||||
/* These would be useful if name_not_typename was useful, but it is just
|
||||
a fake for "variable", so these cause reduce/reduce conflicts because
|
||||
the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
|
||||
=exp) or just an exp. If name_not_typename was ever used in an lvalue
|
||||
context where only a name could occur, this might be useful.
|
||||
| NAME_OR_INT
|
||||
*/
|
||||
/* These would be useful if name_not_typename was useful, but it is
|
||||
just a fake for "variable", so these cause reduce/reduce conflicts
|
||||
because the parser can't tell whether NAME_OR_INT is a
|
||||
name_not_typename (=variable, =exp) or just an exp. If
|
||||
name_not_typename was ever used in an lvalue context where only a
|
||||
name could occur, this might be useful. */
|
||||
| NAME_OR_INT */
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
/* Take care of parsing a number (anything that starts with a digit).
|
||||
Set yylval and return the token type; update lexptr.
|
||||
LEN is the number of characters in it. */
|
||||
Set yylval and return the token type; update lexptr. LEN is the
|
||||
number of characters in it. */
|
||||
|
||||
/*** Needs some error checking for the float case ***/
|
||||
/*** Needs some error checking for the float case. ***/
|
||||
|
||||
static int
|
||||
parse_number (p, len, parsed_float, putithere)
|
||||
|
@ -1004,8 +1004,9 @@ parse_number (p, len, parsed_float, putithere)
|
|||
int parsed_float;
|
||||
YYSTYPE *putithere;
|
||||
{
|
||||
/* FIXME: Shouldn't these be unsigned? We don't deal with negative values
|
||||
here, and we do kind of silly things like cast to unsigned. */
|
||||
/* FIXME: Shouldn't these be unsigned? We don't deal with negative
|
||||
values here, and we do kind of silly things like cast to
|
||||
unsigned. */
|
||||
register LONGEST n = 0;
|
||||
register LONGEST prevn = 0;
|
||||
unsigned LONGEST un;
|
||||
|
@ -1042,7 +1043,7 @@ parse_number (p, len, parsed_float, putithere)
|
|||
#else
|
||||
/* Scan it into a double, then assign it to the long double.
|
||||
This at least wins with values representable in the range
|
||||
of doubles. */
|
||||
of doubles. */
|
||||
double temp;
|
||||
sscanf (p, "%lg", &temp);
|
||||
putithere->typed_val_float.dval = temp;
|
||||
|
@ -1065,7 +1066,7 @@ parse_number (p, len, parsed_float, putithere)
|
|||
return FLOAT;
|
||||
}
|
||||
|
||||
/* Handle base-switching prefixes 0x, 0t, 0d, 0 */
|
||||
/* Handle base-switching prefixes 0x, 0t, 0d, and 0. */
|
||||
if (p[0] == '0')
|
||||
switch (p[1])
|
||||
{
|
||||
|
@ -1128,20 +1129,20 @@ parse_number (p, len, parsed_float, putithere)
|
|||
found_suffix = 1;
|
||||
}
|
||||
else
|
||||
return ERROR; /* Char not a digit */
|
||||
return ERROR; /* Char not a digit. */
|
||||
}
|
||||
if (i >= base)
|
||||
return ERROR; /* Invalid digit in this base */
|
||||
return ERROR; /* Invalid digit in this base. */
|
||||
|
||||
/* Portably test for overflow (only works for nonzero values, so make
|
||||
a second check for zero). FIXME: Can't we just make n and prevn
|
||||
unsigned and avoid this? */
|
||||
/* Portably test for overflow (only works for nonzero values, so
|
||||
make a second check for zero). FIXME: Can't we just make n
|
||||
and prevn unsigned and avoid this? */
|
||||
if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
|
||||
unsigned_p = 1; /* Try something unsigned */
|
||||
unsigned_p = 1; /* Try something unsigned. */
|
||||
|
||||
/* Portably test for unsigned overflow.
|
||||
FIXME: This check is wrong; for example it doesn't find overflow
|
||||
on 0x123456789 when LONGEST is 32 bits. */
|
||||
FIXME: This check is wrong; for example it doesn't find
|
||||
overflow on 0x123456789 when LONGEST is 32 bits. */
|
||||
if (c != 'l' && c != 'u' && n != 0)
|
||||
{
|
||||
if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
|
||||
|
@ -1201,7 +1202,7 @@ parse_number (p, len, parsed_float, putithere)
|
|||
putithere->typed_val_int.val = n;
|
||||
|
||||
/* If the high bit of the worked out type is set then this number
|
||||
has to be unsigned. */
|
||||
has to be unsigned. */
|
||||
|
||||
if (unsigned_p || (n & high_bit))
|
||||
{
|
||||
|
@ -1299,9 +1300,9 @@ yylex ()
|
|||
goto retry;
|
||||
|
||||
case '\'':
|
||||
/* We either have a character constant ('0' or '\177' for example)
|
||||
or we have a quoted symbol reference ('foo(int,int)' in C++
|
||||
for example). */
|
||||
/* We either have a character constant ('0' or '\177' for
|
||||
example) or we have a quoted symbol reference ('foo(int,int)'
|
||||
in C++ for example). */
|
||||
lexptr++;
|
||||
c = *lexptr++;
|
||||
if (c == '\\')
|
||||
|
@ -1352,7 +1353,7 @@ yylex ()
|
|||
case '.':
|
||||
/* Might be a floating point number. */
|
||||
if (lexptr[1] < '0' || lexptr[1] > '9')
|
||||
goto symbol; /* Nope, must be a symbol. */
|
||||
goto symbol; /* Nope, must be a symbol. */
|
||||
/* FALL THRU into number case. */
|
||||
|
||||
case '0':
|
||||
|
@ -1368,7 +1369,7 @@ yylex ()
|
|||
{
|
||||
/* It's a number. */
|
||||
int got_dot = 0, got_e = 0, toktype = FLOAT;
|
||||
/* initialize toktype to anything other than ERROR. */
|
||||
/* Initialize toktype to anything other than ERROR. */
|
||||
register char *p = tokstart;
|
||||
int hex = input_radix > 10;
|
||||
int local_radix = input_radix;
|
||||
|
@ -1393,14 +1394,15 @@ yylex ()
|
|||
|
||||
if (!hex && (*p == 'e' || *p == 'E'))
|
||||
if (got_e)
|
||||
toktype = ERROR; /* only one 'e' in a float */
|
||||
toktype = ERROR; /* Only one 'e' in a float. */
|
||||
else
|
||||
got_e = 1;
|
||||
/* This test does not include !hex, because a '.' always indicates
|
||||
a decimal floating point number regardless of the radix. */
|
||||
/* This test does not include !hex, because a '.' always
|
||||
indicates a decimal floating point number regardless of
|
||||
the radix. */
|
||||
else if (*p == '.')
|
||||
if (got_dot)
|
||||
toktype = ERROR; /* only one '.' in a float */
|
||||
toktype = ERROR; /* Only one '.' in a float. */
|
||||
else
|
||||
got_dot = 1;
|
||||
else if (got_e && (p[-1] == 'e' || p[-1] == 'E') &&
|
||||
|
@ -1408,24 +1410,28 @@ yylex ()
|
|||
/* This is the sign of the exponent, not the end of the
|
||||
number. */
|
||||
continue;
|
||||
/* Always take decimal digits; parse_number handles radix error */
|
||||
/* Always take decimal digits; parse_number handles radix
|
||||
error. */
|
||||
else if (*p >= '0' && *p <= '9')
|
||||
continue;
|
||||
/* We will take letters only if hex is true, and only
|
||||
up to what the input radix would permit. FSF was content
|
||||
to rely on parse_number to validate; but it leaks. */
|
||||
else if (*p >= 'a' && *p <= 'z') {
|
||||
if (!hex || *p >= ('a' + local_radix - 10))
|
||||
toktype = ERROR;
|
||||
}
|
||||
else if (*p >= 'A' && *p <= 'Z') {
|
||||
if (!hex || *p >= ('A' + local_radix - 10))
|
||||
toktype = ERROR;
|
||||
}
|
||||
/* We will take letters only if hex is true, and only up
|
||||
to what the input radix would permit. FSF was content
|
||||
to rely on parse_number to validate; but it leaks. */
|
||||
else if (*p >= 'a' && *p <= 'z')
|
||||
{
|
||||
if (!hex || *p >= ('a' + local_radix - 10))
|
||||
toktype = ERROR;
|
||||
}
|
||||
else if (*p >= 'A' && *p <= 'Z')
|
||||
{
|
||||
if (!hex || *p >= ('A' + local_radix - 10))
|
||||
toktype = ERROR;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if (toktype != ERROR)
|
||||
toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
|
||||
toktype = parse_number (tokstart, p - tokstart,
|
||||
got_dot | got_e, &yylval);
|
||||
if (toktype == ERROR)
|
||||
{
|
||||
char *err_copy = (char *) alloca (p - tokstart + 1);
|
||||
|
@ -1449,7 +1455,7 @@ yylex ()
|
|||
case '~':
|
||||
case '!':
|
||||
#if 0
|
||||
case '@': /* moved out below */
|
||||
case '@': /* Moved out below. */
|
||||
#endif
|
||||
case '<':
|
||||
case '>':
|
||||
|
@ -1473,10 +1479,10 @@ yylex ()
|
|||
error ("Missing '(' in @selector(...)");
|
||||
}
|
||||
tempbufindex = 0;
|
||||
tokptr++; /* skip the '(' */
|
||||
tokptr++; /* Skip the '('. */
|
||||
do {
|
||||
/* Grow the static temp buffer if necessary, including allocating
|
||||
the first one on demand. */
|
||||
/* Grow the static temp buffer if necessary, including
|
||||
allocating the first one on demand. */
|
||||
if (tempbufindex + 1 >= tempbufsize)
|
||||
{
|
||||
tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
|
||||
|
@ -1498,7 +1504,8 @@ yylex ()
|
|||
lexptr++;
|
||||
return tokchr;
|
||||
}
|
||||
/* ObjC NextStep NSString constant: fall thru and parse like STRING */
|
||||
/* ObjC NextStep NSString constant: fall thru and parse like
|
||||
STRING. */
|
||||
tokstart++;
|
||||
|
||||
case '"':
|
||||
|
@ -1508,16 +1515,17 @@ yylex ()
|
|||
buffer is null byte terminated *only* for the convenience of
|
||||
debugging gdb itself and printing the buffer contents when
|
||||
the buffer contains no embedded nulls. Gdb does not depend
|
||||
upon the buffer being null byte terminated, it uses the length
|
||||
string instead. This allows gdb to handle C strings (as well
|
||||
as strings in other languages) with embedded null bytes */
|
||||
upon the buffer being null byte terminated, it uses the
|
||||
length string instead. This allows gdb to handle C strings
|
||||
(as well as strings in other languages) with embedded null
|
||||
bytes. */
|
||||
|
||||
tokptr = ++tokstart;
|
||||
tempbufindex = 0;
|
||||
|
||||
do {
|
||||
/* Grow the static temp buffer if necessary, including allocating
|
||||
the first one on demand. */
|
||||
/* Grow the static temp buffer if necessary, including
|
||||
allocating the first one on demand. */
|
||||
if (tempbufindex + 1 >= tempbufsize)
|
||||
{
|
||||
tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
|
||||
|
@ -1526,7 +1534,7 @@ yylex ()
|
|||
{
|
||||
case '\0':
|
||||
case '"':
|
||||
/* Do nothing, loop will terminate. */
|
||||
/* Do nothing, loop will terminate. */
|
||||
break;
|
||||
case '\\':
|
||||
tokptr++;
|
||||
|
@ -1546,7 +1554,7 @@ yylex ()
|
|||
{
|
||||
error ("Unterminated string in expression.");
|
||||
}
|
||||
tempbuf[tempbufindex] = '\0'; /* See note above */
|
||||
tempbuf[tempbufindex] = '\0'; /* See note above. */
|
||||
yylval.sval.ptr = tempbuf;
|
||||
yylval.sval.length = tempbufindex;
|
||||
lexptr = tokptr;
|
||||
|
@ -1626,8 +1634,9 @@ yylex ()
|
|||
if (current_language->la_language == language_cplus
|
||||
&& STREQN (tokstart, "this", 4))
|
||||
{
|
||||
static const char this_name[] =
|
||||
{ CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
|
||||
static const char this_name[] = {
|
||||
CPLUS_MARKER, 't', 'h', 'i', 's', '\0'
|
||||
};
|
||||
|
||||
if (lookup_symbol (this_name, expression_context_block,
|
||||
VAR_NAMESPACE, (int *) NULL,
|
||||
|
@ -1673,9 +1682,9 @@ yylex ()
|
|||
VAR_NAMESPACE,
|
||||
need_this,
|
||||
(struct symtab **) NULL);
|
||||
/* Call lookup_symtab, not lookup_partial_symtab, in case there are
|
||||
no psymtabs (coff, xcoff, or some future change to blow away the
|
||||
psymtabs once symbols are read). */
|
||||
/* Call lookup_symtab, not lookup_partial_symtab, in case there
|
||||
are no psymtabs (coff, xcoff, or some future change to blow
|
||||
away the psymtabs once symbols are read). */
|
||||
if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
|
||||
lookup_symtab (tmp))
|
||||
{
|
||||
|
@ -1686,24 +1695,26 @@ yylex ()
|
|||
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|
||||
{
|
||||
#if 1
|
||||
/* Despite the following flaw, we need to keep this code enabled.
|
||||
Because we can get called from check_stub_method, if we don't
|
||||
handle nested types then it screws many operations in any
|
||||
program which uses nested types. */
|
||||
/* In "A::x", if x is a member function of A and there happens
|
||||
to be a type (nested or not, since the stabs don't make that
|
||||
distinction) named x, then this code incorrectly thinks we
|
||||
are dealing with nested types rather than a member function. */
|
||||
/* Despite the following flaw, we need to keep this code
|
||||
enabled. Because we can get called from
|
||||
check_stub_method, if we don't handle nested types then
|
||||
it screws many operations in any program which uses
|
||||
nested types. */
|
||||
/* In "A::x", if x is a member function of A and there
|
||||
happens to be a type (nested or not, since the stabs
|
||||
don't make that distinction) named x, then this code
|
||||
incorrectly thinks we are dealing with nested types
|
||||
rather than a member function. */
|
||||
|
||||
char *p;
|
||||
char *namestart;
|
||||
struct symbol *best_sym;
|
||||
|
||||
/* Look ahead to detect nested types. This probably should be
|
||||
done in the grammar, but trying seemed to introduce a lot
|
||||
of shift/reduce and reduce/reduce conflicts. It's possible
|
||||
that it could be done, though. Or perhaps a non-grammar, but
|
||||
less ad hoc, approach would work well. */
|
||||
/* Look ahead to detect nested types. This probably should
|
||||
be done in the grammar, but trying seemed to introduce a
|
||||
lot of shift/reduce and reduce/reduce conflicts. It's
|
||||
possible that it could be done, though. Or perhaps a
|
||||
non-grammar, but less ad hoc, approach would work well. */
|
||||
|
||||
/* Since we do not currently have any way of distinguishing
|
||||
a nested type from a non-nested one (the stabs don't tell
|
||||
|
@ -1732,9 +1743,10 @@ yylex ()
|
|||
if (p != namestart)
|
||||
{
|
||||
struct symbol *cur_sym;
|
||||
/* As big as the whole rest of the expression, which is
|
||||
at least big enough. */
|
||||
char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3);
|
||||
/* As big as the whole rest of the expression,
|
||||
which is at least big enough. */
|
||||
char *ncopy = alloca (strlen (tmp) +
|
||||
strlen (namestart) + 3);
|
||||
char *tmp1;
|
||||
|
||||
tmp1 = ncopy;
|
||||
|
@ -1744,7 +1756,8 @@ yylex ()
|
|||
tmp1 += 2;
|
||||
memcpy (tmp1, namestart, p - namestart);
|
||||
tmp1[p - namestart] = '\0';
|
||||
cur_sym = lookup_symbol (ncopy, expression_context_block,
|
||||
cur_sym = lookup_symbol (ncopy,
|
||||
expression_context_block,
|
||||
VAR_NAMESPACE, (int *) NULL,
|
||||
(struct symtab **) NULL);
|
||||
if (cur_sym)
|
||||
|
@ -1776,14 +1789,17 @@ yylex ()
|
|||
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
|
||||
return TYPENAME;
|
||||
|
||||
if (!sym) /* see if it's an ObjC classname */
|
||||
/* See if it's an ObjC classname. */
|
||||
if (!sym)
|
||||
{
|
||||
CORE_ADDR Class = lookup_objc_class(tmp);
|
||||
if (Class)
|
||||
{
|
||||
extern struct symbol *lookup_struct_typedef();
|
||||
yylval.class.class = Class;
|
||||
if ((sym = lookup_struct_typedef (tmp, expression_context_block, 1)))
|
||||
if ((sym = lookup_struct_typedef (tmp,
|
||||
expression_context_block,
|
||||
1)))
|
||||
yylval.class.type = SYMBOL_TYPE (sym);
|
||||
return CLASSNAME;
|
||||
}
|
||||
|
@ -1806,7 +1822,7 @@ yylex ()
|
|||
}
|
||||
}
|
||||
|
||||
/* Any other kind of symbol */
|
||||
/* Any other kind of symbol. */
|
||||
yylval.ssym.sym = sym;
|
||||
yylval.ssym.is_a_field_of_this = is_a_field_of_this;
|
||||
return NAME;
|
||||
|
@ -1820,5 +1836,6 @@ yyerror (msg)
|
|||
if (*lexptr == '\0')
|
||||
error("A %s near end of expression.", (msg ? msg : "error"));
|
||||
else
|
||||
error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
|
||||
error ("A %s in expression, near `%s'.", (msg ? msg : "error"),
|
||||
lexptr);
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "bfd.h" /* Required by objfiles.h. */
|
||||
#include "symfile.h" /* Required by objfiles.h. */
|
||||
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
|
||||
#include "completer.h" /* For skip_quoted(). */
|
||||
|
||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
||||
as well as gratuitiously global symbol names, so we can have multiple
|
||||
|
|
16
gdb/parse.c
16
gdb/parse.c
|
@ -867,6 +867,11 @@ length_of_subexp (register struct expression *expr, register int endpos)
|
|||
args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
break;
|
||||
|
||||
case OP_MSGCALL: /* Objective C message (method) call */
|
||||
oplen = 4;
|
||||
args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
break;
|
||||
|
||||
case UNOP_MAX:
|
||||
case UNOP_MIN:
|
||||
oplen = 3;
|
||||
|
@ -898,6 +903,8 @@ length_of_subexp (register struct expression *expr, register int endpos)
|
|||
/* fall through */
|
||||
case OP_M2_STRING:
|
||||
case OP_STRING:
|
||||
case OP_NSSTRING: /* Objective C Foundation Class NSString constant */
|
||||
case OP_SELECTOR: /* Objective C "@selector" pseudo-op */
|
||||
case OP_NAME:
|
||||
case OP_EXPRSTRING:
|
||||
oplen = longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
|
@ -936,6 +943,7 @@ length_of_subexp (register struct expression *expr, register int endpos)
|
|||
|
||||
/* C++ */
|
||||
case OP_THIS:
|
||||
case OP_SELF:
|
||||
oplen = 2;
|
||||
break;
|
||||
|
||||
|
@ -1004,6 +1012,11 @@ prefixify_subexp (register struct expression *inexpr,
|
|||
args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
|
||||
break;
|
||||
|
||||
case OP_MSGCALL: /* Objective C message (method) call */
|
||||
oplen = 4;
|
||||
args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
|
||||
break;
|
||||
|
||||
case UNOP_MIN:
|
||||
case UNOP_MAX:
|
||||
oplen = 3;
|
||||
|
@ -1034,6 +1047,8 @@ prefixify_subexp (register struct expression *inexpr,
|
|||
/* fall through */
|
||||
case OP_M2_STRING:
|
||||
case OP_STRING:
|
||||
case OP_NSSTRING: /* Objective C Foundation Class NSString constant */
|
||||
case OP_SELECTOR: /* Objective C "@selector" pseudo-op */
|
||||
case OP_NAME:
|
||||
case OP_EXPRSTRING:
|
||||
oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
|
||||
|
@ -1072,6 +1087,7 @@ prefixify_subexp (register struct expression *inexpr,
|
|||
|
||||
/* C++ */
|
||||
case OP_THIS:
|
||||
case OP_SELF:
|
||||
oplen = 2;
|
||||
break;
|
||||
|
||||
|
|
|
@ -79,6 +79,14 @@ struct symtoken
|
|||
int is_a_field_of_this;
|
||||
};
|
||||
|
||||
struct objc_class_str
|
||||
{
|
||||
struct stoken stoken;
|
||||
struct type *type;
|
||||
int class;
|
||||
};
|
||||
|
||||
|
||||
/* For parsing of complicated types.
|
||||
An array should be preceded in the list by the size of the array. */
|
||||
enum type_pieces
|
||||
|
@ -216,6 +224,11 @@ struct op_print
|
|||
|
||||
extern int target_map_name_to_register (char *, int);
|
||||
|
||||
/* for parsing Objective C */
|
||||
extern void start_msglist (void);
|
||||
extern void add_msglist (struct stoken *str, int addcolon);
|
||||
extern int end_msglist (void);
|
||||
|
||||
/* Function used to avoid direct calls to fprintf
|
||||
in the code generated by the bison parser. */
|
||||
|
||||
|
|
|
@ -1104,7 +1104,11 @@ address_info (char *exp, int from_tty)
|
|||
printf_filtered ("Symbol \"");
|
||||
fprintf_symbol_filtered (gdb_stdout, exp,
|
||||
current_language->la_language, DMGL_ANSI);
|
||||
printf_filtered ("\" is a field of the local class variable `this'\n");
|
||||
printf_filtered ("\" is a field of the local class variable ");
|
||||
if (current_language->la_language == language_objc)
|
||||
printf_filtered ("'self'\n"); /* ObjC equivalent of "this" */
|
||||
else
|
||||
printf_filtered ("'this'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1114,8 +1114,9 @@ print_source_lines (struct symtab *s, int line, int stopline, int noerror)
|
|||
|
||||
/* Print a list of files and line numbers which a user may choose from
|
||||
in order to list a function which was specified ambiguously (as with
|
||||
`list classname::overloadedfuncname', for example). The vector in
|
||||
SALS provides the filenames and line numbers. */
|
||||
`list classname::overloadedfuncname', or 'list objectiveCSelector:).
|
||||
The vector in SALS provides the filenames and line numbers.
|
||||
NOTE: some of the SALS may have no filename or line information! */
|
||||
|
||||
static void
|
||||
ambiguous_line_spec (struct symtabs_and_lines *sals)
|
||||
|
|
|
@ -1267,13 +1267,37 @@ symbol_reference_defined (char **string)
|
|||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
objc_find_colon (name)
|
||||
char *name;
|
||||
{
|
||||
char *s = name;
|
||||
if (s[0] == '-' || *s == '+')
|
||||
{
|
||||
if (s[1] != '[')
|
||||
{
|
||||
error ("invalid symbol name \"%s\"", name);
|
||||
}
|
||||
s = strchr (s, ']');
|
||||
if (s == NULL)
|
||||
{
|
||||
error ("invalid symbol name \"%s\"", name);
|
||||
}
|
||||
return strchr (s, ':');
|
||||
}
|
||||
else
|
||||
{
|
||||
return strchr (s, ':');
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
struct symbol *
|
||||
define_symbol (CORE_ADDR valu, char *string, int desc, int type,
|
||||
struct objfile *objfile)
|
||||
{
|
||||
register struct symbol *sym;
|
||||
char *p = (char *) strchr (string, ':');
|
||||
char *p = (char *) objc_find_colon (string);
|
||||
int deftype;
|
||||
int synonym = 0;
|
||||
register int i;
|
||||
|
@ -2006,7 +2030,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
|
|||
a typedef for "foo". Unfortunately, cfront never makes the typedef
|
||||
when translating C++ into C. We make the typedef here so that
|
||||
"ptype foo" works as expected for cfront translated code. */
|
||||
else if (current_subfile->language == language_cplus)
|
||||
else if ((current_subfile->language == language_cplus)
|
||||
|| (current_subfile->language == language_objc))
|
||||
synonym = 1;
|
||||
|
||||
SYMBOL_TYPE (sym) = read_type (&p, objfile);
|
||||
|
|
|
@ -1951,6 +1951,7 @@ init_filename_language_table (void)
|
|||
/* OBSOLETE add_filename_language (".ch", language_chill); */
|
||||
/* OBSOLETE add_filename_language (".c186", language_chill); */
|
||||
/* OBSOLETE add_filename_language (".c286", language_chill); */
|
||||
add_filename_language (".m", language_objc);
|
||||
add_filename_language (".f", language_fortran);
|
||||
add_filename_language (".F", language_fortran);
|
||||
add_filename_language (".s", language_asm);
|
||||
|
|
16
gdb/symtab.h
16
gdb/symtab.h
|
@ -89,6 +89,11 @@ struct general_symbol_info
|
|||
char *demangled_name;
|
||||
}
|
||||
cplus_specific;
|
||||
struct objc_specific
|
||||
{
|
||||
char *demangled_name;
|
||||
}
|
||||
objc_specific;
|
||||
#if 0
|
||||
/* OBSOLETE struct chill_specific *//* For Chill */
|
||||
/* OBSOLETE { */
|
||||
|
@ -146,6 +151,10 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
|
|||
{ \
|
||||
SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \
|
||||
} \
|
||||
else if (SYMBOL_LANGUAGE (symbol) == language_objc) \
|
||||
{ \
|
||||
SYMBOL_OBJC_DEMANGLED_NAME (symbol) = NULL; \
|
||||
} \
|
||||
/* OBSOLETE else if (SYMBOL_LANGUAGE (symbol) == language_chill) */ \
|
||||
/* OBSOLETE { */ \
|
||||
/* OBSOLETE SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */ \
|
||||
|
@ -170,13 +179,18 @@ extern void symbol_init_demangled_name (struct general_symbol_info *symbol,
|
|||
(SYMBOL_LANGUAGE (symbol) == language_cplus \
|
||||
|| SYMBOL_LANGUAGE (symbol) == language_java \
|
||||
? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \
|
||||
: (SYMBOL_LANGUAGE (symbol) == language_objc \
|
||||
? SYMBOL_OBJC_DEMANGLED_NAME (symbol) \
|
||||
: /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */ \
|
||||
/* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */ \
|
||||
NULL)
|
||||
NULL))
|
||||
|
||||
/* OBSOLETE #define SYMBOL_CHILL_DEMANGLED_NAME(symbol) */
|
||||
/* OBSOLETE (symbol)->ginfo.language_specific.chill_specific.demangled_name */
|
||||
|
||||
#define SYMBOL_OBJC_DEMANGLED_NAME(symbol) \
|
||||
(symbol)->ginfo.language_specific.objc_specific.demangled_name
|
||||
|
||||
/* Macro that returns the "natural source name" of a symbol. In C++ this is
|
||||
the "demangled" form of the name if demangle is on and the "mangled" form
|
||||
of the name if demangle is off. In other languages this is just the
|
||||
|
|
79
gdb/utils.c
79
gdb/utils.c
|
@ -152,13 +152,13 @@ int quit_flag;
|
|||
|
||||
int immediate_quit;
|
||||
|
||||
/* Nonzero means that encoded C++ names should be printed out in their
|
||||
C++ form rather than raw. */
|
||||
/* Nonzero means that encoded C++/ObjC names should be printed out in their
|
||||
C++/ObjC form rather than raw. */
|
||||
|
||||
int demangle = 1;
|
||||
|
||||
/* Nonzero means that encoded C++ names should be printed out in their
|
||||
C++ form even in assembler language displays. If this is set, but
|
||||
/* Nonzero means that encoded C++/ObjC names should be printed out in their
|
||||
C++/ObjC form even in assembler language displays. If this is set, but
|
||||
DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */
|
||||
|
||||
int asm_demangle = 0;
|
||||
|
@ -276,7 +276,7 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
|
|||
void *arg)
|
||||
{
|
||||
register struct cleanup *new
|
||||
= (struct cleanup *) xmalloc (sizeof (struct cleanup));
|
||||
= (struct cleanup *) xmalloc (sizeof (struct cleanup));
|
||||
register struct cleanup *old_chain = *pmy_chain;
|
||||
|
||||
new->next = *pmy_chain;
|
||||
|
@ -1776,6 +1776,51 @@ wrap_here (char *indent)
|
|||
}
|
||||
}
|
||||
|
||||
/* Print input string to gdb_stdout, filtered, with wrap,
|
||||
arranging strings in columns of n chars. String can be
|
||||
right or left justified in the column. Never prints
|
||||
trailing spaces. String should never be longer than
|
||||
width. FIXME: this could be useful for the EXAMINE
|
||||
command, which currently doesn't tabulate very well. */
|
||||
|
||||
void
|
||||
puts_filtered_tabular (char *string, int width, int right)
|
||||
{
|
||||
int spaces = 0;
|
||||
int stringlen;
|
||||
char *spacebuf;
|
||||
|
||||
gdb_assert (chars_per_line > 0);
|
||||
if (chars_per_line == UINT_MAX)
|
||||
{
|
||||
fputs_filtered (string, gdb_stdout);
|
||||
fputs_filtered ("\n", gdb_stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((chars_printed - 1) / width + 2) * width >= chars_per_line)
|
||||
fputs_filtered ("\n", gdb_stdout);
|
||||
|
||||
if (width >= chars_per_line)
|
||||
width = chars_per_line - 1;
|
||||
|
||||
stringlen = strlen (string);
|
||||
|
||||
if (chars_printed > 0)
|
||||
spaces = width - (chars_printed - 1) % width - 1;
|
||||
if (right)
|
||||
spaces += width - stringlen;
|
||||
|
||||
spacebuf = alloca (spaces + 1);
|
||||
spacebuf[spaces] = '\0';
|
||||
while (spaces--)
|
||||
spacebuf[spaces] = ' ';
|
||||
|
||||
fputs_filtered (spacebuf, gdb_stdout);
|
||||
fputs_filtered (string, gdb_stdout);
|
||||
}
|
||||
|
||||
|
||||
/* Ensure that whatever gets printed next, using the filtered output
|
||||
commands, starts at the beginning of the line. I.E. if there is
|
||||
any pending output for the current line, flush it and start a new
|
||||
|
@ -2203,15 +2248,18 @@ print_spaces_filtered (int n, struct ui_file *stream)
|
|||
fputs_filtered (n_spaces (n), stream);
|
||||
}
|
||||
|
||||
/* C++ demangler stuff. */
|
||||
/* C++/ObjC demangler stuff. */
|
||||
|
||||
/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
|
||||
LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
|
||||
If the name is not mangled, or the language for the name is unknown, or
|
||||
demangling is off, the name is printed in its "raw" form. */
|
||||
/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in
|
||||
language LANG, using demangling args ARG_MODE, and print it
|
||||
filtered to STREAM. If the name is not mangled, or the language
|
||||
for the name is unknown, or demangling is off, the name is printed
|
||||
in its "raw" form. */
|
||||
|
||||
void
|
||||
fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
|
||||
fprintf_symbol_filtered (struct ui_file *stream,
|
||||
char *name,
|
||||
enum language lang,
|
||||
int arg_mode)
|
||||
{
|
||||
char *demangled;
|
||||
|
@ -2233,6 +2281,11 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
|
|||
case language_java:
|
||||
demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
|
||||
break;
|
||||
#if 0 /* Enable once objective-c support is turned on. */
|
||||
case language_objc:
|
||||
demangled = objc_demangle (name);
|
||||
break;
|
||||
#endif
|
||||
#if 0
|
||||
/* OBSOLETE case language_chill: */
|
||||
/* OBSOLETE demangled = chill_demangle (name); */
|
||||
|
@ -2352,7 +2405,7 @@ initialize_utils (void)
|
|||
add_show_from_set
|
||||
(add_set_cmd ("demangle", class_support, var_boolean,
|
||||
(char *) &demangle,
|
||||
"Set demangling of encoded C++ names when displaying symbols.",
|
||||
"Set demangling of encoded C++/ObjC names when displaying symbols.",
|
||||
&setprintlist),
|
||||
&showprintlist);
|
||||
|
||||
|
@ -2380,7 +2433,7 @@ initialize_utils (void)
|
|||
add_show_from_set
|
||||
(add_set_cmd ("asm-demangle", class_support, var_boolean,
|
||||
(char *) &asm_demangle,
|
||||
"Set demangling of C++ names in disassembly listings.",
|
||||
"Set demangling of C++/ObjC names in disassembly listings.",
|
||||
&setprintlist),
|
||||
&showprintlist);
|
||||
}
|
||||
|
|
61
gdb/valops.c
61
gdb/valops.c
|
@ -48,10 +48,8 @@ extern int overload_debug;
|
|||
static int typecmp (int staticp, int varargs, int nargs,
|
||||
struct field t1[], struct value *t2[]);
|
||||
|
||||
static CORE_ADDR find_function_addr (struct value *, struct type **);
|
||||
static struct value *value_arg_coerce (struct value *, struct type *, int);
|
||||
|
||||
|
||||
static CORE_ADDR value_push (CORE_ADDR, struct value *);
|
||||
|
||||
static struct value *search_struct_field (char *, struct value *, int,
|
||||
|
@ -91,7 +89,6 @@ int overload_resolution = 0;
|
|||
int unwind_on_signal_p = 0;
|
||||
|
||||
|
||||
|
||||
/* Find the address of function name NAME in the inferior. */
|
||||
|
||||
struct value *
|
||||
|
@ -1219,7 +1216,7 @@ value_arg_coerce (struct value *arg, struct type *param_type,
|
|||
/* Determine a function's address and its return type from its value.
|
||||
Calls error() if the function is not valid for calling. */
|
||||
|
||||
static CORE_ADDR
|
||||
CORE_ADDR
|
||||
find_function_addr (struct value *function, struct type **retval_type)
|
||||
{
|
||||
register struct type *ftype = check_typedef (VALUE_TYPE (function));
|
||||
|
@ -1889,6 +1886,23 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
|||
error ("Cannot invoke functions on this machine.");
|
||||
}
|
||||
}
|
||||
|
||||
struct value *
|
||||
call_function_by_hand_expecting_type (struct value *function,
|
||||
struct type *expect_type,
|
||||
int nargs, struct value **args,
|
||||
int restore_frame)
|
||||
{
|
||||
if (CALL_DUMMY_P)
|
||||
{
|
||||
/* FIXME: Changes to func not implemented yet */
|
||||
return hand_function_call (function, nargs, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("Cannot invoke functions on this machine.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -3303,21 +3317,17 @@ value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop,
|
|||
return new_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* C++: return the value of the class instance variable, if one exists.
|
||||
/* Return the value of the local variable, if one exists.
|
||||
Flag COMPLAIN signals an error if the request is made in an
|
||||
inappropriate context. */
|
||||
|
||||
struct value *
|
||||
value_of_this (int complain)
|
||||
value_of_local (const char *name, int complain)
|
||||
{
|
||||
struct symbol *func, *sym;
|
||||
struct block *b;
|
||||
int i;
|
||||
static const char funny_this[] = "this";
|
||||
struct value *this;
|
||||
struct value * ret;
|
||||
|
||||
if (selected_frame == 0)
|
||||
{
|
||||
|
@ -3331,7 +3341,7 @@ value_of_this (int complain)
|
|||
if (!func)
|
||||
{
|
||||
if (complain)
|
||||
error ("no `this' in nameless context");
|
||||
error ("no %s in nameless context", name);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -3341,26 +3351,39 @@ value_of_this (int complain)
|
|||
if (i <= 0)
|
||||
{
|
||||
if (complain)
|
||||
error ("no args, no `this'");
|
||||
error ("no args, no %s", name);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
|
||||
symbol instead of the LOC_ARG one (if both exist). */
|
||||
sym = lookup_block_symbol (b, funny_this, NULL, VAR_NAMESPACE);
|
||||
sym = lookup_block_symbol (b, name, NULL, VAR_NAMESPACE);
|
||||
if (sym == NULL)
|
||||
{
|
||||
if (complain)
|
||||
error ("current stack frame not in method");
|
||||
error ("current stack frame does not contain a variable named \"%s\"", name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = read_var_value (sym, selected_frame);
|
||||
if (this == 0 && complain)
|
||||
error ("`this' argument at unknown address");
|
||||
return this;
|
||||
ret = read_var_value (sym, selected_frame);
|
||||
if (ret == 0 && complain)
|
||||
error ("%s argument unreadable", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* C++/Objective-C: return the value of the class instance variable,
|
||||
if one exists. Flag COMPLAIN signals an error if the request is
|
||||
made in an inappropriate context. */
|
||||
|
||||
struct value *
|
||||
value_of_this (int complain)
|
||||
{
|
||||
if (current_language->la_language == language_objc)
|
||||
return value_of_local ("self", complain);
|
||||
else
|
||||
return value_of_local ("this", complain);
|
||||
}
|
||||
|
||||
/* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH elements
|
||||
|
|
12
gdb/value.h
12
gdb/value.h
|
@ -535,6 +535,12 @@ extern void clear_value_history (void);
|
|||
|
||||
extern void clear_internalvars (void);
|
||||
|
||||
/* Objective-C */
|
||||
|
||||
extern struct value *value_of_local (const char *name, int complain);
|
||||
|
||||
extern struct value *value_nsstring (char *ptr, int len);
|
||||
|
||||
/* From values.c */
|
||||
|
||||
extern struct value *value_copy (struct value *);
|
||||
|
@ -548,6 +554,10 @@ extern struct value *value_slice (struct value *, int, int);
|
|||
extern struct value *call_function_by_hand (struct value *, int,
|
||||
struct value **);
|
||||
|
||||
extern struct value *call_function_by_hand_expecting_type (struct value *,
|
||||
struct type *, int,
|
||||
struct value **, int);
|
||||
|
||||
extern int default_coerce_float_to_double (struct type *, struct type *);
|
||||
|
||||
extern int standard_coerce_float_to_double (struct type *, struct type *);
|
||||
|
@ -566,4 +576,6 @@ extern CORE_ADDR default_push_arguments (int nargs, struct value ** args,
|
|||
CORE_ADDR sp, int struct_return,
|
||||
CORE_ADDR struct_addr);
|
||||
|
||||
extern CORE_ADDR find_function_addr (struct value *, struct type **);
|
||||
|
||||
#endif /* !defined (VALUE_H) */
|
||||
|
|
Loading…
Reference in a new issue