From: Klee Dienes <klee@mit.edu>
To: Adam Fedor <fedor@doc.com>
Cc: gdb-patches@sources.redhat.com
Subject: Re: Add rules for ObjC files
Date: Fri, 04 Oct 2002 02:25:00 -0000 [thread overview]
Message-ID: <3239ADC4-D77B-11D6-A34B-00039396EEB8@mit.edu> (raw)
In-Reply-To: <3D9CF4C4.6030903@doc.com>
[-- Attachment #1: Type: text/plain, Size: 975 bytes --]
I'm not sure if this is something you want to hassle with at the
moment, or if you'd prefer to let it wait as a modification once a
working version of the Objective-C patches are successfully committed.
But just as a heads-up, I should mention that in more recent versions
of our GDB, we've folded in all of the Objective-C support directly
into c-exp.y, and removed objc-exp.y as a file entirely. Most of
objc-exp.y was always just an out-of-date copy of c-exp.y, anyway;
moving the (rather small) changes into c-exp.y directly not only
allowed us to track changes to the C parser much more smoothly, it
should also allow for much better Objective-C++ support.
You'll probably want to look at the most recent version of our GDB tree
(http://www.opensource.apple.com/projects/darwin/6.0/source/other/gdb-
20020918.tar.gz; no registration or anything similar required), and
check out our changes to c-exp.y; I've attached them for your
convenience.
[-- Attachment #2: objc.diffs --]
[-- Type: application/octet-stream, Size: 9129 bytes --]
diff -u -r1.1.1.8 c-exp.y
--- c-exp.y 2002/09/26 20:56:42 1.1.1.8
+++ c-exp.y 2002/10/04 08:31:39
@@ -46,9 +46,11 @@
#include "parser-defs.h"
#include "language.h"
#include "c-lang.h"
+#include "objc-lang.h" /* For Obj-C language constructs. */
#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. */
#include "charset.h"
/* Flag indicating we're dealing with HP-compiled objects */
@@ -140,6 +142,7 @@
struct block *bval;
enum exp_opcode opcode;
struct internalvar *ivar;
+ struct objc_class_str class;
struct type **tvec;
int *ivec;
@@ -173,8 +176,11 @@
nonterminal "name", which matches either NAME or TYPENAME. */
%token <sval> STRING
-%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <sval> NSSTRING /* Obj-C Foundation "NSString" literal */
+%token <sval> SELECTOR /* Obj-C "@selector" pseudo-operator */
+%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
%token <tsym> TYPENAME
+%token <class> CLASSNAME /* Obj-C Class name */
%type <sval> name
%type <ssym> name_not_typename
%type <tsym> typename
@@ -324,6 +330,71 @@
{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
;
+/* The rules below parse Obj-C message calls of the form:
+ '[' target selector {':' argument}* ']' */
+
+exp : '[' TYPENAME
+ {
+ CORE_ADDR class;
+
+ class = lookup_objc_class (copy_name ($2.stoken));
+ if (class == 0)
+ error ("%s is not an ObjC Class",
+ copy_name ($2.stoken));
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST) class);
+ write_exp_elt_opcode (OP_LONG);
+ start_msglist();
+ }
+ msglist ']'
+ { write_exp_elt_opcode (OP_MSGCALL);
+ end_msglist();
+ write_exp_elt_opcode (OP_MSGCALL);
+ }
+ ;
+
+exp : '[' CLASSNAME
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST) $2.class);
+ write_exp_elt_opcode (OP_LONG);
+ start_msglist();
+ }
+ msglist ']'
+ { write_exp_elt_opcode (OP_MSGCALL);
+ end_msglist();
+ write_exp_elt_opcode (OP_MSGCALL);
+ }
+ ;
+
+exp : '[' exp
+ { start_msglist(); }
+ msglist ']'
+ { write_exp_elt_opcode (OP_MSGCALL);
+ end_msglist();
+ write_exp_elt_opcode (OP_MSGCALL);
+ }
+ ;
+
+msglist : name
+ { add_msglist(&$1, 0); }
+ | msgarglist
+ ;
+
+msgarglist : msgarg
+ | msgarglist msgarg
+ ;
+
+msgarg : name ':' exp
+ { add_msglist(&$1, 1); }
+ | ':' exp /* Unnamed argument. */
+ { add_msglist(0, 1); }
+ | ',' exp /* Variable number of arguments. */
+ { add_msglist(0, 0); }
+ ;
+
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
@@ -499,6 +570,13 @@
/* Already written by write_dollar_variable. */
;
+exp : SELECTOR
+ {
+ write_exp_elt_opcode (OP_SELECTOR);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_SELECTOR); }
+
+
exp : SIZEOF '(' type ')' %prec UNARY
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
@@ -531,6 +609,14 @@
write_exp_elt_opcode (OP_ARRAY); }
;
+exp : NSSTRING /* ObjC NextStep NSString constant
+ * of the form '@' '"' string '"'.
+ */
+ { write_exp_elt_opcode (OP_NSSTRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_NSSTRING); }
+ ;
+
/* C++. */
exp : THIS
{ write_exp_elt_opcode (OP_THIS);
@@ -804,6 +899,14 @@
typebase /* Implements (approximately): (type-qualifier)* type-specifier */
: TYPENAME
{ $$ = $1.type; }
+ | CLASSNAME
+ {
+ if ($1.type == NULL)
+ error ("No symbol \"%s\" in current context.",
+ copy_name($1.stoken));
+ else
+ $$ = $1.type;
+ }
| INT_KEYWORD
{ $$ = builtin_type_int; }
| LONG
@@ -951,7 +1054,8 @@
name : NAME { $$ = $1.stoken; }
| BLOCKNAME { $$ = $1.stoken; }
| TYPENAME { $$ = $1.stoken; }
- | NAME_OR_INT { $$ = $1.stoken; }
+ | CLASSNAME { $$ = $1.stoken; }
+ | NAME_OR_INT { $$ = $1.stoken; }
;
name_not_typename : NAME
@@ -1239,6 +1343,7 @@
int c;
int namelen;
unsigned int i;
+ int tokchr;
char *tokstart;
char *tokptr;
int tempbufindex;
@@ -1284,7 +1389,7 @@
return tokentab2[i].token;
}
- switch (c = *tokstart)
+ switch (tokchr = *tokstart)
{
case 0:
/* If we were just scanning the result of a macro expansion,
@@ -1331,7 +1436,8 @@
c = *lexptr++;
if (c != '\'')
{
- namelen = skip_quoted (tokstart) - tokstart;
+ namelen = skip_quoted (tokstart, get_gdb_completer_word_break_characters ())
+ - tokstart;
if (namelen > 2)
{
lexptr = tokstart + namelen;
@@ -1349,14 +1455,14 @@
case '(':
paren_depth++;
lexptr++;
- return c;
+ return '(';
case ')':
if (paren_depth == 0)
return 0;
paren_depth--;
lexptr++;
- return c;
+ return ')';
case ',':
if (comma_terminates
@@ -1364,7 +1470,7 @@
&& ! scanning_macro_expansion ())
return 0;
lexptr++;
- return c;
+ return ',';
case '.':
/* Might be a floating point number. */
@@ -1445,7 +1572,6 @@
case '^':
case '~':
case '!':
- case '@':
case '<':
case '>':
case '[':
@@ -1457,8 +1583,42 @@
case '}':
symbol:
lexptr++;
- return c;
+ return tokchr;
+ case '@':
+ if (strncmp (tokstart, "@selector", 9) == 0)
+ {
+ tokptr = strchr (tokstart, '(');
+ if (tokptr == NULL)
+ error ("Missing '(' in @selector(...)");
+ tempbufindex = 0;
+ /* skip the '(' */
+ tokptr++;
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+ }
+ tempbuf[tempbufindex++] = *tokptr++;
+ } while ((*tokptr != ')') && (*tokptr != '\0'));
+ if (*tokptr++ != ')')
+ error ("Missing ')' in @selector(...)");
+ tempbuf[tempbufindex] = '\0';
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return SELECTOR;
+ }
+ if (tokstart[1] != '"')
+ {
+ lexptr++;
+ return tokchr;
+ }
+ /* Obj-C NSString constant: fall through and parse like STRING. */
+ tokstart++;
+
case '"':
/* Build the gdb internal form of the input string in tempbuf,
@@ -1522,13 +1682,13 @@
yylval.sval.ptr = tempbuf;
yylval.sval.length = tempbufindex;
lexptr = tokptr;
- return (STRING);
+ return (tokchr == '@' ? NSSTRING : STRING);
}
- if (!(c == '_' || c == '$'
- || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ if (!(tokchr == '_' || tokchr == '$' ||
+ (tokchr >= 'a' && tokchr <= 'z') || (tokchr >= 'A' && tokchr <= 'Z')))
/* We must have come across a bad character (e.g. ';'). */
- error ("Invalid character '%c' in expression.", c);
+ error ("Invalid character '%c' in expression.", tokchr);
/* It's a name. See how long it is. */
namelen = 0;
@@ -1672,16 +1832,22 @@
char *tmp = copy_name (yylval.sval);
struct symbol *sym;
int is_a_field_of_this = 0;
+ int *need_this;
int hextype;
+ if (current_language->la_language == language_cplus
+ || current_language->la_language == language_objc
+ || current_language->la_language == language_objcplus)
+ need_this = &is_a_field_of_this;
+ else
+ need_this = (int *) NULL;
+
sym = lookup_symbol (tmp, expression_context_block,
- VAR_NAMESPACE,
- current_language->la_language == language_cplus
- ? &is_a_field_of_this : (int *) NULL,
+ 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 once symbols are read). */
+ psymtabs once symbols are read). */
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
yylval.ssym.sym = sym;
@@ -1794,6 +1960,23 @@
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
return TYPENAME;
+ /* See if it's an Obj-C classname. */
+ if (!sym && should_lookup_objc_class ())
+ {
+ extern struct symbol *lookup_struct_typedef ();
+ sym = lookup_struct_typedef (tmp, expression_context_block, 1);
+ if (sym)
+ {
+ CORE_ADDR Class = lookup_objc_class (tmp);
+ if (Class)
+ {
+ yylval.class.class = Class;
+ yylval.class.type = SYMBOL_TYPE (sym);
+ return CLASSNAME;
+ }
+ }
+ }
+
/* Input names that aren't symbols but ARE valid hex numbers,
when the input radix permits them, can be names or numbers
depending on the parse. Note we support radixes > 16 here. */
[-- Attachment #3: Type: text/plain, Size: 482 bytes --]
One downside to having the changes directly in c-exp.y is that I don't
know of any good way to conditionalize them; though I am by no means a
bison guru.
The following diffs are unrelated to Objective-C; I'm attaching them
just for your reference (the ones in generic.diffs are likely to be
removed in our sources soon as well; the ones in number-parsing.diffs
remove a memory leak caused by calling parse_number on invalid, but are
unrelated to the Objective-C changes).
[-- Attachment #4: number-parsing.diffs --]
[-- Type: application/octet-stream, Size: 3114 bytes --]
Index: c-exp.y
===================================================================
RCS file: /cvs/Darwin/src/live/cygnus/src/gdb/c-exp.y,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 c-exp.y
--- c-exp.y 2002/09/26 20:56:42 1.1.1.8
+++ c-exp.y 2002/10/04 08:33:41
@@ -1384,19 +1490,23 @@
case '9':
{
/* It's a number. */
- int got_dot = 0, got_e = 0, toktype;
+ /* Initialize toktype to anything other than ERROR. */
+ int got_dot = 0, got_e = 0, toktype = FLOAT;
register char *p = tokstart;
int hex = input_radix > 10;
+ int local_radix = input_radix;
- if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ if (tokchr == '0' && (p[1] == 'x' || p[1] == 'X'))
{
p += 2;
hex = 1;
+ local_radix = 16;
}
- else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ else if (tokchr == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
{
p += 2;
hex = 0;
+ local_radix = 10;
}
for (;; ++p)
@@ -1404,25 +1514,42 @@
/* This test includes !hex because 'e' is a valid hex digit
and thus does not indicate a floating point number when
the radix is hex. */
- if (!hex && !got_e && (*p == 'e' || *p == 'E'))
- got_dot = got_e = 1;
+
+ if (!hex && (*p == 'e' || *p == 'E'))
+ if (got_e)
+ 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. */
- else if (!got_dot && *p == '.')
- got_dot = 1;
- else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
- && (*p == '-' || *p == '+'))
+ else if (*p == '.')
+ if (got_dot)
+ toktype = ERROR; /* only one '.' in a float */
+ else
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E') &&
+ (*p == '-' || *p == '+'))
/* This is the sign of the exponent, not the end of the
number. */
continue;
- /* We will take any letters or digits. parse_number will
- complain if past the radix, or if L or U are not final. */
- else if ((*p < '0' || *p > '9')
- && ((*p < 'a' || *p > 'z')
- && (*p < 'A' || *p > 'Z')))
- break;
+ /* 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;
+ }
+ else break;
}
- toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype != ERROR)
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
if (toktype == ERROR)
{
char *err_copy = (char *) alloca (p - tokstart + 1);
[-- Attachment #5: Type: text/plain, Size: 2 bytes --]
[-- Attachment #6: generic.diffs --]
[-- Type: application/octet-stream, Size: 1216 bytes --]
diff -u -r1.1.1.8 c-exp.y
--- c-exp.y 2002/09/26 20:56:42 1.1.1.8
+++ c-exp.y 2002/10/04 08:31:39
@@ -659,7 +745,7 @@
builtin_type_int);
}
else
- if (!have_full_symbols () && !have_partial_symbols ())
+ if (!have_full_symbols () && !have_partial_symbols () && !have_minimal_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
else
error ("No symbol \"%s\" in current context.", name);
@@ -714,7 +809,7 @@
lookup_function_type (builtin_type_int),
builtin_type_int);
}
- else if (!have_full_symbols () && !have_partial_symbols ())
+ else if (!have_full_symbols () && !have_partial_symbols () && !have_minimal_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
else
error ("No symbol \"%s\" in current context.",
@@ -1825,5 +2008,8 @@
if (prev_lexptr)
lexptr = prev_lexptr;
- error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+ 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);
}
[-- Attachment #7: Type: text/plain, Size: 409 bytes --]
On Thursday, October 3, 2002, at 09:54 PM, Adam Fedor wrote:
> This patch adds rules for the ObjC files but does not enable them.
>
> 2002-10-03 Adam Fedor <fedor@gnu.org>
>
> * Makefile.in (SFILES): Add objc-exp.y objc-lang.c.
> (objc_lang_h): Define.
> (YYFILES): Add objc-exp.tab.c.
> (local-maintainer-clean): Remove objc-exp.tab.c.
> (objc-exp.tab.c, objc-exp.tab.o, objc-lang.o): New target.
next prev parent reply other threads:[~2002-10-04 9:25 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-10-03 18:53 Adam Fedor
2002-10-04 2:25 ` Klee Dienes [this message]
2002-10-04 9:07 ` Adam Fedor
2002-10-04 9:49 ` Stan Shebs
2002-10-04 13:20 ` Klee Dienes
2002-10-04 14:49 ` Michael Snyder
2002-10-04 15:31 ` Kevin Buettner
2002-10-21 12:08 ` Andrew Cagney
2002-10-21 15:40 ` Adam Fedor
2002-10-24 20:33 ` Adam Fedor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3239ADC4-D77B-11D6-A34B-00039396EEB8@mit.edu \
--to=klee@mit.edu \
--cc=fedor@doc.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox