Commit f2e6e530 by Ziemowit Laski Committed by Stan Shebs

c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for contextualizing…

c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for contextualizing Objective-C class name lookup by the...

2001-08-01  Ziemowit Laski  <zlaski@apple.com>

        * c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for
	contextualizing Objective-C class name lookup by the lexer.
	(typespec_reserved_nonattr): Disable ObjC class name lookup after
	seeing a TYPESPEC.
	(protocoldef): Add support for forward @protocol declarations.
	(yylexname): Suppress ObjC class name lookup in certain contexts;
	re-enable after lookup is complete.
	(_yylex): Re-enable ObjC class name lookup when certain
	punctuation marks are seen.

	* objc/objc-act.c (check_protocol_recursively): New function used
	for finding circular dependencies in protocols.
	(objc_declare_protocols): New function for handling forward
	@protocol declarations.
	(receiver_is_class_object): Detect the case when 'self' is used
	inside of a class method.
	(build_message_expr): Issue a warning if class method is desired
	but instance method is found instead.
	(conforms_to_protocol): Streamline.
	(objc_comptypes): Detect the fact that 'Bar<Foo> foo' conforms to
	protocol Foo, even if 'Bar foo' does not.
	(check_protocols): Streamline.
	(start_protocol): Add checks for circular and duplicate protocol
	definitions.
	(encode_aggregate_within): For typedefs of structs, encode the
	underlying struct.
	* objc/objc-act.h (PROTOCOL_DEFINED): New tree accessor.
	(objc_declare_protocols): New prototype.

From-SVN: r44536
parent 80858e66
2001-08-01 Ziemowit Laski <zlaski@apple.com>
* c-parse.in (OBJC_NEED_RAW_IDENTIFIER): Define macro and flag for
contextualizing Objective-C class name lookup by the lexer.
(typespec_reserved_nonattr): Disable ObjC class name lookup after
seeing a TYPESPEC.
(protocoldef): Add support for forward @protocol declarations.
(yylexname): Suppress ObjC class name lookup in certain contexts;
re-enable after lookup is complete.
(_yylex): Re-enable ObjC class name lookup when certain
punctuation marks are seen.
* objc/objc-act.c (check_protocol_recursively): New function used
for finding circular dependencies in protocols.
(objc_declare_protocols): New function for handling forward
@protocol declarations.
(receiver_is_class_object): Detect the case when 'self' is used
inside of a class method.
(build_message_expr): Issue a warning if class method is desired
but instance method is found instead.
(conforms_to_protocol): Streamline.
(objc_comptypes): Detect the fact that 'Bar<Foo> foo' conforms to
protocol Foo, even if 'Bar foo' does not.
(check_protocols): Streamline.
(start_protocol): Add checks for circular and duplicate protocol
definitions.
(encode_aggregate_within): For typedefs of structs, encode the
underlying struct.
* objc/objc-act.h (PROTOCOL_DEFINED): New tree accessor.
(objc_declare_protocols): New prototype.
2001-08-01 Neil Booth <neil@cat.daikokuya.demon.co.uk> 2001-08-01 Neil Booth <neil@cat.daikokuya.demon.co.uk>
* cpphash.h (struct cpp_reader): New members line, pseudo_newlines. * cpphash.h (struct cpp_reader): New members line, pseudo_newlines.
......
...@@ -29,10 +29,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -29,10 +29,10 @@ Boston, MA 02111-1307, USA. */
written by AT&T, but I have never seen it. */ written by AT&T, but I have never seen it. */
ifobjc ifobjc
%expect 31 %expect 31 /* shift/reduce conflicts, and 1 reduce/reduce conflict. */
end ifobjc end ifobjc
ifc ifc
%expect 10 %expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
end ifc end ifc
%{ %{
...@@ -295,8 +295,18 @@ int objc_receiver_context; ...@@ -295,8 +295,18 @@ int objc_receiver_context;
int objc_public_flag; int objc_public_flag;
int objc_pq_context; int objc_pq_context;
/* The following flag is needed to contextualize ObjC lexical analysis.
In some cases (e.g., 'int NSObject;'), it is undesirable to bind
an identifier to an ObjC class, even if a class with that name
exists. */
int objc_need_raw_identifier;
#define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL
end ifobjc end ifobjc
ifc
#define OBJC_NEED_RAW_IDENTIFIER(VAL) /* nothing */
end ifc
/* Tell yyparse how to print a token's value, if yydebug is set. */ /* Tell yyparse how to print a token's value, if yydebug is set. */
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
...@@ -444,7 +454,7 @@ identifier: ...@@ -444,7 +454,7 @@ identifier:
| TYPENAME | TYPENAME
ifobjc ifobjc
| OBJECTNAME | OBJECTNAME
| CLASSNAME | CLASSNAME
end ifobjc end ifobjc
; ;
...@@ -1384,6 +1394,7 @@ typespec_attr: ...@@ -1384,6 +1394,7 @@ typespec_attr:
typespec_reserved_nonattr: typespec_reserved_nonattr:
TYPESPEC TYPESPEC
{ OBJC_NEED_RAW_IDENTIFIER (1); }
| structsp_nonattr | structsp_nonattr
; ;
...@@ -1694,6 +1705,9 @@ parm_declarator_starttypename: ...@@ -1694,6 +1705,9 @@ parm_declarator_starttypename:
| parm_declarator_starttypename array_declarator %prec '.' | parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); } { $$ = set_array_declarator_type ($2, $1, 0); }
| TYPENAME | TYPENAME
ifobjc
| OBJECTNAME
end ifobjc
; ;
parm_declarator_nostarttypename: parm_declarator_nostarttypename:
...@@ -2836,6 +2850,13 @@ protocoldef: ...@@ -2836,6 +2850,13 @@ protocoldef:
finish_protocol(objc_interface_context); finish_protocol(objc_interface_context);
objc_interface_context = NULL_TREE; objc_interface_context = NULL_TREE;
} }
/* The @protocol forward-declaration production introduces a
reduce/reduce conflict on ';', which should be resolved in
favor of the production 'identifier_list -> identifier'. */
| PROTOCOL identifier_list ';'
{
objc_declare_protocols ($2);
}
; ;
protocolrefs: protocolrefs:
...@@ -3119,8 +3140,9 @@ keywordselector: ...@@ -3119,8 +3140,9 @@ keywordselector:
selector: selector:
IDENTIFIER IDENTIFIER
| TYPENAME | TYPENAME
| OBJECTNAME | CLASSNAME
| OBJECTNAME
| reservedwords | reservedwords
; ;
...@@ -3615,12 +3637,26 @@ static int ...@@ -3615,12 +3637,26 @@ static int
yylexname () yylexname ()
{ {
tree decl; tree decl;
ifobjc
int objc_force_identifier = objc_need_raw_identifier;
OBJC_NEED_RAW_IDENTIFIER (0);
end ifobjc
if (C_IS_RESERVED_WORD (yylval.ttype)) if (C_IS_RESERVED_WORD (yylval.ttype))
{ {
enum rid rid_code = C_RID_CODE (yylval.ttype); enum rid rid_code = C_RID_CODE (yylval.ttype);
ifobjc ifobjc
/* Turn non-typedefed refs to "id" into plain identifiers; this
allows constructs like "void foo(id id);" to work. */
if (rid_code == RID_ID)
{
decl = lookup_name (yylval.ttype);
if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
return IDENTIFIER;
}
if (!OBJC_IS_AT_KEYWORD (rid_code) if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
end ifobjc end ifobjc
...@@ -3653,8 +3689,11 @@ ifobjc ...@@ -3653,8 +3689,11 @@ ifobjc
else else
{ {
tree objc_interface_decl = is_class_name (yylval.ttype); tree objc_interface_decl = is_class_name (yylval.ttype);
/* ObjC class names are in the same namespace as variables and
if (objc_interface_decl) typedefs, and hence are shadowed by local declarations. */
if (objc_interface_decl
&& (global_bindings_p ()
|| (!objc_force_identifier && !decl)))
{ {
yylval.ttype = objc_interface_decl; yylval.ttype = objc_interface_decl;
return CLASSNAME; return CLASSNAME;
...@@ -3692,10 +3731,7 @@ _yylex () ...@@ -3692,10 +3731,7 @@ _yylex ()
case CPP_AND_AND: return ANDAND; case CPP_AND_AND: return ANDAND;
case CPP_OR_OR: return OROR; case CPP_OR_OR: return OROR;
case CPP_QUERY: return '?'; case CPP_QUERY: return '?';
case CPP_COLON: return ':';
case CPP_COMMA: return ',';
case CPP_OPEN_PAREN: return '('; case CPP_OPEN_PAREN: return '(';
case CPP_CLOSE_PAREN: return ')';
case CPP_EQ_EQ: yylval.code = EQ_EXPR; return EQCOMPARE; case CPP_EQ_EQ: yylval.code = EQ_EXPR; return EQCOMPARE;
case CPP_NOT_EQ: yylval.code = NE_EXPR; return EQCOMPARE; case CPP_NOT_EQ: yylval.code = NE_EXPR; return EQCOMPARE;
case CPP_GREATER_EQ:yylval.code = GE_EXPR; return ARITHCOMPARE; case CPP_GREATER_EQ:yylval.code = GE_EXPR; return ARITHCOMPARE;
...@@ -3716,7 +3752,6 @@ _yylex () ...@@ -3716,7 +3752,6 @@ _yylex ()
case CPP_CLOSE_SQUARE: return ']'; case CPP_CLOSE_SQUARE: return ']';
case CPP_OPEN_BRACE: return '{'; case CPP_OPEN_BRACE: return '{';
case CPP_CLOSE_BRACE: return '}'; case CPP_CLOSE_BRACE: return '}';
case CPP_SEMICOLON: return ';';
case CPP_ELLIPSIS: return ELLIPSIS; case CPP_ELLIPSIS: return ELLIPSIS;
case CPP_PLUS_PLUS: return PLUSPLUS; case CPP_PLUS_PLUS: return PLUSPLUS;
...@@ -3724,6 +3759,13 @@ _yylex () ...@@ -3724,6 +3759,13 @@ _yylex ()
case CPP_DEREF: return POINTSAT; case CPP_DEREF: return POINTSAT;
case CPP_DOT: return '.'; case CPP_DOT: return '.';
/* The following tokens may affect the interpretation of any
identifiers following, if doing Objective-C. */
case CPP_COLON: OBJC_NEED_RAW_IDENTIFIER (0); return ':';
case CPP_COMMA: OBJC_NEED_RAW_IDENTIFIER (0); return ',';
case CPP_CLOSE_PAREN: OBJC_NEED_RAW_IDENTIFIER (0); return ')';
case CPP_SEMICOLON: OBJC_NEED_RAW_IDENTIFIER (0); return ';';
case CPP_EOF: case CPP_EOF:
if (cpp_pop_buffer (parse_in) == 0) if (cpp_pop_buffer (parse_in) == 0)
return 0; return 0;
...@@ -3741,8 +3783,8 @@ _yylex () ...@@ -3741,8 +3783,8 @@ _yylex ()
case CPP_WSTRING: case CPP_WSTRING:
return STRING; return STRING;
/* This token is Objective-C specific. It gives the next /* This token is Objective-C specific. It gives the next token
token special significance. */ special significance. */
case CPP_ATSIGN: case CPP_ATSIGN:
ifobjc ifobjc
{ {
......
...@@ -253,6 +253,7 @@ static tree build_selector_reference_decl PARAMS ((void)); ...@@ -253,6 +253,7 @@ static tree build_selector_reference_decl PARAMS ((void));
static tree add_protocol PARAMS ((tree)); static tree add_protocol PARAMS ((tree));
static tree lookup_protocol PARAMS ((tree)); static tree lookup_protocol PARAMS ((tree));
static void check_protocol_recursively PARAMS ((tree, tree));
static tree lookup_and_install_protocols PARAMS ((tree)); static tree lookup_and_install_protocols PARAMS ((tree));
/* Type encoding. */ /* Type encoding. */
...@@ -336,6 +337,8 @@ static tree check_duplicates PARAMS ((hash)); ...@@ -336,6 +337,8 @@ static tree check_duplicates PARAMS ((hash));
static tree receiver_is_class_object PARAMS ((tree)); static tree receiver_is_class_object PARAMS ((tree));
static int check_methods PARAMS ((tree, tree, int)); static int check_methods PARAMS ((tree, tree, int));
static int conforms_to_protocol PARAMS ((tree, tree)); static int conforms_to_protocol PARAMS ((tree, tree));
static void check_protocol PARAMS ((tree, const char *,
const char *));
static void check_protocols PARAMS ((tree, const char *, static void check_protocols PARAMS ((tree, const char *,
const char *)); const char *));
static tree encode_method_def PARAMS ((tree)); static tree encode_method_def PARAMS ((tree));
...@@ -1010,6 +1013,12 @@ objc_comptypes (lhs, rhs, reflexive) ...@@ -1010,6 +1013,12 @@ objc_comptypes (lhs, rhs, reflexive)
tree cat; tree cat;
rproto_list = CLASS_PROTOCOL_LIST (rinter); rproto_list = CLASS_PROTOCOL_LIST (rinter);
/* If the underlying ObjC class does not have
protocols attached to it, perhaps there are
"one-off" protocols attached to the rhs?
E.g., 'id<MyProt> foo;'. */
if (!rproto_list)
rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
rproto = lookup_protocol_in_reflist (rproto_list, p); rproto = lookup_protocol_in_reflist (rproto_list, p);
/* Check for protocols adopted by categories. */ /* Check for protocols adopted by categories. */
...@@ -1202,6 +1211,32 @@ get_object_reference (protocols) ...@@ -1202,6 +1211,32 @@ get_object_reference (protocols)
return type; return type;
} }
/* Check for circular dependencies in protocols. The arguments are
PROTO, the protocol to check, and LIST, a list of protocol it
conforms to. */
static void
check_protocol_recursively (proto, list)
tree proto;
tree list;
{
tree p;
for (p = list; p; p = TREE_CHAIN (p))
{
tree pp = TREE_VALUE (p);
if (TREE_CODE (pp) == IDENTIFIER_NODE)
pp = lookup_protocol (pp);
if (pp == proto)
fatal_error ("protocol `%s' has circular dependency",
IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
if (pp)
check_protocol_recursively (proto, PROTOCOL_LIST (pp));
}
}
static tree static tree
lookup_and_install_protocols (protocols) lookup_and_install_protocols (protocols)
tree protocols; tree protocols;
...@@ -4871,18 +4906,27 @@ check_duplicates (hsh) ...@@ -4871,18 +4906,27 @@ check_duplicates (hsh)
return meth; return meth;
} }
/* If RECEIVER is a class reference, return the identifier node for the /* If RECEIVER is a class reference, return the identifier node for
referenced class. RECEIVER is created by get_class_reference, so we the referenced class. RECEIVER is created by get_class_reference,
check the exact form created depending on which runtimes are used. */ so we check the exact form created depending on which runtimes are
used. */
static tree static tree
receiver_is_class_object (receiver) receiver_is_class_object (receiver)
tree receiver; tree receiver;
{ {
tree chain, exp, arg; tree chain, exp, arg;
if (flag_next_runtime) if (flag_next_runtime)
{ {
/* The receiver is a variable created by build_class_reference_decl. */ /* The receiver is 'self' in the context of a class method. */
if (objc_method_context
&& receiver == self_decl
&& TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
return CLASS_NAME (objc_implementation_context);
/* The receiver is a variable created by
build_class_reference_decl. */
if (TREE_CODE (receiver) == VAR_DECL if (TREE_CODE (receiver) == VAR_DECL
&& TREE_TYPE (receiver) == objc_class_type) && TREE_TYPE (receiver) == objc_class_type)
/* Look up the identifier. */ /* Look up the identifier. */
...@@ -4899,7 +4943,7 @@ receiver_is_class_object (receiver) ...@@ -4899,7 +4943,7 @@ receiver_is_class_object (receiver)
&& (exp = TREE_OPERAND (exp, 0)) && (exp = TREE_OPERAND (exp, 0))
&& TREE_CODE (exp) == FUNCTION_DECL && TREE_CODE (exp) == FUNCTION_DECL
&& exp == objc_get_class_decl && exp == objc_get_class_decl
/* we have a call to objc_getClass! */ /* We have a call to objc_getClass! */
&& (arg = TREE_OPERAND (receiver, 1)) && (arg = TREE_OPERAND (receiver, 1))
&& TREE_CODE (arg) == TREE_LIST && TREE_CODE (arg) == TREE_LIST
&& (arg = TREE_VALUE (arg))) && (arg = TREE_VALUE (arg)))
...@@ -5143,7 +5187,8 @@ build_message_expr (mess) ...@@ -5143,7 +5187,8 @@ build_message_expr (mess)
method_prototype = lookup_class_method_static (iface, sel_name); method_prototype = lookup_class_method_static (iface, sel_name);
} }
if (!method_prototype) if (!method_prototype
|| TREE_CODE (method_prototype) != CLASS_METHOD_DECL)
{ {
warning ("cannot find class (factory) method."); warning ("cannot find class (factory) method.");
warning ("return type for `%s' defaults to id", warning ("return type for `%s' defaults to id",
...@@ -5960,16 +6005,17 @@ check_methods (chain, list, mtype) ...@@ -5960,16 +6005,17 @@ check_methods (chain, list, mtype)
return first; return first;
} }
/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
static int static int
conforms_to_protocol (class, protocol) conforms_to_protocol (class, protocol)
tree class; tree class;
tree protocol; tree protocol;
{ {
while (protocol) if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
{ {
tree p = CLASS_PROTOCOL_LIST (class); tree p = CLASS_PROTOCOL_LIST (class);
while (p && TREE_VALUE (p) != protocol)
while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
p = TREE_CHAIN (p); p = TREE_CHAIN (p);
if (!p) if (!p)
...@@ -5981,8 +6027,6 @@ conforms_to_protocol (class, protocol) ...@@ -5981,8 +6027,6 @@ conforms_to_protocol (class, protocol)
if (!tmp) if (!tmp)
return 0; return 0;
} }
protocol = TREE_CHAIN (protocol);
} }
return 1; return 1;
...@@ -6054,57 +6098,81 @@ check_methods_accessible (chain, context, mtype) ...@@ -6054,57 +6098,81 @@ check_methods_accessible (chain, context, mtype)
return first; return first;
} }
/* Check whether the current interface (accessible via
'implementation_context') actually implements protocol P, along
with any protocols that P inherits. */
static void static void
check_protocols (proto_list, type, name) check_protocol (p, type, name)
tree proto_list; tree p;
const char *type; const char *type;
const char *name; const char *name;
{ {
for ( ; proto_list; proto_list = TREE_CHAIN (proto_list)) if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
{ {
tree p = TREE_VALUE (proto_list); int f1, f2;
if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) /* Ensure that all protocols have bodies! */
if (flag_warn_protocol)
{ {
int f1, f2; f1 = check_methods (PROTOCOL_CLS_METHODS (p),
CLASS_CLS_METHODS (implementation_context),
/* Ensure that all protocols have bodies. */ '+');
if (flag_warn_protocol) { f2 = check_methods (PROTOCOL_NST_METHODS (p),
f1 = check_methods (PROTOCOL_CLS_METHODS (p), CLASS_NST_METHODS (implementation_context),
CLASS_CLS_METHODS (implementation_context), '-');
'+');
f2 = check_methods (PROTOCOL_NST_METHODS (p),
CLASS_NST_METHODS (implementation_context),
'-');
} else {
f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
implementation_context,
'+');
f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
implementation_context,
'-');
}
if (!f1 || !f2)
warning ("%s `%s' does not fully implement the `%s' protocol",
type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
} }
else else
{ {
; /* An identifier if we could not find a protocol. */ f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
} implementation_context,
'+');
f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
implementation_context,
'-');
}
/* Check protocols recursively. */ if (!f1 || !f2)
if (PROTOCOL_LIST (p)) warning ("%s `%s' does not fully implement the `%s' protocol",
type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
}
/* Check protocols recursively. */
if (PROTOCOL_LIST (p))
{
tree subs = PROTOCOL_LIST (p);
tree super_class =
lookup_interface (CLASS_SUPER_NAME (implementation_template));
while (subs)
{ {
tree super_class tree sub = TREE_VALUE (subs);
= lookup_interface (CLASS_SUPER_NAME (implementation_template));
if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p))) /* If the superclass does not conform to the protocols
check_protocols (PROTOCOL_LIST (p), type, name); inherited by P, then we must! */
if (!super_class || !conforms_to_protocol (super_class, sub))
check_protocol (sub, type, name);
subs = TREE_CHAIN (subs);
} }
} }
} }
/* Check whether the current interface (accessible via
'implementation_context') actually implements the protocols listed
in PROTO_LIST. */
static void
check_protocols (proto_list, type, name)
tree proto_list;
const char *type;
const char *name;
{
for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
{
tree p = TREE_VALUE (proto_list);
check_protocol (p, type, name);
}
}
/* Make sure that the class CLASS_NAME is defined /* Make sure that the class CLASS_NAME is defined
CODE says which kind of thing CLASS_NAME ought to be. CODE says which kind of thing CLASS_NAME ought to be.
...@@ -6430,6 +6498,33 @@ lookup_protocol (ident) ...@@ -6430,6 +6498,33 @@ lookup_protocol (ident)
return NULL_TREE; return NULL_TREE;
} }
/* This function forward declares the protocols named by NAMES. If
they are already declared or defined, the function has no effect. */
void
objc_declare_protocols (names)
tree names;
{
tree list;
for (list = names; list; list = TREE_CHAIN (list))
{
tree name = TREE_VALUE (list);
if (lookup_protocol (name) == NULL_TREE)
{
tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
TYPE_BINFO (protocol) = make_tree_vec (2);
PROTOCOL_NAME (protocol) = name;
PROTOCOL_LIST (protocol) = NULL_TREE;
add_protocol (protocol);
PROTOCOL_DEFINED (protocol) = 0;
PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
}
}
}
tree tree
start_protocol (code, name, list) start_protocol (code, name, list)
enum tree_code code; enum tree_code code;
...@@ -6438,26 +6533,38 @@ start_protocol (code, name, list) ...@@ -6438,26 +6533,38 @@ start_protocol (code, name, list)
{ {
tree protocol; tree protocol;
/* This is as good a place as any. Need to invoke push_tag_toplevel. */ /* This is as good a place as any. Need to invoke
push_tag_toplevel. */
if (!objc_protocol_template) if (!objc_protocol_template)
objc_protocol_template = build_protocol_template (); objc_protocol_template = build_protocol_template ();
protocol = make_node (code); protocol = lookup_protocol (name);
TYPE_BINFO (protocol) = make_tree_vec (2);
PROTOCOL_NAME (protocol) = name; if (!protocol)
PROTOCOL_LIST (protocol) = list; {
protocol = make_node (code);
TYPE_BINFO (protocol) = make_tree_vec (2);
lookup_and_install_protocols (list); PROTOCOL_NAME (protocol) = name;
PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
add_protocol (protocol);
PROTOCOL_DEFINED (protocol) = 1;
PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
if (lookup_protocol (name)) check_protocol_recursively (protocol, list);
warning ("duplicate declaration for protocol `%s'", }
IDENTIFIER_POINTER (name)); else if (! PROTOCOL_DEFINED (protocol))
else {
add_protocol (protocol); PROTOCOL_DEFINED (protocol) = 1;
PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
check_protocol_recursively (protocol, list);
}
else
{
warning ("duplicate declaration for protocol `%s'",
IDENTIFIER_POINTER (name));
}
return protocol; return protocol;
} }
...@@ -6595,6 +6702,11 @@ encode_aggregate_within (type, curtype, format, left, right) ...@@ -6595,6 +6702,11 @@ encode_aggregate_within (type, curtype, format, left, right)
int left; int left;
int right; int right;
{ {
/* The RECORD_TYPE may in fact be a typedef! For purposes
of encoding, we need the real underlying enchilada. */
if (TYPE_MAIN_VARIANT (type))
type = TYPE_MAIN_VARIANT (type);
if (obstack_object_size (&util_obstack) > 0 if (obstack_object_size (&util_obstack) > 0
&& *(obstack_next_free (&util_obstack) - 1) == '^') && *(obstack_next_free (&util_obstack) - 1) == '^')
{ {
......
/* Declarations for objc-act.c. /* Declarations for objc-act.c.
Copyright (C) 1990, 2000 Free Software Foundation, Inc. Copyright (C) 1990, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -59,6 +59,7 @@ extern tree objc_ellipsis_node; ...@@ -59,6 +59,7 @@ extern tree objc_ellipsis_node;
void objc_declare_alias PARAMS ((tree, tree)); void objc_declare_alias PARAMS ((tree, tree));
void objc_declare_class PARAMS ((tree)); void objc_declare_class PARAMS ((tree));
void objc_declare_protocols PARAMS ((tree));
extern int objc_receiver_context; extern int objc_receiver_context;
...@@ -101,6 +102,7 @@ tree build_encode_expr PARAMS ((tree)); ...@@ -101,6 +102,7 @@ tree build_encode_expr PARAMS ((tree));
#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval) #define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval) #define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) #define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context) #define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context)
/* Define the Objective-C or Objective-C++ language-specific tree codes. */ /* Define the Objective-C or Objective-C++ language-specific tree codes. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment