Commit f8893e47 by Joseph Myers Committed by Joseph Myers

c-tree.h (enum c_declarator_kind, [...]): New.

	* c-tree.h (enum c_declarator_kind, struct c_arg_info, struct
	c_declarator, struct c_type_name, struct c_parm): New.
	(build_array_declarator, set_array_declarator_inner,
	get_parm_info, grokfield, groktypename, grokparm, push_parm_decl,
	start_function, start_decl, build_c_parm, build_attrs_declarator,
	build_function_declarator, make_pointer_declarator, c_cast_expr,
	store_parm_decls_newstyle, c_expr_sizeof_type): Update prototypes.
	(build_id_declarator): New.
	* c-typeck.c (c_cast_expr, c_expr_sizeof_type): Update to new
	structures.
	* c-decl.c (ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES,
	ARG_INFO_OTHERS): Remove.
	(build_id_declarator): New.
	(build_array_declarator, set_array_declarator_inner, groktypename,
	start_decl, grokparm, push_parm_decl, grokparms, get_parm_info,
	grokfield, start_function, store_parm_decls_newstyle,
	store_parm_decls_oldstyle, store_parm_decls,
	build_c_parm, build_attrs_declarator, build_function_declarator,
	make_pointer_declarator, grokdeclarator): Update to new
	structures.
	* c-parse.in (%union): Add arginfotype, dtrtype, typenametype and
	parmtype.
	(declarator, notype_declarator, after_type_declarator,
	parm_declarator, parm_declarator_starttypename,
	parm_declarator_nostarttypename, array_declarator, typename,
	absdcl, absdcl1, absdcl1_ea, absdcl1_noea, direct_absdcl1,
	absdcl_maybe_attribute, parm, firstparm, parms, parmlist,
	parmlist_1, parmlist_2, parmlist_or_identifiers,
	parmlist_or_identifiers_1): Use these types.
	(primary, after_type_declarator, parm_declarator_starttypename,
	notype_declarator, component_decl, component_declarator,
	component_notype_declarator, typename, absdcl,
	absdcl_maybe_attribute, absdcl1_ea, direct_absdcl1, parmlist_1,
	parmlist_2, parmlist_or_identifiers_1): Update to new structures.

objc:
	* objc-act.c (objc_start_function, really_start_method,
	objc_get_parm_info, start_method_def): Update to new arg_info
	structures.

From-SVN: r87217
parent bc4b653b
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk> 2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
* c-tree.h (enum c_declarator_kind, struct c_arg_info, struct
c_declarator, struct c_type_name, struct c_parm): New.
(build_array_declarator, set_array_declarator_inner,
get_parm_info, grokfield, groktypename, grokparm, push_parm_decl,
start_function, start_decl, build_c_parm, build_attrs_declarator,
build_function_declarator, make_pointer_declarator, c_cast_expr,
store_parm_decls_newstyle, c_expr_sizeof_type): Update prototypes.
(build_id_declarator): New.
* c-typeck.c (c_cast_expr, c_expr_sizeof_type): Update to new
structures.
* c-decl.c (ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES,
ARG_INFO_OTHERS): Remove.
(build_id_declarator): New.
(build_array_declarator, set_array_declarator_inner, groktypename,
start_decl, grokparm, push_parm_decl, grokparms, get_parm_info,
grokfield, start_function, store_parm_decls_newstyle,
store_parm_decls_oldstyle, store_parm_decls,
build_c_parm, build_attrs_declarator, build_function_declarator,
make_pointer_declarator, grokdeclarator): Update to new
structures.
* c-parse.in (%union): Add arginfotype, dtrtype, typenametype and
parmtype.
(declarator, notype_declarator, after_type_declarator,
parm_declarator, parm_declarator_starttypename,
parm_declarator_nostarttypename, array_declarator, typename,
absdcl, absdcl1, absdcl1_ea, absdcl1_noea, direct_absdcl1,
absdcl_maybe_attribute, parm, firstparm, parms, parmlist,
parmlist_1, parmlist_2, parmlist_or_identifiers,
parmlist_or_identifiers_1): Use these types.
(primary, after_type_declarator, parm_declarator_starttypename,
notype_declarator, component_decl, component_declarator,
component_notype_declarator, typename, absdcl,
absdcl_maybe_attribute, absdcl1_ea, direct_absdcl1, parmlist_1,
parmlist_2, parmlist_or_identifiers_1): Update to new structures.
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
* c-tree.h (C_DECL_USED, parser_obstack, in_alignof, in_sizeof, * c-tree.h (C_DECL_USED, parser_obstack, in_alignof, in_sizeof,
in_typeof, record_maybe_used_decl, pop_maybe_used, in_typeof, record_maybe_used_decl, pop_maybe_used,
c_expr_sizeof_expr, c_expr_sizeof_type): New. c_expr_sizeof_expr, c_expr_sizeof_type): New.
......
...@@ -91,13 +91,6 @@ static tree enum_next_value; ...@@ -91,13 +91,6 @@ static tree enum_next_value;
static int enum_overflow; static int enum_overflow;
/* These #defines are for clarity in working with the information block
returned by get_parm_info. */
#define ARG_INFO_PARMS(args) TREE_PURPOSE(args)
#define ARG_INFO_TAGS(args) TREE_VALUE(args)
#define ARG_INFO_TYPES(args) TREE_CHAIN(args)
#define ARG_INFO_OTHERS(args) TREE_TYPE(args)
/* The file and line that the prototype came from if this is an /* The file and line that the prototype came from if this is an
old-style definition; used for diagnostics in old-style definition; used for diagnostics in
store_parm_decls_oldstyle. */ store_parm_decls_oldstyle. */
...@@ -107,7 +100,7 @@ static location_t current_function_prototype_locus; ...@@ -107,7 +100,7 @@ static location_t current_function_prototype_locus;
/* The argument information structure for the function currently being /* The argument information structure for the function currently being
defined. */ defined. */
static GTY(()) tree current_function_arg_info; static struct c_arg_info *current_function_arg_info;
/* The obstack on which parser and related data structures, which are /* The obstack on which parser and related data structures, which are
not live beyond their top-level declaration or definition, are not live beyond their top-level declaration or definition, are
...@@ -405,8 +398,9 @@ static GTY(()) tree static_dtors; ...@@ -405,8 +398,9 @@ static GTY(()) tree static_dtors;
/* Forward declarations. */ /* Forward declarations. */
static tree lookup_name_in_scope (tree, struct c_scope *); static tree lookup_name_in_scope (tree, struct c_scope *);
static tree c_make_fname_decl (tree, int); static tree c_make_fname_decl (tree, int);
static tree grokdeclarator (tree, tree, enum decl_context, bool, tree *); static tree grokdeclarator (const struct c_declarator *, tree,
static tree grokparms (tree, bool); enum decl_context, bool, tree *);
static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree); static void layout_array_type (tree);
/* States indicating how grokdeclarator() should handle declspecs marked /* States indicating how grokdeclarator() should handle declspecs marked
...@@ -2752,20 +2746,21 @@ shadow_tag_warned (tree declspecs, int warned) ...@@ -2752,20 +2746,21 @@ shadow_tag_warned (tree declspecs, int warned)
true if "static" is inside the [], false otherwise. VLA_UNSPEC_P true if "static" is inside the [], false otherwise. VLA_UNSPEC_P
is true if the array is [*], a VLA of unspecified length which is is true if the array is [*], a VLA of unspecified length which is
nevertheless a complete type (not currently implemented by GCC), nevertheless a complete type (not currently implemented by GCC),
false otherwise. The declarator is constructed as an ARRAY_REF false otherwise. The field for the contained declarator is left to be
(to be decoded by grokdeclarator), whose operand 0 is what's on the filled in by set_array_declarator_inner. */
left of the [] (filled by in set_array_declarator_inner) and operand 1
is the expression inside; whose TREE_TYPE is the type qualifiers and
which has TREE_STATIC set if "static" is used. */
tree struct c_declarator *
build_array_declarator (tree expr, tree quals, bool static_p, build_array_declarator (tree expr, tree quals, bool static_p,
bool vla_unspec_p) bool vla_unspec_p)
{ {
tree decl; struct c_declarator *declarator = XOBNEW (&parser_obstack,
decl = build_nt (ARRAY_REF, NULL_TREE, expr, NULL_TREE, NULL_TREE); struct c_declarator);
TREE_TYPE (decl) = quals; declarator->kind = cdk_array;
TREE_STATIC (decl) = (static_p ? 1 : 0); declarator->declarator = 0;
declarator->u.array.dimen = expr;
declarator->u.array.quals = quals;
declarator->u.array.static_p = static_p;
declarator->u.array.vla_unspec_p = vla_unspec_p;
if (pedantic && !flag_isoc99) if (pedantic && !flag_isoc99)
{ {
if (static_p || quals != NULL_TREE) if (static_p || quals != NULL_TREE)
...@@ -2775,21 +2770,23 @@ build_array_declarator (tree expr, tree quals, bool static_p, ...@@ -2775,21 +2770,23 @@ build_array_declarator (tree expr, tree quals, bool static_p,
} }
if (vla_unspec_p) if (vla_unspec_p)
warning ("GCC does not yet properly implement `[*]' array declarators"); warning ("GCC does not yet properly implement `[*]' array declarators");
return decl; return declarator;
} }
/* Set the type of an array declarator. DECL is the declarator, as /* Set the contained declarator of an array declarator. DECL is the
constructed by build_array_declarator; TYPE is what appears on the left declarator, as constructed by build_array_declarator; INNER is what
of the [] and goes in operand 0. ABSTRACT_P is true if it is an appears on the left of the []. ABSTRACT_P is true if it is an
abstract declarator, false otherwise; this is used to reject static and abstract declarator, false otherwise; this is used to reject static
type qualifiers in abstract declarators, where they are not in the and type qualifiers in abstract declarators, where they are not in
C99 grammar. */ the C99 grammar (subject to possible change in DR#289). */
tree struct c_declarator *
set_array_declarator_inner (tree decl, tree type, bool abstract_p) set_array_declarator_inner (struct c_declarator *decl,
struct c_declarator *inner, bool abstract_p)
{ {
TREE_OPERAND (decl, 0) = type; decl->declarator = inner;
if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl))) if (abstract_p && (decl->u.array.quals != NULL_TREE
|| decl->u.array.static_p))
error ("static or type qualifiers in abstract declarator"); error ("static or type qualifiers in abstract declarator");
return decl; return decl;
} }
...@@ -2876,22 +2873,20 @@ split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes) ...@@ -2876,22 +2873,20 @@ split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ /* Decode a "typename", such as "int **", returning a ..._TYPE node. */
tree tree
groktypename (tree type_name) groktypename (struct c_type_name *type_name)
{ {
tree type;
tree specs, attrs; tree specs, attrs;
if (TREE_CODE (type_name) != TREE_LIST) split_specs_attrs (type_name->specs, &specs, &attrs);
return type_name;
split_specs_attrs (TREE_PURPOSE (type_name), &specs, &attrs); type = grokdeclarator (type_name->declarator, specs, TYPENAME, false,
type_name = grokdeclarator (TREE_VALUE (type_name), specs, TYPENAME, false,
NULL); NULL);
/* Apply attributes. */ /* Apply attributes. */
decl_attributes (&type_name, attrs, 0); decl_attributes (&type, attrs, 0);
return type_name; return type;
} }
/* Decode a declarator in an ordinary declaration or data definition. /* Decode a declarator in an ordinary declaration or data definition.
...@@ -2910,7 +2905,8 @@ groktypename (tree type_name) ...@@ -2910,7 +2905,8 @@ groktypename (tree type_name)
grokfield and not through here. */ grokfield and not through here. */
tree tree
start_decl (tree declarator, tree declspecs, bool initialized, tree attributes) start_decl (struct c_declarator *declarator, tree declspecs,
bool initialized, tree attributes)
{ {
tree decl; tree decl;
tree tem; tree tem;
...@@ -3023,13 +3019,13 @@ start_decl (tree declarator, tree declspecs, bool initialized, tree attributes) ...@@ -3023,13 +3019,13 @@ start_decl (tree declarator, tree declspecs, bool initialized, tree attributes)
if (TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (decl))) && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
{ {
tree ce = declarator; struct c_declarator *ce = declarator;
if (TREE_CODE (ce) == INDIRECT_REF) if (ce->kind == cdk_pointer)
ce = TREE_OPERAND (declarator, 0); ce = declarator->declarator;
if (TREE_CODE (ce) == CALL_EXPR) if (ce->kind == cdk_function)
{ {
tree args = TREE_PURPOSE (TREE_OPERAND (ce, 1)); tree args = ce->u.arg_info->parms;
for (; args; args = TREE_CHAIN (args)) for (; args; args = TREE_CHAIN (args))
{ {
tree type = TREE_TYPE (args); tree type = TREE_TYPE (args);
...@@ -3348,13 +3344,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree) ...@@ -3348,13 +3344,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
/* Given a parsed parameter declaration, decode it into a PARM_DECL. */ /* Given a parsed parameter declaration, decode it into a PARM_DECL. */
tree tree
grokparm (tree parm) grokparm (const struct c_parm *parm)
{ {
tree decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)), tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false,
TREE_PURPOSE (TREE_PURPOSE (parm)), NULL);
PARM, false, NULL);
decl_attributes (&decl, TREE_VALUE (parm), 0); decl_attributes (&decl, parm->attrs, 0);
return decl; return decl;
} }
...@@ -3363,14 +3358,12 @@ grokparm (tree parm) ...@@ -3363,14 +3358,12 @@ grokparm (tree parm)
and push that on the current scope. */ and push that on the current scope. */
void void
push_parm_decl (tree parm) push_parm_decl (const struct c_parm *parm)
{ {
tree decl; tree decl;
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)), decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL);
TREE_PURPOSE (TREE_PURPOSE (parm)), decl_attributes (&decl, parm->attrs, 0);
PARM, false, NULL);
decl_attributes (&decl, TREE_VALUE (parm), 0);
decl = pushdecl (decl); decl = pushdecl (decl);
...@@ -3664,7 +3657,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) ...@@ -3664,7 +3657,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
and `extern' are interpreted. */ and `extern' are interpreted. */
static tree static tree
grokdeclarator (tree declarator, tree declspecs, grokdeclarator (const struct c_declarator *declarator, tree declspecs,
enum decl_context decl_context, bool initialized, tree *width) enum decl_context decl_context, bool initialized, tree *width)
{ {
int specbits = 0; int specbits = 0;
...@@ -3683,7 +3676,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3683,7 +3676,7 @@ grokdeclarator (tree declarator, tree declspecs,
const char *name, *orig_name; const char *name, *orig_name;
tree typedef_type = 0; tree typedef_type = 0;
int funcdef_flag = 0; int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK; bool funcdef_syntax = false;
int size_varies = 0; int size_varies = 0;
tree decl_attr = NULL_TREE; tree decl_attr = NULL_TREE;
tree array_ptr_quals = NULL_TREE; tree array_ptr_quals = NULL_TREE;
...@@ -3691,7 +3684,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3691,7 +3684,7 @@ grokdeclarator (tree declarator, tree declspecs,
tree returned_attrs = NULL_TREE; tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL; bool bitfield = width != NULL;
tree element_type; tree element_type;
tree arg_info = NULL_TREE; struct c_arg_info *arg_info = 0;
if (decl_context == FUNCDEF) if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL; funcdef_flag = 1, decl_context = NORMAL;
...@@ -3699,25 +3692,26 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3699,25 +3692,26 @@ grokdeclarator (tree declarator, tree declspecs,
/* Look inside a declarator for the name being declared /* Look inside a declarator for the name being declared
and get it as a string, for an error message. */ and get it as a string, for an error message. */
{ {
tree decl = declarator; const struct c_declarator *decl = declarator;
name = 0; name = 0;
while (decl) while (decl)
switch (TREE_CODE (decl)) switch (decl->kind)
{ {
case ARRAY_REF: case cdk_function:
case INDIRECT_REF: case cdk_array:
case CALL_EXPR: case cdk_pointer:
innermost_code = TREE_CODE (decl); funcdef_syntax = (decl->kind == cdk_function);
decl = TREE_OPERAND (decl, 0); decl = decl->declarator;
break; break;
case TREE_LIST: case cdk_attrs:
decl = TREE_VALUE (decl); decl = decl->declarator;
break; break;
case IDENTIFIER_NODE: case cdk_id:
name = IDENTIFIER_POINTER (decl); if (decl->u.id)
name = IDENTIFIER_POINTER (decl->u.id);
decl = 0; decl = 0;
break; break;
...@@ -3732,7 +3726,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3732,7 +3726,7 @@ grokdeclarator (tree declarator, tree declspecs,
/* A function definition's declarator must have the form of /* A function definition's declarator must have the form of
a function declarator. */ a function declarator. */
if (funcdef_flag && innermost_code != CALL_EXPR) if (funcdef_flag && !funcdef_syntax)
return 0; return 0;
/* If this looks like a function definition, make it one, /* If this looks like a function definition, make it one,
...@@ -4163,22 +4157,22 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4163,22 +4157,22 @@ grokdeclarator (tree declarator, tree declspecs,
Descend through it, creating more complex types, until we reach Descend through it, creating more complex types, until we reach
the declared identifier (or NULL_TREE, in an absolute declarator). */ the declared identifier (or NULL_TREE, in an absolute declarator). */
while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE) while (declarator && declarator->kind != cdk_id)
{ {
if (type == error_mark_node) if (type == error_mark_node)
{ {
declarator = TREE_OPERAND (declarator, 0); declarator = declarator->declarator;
continue; continue;
} }
/* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), /* Each level of DECLARATOR is either a cdk_array (for ...[..]),
an INDIRECT_REF (for *...), a cdk_pointer (for *...),
a CALL_EXPR (for ...(...)), a cdk_function (for ...(...)),
a TREE_LIST (for nested attributes), a cdk_attrs (for nested attributes),
an identifier (for the name being declared) or a cdk_id (for the name being declared
or a null pointer (for the place in an absolute declarator or the place in an absolute declarator
where the name was omitted). where the name was omitted).
For the last two cases, we have just exited the loop. For the last case, we have just exited the loop.
At this point, TYPE is the type of elements of an array, At this point, TYPE is the type of elements of an array,
or for a function to return, or for a pointer to point to. or for a function to return, or for a pointer to point to.
...@@ -4196,43 +4190,40 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4196,43 +4190,40 @@ grokdeclarator (tree declarator, tree declspecs,
array_parm_static = 0; array_parm_static = 0;
} }
switch (TREE_CODE (declarator)) switch (declarator->kind)
{ {
case TREE_LIST: case cdk_attrs:
{ {
/* We encode a declarator with embedded attributes using a /* A declarator with embedded attributes. */
TREE_LIST. */ tree attrs = declarator->u.attrs;
tree attrs = TREE_PURPOSE (declarator); const struct c_declarator *inner_decl;
tree inner_decl;
int attr_flags = 0; int attr_flags = 0;
declarator = TREE_VALUE (declarator); declarator = declarator->declarator;
inner_decl = declarator; inner_decl = declarator;
while (inner_decl != NULL_TREE while (inner_decl->kind == cdk_attrs)
&& TREE_CODE (inner_decl) == TREE_LIST) inner_decl = inner_decl->declarator;
inner_decl = TREE_VALUE (inner_decl); if (inner_decl->kind == cdk_id)
if (inner_decl == NULL_TREE
|| TREE_CODE (inner_decl) == IDENTIFIER_NODE)
attr_flags |= (int) ATTR_FLAG_DECL_NEXT; attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
else if (TREE_CODE (inner_decl) == CALL_EXPR) else if (inner_decl->kind == cdk_function)
attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT; attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
else if (TREE_CODE (inner_decl) == ARRAY_REF) else if (inner_decl->kind == cdk_array)
attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT; attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
returned_attrs = decl_attributes (&type, returned_attrs = decl_attributes (&type,
chainon (returned_attrs, attrs), chainon (returned_attrs, attrs),
attr_flags); attr_flags);
break; break;
} }
case ARRAY_REF: case cdk_array:
{ {
tree itype = NULL_TREE; tree itype = NULL_TREE;
tree size = TREE_OPERAND (declarator, 1); tree size = declarator->u.array.dimen;
/* The index is a signed object `sizetype' bits wide. */ /* The index is a signed object `sizetype' bits wide. */
tree index_type = c_common_signed_type (sizetype); tree index_type = c_common_signed_type (sizetype);
array_ptr_quals = TREE_TYPE (declarator); array_ptr_quals = declarator->u.array.quals;
array_parm_static = TREE_STATIC (declarator); array_parm_static = declarator->u.array.static_p;
declarator = TREE_OPERAND (declarator, 0); declarator = declarator->declarator;
/* Check for some types that there cannot be arrays of. */ /* Check for some types that there cannot be arrays of. */
...@@ -4375,7 +4366,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4375,7 +4366,7 @@ grokdeclarator (tree declarator, tree declspecs,
TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE (type) = bitsize_zero_node;
TYPE_SIZE_UNIT (type) = size_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node;
} }
else if (declarator && TREE_CODE (declarator) == INDIRECT_REF) else if (declarator->kind == cdk_pointer)
/* We can never complete an array type which is the /* We can never complete an array type which is the
target of a pointer, so go ahead and lay it out. */ target of a pointer, so go ahead and lay it out. */
layout_type (type); layout_type (type);
...@@ -4389,7 +4380,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4389,7 +4380,7 @@ grokdeclarator (tree declarator, tree declspecs,
} }
break; break;
} }
case CALL_EXPR: case cdk_function:
{ {
/* Say it's a definition only for the declarator closest /* Say it's a definition only for the declarator closest
to the identifier, apart possibly from some to the identifier, apart possibly from some
...@@ -4398,10 +4389,10 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4398,10 +4389,10 @@ grokdeclarator (tree declarator, tree declspecs,
tree arg_types; tree arg_types;
if (funcdef_flag) if (funcdef_flag)
{ {
tree t = TREE_OPERAND (declarator, 0); const struct c_declarator *t = declarator->declarator;
while (TREE_CODE (t) == TREE_LIST) while (t->kind == cdk_attrs)
t = TREE_VALUE (t); t = t->declarator;
really_funcdef = (TREE_CODE (t) == IDENTIFIER_NODE); really_funcdef = (t->kind == cdk_id);
} }
/* Declaring a function type. Make sure we have a valid /* Declaring a function type. Make sure we have a valid
...@@ -4425,7 +4416,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4425,7 +4416,7 @@ grokdeclarator (tree declarator, tree declspecs,
/* Construct the function type and go to the next /* Construct the function type and go to the next
inner layer of declarator. */ inner layer of declarator. */
arg_info = TREE_OPERAND (declarator, 1); arg_info = declarator->u.arg_info;
arg_types = grokparms (arg_info, really_funcdef); arg_types = grokparms (arg_info, really_funcdef);
/* Type qualifiers before the return type of the function /* Type qualifiers before the return type of the function
...@@ -4448,7 +4439,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4448,7 +4439,7 @@ grokdeclarator (tree declarator, tree declspecs,
type_quals = TYPE_UNQUALIFIED; type_quals = TYPE_UNQUALIFIED;
type = build_function_type (type, arg_types); type = build_function_type (type, arg_types);
declarator = TREE_OPERAND (declarator, 0); declarator = declarator->declarator;
/* Set the TYPE_CONTEXTs for each tagged type which is local to /* Set the TYPE_CONTEXTs for each tagged type which is local to
the formal parameter list of this FUNCTION_TYPE to point to the formal parameter list of this FUNCTION_TYPE to point to
...@@ -4456,14 +4447,14 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4456,14 +4447,14 @@ grokdeclarator (tree declarator, tree declspecs,
{ {
tree link; tree link;
for (link = ARG_INFO_TAGS (arg_info); for (link = arg_info->tags;
link; link;
link = TREE_CHAIN (link)) link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = type; TYPE_CONTEXT (TREE_VALUE (link)) = type;
} }
break; break;
} }
case INDIRECT_REF: case cdk_pointer:
{ {
/* Merge any constancy or volatility into the target type /* Merge any constancy or volatility into the target type
for the pointer. */ for the pointer. */
...@@ -4480,7 +4471,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4480,7 +4471,7 @@ grokdeclarator (tree declarator, tree declspecs,
/* Process a list of type modifier keywords (such as const /* Process a list of type modifier keywords (such as const
or volatile) that were given inside the `*'. */ or volatile) that were given inside the `*'. */
if (TREE_TYPE (declarator)) if (declarator->u.pointer_quals)
{ {
tree typemodlist; tree typemodlist;
int erred = 0; int erred = 0;
...@@ -4488,7 +4479,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4488,7 +4479,7 @@ grokdeclarator (tree declarator, tree declspecs,
constp = 0; constp = 0;
volatilep = 0; volatilep = 0;
restrictp = 0; restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist; for (typemodlist = declarator->u.pointer_quals; typemodlist;
typemodlist = TREE_CHAIN (typemodlist)) typemodlist = TREE_CHAIN (typemodlist))
{ {
tree qualifier = TREE_VALUE (typemodlist); tree qualifier = TREE_VALUE (typemodlist);
...@@ -4525,7 +4516,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4525,7 +4516,7 @@ grokdeclarator (tree declarator, tree declspecs,
| (volatilep ? TYPE_QUAL_VOLATILE : 0)); | (volatilep ? TYPE_QUAL_VOLATILE : 0));
} }
declarator = TREE_OPERAND (declarator, 0); declarator = declarator->declarator;
break; break;
} }
default: default:
...@@ -4559,7 +4550,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4559,7 +4550,7 @@ grokdeclarator (tree declarator, tree declspecs,
pedwarn ("ISO C forbids qualified function types"); pedwarn ("ISO C forbids qualified function types");
if (type_quals) if (type_quals)
type = c_build_qualified_type (type, type_quals); type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator, type); decl = build_decl (TYPE_DECL, declarator->u.id, type);
if ((specbits & (1 << (int) RID_SIGNED)) if ((specbits & (1 << (int) RID_SIGNED))
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
...@@ -4691,7 +4682,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4691,7 +4682,7 @@ grokdeclarator (tree declarator, tree declspecs,
type_as_written = type; type_as_written = type;
decl = build_decl (PARM_DECL, declarator, type); decl = build_decl (PARM_DECL, declarator->u.id, type);
if (size_varies) if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1; C_DECL_VARIABLE_SIZE (decl) = 1;
...@@ -4728,7 +4719,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4728,7 +4719,7 @@ grokdeclarator (tree declarator, tree declspecs,
type = build_array_type (c_build_qualified_type (TREE_TYPE (type), type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals), type_quals),
TYPE_DOMAIN (type)); TYPE_DOMAIN (type));
decl = build_decl (FIELD_DECL, declarator, type); decl = build_decl (FIELD_DECL, declarator->u.id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield; DECL_NONADDRESSABLE_P (decl) = bitfield;
if (size_varies) if (size_varies)
...@@ -4755,7 +4746,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4755,7 +4746,7 @@ grokdeclarator (tree declarator, tree declspecs,
error ("invalid storage class for function `%s'", name); error ("invalid storage class for function `%s'", name);
} }
decl = build_decl (FUNCTION_DECL, declarator, type); decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
decl = build_decl_attribute_variant (decl, decl_attr); decl = build_decl_attribute_variant (decl, decl_attr);
DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl); DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
...@@ -4792,7 +4783,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4792,7 +4783,7 @@ grokdeclarator (tree declarator, tree declspecs,
C_FUNCTION_IMPLICIT_INT (decl) = 1; C_FUNCTION_IMPLICIT_INT (decl) = 1;
/* Record presence of `inline', if it is reasonable. */ /* Record presence of `inline', if it is reasonable. */
if (MAIN_NAME_P (declarator)) if (MAIN_NAME_P (declarator->u.id))
{ {
if (inlinep) if (inlinep)
warning ("cannot inline function `main'"); warning ("cannot inline function `main'");
...@@ -4845,8 +4836,8 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4845,8 +4836,8 @@ grokdeclarator (tree declarator, tree declspecs,
the 'extern' declaration is taken to refer to that decl.) */ the 'extern' declaration is taken to refer to that decl.) */
if (extern_ref && current_scope != file_scope) if (extern_ref && current_scope != file_scope)
{ {
tree global_decl = identifier_global_value (declarator); tree global_decl = identifier_global_value (declarator->u.id);
tree visible_decl = lookup_name (declarator); tree visible_decl = lookup_name (declarator->u.id);
if (global_decl if (global_decl
&& global_decl != visible_decl && global_decl != visible_decl
...@@ -4856,7 +4847,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4856,7 +4847,7 @@ grokdeclarator (tree declarator, tree declspecs,
"'extern'"); "'extern'");
} }
decl = build_decl (VAR_DECL, declarator, type); decl = build_decl (VAR_DECL, declarator->u.id, type);
if (size_varies) if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1; C_DECL_VARIABLE_SIZE (decl) = 1;
...@@ -4948,9 +4939,9 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4948,9 +4939,9 @@ grokdeclarator (tree declarator, tree declspecs,
when FUNCDEF_FLAG is false. */ when FUNCDEF_FLAG is false. */
static tree static tree
grokparms (tree arg_info, bool funcdef_flag) grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
{ {
tree arg_types = ARG_INFO_TYPES (arg_info); tree arg_types = arg_info->types;
if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
&& !in_system_header) && !in_system_header)
...@@ -4964,8 +4955,8 @@ grokparms (tree arg_info, bool funcdef_flag) ...@@ -4964,8 +4955,8 @@ grokparms (tree arg_info, bool funcdef_flag)
if (! funcdef_flag) if (! funcdef_flag)
pedwarn ("parameter names (without types) in function declaration"); pedwarn ("parameter names (without types) in function declaration");
ARG_INFO_PARMS (arg_info) = ARG_INFO_TYPES (arg_info); arg_info->parms = arg_info->types;
ARG_INFO_TYPES (arg_info) = 0; arg_info->types = 0;
return 0; return 0;
} }
else else
...@@ -4978,7 +4969,7 @@ grokparms (tree arg_info, bool funcdef_flag) ...@@ -4978,7 +4969,7 @@ grokparms (tree arg_info, bool funcdef_flag)
the scope of the declaration, so the types can never be the scope of the declaration, so the types can never be
completed, and no call can be compiled successfully. */ completed, and no call can be compiled successfully. */
for (parm = ARG_INFO_PARMS (arg_info), typelt = arg_types, parmno = 1; for (parm = arg_info->parms, typelt = arg_types, parmno = 1;
parm; parm;
parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++) parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
{ {
...@@ -5015,26 +5006,20 @@ grokparms (tree arg_info, bool funcdef_flag) ...@@ -5015,26 +5006,20 @@ grokparms (tree arg_info, bool funcdef_flag)
} }
} }
/* Take apart the current scope and return a tree_list node with info /* Take apart the current scope and return a c_arg_info structure with
on a parameter list just parsed. This tree_list node should be info on a parameter list just parsed.
examined using the ARG_INFO_* macros, defined above:
ARG_INFO_PARMS: a list of parameter decls.
ARG_INFO_TAGS: a list of structure, union and enum tags defined.
ARG_INFO_TYPES: a list of argument types to go in the FUNCTION_TYPE.
ARG_INFO_OTHERS: a list of non-parameter decls (notably enumeration
constants) defined with the parameters.
This tree_list node is later fed to 'grokparms' and 'store_parm_decls'. This structure is later fed to 'grokparms' and 'store_parm_decls'.
ELLIPSIS being true means the argument list ended in '...' so don't ELLIPSIS being true means the argument list ended in '...' so don't
append a sentinel (void_list_node) to the end of the type-list. */ append a sentinel (void_list_node) to the end of the type-list. */
tree struct c_arg_info *
get_parm_info (bool ellipsis) get_parm_info (bool ellipsis)
{ {
struct c_binding *b = current_scope->bindings; struct c_binding *b = current_scope->bindings;
tree arg_info = make_node (TREE_LIST); struct c_arg_info *arg_info = XOBNEW (&parser_obstack,
struct c_arg_info);
tree parms = 0; tree parms = 0;
tree tags = 0; tree tags = 0;
tree types = 0; tree types = 0;
...@@ -5043,6 +5028,11 @@ get_parm_info (bool ellipsis) ...@@ -5043,6 +5028,11 @@ get_parm_info (bool ellipsis)
static bool explained_incomplete_types = false; static bool explained_incomplete_types = false;
bool gave_void_only_once_err = false; bool gave_void_only_once_err = false;
arg_info->parms = 0;
arg_info->tags = 0;
arg_info->types = 0;
arg_info->others = 0;
/* The bindings in this scope must not get put into a block. /* The bindings in this scope must not get put into a block.
We will take care of deleting the binding nodes. */ We will take care of deleting the binding nodes. */
current_scope->bindings = 0; current_scope->bindings = 0;
...@@ -5070,7 +5060,7 @@ get_parm_info (bool ellipsis) ...@@ -5070,7 +5060,7 @@ get_parm_info (bool ellipsis)
if (ellipsis) if (ellipsis)
error ("'void' must be the only parameter"); error ("'void' must be the only parameter");
ARG_INFO_TYPES (arg_info) = void_list_node; arg_info->types = void_list_node;
return arg_info; return arg_info;
} }
...@@ -5191,10 +5181,10 @@ get_parm_info (bool ellipsis) ...@@ -5191,10 +5181,10 @@ get_parm_info (bool ellipsis)
b = free_binding_and_advance (b); b = free_binding_and_advance (b);
} }
ARG_INFO_PARMS (arg_info) = parms; arg_info->parms = parms;
ARG_INFO_TAGS (arg_info) = tags; arg_info->tags = tags;
ARG_INFO_TYPES (arg_info) = types; arg_info->types = types;
ARG_INFO_OTHERS (arg_info) = others; arg_info->others = others;
return arg_info; return arg_info;
} }
...@@ -5283,7 +5273,7 @@ start_struct (enum tree_code code, tree name) ...@@ -5283,7 +5273,7 @@ start_struct (enum tree_code code, tree name)
return ref; return ref;
} }
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) /* Process the specs, declarator and width (NULL if omitted)
of a structure component, returning a FIELD_DECL node. of a structure component, returning a FIELD_DECL node.
WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node. WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
...@@ -5292,11 +5282,12 @@ start_struct (enum tree_code code, tree name) ...@@ -5292,11 +5282,12 @@ start_struct (enum tree_code code, tree name)
are ultimately passed to `build_struct' to make the RECORD_TYPE node. */ are ultimately passed to `build_struct' to make the RECORD_TYPE node. */
tree tree
grokfield (tree declarator, tree declspecs, tree width) grokfield (struct c_declarator *declarator, tree declspecs, tree width)
{ {
tree value; tree value;
if (declarator == NULL_TREE && width == NULL_TREE) if (declarator->kind == cdk_id && declarator->u.id == NULL_TREE
&& width == NULL_TREE)
{ {
/* This is an unnamed decl. /* This is an unnamed decl.
...@@ -5925,7 +5916,8 @@ build_enumerator (tree name, tree value) ...@@ -5925,7 +5916,8 @@ build_enumerator (tree name, tree value)
yyparse to report a parse error. */ yyparse to report a parse error. */
int int
start_function (tree declspecs, tree declarator, tree attributes) start_function (tree declspecs, struct c_declarator *declarator,
tree attributes)
{ {
tree decl1, old_decl; tree decl1, old_decl;
tree restype, resdecl; tree restype, resdecl;
...@@ -6137,12 +6129,9 @@ start_function (tree declspecs, tree declarator, tree attributes) ...@@ -6137,12 +6129,9 @@ start_function (tree declspecs, tree declarator, tree attributes)
need only record them as in effect and complain if any redundant need only record them as in effect and complain if any redundant
old-style parm decls were written. */ old-style parm decls were written. */
static void static void
store_parm_decls_newstyle (tree fndecl, tree arg_info) store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
{ {
tree decl; tree decl;
tree parms = ARG_INFO_PARMS (arg_info);
tree tags = ARG_INFO_TAGS (arg_info);
tree others = ARG_INFO_OTHERS (arg_info);
if (current_scope->bindings) if (current_scope->bindings)
{ {
...@@ -6158,13 +6147,13 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info) ...@@ -6158,13 +6147,13 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
(this happens when a function definition has just an ellipsis in (this happens when a function definition has just an ellipsis in
its parameter list). */ its parameter list). */
else if (warn_traditional && !in_system_header && !current_function_scope else if (warn_traditional && !in_system_header && !current_function_scope
&& ARG_INFO_TYPES (arg_info) != error_mark_node) && arg_info->types != error_mark_node)
warning ("%Jtraditional C rejects ISO C style function definitions", warning ("%Jtraditional C rejects ISO C style function definitions",
fndecl); fndecl);
/* Now make all the parameter declarations visible in the function body. /* Now make all the parameter declarations visible in the function body.
We can bypass most of the grunt work of pushdecl. */ We can bypass most of the grunt work of pushdecl. */
for (decl = parms; decl; decl = TREE_CHAIN (decl)) for (decl = arg_info->parms; decl; decl = TREE_CHAIN (decl))
{ {
DECL_CONTEXT (decl) = current_function_decl; DECL_CONTEXT (decl) = current_function_decl;
if (DECL_NAME (decl)) if (DECL_NAME (decl))
...@@ -6175,10 +6164,10 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info) ...@@ -6175,10 +6164,10 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
} }
/* Record the parameter list in the function declaration. */ /* Record the parameter list in the function declaration. */
DECL_ARGUMENTS (fndecl) = parms; DECL_ARGUMENTS (fndecl) = arg_info->parms;
/* Now make all the ancillary declarations visible, likewise. */ /* Now make all the ancillary declarations visible, likewise. */
for (decl = others; decl; decl = TREE_CHAIN (decl)) for (decl = arg_info->others; decl; decl = TREE_CHAIN (decl))
{ {
DECL_CONTEXT (decl) = current_function_decl; DECL_CONTEXT (decl) = current_function_decl;
if (DECL_NAME (decl)) if (DECL_NAME (decl))
...@@ -6187,7 +6176,7 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info) ...@@ -6187,7 +6176,7 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
} }
/* And all the tag declarations. */ /* And all the tag declarations. */
for (decl = tags; decl; decl = TREE_CHAIN (decl)) for (decl = arg_info->tags; decl; decl = TREE_CHAIN (decl))
if (TREE_PURPOSE (decl)) if (TREE_PURPOSE (decl))
bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope, bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope,
/*invisible=*/false, /*nested=*/false); /*invisible=*/false, /*nested=*/false);
...@@ -6197,11 +6186,11 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info) ...@@ -6197,11 +6186,11 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
definitions (separate parameter list and declarations). */ definitions (separate parameter list and declarations). */
static void static void
store_parm_decls_oldstyle (tree fndecl, tree arg_info) store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
{ {
struct c_binding *b; struct c_binding *b;
tree parm, decl, last; tree parm, decl, last;
tree parmids = ARG_INFO_PARMS (arg_info); tree parmids = arg_info->parms;
/* We use DECL_WEAK as a flag to show which parameters have been /* We use DECL_WEAK as a flag to show which parameters have been
seen already, since it is not used on PARM_DECL. */ seen already, since it is not used on PARM_DECL. */
...@@ -6419,7 +6408,7 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info) ...@@ -6419,7 +6408,7 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
function declaration. */ function declaration. */
void void
store_parm_decls_from (tree arg_info) store_parm_decls_from (struct c_arg_info *arg_info)
{ {
current_function_arg_info = arg_info; current_function_arg_info = arg_info;
store_parm_decls (); store_parm_decls ();
...@@ -6439,7 +6428,7 @@ store_parm_decls (void) ...@@ -6439,7 +6428,7 @@ store_parm_decls (void)
bool proto; bool proto;
/* The argument information block for FNDECL. */ /* The argument information block for FNDECL. */
tree arg_info = current_function_arg_info; struct c_arg_info *arg_info = current_function_arg_info;
current_function_arg_info = 0; current_function_arg_info = 0;
/* True if this definition is written with a prototype. Note: /* True if this definition is written with a prototype. Note:
...@@ -6447,7 +6436,7 @@ store_parm_decls (void) ...@@ -6447,7 +6436,7 @@ store_parm_decls (void)
list in a function definition as equivalent to (void) -- an list in a function definition as equivalent to (void) -- an
empty argument list specifies the function has no parameters, empty argument list specifies the function has no parameters,
but only (void) sets up a prototype for future calls. */ but only (void) sets up a prototype for future calls. */
proto = ARG_INFO_TYPES (arg_info) != 0; proto = arg_info->types != 0;
if (proto) if (proto)
store_parm_decls_newstyle (fndecl, arg_info); store_parm_decls_newstyle (fndecl, arg_info);
...@@ -6865,52 +6854,78 @@ build_void_list_node (void) ...@@ -6865,52 +6854,78 @@ build_void_list_node (void)
return t; return t;
} }
/* Return a structure for a parameter with the given SPECS, ATTRS and /* Return a c_parm structure with the given SPECS, ATTRS and DECLARATOR. */
DECLARATOR. */
tree struct c_parm *
build_c_parm (tree specs, tree attrs, tree declarator) build_c_parm (tree specs, tree attrs, struct c_declarator *declarator)
{ {
return build_tree_list (build_tree_list (specs, declarator), attrs); struct c_parm *ret = XOBNEW (&parser_obstack, struct c_parm);
ret->specs = specs;
ret->attrs = attrs;
ret->declarator = declarator;
return ret;
} }
/* Return a declarator with nested attributes. TARGET is the inner /* Return a declarator with nested attributes. TARGET is the inner
declarator to which these attributes apply. ATTRS are the declarator to which these attributes apply. ATTRS are the
attributes. */ attributes. */
tree struct c_declarator *
build_attrs_declarator (tree attrs, tree target) build_attrs_declarator (tree attrs, struct c_declarator *target)
{ {
return tree_cons (attrs, target, NULL_TREE); struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
ret->kind = cdk_attrs;
ret->declarator = target;
ret->u.attrs = attrs;
return ret;
} }
/* Return a declarator for a function with arguments specified by ARGS /* Return a declarator for a function with arguments specified by ARGS
and return type specified by TARGET. */ and return type specified by TARGET. */
tree struct c_declarator *
build_function_declarator (tree args, tree target) build_function_declarator (struct c_arg_info *args,
struct c_declarator *target)
{ {
return build_nt (CALL_EXPR, target, args, NULL_TREE); struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
ret->kind = cdk_function;
ret->declarator = target;
ret->u.arg_info = args;
return ret;
}
/* Return a declarator for the identifier IDENT (which may be
NULL_TREE for an abstract declarator). */
struct c_declarator *
build_id_declarator (tree ident)
{
struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
ret->kind = cdk_id;
ret->declarator = 0;
ret->u.id = ident;
return ret;
} }
/* Return something to represent absolute declarators containing a *. /* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains. TARGET is the absolute declarator that the * contains.
TYPE_QUALS_ATTRS is a list of modifiers such as const or volatile TYPE_QUALS_ATTRS is a list of modifiers such as const or volatile
to apply to the pointer type, represented as identifiers, possible mixed to apply to the pointer type, represented as identifiers, possible mixed
with attributes. with attributes. */
We return an INDIRECT_REF whose "contents" are TARGET (inside a TREE_LIST, struct c_declarator *
if attributes are present) and whose type is the modifier list. */ make_pointer_declarator (tree type_quals_attrs, struct c_declarator *target)
tree
make_pointer_declarator (tree type_quals_attrs, tree target)
{ {
tree quals, attrs; tree quals, attrs;
tree itarget = target; struct c_declarator *itarget = target;
struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
split_specs_attrs (type_quals_attrs, &quals, &attrs); split_specs_attrs (type_quals_attrs, &quals, &attrs);
if (attrs != NULL_TREE) if (attrs != NULL_TREE)
itarget = build_attrs_declarator (attrs, target); itarget = build_attrs_declarator (attrs, target);
return build1 (INDIRECT_REF, quals, itarget); ret->kind = cdk_pointer;
ret->declarator = itarget;
ret->u.pointer_quals = quals;
return ret;
} }
/* Synthesize a function which calls all the global ctors or global /* Synthesize a function which calls all the global ctors or global
......
...@@ -100,6 +100,8 @@ do { \ ...@@ -100,6 +100,8 @@ do { \
%start program %start program
%union {long itype; tree ttype; void *otype; struct c_expr exprtype; %union {long itype; tree ttype; void *otype; struct c_expr exprtype;
struct c_arg_info *arginfotype; struct c_declarator *dtrtype;
struct c_type_name *typenametype; struct c_parm *parmtype;
enum tree_code code; location_t location; } enum tree_code code; location_t location; }
/* All identifiers that are not reserved words /* All identifiers that are not reserved words
...@@ -217,11 +219,11 @@ do { \ ...@@ -217,11 +219,11 @@ do { \
%type <ttype> c99_block_start c99_block_lineno_labeled_stmt %type <ttype> c99_block_start c99_block_lineno_labeled_stmt
%type <ttype> if_statement_1 if_statement_2 %type <ttype> if_statement_1 if_statement_2
%type <ttype> declarator %type <dtrtype> declarator
%type <ttype> notype_declarator after_type_declarator %type <dtrtype> notype_declarator after_type_declarator
%type <ttype> parm_declarator %type <dtrtype> parm_declarator
%type <ttype> parm_declarator_starttypename parm_declarator_nostarttypename %type <dtrtype> parm_declarator_starttypename parm_declarator_nostarttypename
%type <ttype> array_declarator %type <dtrtype> array_declarator
%type <ttype> structsp_attr structsp_nonattr %type <ttype> structsp_attr structsp_nonattr
%type <ttype> component_decl_list component_decl_list2 %type <ttype> component_decl_list component_decl_list2
...@@ -229,13 +231,15 @@ do { \ ...@@ -229,13 +231,15 @@ do { \
%type <ttype> component_notype_declarator %type <ttype> component_notype_declarator
%type <ttype> enumlist enumerator %type <ttype> enumlist enumerator
%type <ttype> struct_head union_head enum_head %type <ttype> struct_head union_head enum_head
%type <ttype> typename absdcl absdcl1 absdcl1_ea absdcl1_noea %type <typenametype> typename
%type <ttype> direct_absdcl1 absdcl_maybe_attribute %type <dtrtype> absdcl absdcl1 absdcl1_ea absdcl1_noea direct_absdcl1
%type <parmtype> absdcl_maybe_attribute
%type <ttype> condition xexpr for_cond_expr for_incr_expr %type <ttype> condition xexpr for_cond_expr for_incr_expr
%type <ttype> parms parm firstparm identifiers %type <parmtype> parm firstparm
%type <ttype> identifiers
%type <ttype> parmlist parmlist_1 parmlist_2 %type <arginfotype> parms parmlist parmlist_1 parmlist_2
%type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1 %type <arginfotype> parmlist_or_identifiers parmlist_or_identifiers_1
%type <ttype> identifiers_or_typenames %type <ttype> identifiers_or_typenames
%type <itype> setspecs setspecs_fp extension %type <itype> setspecs setspecs_fp extension
...@@ -655,12 +659,12 @@ primary: ...@@ -655,12 +659,12 @@ primary:
$$.original_code = ERROR_MARK; } $$.original_code = ERROR_MARK; }
| '(' typename ')' '{' | '(' typename ')' '{'
{ start_init (NULL_TREE, NULL, 0); { start_init (NULL_TREE, NULL, 0);
$2 = groktypename ($2); $<ttype>$ = groktypename ($2);
really_start_incremental_init ($2); } really_start_incremental_init ($<ttype>$); }
initlist_maybe_comma '}' %prec UNARY initlist_maybe_comma '}' %prec UNARY
{ struct c_expr init = pop_init_level (0); { struct c_expr init = pop_init_level (0);
tree constructor = init.value; tree constructor = init.value;
tree type = $2; tree type = $<ttype>5;
finish_init (); finish_init ();
maybe_warn_string_init (type, init); maybe_warn_string_init (type, init);
...@@ -1653,8 +1657,10 @@ after_type_declarator: ...@@ -1653,8 +1657,10 @@ after_type_declarator:
| '*' maybe_type_quals_attrs after_type_declarator %prec UNARY | '*' maybe_type_quals_attrs after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); } { $$ = make_pointer_declarator ($2, $3); }
| TYPENAME | TYPENAME
{ $$ = build_id_declarator ($1); }
@@ifobjc @@ifobjc
| OBJECTNAME | OBJECTNAME
{ $$ = build_id_declarator ($1); }
@@end_ifobjc @@end_ifobjc
; ;
...@@ -1673,8 +1679,10 @@ parm_declarator_starttypename: ...@@ -1673,8 +1679,10 @@ parm_declarator_starttypename:
| parm_declarator_starttypename array_declarator %prec '.' | parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_inner ($2, $1, false); } { $$ = set_array_declarator_inner ($2, $1, false); }
| TYPENAME | TYPENAME
{ $$ = build_id_declarator ($1); }
@@ifobjc @@ifobjc
| OBJECTNAME | OBJECTNAME
{ $$ = build_id_declarator ($1); }
@@end_ifobjc @@end_ifobjc
; ;
...@@ -1704,6 +1712,7 @@ notype_declarator: ...@@ -1704,6 +1712,7 @@ notype_declarator:
| notype_declarator array_declarator %prec '.' | notype_declarator array_declarator %prec '.'
{ $$ = set_array_declarator_inner ($2, $1, false); } { $$ = set_array_declarator_inner ($2, $1, false); }
| IDENTIFIER | IDENTIFIER
{ $$ = build_id_declarator ($1); }
; ;
struct_head: struct_head:
...@@ -1837,7 +1846,8 @@ component_decl: ...@@ -1837,7 +1846,8 @@ component_decl:
if (pedantic) if (pedantic)
pedwarn ("ISO C doesn't support unnamed structs/unions"); pedwarn ("ISO C doesn't support unnamed structs/unions");
$$ = grokfield(NULL, current_declspecs, NULL_TREE); $$ = grokfield (build_id_declarator (NULL_TREE),
current_declspecs, NULL_TREE);
POP_DECLSPEC_STACK; } POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs components_notype | declspecs_nosc_nots setspecs components_notype
{ $$ = $3; { $$ = $3;
...@@ -1876,7 +1886,8 @@ component_declarator: ...@@ -1876,7 +1886,8 @@ component_declarator:
decl_attributes (&$$, decl_attributes (&$$,
chainon ($4, all_prefix_attributes), 0); } chainon ($4, all_prefix_attributes), 0); }
| ':' expr_no_commas maybe_attribute | ':' expr_no_commas maybe_attribute
{ $$ = grokfield (NULL_TREE, current_declspecs, $2.value); { $$ = grokfield (build_id_declarator (NULL_TREE),
current_declspecs, $2.value);
decl_attributes (&$$, decl_attributes (&$$,
chainon ($3, all_prefix_attributes), 0); } chainon ($3, all_prefix_attributes), 0); }
; ;
...@@ -1891,7 +1902,8 @@ component_notype_declarator: ...@@ -1891,7 +1902,8 @@ component_notype_declarator:
decl_attributes (&$$, decl_attributes (&$$,
chainon ($4, all_prefix_attributes), 0); } chainon ($4, all_prefix_attributes), 0); }
| ':' expr_no_commas maybe_attribute | ':' expr_no_commas maybe_attribute
{ $$ = grokfield (NULL_TREE, current_declspecs, $2.value); { $$ = grokfield (build_id_declarator (NULL_TREE),
current_declspecs, $2.value);
decl_attributes (&$$, decl_attributes (&$$,
chainon ($3, all_prefix_attributes), 0); } chainon ($3, all_prefix_attributes), 0); }
; ;
...@@ -1923,19 +1935,21 @@ typename: ...@@ -1923,19 +1935,21 @@ typename:
{ pending_xref_error (); { pending_xref_error ();
$<ttype>$ = $1; } $<ttype>$ = $1; }
absdcl absdcl
{ $$ = build_tree_list ($<ttype>2, $3); } { $$ = XOBNEW (&parser_obstack, struct c_type_name);
$$->specs = $<ttype>2;
$$->declarator = $3; }
; ;
absdcl: /* an absolute declarator */ absdcl: /* an absolute declarator */
/* empty */ /* empty */
{ $$ = NULL_TREE; } { $$ = build_id_declarator (NULL_TREE); }
| absdcl1 | absdcl1
; ;
absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */ absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */
/* empty */ /* empty */
{ $$ = build_c_parm (current_declspecs, all_prefix_attributes, { $$ = build_c_parm (current_declspecs, all_prefix_attributes,
NULL_TREE); } build_id_declarator (NULL_TREE)); }
| absdcl1 | absdcl1
{ $$ = build_c_parm (current_declspecs, all_prefix_attributes, { $$ = build_c_parm (current_declspecs, all_prefix_attributes,
$1); } $1); }
...@@ -1958,7 +1972,8 @@ absdcl1_noea: ...@@ -1958,7 +1972,8 @@ absdcl1_noea:
absdcl1_ea: absdcl1_ea:
'*' maybe_type_quals_attrs '*' maybe_type_quals_attrs
{ $$ = make_pointer_declarator ($2, NULL_TREE); } { $$ = make_pointer_declarator
($2, build_id_declarator (NULL_TREE)); }
| '*' maybe_type_quals_attrs absdcl1_ea | '*' maybe_type_quals_attrs absdcl1_ea
{ $$ = make_pointer_declarator ($2, $3); } { $$ = make_pointer_declarator ($2, $3); }
; ;
...@@ -1971,9 +1986,11 @@ direct_absdcl1: ...@@ -1971,9 +1986,11 @@ direct_absdcl1:
| direct_absdcl1 array_declarator | direct_absdcl1 array_declarator
{ $$ = set_array_declarator_inner ($2, $1, true); } { $$ = set_array_declarator_inner ($2, $1, true); }
| '(' parmlist | '(' parmlist
{ $$ = build_function_declarator ($2, NULL_TREE); } { $$ = build_function_declarator
($2, build_id_declarator (NULL_TREE)); }
| array_declarator | array_declarator
{ $$ = set_array_declarator_inner ($1, NULL_TREE, true); } { $$ = set_array_declarator_inner
($1, build_id_declarator (NULL_TREE), true); }
; ;
/* The [...] part of a declarator for an array type. */ /* The [...] part of a declarator for an array type. */
...@@ -2519,17 +2536,28 @@ parmlist_1: ...@@ -2519,17 +2536,28 @@ parmlist_1:
parmlist_1 parmlist_1
{ $$ = $6; } { $$ = $6; }
| error ')' | error ')'
{ $$ = make_node (TREE_LIST); } { $$ = XOBNEW (&parser_obstack, struct c_arg_info);
$$->parms = 0;
$$->tags = 0;
$$->types = 0;
$$->others = 0; }
; ;
/* This is what appears inside the parens in a function declarator. /* This is what appears inside the parens in a function declarator.
Is value is represented in the format that grokdeclarator expects. */ Its value is represented in the format that grokdeclarator expects. */
parmlist_2: /* empty */ parmlist_2: /* empty */
{ $$ = make_node (TREE_LIST); } { $$ = XOBNEW (&parser_obstack, struct c_arg_info);
$$->parms = 0;
$$->tags = 0;
$$->types = 0;
$$->others = 0; }
| ELLIPSIS | ELLIPSIS
{ $$ = make_node (TREE_LIST); { $$ = XOBNEW (&parser_obstack, struct c_arg_info);
$$->parms = 0;
$$->tags = 0;
$$->others = 0;
/* Suppress -Wold-style-definition for this case. */ /* Suppress -Wold-style-definition for this case. */
TREE_CHAIN ($$) = error_mark_node; $$->types = error_mark_node;
error ("ISO C requires a named argument before `...'"); error ("ISO C requires a named argument before `...'");
} }
| parms | parms
...@@ -2614,7 +2642,11 @@ parmlist_or_identifiers: ...@@ -2614,7 +2642,11 @@ parmlist_or_identifiers:
parmlist_or_identifiers_1: parmlist_or_identifiers_1:
parmlist_1 parmlist_1
| identifiers ')' | identifiers ')'
{ $$ = tree_cons (NULL_TREE, NULL_TREE, $1); { $$ = XOBNEW (&parser_obstack, struct c_arg_info);
$$->parms = 0;
$$->tags = 0;
$$->types = $1;
$$->others = 0;
/* Make sure we have a parmlist after attributes. */ /* Make sure we have a parmlist after attributes. */
if ($<ttype>-1 != 0) if ($<ttype>-1 != 0)
......
...@@ -131,6 +131,81 @@ struct c_expr ...@@ -131,6 +131,81 @@ struct c_expr
enum tree_code original_code; enum tree_code original_code;
}; };
/* The various kinds of declarators in C. */
enum c_declarator_kind {
/* An identifier. */
cdk_id,
/* A function. */
cdk_function,
/* An array. */
cdk_array,
/* A pointer. */
cdk_pointer,
/* Parenthesized declarator with nested attributes. */
cdk_attrs
};
/* Information about the parameters in a function declarator. */
struct c_arg_info {
/* A list of parameter decls. */
tree parms;
/* A list of structure, union and enum tags defined. */
tree tags;
/* A list of argument types to go in the FUNCTION_TYPE. */
tree types;
/* A list of non-parameter decls (notably enumeration constants)
defined with the parameters. */
tree others;
};
/* A declarator. */
struct c_declarator {
/* The kind of declarator. */
enum c_declarator_kind kind;
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
struct c_declarator *declarator;
union {
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
declarator. */
tree id;
/* For functions. */
struct c_arg_info *arg_info;
/* For arrays. */
struct {
/* The array dimension, or NULL for [] and [*]. */
tree dimen;
/* The qualifiers (and attributes, currently ignored) inside []. */
tree quals;
/* Whether [static] was used. */
BOOL_BITFIELD static_p : 1;
/* Whether [*] was used. */
BOOL_BITFIELD vla_unspec_p : 1;
} array;
/* For pointers, the qualifiers on the pointer type. */
tree pointer_quals;
/* For attributes. */
tree attrs;
} u;
};
/* A type name. */
struct c_type_name {
/* The declaration specifiers. */
tree specs;
/* The declarator. */
struct c_declarator *declarator;
};
/* A parameter. */
struct c_parm {
/* The declaration specifiers, minus any prefix attributes. */
tree specs;
/* The attributes. */
tree attrs;
/* The declarator. */
struct c_declarator *declarator;
};
/* Save and restore the variables in this file and elsewhere /* Save and restore the variables in this file and elsewhere
that keep track of the progress of compilation of the current function. that keep track of the progress of compilation of the current function.
Used for nested functions. */ Used for nested functions. */
...@@ -141,7 +216,7 @@ struct language_function GTY(()) ...@@ -141,7 +216,7 @@ struct language_function GTY(())
tree x_break_label; tree x_break_label;
tree x_cont_label; tree x_cont_label;
struct c_switch * GTY((skip)) x_switch_stack; struct c_switch * GTY((skip)) x_switch_stack;
tree arg_info; struct c_arg_info * GTY((skip)) arg_info;
int returns_value; int returns_value;
int returns_null; int returns_null;
int returns_abnormally; int returns_abnormally;
...@@ -171,7 +246,7 @@ extern void c_expand_body (tree); ...@@ -171,7 +246,7 @@ extern void c_expand_body (tree);
extern void c_init_decl_processing (void); extern void c_init_decl_processing (void);
extern void c_dup_lang_specific_decl (tree); extern void c_dup_lang_specific_decl (tree);
extern void c_print_identifier (FILE *, tree, int); extern void c_print_identifier (FILE *, tree, int);
extern tree build_array_declarator (tree, tree, bool, bool); extern struct c_declarator *build_array_declarator (tree, tree, bool, bool);
extern tree build_enumerator (tree, tree); extern tree build_enumerator (tree, tree);
extern void check_for_loop_decls (void); extern void check_for_loop_decls (void);
extern void mark_forward_parm_decls (void); extern void mark_forward_parm_decls (void);
...@@ -184,36 +259,42 @@ extern void finish_decl (tree, tree, tree); ...@@ -184,36 +259,42 @@ extern void finish_decl (tree, tree, tree);
extern tree finish_enum (tree, tree, tree); extern tree finish_enum (tree, tree, tree);
extern void finish_function (void); extern void finish_function (void);
extern tree finish_struct (tree, tree, tree); extern tree finish_struct (tree, tree, tree);
extern tree get_parm_info (bool); extern struct c_arg_info *get_parm_info (bool);
extern tree grokfield (tree, tree, tree); extern tree grokfield (struct c_declarator *, tree, tree);
extern void split_specs_attrs (tree, tree *, tree *); extern void split_specs_attrs (tree, tree *, tree *);
extern tree groktypename (tree); extern tree groktypename (struct c_type_name *);
extern tree grokparm (tree); extern tree grokparm (const struct c_parm *);
extern tree implicitly_declare (tree); extern tree implicitly_declare (tree);
extern void keep_next_level (void); extern void keep_next_level (void);
extern tree lookup_name (tree); extern tree lookup_name (tree);
extern void pending_xref_error (void); extern void pending_xref_error (void);
extern void c_push_function_context (struct function *); extern void c_push_function_context (struct function *);
extern void c_pop_function_context (struct function *); extern void c_pop_function_context (struct function *);
extern void push_parm_decl (tree); extern void push_parm_decl (const struct c_parm *);
extern tree pushdecl_top_level (tree); extern tree pushdecl_top_level (tree);
extern tree set_array_declarator_inner (tree, tree, bool); extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
struct c_declarator *,
bool);
extern tree builtin_function (const char *, tree, int, enum built_in_class, extern tree builtin_function (const char *, tree, int, enum built_in_class,
const char *, tree); const char *, tree);
extern void shadow_tag (tree); extern void shadow_tag (tree);
extern void shadow_tag_warned (tree, int); extern void shadow_tag_warned (tree, int);
extern tree start_enum (tree); extern tree start_enum (tree);
extern int start_function (tree, tree, tree); extern int start_function (tree, struct c_declarator *, tree);
extern tree start_decl (tree, tree, bool, tree); extern tree start_decl (struct c_declarator *, tree, bool, tree);
extern tree start_struct (enum tree_code, tree); extern tree start_struct (enum tree_code, tree);
extern void store_parm_decls (void); extern void store_parm_decls (void);
extern void store_parm_decls_from (tree); extern void store_parm_decls_from (struct c_arg_info *);
extern tree xref_tag (enum tree_code, tree); extern tree xref_tag (enum tree_code, tree);
extern int c_expand_decl (tree); extern int c_expand_decl (tree);
extern tree build_c_parm (tree, tree, tree); extern struct c_parm *build_c_parm (tree, tree, struct c_declarator *);
extern tree build_attrs_declarator (tree, tree); extern struct c_declarator *build_attrs_declarator (tree,
extern tree build_function_declarator (tree, tree); struct c_declarator *);
extern tree make_pointer_declarator (tree, tree); extern struct c_declarator *build_function_declarator (struct c_arg_info *,
struct c_declarator *);
extern struct c_declarator *build_id_declarator (tree);
extern struct c_declarator *make_pointer_declarator (tree,
struct c_declarator *);
/* in c-objc-common.c */ /* in c-objc-common.c */
extern int c_disregard_inline_limits (tree); extern int c_disregard_inline_limits (tree);
...@@ -252,13 +333,13 @@ extern tree build_external_ref (tree, int); ...@@ -252,13 +333,13 @@ extern tree build_external_ref (tree, int);
extern void record_maybe_used_decl (tree); extern void record_maybe_used_decl (tree);
extern void pop_maybe_used (bool); extern void pop_maybe_used (bool);
extern struct c_expr c_expr_sizeof_expr (struct c_expr); extern struct c_expr c_expr_sizeof_expr (struct c_expr);
extern struct c_expr c_expr_sizeof_type (tree); extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
extern struct c_expr parser_build_binary_op (enum tree_code, struct c_expr, extern struct c_expr parser_build_binary_op (enum tree_code, struct c_expr,
struct c_expr); struct c_expr);
extern void readonly_error (tree, const char *); extern void readonly_error (tree, const char *);
extern tree build_conditional_expr (tree, tree, tree); extern tree build_conditional_expr (tree, tree, tree);
extern tree build_compound_expr (tree, tree); extern tree build_compound_expr (tree, tree);
extern tree c_cast_expr (tree, tree); extern tree c_cast_expr (struct c_type_name *, tree);
extern tree build_c_cast (tree, tree); extern tree build_c_cast (tree, tree);
extern tree build_modify_expr (tree, enum tree_code, tree); extern tree build_modify_expr (tree, enum tree_code, tree);
extern void store_init_value (tree, tree); extern void store_init_value (tree, tree);
......
...@@ -1859,7 +1859,7 @@ c_expr_sizeof_expr (struct c_expr expr) ...@@ -1859,7 +1859,7 @@ c_expr_sizeof_expr (struct c_expr expr)
name passed to sizeof (rather than the type itself). */ name passed to sizeof (rather than the type itself). */
struct c_expr struct c_expr
c_expr_sizeof_type (tree t) c_expr_sizeof_type (struct c_type_name *t)
{ {
tree type; tree type;
struct c_expr ret; struct c_expr ret;
...@@ -3217,15 +3217,16 @@ build_c_cast (tree type, tree expr) ...@@ -3217,15 +3217,16 @@ build_c_cast (tree type, tree expr)
/* Interpret a cast of expression EXPR to type TYPE. */ /* Interpret a cast of expression EXPR to type TYPE. */
tree tree
c_cast_expr (tree type, tree expr) c_cast_expr (struct c_type_name *type_name, tree expr)
{ {
tree type;
int saved_wsp = warn_strict_prototypes; int saved_wsp = warn_strict_prototypes;
/* This avoids warnings about unprototyped casts on /* This avoids warnings about unprototyped casts on
integers. E.g. "#define SIG_DFL (void(*)())0". */ integers. E.g. "#define SIG_DFL (void(*)())0". */
if (TREE_CODE (expr) == INTEGER_CST) if (TREE_CODE (expr) == INTEGER_CST)
warn_strict_prototypes = 0; warn_strict_prototypes = 0;
type = groktypename (type); type = groktypename (type_name);
warn_strict_prototypes = saved_wsp; warn_strict_prototypes = saved_wsp;
return build_c_cast (type, expr); return build_c_cast (type, expr);
......
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
* objc-act.c (objc_start_function, really_start_method,
objc_get_parm_info, start_method_def): Update to new arg_info
structures.
2004-09-07 Ziemowit Laski <zlaski@apple.com> 2004-09-07 Ziemowit Laski <zlaski@apple.com>
* Make-lang.in (objc/objc-parse.o): Depend on $(C_COMMON_H) instead of * Make-lang.in (objc/objc-parse.o): Depend on $(C_COMMON_H) instead of
......
...@@ -156,7 +156,11 @@ static tree start_class (enum tree_code, tree, tree, tree); ...@@ -156,7 +156,11 @@ static tree start_class (enum tree_code, tree, tree, tree);
static tree continue_class (tree); static tree continue_class (tree);
static void finish_class (tree); static void finish_class (tree);
static void start_method_def (tree); static void start_method_def (tree);
#ifdef OBJCPLUS
static void objc_start_function (tree, tree, tree, tree); static void objc_start_function (tree, tree, tree, tree);
#else
static void objc_start_function (tree, tree, tree, struct c_arg_info *);
#endif
static tree start_protocol (enum tree_code, tree, tree); static tree start_protocol (enum tree_code, tree, tree);
static tree build_method_decl (enum tree_code, tree, tree, tree); static tree build_method_decl (enum tree_code, tree, tree, tree);
static tree objc_add_method (tree, tree, int); static tree objc_add_method (tree, tree, int);
...@@ -244,12 +248,20 @@ static void encode_gnu_bitfield (int, tree, int); ...@@ -244,12 +248,20 @@ static void encode_gnu_bitfield (int, tree, int);
static void encode_type (tree, int, int); static void encode_type (tree, int, int);
static void encode_field_decl (tree, int, int); static void encode_field_decl (tree, int, int);
#ifdef OBJCPLUS
static void really_start_method (tree, tree); static void really_start_method (tree, tree);
#else
static void really_start_method (tree, struct c_arg_info *);
#endif
static int objc_types_are_equivalent (tree, tree); static int objc_types_are_equivalent (tree, tree);
static int comp_proto_with_proto (tree, tree); static int comp_proto_with_proto (tree, tree);
static tree get_arg_type_list (tree, int, int); static tree get_arg_type_list (tree, int, int);
static void objc_push_parm (tree); static void objc_push_parm (tree);
#ifdef OBJCPLUS
static tree objc_get_parm_info (int); static tree objc_get_parm_info (int);
#else
static struct c_arg_info *objc_get_parm_info (int);
#endif
static void synth_self_and_ucmd_args (void); static void synth_self_and_ucmd_args (void);
/* Utilities for debugging and error diagnostics. */ /* Utilities for debugging and error diagnostics. */
...@@ -7338,16 +7350,22 @@ objc_push_parm (tree parm) ...@@ -7338,16 +7350,22 @@ objc_push_parm (tree parm)
/* Retrieve the formal paramter list constructed via preceding calls to /* Retrieve the formal paramter list constructed via preceding calls to
objc_push_parm(). */ objc_push_parm(). */
static tree
#ifdef OBJCPLUS #ifdef OBJCPLUS
static tree
objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED) objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
#else #else
static struct c_arg_info *
objc_get_parm_info (int have_ellipsis) objc_get_parm_info (int have_ellipsis)
#endif #endif
{ {
#ifdef OBJCPLUS
tree parm_info = objc_parmlist; tree parm_info = objc_parmlist;
objc_parmlist = NULL_TREE;
#ifndef OBJCPLUS return parm_info;
#else
tree parm_info = objc_parmlist;
struct c_arg_info *arg_info;
/* The C front-end requires an elaborate song and dance at /* The C front-end requires an elaborate song and dance at
this point. */ this point. */
push_scope (); push_scope ();
...@@ -7360,12 +7378,11 @@ objc_get_parm_info (int have_ellipsis) ...@@ -7360,12 +7378,11 @@ objc_get_parm_info (int have_ellipsis)
pushdecl (parm_info); pushdecl (parm_info);
parm_info = next; parm_info = next;
} }
parm_info = get_parm_info (have_ellipsis); arg_info = get_parm_info (have_ellipsis);
pop_scope (); pop_scope ();
#endif
objc_parmlist = NULL_TREE; objc_parmlist = NULL_TREE;
return arg_info;
return parm_info; #endif
} }
/* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
...@@ -7400,6 +7417,11 @@ static void ...@@ -7400,6 +7417,11 @@ static void
start_method_def (tree method) start_method_def (tree method)
{ {
tree parmlist; tree parmlist;
#ifdef OBJCPLUS
tree parm_info;
#else
struct c_arg_info *parm_info;
#endif
int have_ellipsis = 0; int have_ellipsis = 0;
/* Required to implement _msgSuper. */ /* Required to implement _msgSuper. */
...@@ -7434,9 +7456,9 @@ start_method_def (tree method) ...@@ -7434,9 +7456,9 @@ start_method_def (tree method)
have_ellipsis = 1; have_ellipsis = 1;
} }
parmlist = objc_get_parm_info (have_ellipsis); parm_info = objc_get_parm_info (have_ellipsis);
really_start_method (objc_method_context, parmlist); really_start_method (objc_method_context, parm_info);
} }
static void static void
...@@ -7509,11 +7531,19 @@ comp_proto_with_proto (tree proto1, tree proto2) ...@@ -7509,11 +7531,19 @@ comp_proto_with_proto (tree proto1, tree proto2)
} }
static void static void
objc_start_function (tree name, tree type, tree attrs, tree params) objc_start_function (tree name, tree type, tree attrs,
#ifdef OBJCPLUS
tree params
#else
struct c_arg_info *params
#endif
)
{ {
tree fndecl = build_decl (FUNCTION_DECL, name, type); tree fndecl = build_decl (FUNCTION_DECL, name, type);
#ifdef OBJCPLUS
DECL_ARGUMENTS (fndecl) = params; DECL_ARGUMENTS (fndecl) = params;
#endif
DECL_INITIAL (fndecl) = error_mark_node; DECL_INITIAL (fndecl) = error_mark_node;
DECL_EXTERNAL (fndecl) = 0; DECL_EXTERNAL (fndecl) = 0;
TREE_STATIC (fndecl) = 1; TREE_STATIC (fndecl) = 1;
...@@ -7532,7 +7562,7 @@ objc_start_function (tree name, tree type, tree attrs, tree params) ...@@ -7532,7 +7562,7 @@ objc_start_function (tree name, tree type, tree attrs, tree params)
= build_decl (RESULT_DECL, NULL_TREE, = build_decl (RESULT_DECL, NULL_TREE,
TREE_TYPE (TREE_TYPE (current_function_decl))); TREE_TYPE (TREE_TYPE (current_function_decl)));
start_fname_decls (); start_fname_decls ();
store_parm_decls_from (DECL_ARGUMENTS (current_function_decl)); store_parm_decls_from (params);
#endif #endif
TREE_USED (current_function_decl) = 1; TREE_USED (current_function_decl) = 1;
...@@ -7545,7 +7575,13 @@ objc_start_function (tree name, tree type, tree attrs, tree params) ...@@ -7545,7 +7575,13 @@ objc_start_function (tree name, tree type, tree attrs, tree params)
- If we have a prototype, check for type consistency. */ - If we have a prototype, check for type consistency. */
static void static void
really_start_method (tree method, tree parmlist) really_start_method (tree method,
#ifdef OBJCPLUS
tree parmlist
#else
struct c_arg_info *parmlist
#endif
)
{ {
tree ret_type, meth_type; tree ret_type, meth_type;
tree method_id; tree method_id;
......
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