home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Education Sampler 1992 [NeXTSTEP]
/
Education_1992_Sampler.iso
/
NeXT
/
GnuSource
/
cc-61.0.1
/
cc
/
objc-parse.y-diffs
< prev
next >
Wrap
Text File
|
1991-06-19
|
33KB
|
1,250 lines
*** c-parse.y Wed Jun 12 15:26:45 1991
--- objc-parse.y Wed Jun 19 13:26:42 1991
***************
*** 1,5 ****
--- 1,6 ----
/* YACC parser for C syntax.
Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
+ Objective-C extensions by s.naroff.
This file is part of GNU CC.
***************
*** 48,53 ****
--- 49,56 ----
#include "c-tree.h"
#include "flags.h"
+ #include "objc-actions.h"
+
#ifdef MULTIBYTE_CHARS
#include <stdlib.h>
#include <locale.h>
***************
*** 117,122 ****
--- 120,129 ----
%token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF ALIGN
%token ATTRIBUTE EXTENSION LABEL
+ /* the Objective-C keywords */
+ %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
+ %token CLASSNAME PUBLIC
+
/* Add precedence rules to solve dangling else s/r conflict */
%nonassoc IF
%nonassoc ELSE
***************
*** 174,179 ****
--- 181,196 ----
%type <filename> save_filename
%type <lineno> save_lineno
+ /* the Objective-C nonterminals */
+
+ %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
+ %type <ttype> methoddecl unaryselector keywordselector selector
+ %type <ttype> keyworddecl receiver objcmessageexpr messageargs
+ %type <ttype> keywordexpr keywordarglist keywordarg
+ %type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
+ %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
+ %type <ttype> CLASSNAME
+
%{
/* the declaration found for the last IDENTIFIER token read in.
yylex must look this up to detect typedefs, which get token type TYPENAME,
***************
*** 202,207 ****
--- 219,238 ----
static int yylex ();
+ /* Objective-C specific information */
+
+ static tree objc_interface_context;
+ static tree objc_implementation_context;
+ static tree objc_method_context;
+ static tree objc_ivar_chain;
+ static tree objc_ivar_context;
+ static enum tree_code objc_inherit_code;
+ static int objc_receiver_context;
+ static int objc_public_flag;
+
+ static char *token_buffer; /* Pointer to token buffer.
+ Actual allocated length is maxtoken + 2. */
+
/* Tell yyparse how to print a token's value, if yydebug is set. */
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
***************
*** 250,257 ****
%%
program: /* empty */
{ if (pedantic)
! pedwarn ("ANSI C forbids an empty source file"); }
| extdefs
;
/* the reason for the strange actions in this rule
--- 281,290 ----
%%
program: /* empty */
{ if (pedantic)
! pedwarn ("ANSI C forbids an empty source file");
! objc_finish (); }
| extdefs
+ { objc_finish (); }
;
/* the reason for the strange actions in this rule
***************
*** 266,271 ****
--- 299,305 ----
extdef:
fndef
| datadef
+ | objcdef
| ASM '(' string ')' ';'
{ if (pedantic)
pedwarn ("ANSI C forbids use of `asm' keyword");
***************
*** 330,335 ****
--- 364,371 ----
identifier:
IDENTIFIER
| TYPENAME
+ | CLASSNAME
+ { $$ = CLASS_NAME ($1); }
;
unop: '&'
***************
*** 480,488 ****
yychar = YYLEX;
if (yychar == '(')
{
! $$ = implicitly_declare ($1);
! assemble_external ($$);
! TREE_USED ($$) = 1;
}
else if (current_function_decl == 0)
{
--- 516,536 ----
yychar = YYLEX;
if (yychar == '(')
{
! if (objc_receiver_context
! && ! (objc_receiver_context
! && strcmp (IDENTIFIER_POINTER ($1), "super")))
! /* we have a message to super */
! $$ = get_super_receiver ();
! else if (objc_method_context
! && is_ivar (objc_ivar_chain, $1))
! $$ = build_ivar_reference ($1);
! else
! {
! /* Ordinary implicit function declaration. */
! $$ = implicitly_declare ($1);
! assemble_external ($$);
! TREE_USED ($$) = 1;
! }
}
else if (current_function_decl == 0)
{
***************
*** 492,521 ****
}
else
{
! if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
! || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
{
! error ("`%s' undeclared (first use this function)",
! IDENTIFIER_POINTER ($1));
!
! if (! undeclared_variable_notice)
{
! error ("(Each undeclared identifier is reported only once");
! error ("for each function it appears in.)");
! undeclared_variable_notice = 1;
}
! }
! $$ = error_mark_node;
! /* Prevent repeated error messages. */
! IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
! IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
}
}
! else if (! TREE_USED ($$))
{
! if (TREE_EXTERNAL ($$))
! assemble_external ($$);
! TREE_USED ($$) = 1;
}
if (TREE_CODE ($$) == CONST_DECL)
$$ = DECL_INITIAL ($$);
--- 540,601 ----
}
else
{
! if (objc_receiver_context
! && ! (objc_receiver_context
! && strcmp (IDENTIFIER_POINTER ($1), "super")))
! /* we have a message to super */
! $$ = get_super_receiver ();
! else if (objc_method_context
! && is_ivar (objc_ivar_chain, $1))
! $$ = build_ivar_reference ($1);
! else
{
! if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
! || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
{
! error ("`%s' undeclared (first use this function)",
! IDENTIFIER_POINTER ($1));
!
! if (! undeclared_variable_notice)
! {
! error ("(Each undeclared identifier is reported only once");
! error ("for each function it appears in.)");
! undeclared_variable_notice = 1;
! }
}
! $$ = error_mark_node;
! /* Prevent repeated error messages. */
! IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
! IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
! }
}
}
! else
{
! if (! TREE_USED ($$))
! {
! if (TREE_EXTERNAL ($$))
! assemble_external ($$);
! TREE_USED ($$) = 1;
! }
! /* we have a definition - still check if iVariable */
!
! if (!objc_receiver_context
! || (objc_receiver_context
! && strcmp (IDENTIFIER_POINTER ($1), "super")))
! {
! if (objc_method_context
! && is_ivar (objc_ivar_chain, $1))
! {
! if (IDENTIFIER_LOCAL_VALUE ($1))
! warning ("local declaration of `%s' hides instance variable",
! IDENTIFIER_POINTER ($1));
! else
! $$ = build_ivar_reference ($1);
! }
! }
! else /* we have a message to super */
! $$ = get_super_receiver ();
}
if (TREE_CODE ($$) == CONST_DECL)
$$ = DECL_INITIAL ($$);
***************
*** 562,574 ****
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
! { $$ = build_component_ref ($1, $3); }
| primary POINTSAT identifier
! { $$ = build_component_ref (build_indirect_ref ($1, "->"), $3); }
| primary PLUSPLUS
{ $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
| primary MINUSMINUS
{ $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
;
/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
--- 642,682 ----
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
! {
! if (doing_objc_thang)
! {
! if (is_public ($1, $3))
! $$ = build_component_ref ($1, $3);
! else
! $$ = error_mark_node;
! }
! else
! $$ = build_component_ref ($1, $3);
! }
| primary POINTSAT identifier
! {
! tree anExpr = build_indirect_ref ($1, "->");
!
! if (doing_objc_thang)
! {
! if (is_public (anExpr, $3))
! $$ = build_component_ref (anExpr, $3);
! else
! $$ = error_mark_node;
! }
! else
! $$ = build_component_ref (anExpr, $3);
! }
| primary PLUSPLUS
{ $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
| primary MINUSMINUS
{ $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
+ | objcmessageexpr
+ { $$ = build_message_expr ($1); }
+ | objcselectorexpr
+ { $$ = build_selector_expr ($1); }
+ | objcencodeexpr
+ { $$ = build_encode_expr ($1); }
;
/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
***************
*** 701,706 ****
--- 809,816 ----
{ /* For a typedef name, record the meaning, not the name.
In case of `foo foo, bar;'. */
$$ = lookup_name ($1); }
+ | CLASSNAME
+ { $$ = get_static_reference ($1); }
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3);
if (pedantic)
***************
*** 1016,1021 ****
--- 1126,1134 ----
| component_decl_list2 ';'
{ if (pedantic)
warning ("extra semicolon in struct or union specified"); }
+ /* foo(sizeof(struct{ @defs(ClassName)})); */
+ | DEFS '(' CLASSNAME ')'
+ { $$ = get_class_ivars ($3); }
;
/* There is a shift-reduce conflict here, because `components' may
***************
*** 1161,1167 ****
pushlevel (0);
clear_last_expr ();
push_momentary ();
! expand_start_bindings (0); }
;
/* Read zero or more forward-declarations for labels
--- 1274,1282 ----
pushlevel (0);
clear_last_expr ();
push_momentary ();
! expand_start_bindings (0);
! if (objc_method_context)
! add_objc_decls (); }
;
/* Read zero or more forward-declarations for labels
***************
*** 1567,1572 ****
--- 1682,2248 ----
| identifiers ',' IDENTIFIER
{ $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
;
+
+ /*
+ * Objective-C productions.
+ */
+ objcdef:
+ classdef
+ | methoddef
+ | END
+ {
+ if (objc_implementation_context)
+ {
+ finish_class (objc_implementation_context);
+ objc_ivar_chain = NULL_TREE;
+ objc_implementation_context = NULL_TREE;
+ }
+ else
+ warning ("`@end' must appear in an implementation context");
+ }
+ ;
+
+ classdef:
+ INTERFACE identifier '{'
+ {
+ objc_interface_context = objc_ivar_context
+ = start_class (INTERFACE_TYPE, $2, NULL_TREE);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier
+ {
+ objc_interface_context
+ = start_class (INTERFACE_TYPE, $2, NULL_TREE);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier ':' identifier '{'
+ {
+ objc_interface_context = objc_ivar_context
+ = start_class (INTERFACE_TYPE, $2, $4);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | INTERFACE identifier ':' identifier
+ {
+ objc_interface_context
+ = start_class (INTERFACE_TYPE, $2, $4);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | IMPLEMENTATION identifier '{'
+ {
+ objc_implementation_context = objc_ivar_context
+ = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier
+ {
+ objc_implementation_context
+ = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier ':' identifier '{'
+ {
+ objc_implementation_context = objc_ivar_context
+ = start_class (IMPLEMENTATION_TYPE, $2, $4);
+ objc_public_flag = 0;
+ }
+ ivar_decl_list '}'
+ {
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | IMPLEMENTATION identifier ':' identifier
+ {
+ objc_implementation_context
+ = start_class (IMPLEMENTATION_TYPE, $2, $4);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+
+ | INTERFACE identifier '(' identifier ')'
+ {
+ objc_interface_context
+ = start_class (PROTOCOL_TYPE, $2, $4);
+ continue_class (objc_interface_context);
+ }
+ methodprotolist
+ END
+ {
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+
+ | IMPLEMENTATION identifier '(' identifier ')'
+ {
+ objc_implementation_context
+ = start_class (CATEGORY_TYPE, $2, $4);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+ }
+ ;
+
+ ivar_decl_list:
+ ivar_decls PUBLIC { objc_public_flag = 1; } ivar_decls
+ | ivar_decls
+ ;
+
+ ivar_decls:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | ivar_decls ivar_decl ';'
+ | ivar_decls ';'
+ {
+ if (pedantic)
+ warning ("extra semicolon in struct or union specified");
+ }
+ ;
+
+
+ /* There is a shift-reduce conflict here, because `components' may
+ start with a `typename'. It happens that shifting (the default resolution)
+ does the right thing, because it treats the `typename' as part of
+ a `typed_typespecs'.
+
+ It is possible that this same technique would allow the distinction
+ between `notype_initdecls' and `initdecls' to be eliminated.
+ But I am being cautious and not trying it. */
+
+ ivar_decl:
+ typed_typespecs setspecs ivars
+ {
+ $$ = $3;
+ resume_momentary ($2);
+ }
+ | nonempty_type_quals setspecs ivars
+ {
+ $$ = $3;
+ resume_momentary ($2);
+ }
+ | error
+ { $$ = NULL_TREE; }
+ ;
+
+ ivars:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | ivar_declarator
+ | ivars ',' ivar_declarator
+ ;
+
+ ivar_declarator:
+ declarator
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ $1, current_declspecs,
+ NULL_TREE);
+ }
+ | declarator ':' expr_no_commas
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ $1, current_declspecs, $3);
+ }
+ | ':' expr_no_commas
+ {
+ $$ = add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ NULL_TREE,
+ current_declspecs, $2);
+ }
+ ;
+
+ methoddef:
+ '+'
+ {
+ if (objc_implementation_context)
+ objc_inherit_code = CLASS_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ }
+ methoddecl
+ {
+ add_class_method (objc_implementation_context, $3);
+ start_method_def ($3);
+ objc_method_context = $3;
+ }
+ optarglist
+ {
+ continue_method_def ();
+ }
+ compstmt_or_error
+ {
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ }
+
+ | '-'
+ {
+ if (objc_implementation_context)
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ else
+ fatal ("method definition not in class context");
+ }
+ methoddecl
+ {
+ add_instance_method (objc_implementation_context, $3);
+ start_method_def ($3);
+ objc_method_context = $3;
+ }
+ optarglist
+ {
+ continue_method_def ();
+ }
+ compstmt_or_error
+ {
+ finish_method_def ();
+ objc_method_context = NULL_TREE;
+ }
+ ;
+
+ /* the reason for the strange actions in this rule
+ is so that notype_initdecls when reached via datadef
+ can find a valid list of type and sc specs in $0. */
+
+ methodprotolist:
+ /* empty */
+ | {$<ttype>$ = NULL_TREE; } methodprotolist2
+ ;
+
+ methodprotolist2: /* eliminates a shift/reduce conflict */
+ methodproto
+ | datadef
+ | methodprotolist2 methodproto
+ | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
+ ;
+
+ semi_or_error:
+ ';'
+ | error
+ ;
+
+ methodproto:
+ '+'
+ {
+ objc_inherit_code = CLASS_METHOD_DECL;
+ }
+ methoddecl
+ {
+ add_class_method (objc_interface_context, $3);
+ }
+ semi_or_error
+
+ | '-'
+ {
+ objc_inherit_code = INSTANCE_METHOD_DECL;
+ }
+ methoddecl
+ {
+ add_instance_method (objc_interface_context, $3);
+ }
+ semi_or_error
+ ;
+
+ methoddecl:
+ '(' typename ')' unaryselector
+ {
+ $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE);
+ }
+
+ | unaryselector
+ {
+ $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
+ }
+
+ | '(' typename ')' keywordselector optparmlist
+ {
+ $$ = build_method_decl (objc_inherit_code, $2, $4, $5);
+ }
+
+ | keywordselector optparmlist
+ {
+ $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
+ }
+ ;
+
+ /* "optarglist" assumes that start_method_def has already been called...
+ if it is not, the "xdecls" will not be placed in the proper scope */
+
+ optarglist:
+ /* empty */
+ | ';' myxdecls
+ ;
+
+ /* to get around the following situation: "int foo (int a) int b; {}" that
+ is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
+
+ myxdecls:
+ /* empty */
+ | mydecls
+ ;
+
+ mydecls:
+ mydecl
+ | errstmt
+ | mydecls mydecl
+ | mydecl errstmt
+ ;
+
+ mydecl:
+ typed_declspecs setspecs myparms ';'
+ { resume_momentary ($2); }
+ | typed_declspecs ';'
+ { shadow_tag ($1); }
+ | declmods ';'
+ { warning ("empty declaration"); }
+ ;
+
+ myparms:
+ myparm
+ { push_parm_decl ($1); }
+ | myparms ',' myparm
+ { push_parm_decl ($3); }
+ ;
+
+ /* A single parameter declaration or parameter type name,
+ as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
+
+ myparm:
+ parm_declarator
+ { $$ = build_tree_list (current_declspecs, $1) ; }
+ | notype_declarator
+ { $$ = build_tree_list (current_declspecs, $1) ; }
+ | absdcl
+ { $$ = build_tree_list (current_declspecs, $1) ; }
+ ;
+
+ optparmlist:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | ',' ELLIPSIS
+ {
+ /* oh what a kludge! */
+ $$ = (tree)1;
+ }
+ | ','
+ {
+ pushlevel (0);
+ }
+ parmlist_2
+ {
+ /* returns a tree list node generated by get_parm_info */
+ $$ = $3;
+ poplevel (0, 0, 0);
+ }
+ ;
+
+ unaryselector:
+ selector
+ ;
+
+ keywordselector:
+ keyworddecl
+
+ | keywordselector keyworddecl
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+ selector:
+ IDENTIFIER
+ | TYPENAME
+ | reservedwords
+ ;
+
+ reservedwords:
+ ENUM { $$ = get_identifier (token_buffer); }
+ | STRUCT { $$ = get_identifier (token_buffer); }
+ | UNION { $$ = get_identifier (token_buffer); }
+ | IF { $$ = get_identifier (token_buffer); }
+ | ELSE { $$ = get_identifier (token_buffer); }
+ | WHILE { $$ = get_identifier (token_buffer); }
+ | DO { $$ = get_identifier (token_buffer); }
+ | FOR { $$ = get_identifier (token_buffer); }
+ | SWITCH { $$ = get_identifier (token_buffer); }
+ | CASE { $$ = get_identifier (token_buffer); }
+ | DEFAULT { $$ = get_identifier (token_buffer); }
+ | BREAK { $$ = get_identifier (token_buffer); }
+ | CONTINUE { $$ = get_identifier (token_buffer); }
+ | RETURN { $$ = get_identifier (token_buffer); }
+ | GOTO { $$ = get_identifier (token_buffer); }
+ | ASM { $$ = get_identifier (token_buffer); }
+ | SIZEOF { $$ = get_identifier (token_buffer); }
+ | TYPEOF { $$ = get_identifier (token_buffer); }
+ | ALIGNOF { $$ = get_identifier (token_buffer); }
+ | TYPESPEC | TYPE_QUAL
+ ;
+
+ keyworddecl:
+ selector ':' '(' typename ')' identifier
+ {
+ $$ = build_keyword_decl ($1, $4, $6);
+ }
+
+ | selector ':' identifier
+ {
+ $$ = build_keyword_decl ($1, NULL_TREE, $3);
+ }
+
+ | ':' '(' typename ')' identifier
+ {
+ $$ = build_keyword_decl (NULL_TREE, $3, $5);
+ }
+
+ | ':' identifier
+ {
+ $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
+ }
+ ;
+
+ messageargs:
+ selector
+ | keywordarglist
+ ;
+
+ keywordarglist:
+ keywordarg
+ | keywordarglist keywordarg
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+
+ keywordexpr:
+ nonnull_exprlist
+ {
+ if (TREE_CHAIN ($1) == NULL_TREE)
+ /* just return the expr., remove a level of indirection */
+ $$ = TREE_VALUE ($1);
+ else
+ /* we have a comma expr., we will collapse later */
+ $$ = $1;
+ }
+ ;
+
+ keywordarg:
+ selector ':' keywordexpr
+ {
+ $$ = build_tree_list ($1, $3);
+ }
+ | ':' keywordexpr
+ {
+ $$ = build_tree_list (NULL_TREE, $2);
+ }
+ ;
+
+ receiver:
+ expr
+ | CLASSNAME
+ {
+ $$ = get_class_reference ($1);
+ }
+ ;
+
+ objcmessageexpr:
+ '['
+ { objc_receiver_context = 1; }
+ receiver
+ { objc_receiver_context = 0; }
+ messageargs ']'
+ {
+ $$ = build_tree_list ($3, $5);
+ }
+ ;
+
+ selectorarg:
+ selector
+ | keywordnamelist
+ ;
+
+ keywordnamelist:
+ keywordname
+ | keywordnamelist keywordname
+ {
+ $$ = chainon ($1, $2);
+ }
+ ;
+
+ keywordname:
+ selector ':'
+ {
+ $$ = build_tree_list ($1, NULL_TREE);
+ }
+ | ':'
+ {
+ $$ = build_tree_list (NULL_TREE, NULL_TREE);
+ }
+ ;
+
+ objcselectorexpr:
+ SELECTOR '(' selectorarg ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+ /* extension to support C-structures in the archiver */
+
+ objcencodeexpr:
+ ENCODE '(' typename ')'
+ {
+ $$ = groktypename ($3);
+ }
+ ;
%%
/* Return something to represent absolute declarators containing a *.
***************
*** 1608,1660 ****
int check_newline ();
! /* C code produced by gperf version 2.5 (GNU C++ version) */
! /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
struct resword { char *name; short token; enum rid rid; };
- #define TOTAL_KEYWORDS 53
#define MIN_WORD_LENGTH 2
! #define MAX_WORD_LENGTH 13
! #define MIN_HASH_VALUE 7
! #define MAX_HASH_VALUE 102
! /* maximum key range = 96, duplicates = 0 */
#ifdef __GNUC__
__inline
#endif
! static unsigned int
hash (str, len)
register char *str;
register int unsigned len;
{
! static unsigned char asso_values[] =
{
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
! 103, 103, 103, 103, 103, 1, 103, 2, 1, 24,
! 1, 5, 19, 39, 16, 13, 103, 1, 25, 1,
! 34, 34, 24, 103, 13, 12, 1, 45, 24, 7,
! 103, 103, 2, 103, 103, 103, 103, 103,
};
! register int hval = len;
switch (hval)
{
! default:
! case 3:
! hval += asso_values[str[2]];
! case 2:
! case 1:
! hval += asso_values[str[0]];
}
! return hval + asso_values[str[len - 1]];
}
#ifdef __GNUC__
--- 2284,2333 ----
int check_newline ();
! /* Data type that represents the GNU C reserved words. */
struct resword { char *name; short token; enum rid rid; };
#define MIN_WORD_LENGTH 2
! #define MAX_WORD_LENGTH 15 /* maximum size for C keyword */
! #define MIN_HASH_VALUE 9 /* range of the hash keys values */
! #define MAX_HASH_VALUE 95 /* for the perfect hash generator */
#ifdef __GNUC__
__inline
#endif
! static int
hash (str, len)
register char *str;
register int unsigned len;
{
! static unsigned char hash_table[] =
{
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 44, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
! 95, 95, 95, 95, 95, 1, 95, 28, 3, 35,
! 8, 7, 18, 20, 19, 13, 95, 1, 13, 18,
! 1, 62, 1, 95, 1, 2, 1, 3, 35, 6,
! 95, 95, 9, 95, 95, 95, 95, 95,
};
! register int hval = len ;
switch (hval)
{
! default:
! case 3:
! hval += hash_table[str[2]];
! case 2:
! case 1:
! hval += hash_table[str[0]];
}
! return hval + hash_table[str[len - 1]] ;
}
#ifdef __GNUC__
***************
*** 1665,1744 ****
register char *str;
register unsigned int len;
{
! static struct resword wordlist[] =
{
! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
! {"asm", ASM, NORID},
! {"",},
! {"__asm", ASM, NORID},
! {"",},
! {"__asm__", ASM, NORID},
! {"break", BREAK, NORID},
! {"__typeof__", TYPEOF, NORID},
! {"",},
! {"__alignof__", ALIGNOF, NORID},
! {"",},
! {"__attribute__", ATTRIBUTE, NORID},
! {"int", TYPESPEC, RID_INT},
! {"__attribute", ATTRIBUTE, NORID},
! {"__extension__", EXTENSION, NORID},
! {"",},
! {"__signed", TYPESPEC, RID_SIGNED},
! {"",},
! {"__signed__", TYPESPEC, RID_SIGNED},
! {"__inline__", SCSPEC, RID_INLINE},
! {"else", ELSE, NORID},
! {"__inline", SCSPEC, RID_INLINE},
! {"default", DEFAULT, NORID},
! {"__typeof", TYPEOF, NORID},
! {"while", WHILE, NORID},
! {"__alignof", ALIGNOF, NORID},
! {"struct", STRUCT, NORID},
! {"__const", TYPE_QUAL, RID_CONST},
! {"if", IF, NORID},
! {"__const__", TYPE_QUAL, RID_CONST},
! {"__label__", LABEL, NORID},
! {"do", DO, NORID},
! {"__volatile__", TYPE_QUAL, RID_VOLATILE},
! {"sizeof", SIZEOF, NORID},
! {"__volatile", TYPE_QUAL, RID_VOLATILE},
! {"auto", SCSPEC, RID_AUTO},
! {"void", TYPESPEC, RID_VOID},
! {"char", TYPESPEC, RID_CHAR},
! {"static", SCSPEC, RID_STATIC},
! {"case", CASE, NORID},
! {"extern", SCSPEC, RID_EXTERN},
! {"switch", SWITCH, NORID},
! {"for", FOR, NORID},
! {"inline", SCSPEC, RID_INLINE},
! {"typeof", TYPEOF, NORID},
! {"typedef", SCSPEC, RID_TYPEDEF},
! {"short", TYPESPEC, RID_SHORT},
! {"",},
! {"return", RETURN, NORID},
! {"enum", ENUM, NORID},
! {"",},
! {"double", TYPESPEC, RID_DOUBLE},
! {"signed", TYPESPEC, RID_SIGNED},
! {"float", TYPESPEC, RID_FLOAT},
! {"",}, {"",},
! {"volatile", TYPE_QUAL, RID_VOLATILE},
! {"",},
! {"const", TYPE_QUAL, RID_CONST},
! {"",},
! {"unsigned", TYPESPEC, RID_UNSIGNED},
! {"",}, {"",}, {"",}, {"",},
! {"continue", CONTINUE, NORID},
! {"",},
! {"register", SCSPEC, RID_REGISTER},
! {"",}, {"",}, {"",}, {"",},
! {"goto", GOTO, NORID},
! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
!
! {"union", UNION, NORID},
! {"",}, {"",}, {"",}, {"",},
! {"long", TYPESPEC, RID_LONG},
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
--- 2338,2416 ----
register char *str;
register unsigned int len;
{
!
! static struct resword wordlist[] =
{
! { "",},{ "",},{ "",},{ "",},{ "",},{ "",},{ "",},{ "",},{ "",},
! { "return", RETURN, NORID },
! { "struct", STRUCT, NORID },
! { "",},{ "",},
! { "__typeof__", TYPEOF, NORID },
! { "__signed__", TYPESPEC, RID_SIGNED },
! { "extern", SCSPEC, RID_EXTERN },
! { "break", BREAK, NORID },
! { "",},
! { "int", TYPESPEC, RID_INT },
! { "__signed", TYPESPEC, RID_SIGNED },
! { "else", ELSE, NORID },
! { "unsigned", TYPESPEC, RID_UNSIGNED },
! { "union", UNION, NORID },
! { "for", FOR, NORID },
! { "double", TYPESPEC, RID_DOUBLE },
! { "__inline__", SCSPEC, RID_INLINE },
! { "typeof", TYPEOF, NORID },
! { "typedef", SCSPEC, RID_TYPEDEF },
! { "__typeof", TYPEOF, NORID },
! { "__inline", SCSPEC, RID_INLINE },
! { "register", SCSPEC, RID_REGISTER },
! { "while", WHILE, NORID },
! { "enum", ENUM, NORID },
! { "if", IF, NORID },
! { "default", DEFAULT, NORID },
! { "sizeof", SIZEOF, NORID },
! { "signed", TYPESPEC, RID_SIGNED },
! { "__asm__", ASM, NORID },
! { "long", TYPESPEC, RID_LONG },
! { "inline", SCSPEC, RID_INLINE },
! { "switch", SWITCH, NORID },
! { "__alignof__", ALIGNOF, NORID },
! { "const", TYPE_QUAL, RID_CONST },
! { "__attribute__", ATTRIBUTE, NORID },
! { "__const", TYPE_QUAL, RID_CONST },
! { "",},
! { "__const__", TYPE_QUAL, RID_CONST },
! { "__attribute", ATTRIBUTE, NORID },
! { "case", CASE, NORID },
! { "__volatile__", TYPE_QUAL, RID_VOLATILE },
! { "",},
! { "continue", CONTINUE, NORID },
! { "__asm", ASM, NORID },
! { "__volatile", TYPE_QUAL, RID_VOLATILE },
! { "",},{ "",},
! { "__alignof", ALIGNOF, NORID },
! { "@end", END, NORID },
! { "@defs", DEFS, NORID },
! { "@encode", ENCODE, NORID },
! { "void", TYPESPEC, RID_VOID },
! { "@selector", SELECTOR, NORID },
! { "@interface", INTERFACE, NORID },
! { "volatile", TYPE_QUAL, RID_VOLATILE },
! { "",},{ "",},{ "",},
! { "asm", ASM, NORID },
! { "char", TYPESPEC, RID_CHAR },
! { "",},
! { "short", TYPESPEC, RID_SHORT },
! { "static", SCSPEC, RID_STATIC },
! { "do", DO, NORID },
! { "",},{ "",},{ "",},{ "",},{ "",},
! { "@implementation", IMPLEMENTATION, NORID },
! { "",},{ "",},{ "",},{ "",},{ "",},{ "",},{ "",},
! { "float", TYPESPEC, RID_FLOAT },
! { "goto", GOTO, NORID },
! { "",},
! { "@public", PUBLIC, NORID },
! { "",},{ "",},{ "",},{ "",},{ "",},
! { "auto", SCSPEC, RID_AUTO },
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
***************
*** 1745,1751 ****
{
register int key = hash (str, len);
! if (key <= MAX_HASH_VALUE && key >= 0)
{
register char *s = wordlist[key].name;
--- 2417,2423 ----
{
register int key = hash (str, len);
! if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
{
register char *s = wordlist[key].name;
***************
*** 2385,2393 ****
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
letter:
p = token_buffer;
! while (isalnum (c) || c == '_' || c == '$')
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
--- 3057,3066 ----
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
+ case '@':
letter:
p = token_buffer;
! while (isalnum (c) || c == '_' || c == '$' || c == '@')
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
***************
*** 2422,2432 ****
--- 3095,3117 ----
if (value == IDENTIFIER)
{
+ if (token_buffer[0] == '@')
+ error ("invalid identifier `%s'", token_buffer);
yylval.ttype = get_identifier (token_buffer);
lastiddecl = lookup_name (yylval.ttype);
if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
value = TYPENAME;
+ else if (doing_objc_thang)
+ {
+ tree objc_interface_decl = lookup_interface (yylval.ttype);
+
+ if (objc_interface_decl)
+ {
+ value = CLASSNAME;
+ yylval.ttype = objc_interface_decl;
+ }
+ }
}
break;