aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parse.in
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-parse.in')
-rw-r--r--gcc/c-parse.in229
1 files changed, 159 insertions, 70 deletions
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 6940f87..6b3374a 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -160,7 +160,11 @@ void yyerror ();
/* The Objective-C keywords. These are included in C and in
Objective C, so that the token codes are the same in both. */
%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
-%token CLASSNAME PUBLIC
+%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+
+/* Objective-C string constants in raw form.
+ yylval is an OBJC_STRING_CST node. */
+%token OBJC_STRING
%type <code> unop
@@ -206,7 +210,8 @@ ifobjc
%type <ttype> keywordexpr keywordarglist keywordarg
%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
-%type <ttype> CLASSNAME
+%type <ttype> objc_string protocolrefs identifier_list objcprotocolexpr
+%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
end ifobjc
%{
@@ -350,8 +355,8 @@ identifier:
IDENTIFIER
| TYPENAME
ifobjc
+ | OBJECTNAME
| CLASSNAME
- { $$ = CLASS_NAME ($1); }
end ifobjc
;
@@ -534,14 +539,21 @@ primary:
if (yychar == '(')
{
ifobjc
+ tree decl;
+
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);
+ && (decl = is_ivar (objc_ivar_chain, $1)))
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
else
end ifobjc
{
@@ -560,13 +572,20 @@ end ifobjc
else
{
ifobjc
+ tree decl;
+
if (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);
+ && (decl = is_ivar (objc_ivar_chain, $1)))
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
else
end ifobjc
{
@@ -646,14 +665,21 @@ ifobjc
|| (objc_receiver_context
&& strcmp (IDENTIFIER_POINTER ($1), "super")))
{
+ tree decl;
+
if (objc_method_context
- && is_ivar (objc_ivar_chain, $1))
+ && (decl = 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);
+ {
+ if (is_private (decl))
+ $$ = error_mark_node;
+ else
+ $$ = build_ivar_reference ($1);
+ }
}
}
else /* we have a message to super */
@@ -756,8 +782,12 @@ ifobjc
{ $$ = build_message_expr ($1); }
| objcselectorexpr
{ $$ = build_selector_expr ($1); }
+ | objcprotocolexpr
+ { $$ = build_protocol_expr ($1); }
| objcencodeexpr
{ $$ = build_encode_expr ($1); }
+ | objc_string
+ { $$ = build_objc_string_object ($1); }
end ifobjc
;
@@ -768,6 +798,16 @@ string:
{ $$ = chainon ($1, $2); }
;
+ifobjc
+/* Produces an OBJC_STRING_CST with prehaps more OBJC_STRING_CSTs chained
+ onto it. */
+objc_string:
+ OBJC_STRING
+ | objc_string OBJC_STRING
+ { $$ = chainon ($1, $2); }
+ ;
+end ifobjc
+
xdecls:
/* empty */
| datadecls
@@ -932,8 +972,10 @@ typespec: TYPESPEC
In case of `foo foo, bar;'. */
$$ = lookup_name ($1); }
ifobjc
- | CLASSNAME
- { $$ = get_static_reference ($1); }
+ | CLASSNAME protocolrefs
+ { $$ = get_static_reference ($1, $2); }
+ | OBJECTNAME protocolrefs
+ { $$ = get_object_reference ($2); }
end ifobjc
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3); }
@@ -1074,7 +1116,10 @@ initlist:
{ $$ = build_tree_list (NULL_TREE, $1); }
| initlist ',' init
{ $$ = tree_cons (NULL_TREE, $3, $1); }
- /* These are for labeled elements. */
+ /* These are for labeled elements. The syntax for an array element
+ initializer conflicts with the syntax for an Objective-C message,
+ so don't include these productions in the Objective-C grammer. */
+ifc
| '[' expr_no_commas ELLIPSIS expr_no_commas ']' init
{ $$ = build_tree_list (tree_cons ($2, NULL_TREE,
build_tree_list ($4, NULL_TREE)),
@@ -1088,6 +1133,7 @@ initlist:
{ $$ = build_tree_list ($2, $4); }
| initlist ',' '[' expr_no_commas ']' init
{ $$ = tree_cons ($4, $6, $1); }
+end ifc
| identifier ':' init
{ $$ = build_tree_list ($1, $3); }
| initlist ',' identifier ':' init
@@ -1161,6 +1207,9 @@ after_type_declarator:
| '*' type_quals after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
| TYPENAME
+ifobjc
+ | OBJECTNAME
+end ifobjc
;
/* Kinds of declarator that can appear in a parameter list
@@ -1271,7 +1320,18 @@ component_decl_list2: /* empty */
ifobjc
/* foo(sizeof(struct{ @defs(ClassName)})); */
| DEFS '(' CLASSNAME ')'
- { $$ = get_class_ivars ($3); }
+ {
+ tree interface = lookup_interface ($3);
+
+ if (interface)
+ $$ = get_class_ivars (interface);
+ else
+ {
+ error ("Cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER ($3));
+ $$ = NULL_TREE;
+ }
+ }
end ifobjc
;
@@ -2012,6 +2072,9 @@ ifobjc
objcdef:
classdef
+ | classdecl
+ | aliasdecl
+ | protocoldef
| methoddef
| END
{
@@ -2026,11 +2089,31 @@ objcdef:
}
;
+/* A nonempty list of identifiers. */
+identifier_list:
+ identifier
+ { $$ = build_tree_list (NULL_TREE, $1); }
+ | identifier_list ',' identifier
+ { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ ;
+
+classdecl:
+ CLASS identifier_list ';'
+ {
+ objc_declare_class ($2);
+ }
+
+aliasdecl:
+ ALIAS identifier identifier ';'
+ {
+ objc_declare_alias ($2, $3);
+ }
+
classdef:
- INTERFACE identifier '{'
+ INTERFACE identifier protocolrefs '{'
{
objc_interface_context = objc_ivar_context
- = start_class (INTERFACE_TYPE, $2, NULL_TREE);
+ = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
objc_public_flag = 0;
}
ivar_decl_list '}'
@@ -2044,10 +2127,10 @@ classdef:
objc_interface_context = NULL_TREE;
}
- | INTERFACE identifier
+ | INTERFACE identifier protocolrefs
{
objc_interface_context
- = start_class (INTERFACE_TYPE, $2, NULL_TREE);
+ = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
continue_class (objc_interface_context);
}
methodprotolist
@@ -2057,10 +2140,10 @@ classdef:
objc_interface_context = NULL_TREE;
}
- | INTERFACE identifier ':' identifier '{'
+ | INTERFACE identifier ':' identifier protocolrefs '{'
{
objc_interface_context = objc_ivar_context
- = start_class (INTERFACE_TYPE, $2, $4);
+ = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
objc_public_flag = 0;
}
ivar_decl_list '}'
@@ -2074,10 +2157,10 @@ classdef:
objc_interface_context = NULL_TREE;
}
- | INTERFACE identifier ':' identifier
+ | INTERFACE identifier ':' identifier protocolrefs
{
objc_interface_context
- = start_class (INTERFACE_TYPE, $2, $4);
+ = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
continue_class (objc_interface_context);
}
methodprotolist
@@ -2090,7 +2173,7 @@ classdef:
| IMPLEMENTATION identifier '{'
{
objc_implementation_context = objc_ivar_context
- = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
objc_public_flag = 0;
}
ivar_decl_list '}'
@@ -2102,7 +2185,7 @@ classdef:
| IMPLEMENTATION identifier
{
objc_implementation_context
- = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
@@ -2110,7 +2193,7 @@ classdef:
| IMPLEMENTATION identifier ':' identifier '{'
{
objc_implementation_context = objc_ivar_context
- = start_class (IMPLEMENTATION_TYPE, $2, $4);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
objc_public_flag = 0;
}
ivar_decl_list '}'
@@ -2122,15 +2205,15 @@ classdef:
| IMPLEMENTATION identifier ':' identifier
{
objc_implementation_context
- = start_class (IMPLEMENTATION_TYPE, $2, $4);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
- | INTERFACE identifier '(' identifier ')'
+ | INTERFACE identifier '(' identifier ')' protocolrefs
{
objc_interface_context
- = start_class (PROTOCOL_TYPE, $2, $4);
+ = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
continue_class (objc_interface_context);
}
methodprotolist
@@ -2143,17 +2226,52 @@ classdef:
| IMPLEMENTATION identifier '(' identifier ')'
{
objc_implementation_context
- = start_class (CATEGORY_TYPE, $2, $4);
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
;
+protocoldef:
+ PROTOCOL identifier protocolrefs
+ {
+ remember_protocol_qualifiers ();
+ objc_interface_context
+ = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
+ }
+ methodprotolist END
+ {
+ forget_protocol_qualifiers();
+ finish_protocol(objc_interface_context);
+ objc_interface_context = NULL_TREE;
+ }
+ ;
+
+protocolrefs:
+ /* empty */
+ {
+ $$ = NULL_TREE;
+ }
+ | ARITHCOMPARE identifier_list ARITHCOMPARE
+ {
+ if ($1 == LT_EXPR && $3 == GT_EXPR)
+ $$ = $2;
+ else
+ YYERROR1;
+ }
+ ;
+
ivar_decl_list:
- ivar_decls PUBLIC { objc_public_flag = 1; } ivar_decls
+ ivar_decl_list visibility_spec ivar_decls
| ivar_decls
;
+visibility_spec:
+ PRIVATE { objc_public_flag = 2; }
+ | PROTECTED { objc_public_flag = 0; }
+ | PUBLIC { objc_public_flag = 1; }
+ ;
+
ivar_decls:
/* empty */
{
@@ -2225,6 +2343,7 @@ ivar_declarator:
methoddef:
'+'
{
+ remember_protocol_qualifiers ();
if (objc_implementation_context)
objc_inherit_code = CLASS_METHOD_DECL;
else
@@ -2232,6 +2351,7 @@ methoddef:
}
methoddecl
{
+ forget_protocol_qualifiers ();
add_class_method (objc_implementation_context, $3);
start_method_def ($3);
objc_method_context = $3;
@@ -2248,6 +2368,7 @@ methoddef:
| '-'
{
+ remember_protocol_qualifiers ();
if (objc_implementation_context)
objc_inherit_code = INSTANCE_METHOD_DECL;
else
@@ -2255,6 +2376,7 @@ methoddef:
}
methoddecl
{
+ forget_protocol_qualifiers ();
add_instance_method (objc_implementation_context, $3);
start_method_def ($3);
objc_method_context = $3;
@@ -2424,6 +2546,7 @@ keywordselector:
selector:
IDENTIFIER
| TYPENAME
+ | OBJECTNAME
| reservedwords
;
@@ -2559,6 +2682,13 @@ objcselectorexpr:
}
;
+objcprotocolexpr:
+ PROTOCOL '(' identifier ')'
+ {
+ $$ = $3;
+ }
+ ;
+
/* extension to support C-structures in the archiver */
objcencodeexpr:
@@ -2570,44 +2700,3 @@ objcencodeexpr:
end ifobjc
%%
-ifobjc
-
-/* If STRING is the name of an Objective C @-keyword
- (not including the @), return the token type for that keyword.
- Otherwise return 0. */
-
-int
-recognize_objc_keyword (string)
- char *string;
-{
- switch (string[0])
- {
- case 'd':
- if (!strcmp (string, "defs"))
- return DEFS;
- break;
- case 'e':
- if (!strcmp (string, "end"))
- return END;
- if (!strcmp (string, "encode"))
- return ENCODE;
- break;
- case 'i':
- if (!strcmp (string, "interface"))
- return INTERFACE;
- if (!strcmp (string, "implementation"))
- return IMPLEMENTATION;
- break;
- case 'p':
- if (!strcmp (string, "public"))
- return PUBLIC;
- break;
- case 's':
- if (!strcmp (string, "selector"))
- return SELECTOR;
- break;
- }
- return 0;
-}
-
-end ifobjc