From: Mark Mitchell Date: Thu, 24 Jun 2004 06:48:44 +0000 (+0000) Subject: Make-lang.in (cp/lex.o): Do not depend on cp/lex.h. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=62d1db179e700aeb45e805aa81de54036745f93e;p=gcc.git Make-lang.in (cp/lex.o): Do not depend on cp/lex.h. * Make-lang.in (cp/lex.o): Do not depend on cp/lex.h. (cp/decl.o): Likewise. (cp/decl2.o): Likewise. (cp/pt.o): Likewise. (cp/semantics.o): Likewise. * config-lang.in (gtfiles): Do not reference cp/lex.h. * class.c: Do not include lex.h. (add_implicitly_declared_members): Do not use adding_implicit_members. (check_bases_and_members): Do not talk about grok_x_components. * cp/cp-tree.h (adding_implicit_members): Remove. (cp_storage_class): New type. (cp_decl_spec): Likewise. (cp_decl_specifier_seq): Likewise. (cp_parameter_declarator): Use it for the decl_specifiers field. (check_tag_decl): Adjust prototype. (shadow_tag): Likewise. (groktypename): Likewise. (start_decl): Likewise. (start_function): Likewise. (start_method): Likewise. (grok_x_components): Remove. (grokfield): Adjust prototype. (grokbitfield): Likewise. (finish_member_class_template): Remove. * decl.c: Do not include lex.h. (adding_implicit_members): Do not define. (check_tag_decl): Do not use trees to represent decl-specifiers. (shadow_tag): Likewise. (groktypename): Likewise. (start_decl): Likewise. (grokvardecl): Likewise. (grokdeclarator): Likewise. (grokparms): Likewise. (start_function): Likewise. (start_method): Likewise. * decl.h (grokdeclarator): Adjust prototype. * decl2.c: Do not include lex.h. (grok_x_components): Remove. (grokfield): Do not use trees to represent decl-specifiers. (grokbitfield): Likewise. * lex.c: Do not include lex.h. * lex.h: Remove. * parser.c: Include target.h. (clear_decl_specs): New function. (cp_parser_translation_unit): Do not use trees to represent decl-specifiers. (cp_parser_postfix_expression): Likewise. (cp_parser_new_type_id): Likewise. (cp_parser_condition): Likewise. (cp_parser_simple_declaration): Likewise. (cp_parser_decl_specifier_seq): Likewise. (cp_parser_function_specifier_opt): Likewise. (cp_parser_conversion_type_id): Likewise. (cp_parser_template_parameter): Likewise. (cp_parser_explicit_instantiation): Likewise. (cp_parser_type_specifier): Likewise. (cp_parser_simple_type_specifier): Likewise. (cp_parser_init_declarator): Likewise. (cp_parser_type_id): Likewise. (cp_parser_type_specifier_seq): Likewise. (cp_parser_parameter_declaration): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_exception_declaration): Likewise. (cp_parser_function_definition_from_specifiers_and_declarator): Likewise. (cp_parser_single_declaration): Likewise. (cp_parser_save_member_function_body): Likewise. (cp_parser_friend_p): Likewise. (cp_parser_set_storage_class): New function. (cp_parser_set_decl_spec_type): Likewise. * pt.c: Do not include lex.h. * semantics.c: Likewise. (finish_member_class_template): Remove. From-SVN: r83584 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 531df512e79..5a18b461705 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,80 @@ +2004-06-23 Mark Mitchell + + * Make-lang.in (cp/lex.o): Do not depend on cp/lex.h. + (cp/decl.o): Likewise. + (cp/decl2.o): Likewise. + (cp/pt.o): Likewise. + (cp/semantics.o): Likewise. + * config-lang.in (gtfiles): Do not reference cp/lex.h. + * class.c: Do not include lex.h. + (add_implicitly_declared_members): Do not use + adding_implicit_members. + (check_bases_and_members): Do not talk about grok_x_components. + * cp/cp-tree.h (adding_implicit_members): Remove. + (cp_storage_class): New type. + (cp_decl_spec): Likewise. + (cp_decl_specifier_seq): Likewise. + (cp_parameter_declarator): Use it for the decl_specifiers field. + (check_tag_decl): Adjust prototype. + (shadow_tag): Likewise. + (groktypename): Likewise. + (start_decl): Likewise. + (start_function): Likewise. + (start_method): Likewise. + (grok_x_components): Remove. + (grokfield): Adjust prototype. + (grokbitfield): Likewise. + (finish_member_class_template): Remove. + * decl.c: Do not include lex.h. + (adding_implicit_members): Do not define. + (check_tag_decl): Do not use trees to represent decl-specifiers. + (shadow_tag): Likewise. + (groktypename): Likewise. + (start_decl): Likewise. + (grokvardecl): Likewise. + (grokdeclarator): Likewise. + (grokparms): Likewise. + (start_function): Likewise. + (start_method): Likewise. + * decl.h (grokdeclarator): Adjust prototype. + * decl2.c: Do not include lex.h. + (grok_x_components): Remove. + (grokfield): Do not use trees to represent decl-specifiers. + (grokbitfield): Likewise. + * lex.c: Do not include lex.h. + * lex.h: Remove. + * parser.c: Include target.h. + (clear_decl_specs): New function. + (cp_parser_translation_unit): Do not use trees to represent + decl-specifiers. + (cp_parser_postfix_expression): Likewise. + (cp_parser_new_type_id): Likewise. + (cp_parser_condition): Likewise. + (cp_parser_simple_declaration): Likewise. + (cp_parser_decl_specifier_seq): Likewise. + (cp_parser_function_specifier_opt): Likewise. + (cp_parser_conversion_type_id): Likewise. + (cp_parser_template_parameter): Likewise. + (cp_parser_explicit_instantiation): Likewise. + (cp_parser_type_specifier): Likewise. + (cp_parser_simple_type_specifier): Likewise. + (cp_parser_init_declarator): Likewise. + (cp_parser_type_id): Likewise. + (cp_parser_type_specifier_seq): Likewise. + (cp_parser_parameter_declaration): Likewise. + (cp_parser_member_declaration): Likewise. + (cp_parser_exception_declaration): Likewise. + (cp_parser_function_definition_from_specifiers_and_declarator): + Likewise. + (cp_parser_single_declaration): Likewise. + (cp_parser_save_member_function_body): Likewise. + (cp_parser_friend_p): Likewise. + (cp_parser_set_storage_class): New function. + (cp_parser_set_decl_spec_type): Likewise. + * pt.c: Do not include lex.h. + * semantics.c: Likewise. + (finish_member_class_template): Remove. + 2004-06-23 Roger Sayle * call.c (build_cxx_call): Don't call expand_tree_builtin. No diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index a928c389213..997b8aac4a8 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -216,15 +216,15 @@ CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h c-common.h \ CXX_PRETTY_PRINT_H = cp/cxx-pretty-print.h $(C_PRETTY_PRINT_H) -cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h \ +cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h \ c-pragma.h toplev.h output.h input.h cp/operators.def $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h langhooks.h \ $(LANGHOOKS_DEF_H) c-common.h $(CXX_PRETTY_PRINT_H) $(DIAGNOSTIC_H) -cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \ +cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/decl.h stack.h \ output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \ cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \ debug.h gt-cp-decl.h gtype-cp.h timevar.h $(TREE_FLOW_H) -cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ +cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/decl.h $(EXPR_H) \ output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h cgraph.h cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \ diagnostic.h @@ -248,13 +248,13 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev. cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \ except.h $(TM_P_H) -cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/lex.h \ +cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h \ toplev.h $(RTL_H) except.h tree-inline.h gt-cp-pt.h cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \ flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \ gt-cp-repo.h -cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h \ +cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \ flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \ tree-inline.h cgraph.h cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d58577f496f..c2d654123f5 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "output.h" #include "toplev.h" -#include "lex.h" #include "target.h" #include "convert.h" @@ -2624,8 +2623,6 @@ add_implicitly_declared_members (tree t, tree virtual_dtor = NULL_TREE; tree *f; - ++adding_implicit_members; - /* Destructor. */ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t)) { @@ -2700,8 +2697,6 @@ add_implicitly_declared_members (tree t, *f = TYPE_METHODS (t); TYPE_METHODS (t) = implicit_fns; } - - --adding_implicit_members; } /* Subroutine of finish_struct_1. Recursively count the number of fields @@ -4206,8 +4201,7 @@ check_bases_and_members (tree t) TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t); - /* Synthesize any needed methods. Note that methods will be synthesized - for anonymous unions; grok_x_components undoes that. */ + /* Synthesize any needed methods. */ add_implicitly_declared_members (t, cant_have_default_ctor, cant_have_const_ctor, no_const_asn_ref); diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index f3037dcca6a..0d0c38f0f42 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" target_libs="target-libstdc++-v3 target-gperf" -gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-lex.c \$(srcdir)/c-pragma.c" +gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-lex.c \$(srcdir)/c-pragma.c" diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9638c2db84e..ecd9b183802 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3082,11 +3082,6 @@ typedef enum base_kind { binfo. */ } base_kind; -/* Set by add_implicitly_declared_members() to keep those members from - being flagged as deprecated or reported as using deprecated - types. */ -extern int adding_implicit_members; - /* in decl{2}.c */ /* A node that is a list (length 1) of error_mark_nodes. */ extern GTY(()) tree error_mark_list; @@ -3508,6 +3503,74 @@ extern GTY(()) operator_name_info_t operator_name_info extern GTY(()) operator_name_info_t assignment_operator_name_info [(int) LAST_CPLUS_TREE_CODE]; +/* A storage class. */ + +typedef enum cp_storage_class { + /* sc_none must be zero so that zeroing a cp_decl_specifier_seq + sets the storage_class field to sc_none. */ + sc_none = 0, + sc_auto, + sc_register, + sc_static, + sc_extern, + sc_mutable, +} cp_storage_class; + +/* An individual decl-specifier. */ + +typedef enum cp_decl_spec { + ds_first, + ds_signed = ds_first, + ds_unsigned, + ds_short, + ds_long, + ds_const, + ds_volatile, + ds_restrict, + ds_inline, + ds_virtual, + ds_explicit, + ds_friend, + ds_typedef, + ds_complex, + ds_thread, + ds_last +} cp_decl_spec; + +/* A decl-specifier-seq. */ + +typedef struct cp_decl_specifier_seq { + /* The number of times each of the keywords has been seen. */ + unsigned specs[(int) ds_last]; + /* The primary type, if any, given by the decl-specifier-seq. + Modifiers, like "short", "const", and "unsigned" are not + reflected here. This field will be a TYPE, unless a typedef-name + was used, in which case it will be a TYPE_DECL. */ + tree type; + /* The attributes, if any, provided with the specifier sequence. */ + tree attributes; + /* If non-NULL, a built-in type that the user attempted to redefine + to some other type. */ + tree redefined_builtin_type; + /* The storage class specified -- or sc_none if no storage class was + explicitly specified. */ + cp_storage_class storage_class; + /* True iff TYPE_SPEC indicates a user-defined type. */ + BOOL_BITFIELD user_defined_type_p : 1; + /* True iff multiple types were (erroneously) specified for this + decl-specifier-seq. */ + BOOL_BITFIELD multiple_types_p : 1; + /* True iff multiple storage classes were (erroneously) specified + for this decl-specifier-seq. */ + BOOL_BITFIELD multiple_storage_classes_p : 1; + /* True iff at least one decl-specifier was found. */ + BOOL_BITFIELD any_specifiers_p : 1; + /* True iff "int" was explicitly provided. */ + BOOL_BITFIELD explicit_int_p : 1; + /* True iff "char" was explicitly provided. */ + BOOL_BITFIELD explicit_char_p : 1; +} cp_decl_specifier_seq; + /* The various kinds of declarators. */ typedef enum cp_declarator_kind { @@ -3531,7 +3594,7 @@ struct cp_parameter_declarator { /* The next parameter, or NULL_TREE if none. */ cp_parameter_declarator *next; /* The decl-specifiers-seq for the parameter. */ - tree decl_specifiers; + cp_decl_specifier_seq decl_specifiers; /* The declarator for the parameter. */ cp_declarator *declarator; /* The default-argument expression, or NULL_TREE, if none. */ @@ -3735,10 +3798,10 @@ extern tree push_library_fn (tree, tree); extern tree push_void_library_fn (tree, tree); extern tree push_throw_library_fn (tree, tree); extern int init_type_desc (void); -extern tree check_tag_decl (tree); -extern tree shadow_tag (tree); -extern tree groktypename (tree, const cp_declarator *); -extern tree start_decl (const cp_declarator *, tree, int, tree, tree); +extern tree check_tag_decl (cp_decl_specifier_seq *); +extern tree shadow_tag (cp_decl_specifier_seq *); +extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *); +extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree); extern void start_decl_1 (tree); extern void cp_finish_decl (tree, tree, tree, int); extern void finish_decl (tree, tree, tree); @@ -3759,11 +3822,11 @@ extern tree start_enum (tree); extern void finish_enum (tree); extern void build_enumerator (tree, tree, tree); extern void start_preparsed_function (tree, tree, int); -extern int start_function (tree, const cp_declarator *, tree); +extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); extern tree begin_function_body (void); extern void finish_function_body (tree); extern tree finish_function (int); -extern tree start_method (tree, const cp_declarator *, tree); +extern tree start_method (cp_decl_specifier_seq *, const cp_declarator *, tree); extern tree finish_method (tree); extern void maybe_register_incomplete_var (tree); extern void complete_vars (tree); @@ -3804,7 +3867,6 @@ extern bool have_extern_spec; /* in decl2.c */ extern bool check_java_method (tree); extern int grok_method_quals (tree, tree, tree); -extern void grok_x_components (tree); extern void maybe_retrofit_in_chrg (tree); extern void maybe_make_one_only (tree); extern void grokclassfn (tree, tree, enum overload_flags, tree); @@ -3812,8 +3874,8 @@ extern tree grok_array_decl (tree, tree); extern tree delete_sanity (tree, tree, bool, int); extern tree check_classfn (tree, tree, tree); extern void check_member_template (tree); -extern tree grokfield (const cp_declarator *, tree, tree, tree, tree); -extern tree grokbitfield (const cp_declarator *, tree, tree); +extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *, tree, tree, tree); +extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *, tree); extern tree groktypefield (tree, tree); extern void cplus_decl_attributes (tree *, tree, int); extern void finish_anon_union (tree); @@ -4157,7 +4219,6 @@ extern tree finish_template_type_parm (tree, tree); extern tree finish_template_template_parm (tree, tree); extern tree begin_class_definition (tree); extern void finish_default_args (void); -extern tree finish_member_class_template (tree); extern void finish_template_decl (tree); extern tree finish_template_type (tree, tree, int); extern tree finish_base_specifier (tree, tree, bool); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 66f6b36e9fe..e986cb7aa7c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -39,7 +39,6 @@ Boston, MA 02111-1307, USA. */ #include "cp-tree.h" #include "tree-inline.h" #include "decl.h" -#include "lex.h" #include "output.h" #include "except.h" #include "toplev.h" @@ -53,7 +52,7 @@ Boston, MA 02111-1307, USA. */ #include "timevar.h" #include "tree-flow.h" -static tree grokparms (const cp_parameter_declarator *, tree *); +static tree grokparms (cp_parameter_declarator *, tree *); static const char *redeclaration_error_message (tree, tree); static int decl_jump_unsafe (tree); @@ -65,7 +64,7 @@ static tree grok_reference_init (tree, tree, tree, tree *); static tree grokfndecl (tree, tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree); -static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree); +static tree grokvardecl (tree, tree, cp_decl_specifier_seq *, int, int, tree); static void record_unknown_type (tree, const char *); static tree builtin_function_1 (const char *, tree, tree, int, enum built_in_class, const char *, @@ -242,11 +241,6 @@ enum deprecated_states { static enum deprecated_states deprecated_state = DEPRECATED_NORMAL; -/* Set by add_implicitly_declared_members() to keep those members from - being flagged as deprecated or reported as using deprecated - types. */ -int adding_implicit_members = 0; - /* True if a declaration with an `extern' linkage specifier is being processed. */ bool have_extern_spec; @@ -3410,13 +3404,10 @@ fixup_anonymous_aggr (tree t) Returns the type declared; or NULL_TREE if none. */ tree -check_tag_decl (tree declspecs) +check_tag_decl (cp_decl_specifier_seq *declspecs) { - int found_type = 0; - int saw_friend = 0; - int saw_typedef = 0; - tree ob_modifier = NULL_TREE; - tree link; + int saw_friend = declspecs->specs[(int)ds_friend] != 0; + int saw_typedef = declspecs->specs[(int)ds_typedef] != 0; /* If a class, struct, or enum type is declared by the DECLSPECS (i.e, if a class-specifier, enum-specifier, or non-typename elaborated-type-specifier appears in the DECLSPECS), @@ -3424,59 +3415,23 @@ check_tag_decl (tree declspecs) tree declared_type = NULL_TREE; bool error_p = false; - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - tree value = TREE_VALUE (link); - - if (TYPE_P (value) || TREE_CODE (value) == TYPE_DECL - || (TREE_CODE (value) == IDENTIFIER_NODE - && is_typename_at_global_scope (value))) - { - ++found_type; - - if (found_type == 2 && TREE_CODE (value) == IDENTIFIER_NODE) - { - if (! in_system_header) - pedwarn ("redeclaration of C++ built-in type `%T'", value); - return NULL_TREE; - } - - if (TYPE_P (value) - && ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value)) - || TREE_CODE (value) == ENUMERAL_TYPE)) - { - my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); - declared_type = value; - } - } - else if (value == ridpointers[(int) RID_TYPEDEF]) - saw_typedef = 1; - else if (value == ridpointers[(int) RID_FRIEND]) - { - if (current_class_type == NULL_TREE - || current_scope () != current_class_type) - ob_modifier = value; - else - saw_friend = 1; - } - else if (value == ridpointers[(int) RID_STATIC] - || value == ridpointers[(int) RID_EXTERN] - || value == ridpointers[(int) RID_AUTO] - || value == ridpointers[(int) RID_REGISTER] - || value == ridpointers[(int) RID_INLINE] - || value == ridpointers[(int) RID_VIRTUAL] - || value == ridpointers[(int) RID_CONST] - || value == ridpointers[(int) RID_VOLATILE] - || value == ridpointers[(int) RID_EXPLICIT] - || value == ridpointers[(int) RID_THREAD]) - ob_modifier = value; - else if (value == error_mark_node) - error_p = true; - } - - if (found_type > 1) + if (declspecs->multiple_types_p) error ("multiple types in one declaration"); + else if (declspecs->redefined_builtin_type) + { + if (!in_system_header) + pedwarn ("redeclaration of C++ built-in type", + declspecs->redefined_builtin_type); + return NULL_TREE; + } + if (TYPE_P (declspecs->type) + && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE + && IS_AGGR_TYPE (declspecs->type)) + || TREE_CODE (declspecs->type) == ENUMERAL_TYPE)) + declared_type = declspecs->type; + else if (declspecs->type == error_mark_node) + error_p = true; if (declared_type == NULL_TREE && ! saw_friend && !error_p) pedwarn ("declaration does not declare anything"); /* Check for an anonymous union. */ @@ -3512,19 +3467,28 @@ check_tag_decl (tree declspecs) pedwarn ("ISO C++ prohibits anonymous structs"); } - else if (ob_modifier) + else { - if (ob_modifier == ridpointers[(int) RID_INLINE] - || ob_modifier == ridpointers[(int) RID_VIRTUAL]) - error ("`%D' can only be specified for functions", ob_modifier); - else if (ob_modifier == ridpointers[(int) RID_FRIEND]) - error ("`%D' can only be specified inside a class", ob_modifier); - else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) - error ("`%D' can only be specified for constructors", - ob_modifier); - else - error ("`%D' can only be specified for objects and functions", - ob_modifier); + if (declspecs->specs[(int)ds_inline] + || declspecs->specs[(int)ds_virtual]) + error ("`%s' can only be specified for functions", + declspecs->specs[(int)ds_inline] + ? "inline" : "virtual"); + else if (saw_friend + && (!current_class_type + || current_scope () != current_class_type)) + error ("`friend' can only be specified inside a class"); + else if (declspecs->specs[(int)ds_explicit]) + error ("`explicit' can only be specified for constructors"); + else if (declspecs->storage_class) + error ("a storage class can only be specified for objects " + "and functions"); + else if (declspecs->specs[(int)ds_const] + || declspecs->specs[(int)ds_volatile] + || declspecs->specs[(int)ds_restrict] + || declspecs->specs[(int)ds_thread]) + error ("qualifiers can only be specified for objects " + "and functions"); } return declared_type; @@ -3544,7 +3508,7 @@ check_tag_decl (tree declspecs) Returns the TYPE declared -- or NULL_TREE if none. */ tree -shadow_tag (tree declspecs) +shadow_tag (cp_decl_specifier_seq *declspecs) { tree t = check_tag_decl (declspecs); @@ -3576,12 +3540,14 @@ shadow_tag (tree declspecs) /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ tree -groktypename (tree type_specifiers, const cp_declarator *declarator) +groktypename (cp_decl_specifier_seq *type_specifiers, + const cp_declarator *declarator) { - tree specs, attrs; + tree attrs; tree type; - split_specs_attrs (type_specifiers, &specs, &attrs); - type = grokdeclarator (declarator, specs, TYPENAME, 0, &attrs); + attrs = type_specifiers->attributes; + type_specifiers->attributes = NULL_TREE; + type = grokdeclarator (declarator, type_specifiers, TYPENAME, 0, &attrs); if (attrs) cplus_decl_attributes (&type, attrs, 0); return type; @@ -3604,7 +3570,7 @@ groktypename (tree type_specifiers, const cp_declarator *declarator) tree start_decl (const cp_declarator *declarator, - tree declspecs, + cp_decl_specifier_seq *declspecs, int initialized, tree attributes, tree prefix_attributes) @@ -3616,8 +3582,7 @@ start_decl (const cp_declarator *declarator, /* This should only be done once on the top most decl. */ if (have_extern_spec) { - declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), - declspecs); + declspecs->storage_class = sc_extern; have_extern_spec = false; } @@ -5758,25 +5723,22 @@ grokfndecl (tree ctype, static tree grokvardecl (tree type, tree name, - RID_BIT_TYPE * specbits_in, + cp_decl_specifier_seq *declspecs, int initialized, int constp, tree scope) { tree decl; - RID_BIT_TYPE specbits; my_friendly_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE, 20020808); - specbits = *specbits_in; - /* Compute the scope in which to place the variable. */ if (!scope) { /* An explicit "extern" specifier indicates a namespace-scope variable. */ - if (RIDBIT_SETP (RID_EXTERN, specbits)) + if (declspecs->storage_class == sc_extern) scope = current_namespace; else if (!at_function_scope_p ()) { @@ -5805,7 +5767,7 @@ grokvardecl (tree type, else DECL_CONTEXT (decl) = scope; - if (RIDBIT_SETP (RID_EXTERN, specbits)) + if (declspecs->storage_class == sc_extern) { DECL_THIS_EXTERN (decl) = 1; DECL_EXTERNAL (decl) = !initialized; @@ -5823,18 +5785,18 @@ grokvardecl (tree type, (perhaps tentative), and absence of `static' makes it public. */ else if (toplevel_bindings_p ()) { - TREE_PUBLIC (decl) = (RIDBIT_NOTSETP (RID_STATIC, specbits) + TREE_PUBLIC (decl) = (declspecs->storage_class != sc_static && (DECL_THIS_EXTERN (decl) || ! constp)); TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); } /* Not at top level, only `static' makes a static definition. */ else { - TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits); + TREE_STATIC (decl) = declspecs->storage_class == sc_static; TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } - if (RIDBIT_SETP (RID_THREAD, specbits)) + if (declspecs->specs[(int)ds_thread]) { if (targetm.have_tls) DECL_THREAD_LOCAL (decl) = 1; @@ -6292,14 +6254,11 @@ check_special_function_return_type (special_function_kind sfk, tree grokdeclarator (const cp_declarator *declarator, - tree declspecs, + cp_decl_specifier_seq *declspecs, enum decl_context decl_context, int initialized, tree* attrlist) { - RID_BIT_TYPE specbits; - int nclasses = 0; - tree spec; tree type = NULL_TREE; int longlong = 0; int type_quals; @@ -6307,7 +6266,6 @@ grokdeclarator (const cp_declarator *declarator, int explicit_int = 0; int explicit_char = 0; int defaulted_int = 0; - int extern_langp = 0; tree dependant_name = NULL_TREE; tree typedef_decl = NULL_TREE; @@ -6348,8 +6306,8 @@ grokdeclarator (const cp_declarator *declarator, this value will be NULL_TREE, even if the entity is located at namespace scope. */ tree in_namespace = NULL_TREE; + cp_decl_spec ds; - RIDBIT_RESET_ALL (specbits); if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; else if (decl_context == MEMFUNCDEF) @@ -6503,7 +6461,7 @@ grokdeclarator (const cp_declarator *declarator, if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG) && innermost_code != cdk_function - && ! (ctype && declspecs == NULL_TREE)) + && ! (ctype && !declspecs->any_specifiers_p)) { error ("declaration of `%D' as non-function", dname); return void_type_node; @@ -6535,143 +6493,59 @@ grokdeclarator (const cp_declarator *declarator, if (name == NULL) name = decl_context == PARM ? "parameter" : "type name"; - /* Look through the decl specs and record which ones appear. - Some typespecs are defined as built-in typenames. - Others, the ones that are modifiers of other types, - are represented by bits in SPECBITS: set the bits for - the modifiers that appear. Storage class keywords are also in SPECBITS. - - If there is a typedef name or a type, store the type in TYPE. - This includes builtin typedefs such as `int'. - - Set EXPLICIT_INT if the type is `int' or `char' and did not - come from a user typedef. - - Set LONGLONG if `long' is mentioned twice. - - For C++, constructors and destructors have their own fast treatment. */ - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) + /* If there were multiple types specified in the decl-specifier-seq, + issue an error message. */ + if (declspecs->multiple_types_p) + error ("two or more data types in declaration of `%s'", name); + /* Extract the basic type from the decl-specifier-seq. */ + type = declspecs->type; + if (type == error_mark_node) + type = NULL_TREE; + /* If the entire declaration is itself tagged as deprecated then + suppress reports of deprecated items. */ + if (type && TREE_DEPRECATED (type) + && deprecated_state != DEPRECATED_SUPPRESS) + warn_deprecated_use (type); + if (type && TREE_CODE (type) == TYPE_DECL) { - int i; - tree id; - - /* Certain parse errors slip through. For example, - `int class;' is not caught by the parser. Try - weakly to recover here. */ - if (TREE_CODE (spec) != TREE_LIST) - return 0; - - id = TREE_VALUE (spec); - - /* If the entire declaration is itself tagged as deprecated then - suppress reports of deprecated items. */ - if (!adding_implicit_members && id && TREE_DEPRECATED (id)) - { - if (deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (id); - } - - if (TREE_CODE (id) == IDENTIFIER_NODE) - { - if (id == ridpointers[(int) RID_INT] - || id == ridpointers[(int) RID_CHAR] - || id == ridpointers[(int) RID_BOOL] - || id == ridpointers[(int) RID_WCHAR]) - { - if (type) - { - if (id == ridpointers[(int) RID_BOOL]) - error ("`bool' is now a keyword"); - else - error ("extraneous `%T' ignored", id); - } - else - { - if (id == ridpointers[(int) RID_INT]) - explicit_int = 1; - else if (id == ridpointers[(int) RID_CHAR]) - explicit_char = 1; - type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); - } - goto found; - } - /* C++ aggregate types. */ - if (IDENTIFIER_HAS_TYPE_VALUE (id)) - { - if (type) - error ("multiple declarations `%T' and `%T'", type, id); - else - type = IDENTIFIER_TYPE_VALUE (id); - goto found; - } - - for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++) - { - if (ridpointers[i] == id) - { - if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits)) - { - if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ISO C++ does not support `long long'"); - if (longlong) - error ("`long long long' is too long for GCC"); - else - longlong = 1; - } - else if (RIDBIT_SETP (i, specbits)) - pedwarn ("duplicate `%E'", id); - - /* Diagnose "__thread extern" or "__thread static". */ - if (RIDBIT_SETP (RID_THREAD, specbits)) - { - if (i == (int)RID_EXTERN) - error ("`__thread' before `extern'"); - else if (i == (int)RID_STATIC) - error ("`__thread' before `static'"); - } - - if (i == (int)RID_EXTERN - && TREE_PURPOSE (spec) == error_mark_node) - /* This extern was part of a language linkage. */ - extern_langp = 1; + typedef_decl = type; + type = TREE_TYPE (typedef_decl); + } + /* No type at all: default to `int', and set DEFAULTED_INT + because it was not a user-defined typedef. */ + if (type == NULL_TREE + && (declspecs->specs[(int)ds_signed] + || declspecs->specs[(int)ds_unsigned] + || declspecs->specs[(int)ds_long] + || declspecs->specs[(int)ds_short])) + { + /* These imply 'int'. */ + type = integer_type_node; + defaulted_int = 1; + } + /* Gather flags. */ + explicit_int = declspecs->explicit_int_p; + explicit_char = declspecs->explicit_char_p; - RIDBIT_SET (i, specbits); - goto found; - } - } - } - else if (TREE_CODE (id) == TYPE_DECL) - { - if (type) - error ("multiple declarations `%T' and `%T'", type, - TREE_TYPE (id)); - else - { - type = TREE_TYPE (id); - TREE_VALUE (spec) = type; - typedef_decl = id; - } - goto found; - } - if (type) - error ("two or more data types in declaration of `%s'", name); - else if (TREE_CODE (id) == IDENTIFIER_NODE) + /* Check for repeated decl-specifiers. */ + for (ds = ds_first; ds != ds_last; ++ds) + { + unsigned count = declspecs->specs[(int)ds]; + if (count < 2) + continue; + /* The "long" specifier is a special case because of + "long long". */ + if (ds == ds_long) { - tree t = lookup_name (id, 1); - if (!t || TREE_CODE (t) != TYPE_DECL) - error ("`%E' fails to be a typedef or built in type", id); + if (count > 2) + error ("`long long long' is too long for GCC"); + else if (pedantic && !in_system_header && warn_long_long) + pedwarn ("ISO C++ does not support `long long'"); else - { - type = TREE_TYPE (t); - typedef_decl = t; - } - } - else if (id != error_mark_node) - /* Can't change CLASS nodes into RECORD nodes here! */ - type = id; - - found: ; + longlong = 1; + } + else if (declspecs->specs[(int)ds] > 1) + error ("duplicate decl-specifier"); } #if 0 @@ -6681,19 +6555,6 @@ grokdeclarator (const cp_declarator *declarator, #endif typedef_type = type; - /* No type at all: default to `int', and set DEFAULTED_INT - because it was not a user-defined typedef. */ - - if (type == NULL_TREE - && (RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_UNSIGNED, specbits) - || RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits))) - { - /* These imply 'int'. */ - type = integer_type_node; - defaulted_int = 1; - } if (sfk != sfk_none) type = check_special_function_return_type (sfk, type, @@ -6731,21 +6592,20 @@ grokdeclarator (const cp_declarator *declarator, and check for invalid combinations. */ /* Long double is a special combination. */ - - if (RIDBIT_SETP (RID_LONG, specbits) + if (declspecs->specs[(int)ds_long] && TYPE_MAIN_VARIANT (type) == double_type_node) { - RIDBIT_RESET (RID_LONG, specbits); + declspecs->specs[(int)ds_long] = 0; type = build_qualified_type (long_double_type_node, cp_type_quals (type)); } /* Check all other uses of type modifiers. */ - if (RIDBIT_SETP (RID_UNSIGNED, specbits) - || RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) + if (declspecs->specs[(int)ds_unsigned] + || declspecs->specs[(int)ds_signed] + || declspecs->specs[(int)ds_long] + || declspecs->specs[(int)ds_short]) { int ok = 0; @@ -6753,19 +6613,19 @@ grokdeclarator (const cp_declarator *declarator, error ("short, signed or unsigned invalid for `%s'", name); else if (TREE_CODE (type) != INTEGER_TYPE) error ("long, short, signed or unsigned invalid for `%s'", name); - else if (RIDBIT_SETP (RID_LONG, specbits) - && RIDBIT_SETP (RID_SHORT, specbits)) + else if (declspecs->specs[(int)ds_long] + && declspecs->specs[(int)ds_short]) error ("long and short specified together for `%s'", name); - else if ((RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) + else if ((declspecs->specs[(int)ds_long] + || declspecs->specs[(int)ds_short]) && explicit_char) error ("long or short specified with char for `%s'", name); - else if ((RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) + else if ((declspecs->specs[(int)ds_long] + || declspecs->specs[(int)ds_short]) && TREE_CODE (type) == REAL_TYPE) error ("long or short specified with floating type for `%s'", name); - else if (RIDBIT_SETP (RID_SIGNED, specbits) - && RIDBIT_SETP (RID_UNSIGNED, specbits)) + else if (declspecs->specs[(int)ds_signed] + && declspecs->specs[(int)ds_unsigned]) error ("signed and unsigned given together for `%s'", name); else { @@ -6782,24 +6642,24 @@ grokdeclarator (const cp_declarator *declarator, /* Discard the type modifiers if they are invalid. */ if (! ok) { - RIDBIT_RESET (RID_UNSIGNED, specbits); - RIDBIT_RESET (RID_SIGNED, specbits); - RIDBIT_RESET (RID_LONG, specbits); - RIDBIT_RESET (RID_SHORT, specbits); + declspecs->specs[(int)ds_unsigned] = 0; + declspecs->specs[(int)ds_signed] = 0; + declspecs->specs[(int)ds_long] = 0; + declspecs->specs[(int)ds_short] = 0; longlong = 0; } } - if (RIDBIT_SETP (RID_COMPLEX, specbits) + if (declspecs->specs[(int)ds_complex] && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) { error ("complex invalid for `%s'", name); - RIDBIT_RESET (RID_COMPLEX, specbits); + declspecs->specs[(int)ds_complex] = 0; } /* Decide whether an integer type is signed or not. Optionally treat bitfields as signed by default. */ - if (RIDBIT_SETP (RID_UNSIGNED, specbits) + if (declspecs->specs[(int)ds_unsigned] /* [class.bit] It is implementation-defined whether a plain (neither @@ -6809,7 +6669,7 @@ grokdeclarator (const cp_declarator *declarator, Naturally, we extend this to long long as well. Note that this does not include wchar_t. */ || (bitfield && !flag_signed_bitfields - && RIDBIT_NOTSETP (RID_SIGNED, specbits) + && !declspecs->specs[(int)ds_signed] /* A typedef for plain `int' without `signed' can be controlled just like plain `int', but a typedef for `signed int' cannot be so controlled. */ @@ -6821,9 +6681,9 @@ grokdeclarator (const cp_declarator *declarator, { if (longlong) type = long_long_unsigned_type_node; - else if (RIDBIT_SETP (RID_LONG, specbits)) + else if (declspecs->specs[(int)ds_long]) type = long_unsigned_type_node; - else if (RIDBIT_SETP (RID_SHORT, specbits)) + else if (declspecs->specs[(int)ds_short]) type = short_unsigned_type_node; else if (type == char_type_node) type = unsigned_char_type_node; @@ -6832,17 +6692,17 @@ grokdeclarator (const cp_declarator *declarator, else type = unsigned_type_node; } - else if (RIDBIT_SETP (RID_SIGNED, specbits) + else if (declspecs->specs[(int)ds_signed] && type == char_type_node) type = signed_char_type_node; else if (longlong) type = long_long_integer_type_node; - else if (RIDBIT_SETP (RID_LONG, specbits)) + else if (declspecs->specs[(int)ds_long]) type = long_integer_type_node; - else if (RIDBIT_SETP (RID_SHORT, specbits)) + else if (declspecs->specs[(int)ds_short]) type = short_integer_type_node; - if (RIDBIT_SETP (RID_COMPLEX, specbits)) + if (declspecs->specs[(int)ds_complex]) { /* If we just have "complex", it is equivalent to "complex double", but if any modifiers at all are specified it is @@ -6850,10 +6710,10 @@ grokdeclarator (const cp_declarator *declarator, "complex short int". */ if (defaulted_int && ! longlong - && ! (RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits) - || RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_UNSIGNED, specbits))) + && ! (declspecs->specs[(int)ds_long] + || declspecs->specs[(int)ds_short] + || declspecs->specs[(int)ds_signed] + || declspecs->specs[(int)ds_unsigned])) type = complex_double_type_node; else if (type == integer_type_node) type = complex_integer_type_node; @@ -6868,11 +6728,11 @@ grokdeclarator (const cp_declarator *declarator, } type_quals = TYPE_UNQUALIFIED; - if (RIDBIT_SETP (RID_CONST, specbits)) + if (declspecs->specs[(int)ds_const]) type_quals |= TYPE_QUAL_CONST; - if (RIDBIT_SETP (RID_VOLATILE, specbits)) + if (declspecs->specs[(int)ds_volatile]) type_quals |= TYPE_QUAL_VOLATILE; - if (RIDBIT_SETP (RID_RESTRICT, specbits)) + if (declspecs->specs[(int)ds_restrict]) type_quals |= TYPE_QUAL_RESTRICT; if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED) error ("qualifiers are not allowed on declaration of `operator %T'", @@ -6886,13 +6746,11 @@ grokdeclarator (const cp_declarator *declarator, type_quals = cp_type_quals (type); staticp = 0; - inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); - virtualp = !! RIDBIT_SETP (RID_VIRTUAL, specbits); - RIDBIT_RESET (RID_VIRTUAL, specbits); - explicitp = !! RIDBIT_SETP (RID_EXPLICIT, specbits); - RIDBIT_RESET (RID_EXPLICIT, specbits); + inlinep = !! declspecs->specs[(int)ds_inline]; + virtualp = !! declspecs->specs[(int)ds_virtual]; + explicitp = !! declspecs->specs[(int)ds_explicit]; - if (RIDBIT_SETP (RID_STATIC, specbits)) + if (declspecs->storage_class == sc_static) staticp = 1 + (decl_context == FIELD); if (virtualp && staticp == 2) @@ -6901,34 +6759,23 @@ grokdeclarator (const cp_declarator *declarator, dname); staticp = 0; } - friendp = !! RIDBIT_SETP (RID_FRIEND, specbits); - RIDBIT_RESET (RID_FRIEND, specbits); + friendp = !! declspecs->specs[(int)ds_friend]; if (dependant_name && !friendp) { error ("`%T::%D' is not a valid declarator", ctype, dependant_name); return void_type_node; } - - /* Warn if two storage classes are given. Default to `auto'. */ - if (RIDBIT_ANY_SET (specbits)) + /* Issue errors about use of storage classes for parameters. */ + if (decl_context == PARM) { - if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++; - if (RIDBIT_SETP (RID_EXTERN, specbits) && !extern_langp) nclasses++; - if (RIDBIT_SETP (RID_THREAD, specbits)) nclasses++; - if (decl_context == PARM && nclasses > 0) + if (declspecs->specs[(int)ds_typedef]) + error ("typedef declaration invalid in parameter declaration"); + else if (declspecs->storage_class == sc_static + || declspecs->storage_class == sc_extern + || declspecs->specs[(int)ds_thread]) error ("storage class specifiers invalid in parameter declarations"); - if (RIDBIT_SETP (RID_TYPEDEF, specbits)) - { - if (decl_context == PARM) - error ("typedef declaration invalid in parameter declaration"); - nclasses++; - } - if (RIDBIT_SETP (RID_AUTO, specbits)) nclasses++; - if (RIDBIT_SETP (RID_REGISTER, specbits)) nclasses++; - if (!nclasses && !friendp && extern_langp) - nclasses++; } /* Give error if `virtual' is used outside of class declaration. */ @@ -6941,33 +6788,27 @@ grokdeclarator (const cp_declarator *declarator, /* Static anonymous unions are dealt with here. */ if (staticp && decl_context == TYPENAME - && TREE_CODE (declspecs) == TREE_LIST - && ANON_AGGR_TYPE_P (TREE_VALUE (declspecs))) + && declspecs->type + && ANON_AGGR_TYPE_P (declspecs->type)) decl_context = FIELD; /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ - - /* "static __thread" and "extern __thread" are allowed. */ - if (nclasses == 2 - && RIDBIT_SETP (RID_THREAD, specbits) - && (RIDBIT_SETP (RID_EXTERN, specbits) - || RIDBIT_SETP (RID_STATIC, specbits))) - nclasses = 1; - - if (nclasses > 1) + if (declspecs->multiple_storage_classes_p) error ("multiple storage classes in declaration of `%s'", name); - else if (decl_context != NORMAL && nclasses > 0) + else if (decl_context != NORMAL + && declspecs->storage_class != sc_none + && declspecs->storage_class != sc_mutable) { if ((decl_context == PARM || decl_context == CATCHPARM) - && (RIDBIT_SETP (RID_REGISTER, specbits) - || RIDBIT_SETP (RID_AUTO, specbits))) + && (declspecs->storage_class == sc_register + || declspecs->storage_class == sc_auto)) ; - else if (RIDBIT_SETP (RID_TYPEDEF, specbits)) + else if (declspecs->specs[(int)ds_typedef]) ; else if (decl_context == FIELD /* C++ allows static class elements. */ - && RIDBIT_SETP (RID_STATIC, specbits)) + && declspecs->storage_class == sc_static) /* C++ also allows inlines and signed and unsigned elements, but in those cases we don't come in here. */ ; @@ -7005,13 +6846,15 @@ grokdeclarator (const cp_declarator *declarator, else error ("storage class specified for typename"); } - RIDBIT_RESET (RID_REGISTER, specbits); - RIDBIT_RESET (RID_AUTO, specbits); - RIDBIT_RESET (RID_EXTERN, specbits); - RIDBIT_RESET (RID_THREAD, specbits); + if (declspecs->storage_class == sc_register + || declspecs->storage_class == sc_auto + || declspecs->storage_class == sc_extern + || declspecs->specs[(int)ds_thread]) + declspecs->storage_class = sc_none; } } - else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) + else if (declspecs->storage_class == sc_extern && initialized + && !funcdef_flag) { if (toplevel_bindings_p ()) { @@ -7023,24 +6866,24 @@ grokdeclarator (const cp_declarator *declarator, else error ("`%s' has both `extern' and initializer", name); } - else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag + else if (declspecs->storage_class == sc_extern && funcdef_flag && ! toplevel_bindings_p ()) error ("nested function `%s' declared `extern'", name); else if (toplevel_bindings_p ()) { - if (RIDBIT_SETP (RID_AUTO, specbits)) + if (declspecs->storage_class == sc_auto) error ("top-level declaration of `%s' specifies `auto'", name); } - else if (RIDBIT_SETP (RID_THREAD, specbits) - && !RIDBIT_SETP (RID_EXTERN, specbits) - && !RIDBIT_SETP (RID_STATIC, specbits)) + else if (declspecs->specs[(int)ds_thread] + && declspecs->storage_class != sc_extern + && declspecs->storage_class != sc_static) { error ("function-scope `%s' implicitly auto and declared `__thread'", name); - RIDBIT_RESET (RID_THREAD, specbits); + declspecs->specs[(int)ds_thread] = 0; } - if (nclasses > 0 && friendp) + if (declspecs->storage_class && friendp) error ("storage class specifiers invalid in friend function declarations"); if (!id_declarator) @@ -7211,14 +7054,6 @@ grokdeclarator (const cp_declarator *declarator, TREE_VALUE (quals)); quals = NULL_TREE; } - { - RID_BIT_TYPE tmp_bits; - memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE)); - RIDBIT_RESET (RID_INLINE, tmp_bits); - RIDBIT_RESET (RID_STATIC, tmp_bits); - if (RIDBIT_ANY_SET (tmp_bits)) - error ("return value type specifier for constructor ignored"); - } if (decl_context == FIELD) { if (! member_function_or_else (ctype, @@ -7241,7 +7076,6 @@ grokdeclarator (const cp_declarator *declarator, { /* Cannot be both friend and virtual. */ error ("virtual functions cannot be friends"); - RIDBIT_RESET (RID_FRIEND, specbits); friendp = 0; } if (decl_context == NORMAL) @@ -7453,7 +7287,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } } - else if (RIDBIT_SETP (RID_TYPEDEF, specbits) + else if (declspecs->specs[(int)ds_typedef] || COMPLETE_TYPE_P (complete_type (ctype))) { /* Have to move this code elsewhere in this function. @@ -7516,38 +7350,38 @@ grokdeclarator (const cp_declarator *declarator, explicitp = 0; } - if (RIDBIT_SETP (RID_MUTABLE, specbits)) + if (declspecs->storage_class == sc_mutable) { if (decl_context != FIELD || friendp) { error ("non-member `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } - else if (decl_context == TYPENAME || RIDBIT_SETP (RID_TYPEDEF, specbits)) + else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef]) { error ("non-object member `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) { error ("function `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } else if (staticp) { error ("static `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } else if (type_quals & TYPE_QUAL_CONST) { error ("const `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } } /* If this is declaring a typedef name, return a TYPE_DECL. */ - if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME) + if (declspecs->specs[(int)ds_typedef] && decl_context != TYPENAME) { tree decl; @@ -7622,7 +7456,7 @@ grokdeclarator (const cp_declarator *declarator, grok_method_quals (ctype, decl, quals); } - if (RIDBIT_SETP (RID_SIGNED, specbits) + if (declspecs->specs[(int)ds_signed] || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; @@ -7944,8 +7778,8 @@ grokdeclarator (const cp_declarator *declarator, if (current_class_type && TYPE_NAME (current_class_type) && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)) - && declspecs && TREE_VALUE (declspecs) - && TREE_TYPE (TREE_VALUE (declspecs)) == type) + && declspecs->type + && declspecs->type == type) error (" in instantiation of template `%T'", current_class_type); @@ -8039,10 +7873,10 @@ grokdeclarator (const cp_declarator *declarator, { decl = build_decl (FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; - if (RIDBIT_SETP (RID_MUTABLE, specbits)) + if (declspecs->storage_class == sc_mutable) { DECL_MUTABLE_P (decl) = 1; - RIDBIT_RESET (RID_MUTABLE, specbits); + declspecs->storage_class = sc_none; } } @@ -8064,25 +7898,25 @@ grokdeclarator (const cp_declarator *declarator, else original_name = unqualified_id; - if (RIDBIT_SETP (RID_AUTO, specbits)) + if (declspecs->storage_class == sc_auto) error ("storage class `auto' invalid for function `%s'", name); - else if (RIDBIT_SETP (RID_REGISTER, specbits)) + else if (declspecs->storage_class == sc_register) error ("storage class `register' invalid for function `%s'", name); - else if (RIDBIT_SETP (RID_THREAD, specbits)) + else if (declspecs->specs[(int)ds_thread]) error ("storage class `__thread' invalid for function `%s'", name); /* Function declaration not at top level. Storage classes other than `extern' are not allowed and `extern' makes no difference. */ if (! toplevel_bindings_p () - && (RIDBIT_SETP (RID_STATIC, specbits) - || RIDBIT_SETP (RID_INLINE, specbits)) + && (declspecs->storage_class == sc_static + || declspecs->specs[(int)ds_inline]) && pedantic) { - if (RIDBIT_SETP (RID_STATIC, specbits)) - pedwarn ("storage class `static' invalid for function `%s' declared out of global scope", name); + if (declspecs->storage_class == sc_static) + pedwarn ("`static' specified invalid for function `%s' declared out of global scope", name); else - pedwarn ("storage class `inline' invalid for function `%s' declared out of global scope", name); + pedwarn ("`inline' specifier invalid for function `%s' declared out of global scope", name); } if (ctype == NULL_TREE) @@ -8101,8 +7935,8 @@ grokdeclarator (const cp_declarator *declarator, /* Record presence of `static'. */ publicp = (ctype != NULL_TREE - || RIDBIT_SETP (RID_EXTERN, specbits) - || !RIDBIT_SETP (RID_STATIC, specbits)); + || declspecs->storage_class == sc_extern + || declspecs->storage_class != sc_static); decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, virtualp, flags, quals, raises, @@ -8133,7 +7967,7 @@ grokdeclarator (const cp_declarator *declarator, if (invalid_static) { staticp = 0; - RIDBIT_RESET (RID_STATIC, specbits); + declspecs->storage_class = sc_none; } } } @@ -8142,7 +7976,8 @@ grokdeclarator (const cp_declarator *declarator, /* It's a variable. */ /* An uninitialized decl with `extern' is a reference. */ - decl = grokvardecl (type, unqualified_id, &specbits, + decl = grokvardecl (type, unqualified_id, + declspecs, initialized, (type_quals & TYPE_QUAL_CONST) != 0, ctype ? ctype : in_namespace); @@ -8156,34 +7991,30 @@ grokdeclarator (const cp_declarator *declarator, { pedwarn ("`static' may not be used when defining (as opposed to declaring) a static data member"); staticp = 0; - RIDBIT_RESET (RID_STATIC, specbits); + declspecs->storage_class = sc_none; } - if (RIDBIT_SETP (RID_REGISTER, specbits) && TREE_STATIC (decl)) + if (declspecs->storage_class == sc_register && TREE_STATIC (decl)) { error ("static member `%D' declared `register'", decl); - RIDBIT_RESET (RID_REGISTER, specbits); + declspecs->storage_class = sc_none; } - if (RIDBIT_SETP (RID_EXTERN, specbits) && pedantic) + if (declspecs->storage_class == sc_extern && pedantic) { pedwarn ("cannot explicitly declare member `%#D' to have extern linkage", decl); - RIDBIT_RESET (RID_EXTERN, specbits); + declspecs->storage_class = sc_none; } } } - my_friendly_assert (!RIDBIT_SETP (RID_MUTABLE, specbits), 19990927); - /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ - if (RIDBIT_SETP (RID_REGISTER, specbits)) + if (declspecs->storage_class == sc_register) DECL_REGISTER (decl) = 1; - - if (RIDBIT_SETP (RID_EXTERN, specbits)) + else if (declspecs->storage_class == sc_extern) DECL_THIS_EXTERN (decl) = 1; - - if (RIDBIT_SETP (RID_STATIC, specbits)) + else if (declspecs->storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; /* Record constancy and volatility. There's no need to do this @@ -8348,27 +8179,27 @@ check_default_argument (tree decl, tree arg) *PARMS is set to the chain of PARM_DECLs created. */ static tree -grokparms (const cp_parameter_declarator *first_parm, tree *parms) +grokparms (cp_parameter_declarator *first_parm, tree *parms) { tree result = NULL_TREE; tree decls = NULL_TREE; int ellipsis = !first_parm || first_parm->ellipsis_p; - const cp_parameter_declarator *parm; + cp_parameter_declarator *parm; int any_error = 0; for (parm = first_parm; parm != NULL; parm = parm->next) { tree type = NULL_TREE; - tree decl_specifiers = parm->decl_specifiers; tree init = parm->default_argument; - tree specs, attrs; + tree attrs; tree decl; if (parm == no_parameters) break; - split_specs_attrs (decl_specifiers, &specs, &attrs); - decl = grokdeclarator (parm->declarator, specs, + attrs = parm->decl_specifiers.attributes; + parm->decl_specifiers.attributes = NULL_TREE; + decl = grokdeclarator (parm->declarator, &parm->decl_specifiers, PARM, init != NULL_TREE, &attrs); if (! decl || TREE_TYPE (decl) == error_mark_node) continue; @@ -10070,15 +9901,15 @@ start_preparsed_function (tree decl1, tree attrs, int flags) yyparse to report a parse error. */ int -start_function (tree declspecs, const cp_declarator *declarator, +start_function (cp_decl_specifier_seq *declspecs, + const cp_declarator *declarator, tree attrs) { tree decl1; if (have_extern_spec) { - declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), - declspecs); + declspecs->storage_class = sc_extern; /* This should only be done once on the outermost decl. */ have_extern_spec = false; } @@ -10598,7 +10429,8 @@ finish_function (int flags) CHANGES TO CODE IN `grokfield'. */ tree -start_method (tree declspecs, const cp_declarator *declarator, tree attrlist) +start_method (cp_decl_specifier_seq *declspecs, + const cp_declarator *declarator, tree attrlist) { tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, &attrlist); diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h index 871d568a0c5..fae386e7133 100644 --- a/gcc/cp/decl.h +++ b/gcc/cp/decl.h @@ -31,7 +31,9 @@ enum decl_context }; /* We need this in here to get the decl_context definition. */ -extern tree grokdeclarator (const cp_declarator *, tree, enum decl_context, int, tree*); +extern tree grokdeclarator (const cp_declarator *, + cp_decl_specifier_seq *, + enum decl_context, int, tree*); #ifdef DEBUG_CP_BINDING_LEVELS /* Purely for debugging purposes. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 80e56ec82e7..10384b3b9b6 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -38,7 +38,6 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "cp-tree.h" #include "decl.h" -#include "lex.h" #include "output.h" #include "except.h" #include "toplev.h" @@ -157,27 +156,6 @@ grok_method_quals (tree ctype, tree function, tree quals) return this_quals; } -/* A subroutine of the parser, to handle a component list. */ - -void -grok_x_components (tree specs) -{ - tree t; - - specs = strip_attrs (specs); - - check_tag_decl (specs); - t = groktypename (specs, /*declarator=*/NULL); - - /* The only case where we need to do anything additional here is an - anonymous union field, e.g.: `struct S { union { int i; }; };'. */ - if (t == NULL_TREE || !ANON_AGGR_TYPE_P (t)) - return; - - fixup_anonymous_aggr (t); - finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t)); -} - /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE appropriately. */ @@ -840,7 +818,8 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree, CHANGES TO CODE IN `start_method'. */ tree -grokfield (const cp_declarator *declarator, tree declspecs, +grokfield (const cp_declarator *declarator, + cp_decl_specifier_seq *declspecs, tree init, tree asmspec_tree, tree attrlist) { @@ -848,7 +827,7 @@ grokfield (const cp_declarator *declarator, tree declspecs, const char *asmspec = 0; int flags = LOOKUP_ONLYCONVERTING; - if (declspecs == NULL_TREE + if (!declspecs->any_specifiers_p && declarator->kind == cdk_id && TREE_CODE (declarator->u.id.name) == SCOPE_REF && (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1)) @@ -1023,7 +1002,8 @@ grokfield (const cp_declarator *declarator, tree declspecs, WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */ tree -grokbitfield (const cp_declarator *declarator, tree declspecs, tree width) +grokbitfield (const cp_declarator *declarator, + cp_decl_specifier_seq *declspecs, tree width) { tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 7152e692759..c9422696f4b 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include "cp-tree.h" #include "cpplib.h" -#include "lex.h" #include "flags.h" #include "c-pragma.h" #include "toplev.h" diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h deleted file mode 100644 index 35c3503ea41..00000000000 --- a/gcc/cp/lex.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Define constants and variables for communication with the parser. - Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - and by Brendan Kehoe (brendan@cygnus.com). - - This file is part of GCC. - - 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. - - 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 GCC; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - - -#ifndef GCC_CP_LEX_H -#define GCC_CP_LEX_H - -#if 0 -/* Formerly, the RID_* values used as mask bits did not fit into a - single 32-bit word. Now they do, but let's preserve the old logic - in case they ever stop fitting again. -zw, 8 Aug 2000 */ - -/* The type that can represent all values of RIDBIT. */ -/* We assume that we can stick in at least 32 bits into this. */ -typedef struct { unsigned long idata[2]; } - RID_BIT_TYPE; - -/* Be careful, all these modify N twice. */ -#define RIDBIT_SETP(N, V) (((unsigned long)1 << (int) ((N)%32)) \ - & (V).idata[(N)/32]) -#define RIDBIT_NOTSETP(NN, VV) (! RIDBIT_SETP (NN, VV)) -#define RIDBIT_SET(N, V) do { \ - (V).idata[(N)/32] \ - |= ((unsigned long)1 << (int) ((N)%32)); \ - } while (0) -#define RIDBIT_RESET(N, V) do { \ - (V).idata[(N)/32] \ - &= ~((unsigned long)1 << (int) ((N)%32)); \ - } while (0) -#define RIDBIT_RESET_ALL(V) do { \ - (V).idata[0] = 0; \ - (V).idata[1] = 0; \ - } while (0) -#define RIDBIT_ANY_SET(V) ((V).idata[0] || (V).idata[1]) -#else -typedef unsigned long RID_BIT_TYPE; /* assumed at least 32 bits */ -#define RIDBIT_OF(R) ((unsigned long)1 << (int) (R)) - -#define RIDBIT_SETP(N, V) ((V) & RIDBIT_OF (N)) -#define RIDBIT_NOTSETP(N, V) (! ((V) & RIDBIT_OF (N))) -#define RIDBIT_ANY_SET(V) (V) - -#define RIDBIT_SET(N, V) do { (V) |= RIDBIT_OF (N); } while (0) -#define RIDBIT_RESET(N, V) do { (V) &= ~RIDBIT_OF (N); } while (0) -#define RIDBIT_RESET_ALL(V) do { (V) = 0; } while (0) -#endif - -#endif /* ! GCC_CP_LEX_H */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d86f2039675..ffaf0c85c99 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -34,6 +34,7 @@ #include "diagnostic.h" #include "toplev.h" #include "output.h" +#include "target.h" /* The lexer. */ @@ -995,6 +996,19 @@ cp_lexer_stop_debugging (cp_lexer* lexer) } +/* Decl-specifiers. */ + +static void clear_decl_specs + (cp_decl_specifier_seq *); + +/* Set *DECL_SPECS to represent an empty decl-specifier-seq. */ + +static void +clear_decl_specs (cp_decl_specifier_seq *decl_specs) +{ + memset (decl_specs, 0, sizeof (cp_decl_specifier_seq)); +} + /* Declarators. */ /* Nothing other than the parser should be creating declarators; @@ -1013,7 +1027,7 @@ static cp_declarator *make_pointer_declarator static cp_declarator *make_reference_declarator (tree, cp_declarator *); static cp_parameter_declarator *make_parameter_declarator - (tree, cp_declarator *, tree); + (cp_decl_specifier_seq *, cp_declarator *, tree); static cp_declarator *make_ptrmem_declarator (tree, tree, cp_declarator *); @@ -1153,7 +1167,7 @@ cp_parameter_declarator *no_parameters; DECLARATOR and DEFAULT_ARGUMENT. */ cp_parameter_declarator * -make_parameter_declarator (tree decl_specifiers, +make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers, cp_declarator *declarator, tree default_argument) { @@ -1162,7 +1176,10 @@ make_parameter_declarator (tree decl_specifiers, parameter = ((cp_parameter_declarator *) alloc_declarator (sizeof (cp_parameter_declarator))); parameter->next = NULL; - parameter->decl_specifiers = decl_specifiers; + if (decl_specifiers) + parameter->decl_specifiers = *decl_specifiers; + else + clear_decl_specs (¶meter->decl_specifiers); parameter->declarator = declarator; parameter->default_argument = default_argument; parameter->ellipsis_p = false; @@ -1627,16 +1644,17 @@ static void cp_parser_block_declaration (cp_parser *, bool); static void cp_parser_simple_declaration (cp_parser *, bool); -static tree cp_parser_decl_specifier_seq - (cp_parser *, cp_parser_flags, tree *, int *); +static void cp_parser_decl_specifier_seq + (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *); static tree cp_parser_storage_class_specifier_opt (cp_parser *); static tree cp_parser_function_specifier_opt - (cp_parser *); + (cp_parser *, cp_decl_specifier_seq *); static tree cp_parser_type_specifier - (cp_parser *, cp_parser_flags, bool, bool, int *, bool *); + (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool, + int *, bool *); static tree cp_parser_simple_type_specifier - (cp_parser *, cp_parser_flags, bool); + (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags); static tree cp_parser_type_name (cp_parser *); static tree cp_parser_elaborated_type_specifier @@ -1669,7 +1687,7 @@ static void cp_parser_linkage_specification /* Declarators [gram.dcl.decl] */ static tree cp_parser_init_declarator - (cp_parser *, tree, tree, bool, bool, int, bool *); + (cp_parser *, cp_decl_specifier_seq *, bool, bool, int, bool *); static cp_declarator *cp_parser_declarator (cp_parser *, cp_parser_declarator_kind, int *, bool *); static cp_declarator *cp_parser_direct_declarator @@ -1684,8 +1702,8 @@ static tree cp_parser_declarator_id (cp_parser *); static tree cp_parser_type_id (cp_parser *); -static tree cp_parser_type_specifier_seq - (cp_parser *); +static void cp_parser_type_specifier_seq + (cp_parser *, cp_decl_specifier_seq *); static cp_parameter_declarator *cp_parser_parameter_declaration_clause (cp_parser *); static cp_parameter_declarator *cp_parser_parameter_declaration_list @@ -1834,7 +1852,7 @@ static tree cp_parser_global_scope_opt static bool cp_parser_constructor_declarator_p (cp_parser *, bool); static tree cp_parser_function_definition_from_specifiers_and_declarator - (cp_parser *, tree, tree, const cp_declarator *); + (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *); static tree cp_parser_function_definition_after_declarator (cp_parser *, bool); static void cp_parser_template_declaration_after_export @@ -1844,7 +1862,7 @@ static tree cp_parser_single_declaration static tree cp_parser_functional_cast (cp_parser *, tree); static tree cp_parser_save_member_function_body - (cp_parser *, tree, cp_declarator *, tree); + (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree); static tree cp_parser_enclosed_template_argument_list (cp_parser *); static void cp_parser_save_default_args @@ -1857,8 +1875,12 @@ static tree cp_parser_sizeof_operand (cp_parser *, enum rid); static bool cp_parser_declares_only_class_p (cp_parser *); +static void cp_parser_set_storage_class + (cp_decl_specifier_seq *, cp_storage_class); +static void cp_parser_set_decl_spec_type + (cp_decl_specifier_seq *, tree, bool); static bool cp_parser_friend_p - (tree); + (const cp_decl_specifier_seq *); static cp_token *cp_parser_require (cp_parser *, enum cpp_ttype, const char *); static cp_token *cp_parser_require_keyword @@ -2612,7 +2634,7 @@ cp_parser_translation_unit (cp_parser* parser) /* Create the error declarator. */ cp_error_declarator = make_declarator (cdk_error); /* Create the empty parameter list. */ - no_parameters = make_parameter_declarator (NULL_TREE, NULL, NULL_TREE); + no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE); /* Remember where the base of the declarator obstack lies. */ declarator_obstack_base = obstack_next_free (&declarator_obstack); } @@ -3880,8 +3902,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) cp_parser_parse_tentatively (parser); /* Look for the simple-type-specifier. */ type = cp_parser_simple_type_specifier (parser, - CP_PARSER_FLAGS_NONE, - /*identifier_p=*/false); + /*decl_specs=*/NULL, + CP_PARSER_FLAGS_NONE); /* Parse the cast itself. */ if (!cp_parser_error_occurred (parser)) postfix_expression @@ -4850,7 +4872,7 @@ cp_parser_new_placement (cp_parser* parser) static tree cp_parser_new_type_id (cp_parser* parser, tree *nelts) { - tree type_specifier_seq; + cp_decl_specifier_seq type_specifier_seq; cp_declarator *new_declarator; cp_declarator *declarator; cp_declarator *outer_declarator; @@ -4865,7 +4887,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts) parser->type_definition_forbidden_message = "types may not be defined in a new-type-id"; /* Parse the type-specifier-seq. */ - type_specifier_seq = cp_parser_type_specifier_seq (parser); + cp_parser_type_specifier_seq (parser, &type_specifier_seq); /* Restore the old message. */ parser->type_definition_forbidden_message = saved_message; /* Parse the new-declarator. */ @@ -4912,7 +4934,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts) new_declarator = NULL; } - type = groktypename (type_specifier_seq, new_declarator); + type = groktypename (&type_specifier_seq, new_declarator); if (TREE_CODE (type) == ARRAY_TYPE && *nelts == NULL_TREE) { *nelts = array_type_nelts_top (type); @@ -6257,7 +6279,7 @@ cp_parser_selection_statement (cp_parser* parser) static tree cp_parser_condition (cp_parser* parser) { - tree type_specifiers; + cp_decl_specifier_seq type_specifiers; const char *saved_message; /* Try the declaration first. */ @@ -6268,7 +6290,7 @@ cp_parser_condition (cp_parser* parser) parser->type_definition_forbidden_message = "types may not be defined in conditions"; /* Parse the type-specifier-seq. */ - type_specifiers = cp_parser_type_specifier_seq (parser); + cp_parser_type_specifier_seq (parser, &type_specifiers); /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; /* If all is well, we might be looking at a declaration. */ @@ -6301,7 +6323,7 @@ cp_parser_condition (cp_parser* parser) if (cp_parser_parse_definitely (parser)) { /* Create the declaration. */ - decl = start_decl (declarator, type_specifiers, + decl = start_decl (declarator, &type_specifiers, /*initialized_p=*/true, attributes, /*prefix_attributes=*/NULL_TREE); /* Parse the assignment-expression. */ @@ -6911,8 +6933,7 @@ static void cp_parser_simple_declaration (cp_parser* parser, bool function_definition_allowed_p) { - tree decl_specifiers; - tree attributes; + cp_decl_specifier_seq decl_specifiers; int declares_class_or_enum; bool saw_declarator; @@ -6932,18 +6953,18 @@ cp_parser_simple_declaration (cp_parser* parser, omitted only when declaring a class or enumeration, that is when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier, or an enum-specifier. */ - decl_specifiers - = cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_OPTIONAL, - &attributes, - &declares_class_or_enum); + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_OPTIONAL, + &decl_specifiers, + &declares_class_or_enum); /* We no longer need to defer access checks. */ stop_deferring_access_checks (); /* In a block scope, a valid declaration must always have a decl-specifier-seq. By not trying to parse declarators, we can resolve the declaration/expression ambiguity more quickly. */ - if (!function_definition_allowed_p && !decl_specifiers) + if (!function_definition_allowed_p + && !decl_specifiers.any_specifiers_p) { cp_parser_error (parser, "expected declaration"); goto done; @@ -6976,7 +6997,7 @@ cp_parser_simple_declaration (cp_parser* parser, saw_declarator = true; /* Parse the init-declarator. */ - decl = cp_parser_init_declarator (parser, decl_specifiers, attributes, + decl = cp_parser_init_declarator (parser, &decl_specifiers, function_definition_allowed_p, /*member_p=*/false, declares_class_or_enum, @@ -7039,7 +7060,7 @@ cp_parser_simple_declaration (cp_parser* parser, if (!saw_declarator) { if (cp_parser_declares_only_class_p (parser)) - shadow_tag (decl_specifiers); + shadow_tag (&decl_specifiers); /* Perform any deferred access checks. */ perform_deferred_access_checks (); } @@ -7068,14 +7089,7 @@ cp_parser_simple_declaration (cp_parser* parser, decl-specifier: attributes - Returns a TREE_LIST, giving the decl-specifiers in the order they - appear in the source code. The TREE_VALUE of each node is the - decl-specifier. For a keyword (such as `auto' or `friend'), the - TREE_VALUE is simply the corresponding TREE_IDENTIFIER. For the - representation of a type-specifier, see cp_parser_type_specifier. - - If there are attributes, they will be stored in *ATTRIBUTES, - represented as described above cp_parser_attributes. + Set *DECL_SPECS to a representation of the decl-specifier-seq. If FRIEND_IS_NOT_CLASS_P is non-NULL, and the `friend' specifier appears, and the entity that will be a friend is not going to be a @@ -7090,30 +7104,28 @@ cp_parser_simple_declaration (cp_parser* parser, (i.e., a type declaration) 2: one of the decl-specifiers is an enum-specifier or a class-specifier (i.e., a type definition) - + */ -static tree +static void cp_parser_decl_specifier_seq (cp_parser* parser, - cp_parser_flags flags, - tree* attributes, + cp_parser_flags flags, + cp_decl_specifier_seq *decl_specs, int* declares_class_or_enum) { - tree decl_specs = NULL_TREE; - bool friend_p = false; bool constructor_possible_p = !parser->in_declarator_p; + /* Clear DECL_SPECS. */ + clear_decl_specs (decl_specs); + /* Assume no class or enumeration type is declared. */ *declares_class_or_enum = 0; - /* Assume there are no attributes. */ - *attributes = NULL_TREE; - /* Keep reading specifiers until there are no more to read. */ while (true) { - tree decl_spec = NULL_TREE; bool constructor_p; + bool found_decl_spec; cp_token *token; /* Peek at the next token. */ @@ -7122,25 +7134,22 @@ cp_parser_decl_specifier_seq (cp_parser* parser, if (token->keyword == RID_ATTRIBUTE) { /* Parse the attributes. */ - decl_spec = cp_parser_attributes_opt (parser); - /* Add them to the list. */ - *attributes = chainon (*attributes, decl_spec); + decl_specs->attributes + = chainon (decl_specs->attributes, + cp_parser_attributes_opt (parser)); continue; } + /* Assume we will find a decl-specifier keyword. */ + found_decl_spec = true; /* If the next token is an appropriate keyword, we can simply add it to the list. */ switch (token->keyword) { - case RID_FRIEND: /* decl-specifier: friend */ - if (friend_p) + case RID_FRIEND: + if (decl_specs->specs[(int) ds_friend]++) error ("duplicate `friend'"); - else - friend_p = true; - /* The representation of the specifier is simply the - appropriate TREE_IDENTIFIER node. */ - decl_spec = token->value; /* Consume the token. */ cp_lexer_consume_token (parser->lexer); break; @@ -7152,15 +7161,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_INLINE: case RID_VIRTUAL: case RID_EXPLICIT: - decl_spec = cp_parser_function_specifier_opt (parser); + cp_parser_function_specifier_opt (parser, decl_specs); break; /* decl-specifier: typedef */ case RID_TYPEDEF: - /* The representation of the specifier is simply the - appropriate TREE_IDENTIFIER node. */ - decl_spec = token->value; + ++decl_specs->specs[(int) ds_typedef]; /* Consume the token. */ cp_lexer_consume_token (parser->lexer); /* A constructor declarator cannot appear in a typedef. */ @@ -7180,35 +7187,67 @@ cp_parser_decl_specifier_seq (cp_parser* parser, GNU Extension: thread */ case RID_AUTO: + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + cp_parser_set_storage_class (decl_specs, sc_auto); + break; case RID_REGISTER: + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + cp_parser_set_storage_class (decl_specs, sc_register); + break; case RID_STATIC: + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + if (decl_specs->specs[(int) ds_thread]) + error ("`__thread' before `static'"); + else + cp_parser_set_storage_class (decl_specs, sc_static); + break; case RID_EXTERN: + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + if (decl_specs->specs[(int) ds_thread]) + error ("`__thread' before `extern'"); + else + cp_parser_set_storage_class (decl_specs, sc_extern); + break; case RID_MUTABLE: + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + cp_parser_set_storage_class (decl_specs, sc_mutable); + break; case RID_THREAD: - decl_spec = cp_parser_storage_class_specifier_opt (parser); + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + ++decl_specs->specs[(int) ds_thread]; break; default: + /* We did not yet find a decl-specifier yet. */ + found_decl_spec = false; break; } /* Constructors are a special case. The `S' in `S()' is not a decl-specifier; it is the beginning of the declarator. */ - constructor_p = (!decl_spec - && constructor_possible_p - && cp_parser_constructor_declarator_p (parser, - friend_p)); + constructor_p + = (!found_decl_spec + && constructor_possible_p + && (cp_parser_constructor_declarator_p + (parser, decl_specs->specs[(int) ds_friend] != 0))); /* If we don't have a DECL_SPEC yet, then we must be looking at a type-specifier. */ - if (!decl_spec && !constructor_p) + if (!found_decl_spec && !constructor_p) { int decl_spec_declares_class_or_enum; bool is_cv_qualifier; + tree type_spec; - decl_spec + type_spec = cp_parser_type_specifier (parser, flags, - friend_p, + decl_specs, /*is_declaration=*/true, &decl_spec_declares_class_or_enum, &is_cv_qualifier); @@ -7251,44 +7290,31 @@ cp_parser_decl_specifier_seq (cp_parser* parser, user-defined types. We *do* still allow things like `int int' to be considered a decl-specifier-seq, and issue the error message later. */ - if (decl_spec && !is_cv_qualifier) + if (type_spec && !is_cv_qualifier) flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; /* A constructor declarator cannot follow a type-specifier. */ - if (decl_spec) - constructor_possible_p = false; - } - - /* If we still do not have a DECL_SPEC, then there are no more - decl-specifiers. */ - if (!decl_spec) - { - /* Issue an error message, unless the entire construct was - optional. */ - if (!(flags & CP_PARSER_FLAGS_OPTIONAL)) + if (type_spec) { - cp_parser_error (parser, "expected decl specifier"); - return error_mark_node; + constructor_possible_p = false; + found_decl_spec = true; } - - break; } - /* Add the DECL_SPEC to the list of specifiers. */ - if (decl_specs == NULL || TREE_VALUE (decl_specs) != error_mark_node) - decl_specs = tree_cons (NULL_TREE, decl_spec, decl_specs); + /* If we still do not have a DECL_SPEC, then there are no more + decl-specifiers. */ + if (!found_decl_spec) + break; + decl_specs->any_specifiers_p = true; /* After we see one decl-specifier, further decl-specifiers are always optional. */ flags |= CP_PARSER_FLAGS_OPTIONAL; } /* Don't allow a friend specifier with a class definition. */ - if (friend_p && (*declares_class_or_enum & 2)) + if (decl_specs->specs[(int) ds_friend] != 0 + && (*declares_class_or_enum & 2)) error ("class definition may not be declared a friend"); - - /* We have built up the DECL_SPECS in reverse order. Return them in - the correct order. */ - return nreverse (decl_specs); } /* Parse an (optional) storage-class-specifier. @@ -7333,22 +7359,36 @@ cp_parser_storage_class_specifier_opt (cp_parser* parser) virtual explicit - Returns an IDENTIFIER_NODE corresponding to the keyword used. */ + Returns an IDENTIFIER_NODE corresponding to the keyword used. + Updates DECL_SPECS, if it is non-NULL. */ static tree -cp_parser_function_specifier_opt (cp_parser* parser) +cp_parser_function_specifier_opt (cp_parser* parser, + cp_decl_specifier_seq *decl_specs) { switch (cp_lexer_peek_token (parser->lexer)->keyword) { case RID_INLINE: + if (decl_specs) + ++decl_specs->specs[(int) ds_inline]; + break; + case RID_VIRTUAL: + if (decl_specs) + ++decl_specs->specs[(int) ds_virtual]; + break; + case RID_EXPLICIT: - /* Consume the token. */ - return cp_lexer_consume_token (parser->lexer)->value; + if (decl_specs) + ++decl_specs->specs[(int) ds_explicit]; + break; default: return NULL_TREE; } + + /* Consume the token. */ + return cp_lexer_consume_token (parser->lexer)->value; } /* Parse a linkage-specification. @@ -7497,20 +7537,20 @@ static tree cp_parser_conversion_type_id (cp_parser* parser) { tree attributes; - tree type_specifiers; + cp_decl_specifier_seq type_specifiers; cp_declarator *declarator; /* Parse the attributes. */ attributes = cp_parser_attributes_opt (parser); /* Parse the type-specifiers. */ - type_specifiers = cp_parser_type_specifier_seq (parser); + cp_parser_type_specifier_seq (parser, &type_specifiers); /* If that didn't work, stop. */ - if (type_specifiers == error_mark_node) + if (type_specifiers.type == error_mark_node) return error_mark_node; /* Parse the conversion-declarator. */ declarator = cp_parser_conversion_declarator_opt (parser); - return grokdeclarator (declarator, type_specifiers, TYPENAME, + return grokdeclarator (declarator, &type_specifiers, TYPENAME, /*initialized=*/0, &attributes); } @@ -8114,7 +8154,7 @@ static tree cp_parser_template_parameter (cp_parser* parser, bool *is_non_type) { cp_token *token; - const cp_parameter_declarator *parameter_declarator; + cp_parameter_declarator *parameter_declarator; /* Assume it is a type parameter or a template parameter. */ *is_non_type = false; @@ -8166,7 +8206,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type) return (build_tree_list (parameter_declarator->default_argument, grokdeclarator (parameter_declarator->declarator, - parameter_declarator->decl_specifiers, + ¶meter_declarator->decl_specifiers, PARM, /*initialized=*/0, /*attrlist=*/NULL))); } @@ -9005,8 +9045,7 @@ static void cp_parser_explicit_instantiation (cp_parser* parser) { int declares_class_or_enum; - tree decl_specifiers; - tree attributes; + cp_decl_specifier_seq decl_specifiers; tree extension_specifier = NULL_TREE; /* Look for an (optional) storage-class-specifier or @@ -9016,7 +9055,9 @@ cp_parser_explicit_instantiation (cp_parser* parser) extension_specifier = cp_parser_storage_class_specifier_opt (parser); if (!extension_specifier) - extension_specifier = cp_parser_function_specifier_opt (parser); + extension_specifier + = cp_parser_function_specifier_opt (parser, + /*decl_specs=*/NULL); } /* Look for the `template' keyword. */ @@ -9028,11 +9069,10 @@ cp_parser_explicit_instantiation (cp_parser* parser) control while processing explicit instantiation directives. */ push_deferring_access_checks (dk_no_check); /* Parse a decl-specifier-seq. */ - decl_specifiers - = cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_OPTIONAL, - &attributes, - &declares_class_or_enum); + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_OPTIONAL, + &decl_specifiers, + &declares_class_or_enum); /* If there was exactly one decl-specifier, and it declared a class, and there's no declarator, then we have an explicit type instantiation. */ @@ -9040,7 +9080,7 @@ cp_parser_explicit_instantiation (cp_parser* parser) { tree type; - type = check_tag_decl (decl_specifiers); + type = check_tag_decl (&decl_specifiers); /* Turn access control back on for names used during template instantiation. */ pop_deferring_access_checks (); @@ -9061,7 +9101,7 @@ cp_parser_explicit_instantiation (cp_parser* parser) declares_class_or_enum); if (declarator != cp_error_declarator) { - decl = grokdeclarator (declarator, decl_specifiers, + decl = grokdeclarator (declarator, &decl_specifiers, NORMAL, 0, NULL); /* Turn access control back on for names used during template instantiation. */ @@ -9146,11 +9186,9 @@ cp_parser_explicit_specialization (cp_parser* parser) type-specifier: __complex__ - Returns a representation of the type-specifier. If the - type-specifier is a keyword (like `int' or `const', or - `__complex__') then the corresponding IDENTIFIER_NODE is returned. - For a class-specifier, enum-specifier, or elaborated-type-specifier - a TREE_TYPE is returned; otherwise, a TYPE_DECL is returned. + Returns a representation of the type-specifier. For a + class-specifier, enum-specifier, or elaborated-type-specifier, a + TREE_TYPE is returned; otherwise, a TYPE_DECL is returned. If IS_FRIEND is TRUE then this type-specifier is being declared a `friend'. If IS_DECLARATION is TRUE, then this type-specifier is @@ -9169,7 +9207,7 @@ cp_parser_explicit_specialization (cp_parser* parser) static tree cp_parser_type_specifier (cp_parser* parser, cp_parser_flags flags, - bool is_friend, + cp_decl_specifier_seq *decl_specs, bool is_declaration, int* declares_class_or_enum, bool* is_cv_qualifier) @@ -9177,6 +9215,7 @@ cp_parser_type_specifier (cp_parser* parser, tree type_spec = NULL_TREE; cp_token *token; enum rid keyword; + cp_decl_spec ds = ds_last; /* Assume this type-specifier does not declare a new type. */ if (declares_class_or_enum) @@ -9212,6 +9251,10 @@ cp_parser_type_specifier (cp_parser* parser, { if (declares_class_or_enum) *declares_class_or_enum = 2; + if (decl_specs) + cp_parser_set_decl_spec_type (decl_specs, + type_spec, + /*user_defined_p=*/true); return type_spec; } @@ -9219,40 +9262,64 @@ cp_parser_type_specifier (cp_parser* parser, case RID_TYPENAME: /* Look for an elaborated-type-specifier. */ - type_spec = cp_parser_elaborated_type_specifier (parser, - is_friend, - is_declaration); + type_spec + = (cp_parser_elaborated_type_specifier + (parser, + decl_specs && decl_specs->specs[(int) ds_friend], + is_declaration)); /* We're declaring a class or enum -- unless we're using `typename'. */ if (declares_class_or_enum && keyword != RID_TYPENAME) *declares_class_or_enum = 1; + if (decl_specs) + cp_parser_set_decl_spec_type (decl_specs, + type_spec, + /*user_defined_p=*/true); return type_spec; case RID_CONST: + ds = ds_const; + if (is_cv_qualifier) + *is_cv_qualifier = true; + break; + case RID_VOLATILE: - case RID_RESTRICT: - type_spec = cp_parser_cv_qualifier_opt (parser); - /* Even though we call a routine that looks for an optional - qualifier, we know that there should be one. */ - my_friendly_assert (type_spec != NULL, 20000328); - /* This type-specifier was a cv-qualified. */ + ds = ds_volatile; if (is_cv_qualifier) *is_cv_qualifier = true; + break; - return type_spec; + case RID_RESTRICT: + ds = ds_restrict; + if (is_cv_qualifier) + *is_cv_qualifier = true; + break; case RID_COMPLEX: /* The `__complex__' keyword is a GNU extension. */ - return cp_lexer_consume_token (parser->lexer)->value; + ds = ds_complex; + break; default: break; } + /* Handle simple keywords. */ + if (ds != ds_last) + { + if (decl_specs) + { + ++decl_specs->specs[(int)ds]; + decl_specs->any_specifiers_p = true; + } + return cp_lexer_consume_token (parser->lexer)->value; + } + /* If we do not already have a type-specifier, assume we are looking at a simple-type-specifier. */ - type_spec = cp_parser_simple_type_specifier (parser, flags, - /*identifier_p=*/true); + type_spec = cp_parser_simple_type_specifier (parser, + decl_specs, + flags); /* If we didn't find a type-specifier, and a type-specifier was not optional in this context, issue an error message. */ @@ -9288,14 +9355,13 @@ cp_parser_type_specifier (cp_parser* parser, __typeof__ unary-expression __typeof__ ( type-id ) - For the various keywords, the value returned is simply the - TREE_IDENTIFIER representing the keyword if IDENTIFIER_P is true. - For the first two productions, and if IDENTIFIER_P is false, the - value returned is the indicated TYPE_DECL. */ + Returns the indicated TYPE_DECL. If DECL_SPECS is not NULL, it is + appropriately updated. */ static tree -cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, - bool identifier_p) +cp_parser_simple_type_specifier (cp_parser* parser, + cp_decl_specifier_seq *decl_specs, + cp_parser_flags flags) { tree type = NULL_TREE; cp_token *token; @@ -9307,6 +9373,8 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, switch (token->keyword) { case RID_CHAR: + if (decl_specs) + decl_specs->explicit_char_p = true; type = char_type_node; break; case RID_WCHAR: @@ -9316,18 +9384,28 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, type = boolean_type_node; break; case RID_SHORT: + if (decl_specs) + ++decl_specs->specs[(int) ds_short]; type = short_integer_type_node; break; case RID_INT: + if (decl_specs) + decl_specs->explicit_int_p = true; type = integer_type_node; break; case RID_LONG: + if (decl_specs) + ++decl_specs->specs[(int) ds_long]; type = long_integer_type_node; break; case RID_SIGNED: + if (decl_specs) + ++decl_specs->specs[(int) ds_signed]; type = integer_type_node; break; case RID_UNSIGNED: + if (decl_specs) + ++decl_specs->specs[(int) ds_unsigned]; type = unsigned_type_node; break; case RID_FLOAT: @@ -9341,19 +9419,19 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, break; case RID_TYPEOF: - { - tree operand; - - /* Consume the `typeof' token. */ - cp_lexer_consume_token (parser->lexer); - /* Parse the operand to `typeof'. */ - operand = cp_parser_sizeof_operand (parser, RID_TYPEOF); - /* If it is not already a TYPE, take its type. */ - if (!TYPE_P (operand)) - operand = finish_typeof (operand); - - return operand; - } + /* Consume the `typeof' token. */ + cp_lexer_consume_token (parser->lexer); + /* Parse the operand to `typeof'. */ + type = cp_parser_sizeof_operand (parser, RID_TYPEOF); + /* If it is not already a TYPE, take its type. */ + if (!TYPE_P (type)) + type = finish_typeof (type); + + if (decl_specs) + cp_parser_set_decl_spec_type (decl_specs, type, + /*user_defined_p=*/true); + + return type; default: break; @@ -9364,6 +9442,18 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, { tree id; + /* Record the type. */ + if (decl_specs + && (token->keyword != RID_SIGNED + && token->keyword != RID_UNSIGNED + && token->keyword != RID_SHORT + && token->keyword != RID_LONG)) + cp_parser_set_decl_spec_type (decl_specs, + type, + /*user_defined=*/false); + if (decl_specs) + decl_specs->any_specifiers_p = true; + /* Consume the token. */ id = cp_lexer_consume_token (parser->lexer)->value; @@ -9372,7 +9462,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, that the type was a template. */ cp_parser_check_for_invalid_template_id (parser, type); - return identifier_p ? id : TYPE_NAME (type); + return TYPE_NAME (type); } /* The type-specifier must be a user-defined type. */ @@ -9427,6 +9517,9 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags, if ((flags & CP_PARSER_FLAGS_OPTIONAL) && !cp_parser_parse_definitely (parser)) type = NULL_TREE; + if (type && decl_specs) + cp_parser_set_decl_spec_type (decl_specs, type, + /*user_defined=*/true); } /* If we didn't get a type-name, issue an error message. */ @@ -10370,8 +10463,7 @@ cp_parser_asm_definition (cp_parser* parser) static tree cp_parser_init_declarator (cp_parser* parser, - tree decl_specifiers, - tree prefix_attributes, + cp_decl_specifier_seq *decl_specifiers, bool function_definition_allowed_p, bool member_p, int declares_class_or_enum, @@ -10379,6 +10471,7 @@ cp_parser_init_declarator (cp_parser* parser, { cp_token *token; cp_declarator *declarator; + tree prefix_attributes; tree attributes; tree asm_specification; tree initializer; @@ -10391,6 +10484,11 @@ cp_parser_init_declarator (cp_parser* parser, bool friend_p; bool pop_p = false; + /* Gather the attributes that were provided with the + decl-specifiers. */ + prefix_attributes = decl_specifiers->attributes; + decl_specifiers->attributes = NULL_TREE; + /* Assume that this is not the declarator for a function definition. */ if (function_definition_p) @@ -10485,7 +10583,7 @@ cp_parser_init_declarator (cp_parser* parser, We explicitly postpone this check past the point where we handle function-definitions because we tolerate function-definitions that are missing their return types in some modes. */ - if (!decl_specifiers && ctor_dtor_or_conv_p <= 0) + if (!decl_specifiers->any_specifiers_p && ctor_dtor_or_conv_p <= 0) { cp_parser_error (parser, "expected constructor, destructor, or type conversion"); @@ -10514,11 +10612,11 @@ cp_parser_init_declarator (cp_parser* parser, sure this was intended to be a declarator. Then continue declaring the variable(s), as int, to try to cut down on further errors. */ - if (decl_specifiers != NULL - && TREE_VALUE (decl_specifiers) == error_mark_node) + if (decl_specifiers->any_specifiers_p + && decl_specifiers->type == error_mark_node) { cp_parser_error (parser, "invalid type in declaration"); - TREE_VALUE (decl_specifiers) = integer_type_node; + decl_specifiers->type = integer_type_node; } /* Check to see whether or not this declaration is a friend. */ @@ -10535,9 +10633,7 @@ cp_parser_init_declarator (cp_parser* parser, { if (parser->in_unbraced_linkage_specification_p) { - decl_specifiers = tree_cons (error_mark_node, - get_identifier ("extern"), - decl_specifiers); + decl_specifiers->storage_class = sc_extern; have_extern_spec = false; } decl = start_decl (declarator, decl_specifiers, @@ -11331,13 +11427,12 @@ cp_parser_declarator_id (cp_parser* parser) static tree cp_parser_type_id (cp_parser* parser) { - tree type_specifier_seq; + cp_decl_specifier_seq type_specifier_seq; cp_declarator *abstract_declarator; /* Parse the type-specifier-seq. */ - type_specifier_seq - = cp_parser_type_specifier_seq (parser); - if (type_specifier_seq == error_mark_node) + cp_parser_type_specifier_seq (parser, &type_specifier_seq); + if (type_specifier_seq.type == error_mark_node) return error_mark_node; /* There might or might not be an abstract declarator. */ @@ -11350,7 +11445,7 @@ cp_parser_type_id (cp_parser* parser) if (!cp_parser_parse_definitely (parser)) abstract_declarator = NULL; - return groktypename (type_specifier_seq, abstract_declarator); + return groktypename (&type_specifier_seq, abstract_declarator); } /* Parse a type-specifier-seq. @@ -11363,14 +11458,16 @@ cp_parser_type_id (cp_parser* parser) type-specifier-seq: attributes type-specifier-seq [opt] - Returns a TREE_LIST. Either the TREE_VALUE of each node is a - type-specifier, or the TREE_PURPOSE is a list of attributes. */ + Sets *TYPE_SPECIFIER_SEQ to represent the sequence. */ -static tree -cp_parser_type_specifier_seq (cp_parser* parser) +static void +cp_parser_type_specifier_seq (cp_parser* parser, + cp_decl_specifier_seq *type_specifier_seq) { bool seen_type_specifier = false; - tree type_specifier_seq = NULL_TREE; + + /* Clear the TYPE_SPECIFIER_SEQ. */ + clear_decl_specs (type_specifier_seq); /* Parse the type-specifiers and attributes. */ while (true) @@ -11380,39 +11477,36 @@ cp_parser_type_specifier_seq (cp_parser* parser) /* Check for attributes first. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)) { - type_specifier_seq = tree_cons (cp_parser_attributes_opt (parser), - NULL_TREE, - type_specifier_seq); + type_specifier_seq->attributes = + chainon (type_specifier_seq->attributes, + cp_parser_attributes_opt (parser)); continue; } - /* After the first type-specifier, others are optional. */ - if (seen_type_specifier) - cp_parser_parse_tentatively (parser); /* Look for the type-specifier. */ type_specifier = cp_parser_type_specifier (parser, - CP_PARSER_FLAGS_NONE, - /*is_friend=*/false, + CP_PARSER_FLAGS_OPTIONAL, + type_specifier_seq, /*is_declaration=*/false, NULL, NULL); /* If the first type-specifier could not be found, this is not a type-specifier-seq at all. */ - if (!seen_type_specifier && type_specifier == error_mark_node) - return error_mark_node; + if (!seen_type_specifier && !type_specifier) + { + cp_parser_error (parser, "expected type-specifier"); + type_specifier_seq->type = error_mark_node; + return; + } /* If subsequent type-specifiers could not be found, the type-specifier-seq is complete. */ - else if (seen_type_specifier && !cp_parser_parse_definitely (parser)) + else if (seen_type_specifier && !type_specifier) break; - /* Add the new type-specifier to the list. */ - type_specifier_seq - = tree_cons (NULL_TREE, type_specifier, type_specifier_seq); seen_type_specifier = true; } - /* We built up the list in reverse order. */ - return nreverse (type_specifier_seq); + return; } /* Parse a parameter-declaration-clause. @@ -11625,8 +11719,7 @@ cp_parser_parameter_declaration (cp_parser *parser, { int declares_class_or_enum; bool greater_than_is_operator_p; - tree decl_specifiers; - tree attributes; + cp_decl_specifier_seq decl_specifiers; cp_declarator *declarator; tree default_argument; cp_token *token; @@ -11648,11 +11741,10 @@ cp_parser_parameter_declaration (cp_parser *parser, = "types may not be defined in parameter types"; /* Parse the declaration-specifiers. */ - decl_specifiers - = cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_NONE, - &attributes, - &declares_class_or_enum); + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_NONE, + &decl_specifiers, + &declares_class_or_enum); /* If an error occurred, there's no reason to attempt to parse the rest of the declaration. */ if (cp_parser_error_occurred (parser)) @@ -11705,7 +11797,9 @@ cp_parser_parameter_declaration (cp_parser *parser, parenthesized_p); parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ - attributes = chainon (attributes, cp_parser_attributes_opt (parser)); + decl_specifiers.attributes + = chainon (decl_specifiers.attributes, + cp_parser_attributes_opt (parser)); } /* The restriction on defining new types applies only to the type @@ -11846,11 +11940,7 @@ cp_parser_parameter_declaration (cp_parser *parser, else default_argument = NULL_TREE; - /* Create the representation of the parameter. */ - if (attributes) - decl_specifiers = tree_cons (attributes, NULL_TREE, decl_specifiers); - - return make_parameter_declarator (decl_specifiers, + return make_parameter_declarator (&decl_specifiers, declarator, default_argument); } @@ -12809,7 +12899,7 @@ cp_parser_member_specification_opt (cp_parser* parser) static void cp_parser_member_declaration (cp_parser* parser) { - tree decl_specifiers; + cp_decl_specifier_seq decl_specifiers; tree prefix_attributes; tree decl; int declares_class_or_enum; @@ -12847,11 +12937,12 @@ cp_parser_member_declaration (cp_parser* parser) } /* Parse the decl-specifier-seq. */ - decl_specifiers - = cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_OPTIONAL, - &prefix_attributes, - &declares_class_or_enum); + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_OPTIONAL, + &decl_specifiers, + &declares_class_or_enum); + prefix_attributes = decl_specifiers.attributes; + decl_specifiers.attributes = NULL_TREE; /* Check for an invalid type-name. */ if (cp_parser_parse_and_diagnose_invalid_type_name (parser)) return; @@ -12868,7 +12959,7 @@ cp_parser_member_declaration (cp_parser* parser) Each member-declaration shall declare at least one member name of the class. */ - if (!decl_specifiers) + if (!decl_specifiers.any_specifiers_p) { if (pedantic) pedwarn ("extra semicolon"); @@ -12878,10 +12969,10 @@ cp_parser_member_declaration (cp_parser* parser) tree type; /* See if this declaration is a friend. */ - friend_p = cp_parser_friend_p (decl_specifiers); + friend_p = cp_parser_friend_p (&decl_specifiers); /* If there were decl-specifiers, check to see if there was a class-declaration. */ - type = check_tag_decl (decl_specifiers); + type = check_tag_decl (&decl_specifiers); /* Nested classes have already been added to the class, but a `friend' needs to be explicitly registered. */ if (friend_p) @@ -12898,27 +12989,10 @@ cp_parser_member_declaration (cp_parser* parser) A::B will be represented by a TYPENAME_TYPE, and therefore not recognized by check_tag_decl. */ - if (!type) - { - tree specifier; - - for (specifier = decl_specifiers; - specifier; - specifier = TREE_CHAIN (specifier)) - { - tree s = TREE_VALUE (specifier); - - if (TREE_CODE (s) == IDENTIFIER_NODE) - get_global_value_if_present (s, &type); - if (TREE_CODE (s) == TYPE_DECL) - s = TREE_TYPE (s); - if (TYPE_P (s)) - { - type = s; - break; - } - } - } + if (!type + && decl_specifiers.type + && TYPE_P (decl_specifiers.type)) + type = decl_specifiers.type; if (!type || !TYPE_P (type)) error ("friend declaration does not name a class or " "function"); @@ -12928,7 +13002,7 @@ cp_parser_member_declaration (cp_parser* parser) } /* If there is no TYPE, an error message will already have been issued. */ - else if (!type) + else if (!type || type == error_mark_node) ; /* An anonymous aggregate has to be handled specially; such a declaration really declares a data member (with a @@ -12950,7 +13024,7 @@ cp_parser_member_declaration (cp_parser* parser) else { /* See if these declarations will be friends. */ - friend_p = cp_parser_friend_p (decl_specifiers); + friend_p = cp_parser_friend_p (&decl_specifiers); /* Keep going until we hit the `;' at the end of the declaration. */ @@ -12999,7 +13073,7 @@ cp_parser_member_declaration (cp_parser* parser) decl = grokbitfield (identifier ? make_id_declarator (identifier) : NULL, - decl_specifiers, + &decl_specifiers, width); /* Apply the attributes. */ cplus_decl_attributes (&decl, attributes, /*flags=*/0); @@ -13095,7 +13169,7 @@ cp_parser_member_declaration (cp_parser* parser) if (initializer) error ("pure-specifier on function-definition"); decl = cp_parser_save_member_function_body (parser, - decl_specifiers, + &decl_specifiers, declarator, attributes); /* If the member was not a friend, declare it here. */ @@ -13111,7 +13185,7 @@ cp_parser_member_declaration (cp_parser* parser) else { /* Create the declaration. */ - decl = grokfield (declarator, decl_specifiers, + decl = grokfield (declarator, &decl_specifiers, initializer, asm_specification, attributes); /* Any initialization must have been from a @@ -13607,7 +13681,7 @@ static tree cp_parser_exception_declaration (cp_parser* parser) { tree decl; - tree type_specifiers; + cp_decl_specifier_seq type_specifiers; cp_declarator *declarator; const char *saved_message; @@ -13625,7 +13699,7 @@ cp_parser_exception_declaration (cp_parser* parser) = "types may not be defined in exception-declarations"; /* Parse the type-specifier-seq. */ - type_specifiers = cp_parser_type_specifier_seq (parser); + cp_parser_type_specifier_seq (parser, &type_specifiers); /* If it's a `)', then there is no declarator. */ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) declarator = NULL; @@ -13637,9 +13711,9 @@ cp_parser_exception_declaration (cp_parser* parser) /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; - if (type_specifiers) + if (type_specifiers.any_specifiers_p) { - decl = grokdeclarator (declarator, type_specifiers, CATCHPARM, 1, NULL); + decl = grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL); if (decl == NULL_TREE) error ("invalid catch parameter"); } @@ -14628,7 +14702,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) /* Look for the type-specifier. */ cp_parser_type_specifier (parser, CP_PARSER_FLAGS_NONE, - /*is_friend=*/false, + /*decl_specs=*/NULL, /*is_declarator=*/true, /*declares_class_or_enum=*/NULL, /*is_cv_qualifier=*/NULL); @@ -14660,7 +14734,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) static tree cp_parser_function_definition_from_specifiers_and_declarator (cp_parser* parser, - tree decl_specifiers, + cp_decl_specifier_seq *decl_specifiers, tree attributes, const cp_declarator *declarator) { @@ -14859,8 +14933,7 @@ cp_parser_single_declaration (cp_parser* parser, { int declares_class_or_enum; tree decl = NULL_TREE; - tree decl_specifiers; - tree attributes; + cp_decl_specifier_seq decl_specifiers; bool function_definition_p = false; /* Defer access checks until we know what is being declared. */ @@ -14868,13 +14941,12 @@ cp_parser_single_declaration (cp_parser* parser, /* Try the `decl-specifier-seq [opt] init-declarator [opt]' alternative. */ - decl_specifiers - = cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_OPTIONAL, - &attributes, - &declares_class_or_enum); + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_OPTIONAL, + &decl_specifiers, + &declares_class_or_enum); if (friend_p) - *friend_p = cp_parser_friend_p (decl_specifiers); + *friend_p = cp_parser_friend_p (&decl_specifiers); /* Gather up the access checks that occurred the decl-specifier-seq. */ stop_deferring_access_checks (); @@ -14884,8 +14956,8 @@ cp_parser_single_declaration (cp_parser* parser, { if (cp_parser_declares_only_class_p (parser)) { - decl = shadow_tag (decl_specifiers); - if (decl) + decl = shadow_tag (&decl_specifiers); + if (decl && decl != error_mark_node) decl = TYPE_NAME (decl); else decl = error_mark_node; @@ -14900,10 +14972,9 @@ cp_parser_single_declaration (cp_parser* parser, In that case, there's no need to warn about a missing declarator. */ if (!decl && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON) - || !value_member (error_mark_node, decl_specifiers))) + || decl_specifiers.type != error_mark_node)) decl = cp_parser_init_declarator (parser, - decl_specifiers, - attributes, + &decl_specifiers, /*function_definition_allowed_p=*/true, member_p, declares_class_or_enum, @@ -14966,7 +15037,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type) static tree cp_parser_save_member_function_body (cp_parser* parser, - tree decl_specifiers, + cp_decl_specifier_seq *decl_specifiers, cp_declarator *declarator, tree attributes) { @@ -15304,14 +15375,15 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) /* If all went well, then we're done. */ if (cp_parser_parse_definitely (parser)) { - /* Build a list of decl-specifiers; right now, we have only - a single type-specifier. */ - type = build_tree_list (NULL_TREE, - type); + cp_decl_specifier_seq decl_specs; + + /* Build a trivial decl-specifier-seq. */ + clear_decl_specs (&decl_specs); + decl_specs.type = type; /* Call grokdeclarator to figure out what type this is. */ expr = grokdeclarator (NULL, - type, + &decl_specs, TYPENAME, /*initialized=*/0, /*attrlist=*/NULL); @@ -15345,24 +15417,49 @@ cp_parser_declares_only_class_p (cp_parser *parser) || cp_lexer_next_token_is (parser->lexer, CPP_COMMA)); } -/* DECL_SPECIFIERS is the representation of a decl-specifier-seq. - Returns TRUE iff `friend' appears among the DECL_SPECIFIERS. */ +/* Update the DECL_SPECS to reflect the STORAGE_CLASS. */ -static bool -cp_parser_friend_p (tree decl_specifiers) +static void +cp_parser_set_storage_class (cp_decl_specifier_seq *decl_specs, + cp_storage_class storage_class) { - while (decl_specifiers) - { - /* See if this decl-specifier is `friend'. */ - if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE - && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_FRIEND) - return true; + if (decl_specs->storage_class != sc_none) + decl_specs->multiple_storage_classes_p = true; + else + decl_specs->storage_class = storage_class; +} + +/* Update the DECL_SPECS to reflect the TYPE_SPEC. If USER_DEFINED_P + is true, the type is a user-defined type; otherwise it is a + built-in type specified by a keyword. */ - /* Go on to the next decl-specifier. */ - decl_specifiers = TREE_CHAIN (decl_specifiers); +static void +cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, + tree type_spec, + bool user_defined_p) +{ + decl_specs->any_specifiers_p = true; + if (decl_specs->type) + { + if (decl_specs->specs[(int)ds_typedef] && !user_defined_p) + decl_specs->redefined_builtin_type = type_spec; + else + decl_specs->multiple_types_p = true; + } + else + { + decl_specs->type = type_spec; + decl_specs->user_defined_type_p = user_defined_p; } +} - return false; +/* DECL_SPECIFIERS is the representation of a decl-specifier-seq. + Returns TRUE iff `friend' appears among the DECL_SPECIFIERS. */ + +static bool +cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers) +{ + return decl_specifiers->specs[(int) ds_friend] != 0; } /* If the next token is of the indicated TYPE, consume it. Otherwise, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e451a29fc20..da2b306af77 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */ #include "cp-tree.h" #include "tree-inline.h" #include "decl.h" -#include "lex.h" #include "output.h" #include "except.h" #include "toplev.h" diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0d4f4a75a97..c9f66d9dc1c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -34,7 +34,6 @@ #include "tree-inline.h" #include "tree-mudflap.h" #include "except.h" -#include "lex.h" #include "toplev.h" #include "flags.h" #include "rtl.h" @@ -2147,36 +2146,6 @@ finish_member_declaration (tree decl) } } -/* Finish processing the declaration of a member class template - TYPES whose template parameters are given by PARMS. */ - -tree -finish_member_class_template (tree types) -{ - tree t; - - /* If there are declared, but undefined, partial specializations - mixed in with the typespecs they will not yet have passed through - maybe_process_partial_specialization, so we do that here. */ - for (t = types; t != NULL_TREE; t = TREE_CHAIN (t)) - if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t)))) - maybe_process_partial_specialization (TREE_VALUE (t)); - - grok_x_components (types); - if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type) - /* The component was in fact a friend declaration. We avoid - finish_member_template_decl performing certain checks by - unsetting TYPES. */ - types = NULL_TREE; - - finish_member_template_decl (types); - - /* As with other component type declarations, we do - not store the new DECL on the list of - component_decls. */ - return NULL_TREE; -} - /* Finish processing a complete template declaration. The PARMS are the template parameters. */