Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
/* This file defines the grammar of C and that of Objective C.
ifobjc ... end ifobjc conditionals contain code for Objective C only.
written by AT&T, but I have never seen it. */
ifobjc
-%expect 31
+%expect 31 /* shift/reduce conflicts, and 1 reduce/reduce conflict. */
end ifobjc
ifc
-%expect 10
+%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
end ifc
%{
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "tree.h"
#include "input.h"
#include "cpplib.h"
#include "objc-act.h"
end ifobjc
-/* Since parsers are distinct for each language, put the language string
- definition here. */
-ifobjc
-const char * const language_string = "GNU Objective-C";
-end ifobjc
-ifc
-const char * const language_string = "GNU C";
-end ifc
-
/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
%token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
%token ATTRIBUTE EXTENSION LABEL
-%token REALPART IMAGPART VA_ARG
+%token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
%token PTR_VALUE PTR_BASE PTR_EXTENT
/* function name can be a string const or a var decl. */
%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
-/* Objective-C string constants in raw form.
- yylval is an STRING_CST node. */
-%token OBJC_STRING
-
-
%type <code> unop
%type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
%type <ttype> declspecs_ts declspecs_nots
%type <ttype> declspecs_ts_nosa declspecs_nots_nosa
%type <ttype> declspecs_nosc_ts declspecs_nosc_nots declspecs_nosc declspecs
-%type <ttype> maybe_type_quals_setattrs typespec_nonattr typespec_attr
+%type <ttype> maybe_type_quals_attrs typespec_nonattr typespec_attr
%type <ttype> typespec_reserved_nonattr typespec_reserved_attr
%type <ttype> typespec_nonreserved_nonattr
%type <ttype> init maybeasm
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
-%type <ttype> maybe_setattrs
%type <ttype> any_word extension
%type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
-%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
+%type <ttype> CLASSNAME OBJECTNAME
end ifobjc
\f
%{
static tree current_declspecs = NULL_TREE;
static tree prefix_attributes = NULL_TREE;
-/* Stack of saved values of current_declspecs and prefix_attributes. */
+/* List of all the attributes applying to the identifier currently being
+ declared; includes prefix_attributes and possibly some more attributes
+ just after a comma. */
+static tree all_prefix_attributes = NULL_TREE;
+
+/* Stack of saved values of current_declspecs, prefix_attributes and
+ all_prefix_attributes. */
static tree declspec_stack;
+/* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK
+ should be called from the productions making use of setspecs. */
+#define PUSH_DECLSPEC_STACK \
+ do { \
+ declspec_stack = tree_cons (build_tree_list (prefix_attributes, \
+ all_prefix_attributes), \
+ current_declspecs, \
+ declspec_stack); \
+ } while (0)
+
+#define POP_DECLSPEC_STACK \
+ do { \
+ current_declspecs = TREE_VALUE (declspec_stack); \
+ prefix_attributes = TREE_PURPOSE (TREE_PURPOSE (declspec_stack)); \
+ all_prefix_attributes = TREE_VALUE (TREE_PURPOSE (declspec_stack)); \
+ declspec_stack = TREE_CHAIN (declspec_stack); \
+ } while (0)
+
/* For __extension__, save/restore the warning flags which are
controlled by __extension__. */
#define SAVE_WARN_FLAGS() \
} while (0)
ifobjc
-/* Objective-C specific information */
-
-tree objc_interface_context;
-tree objc_implementation_context;
-tree objc_method_context;
-tree objc_ivar_chain;
-tree objc_ivar_context;
-enum tree_code objc_inherit_code;
-int objc_receiver_context;
-int objc_public_flag;
-int objc_pq_context;
+/* Objective-C specific parser/lexer information */
+static enum tree_code objc_inherit_code;
+static int objc_pq_context = 0, objc_public_flag = 0;
+
+/* 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. */
+static int objc_need_raw_identifier;
+#define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL
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. */
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
void
c_parse_init ()
{
+ init_reswords ();
+
ggc_add_tree_root (&declspec_stack, 1);
ggc_add_tree_root (¤t_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
-ifobjc
- ggc_add_tree_root (&objc_interface_context, 1);
- ggc_add_tree_root (&objc_implementation_context, 1);
- ggc_add_tree_root (&objc_method_context, 1);
- ggc_add_tree_root (&objc_ivar_chain, 1);
- ggc_add_tree_root (&objc_ivar_context, 1);
-end ifobjc
+ ggc_add_tree_root (&all_prefix_attributes, 1);
}
%}
else if (!flag_traditional)
warning ("data definition has no type or storage class");
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs ';'
{ shadow_tag ($1); }
| error ';'
fndef:
declspecs_ts setspecs declarator
{ if (! start_function (current_declspecs, $3,
- prefix_attributes, NULL_TREE))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator
{ if (! start_function (current_declspecs, $3,
- prefix_attributes, NULL_TREE))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| setspecs notype_declarator
{ if (! start_function (NULL_TREE, $2,
- prefix_attributes, NULL_TREE))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $6;
DECL_SOURCE_LINE (current_function_decl) = $7;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| setspecs notype_declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
;
identifier:
| TYPENAME
ifobjc
| OBJECTNAME
- | CLASSNAME
+ | CLASSNAME
end ifobjc
;
{ char class;
$$ = build_modify_expr ($1, NOP_EXPR, $3);
class = TREE_CODE_CLASS (TREE_CODE ($$));
- if (class == 'e' || class == '1'
- || class == '2' || class == '<')
+ if (IS_EXPR_CODE_CLASS (class))
C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR);
}
| expr_no_commas ASSIGN expr_no_commas
$$ = build_modify_expr ($1, $2, $3);
/* This inhibits warnings in truthvalue_conversion. */
class = TREE_CODE_CLASS (TREE_CODE ($$));
- if (class == 'e' || class == '1'
- || class == '2' || class == '<')
+ if (IS_EXPR_CODE_CLASS (class))
C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK);
}
;
$2 = groktypename ($2);
really_start_incremental_init ($2); }
initlist_maybe_comma '}' %prec UNARY
- { const char *name;
- tree result = pop_init_level (0);
+ { tree constructor = pop_init_level (0);
tree type = $2;
finish_init ();
if (pedantic && ! flag_isoc99)
pedwarn ("ISO C89 forbids compound literals");
- if (TYPE_NAME (type) != 0)
- {
- if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- name = IDENTIFIER_POINTER (TYPE_NAME (type));
- else
- name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
- }
- else
- name = "";
- $$ = result;
- if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
- {
- int failure = complete_array_type (type, $$, 1);
- if (failure)
- abort ();
- }
+ $$ = build_compound_literal (type, constructor);
}
| '(' expr ')'
{ char class = TREE_CODE_CLASS (TREE_CODE ($2));
- if (class == 'e' || class == '1'
- || class == '2' || class == '<')
+ if (IS_EXPR_CODE_CLASS (class))
C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
$$ = $2; }
| '(' error ')'
{ $$ = build_function_call ($1, $3); }
| VA_ARG '(' expr_no_commas ',' typename ')'
{ $$ = build_va_arg ($3, groktypename ($5)); }
+ | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' expr_no_commas ')'
+ {
+ tree c;
+
+ c = fold ($3);
+ STRIP_NOPS (c);
+ if (TREE_CODE (c) != INTEGER_CST)
+ error ("first argument to __builtin_choose_expr not a constant");
+ $$ = integer_zerop (c) ? $7 : $5;
+ }
+ | TYPES_COMPATIBLE_P '(' typename ',' typename ')'
+ {
+ tree e1, e2;
+
+ e1 = TYPE_MAIN_VARIANT (groktypename ($3));
+ e2 = TYPE_MAIN_VARIANT (groktypename ($5));
+
+ $$ = comptypes (e1, e2)
+ ? build_int_2 (1, 0) : build_int_2 (0, 0);
+ }
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
/* Produces an STRING_CST with perhaps more STRING_CSTs chained
onto it, which is to be read as an ObjC string object. */
objc_string:
- OBJC_STRING
- | objc_string OBJC_STRING
- { $$ = chainon ($1, $2); }
+ '@' STRING
+ { $$ = $2; }
+ | objc_string '@' STRING
+ { $$ = chainon ($1, $3); }
;
end ifobjc
style parm. */
datadecl:
declspecs_ts_nosa setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts_nosa ';'
{ shadow_tag_warned ($1, 1);
pedwarn ("empty declaration"); }
for the sake of parm declarations nested in function declarators. */
setspecs: /* empty */
{ pending_xref_error ();
- declspec_stack = tree_cons (prefix_attributes,
- current_declspecs,
- declspec_stack);
+ PUSH_DECLSPEC_STACK;
split_specs_attrs ($<ttype>0,
- ¤t_declspecs, &prefix_attributes); }
- ;
-
-/* ??? Yuck. See maybe_setattrs. */
-setattrs: /* empty */
- { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
+ ¤t_declspecs, &prefix_attributes);
+ all_prefix_attributes = prefix_attributes; }
;
-maybe_setattrs:
- /* ??? Yuck. setattrs is a quick hack. We can't use
- prefix_attributes because $1 only applies to this
- declarator. We assume setspecs has already been done.
- setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
- attributes could be recognized here or in `attributes').
- Properly attributes ought to be able to apply to any level of
- nested declarator, but the necessary compiler support isn't
- present, so the attributes apply to a declaration (which may be
- nested). */
- maybe_attribute setattrs
+/* Possibly attributes after a comma, which should reset all_prefix_attributes
+ to prefix_attributes with these ones chained on the front. */
+maybe_resetattrs:
+ maybe_attribute
+ { all_prefix_attributes = chainon ($1, prefix_attributes); }
;
decl:
declspecs_ts setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts setspecs nested_function
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_nested_function
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs ';'
{ shadow_tag ($1); }
| extension decl
| declspecs_sc_ts_sa_ea
;
-/* A (possibly empty) sequence of type qualifiers and attributes, to be
- followed by the effect of setattrs if any attributes were present. */
-maybe_type_quals_setattrs:
+/* A (possibly empty) sequence of type qualifiers and attributes. */
+maybe_type_quals_attrs:
/* empty */
{ $$ = NULL_TREE; }
| declspecs_nosc_nots
- { tree specs, attrs;
- split_specs_attrs ($1, &specs, &attrs);
- /* ??? Yuck. See maybe_setattrs. */
- if (attrs != NULL_TREE)
- prefix_attributes = chainon (prefix_attributes, attrs);
- $$ = specs; }
+ { $$ = $1; }
;
/* A type specifier (but not a type qualifier).
typespec_reserved_nonattr:
TYPESPEC
+ { OBJC_NEED_RAW_IDENTIFIER (1); }
| structsp_nonattr
;
initdecls:
initdcl
- | initdecls ',' maybe_setattrs initdcl
+ | initdecls ',' maybe_resetattrs initdcl
;
notype_initdecls:
notype_initdcl
- | notype_initdecls ',' maybe_setattrs notype_initdcl
+ | notype_initdecls ',' maybe_resetattrs notype_initdcl
;
maybeasm:
initdcl:
declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($1, current_declspecs, 1,
- $3, prefix_attributes);
+ chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
finish_decl ($<ttype>5, $6, $2); }
| declarator maybeasm maybe_attribute
{ tree d = start_decl ($1, current_declspecs, 0,
- $3, prefix_attributes);
+ chainon ($3, all_prefix_attributes));
finish_decl (d, NULL_TREE, $2);
}
;
notype_initdcl:
notype_declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($1, current_declspecs, 1,
- $3, prefix_attributes);
+ chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_init ();
- decl_attributes ($<ttype>5, $3, prefix_attributes);
finish_decl ($<ttype>5, $6, $2); }
| notype_declarator maybeasm maybe_attribute
{ tree d = start_decl ($1, current_declspecs, 0,
- $3, prefix_attributes);
+ chainon ($3, all_prefix_attributes));
finish_decl (d, NULL_TREE, $2); }
;
/* the * rules are dummies to accept the Apollo extended syntax
push_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes, NULL_TREE))
+ all_prefix_attributes))
{
pop_function_context ();
YYERROR1;
push_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes, NULL_TREE))
+ all_prefix_attributes))
{
pop_function_context ();
YYERROR1;
/* A declarator that is allowed only after an explicit typespec. */
after_type_declarator:
- '(' maybe_setattrs after_type_declarator ')'
- { $$ = $3; }
+ '(' maybe_attribute after_type_declarator ')'
+ { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
| after_type_declarator '(' parmlist_or_identifiers %prec '.'
{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
/* | after_type_declarator '(' error ')' %prec '.'
poplevel (0, 0, 0); } */
| after_type_declarator array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
- | '*' maybe_type_quals_setattrs after_type_declarator %prec UNARY
+ | '*' maybe_type_quals_attrs after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
| TYPENAME
ifobjc
| parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
| TYPENAME
+ifobjc
+ | OBJECTNAME
+end ifobjc
;
parm_declarator_nostarttypename:
poplevel (0, 0, 0); } */
| parm_declarator_nostarttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
- | '*' maybe_type_quals_setattrs parm_declarator_starttypename %prec UNARY
+ | '*' maybe_type_quals_attrs parm_declarator_starttypename %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
- | '*' maybe_type_quals_setattrs parm_declarator_nostarttypename %prec UNARY
+ | '*' maybe_type_quals_attrs parm_declarator_nostarttypename %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
- | '(' maybe_setattrs parm_declarator_nostarttypename ')'
- { $$ = $3; }
+ | '(' maybe_attribute parm_declarator_nostarttypename ')'
+ { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
;
/* A declarator allowed whether or not there has been
/* | notype_declarator '(' error ')' %prec '.'
{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
poplevel (0, 0, 0); } */
- | '(' maybe_setattrs notype_declarator ')'
- { $$ = $3; }
- | '*' maybe_type_quals_setattrs notype_declarator %prec UNARY
+ | '(' maybe_attribute notype_declarator ')'
+ { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
+ | '*' maybe_type_quals_attrs notype_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
| notype_declarator array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
$$ = get_class_ivars (interface);
else
{
- error ("Cannot find interface declaration for `%s'",
+ error ("cannot find interface declaration for `%s'",
IDENTIFIER_POINTER ($3));
$$ = NULL_TREE;
}
component_decl:
declspecs_nosc_ts setspecs components
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_ts setspecs save_filename save_lineno
{
/* Support for unnamed structs or unions as members of
pedwarn ("ISO C doesn't support unnamed structs/unions");
$$ = grokfield($3, $4, NULL, current_declspecs, NULL_TREE);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack);
- }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs components_notype
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots
{ if (pedantic)
pedwarn ("ISO C forbids member declarations with no members");
components:
component_declarator
- | components ',' maybe_setattrs component_declarator
+ | components ',' maybe_resetattrs component_declarator
{ $$ = chainon ($1, $4); }
;
components_notype:
component_notype_declarator
- | components_notype ',' maybe_setattrs component_notype_declarator
+ | components_notype ',' maybe_resetattrs component_notype_declarator
{ $$ = chainon ($1, $4); }
;
component_declarator:
save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes ($$, $4, prefix_attributes); }
+ decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
| save_filename save_lineno
declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes ($$, $6, prefix_attributes); }
+ decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes ($$, $5, prefix_attributes); }
+ decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
;
component_notype_declarator:
save_filename save_lineno notype_declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes ($$, $4, prefix_attributes); }
+ decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
| save_filename save_lineno
notype_declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes ($$, $6, prefix_attributes); }
+ decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes ($$, $5, prefix_attributes); }
+ decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
;
/* We chain the enumerators in reverse order.
/* empty */
{ $$ = build_tree_list (build_tree_list (current_declspecs,
NULL_TREE),
- build_tree_list (prefix_attributes,
- NULL_TREE)); }
+ all_prefix_attributes); }
| absdcl1
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- build_tree_list (prefix_attributes,
- NULL_TREE)); }
+ all_prefix_attributes); }
| absdcl1_noea attributes
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- build_tree_list (prefix_attributes,
- $2)); }
+ chainon ($2, all_prefix_attributes)); }
;
absdcl1: /* a nonempty absolute declarator */
absdcl1_noea:
direct_absdcl1
- | '*' maybe_type_quals_setattrs absdcl1_noea
+ | '*' maybe_type_quals_attrs absdcl1_noea
{ $$ = make_pointer_declarator ($2, $3); }
;
absdcl1_ea:
- '*' maybe_type_quals_setattrs
+ '*' maybe_type_quals_attrs
{ $$ = make_pointer_declarator ($2, NULL_TREE); }
- | '*' maybe_type_quals_setattrs absdcl1_ea
+ | '*' maybe_type_quals_attrs absdcl1_ea
{ $$ = make_pointer_declarator ($2, $3); }
;
direct_absdcl1:
- '(' maybe_setattrs absdcl1 ')'
- { $$ = $3; }
+ '(' maybe_attribute absdcl1 ')'
+ { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
| direct_absdcl1 '(' parmlist
{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
| direct_absdcl1 array_declarator
/* ??? We currently have no way of recording
the filename for a statement. This probably
matters little in practice at the moment,
- but I suspect that problems will ocurr when
+ but I suspect that problems will occur when
doing inlining at the tree level. */
}
}
stmt_count++;
if (label)
{
- decl_attributes (label, $5, NULL_TREE);
+ decl_attributes (&label, $5, 0);
$$ = add_stmt (build_stmt (LABEL_STMT, label));
}
else
asm_operand:
STRING '(' expr ')'
- { $$ = build_tree_list ($1, $3); }
+ { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $3); }
+ | '[' identifier ']' STRING '(' expr ')'
+ { $$ = build_tree_list (build_tree_list ($2, $4), $6); }
;
asm_clobbers:
declspecs_ts setspecs parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
;
/* The first parm, which must suck attributes from off the top of the parser
declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- build_tree_list (prefix_attributes,
- $4));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
;
setspecs_fp:
setspecs
- { prefix_attributes = chainon (prefix_attributes, $<ttype>-2); }
+ { prefix_attributes = chainon (prefix_attributes, $<ttype>-2);
+ all_prefix_attributes = prefix_attributes; }
;
/* This is used in a function definition
finish_protocol(objc_interface_context);
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:
ivar_decl:
declspecs_nosc_ts setspecs ivars
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs ivars
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| error
{ $$ = NULL_TREE; }
;
/* empty */
{ $$ = NULL_TREE; }
| ivar_declarator
- | ivars ',' maybe_setattrs ivar_declarator
+ | ivars ',' maybe_resetattrs ivar_declarator
;
ivar_declarator:
else
add_instance_method (objc_implementation_context, $3);
start_method_def ($3);
- objc_method_context = $3;
}
optarglist
{
compstmt_or_error
{
finish_method_def ();
- objc_method_context = NULL_TREE;
}
;
mydecl:
declspecs_ts setspecs myparms ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts ';'
{ shadow_tag ($1); }
| declspecs_nots ';'
parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- build_tree_list (prefix_attributes,
- $2)); }
+ chainon ($2, all_prefix_attributes)); }
| notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- build_tree_list (prefix_attributes,
- $2)); }
+ chainon ($2, all_prefix_attributes)); }
| absdcl_maybe_attribute
{ $$ = $1; }
;
selector:
IDENTIFIER
- | TYPENAME
- | OBJECTNAME
+ | TYPENAME
+ | CLASSNAME
+ | OBJECTNAME
| reservedwords
;
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__bounded", RID_BOUNDED, 0 },
{ "__bounded__", RID_BOUNDED, 0 },
+ { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
+ { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
{ "volatile", RID_VOLATILE, D_TRAD },
{ "while", RID_WHILE, 0 },
ifobjc
- { "@class", RID_AT_CLASS, D_OBJC },
- { "@compatibility_alias", RID_AT_ALIAS, D_OBJC },
- { "@defs", RID_AT_DEFS, D_OBJC },
- { "@encode", RID_AT_ENCODE, D_OBJC },
- { "@end", RID_AT_END, D_OBJC },
- { "@implementation", RID_AT_IMPLEMENTATION, D_OBJC },
- { "@interface", RID_AT_INTERFACE, D_OBJC },
- { "@private", RID_AT_PRIVATE, D_OBJC },
- { "@protected", RID_AT_PROTECTED, D_OBJC },
- { "@protocol", RID_AT_PROTOCOL, D_OBJC },
- { "@public", RID_AT_PUBLIC, D_OBJC },
- { "@selector", RID_AT_SELECTOR, D_OBJC },
{ "id", RID_ID, D_OBJC },
+
+ /* These objc keywords are recognized only immediately after
+ an '@'. */
+ { "class", RID_AT_CLASS, D_OBJC },
+ { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
+ { "defs", RID_AT_DEFS, D_OBJC },
+ { "encode", RID_AT_ENCODE, D_OBJC },
+ { "end", RID_AT_END, D_OBJC },
+ { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
+ { "interface", RID_AT_INTERFACE, D_OBJC },
+ { "private", RID_AT_PRIVATE, D_OBJC },
+ { "protected", RID_AT_PROTECTED, D_OBJC },
+ { "protocol", RID_AT_PROTOCOL, D_OBJC },
+ { "public", RID_AT_PUBLIC, D_OBJC },
+ { "selector", RID_AT_SELECTOR, D_OBJC },
+
+ /* These are recognized only in protocol-qualifier context
+ (see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
/* RID_PTREXTENT */ PTR_EXTENT,
/* RID_PTRVALUE */ PTR_VALUE,
+ /* RID_CHOOSE_EXPR */ CHOOSE_EXPR,
+ /* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P,
+
/* RID_FUNCTION_NAME */ STRING_FUNC_NAME,
/* RID_PRETTY_FUNCTION_NAME */ STRING_FUNC_NAME,
/* RID_C99_FUNCTION_NAME */ VAR_FUNC_NAME,
/* RID_AT_IMPLEMENTATION */ IMPLEMENTATION
};
-ifobjc
-/* Lookup table for ObjC keywords beginning with '@'. Crude but
- hopefully effective. */
-#define N_at_reswords ((int) RID_AT_IMPLEMENTATION - (int)RID_AT_ENCODE + 1)
-static tree objc_rid_sans_at[N_at_reswords];
-end ifobjc
-
static void
init_reswords ()
{
C_RID_CODE (id) = reswords[i].rid;
C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) reswords[i].rid] = id;
-
-ifobjc
- /* Enter ObjC @-prefixed keywords into the "sans" table
- _without_ their leading at-sign. Again, all these
- identifiers are reachable by the get_identifer table, so it's
- not necessary to make objc_rid_sans_at a GC root. */
- if (reswords[i].word[0] == '@')
- objc_rid_sans_at[(int) reswords[i].rid - (int) RID_AT_ENCODE]
- = get_identifier (reswords[i].word + 1);
-end ifobjc
}
}
-const char *
-init_parse (filename)
- const char *filename;
-{
- add_c_tree_codes ();
-
- /* Make identifier nodes long enough for the language-specific slots. */
- set_identifier_size (sizeof (struct lang_identifier));
-
- init_reswords ();
- init_pragma ();
-
- return init_c_lex (filename);
-}
-
-void
-finish_parse ()
-{
- cpp_finish (parse_in);
- /* Call to cpp_destroy () omitted for performance reasons. */
- errorcount += cpp_errors (parse_in);
-}
-
#define NAME(type) cpp_type2name (type)
static void
else if (last_token == CPP_CHAR || last_token == CPP_WCHAR)
{
unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
- const char *ell = (last_token == CPP_CHAR) ? "" : "L";
+ const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
if (val <= UCHAR_MAX && ISGRAPH (val))
error ("%s before %s'%c'", string, ell, val);
else
else if (last_token == CPP_STRING
|| last_token == CPP_WSTRING)
error ("%s before string constant", string);
- else if (last_token == CPP_NUMBER
- || last_token == CPP_INT
- || last_token == CPP_FLOAT)
+ else if (last_token == CPP_NUMBER)
error ("%s before numeric constant", string);
else if (last_token == CPP_NAME)
error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype));
yylexname ()
{
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))
{
enum rid rid_code = C_RID_CODE (yylval.ttype);
ifobjc
- if (!((unsigned int) rid_code - (unsigned int) RID_FIRST_PQ < 6)
- || objc_pq_context)
+ /* 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)
+ && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
end ifobjc
{
int yycode = rid_to_yy[(int) rid_code];
const char *name = fname_string (rid_code);
yylval.ttype = build_string (strlen (name) + 1, name);
+ C_ARTIFICIAL_STRING_P (yylval.ttype) = 1;
last_token = CPP_STRING; /* so yyerror won't choke */
return STRING;
}
else
{
tree objc_interface_decl = is_class_name (yylval.ttype);
-
- if (objc_interface_decl)
+ /* ObjC class names are in the same namespace as variables and
+ typedefs, and hence are shadowed by local declarations. */
+ if (objc_interface_decl
+ && (global_bindings_p ()
+ || (!objc_force_identifier && !decl)))
{
yylval.ttype = objc_interface_decl;
return CLASSNAME;
{
get_next:
last_token = c_lex (&yylval.ttype);
-ifobjc
- reconsider:
-end ifobjc
switch (last_token)
{
case CPP_EQ: return '=';
case CPP_AND_AND: return ANDAND;
case CPP_OR_OR: return OROR;
case CPP_QUERY: return '?';
- case CPP_COLON: return ':';
- case CPP_COMMA: return ',';
case CPP_OPEN_PAREN: return '(';
- case CPP_CLOSE_PAREN: return ')';
case CPP_EQ_EQ: yylval.code = EQ_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_CLOSE_SQUARE: return ']';
case CPP_OPEN_BRACE: return '{';
case CPP_CLOSE_BRACE: return '}';
- case CPP_SEMICOLON: return ';';
case CPP_ELLIPSIS: return ELLIPSIS;
case CPP_PLUS_PLUS: return PLUSPLUS;
case CPP_DEREF: return POINTSAT;
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:
- if (cpp_pop_buffer (parse_in) == 0)
- return 0;
- goto get_next;
+ return 0;
case CPP_NAME:
return yylexname ();
- case CPP_INT:
- case CPP_FLOAT:
case CPP_NUMBER:
case CPP_CHAR:
case CPP_WCHAR:
case CPP_WSTRING:
return STRING;
- /* This token is Objective-C specific. It gives the next
- token special significance. */
+ /* This token is Objective-C specific. It gives the next token
+ special significance. */
case CPP_ATSIGN:
ifobjc
- last_token = c_lex (&yylval.ttype);
- if (last_token == CPP_STRING)
- return OBJC_STRING;
- else if (last_token == CPP_NAME)
- {
- int i;
- for (i = 0; i < N_at_reswords; i++)
- if (objc_rid_sans_at[i] == yylval.ttype)
- {
- int rid_code = i + (int) RID_AT_ENCODE;
- yylval.ttype = ridpointers[rid_code];
- return rid_to_yy[rid_code];
- }
- }
- error ("syntax error at '@' token");
- goto reconsider;
+ {
+ tree after_at;
+ enum cpp_ttype after_at_type;
+
+ after_at_type = c_lex (&after_at);
+
+ if (after_at_type == CPP_NAME
+ && C_IS_RESERVED_WORD (after_at)
+ && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
+ {
+ yylval.ttype = after_at;
+ last_token = after_at_type;
+ return rid_to_yy [(int) C_RID_CODE (after_at)];
+ }
+ _cpp_backup_tokens (parse_in, 1);
+ return '@';
+ }
end ifobjc
+
/* These tokens are C++ specific (and will not be generated
in C mode, but let's be cautious). */
case CPP_SCOPE:
in order to build the compiler. */
void
-set_yydebug (value)
+c_set_yydebug (value)
int value;
{
#if YYDEBUG != 0
yydebug = value;
#else
- warning ("YYDEBUG not defined.");
+ warning ("YYDEBUG not defined");
#endif
}
/* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains.
- TYPE_QUALS is a list of modifiers such as const or volatile
- to apply to the pointer type, represented as identifiers.
+ TYPE_QUALS_ATTRS is a list of modifiers such as const or volatile
+ to apply to the pointer type, represented as identifiers, possible mixed
+ with attributes.
- We return an INDIRECT_REF whose "contents" are TARGET
- and whose type is the modifier list. */
+ We return an INDIRECT_REF whose "contents" are TARGET (inside a TREE_LIST,
+ if attributes are present) and whose type is the modifier list. */
tree
-make_pointer_declarator (type_quals, target)
- tree type_quals, target;
+make_pointer_declarator (type_quals_attrs, target)
+ tree type_quals_attrs, target;
{
- return build1 (INDIRECT_REF, type_quals, target);
+ tree quals, attrs;
+ tree itarget = target;
+ split_specs_attrs (type_quals_attrs, &quals, &attrs);
+ if (attrs != NULL_TREE)
+ itarget = tree_cons (attrs, target, NULL_TREE);
+ return build1 (INDIRECT_REF, quals, itarget);
}