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:
Michael Snyder 2002-09-19 01:34:51 +00:00
parent b9caf5053f
commit 3b4efeaa2d
21 changed files with 446 additions and 184 deletions

View file

@ -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> 2002-09-18 Andrew Cagney <ac131313@redhat.com>
* complaints.h: Update copyright. * complaints.h: Update copyright.

View file

@ -4618,13 +4618,16 @@ parse_breakpoint_sals (char **address,
current_source_symtab (which is decode_line_1's default). This current_source_symtab (which is decode_line_1's default). This
should produce the results we want almost all of the time while should produce the results we want almost all of the time while
leaving default_breakpoint_* alone. */ leaving default_breakpoint_* alone. */
/* Also ignore objc method name. FIXME better comment? */
if (default_breakpoint_valid if (default_breakpoint_valid
&& (!current_source_symtab && (!current_source_symtab
|| (strchr ("+-", (*address)[0]) != NULL))) || ((strchr ("+-", (*address)[0]) != NULL)
&& ((*address)[1] != '['))))
*sals = decode_line_1 (address, 1, default_breakpoint_symtab, *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
default_breakpoint_line, addr_string); default_breakpoint_line, addr_string);
else 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. */ /* For any SAL that didn't have a canonical string, fill one in. */
if (sals->nelts > 0 && *addr_string == NULL) if (sals->nelts > 0 && *addr_string == NULL)

View file

@ -49,6 +49,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h" /* Required by objfiles.h. */ #include "bfd.h" /* Required by objfiles.h. */
#include "symfile.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 "completer.h" /* For skip_quoted(). */
/* Flag indicating we're dealing with HP-compiled objects */ /* Flag indicating we're dealing with HP-compiled objects */
extern int hp_som_som_object_present; extern int hp_som_som_object_present;

View file

@ -208,6 +208,7 @@ enum language
language_auto, /* Placeholder for automatic setting */ language_auto, /* Placeholder for automatic setting */
language_c, /* C */ language_c, /* C */
language_cplus, /* C++ */ language_cplus, /* C++ */
language_objc, /* Objective-C */
language_java, /* Java */ language_java, /* Java */
/* OBSOLETE language_chill, */ /* Chill */ /* OBSOLETE language_chill, */ /* Chill */
language_fortran, /* Fortran */ language_fortran, /* Fortran */
@ -445,6 +446,8 @@ extern void puts_filtered (const char *);
extern void puts_unfiltered (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 puts_debug (char *prefix, char *string, char *suffix);
extern void vprintf_filtered (const char *, va_list) ATTR_FORMAT (printf, 1, 0); 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); typedef void initialize_file_ftype (void);
extern char *skip_quoted (char *);
extern char *gdb_readline (char *); extern char *gdb_readline (char *);
extern char *gdb_readline_wrapper (char *); extern char *gdb_readline_wrapper (char *);

View file

@ -349,7 +349,13 @@ elf_symtab_read (struct objfile *objfile, int dynamic)
} }
else if (sym->section->flags & SEC_CODE) 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; ms_type = mst_text;
} }

View file

@ -181,6 +181,12 @@ enum exp_opcode
making three exp_elements. */ making three exp_elements. */
OP_FUNCALL, 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. /* This is EXACTLY like OP_FUNCALL but is semantically different.
In F77, array subscript expressions, substring expressions In F77, array subscript expressions, substring expressions
and function calls are all exactly the same syntactically. They may and function calls are all exactly the same syntactically. They may
@ -273,11 +279,18 @@ enum exp_opcode
STRUCTOP_STRUCT, STRUCTOP_STRUCT,
STRUCTOP_PTR, STRUCTOP_PTR,
/* C++ */ /* C++:
/* OP_THIS is just a placeholder for the class instance variable. 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_THIS, 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 /* OP_SCOPE surrounds a type name and a field name. The type
name is encoded as one element, but the field name stays as name is encoded as one element, but the field name stays as
a string, which, of course, is variable length. */ a string, which, of course, is variable length. */
@ -305,7 +318,10 @@ enum exp_opcode
OP_NAME, OP_NAME,
/* An unparsed expression. Used for Scheme (for now at least) */ /* 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 union exp_element
@ -350,7 +366,7 @@ extern struct block *innermost_block;
/* From eval.c */ /* From eval.c */
/* Values of NOSIDE argument to eval_subexp. */ /* Values of NOSIDE argument to evaluate_subexp. */
enum noside enum noside
{ {

View file

@ -48,6 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h" /* Required by objfiles.h. */ #include "bfd.h" /* Required by objfiles.h. */
#include "symfile.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 "completer.h" /* For skip_quoted(). */
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple as well as gratuitiously global symbol names, so we can have multiple

View file

@ -549,6 +549,7 @@ binop_result_type (struct value *v1, struct value *v2)
{ {
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
if (TYPE_CODE (t1) == TYPE_CODE_FLT) if (TYPE_CODE (t1) == TYPE_CODE_FLT)
return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ? return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
VALUE_TYPE (v2) : VALUE_TYPE (v1); VALUE_TYPE (v2) : VALUE_TYPE (v1);
@ -786,6 +787,7 @@ integral_type (struct type *type)
{ {
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
return (TYPE_CODE (type) != TYPE_CODE_INT) && return (TYPE_CODE (type) != TYPE_CODE_INT) &&
(TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1; (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
case language_m2: case language_m2:
@ -828,6 +830,7 @@ character_type (struct type *type)
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
return (TYPE_CODE (type) == TYPE_CODE_INT) && return (TYPE_CODE (type) == TYPE_CODE_INT) &&
TYPE_LENGTH (type) == sizeof (char) TYPE_LENGTH (type) == sizeof (char)
? 1 : 0; ? 1 : 0;
@ -850,6 +853,7 @@ string_type (struct type *type)
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
/* C does not have distinct string type. */ /* C does not have distinct string type. */
return (0); return (0);
default: default:
@ -868,6 +872,7 @@ boolean_type (struct type *type)
{ {
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
/* Might be more cleanly handled by having a /* Might be more cleanly handled by having a
TYPE_CODE_INT_NOT_BOOL for (OBSOLETE) CHILL and such TYPE_CODE_INT_NOT_BOOL for (OBSOLETE) CHILL and such
languages, or a TYPE_CODE_INT_OR_BOOL for C. */ languages, or a TYPE_CODE_INT_OR_BOOL for C. */
@ -904,6 +909,7 @@ structured_type (struct type *type)
{ {
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
(TYPE_CODE (type) == TYPE_CODE_UNION) || (TYPE_CODE (type) == TYPE_CODE_UNION) ||
(TYPE_CODE (type) == TYPE_CODE_ARRAY); (TYPE_CODE (type) == TYPE_CODE_ARRAY);
@ -1124,6 +1130,7 @@ binop_type_check (struct value *arg1, struct value *arg2, int op)
#ifdef _LANG_c #ifdef _LANG_c
case language_c: case language_c:
case language_cplus: case language_cplus:
case language_objc:
switch (op) switch (op)
{ {
case BINOP_DIV: case BINOP_DIV:

View file

@ -288,7 +288,8 @@ language_mode;
/* "cast" really means conversion */ /* "cast" really means conversion */
/* FIXME -- should be a setting in language_defn */ /* FIXME -- should be a setting in language_defn */
#define CAST_IS_CONVERSION (current_language->la_language == language_c || \ #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); extern void language_info (int);

View file

@ -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 along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Parse a C expression from text in a string, /* Parse a C expression from text in a string, and return the result
and return the result as a struct expression pointer. as a struct expression pointer. That structure contains arithmetic
That structure contains arithmetic operations in reverse polish, operations in reverse polish, with constants represented by
with constants represented by operations that are followed by special data. operations that are followed by special data. See expression.h for
See expression.h for the details of the format. the details of the format. What is important here is that it can
What is important here is that it can be built up sequentially be built up sequentially during the process of parsing; the lower
during the process of parsing; the lower levels of the tree always levels of the tree always come first in the result.
come first in the result.
Note that malloc's and realloc's in this file are transformed to Note that malloc's and realloc's in this file are transformed to
xmalloc and xrealloc respectively by the same sed command in the xmalloc and xrealloc respectively by the same sed command in the
makefile that remaps any other malloc/realloc inserted by the parser makefile that remaps any other malloc/realloc inserted by the
generator. Doing this with #defines and trying to control the interaction parser generator. Doing this with #defines and trying to control
with include files (<malloc.h> and <stdlib.h> for example) just became the interaction with include files (<malloc.h> and <stdlib.h> for
too messy, particularly when such includes can be inserted at random example) just became too messy, particularly when such includes can
times by the parser generator. */ 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 <ctype.h>
#include "expression.h" #include "expression.h"
#include "objc-lang.h" /* for objc language constructs */ #include "objc-lang.h" /* For objc language constructs. */
#include "value.h" #include "value.h"
#include "parser-defs.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 "c-lang.h"
#include "bfd.h" /* Required by objfiles.h. */ #include "bfd.h" /* Required by objfiles.h. */
#include "symfile.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 "top.h"
#include "completer.h" /* For skip_quoted(). */ #include "completer.h" /* For skip_quoted(). */
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), /* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
as well as gratuitiously global symbol names, so we can have multiple etc), as well as gratuitiously global symbol names, so we can have
yacc generated parsers in gdb. Note that these are only the variables multiple yacc generated parsers in gdb. Note that these are only
produced by yacc. If other parser generators (bison, byacc, etc) produce the variables produced by yacc. If other parser generators (bison,
additional global names that conflict at link time, then those parser byacc, etc) produce additional global names that conflict at link
generators need to be fixed instead of adding those names to this list. */ time, then those parser generators need to be fixed instead of
adding those names to this list. */
#define yymaxdepth objc_maxdepth #define yymaxdepth objc_maxdepth
#define yyparse objc_parse #define yyparse objc_parse
@ -103,7 +103,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define yycheck objc_yycheck #define yycheck objc_yycheck
#ifndef YYDEBUG #ifndef YYDEBUG
#define YYDEBUG 0 /* Default to no yydebug support */ #define YYDEBUG 0 /* Default to no yydebug support. */
#endif #endif
int int
@ -148,7 +148,7 @@ yyerror PARAMS ((char *));
} }
%{ %{
/* YYSTYPE gets defined by %union */ /* YYSTYPE gets defined by %union. */
static int static int
parse_number PARAMS ((char *, int, int, YYSTYPE *)); 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_int> INT
%token <typed_val_float> FLOAT %token <typed_val_float> FLOAT
/* Both NAME and TYPENAME tokens represent symbols in the input, /* Both NAME and TYPENAME tokens represent symbols in the input, and
and both convey their data as strings. both convey their data as strings. But a TYPENAME is a string that
But a TYPENAME is a string that happens to be defined as a typedef happens to be defined as a typedef or builtin type name (such as
or builtin type name (such as int or char) int or char) and a NAME is any other symbol. Contexts where this
and a NAME is any other symbol. distinction is not important can use the nonterminal "name", which
Contexts where this distinction is not important can use the matches either NAME or TYPENAME. */
nonterminal "name", which matches either NAME or TYPENAME. */
%token <sval> STRING %token <sval> STRING
%token <sval> NSSTRING /* ObjC Foundation "NSString" literal */ %token <sval> NSSTRING /* ObjC Foundation "NSString" literal */
@ -196,8 +195,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
%token TEMPLATE %token TEMPLATE
%token ERROR %token ERROR
/* Special type cases, put in to allow the parser to distinguish different /* Special type cases, put in to allow the parser to distinguish
legal basetypes. */ different legal basetypes. */
%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
%token <voidval> VARIABLE %token <voidval> VARIABLE
@ -386,9 +385,9 @@ msgarglist : msgarg
msgarg : name ':' exp msgarg : name ':' exp
{ add_msglist(&$1, 1); } { add_msglist(&$1, 1); }
| ':' exp /* unnamed arg */ | ':' exp /* Unnamed arg. */
{ add_msglist(0, 1); } { add_msglist(0, 1); }
| ',' exp /* variable number of args */ | ',' exp /* Variable number of args. */
{ add_msglist(0, 0); } { add_msglist(0, 0); }
; ;
@ -582,10 +581,11 @@ exp : SIZEOF '(' type ')' %prec UNARY
; ;
exp : STRING exp : STRING
{ /* C strings are converted into array constants with { /* C strings are converted into array
an explicit null byte added at the end. Thus constants with an explicit null byte
the array upper bound is the string length. added at the end. Thus the array upper
There is no such thing in C as a completely empty bound is the string length. There is no
such thing in C as a completely empty
string. */ string. */
char *sp = $1.ptr; int count = $1.length; char *sp = $1.ptr; int count = $1.length;
while (count-- > 0) while (count-- > 0)
@ -606,7 +606,7 @@ exp : STRING
; ;
exp : NSSTRING /* ObjC NextStep NSString constant exp : NSSTRING /* ObjC NextStep NSString constant
* of the form '@' '"' string '"' * of the form '@' '"' string '"'.
*/ */
{ write_exp_elt_opcode (OP_NSSTRING); { write_exp_elt_opcode (OP_NSSTRING);
write_exp_string ($1); write_exp_string ($1);
@ -798,11 +798,11 @@ variable: name_not_typename
ptype : typebase ptype : typebase
/* "const" and "volatile" are curently ignored. A type qualifier /* "const" and "volatile" are curently ignored. A type
before the type is currently handled in the typebase rule. qualifier before the type is currently handled in the
The reason for recognizing these here (shift/reduce conflicts) typebase rule. The reason for recognizing these here
might be obsolete now that some pointer to member rules have (shift/reduce conflicts) might be obsolete now that some
been deleted. */ pointer to member rules have been deleted. */
| typebase CONST_KEYWORD | typebase CONST_KEYWORD
| typebase VOLATILE_KEYWORD | typebase VOLATILE_KEYWORD
| typebase abs_decl | typebase abs_decl
@ -857,8 +857,8 @@ func_mod: '(' ')'
; ;
/* We used to try to recognize more pointer to member types here, but /* 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 that didn't work (shift/reduce conflicts meant that these rules
got executed). The problem is that never got executed). The problem is that
int (foo::bar::baz::bizzle) int (foo::bar::baz::bizzle)
is a function type but is a function type but
int (foo::bar::baz::bizzle::*) int (foo::bar::baz::bizzle::*)
@ -869,7 +869,7 @@ type : ptype
{ $$ = lookup_member_type (builtin_type_int, $1); } { $$ = lookup_member_type (builtin_type_int, $1); }
; ;
typebase /* Implements (approximately): (type-qualifier)* type-specifier */ typebase /* Implements (approximately): (type-qualifier)* type-specifier. */
: TYPENAME : TYPENAME
{ $$ = $1.type; } { $$ = $1.type; }
| CLASSNAME | CLASSNAME
@ -930,9 +930,9 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
{ $$ = lookup_template_type(copy_name($2), $4, { $$ = lookup_template_type(copy_name($2), $4,
expression_context_block); expression_context_block);
} }
/* "const" and "volatile" are curently ignored. A type qualifier /* "const" and "volatile" are curently ignored. A type
after the type is handled in the ptype rule. I think these could qualifier after the type is handled in the ptype rule. I
be too. */ think these could be too. */
| CONST_KEYWORD typebase { $$ = $2; } | CONST_KEYWORD typebase { $$ = $2; }
| VOLATILE_KEYWORD typebase { $$ = $2; } | VOLATILE_KEYWORD typebase { $$ = $2; }
; ;
@ -961,7 +961,7 @@ typename: TYPENAME
nonempty_typelist nonempty_typelist
: type : type
{ $$ = (struct type **) malloc (sizeof (struct type *) * 2); { $$ = (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; $$[1] = $1;
} }
| nonempty_typelist ',' type | nonempty_typelist ',' type
@ -980,22 +980,22 @@ name : NAME { $$ = $1.stoken; }
name_not_typename : NAME name_not_typename : NAME
| BLOCKNAME | BLOCKNAME
/* These would be useful if name_not_typename was useful, but it is just /* These would be useful if name_not_typename was useful, but it is
a fake for "variable", so these cause reduce/reduce conflicts because just a fake for "variable", so these cause reduce/reduce conflicts
the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable, because the parser can't tell whether NAME_OR_INT is a
=exp) or just an exp. If name_not_typename was ever used in an lvalue name_not_typename (=variable, =exp) or just an exp. If
context where only a name could occur, this might be useful. name_not_typename was ever used in an lvalue context where only a
| NAME_OR_INT name could occur, this might be useful. */
*/ | NAME_OR_INT */
; ;
%% %%
/* Take care of parsing a number (anything that starts with a digit). /* Take care of parsing a number (anything that starts with a digit).
Set yylval and return the token type; update lexptr. Set yylval and return the token type; update lexptr. LEN is the
LEN is the number of characters in it. */ number of characters in it. */
/*** Needs some error checking for the float case ***/ /*** Needs some error checking for the float case. ***/
static int static int
parse_number (p, len, parsed_float, putithere) parse_number (p, len, parsed_float, putithere)
@ -1004,8 +1004,9 @@ parse_number (p, len, parsed_float, putithere)
int parsed_float; int parsed_float;
YYSTYPE *putithere; YYSTYPE *putithere;
{ {
/* FIXME: Shouldn't these be unsigned? We don't deal with negative values /* FIXME: Shouldn't these be unsigned? We don't deal with negative
here, and we do kind of silly things like cast to unsigned. */ values here, and we do kind of silly things like cast to
unsigned. */
register LONGEST n = 0; register LONGEST n = 0;
register LONGEST prevn = 0; register LONGEST prevn = 0;
unsigned LONGEST un; unsigned LONGEST un;
@ -1065,7 +1066,7 @@ parse_number (p, len, parsed_float, putithere)
return FLOAT; return FLOAT;
} }
/* Handle base-switching prefixes 0x, 0t, 0d, 0 */ /* Handle base-switching prefixes 0x, 0t, 0d, and 0. */
if (p[0] == '0') if (p[0] == '0')
switch (p[1]) switch (p[1])
{ {
@ -1128,20 +1129,20 @@ parse_number (p, len, parsed_float, putithere)
found_suffix = 1; found_suffix = 1;
} }
else else
return ERROR; /* Char not a digit */ return ERROR; /* Char not a digit. */
} }
if (i >= base) 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 /* Portably test for overflow (only works for nonzero values, so
a second check for zero). FIXME: Can't we just make n and prevn make a second check for zero). FIXME: Can't we just make n
unsigned and avoid this? */ and prevn unsigned and avoid this? */
if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) 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. /* Portably test for unsigned overflow.
FIXME: This check is wrong; for example it doesn't find overflow FIXME: This check is wrong; for example it doesn't find
on 0x123456789 when LONGEST is 32 bits. */ overflow on 0x123456789 when LONGEST is 32 bits. */
if (c != 'l' && c != 'u' && n != 0) if (c != 'l' && c != 'u' && n != 0)
{ {
if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n)) if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
@ -1299,9 +1300,9 @@ yylex ()
goto retry; goto retry;
case '\'': case '\'':
/* We either have a character constant ('0' or '\177' for example) /* We either have a character constant ('0' or '\177' for
or we have a quoted symbol reference ('foo(int,int)' in C++ example) or we have a quoted symbol reference ('foo(int,int)'
for example). */ in C++ for example). */
lexptr++; lexptr++;
c = *lexptr++; c = *lexptr++;
if (c == '\\') if (c == '\\')
@ -1368,7 +1369,7 @@ yylex ()
{ {
/* It's a number. */ /* It's a number. */
int got_dot = 0, got_e = 0, toktype = FLOAT; 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; register char *p = tokstart;
int hex = input_radix > 10; int hex = input_radix > 10;
int local_radix = input_radix; int local_radix = input_radix;
@ -1393,14 +1394,15 @@ yylex ()
if (!hex && (*p == 'e' || *p == 'E')) if (!hex && (*p == 'e' || *p == 'E'))
if (got_e) if (got_e)
toktype = ERROR; /* only one 'e' in a float */ toktype = ERROR; /* Only one 'e' in a float. */
else else
got_e = 1; got_e = 1;
/* This test does not include !hex, because a '.' always indicates /* This test does not include !hex, because a '.' always
a decimal floating point number regardless of the radix. */ indicates a decimal floating point number regardless of
the radix. */
else if (*p == '.') else if (*p == '.')
if (got_dot) if (got_dot)
toktype = ERROR; /* only one '.' in a float */ toktype = ERROR; /* Only one '.' in a float. */
else else
got_dot = 1; got_dot = 1;
else if (got_e && (p[-1] == 'e' || p[-1] == 'E') && 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 /* This is the sign of the exponent, not the end of the
number. */ number. */
continue; 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') else if (*p >= '0' && *p <= '9')
continue; continue;
/* We will take letters only if hex is true, and only /* We will take letters only if hex is true, and only up
up to what the input radix would permit. FSF was content to what the input radix would permit. FSF was content
to rely on parse_number to validate; but it leaks. */ to rely on parse_number to validate; but it leaks. */
else if (*p >= 'a' && *p <= 'z') { else if (*p >= 'a' && *p <= 'z')
{
if (!hex || *p >= ('a' + local_radix - 10)) if (!hex || *p >= ('a' + local_radix - 10))
toktype = ERROR; toktype = ERROR;
} }
else if (*p >= 'A' && *p <= 'Z') { else if (*p >= 'A' && *p <= 'Z')
{
if (!hex || *p >= ('A' + local_radix - 10)) if (!hex || *p >= ('A' + local_radix - 10))
toktype = ERROR; toktype = ERROR;
} }
else break; else break;
} }
if (toktype != ERROR) 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) if (toktype == ERROR)
{ {
char *err_copy = (char *) alloca (p - tokstart + 1); char *err_copy = (char *) alloca (p - tokstart + 1);
@ -1449,7 +1455,7 @@ yylex ()
case '~': case '~':
case '!': case '!':
#if 0 #if 0
case '@': /* moved out below */ case '@': /* Moved out below. */
#endif #endif
case '<': case '<':
case '>': case '>':
@ -1473,10 +1479,10 @@ yylex ()
error ("Missing '(' in @selector(...)"); error ("Missing '(' in @selector(...)");
} }
tempbufindex = 0; tempbufindex = 0;
tokptr++; /* skip the '(' */ tokptr++; /* Skip the '('. */
do { do {
/* Grow the static temp buffer if necessary, including allocating /* Grow the static temp buffer if necessary, including
the first one on demand. */ allocating the first one on demand. */
if (tempbufindex + 1 >= tempbufsize) if (tempbufindex + 1 >= tempbufsize)
{ {
tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
@ -1498,7 +1504,8 @@ yylex ()
lexptr++; lexptr++;
return tokchr; return tokchr;
} }
/* ObjC NextStep NSString constant: fall thru and parse like STRING */ /* ObjC NextStep NSString constant: fall thru and parse like
STRING. */
tokstart++; tokstart++;
case '"': case '"':
@ -1508,16 +1515,17 @@ yylex ()
buffer is null byte terminated *only* for the convenience of buffer is null byte terminated *only* for the convenience of
debugging gdb itself and printing the buffer contents when debugging gdb itself and printing the buffer contents when
the buffer contains no embedded nulls. Gdb does not depend the buffer contains no embedded nulls. Gdb does not depend
upon the buffer being null byte terminated, it uses the length upon the buffer being null byte terminated, it uses the
string instead. This allows gdb to handle C strings (as well length string instead. This allows gdb to handle C strings
as strings in other languages) with embedded null bytes */ (as well as strings in other languages) with embedded null
bytes. */
tokptr = ++tokstart; tokptr = ++tokstart;
tempbufindex = 0; tempbufindex = 0;
do { do {
/* Grow the static temp buffer if necessary, including allocating /* Grow the static temp buffer if necessary, including
the first one on demand. */ allocating the first one on demand. */
if (tempbufindex + 1 >= tempbufsize) if (tempbufindex + 1 >= tempbufsize)
{ {
tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
@ -1546,7 +1554,7 @@ yylex ()
{ {
error ("Unterminated string in expression."); error ("Unterminated string in expression.");
} }
tempbuf[tempbufindex] = '\0'; /* See note above */ tempbuf[tempbufindex] = '\0'; /* See note above. */
yylval.sval.ptr = tempbuf; yylval.sval.ptr = tempbuf;
yylval.sval.length = tempbufindex; yylval.sval.length = tempbufindex;
lexptr = tokptr; lexptr = tokptr;
@ -1626,8 +1634,9 @@ yylex ()
if (current_language->la_language == language_cplus if (current_language->la_language == language_cplus
&& STREQN (tokstart, "this", 4)) && STREQN (tokstart, "this", 4))
{ {
static const char this_name[] = static const char this_name[] = {
{ CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; CPLUS_MARKER, 't', 'h', 'i', 's', '\0'
};
if (lookup_symbol (this_name, expression_context_block, if (lookup_symbol (this_name, expression_context_block,
VAR_NAMESPACE, (int *) NULL, VAR_NAMESPACE, (int *) NULL,
@ -1673,9 +1682,9 @@ yylex ()
VAR_NAMESPACE, VAR_NAMESPACE,
need_this, need_this,
(struct symtab **) NULL); (struct symtab **) NULL);
/* Call lookup_symtab, not lookup_partial_symtab, in case there are /* Call lookup_symtab, not lookup_partial_symtab, in case there
no psymtabs (coff, xcoff, or some future change to blow away the are no psymtabs (coff, xcoff, or some future change to blow
psymtabs once symbols are read). */ away the psymtabs once symbols are read). */
if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
lookup_symtab (tmp)) lookup_symtab (tmp))
{ {
@ -1686,24 +1695,26 @@ yylex ()
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{ {
#if 1 #if 1
/* Despite the following flaw, we need to keep this code enabled. /* Despite the following flaw, we need to keep this code
Because we can get called from check_stub_method, if we don't enabled. Because we can get called from
handle nested types then it screws many operations in any check_stub_method, if we don't handle nested types then
program which uses nested types. */ it screws many operations in any program which uses
/* In "A::x", if x is a member function of A and there happens nested types. */
to be a type (nested or not, since the stabs don't make that /* In "A::x", if x is a member function of A and there
distinction) named x, then this code incorrectly thinks we happens to be a type (nested or not, since the stabs
are dealing with nested types rather than a member function. */ 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 *p;
char *namestart; char *namestart;
struct symbol *best_sym; struct symbol *best_sym;
/* Look ahead to detect nested types. This probably should be /* Look ahead to detect nested types. This probably should
done in the grammar, but trying seemed to introduce a lot be done in the grammar, but trying seemed to introduce a
of shift/reduce and reduce/reduce conflicts. It's possible lot of shift/reduce and reduce/reduce conflicts. It's
that it could be done, though. Or perhaps a non-grammar, but possible that it could be done, though. Or perhaps a
less ad hoc, approach would work well. */ non-grammar, but less ad hoc, approach would work well. */
/* Since we do not currently have any way of distinguishing /* Since we do not currently have any way of distinguishing
a nested type from a non-nested one (the stabs don't tell a nested type from a non-nested one (the stabs don't tell
@ -1732,9 +1743,10 @@ yylex ()
if (p != namestart) if (p != namestart)
{ {
struct symbol *cur_sym; struct symbol *cur_sym;
/* As big as the whole rest of the expression, which is /* As big as the whole rest of the expression,
at least big enough. */ which is at least big enough. */
char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); char *ncopy = alloca (strlen (tmp) +
strlen (namestart) + 3);
char *tmp1; char *tmp1;
tmp1 = ncopy; tmp1 = ncopy;
@ -1744,7 +1756,8 @@ yylex ()
tmp1 += 2; tmp1 += 2;
memcpy (tmp1, namestart, p - namestart); memcpy (tmp1, namestart, p - namestart);
tmp1[p - namestart] = '\0'; tmp1[p - namestart] = '\0';
cur_sym = lookup_symbol (ncopy, expression_context_block, cur_sym = lookup_symbol (ncopy,
expression_context_block,
VAR_NAMESPACE, (int *) NULL, VAR_NAMESPACE, (int *) NULL,
(struct symtab **) NULL); (struct symtab **) NULL);
if (cur_sym) if (cur_sym)
@ -1776,14 +1789,17 @@ yylex ()
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
return TYPENAME; 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); CORE_ADDR Class = lookup_objc_class(tmp);
if (Class) if (Class)
{ {
extern struct symbol *lookup_struct_typedef(); extern struct symbol *lookup_struct_typedef();
yylval.class.class = Class; 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); yylval.class.type = SYMBOL_TYPE (sym);
return CLASSNAME; return CLASSNAME;
} }
@ -1806,7 +1822,7 @@ yylex ()
} }
} }
/* Any other kind of symbol */ /* Any other kind of symbol. */
yylval.ssym.sym = sym; yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this; yylval.ssym.is_a_field_of_this = is_a_field_of_this;
return NAME; return NAME;
@ -1820,5 +1836,6 @@ yyerror (msg)
if (*lexptr == '\0') if (*lexptr == '\0')
error("A %s near end of expression.", (msg ? msg : "error")); error("A %s near end of expression.", (msg ? msg : "error"));
else else
error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); error ("A %s in expression, near `%s'.", (msg ? msg : "error"),
lexptr);
} }

View file

@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h" /* Required by objfiles.h. */ #include "bfd.h" /* Required by objfiles.h. */
#include "symfile.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 "completer.h" /* For skip_quoted(). */
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple as well as gratuitiously global symbol names, so we can have multiple

View file

@ -867,6 +867,11 @@ length_of_subexp (register struct expression *expr, register int endpos)
args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
break; 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_MAX:
case UNOP_MIN: case UNOP_MIN:
oplen = 3; oplen = 3;
@ -898,6 +903,8 @@ length_of_subexp (register struct expression *expr, register int endpos)
/* fall through */ /* fall through */
case OP_M2_STRING: case OP_M2_STRING:
case OP_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_NAME:
case OP_EXPRSTRING: case OP_EXPRSTRING:
oplen = longest_to_int (expr->elts[endpos - 2].longconst); oplen = longest_to_int (expr->elts[endpos - 2].longconst);
@ -936,6 +943,7 @@ length_of_subexp (register struct expression *expr, register int endpos)
/* C++ */ /* C++ */
case OP_THIS: case OP_THIS:
case OP_SELF:
oplen = 2; oplen = 2;
break; break;
@ -1004,6 +1012,11 @@ prefixify_subexp (register struct expression *inexpr,
args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst); args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
break; 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_MIN:
case UNOP_MAX: case UNOP_MAX:
oplen = 3; oplen = 3;
@ -1034,6 +1047,8 @@ prefixify_subexp (register struct expression *inexpr,
/* fall through */ /* fall through */
case OP_M2_STRING: case OP_M2_STRING:
case OP_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_NAME:
case OP_EXPRSTRING: case OP_EXPRSTRING:
oplen = longest_to_int (inexpr->elts[inend - 2].longconst); oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
@ -1072,6 +1087,7 @@ prefixify_subexp (register struct expression *inexpr,
/* C++ */ /* C++ */
case OP_THIS: case OP_THIS:
case OP_SELF:
oplen = 2; oplen = 2;
break; break;

View file

@ -79,6 +79,14 @@ struct symtoken
int is_a_field_of_this; int is_a_field_of_this;
}; };
struct objc_class_str
{
struct stoken stoken;
struct type *type;
int class;
};
/* For parsing of complicated types. /* For parsing of complicated types.
An array should be preceded in the list by the size of the array. */ An array should be preceded in the list by the size of the array. */
enum type_pieces enum type_pieces
@ -216,6 +224,11 @@ struct op_print
extern int target_map_name_to_register (char *, int); 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 /* Function used to avoid direct calls to fprintf
in the code generated by the bison parser. */ in the code generated by the bison parser. */

View file

@ -1104,7 +1104,11 @@ address_info (char *exp, int from_tty)
printf_filtered ("Symbol \""); printf_filtered ("Symbol \"");
fprintf_symbol_filtered (gdb_stdout, exp, fprintf_symbol_filtered (gdb_stdout, exp,
current_language->la_language, DMGL_ANSI); 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; return;
} }

View file

@ -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 /* 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 in order to list a function which was specified ambiguously (as with
`list classname::overloadedfuncname', for example). The vector in `list classname::overloadedfuncname', or 'list objectiveCSelector:).
SALS provides the filenames and line numbers. */ The vector in SALS provides the filenames and line numbers.
NOTE: some of the SALS may have no filename or line information! */
static void static void
ambiguous_line_spec (struct symtabs_and_lines *sals) ambiguous_line_spec (struct symtabs_and_lines *sals)

View file

@ -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 */ /* ARGSUSED */
struct symbol * struct symbol *
define_symbol (CORE_ADDR valu, char *string, int desc, int type, define_symbol (CORE_ADDR valu, char *string, int desc, int type,
struct objfile *objfile) struct objfile *objfile)
{ {
register struct symbol *sym; register struct symbol *sym;
char *p = (char *) strchr (string, ':'); char *p = (char *) objc_find_colon (string);
int deftype; int deftype;
int synonym = 0; int synonym = 0;
register int i; 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 a typedef for "foo". Unfortunately, cfront never makes the typedef
when translating C++ into C. We make the typedef here so that when translating C++ into C. We make the typedef here so that
"ptype foo" works as expected for cfront translated code. */ "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; synonym = 1;
SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_TYPE (sym) = read_type (&p, objfile);

View file

@ -1951,6 +1951,7 @@ init_filename_language_table (void)
/* OBSOLETE add_filename_language (".ch", language_chill); */ /* OBSOLETE add_filename_language (".ch", language_chill); */
/* OBSOLETE add_filename_language (".c186", language_chill); */ /* OBSOLETE add_filename_language (".c186", language_chill); */
/* OBSOLETE add_filename_language (".c286", 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 (".F", language_fortran); add_filename_language (".F", language_fortran);
add_filename_language (".s", language_asm); add_filename_language (".s", language_asm);

View file

@ -89,6 +89,11 @@ struct general_symbol_info
char *demangled_name; char *demangled_name;
} }
cplus_specific; cplus_specific;
struct objc_specific
{
char *demangled_name;
}
objc_specific;
#if 0 #if 0
/* OBSOLETE struct chill_specific *//* For Chill */ /* OBSOLETE struct chill_specific *//* For Chill */
/* OBSOLETE { */ /* OBSOLETE { */
@ -146,6 +151,10 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
{ \ { \
SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \ 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 else if (SYMBOL_LANGUAGE (symbol) == language_chill) */ \
/* OBSOLETE { */ \ /* OBSOLETE { */ \
/* OBSOLETE SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */ \ /* 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_cplus \
|| SYMBOL_LANGUAGE (symbol) == language_java \ || SYMBOL_LANGUAGE (symbol) == language_java \
? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \ ? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \
: (SYMBOL_LANGUAGE (symbol) == language_objc \
? SYMBOL_OBJC_DEMANGLED_NAME (symbol) \
: /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */ \ : /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */ \
/* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */ \ /* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */ \
NULL) NULL))
/* OBSOLETE #define SYMBOL_CHILL_DEMANGLED_NAME(symbol) */ /* OBSOLETE #define SYMBOL_CHILL_DEMANGLED_NAME(symbol) */
/* OBSOLETE (symbol)->ginfo.language_specific.chill_specific.demangled_name */ /* 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 /* 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 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 of the name if demangle is off. In other languages this is just the

View file

@ -152,13 +152,13 @@ int quit_flag;
int immediate_quit; int immediate_quit;
/* Nonzero means that encoded C++ names should be printed out in their /* Nonzero means that encoded C++/ObjC names should be printed out in their
C++ form rather than raw. */ C++/ObjC form rather than raw. */
int demangle = 1; int demangle = 1;
/* Nonzero means that encoded C++ names should be printed out in their /* Nonzero means that encoded C++/ObjC names should be printed out in their
C++ form even in assembler language displays. If this is set, but C++/ObjC form even in assembler language displays. If this is set, but
DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */ DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */
int asm_demangle = 0; int asm_demangle = 0;
@ -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 /* Ensure that whatever gets printed next, using the filtered output
commands, starts at the beginning of the line. I.E. if there is 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 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); fputs_filtered (n_spaces (n), stream);
} }
/* C++ demangler stuff. */ /* C++/ObjC demangler stuff. */
/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language /* fprintf_symbol_filtered attempts to demangle NAME, a symbol in
LANG, using demangling args ARG_MODE, and print it filtered to STREAM. language LANG, using demangling args ARG_MODE, and print it
If the name is not mangled, or the language for the name is unknown, or filtered to STREAM. If the name is not mangled, or the language
demangling is off, the name is printed in its "raw" form. */ for the name is unknown, or demangling is off, the name is printed
in its "raw" form. */
void 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) int arg_mode)
{ {
char *demangled; char *demangled;
@ -2233,6 +2281,11 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
case language_java: case language_java:
demangled = cplus_demangle (name, arg_mode | DMGL_JAVA); demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
break; break;
#if 0 /* Enable once objective-c support is turned on. */
case language_objc:
demangled = objc_demangle (name);
break;
#endif
#if 0 #if 0
/* OBSOLETE case language_chill: */ /* OBSOLETE case language_chill: */
/* OBSOLETE demangled = chill_demangle (name); */ /* OBSOLETE demangled = chill_demangle (name); */
@ -2352,7 +2405,7 @@ initialize_utils (void)
add_show_from_set add_show_from_set
(add_set_cmd ("demangle", class_support, var_boolean, (add_set_cmd ("demangle", class_support, var_boolean,
(char *) &demangle, (char *) &demangle,
"Set demangling of encoded C++ names when displaying symbols.", "Set demangling of encoded C++/ObjC names when displaying symbols.",
&setprintlist), &setprintlist),
&showprintlist); &showprintlist);
@ -2380,7 +2433,7 @@ initialize_utils (void)
add_show_from_set add_show_from_set
(add_set_cmd ("asm-demangle", class_support, var_boolean, (add_set_cmd ("asm-demangle", class_support, var_boolean,
(char *) &asm_demangle, (char *) &asm_demangle,
"Set demangling of C++ names in disassembly listings.", "Set demangling of C++/ObjC names in disassembly listings.",
&setprintlist), &setprintlist),
&showprintlist); &showprintlist);
} }

View file

@ -48,10 +48,8 @@ extern int overload_debug;
static int typecmp (int staticp, int varargs, int nargs, static int typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[]); 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 struct value *value_arg_coerce (struct value *, struct type *, int);
static CORE_ADDR value_push (CORE_ADDR, struct value *); static CORE_ADDR value_push (CORE_ADDR, struct value *);
static struct value *search_struct_field (char *, struct value *, int, static struct value *search_struct_field (char *, struct value *, int,
@ -91,7 +89,6 @@ int overload_resolution = 0;
int unwind_on_signal_p = 0; int unwind_on_signal_p = 0;
/* Find the address of function name NAME in the inferior. */ /* Find the address of function name NAME in the inferior. */
struct value * 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. /* Determine a function's address and its return type from its value.
Calls error() if the function is not valid for calling. */ 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) find_function_addr (struct value *function, struct type **retval_type)
{ {
register struct type *ftype = check_typedef (VALUE_TYPE (function)); 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."); 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; return new_val;
} }
/* Return the value of the local variable, if one exists.
/* C++: return the value of the class instance variable, if one exists.
Flag COMPLAIN signals an error if the request is made in an Flag COMPLAIN signals an error if the request is made in an
inappropriate context. */ inappropriate context. */
struct value * struct value *
value_of_this (int complain) value_of_local (const char *name, int complain)
{ {
struct symbol *func, *sym; struct symbol *func, *sym;
struct block *b; struct block *b;
int i; int i;
static const char funny_this[] = "this"; struct value * ret;
struct value *this;
if (selected_frame == 0) if (selected_frame == 0)
{ {
@ -3331,7 +3341,7 @@ value_of_this (int complain)
if (!func) if (!func)
{ {
if (complain) if (complain)
error ("no `this' in nameless context"); error ("no %s in nameless context", name);
else else
return 0; return 0;
} }
@ -3341,26 +3351,39 @@ value_of_this (int complain)
if (i <= 0) if (i <= 0)
{ {
if (complain) if (complain)
error ("no args, no `this'"); error ("no args, no %s", name);
else else
return 0; return 0;
} }
/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
symbol instead of the LOC_ARG one (if both exist). */ 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 (sym == NULL)
{ {
if (complain) if (complain)
error ("current stack frame not in method"); error ("current stack frame does not contain a variable named \"%s\"", name);
else else
return NULL; return NULL;
} }
this = read_var_value (sym, selected_frame); ret = read_var_value (sym, selected_frame);
if (this == 0 && complain) if (ret == 0 && complain)
error ("`this' argument at unknown address"); error ("%s argument unreadable", name);
return this; 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 /* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH elements

View file

@ -535,6 +535,12 @@ extern void clear_value_history (void);
extern void clear_internalvars (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 */ /* From values.c */
extern struct value *value_copy (struct value *); 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, extern struct value *call_function_by_hand (struct value *, int,
struct value **); 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 default_coerce_float_to_double (struct type *, struct type *);
extern int standard_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 sp, int struct_return,
CORE_ADDR struct_addr); CORE_ADDR struct_addr);
extern CORE_ADDR find_function_addr (struct value *, struct type **);
#endif /* !defined (VALUE_H) */ #endif /* !defined (VALUE_H) */