cp-tree.def (NEW_EXPR): Add a fourth slot.
authorMark Mitchell <mark@codesourcery.com>
Tue, 22 Jun 2004 07:18:38 +0000 (07:18 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 22 Jun 2004 07:18:38 +0000 (07:18 +0000)
* cp-tree.def (NEW_EXPR): Add a fourth slot.
* cp-tree.h (PARMLIST_ELLIPSIS_P): Remove.
(TREE_PARMLIST): Likewise.
(CALL_DECLARATOR_PARMS): Likewise.
(CALL_DECLARATOR_QUALS): Likewise.
(CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
(cp_declarator_kind): New type.
(cp_parameter_declarator): Likewise.
(cp_declarator): Likewise.
(cp_error_declarator): Likewise.
(no_parameters): Likewise.
(groktypename): Change prototype.
(start_decl): Likewise.
(start_handler_parms): Likewise.
(get_scope_of_declarator): Likewise.
(start_function): Likewise.
(start_preparsed_function): New function.
(start_function): Change prototype.
(start_method): Likewise.
(grokfield): Likewise.
(grokbitfield): Likewise.
(build_new): Likewise.
(make_pointer_declarator): Remove.
(make_reference_declarator): Likewise.
(make_call_declarator): Likewise.
(set_quals_and_spec): Likewise.
(process_template_parm): Change prototype.
(begin_function_definition): Remove.
(finish_parmlist): Remove.
* decl.c (groktypename): Do not use trees to represent
declarators.
(start_decl): Likewise.
(start_handler_parms): Remove.
(get_scope_of_declarator): Reimplement.
(grokdeclarator): Do not use trees to represent declarators.
(grokparms): Likewise.
(start_function): Likewise.
(start_method): Likewise.
(build_void_list_mode): Do not use TREE_PARMLIST.
* decl.h (grokdeclarator): Change prototype.
* decl2.c (grok_method_quals): Robustify.
(grok_x_components): Do not use trees to represent declarators.
(grokfield): Likewise.
(grokbitfield): Likewise.
(start_objects): Build FUNCTION_DECLs, not declarators.
(start_static_storage_duration_function): Likewise.
* init.c (build_new): Simplify.
* lex.c (make_pointer_declarator): Remove.
(make_reference_declarator): Likewise.
(make_call_declarator): Likewise.
(set_quals_and_spec): Likewise.
* method.c (use_thunk): Use start_preparsed_function.
(synthesize_method): Likewise.
(implicitly_declare_fn): Build FUNCTION_DECLs, not declarators.
* optimize.c (maybe_clone_body): Use start_preparsed_function.
* parser.c (cp_error_declarator): New variable.
(declarator_obstack): Likewise.
(alloc_declarator): New function.
(make_declarator): Likewise.
(make_id_declarator): Likewise.
(make_pointer_declarator): Likewise.
(make_reference_declarator): Likewise.
(make_ptrmem_declarator): Likewise.
(make_call_declarator): Likewise.
(make_array_declarator): Likewise.
(no_parameters): New variable.
(make_parameter_declarator): Likewise.
(cp_parser_check_for_definition_in_return_type): Do not use trees
to represent declarators.
(cp_parser_translation_unit): Likewise.
(cp_parser_new_expression): Likewise.
(cp_parser_new_type_id): Likewise.
(cp_parser_new_declarator_opt): Likewise.
(cp_parser_direct_new_declarator): Likewise.
(cp_parser_condition): Likewise.
(cp_parser_declaration_statement): Likewise.
(cp_parser_declaration): Likewise.
(cp_parser_conversion_type_id): Likewise.
(cp_parser_conversion_declarator_opt): Likewise.
(cp_parser_template_parameter_list): Likewise.
(cp_parser_template_parameter): Likewise.
(cp_parser_explicit_instantiation): Likewise.
(cp_parser_init_declarator): Likewise.
(cp_parser_declarator): Likewise.
(cp_parser_direct_declarator): Likewise.
(cp_parser_type_id): Likewise.
(cp_parser_parameter_declaration_clause): Likewise.
(cp_parser_parameter_declaration_list): Likewise.
(cp_parser_parameter_declaration): Likewise.
(cp_parser_member_declaration): Likewise.
(cp_parser_exception_declaration): Likewise.
(cp_parser_check_declarator_template_parameters): Likewise.
(cp_parser_function_definition_from_specifiers_and_declarator):
Likewise.
(cp_parser_save_member_function_body): Likewise.
* pt.c (process_template_parm): Add is_non_type parameter.
(convert_template_argument): Adjust call to groktypename.
(tsubst_call_declarator_parms): Remove use of TREE_PARMLIST.
(tsubst): Do not expect declarators.
(tsubst_copy_and_build): Adjust NEW_EXPR case to handle additional
argument.
(instantiate_decl): Use start_preparsed_function.
* semantics.c (begin_function_definition): Remove.
(finish_parmlist): Remove.
* cp-mudflap.c (mflang_flush_calls): Build FUNCTION_DECLs, not
declarators.

From-SVN: r83482

14 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-mudflap.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl.h
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/optimize.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c

index d8b494bdff6887cd9f4da8f0c78231f1186773a1..05ddba31d7b2471eb7bd2ee23a5bec567dd009ae 100644 (file)
@@ -1,3 +1,112 @@
+2004-06-21  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.def (NEW_EXPR): Add a fourth slot.
+       * cp-tree.h (PARMLIST_ELLIPSIS_P): Remove.
+       (TREE_PARMLIST): Likewise.
+       (CALL_DECLARATOR_PARMS): Likewise.
+       (CALL_DECLARATOR_QUALS): Likewise.
+       (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
+       (cp_declarator_kind): New type.
+       (cp_parameter_declarator): Likewise.
+       (cp_declarator): Likewise.
+       (cp_error_declarator): Likewise.
+       (no_parameters): Likewise.
+       (groktypename): Change prototype.
+       (start_decl): Likewise.
+       (start_handler_parms): Likewise.
+       (get_scope_of_declarator): Likewise.
+       (start_function): Likewise.
+       (start_preparsed_function): New function.
+       (start_function): Change prototype.
+       (start_method): Likewise.
+       (grokfield): Likewise.
+       (grokbitfield): Likewise.
+       (build_new): Likewise.
+       (make_pointer_declarator): Remove.
+       (make_reference_declarator): Likewise.
+       (make_call_declarator): Likewise.
+       (set_quals_and_spec): Likewise.
+       (process_template_parm): Change prototype.
+       (begin_function_definition): Remove.
+       (finish_parmlist): Remove.
+       * decl.c (groktypename): Do not use trees to represent
+       declarators.
+       (start_decl): Likewise.
+       (start_handler_parms): Remove.
+       (get_scope_of_declarator): Reimplement.
+       (grokdeclarator): Do not use trees to represent declarators.
+       (grokparms): Likewise.
+       (start_function): Likewise.
+       (start_method): Likewise.
+       (build_void_list_mode): Do not use TREE_PARMLIST.
+       * decl.h (grokdeclarator): Change prototype.
+       * decl2.c (grok_method_quals): Robustify.
+       (grok_x_components): Do not use trees to represent declarators.
+       (grokfield): Likewise.
+       (grokbitfield): Likewise.
+       (start_objects): Build FUNCTION_DECLs, not declarators.
+       (start_static_storage_duration_function): Likewise.
+       * init.c (build_new): Simplify.
+       * lex.c (make_pointer_declarator): Remove.
+       (make_reference_declarator): Likewise.
+       (make_call_declarator): Likewise.
+       (set_quals_and_spec): Likewise.
+       * method.c (use_thunk): Use start_preparsed_function.
+       (synthesize_method): Likewise.
+       (implicitly_declare_fn): Build FUNCTION_DECLs, not declarators.
+       * optimize.c (maybe_clone_body): Use start_preparsed_function.
+       * parser.c (cp_error_declarator): New variable.
+       (declarator_obstack): Likewise.
+       (alloc_declarator): New function.
+       (make_declarator): Likewise.
+       (make_id_declarator): Likewise.
+       (make_pointer_declarator): Likewise.
+       (make_reference_declarator): Likewise.
+       (make_ptrmem_declarator): Likewise.
+       (make_call_declarator): Likewise.
+       (make_array_declarator): Likewise.
+       (no_parameters): New variable.
+       (make_parameter_declarator): Likewise.
+       (cp_parser_check_for_definition_in_return_type): Do not use trees
+       to represent declarators.
+       (cp_parser_translation_unit): Likewise.
+       (cp_parser_new_expression): Likewise.
+       (cp_parser_new_type_id): Likewise.
+       (cp_parser_new_declarator_opt): Likewise.
+       (cp_parser_direct_new_declarator): Likewise.
+       (cp_parser_condition): Likewise.
+       (cp_parser_declaration_statement): Likewise.
+       (cp_parser_declaration): Likewise.
+       (cp_parser_conversion_type_id): Likewise.
+       (cp_parser_conversion_declarator_opt): Likewise.
+       (cp_parser_template_parameter_list): Likewise.
+       (cp_parser_template_parameter): Likewise.
+       (cp_parser_explicit_instantiation): Likewise.
+       (cp_parser_init_declarator): Likewise.
+       (cp_parser_declarator): Likewise.
+       (cp_parser_direct_declarator): Likewise.
+       (cp_parser_type_id): Likewise.
+       (cp_parser_parameter_declaration_clause): Likewise.
+       (cp_parser_parameter_declaration_list): Likewise.
+       (cp_parser_parameter_declaration): Likewise.
+       (cp_parser_member_declaration): Likewise.
+       (cp_parser_exception_declaration): Likewise.
+       (cp_parser_check_declarator_template_parameters): Likewise.
+       (cp_parser_function_definition_from_specifiers_and_declarator):
+       Likewise.
+       (cp_parser_save_member_function_body): Likewise.
+       * pt.c (process_template_parm): Add is_non_type parameter.
+       (convert_template_argument): Adjust call to groktypename.
+       (tsubst_call_declarator_parms): Remove use of TREE_PARMLIST.
+       (tsubst): Do not expect declarators.
+       (tsubst_copy_and_build): Adjust NEW_EXPR case to handle additional
+       argument.
+       (instantiate_decl): Use start_preparsed_function.
+       * semantics.c (begin_function_definition): Remove.
+       (finish_parmlist): Remove.
+       * cp-mudflap.c (mflang_flush_calls): Build FUNCTION_DECLs, not
+       declarators.
+
 2004-06-21  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
index faa57e2df5e2499d10ceb5a7379fe5470b310d25..23e875029d6de73b34b6052d2d2411834c21732f 100644 (file)
@@ -63,6 +63,7 @@ void
 mflang_flush_calls (tree enqueued_call_stmt_chain)
 {
   tree fnname, fndecl, body;
+  tree type;
 
   /* Short-circuit!  */
   if (enqueued_call_stmt_chain == NULL_TREE)
@@ -70,11 +71,8 @@ mflang_flush_calls (tree enqueued_call_stmt_chain)
 
   /* Create a ctor function declaration.  */
   fnname = get_identifier ("__static_initialization_and_destruction_mudflap");
-
-  start_function (void_list_node,
-                 make_call_declarator (fnname, void_list_node, NULL_TREE,
-                                       NULL_TREE),
-                 NULL_TREE, SF_DEFAULT);
+  type = build_function_type (void_type_node, void_list_node);
+  fndecl = build_lang_decl (FUNCTION_DECL, fnname, type);
 
   TREE_PUBLIC (current_function_decl) = 0;
   TREE_USED (current_function_decl) = 1;
@@ -82,6 +80,7 @@ mflang_flush_calls (tree enqueued_call_stmt_chain)
   mf_mark (current_function_decl);
 
   /* Generate the body, one statement at a time.  */
+  start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
   body = begin_compound_stmt (BCS_FN_BODY);
 
   while (enqueued_call_stmt_chain)
index 4f7961b7b8aeca556c81cd603de367132436d2b9..f1912b17438ec949568a850ea359543d6c8bd102 100644 (file)
@@ -51,8 +51,9 @@ DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 0)
 
 /* For NEW_EXPR, operand 0 is the placement list.
    Operand 1 is the new-declarator.
-   Operand 2 is the initializer.  */
-DEFTREECODE (NEW_EXPR, "nw_expr", 'e', 3)
+   Operand 2 is the number of elements in the array.
+   Operand 3 is the initializer.  */
+DEFTREECODE (NEW_EXPR, "nw_expr", 'e', 4)
 DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", 'e', 3)
 
 /* For DELETE_EXPR, operand 0 is the store to be destroyed.
index 9d668d398b76aeee812d104010cc2478ad810a27..e29e084e0bb20582730cfe0742a2280019e972a7 100644 (file)
@@ -45,7 +45,6 @@ struct diagnostic_context;
       CLEANUP_P (in TRY_BLOCK)
       AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
       PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
-      PARMLIST_ELLIPSIS_P (in PARMLIST)
       DECL_PRETTY_FUNCTION_P (in VAR_DECL)
       KOENIG_LOOKUP_P (in CALL_EXPR)
       STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST).
@@ -64,7 +63,6 @@ struct diagnostic_context;
       TYPE_POLYMORPHIC_P (in _TYPE)
       ICS_THIS_FLAG (in _CONV)
       BINFO_LOST_PRIMARY_P (in BINFO)
-      TREE_PARMLIST (in TREE_LIST)
       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
       STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST)
    3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
@@ -1566,13 +1564,6 @@ struct lang_type GTY(())
 #define BV_FN(NODE) (TREE_VALUE (NODE))
 
 \f
-/* Nonzero for TREE_LIST node means that this list of things
-   is a list of parameters, as opposed to a list of expressions.  */
-#define TREE_PARMLIST(NODE) (TREE_LANG_FLAG_2 (NODE))
-
-/* Nonzero for a parmlist means that this parmlist ended in ...  */
-#define PARMLIST_ELLIPSIS_P(NODE) TREE_LANG_FLAG_0 (NODE)
-
 /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
    this type can raise.  Each TREE_VALUE is a _TYPE.  The TREE_VALUE
    will be NULL_TREE to indicate a throw specification of `()', or
@@ -2953,18 +2944,6 @@ struct lang_decl GTY(())
 #define THEN_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
 #define ELSE_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
 
-/* The parameters for a call-declarator.  */
-#define CALL_DECLARATOR_PARMS(NODE) \
-  (TREE_PURPOSE (TREE_OPERAND (NODE, 1)))
-
-/* The cv-qualifiers for a call-declarator.  */
-#define CALL_DECLARATOR_QUALS(NODE) \
-  (TREE_VALUE (TREE_OPERAND (NODE, 1)))
-
-/* The exception-specification for a call-declarator.  */
-#define CALL_DECLARATOR_EXCEPTION_SPEC(NODE) \
-  (TREE_TYPE (NODE))
-
 /* An enumeration of the kind of tags that C++ accepts.  */
 enum tag_types { 
   none_type = 0, /* Not a tag type.  */
@@ -3529,6 +3508,89 @@ extern GTY(()) operator_name_info_t operator_name_info
 extern GTY(()) operator_name_info_t assignment_operator_name_info
   [(int) LAST_CPLUS_TREE_CODE];
 
+/* The various kinds of declarators.  */
+
+typedef enum cp_declarator_kind {
+  cdk_id,
+  cdk_function,
+  cdk_array,
+  cdk_pointer,
+  cdk_reference,
+  cdk_ptrmem,
+  cdk_error
+} cp_declarator_kind;
+
+/* A declarator.  */
+
+typedef struct cp_declarator cp_declarator;
+
+typedef struct cp_parameter_declarator cp_parameter_declarator;
+
+/* A parameter, before it has been semantically analyzed.  */
+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;
+  /* The declarator for the parameter.  */
+  cp_declarator *declarator;
+  /* The default-argument expression, or NULL_TREE, if none.  */
+  tree default_argument;
+  /* True iff this is the first parameter in the list and the
+     parameter sequence ends with an ellipsis.  */
+  bool ellipsis_p;
+};
+
+/* A declarator.  */
+struct cp_declarator {
+  /* The kind of declarator.  */
+  cp_declarator_kind kind;
+  /* Attributes that apply to this declarator.  */
+  tree attributes;
+  /* For all but cdk_id and cdk_error, the contained declarator.  For
+     cdk_id and cdk_error, guaranteed to be NULL.  */
+  cp_declarator *declarator;
+  union {
+    /* For identifiers.  */
+    struct {
+      /* The name of the function -- an IDENTIFIER_NODE, BIT_NOT_EXPR,
+        TEMPLATE_ID_EXPR, or SCOPE_REF.  */
+      tree name;
+      /* If this is the name of a function, what kind of special
+        function (if any).  */
+      special_function_kind sfk;
+    } id;
+    /* For functions.  */
+    struct {
+      /* The parameters to the function.  */
+      cp_parameter_declarator *parameters;
+      /* The cv-qualifiers for the function.  */
+      tree qualifiers;
+      /* The exception-specification for the function.  */
+      tree exception_specification;
+    } function;
+    /* For arrays.  */
+    struct {
+      /* The bounds to the array.  */
+      tree bounds;
+    } array;
+    /* For cdk_pointer, cdk_reference, and cdk_ptrmem.  */
+    struct {
+      /* The cv-qualifiers for the pointer.  */
+      tree qualifiers;
+      /* For cdk_ptrmem, the class type containing the member.  */
+      tree class_type;
+    } pointer;
+  } u;
+};
+
+/* An erroneous declarator.  */
+extern cp_declarator *cp_error_declarator;
+
+/* A parameter list indicating for a function with no parameters,
+   e.g  "int f(void)".  */
+extern cp_parameter_declarator *no_parameters;
+
 /* in call.c */
 extern bool check_dtor_name (tree, tree);
 
@@ -3674,19 +3736,18 @@ 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);
-extern tree start_decl                         (tree, tree, int, tree, tree);
+extern tree groktypename                       (tree, const cp_declarator *);
+extern tree start_decl                         (const cp_declarator *, tree, 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);
 extern void maybe_inject_for_scope_var          (tree);
-extern tree start_handler_parms                 (tree, tree);
 extern int complete_array_type                 (tree, tree, int);
 extern tree build_ptrmemfunc_type              (tree);
 extern tree build_ptrmem_type                   (tree, tree);
 /* the grokdeclarator prototype is in decl.h */
 extern int copy_fn_p                           (tree);
-extern tree get_scope_of_declarator             (tree);
+extern tree get_scope_of_declarator             (const cp_declarator *);
 extern void grok_special_member_properties     (tree);
 extern int grok_ctor_properties                        (tree, tree);
 extern bool grok_op_properties                 (tree, int, bool);
@@ -3696,11 +3757,12 @@ extern void xref_basetypes                      (tree, tree);
 extern tree start_enum                         (tree);
 extern void finish_enum                                (tree);
 extern void build_enumerator                   (tree, tree, tree);
-extern int start_function                      (tree, tree, tree, int);
+extern void start_preparsed_function            (tree, tree, int);
+extern int start_function                      (tree, 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, tree, tree);
+extern tree start_method                       (tree, const cp_declarator *, tree);
 extern tree finish_method                      (tree);
 extern void maybe_register_incomplete_var       (tree);
 extern void complete_vars                      (tree);
@@ -3749,8 +3811,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 (tree, tree, tree, tree, tree);
-extern tree grokbitfield (tree, tree, tree);
+extern tree grokfield (const cp_declarator *, tree, tree, tree, tree);
+extern tree grokbitfield (const cp_declarator *, tree, tree);
 extern tree groktypefield                      (tree, tree);
 extern void cplus_decl_attributes (tree *, tree, int);
 extern void finish_anon_union (tree);
@@ -3828,7 +3890,7 @@ extern tree get_aggr_from_typedef         (tree, int);
 extern tree get_type_value                     (tree);
 extern tree build_zero_init                    (tree, tree, bool);
 extern tree build_offset_ref                   (tree, tree, bool);
-extern tree build_new                          (tree, tree, tree, int);
+extern tree build_new                          (tree, tree, tree, tree, int);
 extern tree build_vec_init                     (tree, tree, tree, int);
 extern tree build_x_delete                     (tree, int, tree);
 extern tree build_delete                       (tree, tree, special_function_kind, int, int);
@@ -3839,14 +3901,8 @@ extern tree create_temporary_var                (tree);
 extern void initialize_vtbl_ptrs                (tree);
 extern tree build_java_class_ref                (tree);
 
-/* in input.c */
-
 /* in lex.c */
 extern void cxx_dup_lang_specific_decl         (tree);
-extern tree make_pointer_declarator            (tree, tree);
-extern tree make_reference_declarator          (tree, tree);
-extern tree make_call_declarator               (tree, tree, tree, tree);
-extern void set_quals_and_spec                 (tree, tree, tree);
 extern void print_parse_statistics             (void);
 extern void do_pending_inlines                 (void);
 extern void yyungetc                           (int, int);
@@ -3892,7 +3948,7 @@ extern void end_specialization                  (void);
 extern void begin_explicit_instantiation        (void);
 extern void end_explicit_instantiation          (void);
 extern tree check_explicit_specialization       (tree, tree, int, int);
-extern tree process_template_parm              (tree, tree);
+extern tree process_template_parm              (tree, tree, bool);
 extern tree end_template_parm_list             (tree);
 extern void end_template_decl                  (void);
 extern tree current_template_args              (void);
@@ -4095,11 +4151,9 @@ extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
 extern tree finish_unary_op_expr                (enum tree_code, tree);
 extern tree finish_compound_literal             (tree, tree);
 extern tree finish_fname                        (tree);
-extern int begin_function_definition            (tree, tree, tree);
 extern void finish_translation_unit             (void);
 extern tree finish_template_type_parm           (tree, tree);
 extern tree finish_template_template_parm       (tree, tree);
-extern tree finish_parmlist                     (tree, int);
 extern tree begin_class_definition              (tree);
 extern void finish_default_args                 (void);
 extern tree finish_member_class_template        (tree);
index 55ce6841723c7cd0af8bade3869a99bc8d042c79..66f6b36e9fed9ff76da4faf0b749e3e4cc3e83fb 100644 (file)
@@ -53,7 +53,7 @@ Boston, MA 02111-1307, USA.  */
 #include "timevar.h"
 #include "tree-flow.h"
 
-static tree grokparms (tree, tree *);
+static tree grokparms (const cp_parameter_declarator *, tree *);
 static const char *redeclaration_error_message (tree, tree);
 
 static int decl_jump_unsafe (tree);
@@ -3564,8 +3564,8 @@ shadow_tag (tree declspecs)
 
       if (TYPE_FIELDS (t))
        {
-         tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,
-                                     NULL);
+         tree decl = grokdeclarator (/*declarator=*/NULL, 
+                                     declspecs, NORMAL, 0, NULL);
          finish_anon_union (decl);
        }
     }
@@ -3576,15 +3576,12 @@ shadow_tag (tree declspecs)
 /* Decode a "typename", such as "int **", returning a ..._TYPE node.  */
 
 tree
-groktypename (tree typename)
+groktypename (tree type_specifiers, const cp_declarator *declarator)
 {
   tree specs, attrs;
   tree type;
-  if (TREE_CODE (typename) != TREE_LIST)
-    return typename;
-  split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
-  type = grokdeclarator (TREE_VALUE (typename), specs,
-                        TYPENAME, 0, &attrs);
+  split_specs_attrs (type_specifiers, &specs, &attrs);
+  type = grokdeclarator (declarator, specs, TYPENAME, 0, &attrs);
   if (attrs)
     cplus_decl_attributes (&type, attrs, 0);
   return type;
@@ -3606,7 +3603,7 @@ groktypename (tree typename)
    grokfield and not through here.  */
 
 tree
-start_decl (tree declarator, 
+start_decl (const cp_declarator *declarator, 
             tree declspecs, 
             int initialized, 
             tree attributes, 
@@ -5122,7 +5119,7 @@ start_cleanup_fn (void)
     }
 
   pushdecl (fndecl);
-  start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED);
+  start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
 
   interface_unknown = old_interface_unknown;
   interface_only = old_interface_only;
@@ -5284,25 +5281,6 @@ expand_static_init (tree decl, tree init)
     static_aggregates = tree_cons (init, decl, static_aggregates);
 }
 
-/* Finish the declaration of a catch-parameter.  */
-
-tree
-start_handler_parms (tree declspecs, tree declarator)
-{
-  tree decl;
-  if (declspecs)
-    {
-      decl = grokdeclarator (declarator, declspecs, CATCHPARM,
-                            1, NULL);
-      if (decl == NULL_TREE)
-       error ("invalid catch parameter");
-    }
-  else
-    decl = NULL_TREE;
-
-  return decl;
-}
-
 \f
 /* Make TYPE a complete type based on INITIAL_VALUE.
    Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
@@ -6140,40 +6118,21 @@ compute_array_index_type (tree name, tree size)
    unqualified name, NULL_TREE is returned.  */
 
 tree
-get_scope_of_declarator (tree declarator)
+get_scope_of_declarator (const cp_declarator *declarator)
 {
-  if (!declarator)
-    return NULL_TREE;
-  
-  switch (TREE_CODE (declarator))
-    {
-    case CALL_EXPR:
-    case ARRAY_REF:
-    case INDIRECT_REF:
-    case ADDR_EXPR:
-      /* For any of these, the main declarator is the first operand.  */
-      return get_scope_of_declarator (TREE_OPERAND
-                                     (declarator, 0));
-
-    case SCOPE_REF:
-      /* For a pointer-to-member, continue descending.  */
-      if (TREE_CODE (TREE_OPERAND (declarator, 1))
-         == INDIRECT_REF)
-       return get_scope_of_declarator (TREE_OPERAND
-                                       (declarator, 1));
-      /* Otherwise, if the declarator-id is a SCOPE_REF, the scope in
-        which the declaration occurs is the first operand.  */
-      return TREE_OPERAND (declarator, 0);
-
-    case TREE_LIST:
-      /* Attributes to be applied. The declarator is TREE_VALUE.  */
-      return get_scope_of_declarator (TREE_VALUE (declarator));
-      
-    default:
-      /* Otherwise, we have a declarator-id which is not a qualified
-        name; the entity will be declared in the current scope.  */
-      return NULL_TREE;
-    }
+  while (declarator && declarator->kind != cdk_id)
+    declarator = declarator->declarator;
+
+  /* If the declarator-id is a SCOPE_REF, the scope in which the
+     declaration occurs is the first operand.  */
+  if (declarator
+      && declarator->u.id.name
+      && TREE_CODE (declarator->u.id.name) == SCOPE_REF)
+    return TREE_OPERAND (declarator->u.id.name, 0);
+
+  /* Otherwise, the declarator is not a quablified name; the entity will
+     be declared in the current scope.  */
+  return NULL_TREE;
 }
 
 /* Returns an ARRAY_TYPE for an array with SIZE elements of the
@@ -6332,7 +6291,7 @@ check_special_function_return_type (special_function_kind sfk,
    should not be `S'.  */
 
 tree
-grokdeclarator (tree declarator,
+grokdeclarator (const cp_declarator *declarator,
                 tree declspecs,
                 enum decl_context decl_context,
                 int initialized,
@@ -6352,10 +6311,10 @@ grokdeclarator (tree declarator,
   tree dependant_name = NULL_TREE;
   
   tree typedef_decl = NULL_TREE;
-  const char *name;
+  const char *name = NULL;
   tree typedef_type = NULL_TREE;
   int funcdef_flag = 0;
-  enum tree_code innermost_code = ERROR_MARK;
+  cp_declarator_kind innermost_code = cdk_error;
   int bitfield = 0;
 #if 0
   /* See the code below that used this.  */
@@ -6368,16 +6327,27 @@ grokdeclarator (tree declarator,
   special_function_kind sfk = sfk_none;
 
   tree dname = NULL_TREE;
-  tree ctype = current_class_type;
   tree ctor_return_type = NULL_TREE;
   enum overload_flags flags = NO_SPECIAL;
   tree quals = NULL_TREE;
   tree raises = NULL_TREE;
   int template_count = 0;
-  tree in_namespace = NULL_TREE;
   tree returned_attrs = NULL_TREE;
-  tree scope = NULL_TREE;
   tree parms = NULL_TREE;
+  const cp_declarator *id_declarator;
+  /* The unqualified name of the declarator; either an
+     IDENTIFIER_NODE, BIT_NOT_EXPR, or TEMPLATE_ID_EXPR.  */
+  tree unqualified_id;
+  /* The class type, if any, in which this entity is located,
+     or NULL_TREE if none.  Note that this value may be different from
+     the current class type; for example if an attempt is made to declare
+     "A::f" inside "B", this value will be "A".  */
+  tree ctype = current_class_type;
+  /* The NAMESPACE_DECL for the namespace in which this entity is
+     located.  If an unqualified name is used to declare the entity,
+     this value will be NULL_TREE, even if the entity is located at
+     namespace scope.  */ 
+  tree in_namespace = NULL_TREE;
 
   RIDBIT_RESET_ALL (specbits);
   if (decl_context == FUNCDEF)
@@ -6389,186 +6359,35 @@ grokdeclarator (tree declarator,
 
   /* Look inside a declarator for the name being declared
      and get it as a string, for an error message.  */
-  {
-    tree *next = &declarator;
-    tree decl;
-    name = NULL;
-
-    while (next && *next)
-      {
-       decl = *next;
-       switch (TREE_CODE (decl))
-         {
-         case TREE_LIST:
-           /* For attributes.  */
-           next = &TREE_VALUE (decl);
-           break;
-
-         case COND_EXPR:
-           ctype = NULL_TREE;
-           next = &TREE_OPERAND (decl, 0);
-           break;
+  for (id_declarator = declarator; 
+       id_declarator; 
+       id_declarator = id_declarator->declarator)
+    {
+      if (id_declarator->kind != cdk_id)
+       innermost_code = id_declarator->kind;
 
-         case BIT_NOT_EXPR:    /* For C++ destructors!  */
+      switch (id_declarator->kind)
+       {
+       case cdk_function:
+         if (id_declarator->declarator
+             && id_declarator->declarator->kind == cdk_id)
            {
-             tree name = TREE_OPERAND (decl, 0);
-             tree rename = NULL_TREE;
-
-             my_friendly_assert (flags == NO_SPECIAL, 152);
-             flags = DTOR_FLAG;
-             sfk = sfk_destructor;
-             if (TYPE_P (name))
-               TREE_OPERAND (decl, 0) = name = constructor_name (name);
-             my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
-             if (ctype == NULL_TREE)
-               {
-                 if (current_class_type == NULL_TREE)
-                   {
-                     error ("destructors must be member functions");
-                     flags = NO_SPECIAL;
-                   }
-                 else
-                   {
-                     tree t = constructor_name (current_class_type);
-                     if (t != name)
-                       rename = t;
-                   }
-               }
-             else
-               {
-                 tree t = constructor_name (ctype);
-                 if (t != name)
-                   rename = t;
-               }
-
-             if (rename)
-               {
-                 error ("destructor `%T' must match class name `%T'",
-                           name, rename);
-                 TREE_OPERAND (decl, 0) = rename;
-               }
-             next = &name;
+             sfk = id_declarator->declarator->u.id.sfk;
+             if (sfk == sfk_destructor)
+               flags = DTOR_FLAG;
            }
-           break;
-
-         case ADDR_EXPR:       /* C++ reference declaration */
-           /* Fall through.  */
-         case ARRAY_REF:
-         case INDIRECT_REF:
-           ctype = NULL_TREE;
-           innermost_code = TREE_CODE (decl);
-           next = &TREE_OPERAND (decl, 0);
-           break;
-
-         case CALL_EXPR:
-           innermost_code = TREE_CODE (decl);
-           if (decl_context == FIELD && ctype == NULL_TREE)
-             ctype = current_class_type;
-           if (ctype
-               && TREE_OPERAND (decl, 0)
-               && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL
-                   && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 0)),
-                                          ctype)))
-             TREE_OPERAND (decl, 0) = constructor_name (ctype);
-           next = &TREE_OPERAND (decl, 0);
-           decl = *next;
-           if (ctype != NULL_TREE
-               && decl != NULL_TREE && flags != DTOR_FLAG
-               && constructor_name_p (decl, ctype))
-             {
-               sfk = sfk_constructor;
-               ctor_return_type = ctype;
-             }
-           ctype = NULL_TREE;
-           break;
-
-         case TEMPLATE_ID_EXPR:
-             {
-               tree fns = TREE_OPERAND (decl, 0);
-
-               dname = fns;
-               if (TREE_CODE (dname) == COMPONENT_REF)
-                 dname = TREE_OPERAND (dname, 1);
-               if (TREE_CODE (dname) != IDENTIFIER_NODE)
-                 {
-                   my_friendly_assert (is_overloaded_fn (dname),
-                                       19990331);
-                   dname = DECL_NAME (get_first_fn (dname));
-                 }
-             }
-         /* Fall through.  */
-
-         case IDENTIFIER_NODE:
-           if (TREE_CODE (decl) == IDENTIFIER_NODE)
-             dname = decl;
-
-           next = 0;
+         break;
 
-           if (C_IS_RESERVED_WORD (dname))
-             {
-               error ("declarator-id missing; using reserved word `%D'",
-                         dname);
-               name = IDENTIFIER_POINTER (dname);
-             }
-           else if (!IDENTIFIER_TYPENAME_P (dname))
-             name = IDENTIFIER_POINTER (dname);
-           else
+       case cdk_id:
+         {
+           tree decl = id_declarator->u.id.name;
+           if (!decl)
+             break;
+           if (TREE_CODE (decl) == SCOPE_REF)
              {
-               my_friendly_assert (flags == NO_SPECIAL, 154);
-               flags = TYPENAME_FLAG;
-               ctor_return_type = TREE_TYPE (dname);
-               sfk = sfk_conversion;
-               if (is_typename_at_global_scope (dname))
-                 name = IDENTIFIER_POINTER (dname);
-               else
-                 name = "<invalid operator>";
-             }
-           break;
-
-           /* C++ extension */
-         case SCOPE_REF:
-           {
-             /* Perform error checking, and decide on a ctype.  */
-             tree cname = TREE_OPERAND (decl, 0);
-             if (cname == NULL_TREE)
-               ctype = NULL_TREE;
-             else if (TREE_CODE (cname) == NAMESPACE_DECL)
-               {
-                 ctype = NULL_TREE;
-                 in_namespace = TREE_OPERAND (decl, 0);
-               }
-             else if (! is_aggr_type (cname, 1))
-               ctype = NULL_TREE;
-             /* Must test TREE_OPERAND (decl, 1), in case user gives
-                us `typedef (class::memfunc)(int); memfunc *memfuncptr;'  */
-             else if (TREE_OPERAND (decl, 1)
-                      && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
-               ctype = cname;
-             else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
-                      || TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
-               {
-                 /* This might be declaring a member of a template
-                    parm to be a friend.  */
-                 ctype = cname;
-                 dependant_name = TREE_OPERAND (decl, 1);
-               }
-             else if (ctype == NULL_TREE)
-               ctype = cname;
-             else if (TREE_COMPLEXITY (decl) == current_class_depth)
-               ;
-             else
-               {
-                 if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
-                   {
-                     error ("type `%T' is not derived from type `%T'",
-                               cname, ctype);
-                     ctype = NULL_TREE;
-                   }
-                 else
-                   ctype = cname;
-               }
-
-             /* It is valid to write:
+               tree qualifying_scope = TREE_OPERAND (decl, 0);
+;
+               /* It is valid to write:
 
                   class C { void f(); };
                   typedef C D;
@@ -6578,93 +6397,112 @@ grokdeclarator (tree declarator,
                 legal; as of 2002-09-15 the committee is considering
                 that question.  EDG 3.0 allows that syntax.
                 Therefore, we do as well.  */
-             if (ctype)
-               ctype = TYPE_MAIN_VARIANT (ctype);
-             /* Update the declarator so that when we process it
-                again the correct type is present.  */
-             TREE_OPERAND (decl, 0) = ctype;
-
-             if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
-                 && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)),
-                                        ctype))
-               TREE_OPERAND (decl, 1) = constructor_name (ctype);
-             next = &TREE_OPERAND (decl, 1);
-             decl = *next;
-             if (ctype)
+               if (qualifying_scope && TYPE_P (qualifying_scope))
+                 {
+                   ctype = TYPE_MAIN_VARIANT (qualifying_scope); 
+                   if (innermost_code != cdk_function
+                       && current_class_type
+                       && !UNIQUELY_DERIVED_FROM_P (ctype, 
+                                                    current_class_type))
+                     {
+                       error ("type `%T' is not derived from type `%T'",
+                              ctype, current_class_type);
+                       ctype = NULL_TREE;
+                     }
+                   TREE_OPERAND (decl, 0) = ctype; 
+                 }
+               else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
+                 in_namespace = qualifying_scope;
+               decl = TREE_OPERAND (decl, 1);
+             }
+           if (TREE_CODE (decl) == BASELINK)
+             decl = BASELINK_FUNCTIONS (decl);
+           switch (TREE_CODE (decl))
+             {
+             case BIT_NOT_EXPR:
                {
-                 tree name = decl;
+                 tree type = TREE_OPERAND (decl, 0);
+                 type = constructor_name (type);
+                 name = IDENTIFIER_POINTER (type);
+               }
+               break;
 
-                 if (TREE_CODE (name) == BIT_NOT_EXPR)
-                   name = TREE_OPERAND (name, 0);
+             case TEMPLATE_ID_EXPR:
+               {
+                 tree fns = TREE_OPERAND (decl, 0);
 
-                 if (!constructor_name_p (decl, ctype))
-                   ;
-                 else if (decl == name)
-                   {
-                     sfk = sfk_constructor;
-                     ctor_return_type = ctype;
-                   }
-                 else
+                 dname = fns;
+                 if (TREE_CODE (dname) == COMPONENT_REF)
+                   dname = TREE_OPERAND (dname, 1);
+                 if (TREE_CODE (dname) != IDENTIFIER_NODE)
                    {
-                     sfk = sfk_destructor;
-                     ctor_return_type = ctype;
-                     flags = DTOR_FLAG;
-                     TREE_OPERAND (decl, 0) = constructor_name (ctype);
-                     next = &TREE_OPERAND (decl, 0);
+                     my_friendly_assert (is_overloaded_fn (dname),
+                                         19990331);
+                     dname = DECL_NAME (get_first_fn (dname));
                    }
                }
-           }
-           break;
+               /* Fall through.  */
 
-         case ERROR_MARK:
-           next = 0;
-           break;
+             case IDENTIFIER_NODE:
+               if (TREE_CODE (decl) == IDENTIFIER_NODE)
+                 dname = decl;
 
-         case TYPE_DECL:
-           /* Parse error puts this typespec where
-              a declarator should go.  */
-           error ("`%T' specified as declarator-id", DECL_NAME (decl));
-           if (TREE_TYPE (decl) == current_class_type)
-             error ("  perhaps you want `%T' for a constructor",
-                       current_class_name);
-           dname = DECL_NAME (decl);
-           name = IDENTIFIER_POINTER (dname);
-
-           /* Avoid giving two errors for this.  */
-           IDENTIFIER_CLASS_VALUE (dname) = NULL_TREE;
-
-           declspecs = tree_cons (NULL_TREE, integer_type_node, declspecs);
-           *next = dname;
-           next = 0;
+               if (C_IS_RESERVED_WORD (dname))
+                 {
+                   error ("declarator-id missing; using reserved word `%D'",
+                          dname);
+                   name = IDENTIFIER_POINTER (dname);
+                 }
+               else if (!IDENTIFIER_TYPENAME_P (dname))
+                 name = IDENTIFIER_POINTER (dname);
+               else
+                 {
+                   my_friendly_assert (flags == NO_SPECIAL, 154);
+                   flags = TYPENAME_FLAG;
+                   ctor_return_type = TREE_TYPE (dname);
+                   sfk = sfk_conversion;
+                   if (is_typename_at_global_scope (dname))
+                     name = IDENTIFIER_POINTER (dname);
+                   else
+                     name = "<invalid operator>";
+                 }
+               break;
+
+             case TYPE_DECL:
+               dname = constructor_name (TREE_TYPE (decl));
+               name = IDENTIFIER_POINTER (dname);
+               break;
+
+             default:
+               abort ();
+             }
            break;
 
-         case BASELINK:
-           next = &BASELINK_FUNCTIONS (decl);
+         case cdk_array:
+         case cdk_pointer:
+         case cdk_reference:
+         case cdk_ptrmem:
            break;
 
-         case TEMPLATE_DECL:
-           /* Sometimes, we see a template-name used as part of a 
-              decl-specifier like in 
-                 std::allocator alloc;
-              Handle that gracefully.  */
-           error ("invalid use of template-name '%E' in a declarator", decl);
-           return error_mark_node;
+         case cdk_error:
            break;
-           
+
          default:
-           my_friendly_assert (0, 20020917);
+           abort ();
          }
-      }
-  }
+       }
+      if (id_declarator->kind == cdk_id)
+       break;
+    }
 
   /* A function definition's declarator must have the form of
      a function declarator.  */
 
-  if (funcdef_flag && innermost_code != CALL_EXPR)
+  if (funcdef_flag && innermost_code != cdk_function)
     return 0;
 
   if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
-      && innermost_code != CALL_EXPR
+      && innermost_code != cdk_function
       && ! (ctype && declspecs == NULL_TREE))
     {
       error ("declaration of `%D' as non-function", dname);
@@ -7143,10 +6981,10 @@ grokdeclarator (tree declarator,
              if (declarator)
                {
                  /* Avoid trying to get an operand off an identifier node.  */
-                 if (TREE_CODE (declarator) == IDENTIFIER_NODE)
-                   tmp = declarator;
+                 if (declarator->kind != cdk_id)
+                   tmp = declarator->declarator->u.id.name;
                  else
-                   tmp = TREE_OPERAND (declarator, 0);
+                   tmp = declarator->u.id.name;
                  op = IDENTIFIER_OPNAME_P (tmp);
                  if (IDENTIFIER_TYPENAME_P (tmp))
                    {
@@ -7205,114 +7043,85 @@ grokdeclarator (tree declarator,
   if (nclasses > 0 && friendp)
     error ("storage class specifiers invalid in friend function declarations");
 
-  scope = get_scope_of_declarator (declarator);
-
-  /* Now figure out the structure of the declarator proper.
-     Descend through it, creating more complex types, until we reach
-     the declared identifier (or NULL_TREE, in an abstract declarator).  */
-
-  while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
-        && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
+  if (!id_declarator)
+    unqualified_id = NULL_TREE;
+  else
     {
-      /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),
-        an INDIRECT_REF (for *...),
-        a CALL_EXPR (for ...(...)),
-        an identifier (for the name being declared)
-        or a null pointer (for the place in an absolute declarator
-        where the name was omitted).
-        For the last two cases, we have just exited the loop.
-
-        For C++ it could also be
-        a SCOPE_REF (for class :: ...).  In this case, we have converted
-        sensible names to types, and those are the values we use to
-        qualify the member name.
-        an ADDR_EXPR (for &...),
-        a BIT_NOT_EXPR (for destructors)
-
-        At this point, TYPE is the type of elements of an array,
-        or for a function to return, or for a pointer to point to.
-        After this sequence of ifs, TYPE is the type of the
-        array or function or pointer, and DECLARATOR has had its
-        outermost layer removed.  */
-
-      if (type == error_mark_node)
+      unqualified_id = id_declarator->u.id.name;
+      if (TREE_CODE (unqualified_id) == SCOPE_REF)
+       unqualified_id = TREE_OPERAND (unqualified_id, 1);
+      if (TREE_CODE (unqualified_id) == BASELINK)
+       unqualified_id = BASELINK_FUNCTIONS (unqualified_id);
+      switch (TREE_CODE (unqualified_id))
        {
-         if (declarator == error_mark_node)
-           return error_mark_node;
-         else if (TREE_CODE (declarator) == SCOPE_REF)
-           declarator = TREE_OPERAND (declarator, 1);
-         else
-           declarator = TREE_OPERAND (declarator, 0);
-         continue;
-       }
-      if (quals != NULL_TREE
-         && (declarator == NULL_TREE
-             || TREE_CODE (declarator) != SCOPE_REF))
-       {
-         if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE)
-           ctype = TYPE_METHOD_BASETYPE (type);
-         if (ctype != NULL_TREE)
-           {
-             tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
-             grok_method_quals (ctype, dummy, quals);
-             type = TREE_TYPE (dummy);
-             quals = NULL_TREE;
-           }
-       }
+       case BIT_NOT_EXPR:
+         unqualified_id 
+           = constructor_name (TREE_OPERAND (unqualified_id, 0));
+         break;
+         
+       case TYPE_DECL:
+         unqualified_id 
+           = constructor_name (TREE_TYPE (unqualified_id));
+         break;
 
-      switch (TREE_CODE (declarator))
-       {
-       case TREE_LIST:
-         {
-           /* We encode a declarator with embedded attributes using
-              a TREE_LIST.  */
-           tree attrs = TREE_PURPOSE (declarator);
-           tree inner_decl;
-           int attr_flags;
-
-           declarator = TREE_VALUE (declarator);
-           inner_decl = declarator;
-           while (inner_decl != NULL_TREE
-                  && TREE_CODE (inner_decl) == TREE_LIST)
-             inner_decl = TREE_VALUE (inner_decl);
-           attr_flags = 0;
-           if (inner_decl == NULL_TREE
-               || TREE_CODE (inner_decl) == IDENTIFIER_NODE)
-             attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
-           if (TREE_CODE (inner_decl) == CALL_EXPR)
-             attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
-           if (TREE_CODE (inner_decl) == ARRAY_REF)
-             attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
-           returned_attrs = decl_attributes (&type,
-                                             chainon (returned_attrs, attrs),
-                                             attr_flags);
-         }
+       case IDENTIFIER_NODE:
+       case TEMPLATE_ID_EXPR:
          break;
+       
+       default:
+         abort ();
+       }
+    }
 
-       case ARRAY_REF:
-         {
-           tree size = TREE_OPERAND (declarator, 1);
-           declarator = TREE_OPERAND (declarator, 0);
+  /* Determine the type of the entity declared by recurring on the
+     declarator.  */
+  for (; 
+       declarator && declarator->kind != cdk_id;
+       declarator = declarator->declarator)
+    {
+      const cp_declarator *inner_declarator;
+      tree attrs;
 
-           type = create_array_type_for_decl (dname, type, size);
+      if (type == error_mark_node)
+       return error_mark_node;
 
-           if (declarator
-               && (TREE_CODE (declarator) == INDIRECT_REF
-                   || TREE_CODE (declarator) == ADDR_EXPR))
-             /* We can never complete an array type which is the target of a
-                pointer, so go ahead and lay it out.  */
-             layout_type (type);
+      inner_declarator = declarator->declarator;
 
-           ctype = NULL_TREE;
-         }
+      attrs = declarator->attributes;
+      if (attrs)
+       {
+         int attr_flags;
+         
+         attr_flags = 0;
+         if (declarator == NULL || declarator->kind == cdk_id)
+           attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
+         if (declarator->kind == cdk_function)
+           attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
+         if (declarator->kind == cdk_array)
+           attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
+         returned_attrs = decl_attributes (&type,
+                                           chainon (returned_attrs, attrs),
+                                           attr_flags);
+       }
+
+      switch (declarator->kind)
+       {
+       case cdk_array:
+         type = create_array_type_for_decl (dname, type, 
+                                            declarator->u.array.bounds);
+         if (inner_declarator
+             && (inner_declarator->kind == cdk_pointer
+                 || inner_declarator->kind == cdk_reference
+                 || inner_declarator->kind == cdk_ptrmem))
+           /* We can never complete an array type which is the
+              target of a pointer, so go ahead and lay it out.  */
+           layout_type (type);
          break;
 
-       case CALL_EXPR:
+       case cdk_function:
          {
            tree arg_types;
            int funcdecl_p;
-           tree inner_parms = CALL_DECLARATOR_PARMS (declarator);
-           tree inner_decl = TREE_OPERAND (declarator, 0);
 
            /* Declaring a function type.
               Make sure we have a valid type for the function to return.  */
@@ -7334,25 +7143,15 @@ grokdeclarator (tree declarator,
                type = integer_type_node;
              }
 
-           if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF)
-             inner_decl = TREE_OPERAND (inner_decl, 1);
-
-           if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR)
-             inner_decl = dname;
-
            /* Pick up type qualifiers which should be applied to `this'.  */
-           quals = CALL_DECLARATOR_QUALS (declarator);
+           quals = declarator->u.function.qualifiers;
 
            /* Pick up the exception specifications.  */
-           raises = CALL_DECLARATOR_EXCEPTION_SPEC (declarator);
+           raises = declarator->u.function.exception_specification;
 
            /* Say it's a definition only for the CALL_EXPR
               closest to the identifier.  */
-           funcdecl_p
-             = inner_decl
-             && (TREE_CODE (inner_decl) == IDENTIFIER_NODE
-                 || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR
-                 || TREE_CODE (inner_decl) == BIT_NOT_EXPR);
+           funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
 
            if (ctype == NULL_TREE
                && decl_context == FIELD
@@ -7362,7 +7161,8 @@ grokdeclarator (tree declarator,
 
            if (ctype && sfk == sfk_conversion)
              TYPE_HAS_CONVERSION (ctype) = 1;
-           if (ctype && constructor_name_p (dname, ctype))
+           if (ctype && (sfk == sfk_constructor
+                         || sfk == sfk_destructor))
              {
                /* We are within a class's scope. If our declarator name
                   is the same as the class name, and we are defining
@@ -7451,75 +7251,76 @@ grokdeclarator (tree declarator,
                            name);
              }
 
-           /* Construct the function type and go to the next
-              inner layer of declarator.  */
-
-           declarator = TREE_OPERAND (declarator, 0);
-
-           arg_types = grokparms (inner_parms, &parms);
+           arg_types = grokparms (declarator->u.function.parameters, 
+                                  &parms);
 
-           if (declarator && flags == DTOR_FLAG)
+           if (inner_declarator
+               && inner_declarator->kind == cdk_id
+               && inner_declarator->u.id.sfk == sfk_destructor
+               && arg_types != void_list_node)
              {
-               /* A destructor declared in the body of a class will
-                  be represented as a BIT_NOT_EXPR.  But, we just
-                  want the underlying IDENTIFIER.  */
-               if (TREE_CODE (declarator) == BIT_NOT_EXPR)
-                 declarator = TREE_OPERAND (declarator, 0);
-
-                if (arg_types != void_list_node)
-                 {
-                   error ("destructors may not have parameters");
-                   arg_types = void_list_node;
-                   parms = NULL_TREE;
-                 }
+               error ("destructors may not have parameters");
+               arg_types = void_list_node;
+               parms = NULL_TREE;
              }
-
-           /* ANSI says that `const int foo ();'
-              does not make the function foo const.  */
+           
            type = build_function_type (type, arg_types);
          }
          break;
 
-       case ADDR_EXPR:
-       case INDIRECT_REF:
+       case cdk_pointer:
+       case cdk_reference:
+       case cdk_ptrmem:
          /* Filter out pointers-to-references and references-to-references.
             We can get these if a TYPE_DECL is used.  */
 
          if (TREE_CODE (type) == REFERENCE_TYPE)
            {
-             error (TREE_CODE (declarator) == ADDR_EXPR
+             error (declarator->kind == cdk_reference
                     ? "cannot declare reference to `%#T'"
                     : "cannot declare pointer to `%#T'", type);
              type = TREE_TYPE (type);
            }
-         else if (VOID_TYPE_P (type)
-                  && (ctype || TREE_CODE (declarator) == ADDR_EXPR))
-           error (ctype ? "cannot declare pointer to `%#T' member"
-                    : "cannot declare reference to `%#T'", type);
-
-         /* Merge any constancy or volatility into the target type
-            for the pointer.  */
+         else if (VOID_TYPE_P (type))
+           {
+             if (declarator->kind == cdk_reference)
+               error ("cannot declare reference to `%#T'", type);
+             else if (declarator->kind == cdk_ptrmem)
+               error ("cannot declare pointer to `%#T' member", type);
+           }
 
          /* We now know that the TYPE_QUALS don't apply to the decl,
             but to the target of the pointer.  */
          type_quals = TYPE_UNQUALIFIED;
 
-         if (TREE_CODE (declarator) == ADDR_EXPR)
+         if (declarator->kind == cdk_ptrmem
+             && (TREE_CODE (type) == FUNCTION_TYPE
+                 || (quals && TREE_CODE (type) == METHOD_TYPE)))
+           {
+             tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
+             grok_method_quals (declarator->u.pointer.class_type, 
+                                dummy, quals);
+             type = TREE_TYPE (dummy);
+             quals = NULL_TREE;
+           }
+
+         if (declarator->kind == cdk_reference)
            {
              if (!VOID_TYPE_P (type))
                type = build_reference_type (type);
            }
          else if (TREE_CODE (type) == METHOD_TYPE)
            type = build_ptrmemfunc_type (build_pointer_type (type));
-         else if (ctype)
-           type = build_ptrmem_type (ctype, type);
+         else if (declarator->kind == cdk_ptrmem)
+           type = build_ptrmem_type (declarator->u.pointer.class_type, 
+                                     type);
          else
            type = build_pointer_type (type);
 
          /* Process a list of type modifier keywords (such as
             const or volatile) that were given inside the `*' or `&'.  */
 
-         if (TREE_TYPE (declarator))
+         if (declarator->u.pointer.qualifiers)
            {
              tree typemodlist;
              int erred = 0;
@@ -7527,7 +7328,7 @@ grokdeclarator (tree declarator,
              int volatilep = 0;
              int restrictp = 0;
              
-             for (typemodlist = TREE_TYPE (declarator); typemodlist;
+             for (typemodlist = declarator->u.pointer.qualifiers; typemodlist;
                   typemodlist = TREE_CHAIN (typemodlist))
                {
                  tree qualifier = TREE_VALUE (typemodlist);
@@ -7562,158 +7363,115 @@ grokdeclarator (tree declarator,
              type = cp_build_qualified_type (type, type_quals);
              type_quals = cp_type_quals (type);
            }
-         declarator = TREE_OPERAND (declarator, 0);
          ctype = NULL_TREE;
          break;
 
-       case SCOPE_REF:
-         {
-           /* We have converted type names to NULL_TREE if the
-              name was bogus, or to a _TYPE node, if not.
-
-              The variable CTYPE holds the type we will ultimately
-              resolve to.  The code here just needs to build
-              up appropriate member types.  */
-           tree sname = TREE_OPERAND (declarator, 1);
-           tree t;
-
-           /* Destructors can have their visibilities changed as well.  */
-           if (TREE_CODE (sname) == BIT_NOT_EXPR)
-             sname = TREE_OPERAND (sname, 0);
-
-           if (TREE_OPERAND (declarator, 0) == NULL_TREE)
-             {
-               /* We had a reference to a global decl, or
-                  perhaps we were given a non-aggregate typedef,
-                  in which case we cleared this out, and should just
-                  keep going as though it wasn't there.  */
-               declarator = sname;
-               continue;
-             }
-           ctype = TREE_OPERAND (declarator, 0);
+       case cdk_error:
+         break;
 
-           t = ctype;
-           if (TREE_CODE (TREE_OPERAND (declarator, 1)) != INDIRECT_REF)
-             while (t != NULL_TREE && CLASS_TYPE_P (t))
-               {
-                 /* You're supposed to have one `template <...>'
-                    for every template class, but you don't need one
-                    for a full specialization.  For example:
-                    
-                    template <class T> struct S{};
-                    template <> struct S<int> { void f(); };
-                    void S<int>::f () {}
-                    
-                    is correct; there shouldn't be a `template <>' for
-                    the definition of `S<int>::f'.  */
-                 if (CLASSTYPE_TEMPLATE_INFO (t)
-                     && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
-                         || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
-                     && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
-                   template_count += 1;
-                 
-                 t = TYPE_MAIN_DECL (t);
-                 t = DECL_CONTEXT (t);
-               }
+       default:
+         abort ();
+       }
+    }
+  
+  if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
+      && TREE_CODE (type) != FUNCTION_TYPE
+      && TREE_CODE (type) != METHOD_TYPE)
+    {
+      error ("template-id `%D' used as a declarator", 
+            unqualified_id);
+      unqualified_id = dname;
+    }
 
-           if (sname == NULL_TREE)
-             goto done_scoping;
+  /* If DECLARATOR is non-NULL, we know it is a cdk_id declarator;
+     otherwise, we would not have exited the loop above.  */
+  if (declarator 
+      && TREE_CODE (declarator->u.id.name) == SCOPE_REF
+      /* If the qualifying scope was invalid, it will have been set to
+        NULL_TREE above.  */
+      && TREE_OPERAND (declarator->u.id.name, 0)
+      && TYPE_P (TREE_OPERAND (declarator->u.id.name, 0)))
+    {
+      tree t;
 
-           if (TREE_CODE (sname) == IDENTIFIER_NODE)
-             {
-               /* This is the `standard' use of the scoping operator:
-                  basetype :: member .  */
+      ctype = TREE_OPERAND (declarator->u.id.name, 0);
+      if (TYPE_P (ctype))
+       ctype = TYPE_MAIN_VARIANT (ctype);
+      t = ctype;
+      while (t != NULL_TREE && CLASS_TYPE_P (t))
+       {
+         /* You're supposed to have one `template <...>' for every
+            template class, but you don't need one for a full
+            specialization.  For example:
 
-               if (ctype == current_class_type)
-                 {
-                   /* class A {
-                        void A::f ();
-                      };
+              template <class T> struct S{};
+              template <> struct S<int> { void f(); };
+              void S<int>::f () {}
 
-                      Is this ill-formed?  */
+            is correct; there shouldn't be a `template <>' for the
+            definition of `S<int>::f'.  */
+         if (CLASSTYPE_TEMPLATE_INFO (t)
+             && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+                 || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
+             && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
+           template_count += 1;
 
-                   if (pedantic)
-                     pedwarn ("extra qualification `%T::' on member `%s' ignored",
-                                 ctype, name);
-                 }
-               else if (TREE_CODE (type) == FUNCTION_TYPE)
-                 {
-                   if (NEW_DELETE_OPNAME_P (sname))
-                     /* Overloaded operator new and operator delete
-                        are always static functions.  */
-                     ;
-                   else if (current_class_type == NULL_TREE || friendp)
-                     type 
-                       = build_method_type_directly (ctype, 
-                                                     TREE_TYPE (type),
-                                                     TYPE_ARG_TYPES (type));
-                   else
-                     {
-                       error ("cannot declare member function `%T::%s' within `%T'",
-                                 ctype, name, current_class_type);
-                       return error_mark_node;
-                     }
-                 }
-               else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
-                        || COMPLETE_TYPE_P (complete_type (ctype)))
-                 {
-                   /* Have to move this code elsewhere in this function.
-                      this code is used for i.e., typedef int A::M; M *pm;
-
-                      It is?  How? jason 10/2/94 */
-
-                   if (current_class_type)
-                     {
-                       error ("cannot declare member `%T::%s' within `%T'",
-                                 ctype, name, current_class_type);
-                       return void_type_node;
-                     }
-                 }
-               else
-                 {
-                   cxx_incomplete_type_error (NULL_TREE, ctype);
-                   return error_mark_node;
-                 }
+         t = TYPE_MAIN_DECL (t);
+         t = DECL_CONTEXT (t);
+       }
 
-               declarator = sname;
-             }
-           else if (TREE_CODE (sname) == SCOPE_REF)
-             abort ();
-           else
-             {
-             done_scoping:
-               declarator = TREE_OPERAND (declarator, 1);
-               if (declarator && TREE_CODE (declarator) == CALL_EXPR)
-                 /* In this case, we will deal with it later.  */
-                 ;
-               else if (TREE_CODE (type) == FUNCTION_TYPE)
-                 type = build_method_type_directly (ctype, 
-                                                    TREE_TYPE (type),
-                                                    TYPE_ARG_TYPES (type));
-             }
-         }
-         break;
+      if (ctype == current_class_type)
+       {
+         /* class A {
+              void A::f ();
+            };
 
-       case BIT_NOT_EXPR:
-         declarator = TREE_OPERAND (declarator, 0);
-         break;
+            Is this ill-formed?  */
 
-       case BASELINK:
-         declarator = BASELINK_FUNCTIONS (declarator);
-         break;
+         if (pedantic)
+           pedwarn ("extra qualification `%T::' on member `%s' ignored",
+                       ctype, name);
+       }
+      else if (TREE_CODE (type) == FUNCTION_TYPE)
+       {
+         tree sname = TREE_OPERAND (declarator->u.id.name, 1);
 
-       case RECORD_TYPE:
-       case UNION_TYPE:
-       case ENUMERAL_TYPE:
-         declarator = NULL_TREE;
-         break;
+         if (TREE_CODE (sname) == IDENTIFIER_NODE
+             && NEW_DELETE_OPNAME_P (sname))
+           /* Overloaded operator new and operator delete
+              are always static functions.  */
+           ;
+         else if (current_class_type == NULL_TREE || friendp)
+           type 
+             = build_method_type_directly (ctype, 
+                                           TREE_TYPE (type),
+                                           TYPE_ARG_TYPES (type));
+         else
+           {
+             error ("cannot declare member function `%T::%s' within `%T'",
+                    ctype, name, current_class_type);
+             return error_mark_node;
+           }
+       }
+      else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
+              || COMPLETE_TYPE_P (complete_type (ctype)))
+       {
+         /* Have to move this code elsewhere in this function.
+            this code is used for i.e., typedef int A::M; M *pm;
 
-       case ERROR_MARK:
-         declarator = NULL_TREE;
-         break;
+            It is?  How? jason 10/2/94 */
 
-       default:
-         abort ();
+         if (current_class_type)
+           {
+             error ("cannot declare member `%T::%s' within `%T'",
+                    ctype, name, current_class_type);
+             return void_type_node;
+           }
+       }
+      else
+       {
+         cxx_incomplete_type_error (NULL_TREE, ctype);
+         return error_mark_node;
        }
     }
 
@@ -7788,24 +7546,7 @@ grokdeclarator (tree declarator,
        }
     }
 
-  if (declarator == NULL_TREE
-      || TREE_CODE (declarator) == ERROR_MARK
-      || TREE_CODE (declarator) == IDENTIFIER_NODE
-      || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR
-         && (TREE_CODE (type) == FUNCTION_TYPE
-             || TREE_CODE (type) == METHOD_TYPE)))
-    /* OK */;
-  else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
-    {
-      error ("template-id `%D' used as a declarator", declarator);
-      declarator = dname;
-    }
-  else
-    /* Unexpected declarator format.  */
-    abort ();
-
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
-
   if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)
     {
       tree decl;
@@ -7817,14 +7558,14 @@ grokdeclarator (tree declarator,
 
       if (decl_context == FIELD)
        {
-         if (constructor_name_p (declarator, current_class_type))
+         if (constructor_name_p (unqualified_id, current_class_type))
            pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
-                       declarator);
-         decl = build_lang_decl (TYPE_DECL, declarator, type);
+                    unqualified_id);
+         decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
        }
       else
        {
-         decl = build_decl (TYPE_DECL, declarator, type);
+         decl = build_decl (TYPE_DECL, unqualified_id, type);
          if (in_namespace || ctype)
            error ("%Jtypedef name may not be a nested-name-specifier", decl);
          if (!current_function_decl)
@@ -7836,7 +7577,7 @@ grokdeclarator (tree declarator,
         Nothing can refer to it, so nothing needs know about the name
         change.  */
       if (type != error_mark_node
-         && declarator
+         && unqualified_id
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_ANONYMOUS_P (type)
@@ -7848,7 +7589,7 @@ grokdeclarator (tree declarator,
          tree t;
 
          /* Replace the anonymous name with the real name everywhere.  */
-         lookup_tag_reverse (type, declarator);
+         lookup_tag_reverse (type, unqualified_id);
          for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
            if (TYPE_NAME (t) == oldname)
              TYPE_NAME (t) = decl;
@@ -7984,7 +7725,7 @@ grokdeclarator (tree declarator,
            }
          if (ctype)
            {
-             tree dummy = build_decl (TYPE_DECL, declarator, type);
+             tree dummy = build_decl (TYPE_DECL, unqualified_id, type);
              grok_method_quals (ctype, dummy, quals);
              type = TREE_TYPE (dummy);
            }
@@ -7992,13 +7733,13 @@ grokdeclarator (tree declarator,
 
       return type;
     }
-  else if (declarator == NULL_TREE && decl_context != PARM
+  else if (unqualified_id == NULL_TREE && decl_context != PARM
           && decl_context != CATCHPARM
           && TREE_CODE (type) != UNION_TYPE
           && ! bitfield)
     {
       error ("abstract declarator `%T' used as declaration", type);
-      declarator = make_anon_name ();
+      unqualified_id = make_anon_name ();
     }
 
   /* `void' at top level (not within pointer)
@@ -8008,11 +7749,11 @@ grokdeclarator (tree declarator,
 
   if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
     {
-      if (! declarator)
+      if (! unqualified_id)
        error ("unnamed variable or field declared void");
-      else if (TREE_CODE (declarator) == IDENTIFIER_NODE)
+      else if (TREE_CODE (unqualified_id) == IDENTIFIER_NODE)
        {
-         if (IDENTIFIER_OPNAME_P (declarator))
+         if (IDENTIFIER_OPNAME_P (unqualified_id))
            abort ();
          else
            error ("variable or field `%s' declared void", name);
@@ -8049,7 +7790,7 @@ grokdeclarator (tree declarator,
 
     if (decl_context == PARM)
       {
-       decl = cp_build_parm_decl (declarator, type);
+       decl = cp_build_parm_decl (unqualified_id, type);
 
        bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
                        inlinep, friendp, raises != NULL_TREE);
@@ -8083,10 +7824,10 @@ grokdeclarator (tree declarator,
 
            /* We catch the others as conflicts with the builtin
               typedefs.  */
-           if (friendp && declarator == ridpointers[(int) RID_SIGNED])
+           if (friendp && unqualified_id == ridpointers[(int) RID_SIGNED])
              {
                error ("function `%D' cannot be declared friend",
-                         declarator);
+                      unqualified_id);
                friendp = 0;
              }
 
@@ -8098,7 +7839,7 @@ grokdeclarator (tree declarator,
                if (ctype == NULL_TREE)
                  {
                    error ("can't make `%D' into a method -- not in a class",
-                             declarator);
+                          unqualified_id);
                    return void_type_node;
                  }
 
@@ -8107,16 +7848,16 @@ grokdeclarator (tree declarator,
                if (virtualp && TREE_CODE (ctype) == UNION_TYPE)
                  {
                    error ("function `%D' declared virtual inside a union",
-                             declarator);
+                          unqualified_id);
                    return void_type_node;
                  }
 
-               if (NEW_DELETE_OPNAME_P (declarator))
+               if (NEW_DELETE_OPNAME_P (unqualified_id))
                  {
                    if (virtualp)
                      {
                        error ("`%D' cannot be declared virtual, since it is always static",
-                                 declarator);
+                              unqualified_id);
                        virtualp = 0;
                      }
                  }
@@ -8132,10 +7873,10 @@ grokdeclarator (tree declarator,
            publicp = (! friendp || ! staticp)
              && function_context == NULL_TREE;
            decl = grokfndecl (ctype, type,
-                              TREE_CODE (declarator) != TEMPLATE_ID_EXPR
-                              ? declarator : dname,
+                              TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
+                              ? unqualified_id : dname,
                               parms,
-                              declarator,
+                              unqualified_id,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, publicp, inlinep,
                               funcdef_flag, template_count, in_namespace);
@@ -8179,10 +7920,10 @@ grokdeclarator (tree declarator,
            /* All method decls are public, so tell grokfndecl to set
               TREE_PUBLIC, also.  */
            decl = grokfndecl (ctype, type,
-                              TREE_CODE (declarator) != TEMPLATE_ID_EXPR
-                              ? declarator : dname,
+                              TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
+                              ? unqualified_id : dname,
                               parms,
-                              declarator,
+                              unqualified_id,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
                               template_count, in_namespace);
@@ -8193,8 +7934,8 @@ grokdeclarator (tree declarator,
                 && !COMPLETE_TYPE_P (complete_type (type))
                 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
          {
-           if (declarator)
-             error ("field `%D' has incomplete type", declarator);
+           if (unqualified_id)
+             error ("field `%D' has incomplete type", unqualified_id);
            else
              error ("name `%T' has incomplete type", type);
 
@@ -8216,7 +7957,7 @@ grokdeclarator (tree declarator,
            if (friendp)
              {
                error ("`%E' is neither function nor member function; "
-                       "cannot be declared friend", declarator);
+                       "cannot be declared friend", unqualified_id);
                friendp = 0;
              }
            decl = NULL_TREE;
@@ -8232,13 +7973,13 @@ grokdeclarator (tree declarator,
                if (template_class_depth (current_class_type) == 0)
                  {
                    decl = check_explicit_specialization
-                     (declarator, decl, template_count,
+                     (unqualified_id, decl, template_count,
                       2 * (funcdef_flag != 0) + 4);
                    if (decl == error_mark_node)
                      return error_mark_node;
                  }
                
-               decl = do_friend (ctype, declarator, decl,
+               decl = do_friend (ctype, unqualified_id, decl,
                                  *attrlist, flags, quals, funcdef_flag);
                return decl;
              }
@@ -8267,15 +8008,15 @@ grokdeclarator (tree declarator,
                       handle the initialization unless the member is
                       static so we make it static below.  */
                    pedwarn ("ISO C++ forbids initialization of member `%D'",
-                               declarator);
-                   pedwarn ("making `%D' static", declarator);
+                            unqualified_id);
+                   pedwarn ("making `%D' static", unqualified_id);
                    staticp = 1;
                  }
 
                if (uses_template_parms (type))
                  /* We'll check at instantiation time.  */
                  ;
-               else if (check_static_variable_definition (declarator,
+               else if (check_static_variable_definition (unqualified_id,
                                                           type))
                  /* If we just return the declaration, crashes
                     will sometimes occur.  We therefore return
@@ -8289,14 +8030,14 @@ grokdeclarator (tree declarator,
              {
                /* C++ allows static class members.  All other work
                   for this is done by grokfield.  */
-               decl = build_lang_decl (VAR_DECL, declarator, type);
+               decl = build_lang_decl (VAR_DECL, unqualified_id, type);
                TREE_STATIC (decl) = 1;
                /* In class context, 'static' means public access.  */
                TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1;
              }
            else
              {
-               decl = build_decl (FIELD_DECL, declarator, type);
+               decl = build_decl (FIELD_DECL, unqualified_id, type);
                DECL_NONADDRESSABLE_P (decl) = bitfield;
                if (RIDBIT_SETP (RID_MUTABLE, specbits))
                  {
@@ -8315,13 +8056,13 @@ grokdeclarator (tree declarator,
        tree original_name;
        int publicp = 0;
 
-       if (! declarator)
+       if (!unqualified_id)
          return NULL_TREE;
 
-       if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+       if (TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR)
          original_name = dname;
        else
-         original_name = declarator;
+         original_name = unqualified_id;
 
        if (RIDBIT_SETP (RID_AUTO, specbits))
          error ("storage class `auto' invalid for function `%s'", name);
@@ -8363,7 +8104,7 @@ grokdeclarator (tree declarator,
                   || RIDBIT_SETP (RID_EXTERN, specbits)
                   || !RIDBIT_SETP (RID_STATIC, specbits));
 
-       decl = grokfndecl (ctype, type, original_name, parms, declarator,
+       decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, quals, raises,
                           1, friendp,
                           publicp, inlinep, funcdef_flag,
@@ -8401,7 +8142,7 @@ grokdeclarator (tree declarator,
        /* It's a variable.  */
 
        /* An uninitialized decl with `extern' is a reference.  */
-       decl = grokvardecl (type, declarator, &specbits,
+       decl = grokvardecl (type, unqualified_id, &specbits,
                            initialized,
                            (type_quals & TYPE_QUAL_CONST) != 0,
                            ctype ? ctype : in_namespace);
@@ -8601,48 +8342,33 @@ check_default_argument (tree decl, tree arg)
    Given the list of things declared inside the parens,
    return a list of types.
 
-   We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
-   flag. If unset, we append void_list_node. A parmlist declared
-   as `(void)' is accepted as the empty parmlist.
+   If this parameter does not end with an ellipsis, we append
+   void_list_node.
 
    *PARMS is set to the chain of PARM_DECLs created.  */
 
 static tree
-grokparms (tree first_parm, tree *parms)
+grokparms (const cp_parameter_declarator *first_parm, tree *parms)
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
-  int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
-  tree parm, chain;
+  int ellipsis = !first_parm || first_parm->ellipsis_p;
+  const cp_parameter_declarator *parm;
   int any_error = 0;
 
-  my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
-
-  for (parm = first_parm; parm != NULL_TREE; parm = chain)
+  for (parm = first_parm; parm != NULL; parm = parm->next)
     {
       tree type = NULL_TREE;
-      tree decl = TREE_VALUE (parm);
-      tree init = TREE_PURPOSE (parm);
+      tree decl_specifiers = parm->decl_specifiers;
+      tree init = parm->default_argument;
       tree specs, attrs;
+      tree decl;
 
-      chain = TREE_CHAIN (parm);
-      /* @@ weak defense against parse errors.  */
-      if (TREE_CODE (decl) != VOID_TYPE
-         && TREE_CODE (decl) != TREE_LIST)
-       {
-         /* Give various messages as the need arises.  */
-         if (TREE_CODE (decl) == STRING_CST)
-           error ("invalid string constant `%E'", decl);
-         else if (TREE_CODE (decl) == INTEGER_CST)
-           error ("invalid integer constant in parameter list, did you forget to give parameter name?");
-         continue;
-       }
-
-      if (parm == void_list_node)
+      if (parm == no_parameters)
         break;
 
-      split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);
-      decl = grokdeclarator (TREE_VALUE (decl), specs,
+      split_specs_attrs (decl_specifiers, &specs, &attrs);
+      decl = grokdeclarator (parm->declarator, specs,
                             PARM, init != NULL_TREE, &attrs);
       if (! decl || TREE_TYPE (decl) == error_mark_node)
         continue;
@@ -8654,7 +8380,7 @@ grokparms (tree first_parm, tree *parms)
       if (VOID_TYPE_P (type))
         {
           if (same_type_p (type, void_type_node)
-              && !DECL_NAME (decl) && !result && !chain && !ellipsis)
+              && !DECL_NAME (decl) && !result && !parm->next && !ellipsis)
             /* this is a parmlist of `(void)', which is ok.  */
             break;
           cxx_incomplete_type_error (decl, type);
@@ -10036,19 +9762,14 @@ check_function_type (tree decl, tree current_function_parms)
    This function creates a binding context for the function body
    as well as setting up the FUNCTION_DECL in current_function_decl.
 
-   Returns 1 on success.  If the DECLARATOR is not suitable for a function
-   (it defines a datum instead), we return 0, which tells
-   yyparse to report a parse error.
-
    For C++, we must first check whether that datum makes any sense.
    For example, "class A local_a(1,2);" means that variable local_a
    is an aggregate of type A, which should have a constructor
    applied to it with the argument list [1, 2].  */
 
-int
-start_function (tree declspecs, tree declarator, tree attrs, int flags)
+void
+start_preparsed_function (tree decl1, tree attrs, int flags)
 {
-  tree decl1;
   tree ctype = NULL_TREE;
   tree fntype;
   tree restype;
@@ -10060,67 +9781,23 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
   my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
   my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);
 
-  /* This should only be done once on the top most decl.  */
-  if (have_extern_spec)
-    {
-      declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs);
-      have_extern_spec = false;
-    }
-
-  if (flags & SF_PRE_PARSED)
-    {
-      decl1 = declarator;
-
-      fntype = TREE_TYPE (decl1);
-      if (TREE_CODE (fntype) == METHOD_TYPE)
-       ctype = TYPE_METHOD_BASETYPE (fntype);
-
-      /* ISO C++ 11.4/5.  A friend function defined in a class is in
-        the (lexical) scope of the class in which it is defined.  */
-      if (!ctype && DECL_FRIEND_P (decl1))
-       {
-         ctype = DECL_FRIEND_CONTEXT (decl1);
-
-         /* CTYPE could be null here if we're dealing with a template;
-            for example, `inline friend float foo()' inside a template
-            will have no CTYPE set.  */
-         if (ctype && TREE_CODE (ctype) != RECORD_TYPE)
-           ctype = NULL_TREE;
-         else
-           doing_friend = 1;
-       }
-    }
-  else
+  fntype = TREE_TYPE (decl1);
+  if (TREE_CODE (fntype) == METHOD_TYPE)
+    ctype = TYPE_METHOD_BASETYPE (fntype);
+  
+  /* ISO C++ 11.4/5.  A friend function defined in a class is in
+     the (lexical) scope of the class in which it is defined.  */
+  if (!ctype && DECL_FRIEND_P (decl1))
     {
-      decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
-      /* If the declarator is not suitable for a function definition,
-        cause a syntax error.  */
-      if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
-       return 0;
-
-      cplus_decl_attributes (&decl1, attrs, 0);
-
-      /* If #pragma weak was used, mark the decl weak now.  */
-      if (global_scope_p (current_binding_level))
-       maybe_apply_pragma_weak (decl1);
-
-      fntype = TREE_TYPE (decl1);
-
-      restype = TREE_TYPE (fntype);
-
-      if (TREE_CODE (fntype) == METHOD_TYPE)
-       ctype = TYPE_METHOD_BASETYPE (fntype);
-      else if (DECL_MAIN_P (decl1))
-       {
-         /* If this doesn't return integer_type, or a typedef to
-            integer_type, complain.  */
-         if (!same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node))
-           {
-             if (pedantic || warn_return_type)
-               pedwarn ("return type for `main' changed to `int'");
-             TREE_TYPE (decl1) = fntype = default_function_type;
-           }
-       }
+      ctype = DECL_FRIEND_CONTEXT (decl1);
+      
+      /* CTYPE could be null here if we're dealing with a template;
+        for example, `inline friend float foo()' inside a template
+        will have no CTYPE set.  */
+      if (ctype && TREE_CODE (ctype) != RECORD_TYPE)
+       ctype = NULL_TREE;
+      else
+       doing_friend = 1;
     }
 
   if (DECL_DECLARED_INLINE_P (decl1)
@@ -10382,6 +10059,55 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
   start_fname_decls ();
   
   store_parm_decls (current_function_parms);
+}
+
+
+/* Like start_preparsed_function, except that instead of a
+   FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.
+
+   Returns 1 on success.  If the DECLARATOR is not suitable for a function
+   (it defines a datum instead), we return 0, which tells
+   yyparse to report a parse error.  */
+
+int
+start_function (tree declspecs, const cp_declarator *declarator,
+               tree attrs)
+{
+  tree decl1;
+
+  if (have_extern_spec)
+    {
+      declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), 
+                            declspecs);
+      /* This should only be done once on the outermost decl.  */
+      have_extern_spec = false;
+    }
+  
+  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
+  /* If the declarator is not suitable for a function definition,
+     cause a syntax error.  */
+  if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
+    return 0;
+  
+  cplus_decl_attributes (&decl1, attrs, 0);
+  
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (global_scope_p (current_binding_level))
+    maybe_apply_pragma_weak (decl1);
+  
+  if (DECL_MAIN_P (decl1))
+    {
+      /* If this doesn't return integer_type, or a typedef to
+        integer_type, complain.  */
+      if (!same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node))
+       {
+         if (pedantic || warn_return_type)
+           pedwarn ("return type for `main' changed to `int'");
+         TREE_TYPE (decl1) = default_function_type;
+       }
+    }
+
+  start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
 
   return 1;
 }
@@ -10872,7 +10598,7 @@ finish_function (int flags)
    CHANGES TO CODE IN `grokfield'.  */
 
 tree
-start_method (tree declspecs, tree declarator, tree attrlist)
+start_method (tree declspecs, const cp_declarator *declarator, tree attrlist)
 {
   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
                                &attrlist);
@@ -11184,7 +10910,6 @@ tree
 build_void_list_node (void)
 {
   tree t = build_tree_list (NULL_TREE, void_type_node);
-  TREE_PARMLIST (t) = 1;
   return t;
 }
 
index 4bae89c64f540cb45f959deabe224de5247ac1b4..871d568a0c58b05508624cc0fa35fe50f797bcd6 100644 (file)
@@ -31,7 +31,7 @@ enum decl_context
 };
 
 /* We need this in here to get the decl_context definition.  */
-extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
+extern tree grokdeclarator (const cp_declarator *, tree, enum decl_context, int, tree*);
 
 #ifdef DEBUG_CP_BINDING_LEVELS
 /* Purely for debugging purposes.  */
index 00105a6d2a6945153a804484be9b644eebdeaafe..80e56ec82e7bc97381477bfea9eefdf8cfbefd19 100644 (file)
@@ -127,7 +127,7 @@ grok_method_quals (tree ctype, tree function, tree quals)
   int dup_quals = TYPE_UNQUALIFIED;
   int this_quals = TYPE_UNQUALIFIED;
 
-  do
+  while (quals)
     {
       int tq = cp_type_qual_from_rid (TREE_VALUE (quals));
       
@@ -139,7 +139,6 @@ grok_method_quals (tree ctype, tree function, tree quals)
        type_quals |= tq;
       quals = TREE_CHAIN (quals);
     } 
-  while (quals);
 
   if (dup_quals != TYPE_UNQUALIFIED)
     error ("duplicate type qualifiers in %s declaration",
@@ -168,7 +167,7 @@ grok_x_components (tree specs)
   specs = strip_attrs (specs);
 
   check_tag_decl (specs);
-  t = groktypename (build_tree_list (specs, NULL_TREE)); 
+  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; }; };'.  */
@@ -841,7 +840,8 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
    CHANGES TO CODE IN `start_method'.  */
 
 tree
-grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
+grokfield (const cp_declarator *declarator, tree declspecs, 
+          tree init, tree asmspec_tree,
            tree attrlist)
 {
   tree value;
@@ -849,15 +849,18 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
   int flags = LOOKUP_ONLYCONVERTING;
 
   if (declspecs == NULL_TREE
-      && TREE_CODE (declarator) == SCOPE_REF
-      && TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE)
+      && declarator->kind == cdk_id
+      && TREE_CODE (declarator->u.id.name) == SCOPE_REF
+      && (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1)) 
+         == IDENTIFIER_NODE))
     {
       /* Access declaration */
-      if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0))))
+      if (! IS_AGGR_TYPE_CODE (TREE_CODE 
+                              (TREE_OPERAND (declarator->u.id.name, 0))))
        ;
-      else if (TREE_COMPLEXITY (declarator) == current_class_depth)
+      else if (TREE_COMPLEXITY (declarator->u.id.name) == current_class_depth)
        pop_nested_class ();
-      return do_class_using_decl (declarator);
+      return do_class_using_decl (declarator->u.id.name);
     }
 
   if (init
@@ -1020,7 +1023,7 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
    WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.  */
 
 tree
-grokbitfield (tree declarator, tree declspecs, tree width)
+grokbitfield (const cp_declarator *declarator, tree declspecs, tree width)
 {
   tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL);
 
@@ -1915,8 +1918,8 @@ set_guard (tree guard)
 static tree
 start_objects (int method_type, int initp)
 {
-  tree fnname;
   tree body;
+  tree fndecl;
   char type[10];
 
   /* Make ctor or dtor function.  METHOD_TYPE may be 'I' or 'D'.  */
@@ -1936,12 +1939,11 @@ start_objects (int method_type, int initp)
   else
     sprintf (type, "%c", method_type);
 
-  fnname = get_file_function_name_long (type);
-
-  start_function (void_list_node,
-                 make_call_declarator (fnname, void_list_node, NULL_TREE,
-                                       NULL_TREE),
-                 NULL_TREE, SF_DEFAULT);
+  fndecl = build_lang_decl (FUNCTION_DECL, 
+                           get_file_function_name_long (type),
+                           build_function_type (void_type_node,
+                                                void_list_node));
+  start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
 
   /* It can be a static function as long as collect2 does not have
      to scan the object file to find its ctor/dtor routine.  */
@@ -2108,10 +2110,9 @@ start_static_storage_duration_function (unsigned count)
        
      It is static because we only need to call this function from the
      various constructor and destructor functions for this module.  */
-  start_function (/*specs=*/NULL_TREE, 
-                 ssdf_decl,
-                 /*attrs=*/NULL_TREE,
-                 SF_PRE_PARSED);
+  start_preparsed_function (ssdf_decl,
+                           /*attrs=*/NULL_TREE,
+                           SF_PRE_PARSED);
 
   /* Set up the scope of the outermost block in the function.  */
   body = begin_compound_stmt (BCS_FN_BODY);
index 2af51185e7ba2d1f63e04a9661227938f273cfde..c2a98781431ad4d2910f9543615254975f95ab41 100644 (file)
@@ -1665,126 +1665,18 @@ build_builtin_delete_call (tree addr)
    PLACEMENT is the `placement' list for user-defined operator new ().  */
 
 tree
-build_new (tree placement, tree decl, tree init, int use_global_new)
+build_new (tree placement, tree type, tree nelts, tree init, 
+          int use_global_new)
 {
-  tree type, rval;
-  tree nelts = NULL_TREE, t;
-  int has_array = 0;
+  tree rval;
 
-  if (decl == error_mark_node)
+  if (type == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (decl) == TREE_LIST)
-    {
-      tree absdcl = TREE_VALUE (decl);
-      tree last_absdcl = NULL_TREE;
-
-      if (current_function_decl
-         && DECL_CONSTRUCTOR_P (current_function_decl))
-       my_friendly_assert (immediate_size_expand == 0, 19990926);
-
-      nelts = integer_one_node;
-
-      if (absdcl && TREE_CODE (absdcl) == CALL_EXPR)
-       abort ();
-      while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF)
-       {
-         last_absdcl = absdcl;
-         absdcl = TREE_OPERAND (absdcl, 0);
-       }
-
-      if (absdcl && TREE_CODE (absdcl) == ARRAY_REF)
-       {
-         /* Probably meant to be a vec new.  */
-         tree this_nelts;
-
-         while (TREE_OPERAND (absdcl, 0)
-                && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF)
-           {
-             last_absdcl = absdcl;
-             absdcl = TREE_OPERAND (absdcl, 0);
-           }
-
-         has_array = 1;
-         this_nelts = TREE_OPERAND (absdcl, 1);
-         if (this_nelts != error_mark_node)
-           {
-             if (this_nelts == NULL_TREE)
-               error ("new of array type fails to specify size");
-             else if (processing_template_decl)
-               {
-                 nelts = this_nelts;
-                 absdcl = TREE_OPERAND (absdcl, 0);
-               }
-             else
-               {
-                 if (build_expr_type_conversion (WANT_INT | WANT_ENUM, 
-                                                 this_nelts, false)
-                     == NULL_TREE)
-                   pedwarn ("size in array new must have integral type");
-
-                 this_nelts = save_expr (cp_convert (sizetype, this_nelts));
-                 absdcl = TREE_OPERAND (absdcl, 0);
-                 if (this_nelts == integer_zero_node)
-                   {
-                     warning ("zero size array reserves no space");
-                     nelts = integer_zero_node;
-                   }
-                 else
-                   nelts = cp_build_binary_op (MULT_EXPR, nelts, this_nelts);
-               }
-           }
-         else
-           nelts = integer_zero_node;
-       }
-
-      if (last_absdcl)
-       TREE_OPERAND (last_absdcl, 0) = absdcl;
-      else
-       TREE_VALUE (decl) = absdcl;
-
-      type = groktypename (decl);
-      if (! type || type == error_mark_node)
-       return error_mark_node;
-    }
-  else if (TREE_CODE (decl) == IDENTIFIER_NODE)
-    {
-      if (IDENTIFIER_HAS_TYPE_VALUE (decl))
-       {
-         /* An aggregate type.  */
-         type = IDENTIFIER_TYPE_VALUE (decl);
-         decl = TYPE_MAIN_DECL (type);
-       }
-      else
-       {
-         /* A builtin type.  */
-         decl = lookup_name (decl, 1);
-         my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215);
-         type = TREE_TYPE (decl);
-       }
-    }
-  else if (TREE_CODE (decl) == TYPE_DECL)
-    {
-      type = TREE_TYPE (decl);
-    }
-  else
-    {
-      type = decl;
-      decl = TYPE_MAIN_DECL (type);
-    }
-
   if (processing_template_decl)
     {
-      if (has_array)
-       t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
-                      build_min_nt (ARRAY_REF, NULL_TREE, nelts,
-                                    NULL_TREE, NULL_TREE),
-                      NULL_TREE);
-      else
-       t = type;
-       
       rval = build_min (NEW_EXPR, build_pointer_type (type), 
-                       placement, t, init);
+                       placement, type, nelts, init);
       NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
       TREE_SIDE_EFFECTS (rval) = 1;
       return rval;
@@ -1805,22 +1697,8 @@ build_new (tree placement, tree decl, tree init, int use_global_new)
       return error_mark_node;
     }
 
-  /* When the object being created is an array, the new-expression yields a
-     pointer to the initial element (if any) of the array.  For example,
-     both new int and new int[10] return an int*.  5.3.4.  */
-  if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0)
-    {
-      nelts = array_type_nelts_top (type);
-      has_array = 1;
-      type = TREE_TYPE (type);
-    }
-
-  if (has_array)
-    t = build_nt (ARRAY_REF, type, nelts, NULL_TREE, NULL_TREE);
-  else
-    t = type;
-
-  rval = build (NEW_EXPR, build_pointer_type (type), placement, t, init);
+  rval = build (NEW_EXPR, build_pointer_type (type), placement, type,
+               nelts, init);
   NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
   TREE_SIDE_EFFECTS (rval) = 1;
   rval = build_new_1 (rval);
@@ -1957,15 +1835,14 @@ build_new_1 (tree exp)
 
   placement = TREE_OPERAND (exp, 0);
   type = TREE_OPERAND (exp, 1);
-  init = TREE_OPERAND (exp, 2);
+  nelts = TREE_OPERAND (exp, 2);
+  init = TREE_OPERAND (exp, 3);
   globally_qualified_p = NEW_EXPR_USE_GLOBAL (exp);
 
-  if (TREE_CODE (type) == ARRAY_REF)
+  if (nelts)
     {
       has_array = 1;
-      nelts = outer_nelts = TREE_OPERAND (type, 1);
-      type = TREE_OPERAND (type, 0);
-
+      outer_nelts = nelts;
       /* Use an incomplete array type to avoid VLA headaches.  */
       full_type = build_cplus_array_type (type, NULL_TREE);
     }
index d10fa2e37585698ed2814d6fd7370a5c8943af0d..7152e692759296c780c760f9a8cef231b8553694 100644 (file)
@@ -82,62 +82,6 @@ struct impl_files
 
 static struct impl_files *impl_file_chain;
 
-\f
-/* Return something to represent absolute declarators containing a *.
-   TARGET is the absolute declarator that the * contains.
-   CV_QUALIFIERS is a list of modifiers such as const or volatile
-   to apply to the pointer type, represented as identifiers.
-
-   We return an INDIRECT_REF whose "contents" are TARGET
-   and whose type is the modifier list.  */
-
-tree
-make_pointer_declarator (tree cv_qualifiers, tree target)
-{
-  if (target && TREE_CODE (target) == IDENTIFIER_NODE
-      && ANON_AGGRNAME_P (target))
-    error ("type name expected before `*'");
-  target = build_nt (INDIRECT_REF, target);
-  TREE_TYPE (target) = cv_qualifiers;
-  return target;
-}
-
-/* Return something to represent absolute declarators containing a &.
-   TARGET is the absolute declarator that the & contains.
-   CV_QUALIFIERS is a list of modifiers such as const or volatile
-   to apply to the reference type, represented as identifiers.
-
-   We return an ADDR_EXPR whose "contents" are TARGET
-   and whose type is the modifier list.  */
-
-tree
-make_reference_declarator (tree cv_qualifiers, tree target)
-{
-  target = build_nt (ADDR_EXPR, target);
-  TREE_TYPE (target) = cv_qualifiers;
-  return target;
-}
-
-tree
-make_call_declarator (tree target, tree parms, tree cv_qualifiers, 
-                      tree exception_specification)
-{
-  target = build_nt (CALL_EXPR, target,
-                    tree_cons (parms, cv_qualifiers, NULL_TREE),
-                    /* The third operand is really RTL.  We
-                       shouldn't put anything there.  */
-                    NULL_TREE);
-  CALL_DECLARATOR_EXCEPTION_SPEC (target) = exception_specification;
-  return target;
-}
-
-void
-set_quals_and_spec (tree call_declarator, tree cv_qualifiers, 
-                    tree exception_specification)
-{
-  CALL_DECLARATOR_QUALS (call_declarator) = cv_qualifiers;
-  CALL_DECLARATOR_EXCEPTION_SPEC (call_declarator) = exception_specification;
-}
 \f
 int interface_only;            /* whether or not current file is only for
                                   interface definitions.  */
index 495244fa748fb9433a4f3995f278fc5ea422c7dd..cc06725c3c3b40bdd68f473ac098f8186c6099b8 100644 (file)
@@ -448,7 +448,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
 
       DECL_RESULT (thunk_fndecl) = NULL_TREE;
 
-      start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
+      start_preparsed_function (thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
       /* We don't bother with a body block for thunks.  */
 
       /* There's no need to check accessibility inside the thunk body.  */
@@ -742,7 +742,7 @@ synthesize_method (tree fndecl)
   DECL_SOURCE_LOCATION (fndecl) = input_location;
 
   interface_unknown = 1;
-  start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
+  start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
   clear_last_expr ();
   stmt = begin_function_body ();
 
@@ -937,56 +937,56 @@ locate_copy (tree type, void *client_)
 tree
 implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
 {
-  tree declspecs = NULL_TREE;
-  tree fn, args = NULL_TREE;
+  tree fn;
+  tree parameter_types = void_list_node;
+  tree return_type = void_type_node;
+  tree fn_type;
   tree raises = empty_except_spec;
-  bool retref = false;
-  bool has_parm = false;
-  tree name = constructor_name (type);
+  tree rhs_parm_type = NULL_TREE;
+  tree name;
 
   switch (kind)
     {
     case sfk_destructor:
       /* Destructor.  */
-      name = build_nt (BIT_NOT_EXPR, name);
-      args = void_list_node;
+      name = constructor_name (type);
       raises = synthesize_exception_spec (type, &locate_dtor, 0);
       break;
 
     case sfk_constructor:
       /* Default constructor.  */
-      args = void_list_node;
+      name = constructor_name (type);
       raises = synthesize_exception_spec (type, &locate_ctor, 0);
+      TYPE_HAS_CONSTRUCTOR (type) = 1;
       break;
 
     case sfk_copy_constructor:
+      TYPE_HAS_CONSTRUCTOR (type) = 1;
+      /* Fall through. */
     case sfk_assignment_operator:
     {
       struct copy_data data;
-      tree argtype = type;
       
-      has_parm = true;
       data.name = NULL;
       data.quals = 0;
       if (kind == sfk_assignment_operator)
         {
-          retref = true;
-          declspecs = build_tree_list (NULL_TREE, type);
-
+         return_type = build_reference_type (type);
           name = ansi_assopname (NOP_EXPR);
           data.name = name;
         }
+      else
+       name = constructor_name (type);
+
       if (const_p)
         {
           data.quals = TYPE_QUAL_CONST;
-          argtype = build_qualified_type (argtype, TYPE_QUAL_CONST);
+         rhs_parm_type = build_qualified_type (type, TYPE_QUAL_CONST);
         }
-    
-      argtype = build_reference_type (argtype);
-      args = build_tree_list (hash_tree_chain (argtype, NULL_TREE),
-                             get_identifier ("_ctor_arg"));
-      args = tree_cons (NULL_TREE, args, void_list_node);
-      
+      else
+       rhs_parm_type = type;
+      rhs_parm_type = build_reference_type (rhs_parm_type);
+      parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
       raises = synthesize_exception_spec (type, &locate_copy, &data);
       break;
     }
@@ -994,21 +994,37 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
       abort ();
     }
 
-  TREE_PARMLIST (args) = 1;
-
-  {
-    tree declarator = make_call_declarator (name, args, NULL_TREE, raises);
-    
-    if (retref)
-      declarator = build_nt (ADDR_EXPR, declarator);
-
-    fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
-    if (has_parm)
-      TREE_USED (FUNCTION_FIRST_USER_PARM (fn)) = 1;
-  }
-
-  my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 20000408);
+  /* Create the function.  */
+  fn_type = build_method_type_directly (type, return_type, parameter_types);
+  if (raises)
+    fn_type = build_exception_variant (fn_type, raises);
+  fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
+  if (kind == sfk_constructor || kind == sfk_copy_constructor)
+    DECL_CONSTRUCTOR_P (fn) = 1;
+  else if (kind == sfk_destructor)
+    DECL_DESTRUCTOR_P (fn) = 1;
+  else
+    {
+      DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
+      SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+    }
+  /* Create the argument list.  The call to "grokclassfn" will add the
+     "this" parameter and any other implicit parameters.  */
+  if (rhs_parm_type)
+    {
+      /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
+        want its type to be included in the mangled function
+        name.  */
+      DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
+      TREE_READONLY (DECL_ARGUMENTS (fn)) = 1;
+    }
 
+  grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL,
+              /*quals=*/NULL_TREE);
+  grok_special_member_properties (fn);
+  cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE,
+                 /*flags=*/LOOKUP_ONLYCONVERTING);
+  DECL_IN_AGGR_P (fn) = 1;
   DECL_ARTIFICIAL (fn) = 1;
   DECL_NOT_REALLY_EXTERN (fn) = 1;
   DECL_DECLARED_INLINE_P (fn) = 1;
index 5102f576bbe11f041b087f4bae7c13de52abb24e..448a0b376a900cc1c91194574701872631d6140a 100644 (file)
@@ -132,7 +132,7 @@ maybe_clone_body (tree fn)
 
       /* Start processing the function.  */
       push_to_top_level ();
-      start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED);
+      start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
 
       /* Remap the parameters.  */
       decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
index 5ad4250ee0a8e7ab874516bb67a8ed5ee547a5eb..d86f203967506a3be3b469cdd08d1e63d8733632 100644 (file)
@@ -995,6 +995,181 @@ cp_lexer_stop_debugging (cp_lexer* lexer)
 }
 
 \f
+/* Declarators.  */
+
+/* Nothing other than the parser should be creating declarators;
+   declarators are a semi-syntactic representation of C++ entities.
+   Other parts of the front end that need to create entities (like
+   VAR_DECLs or FUNCTION_DECLs) should do that directly.  */
+
+static cp_declarator *make_id_declarator 
+  (tree);
+static cp_declarator *make_call_declarator     
+  (cp_declarator *, cp_parameter_declarator *, tree, tree);
+static cp_declarator *make_array_declarator    
+  (cp_declarator *, tree);
+static cp_declarator *make_pointer_declarator  
+  (tree, cp_declarator *);
+static cp_declarator *make_reference_declarator        
+  (tree, cp_declarator *);
+static cp_parameter_declarator *make_parameter_declarator 
+  (tree, cp_declarator *, tree);
+static cp_declarator *make_ptrmem_declarator   
+  (tree, tree, cp_declarator *);
+
+cp_declarator *cp_error_declarator;
+
+/* The obstack on which declarators and related data structures are
+   allocated.  */
+static struct obstack declarator_obstack;
+
+/* Alloc BYTES from the declarator memory pool.  */
+
+static inline void *
+alloc_declarator (size_t bytes)
+{
+  return obstack_alloc (&declarator_obstack, bytes);
+}
+
+/* Allocate a declarator of the indicated KIND.  Clear fields that are
+   common to all declarators.  */
+
+static cp_declarator *
+make_declarator (cp_declarator_kind kind)
+{
+  cp_declarator *declarator;
+
+  declarator = (cp_declarator *) alloc_declarator (sizeof (cp_declarator));
+  declarator->kind = kind;
+  declarator->attributes = NULL_TREE;
+  declarator->declarator = NULL;
+
+  return declarator;
+}
+
+/* Make a declarator for a generalized identifier.  */
+
+cp_declarator *
+make_id_declarator (tree id)
+{
+  cp_declarator *declarator;
+  
+  declarator = make_declarator (cdk_id);
+  declarator->u.id.name = id;
+  declarator->u.id.sfk = sfk_none;
+
+  return declarator;
+}
+
+/* Make a declarator for a pointer to TARGET.  CV_QUALIFIERS is a list
+   of modifiers such as const or volatile to apply to the pointer
+   type, represented as identifiers.  */
+
+cp_declarator *
+make_pointer_declarator (tree cv_qualifiers, cp_declarator *target)
+{
+  cp_declarator *declarator;
+
+  declarator = make_declarator (cdk_pointer);
+  declarator->declarator = target;
+  declarator->u.pointer.qualifiers = cv_qualifiers;
+  declarator->u.pointer.class_type = NULL_TREE;
+
+  return declarator;
+}
+
+/* Like make_pointer_declarator -- but for references.  */
+
+cp_declarator *
+make_reference_declarator (tree cv_qualifiers, cp_declarator *target)
+{
+  cp_declarator *declarator;
+
+  declarator = make_declarator (cdk_reference);
+  declarator->declarator = target;
+  declarator->u.pointer.qualifiers = cv_qualifiers;
+  declarator->u.pointer.class_type = NULL_TREE;
+
+  return declarator;
+}
+
+/* Like make_pointer_declarator -- but for a pointer to a non-static
+   member of CLASS_TYPE.  */
+
+cp_declarator *
+make_ptrmem_declarator (tree cv_qualifiers, tree class_type,
+                       cp_declarator *pointee)
+{
+  cp_declarator *declarator;
+
+  declarator = make_declarator (cdk_ptrmem);
+  declarator->declarator = pointee;
+  declarator->u.pointer.qualifiers = cv_qualifiers;
+  declarator->u.pointer.class_type = class_type;
+
+  return declarator;
+}
+
+/* Make a declarator for the function given by TARGET, with the
+   indicated PARMS.  The CV_QUALIFIERS aply to the function, as in
+   "const"-qualified member function.  The EXCEPTION_SPECIFICATION
+   indicates what exceptions can be thrown.  */
+
+cp_declarator *
+make_call_declarator (cp_declarator *target, 
+                     cp_parameter_declarator *parms,
+                     tree cv_qualifiers, 
+                      tree exception_specification)
+{
+  cp_declarator *declarator;
+
+  declarator = make_declarator (cdk_function);
+  declarator->declarator = target;
+  declarator->u.function.parameters = parms;
+  declarator->u.function.qualifiers = cv_qualifiers;
+  declarator->u.function.exception_specification = exception_specification;
+
+  return declarator;
+}
+
+/* Make a declarator for an array of BOUNDS elements, each of which is
+   defined by ELEMENT.  */
+
+cp_declarator *
+make_array_declarator (cp_declarator *element, tree bounds)
+{
+  cp_declarator *declarator;
+
+  declarator = make_declarator (cdk_array);
+  declarator->declarator = element;
+  declarator->u.array.bounds = bounds;
+
+  return declarator;
+}
+
+cp_parameter_declarator *no_parameters;
+
+/* Create a parameter declarator with the indicated DECL_SPECIFIERS,
+   DECLARATOR and DEFAULT_ARGUMENT.  */
+
+cp_parameter_declarator *
+make_parameter_declarator (tree decl_specifiers, 
+                          cp_declarator *declarator,
+                          tree default_argument)
+{
+  cp_parameter_declarator *parameter;
+
+  parameter = ((cp_parameter_declarator *) 
+              alloc_declarator (sizeof (cp_parameter_declarator)));
+  parameter->next = NULL;
+  parameter->decl_specifiers = decl_specifiers;
+  parameter->declarator = declarator;
+  parameter->default_argument = default_argument;
+  parameter->ellipsis_p = false;
+
+  return parameter;
+}
+
 /* The parser.  */
 
 /* Overview
@@ -1366,10 +1541,10 @@ static tree cp_parser_new_expression
 static tree cp_parser_new_placement
   (cp_parser *);
 static tree cp_parser_new_type_id
+  (cp_parser *, tree *);
+static cp_declarator *cp_parser_new_declarator_opt
   (cp_parser *);
-static tree cp_parser_new_declarator_opt
-  (cp_parser *);
-static tree cp_parser_direct_new_declarator
+static cp_declarator *cp_parser_direct_new_declarator
   (cp_parser *);
 static tree cp_parser_new_initializer
   (cp_parser *);
@@ -1495,9 +1670,9 @@ static void cp_parser_linkage_specification
 
 static tree cp_parser_init_declarator
   (cp_parser *, tree, tree, bool, bool, int, bool *);
-static tree cp_parser_declarator
+static cp_declarator *cp_parser_declarator
   (cp_parser *, cp_parser_declarator_kind, int *, bool *);
-static tree cp_parser_direct_declarator
+static cp_declarator *cp_parser_direct_declarator
   (cp_parser *, cp_parser_declarator_kind, int *);
 static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, tree *);
@@ -1511,11 +1686,11 @@ static tree cp_parser_type_id
   (cp_parser *);
 static tree cp_parser_type_specifier_seq
   (cp_parser *);
-static tree cp_parser_parameter_declaration_clause
+static cp_parameter_declarator *cp_parser_parameter_declaration_clause
   (cp_parser *);
-static tree cp_parser_parameter_declaration_list
-  (cp_parser *);
-static tree cp_parser_parameter_declaration
+static cp_parameter_declarator *cp_parser_parameter_declaration_list
+  (cp_parser *, bool *);
+static cp_parameter_declarator *cp_parser_parameter_declaration
   (cp_parser *, bool, bool *);
 static void cp_parser_function_body
   (cp_parser *);
@@ -1561,7 +1736,7 @@ static tree cp_parser_conversion_function_id
   (cp_parser *);
 static tree cp_parser_conversion_type_id
   (cp_parser *);
-static tree cp_parser_conversion_declarator_opt
+static cp_declarator *cp_parser_conversion_declarator_opt
   (cp_parser *);
 static bool cp_parser_ctor_initializer_opt
   (cp_parser *);
@@ -1586,7 +1761,7 @@ static void cp_parser_template_declaration
 static tree cp_parser_template_parameter_list
   (cp_parser *);
 static tree cp_parser_template_parameter
-  (cp_parser *);
+  (cp_parser *, bool *);
 static tree cp_parser_type_parameter
   (cp_parser *);
 static tree cp_parser_template_id
@@ -1647,7 +1822,7 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 static bool cp_parser_check_declarator_template_parameters
-  (cp_parser *, tree);
+  (cp_parser *, cp_declarator *);
 static bool cp_parser_check_template_parameters
   (cp_parser *, unsigned);
 static tree cp_parser_simple_cast_expression
@@ -1659,7 +1834,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, tree);
+  (cp_parser *, tree, tree, const cp_declarator *);
 static tree cp_parser_function_definition_after_declarator
   (cp_parser *, bool);
 static void cp_parser_template_declaration_after_export
@@ -1669,7 +1844,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, tree, tree);
+  (cp_parser *, tree, cp_declarator *, tree);
 static tree cp_parser_enclosed_template_argument_list
   (cp_parser *);
 static void cp_parser_save_default_args
@@ -1729,7 +1904,7 @@ static bool cp_parser_simulate_error
 static void cp_parser_check_type_definition
   (cp_parser *);
 static void cp_parser_check_for_definition_in_return_type
-  (tree, int);
+  (cp_declarator *, int);
 static void cp_parser_check_for_invalid_template_id
   (cp_parser *, tree);
 static bool cp_parser_non_integral_constant_expression
@@ -1871,18 +2046,19 @@ cp_parser_check_type_definition (cp_parser* parser)
    then an error is issued.  */
 
 static void
-cp_parser_check_for_definition_in_return_type (tree declarator,
+cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
                                               int declares_class_or_enum)
 {
   /* [dcl.fct] forbids type definitions in return types.
      Unfortunately, it's not easy to know whether or not we are
      processing a return type until after the fact.  */
   while (declarator
-        && (TREE_CODE (declarator) == INDIRECT_REF
-            || TREE_CODE (declarator) == ADDR_EXPR))
-    declarator = TREE_OPERAND (declarator, 0);
+        && (declarator->kind == cdk_pointer
+            || declarator->kind == cdk_reference
+            || declarator->kind == cdk_ptrmem))
+    declarator = declarator->declarator;
   if (declarator
-      && TREE_CODE (declarator) == CALL_EXPR
+      && declarator->kind == cdk_function
       && declares_class_or_enum & 2)
     error ("new types may not be defined in a return type");
 }
@@ -2423,27 +2599,55 @@ cp_parser_identifier (cp_parser* parser)
 static bool
 cp_parser_translation_unit (cp_parser* parser)
 {
+  /* The address of the first non-permanent object on the declarator
+     obstack.  */
+  static void *declarator_obstack_base;
+
+  bool success;
+  
+  /* Create the declarator obstack, if necessary.  */
+  if (!cp_error_declarator)
+    {
+      gcc_obstack_init (&declarator_obstack);
+      /* 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);
+      /* Remember where the base of the declarator obstack lies.  */
+      declarator_obstack_base = obstack_next_free (&declarator_obstack);
+    }
+
   while (true)
     {
       cp_parser_declaration_seq_opt (parser);
 
       /* If there are no tokens left then all went well.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
-       break;
+       {
+         /* Consume the EOF token.  */
+         cp_parser_require (parser, CPP_EOF, "end-of-file");
+         
+         /* Finish up.  */
+         finish_translation_unit ();
 
-      /* Otherwise, issue an error message.  */
-      cp_parser_error (parser, "expected declaration");
-      return false;
+         success = true;
+         break;
+       }
+      else
+       {
+         cp_parser_error (parser, "expected declaration");
+         success = false;
+         break;
+       }
     }
 
-  /* Consume the EOF token.  */
-  cp_parser_require (parser, CPP_EOF, "end-of-file");
-
-  /* Finish up.  */
-  finish_translation_unit ();
+  /* Make sure the declarator obstack was fully cleaned up.  */
+  my_friendly_assert (obstack_next_free (&declarator_obstack) ==
+                     declarator_obstack_base,
+                     20040621);
 
   /* All went well.  */
-  return true;
+  return success;
 }
 
 /* Expressions [gram.expr] */
@@ -4557,6 +4761,7 @@ cp_parser_new_expression (cp_parser* parser)
   tree placement;
   tree type;
   tree initializer;
+  tree nelts;
 
   /* Look for the optional `::' operator.  */
   global_scope_p
@@ -4593,10 +4798,11 @@ cp_parser_new_expression (cp_parser* parser)
          inform ("try removing the parentheses around the type-id");
          cp_parser_direct_new_declarator (parser);
        }
+      nelts = integer_one_node;
     }
   /* Otherwise, there must be a new-type-id.  */
   else
-    type = cp_parser_new_type_id (parser);
+    type = cp_parser_new_type_id (parser, &nelts);
 
   /* If the next token is a `(', then we have a new-initializer.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -4610,7 +4816,7 @@ cp_parser_new_expression (cp_parser* parser)
     return error_mark_node;
 
   /* Create a representation of the new-expression.  */
-  return build_new (placement, type, initializer, global_scope_p);
+  return build_new (placement, type, nelts, initializer, global_scope_p);
 }
 
 /* Parse a new-placement.
@@ -4637,15 +4843,19 @@ cp_parser_new_placement (cp_parser* parser)
    new-type-id:
      type-specifier-seq new-declarator [opt]
 
-   Returns a TREE_LIST whose TREE_PURPOSE is the type-specifier-seq,
-   and whose TREE_VALUE is the new-declarator.  */
+   Returns the TYPE allocated.  If the new-type-id indicates an array
+   type, *NELTS is set to the number of elements in the last array
+   bound; the TYPE will not include the last array bound.  */
 
 static tree
-cp_parser_new_type_id (cp_parser* parser)
+cp_parser_new_type_id (cp_parser* parser, tree *nelts)
 {
   tree type_specifier_seq;
-  tree declarator;
+  cp_declarator *new_declarator;
+  cp_declarator *declarator;
+  cp_declarator *outer_declarator;
   const char *saved_message;
+  tree type;
 
   /* The type-specifier sequence must not contain type definitions.
      (It cannot contain declarations of new types either, but if they
@@ -4659,9 +4869,56 @@ cp_parser_new_type_id (cp_parser* parser)
   /* Restore the old message.  */
   parser->type_definition_forbidden_message = saved_message;
   /* Parse the new-declarator.  */
-  declarator = cp_parser_new_declarator_opt (parser);
+  new_declarator = cp_parser_new_declarator_opt (parser);
 
-  return build_tree_list (type_specifier_seq, declarator);
+  /* Determine the number of elements in the last array dimension, if
+     any.  */
+  *nelts = NULL_TREE;
+  /* Skip down to the last array dimension.  */
+  declarator = new_declarator;
+  outer_declarator = NULL;
+  while (declarator && (declarator->kind == cdk_pointer
+                       || declarator->kind == cdk_ptrmem))
+    {
+      outer_declarator = declarator;
+      declarator = declarator->declarator;
+    }
+  while (declarator 
+        && declarator->kind == cdk_array
+        && declarator->declarator
+        && declarator->declarator->kind == cdk_array)
+    {
+      outer_declarator = declarator;
+      declarator = declarator->declarator;
+    }
+  
+  if (declarator && declarator->kind == cdk_array)
+    {
+      *nelts = declarator->u.array.bounds;
+      if (*nelts == error_mark_node)
+       *nelts = integer_one_node;
+      else if (!processing_template_decl)
+       {
+         if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, *nelts, 
+                                          false))
+           pedwarn ("size in array new must have integral type");
+         *nelts = save_expr (cp_convert (sizetype, *nelts));
+         if (*nelts == integer_zero_node)
+           warning ("zero size array reserves no space");
+       }
+      if (outer_declarator)
+       outer_declarator->declarator = declarator->declarator;
+      else
+       new_declarator = NULL;
+    }
+
+  type = groktypename (type_specifier_seq, new_declarator);
+  if (TREE_CODE (type) == ARRAY_TYPE && *nelts == NULL_TREE)
+    {
+      *nelts = array_type_nelts_top (type);
+      type = TREE_TYPE (type);
+    }
+  return type;
 }
 
 /* Parse an (optional) new-declarator.
@@ -4670,10 +4927,9 @@ cp_parser_new_type_id (cp_parser* parser)
      ptr-operator new-declarator [opt]
      direct-new-declarator
 
-   Returns a representation of the declarator.  See
-   cp_parser_declarator for the representations used.  */
+   Returns the declarator.  */
 
-static tree
+static cp_declarator *
 cp_parser_new_declarator_opt (cp_parser* parser)
 {
   enum tree_code code;
@@ -4687,23 +4943,23 @@ cp_parser_new_declarator_opt (cp_parser* parser)
   /* If that worked, look for more new-declarators.  */
   if (cp_parser_parse_definitely (parser))
     {
-      tree declarator;
+      cp_declarator *declarator;
 
       /* Parse another optional declarator.  */
       declarator = cp_parser_new_declarator_opt (parser);
 
       /* Create the representation of the declarator.  */
-      if (code == INDIRECT_REF)
+      if (type)
+       declarator = make_ptrmem_declarator (cv_qualifier_seq,
+                                            type,
+                                            declarator);
+      else if (code == INDIRECT_REF)
        declarator = make_pointer_declarator (cv_qualifier_seq,
                                              declarator);
       else
        declarator = make_reference_declarator (cv_qualifier_seq,
                                                declarator);
 
-     /* Handle the pointer-to-member case.  */
-     if (type)
-       declarator = build_nt (SCOPE_REF, type, declarator);
-
       return declarator;
     }
 
@@ -4711,7 +4967,7 @@ cp_parser_new_declarator_opt (cp_parser* parser)
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
     return cp_parser_direct_new_declarator (parser);
 
-  return NULL_TREE;
+  return NULL;
 }
 
 /* Parse a direct-new-declarator.
@@ -4720,13 +4976,12 @@ cp_parser_new_declarator_opt (cp_parser* parser)
      [ expression ]
      direct-new-declarator [constant-expression]
 
-   Returns an ARRAY_REF, following the same conventions as are
-   documented for cp_parser_direct_declarator.  */
+   */
 
-static tree
+static cp_declarator *
 cp_parser_direct_new_declarator (cp_parser* parser)
 {
-  tree declarator = NULL_TREE;
+  cp_declarator *declarator = NULL;
 
   while (true)
     {
@@ -4767,8 +5022,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
       cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
 
       /* Add this bound to the declarator.  */
-      declarator = build_nt (ARRAY_REF, declarator, expression,
-                            NULL_TREE, NULL_TREE);
+      declarator = make_array_declarator (declarator, expression);
 
       /* If the next token is not a `[', then there are no more
         bounds.  */
@@ -6023,7 +6277,7 @@ cp_parser_condition (cp_parser* parser)
       tree decl;
       tree asm_specification;
       tree attributes;
-      tree declarator;
+      cp_declarator *declarator;
       tree initializer = NULL_TREE;
 
       /* Parse the declarator.  */
@@ -6334,9 +6588,17 @@ cp_parser_jump_statement (cp_parser* parser)
 static void
 cp_parser_declaration_statement (cp_parser* parser)
 {
-  /* Parse the block-declaration.  */
+  void *p;
+
+  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
+  p = obstack_alloc (&declarator_obstack, 0);
+
+ /* Parse the block-declaration.  */
   cp_parser_block_declaration (parser, /*statement_p=*/true);
 
+  /* Free any declarators allocated.  */
+  obstack_free (&declarator_obstack, p);
+
   /* Finish off the statement.  */
   finish_stmt ();
 }
@@ -6467,6 +6729,7 @@ cp_parser_declaration (cp_parser* parser)
   cp_token token1;
   cp_token token2;
   int saved_pedantic;
+  void *p;
 
   /* Set this here since we can be called after
      pushing the linkage specification.  */
@@ -6495,6 +6758,9 @@ cp_parser_declaration (cp_parser* parser)
 
   c_lex_string_translate = 1;
 
+  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
+  p = obstack_alloc (&declarator_obstack, 0);
+
   /* If the next token is `extern' and the following token is a string
      literal, then we have a linkage specification.  */
   if (token1.keyword == RID_EXTERN
@@ -6544,6 +6810,9 @@ cp_parser_declaration (cp_parser* parser)
   else
     /* Try to parse a block-declaration, or a function-definition.  */
     cp_parser_block_declaration (parser, /*statement_p=*/false);
+
+  /* Free any declarators allocated.  */
+  obstack_free (&declarator_obstack, p);
 }
 
 /* Parse a block-declaration.
@@ -7229,7 +7498,7 @@ cp_parser_conversion_type_id (cp_parser* parser)
 {
   tree attributes;
   tree type_specifiers;
-  tree declarator;
+  cp_declarator *declarator;
 
   /* Parse the attributes.  */
   attributes = cp_parser_attributes_opt (parser);
@@ -7250,10 +7519,9 @@ cp_parser_conversion_type_id (cp_parser* parser)
    conversion-declarator:
      ptr-operator conversion-declarator [opt]
 
-   Returns a representation of the declarator.  See
-   cp_parser_declarator for details.  */
+   */
 
-static tree
+static cp_declarator *
 cp_parser_conversion_declarator_opt (cp_parser* parser)
 {
   enum tree_code code;
@@ -7268,27 +7536,27 @@ cp_parser_conversion_declarator_opt (cp_parser* parser)
   /* If it worked, look for more conversion-declarators.  */
   if (cp_parser_parse_definitely (parser))
     {
-     tree declarator;
-
-     /* Parse another optional declarator.  */
-     declarator = cp_parser_conversion_declarator_opt (parser);
-
-     /* Create the representation of the declarator.  */
-     if (code == INDIRECT_REF)
-       declarator = make_pointer_declarator (cv_qualifier_seq,
+      cp_declarator *declarator;
+      
+      /* Parse another optional declarator.  */
+      declarator = cp_parser_conversion_declarator_opt (parser);
+      
+      /* Create the representation of the declarator.  */
+      if (class_type)
+       declarator = make_ptrmem_declarator (cv_qualifier_seq,
+                                            class_type,
                                             declarator);
-     else
-       declarator =  make_reference_declarator (cv_qualifier_seq,
+      else if (code == INDIRECT_REF)
+       declarator = make_pointer_declarator (cv_qualifier_seq,
+                                             declarator);
+      else
+       declarator = make_reference_declarator (cv_qualifier_seq,
                                                declarator);
-
-     /* Handle the pointer-to-member case.  */
-     if (class_type)
-       declarator = build_nt (SCOPE_REF, class_type, declarator);
-
-     return declarator;
+      
+      return declarator;
    }
 
-  return NULL_TREE;
+  return NULL;
 }
 
 /* Parse an (optional) ctor-initializer.
@@ -7812,13 +8080,14 @@ cp_parser_template_parameter_list (cp_parser* parser)
     {
       tree parameter;
       cp_token *token;
+      bool is_non_type;
 
       /* Parse the template-parameter.  */
-      parameter = cp_parser_template_parameter (parser);
+      parameter = cp_parser_template_parameter (parser, &is_non_type);
       /* Add it to the list.  */
       parameter_list = process_template_parm (parameter_list,
-                                             parameter);
-
+                                             parameter,
+                                             is_non_type);
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
       /* If it's not a `,', we're done.  */
@@ -7838,13 +8107,17 @@ cp_parser_template_parameter_list (cp_parser* parser)
      parameter-declaration
 
    Returns a TREE_LIST.  The TREE_VALUE represents the parameter.  The
-   TREE_PURPOSE is the default value, if any.  */
+   TREE_PURPOSE is the default value, if any.  *IS_NON_TYPE is set to
+   true iff this parameter is a non-type parameter.  */
 
 static tree
-cp_parser_template_parameter (cp_parser* parser)
+cp_parser_template_parameter (cp_parser* parser, bool *is_non_type)
 {
   cp_token *token;
+  const cp_parameter_declarator *parameter_declarator;
 
+  /* Assume it is a type parameter or a template parameter.  */
+  *is_non_type = false;
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
   /* If it is `class' or `template', we have a type-parameter.  */
@@ -7886,9 +8159,16 @@ cp_parser_template_parameter (cp_parser* parser)
      template-parameter, the first non-nested `>' is taken as the end
      of the template parameter-list rather than a greater-than
      operator.  */
-  return
-    cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
-                                    /*parenthesized_p=*/NULL);
+  *is_non_type = true;
+  parameter_declarator
+     = cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
+                                       /*parenthesized_p=*/NULL);
+  return (build_tree_list 
+         (parameter_declarator->default_argument,
+          grokdeclarator (parameter_declarator->declarator,
+                          parameter_declarator->decl_specifiers,
+                          PARM, /*initialized=*/0, 
+                          /*attrlist=*/NULL)));
 }
 
 /* Parse a type-parameter.
@@ -8769,7 +9049,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
     }
   else
     {
-      tree declarator;
+      cp_declarator *declarator;
       tree decl;
 
       /* Parse the declarator.  */
@@ -8779,7 +9059,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
                                /*parenthesized_p=*/NULL);
       cp_parser_check_for_definition_in_return_type (declarator,
                                                     declares_class_or_enum);
-      if (declarator != error_mark_node)
+      if (declarator != cp_error_declarator)
        {
          decl = grokdeclarator (declarator, decl_specifiers,
                                 NORMAL, 0, NULL);
@@ -10098,7 +10378,7 @@ cp_parser_init_declarator (cp_parser* parser,
                           bool* function_definition_p)
 {
   cp_token *token;
-  tree declarator;
+  cp_declarator *declarator;
   tree attributes;
   tree asm_specification;
   tree initializer;
@@ -10131,7 +10411,7 @@ cp_parser_init_declarator (cp_parser* parser,
 
   /* If the DECLARATOR was erroneous, there's no need to go
      further.  */
-  if (declarator == error_mark_node)
+  if (declarator == cp_error_declarator)
     return error_mark_node;
 
   cp_parser_check_for_definition_in_return_type (declarator,
@@ -10373,26 +10653,6 @@ cp_parser_init_declarator (cp_parser* parser,
      attributes [opt] ptr-operator abstract-declarator [opt]
      attributes [opt] direct-abstract-declarator
 
-   Returns a representation of the declarator.  If the declarator has
-   the form `* declarator', then an INDIRECT_REF is returned, whose
-   only operand is the sub-declarator.  Analogously, `& declarator' is
-   represented as an ADDR_EXPR.  For `X::* declarator', a SCOPE_REF is
-   used.  The first operand is the TYPE for `X'.  The second operand
-   is an INDIRECT_REF whose operand is the sub-declarator.
-
-   Otherwise, the representation is as for a direct-declarator.
-
-   (It would be better to define a structure type to represent
-   declarators, rather than abusing `tree' nodes to represent
-   declarators.  That would be much clearer and save some memory.
-   There is no reason for declarators to be garbage-collected, for
-   example; they are created during parser and no longer needed after
-   `grokdeclarator' has been called.)
-
-   For a ptr-operator that has the optional cv-qualifier-seq,
-   cv-qualifiers will be stored in the TREE_TYPE of the INDIRECT_REF
-   node.
-
    If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to
    detect constructor, destructor or conversion operators. It is set
    to -1 if the declarator is a name, and +1 if it is a
@@ -10410,14 +10670,14 @@ cp_parser_init_declarator (cp_parser* parser,
    If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
    the declarator is a direct-declarator of the form "(...)".  */
 
-static tree
+static cp_declarator *
 cp_parser_declarator (cp_parser* parser,
                       cp_parser_declarator_kind dcl_kind,
                       int* ctor_dtor_or_conv_p,
                      bool* parenthesized_p)
 {
   cp_token *token;
-  tree declarator;
+  cp_declarator *declarator;
   enum tree_code code;
   tree cv_qualifier_seq;
   tree class_type;
@@ -10461,18 +10721,19 @@ cp_parser_declarator (cp_parser* parser,
         case where the dependent declarator is absent.  */
       if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
          && !cp_parser_parse_definitely (parser))
-       declarator = NULL_TREE;
+       declarator = NULL;
 
       /* Build the representation of the ptr-operator.  */
-      if (code == INDIRECT_REF)
+      if (class_type)
+       declarator = make_ptrmem_declarator (cv_qualifier_seq,
+                                            class_type,
+                                            declarator);
+      else if (code == INDIRECT_REF)
        declarator = make_pointer_declarator (cv_qualifier_seq,
                                              declarator);
       else
        declarator = make_reference_declarator (cv_qualifier_seq,
                                                declarator);
-      /* Handle the pointer-to-member case.  */
-      if (class_type)
-       declarator = build_nt (SCOPE_REF, class_type, declarator);
     }
   /* Everything else is a direct-declarator.  */
   else
@@ -10484,8 +10745,8 @@ cp_parser_declarator (cp_parser* parser,
                                                ctor_dtor_or_conv_p);
     }
 
-  if (attributes && declarator != error_mark_node)
-    declarator = tree_cons (attributes, declarator, NULL_TREE);
+  if (attributes && declarator != cp_error_declarator)
+    declarator->attributes = attributes;
 
   return declarator;
 }
@@ -10515,24 +10776,15 @@ cp_parser_declarator (cp_parser* parser,
    CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
    of ambiguity we prefer an abstract declarator, as per
    [dcl.ambig.res].  CTOR_DTOR_OR_CONV_P is as for
-   cp_parser_declarator.
+   cp_parser_declarator.  */
 
-   For the declarator-id production, the representation is as for an
-   id-expression, except that a qualified name is represented as a
-   SCOPE_REF.  A function-declarator is represented as a CALL_EXPR;
-   see the documentation of the FUNCTION_DECLARATOR_* macros for
-   information about how to find the various declarator components.
-   An array-declarator is represented as an ARRAY_REF.  The
-   direct-declarator is the first operand; the constant-expression
-   indicating the size of the array is the second operand.  */
-
-static tree
+static cp_declarator *
 cp_parser_direct_declarator (cp_parser* parser,
                              cp_parser_declarator_kind dcl_kind,
                              int* ctor_dtor_or_conv_p)
 {
   cp_token *token;
-  tree declarator = NULL_TREE;
+  cp_declarator *declarator = NULL;
   tree scope = NULL_TREE;
   bool saved_default_arg_ok_p = parser->default_arg_ok_p;
   bool saved_in_declarator_p = parser->in_declarator_p;
@@ -10585,7 +10837,7 @@ cp_parser_direct_declarator (cp_parser* parser,
 
          if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
            {
-             tree params;
+             cp_parameter_declarator *params;
              unsigned saved_num_template_parameter_lists;
 
              cp_parser_parse_tentatively (parser);
@@ -10667,8 +10919,8 @@ cp_parser_direct_declarator (cp_parser* parser,
              first = false;
              /* Expect a `)'.  */
              if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
-               declarator = error_mark_node;
-             if (declarator == error_mark_node)
+               declarator = cp_error_declarator;
+             if (declarator == cp_error_declarator)
                break;
 
              goto handle_declarator;
@@ -10711,37 +10963,40 @@ cp_parser_direct_declarator (cp_parser* parser,
          /* Look for the closing `]'.  */
          if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'"))
            {
-             declarator = error_mark_node;
+             declarator = cp_error_declarator;
              break;
            }
 
-         declarator = build_nt (ARRAY_REF, declarator, bounds,
-                                NULL_TREE, NULL_TREE);
+         declarator = make_array_declarator (declarator, bounds);
        }
       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
        {
+         tree id;
+
          /* Parse a declarator-id */
          if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
            cp_parser_parse_tentatively (parser);
-         declarator = cp_parser_declarator_id (parser);
+         id = cp_parser_declarator_id (parser);
          if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
            {
              if (!cp_parser_parse_definitely (parser))
-               declarator = error_mark_node;
-             else if (TREE_CODE (declarator) != IDENTIFIER_NODE)
+               id = error_mark_node;
+             else if (TREE_CODE (id) != IDENTIFIER_NODE)
                {
                  cp_parser_error (parser, "expected unqualified-id");
-                 declarator = error_mark_node;
+                 id = error_mark_node;
                }
            }
 
-         if (declarator == error_mark_node)
-           break;
+         if (id == error_mark_node)
+           {
+             declarator = cp_error_declarator;
+             break;
+           }
 
-         if (TREE_CODE (declarator) == SCOPE_REF
-             && !current_scope ())
+         if (TREE_CODE (id) == SCOPE_REF && !current_scope ())
            {
-             tree scope = TREE_OPERAND (declarator, 0);
+             tree scope = TREE_OPERAND (id, 0);
 
              /* In the declaration of a member of a template class
                 outside of the class itself, the SCOPE will sometimes
@@ -10772,53 +11027,54 @@ cp_parser_direct_declarator (cp_parser* parser,
                           TYPE_CONTEXT (scope),
                           TYPE_IDENTIFIER (scope));
                  /* Build a new DECLARATOR.  */
-                 declarator = build_nt (SCOPE_REF,
-                                        type,
-                                        TREE_OPERAND (declarator, 1));
+                 id = build_nt (SCOPE_REF, type, TREE_OPERAND (id, 1));
                }
            }
 
-         /* Check to see whether the declarator-id names a constructor,
-            destructor, or conversion.  */
-         if (declarator && ctor_dtor_or_conv_p
-             && ((TREE_CODE (declarator) == SCOPE_REF
-                  && CLASS_TYPE_P (TREE_OPERAND (declarator, 0)))
-                 || (TREE_CODE (declarator) != SCOPE_REF
-                     && at_class_scope_p ())))
+         declarator = make_id_declarator (id);
+         if (id)
            {
-             tree unqualified_name;
              tree class_type;
+             tree unqualified_name;
 
-             /* Get the unqualified part of the name.  */
-             if (TREE_CODE (declarator) == SCOPE_REF)
+             if (TREE_CODE (id) == SCOPE_REF
+                 && CLASS_TYPE_P (TREE_OPERAND (id, 0)))
                {
-                 class_type = TREE_OPERAND (declarator, 0);
-                 unqualified_name = TREE_OPERAND (declarator, 1);
+                 class_type = TREE_OPERAND (id, 0);
+                 unqualified_name = TREE_OPERAND (id, 1);
                }
              else
                {
                  class_type = current_class_type;
-                 unqualified_name = declarator;
+                 unqualified_name = id;
                }
 
-             /* See if it names ctor, dtor or conv.  */
-             if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR
-                 || IDENTIFIER_TYPENAME_P (unqualified_name)
-                 || constructor_name_p (unqualified_name, class_type)
-                 || (TREE_CODE (unqualified_name) == TYPE_DECL
-                     && same_type_p (TREE_TYPE (unqualified_name),
-                                     class_type)))
-               *ctor_dtor_or_conv_p = -1;
-               if (TREE_CODE (declarator) == SCOPE_REF
-                   && TREE_CODE (unqualified_name) == TYPE_DECL 
-                   && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
-                 {
-                   error ("invalid use of constructor as a template");
-                   inform ("use `%T::%D' instead of `%T::%T' to name the "
-                           "constructor in a qualified name", class_type, 
-                           DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
-                           class_type, class_type);
-                 }
+             if (class_type)
+               {
+                 if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
+                   declarator->u.id.sfk = sfk_destructor;
+                 else if (IDENTIFIER_TYPENAME_P (unqualified_name))
+                   declarator->u.id.sfk = sfk_conversion;
+                 else if (constructor_name_p (unqualified_name,
+                                              class_type)
+                          || (TREE_CODE (unqualified_name) == TYPE_DECL
+                              && same_type_p (TREE_TYPE (unqualified_name),
+                                              class_type)))
+                   declarator->u.id.sfk = sfk_constructor;
+
+                 if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
+                   *ctor_dtor_or_conv_p = -1;
+                 if (TREE_CODE (id) == SCOPE_REF
+                     && TREE_CODE (unqualified_name) == TYPE_DECL 
+                     && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
+                   {
+                     error ("invalid use of constructor as a template");
+                     inform ("use `%T::%D' instead of `%T::%T' to name the "
+                             "constructor in a qualified name", class_type, 
+                             DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+                             class_type, class_type);
+                   }
+               }
            }
 
        handle_declarator:;
@@ -10829,9 +11085,7 @@ cp_parser_direct_declarator (cp_parser* parser,
            pop_p = push_scope (scope);
          parser->in_declarator_p = true;
          if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
-             || (declarator
-                 && (TREE_CODE (declarator) == SCOPE_REF
-                     || TREE_CODE (declarator) == IDENTIFIER_NODE)))
+             || (declarator && declarator->kind == cdk_id))
            /* Default args are only allowed on function
               declarations.  */
            parser->default_arg_ok_p = saved_default_arg_ok_p;
@@ -11078,7 +11332,7 @@ static tree
 cp_parser_type_id (cp_parser* parser)
 {
   tree type_specifier_seq;
-  tree abstract_declarator;
+  cp_declarator *abstract_declarator;
 
   /* Parse the type-specifier-seq.  */
   type_specifier_seq
@@ -11094,10 +11348,9 @@ cp_parser_type_id (cp_parser* parser)
                            /*parenthesized_p=*/NULL);
   /* Check to see if there really was a declarator.  */
   if (!cp_parser_parse_definitely (parser))
-    abstract_declarator = NULL_TREE;
+    abstract_declarator = NULL;
 
-  return groktypename (build_tree_list (type_specifier_seq,
-                                       abstract_declarator));
+  return groktypename (type_specifier_seq, abstract_declarator);
 }
 
 /* Parse a type-specifier-seq.
@@ -11168,19 +11421,17 @@ cp_parser_type_specifier_seq (cp_parser* parser)
      parameter-declaration-list [opt] ... [opt]
      parameter-declaration-list , ...
 
-   Returns a representation for the parameter declarations.  Each node
-   is a TREE_LIST.  (See cp_parser_parameter_declaration for the exact
-   representation.)  If the parameter-declaration-clause ends with an
-   ellipsis, PARMLIST_ELLIPSIS_P will hold of the first node in the
-   list.  A return value of NULL_TREE indicates a
-   parameter-declaration-clause consisting only of an ellipsis.  */
+   Returns a representation for the parameter declarations.  A return
+   value of NULL indicates a parameter-declaration-clause consisting
+   only of an ellipsis.  */
 
-static tree
+static cp_parameter_declarator *
 cp_parser_parameter_declaration_clause (cp_parser* parser)
 {
-  tree parameters;
+  cp_parameter_declarator *parameters;
   cp_token *token;
   bool ellipsis_p;
+  bool is_error;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -11189,7 +11440,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
     {
       /* Consume the `...' token.  */
       cp_lexer_consume_token (parser->lexer);
-      return NULL_TREE;
+      return NULL;
     }
   else if (token->type == CPP_CLOSE_PAREN)
     /* There are no parameters.  */
@@ -11197,10 +11448,10 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
 #ifndef NO_IMPLICIT_EXTERN_C
       if (in_system_header && current_class_type == NULL
          && current_lang_name == lang_name_c)
-       return NULL_TREE;
+       return NULL;
       else
 #endif
-       return void_list_node;
+       return no_parameters;
     }
   /* Check for `(void)', too, which is a special case.  */
   else if (token->keyword == RID_VOID
@@ -11210,16 +11461,16 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
       /* Consume the `void' token.  */
       cp_lexer_consume_token (parser->lexer);
       /* There are no parameters.  */
-      return void_list_node;
+      return no_parameters;
     }
 
   /* Parse the parameter-declaration-list.  */
-  parameters = cp_parser_parameter_declaration_list (parser);
+  parameters = cp_parser_parameter_declaration_list (parser, &is_error);
   /* If a parse error occurred while parsing the
      parameter-declaration-list, then the entire
      parameter-declaration-clause is erroneous.  */
-  if (parameters == error_mark_node)
-    return error_mark_node;
+  if (is_error)
+    return NULL;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -11245,7 +11496,10 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
     ellipsis_p = false;
 
   /* Finish the parameter list.  */
-  return finish_parmlist (parameters, ellipsis_p);
+  if (parameters && ellipsis_p)
+    parameters->ellipsis_p = true;
+  
+  return parameters;
 }
 
 /* Parse a parameter-declaration-list.
@@ -11256,17 +11510,22 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
 
    Returns a representation of the parameter-declaration-list, as for
    cp_parser_parameter_declaration_clause.  However, the
-   `void_list_node' is never appended to the list.  */
+   `void_list_node' is never appended to the list.  Upon return,
+   *IS_ERROR will be true iff an error occurred.  */
 
-static tree
-cp_parser_parameter_declaration_list (cp_parser* parser)
+static cp_parameter_declarator *
+cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
 {
-  tree parameters = NULL_TREE;
+  cp_parameter_declarator *parameters = NULL;
+  cp_parameter_declarator **tail = &parameters;
+
+  /* Assume all will go well.  */
+  *is_error = false;
 
   /* Look for more parameters.  */
   while (true)
     {
-      tree parameter;
+      cp_parameter_declarator *parameter;
       bool parenthesized_p;
       /* Parse the parameter.  */
       parameter
@@ -11276,14 +11535,15 @@ cp_parser_parameter_declaration_list (cp_parser* parser)
 
       /* If a parse error occurred parsing the parameter declaration,
         then the entire parameter-declaration-list is erroneous.  */
-      if (parameter == error_mark_node)
+      if (!parameter)
        {
-         parameters = error_mark_node;
+         *is_error = true;
+         parameters = NULL;
          break;
        }
       /* Add the new parameter to the list.  */
-      TREE_CHAIN (parameter) = parameters;
-      parameters = parameter;
+      *tail = parameter;
+      tail = &parameter->next;
 
       /* Peek at the next token.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
@@ -11338,8 +11598,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser)
        }
     }
 
-  /* We built up the list in reverse order; straighten it out now.  */
-  return nreverse (parameters);
+  return parameters;
 }
 
 /* Parse a parameter declaration.
@@ -11355,16 +11614,11 @@ cp_parser_parameter_declaration_list (cp_parser* parser)
    token encountered during the parsing of the assignment-expression
    is not interpreted as a greater-than operator.)
 
-   Returns a TREE_LIST representing the parameter-declaration.  The
-   TREE_PURPOSE is the default argument expression, or NULL_TREE if
-   there is no default argument.  The TREE_VALUE is a representation
-   of the decl-specifier-seq and declarator.  In particular, the
-   TREE_VALUE will be a TREE_LIST whose TREE_PURPOSE represents the
-   decl-specifier-seq and whose TREE_VALUE represents the declarator.
-   If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
-   the declarator is of the form "(p)".  */
+   Returns a representation of the parameter, or NULL if an error
+   occurs.  If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to
+   true iff the declarator is of the form "(p)".  */
 
-static tree
+static cp_parameter_declarator *
 cp_parser_parameter_declaration (cp_parser *parser,
                                 bool template_parm_p,
                                 bool *parenthesized_p)
@@ -11373,9 +11627,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
   bool greater_than_is_operator_p;
   tree decl_specifiers;
   tree attributes;
-  tree declarator;
+  cp_declarator *declarator;
   tree default_argument;
-  tree parameter;
   cp_token *token;
   const char *saved_message;
 
@@ -11405,7 +11658,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
   if (cp_parser_error_occurred (parser))
     {
       parser->type_definition_forbidden_message = saved_message;
-      return error_mark_node;
+      return NULL;
     }
 
   /* Peek at the next token.  */
@@ -11418,7 +11671,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
       || token->type == CPP_ELLIPSIS
       || token->type == CPP_GREATER)
     {
-      declarator = NULL_TREE;
+      declarator = NULL;
       if (parenthesized_p)
        *parenthesized_p = false;
     }
@@ -11596,11 +11849,10 @@ cp_parser_parameter_declaration (cp_parser *parser,
   /* Create the representation of the parameter.  */
   if (attributes)
     decl_specifiers = tree_cons (attributes, NULL_TREE, decl_specifiers);
-  parameter = build_tree_list (default_argument,
-                              build_tree_list (decl_specifiers,
-                                               declarator));
 
-  return parameter;
+  return make_parameter_declarator (decl_specifiers,
+                                   declarator,
+                                   default_argument);
 }
 
 /* Parse a function-body.
@@ -12744,7 +12996,9 @@ cp_parser_member_declaration (cp_parser* parser)
              attributes = chainon (prefix_attributes, attributes);
 
              /* Create the bitfield declaration.  */
-             decl = grokbitfield (identifier,
+             decl = grokbitfield (identifier 
+                                  ? make_id_declarator (identifier)
+                                  : NULL,
                                   decl_specifiers,
                                   width);
              /* Apply the attributes.  */
@@ -12752,7 +13006,7 @@ cp_parser_member_declaration (cp_parser* parser)
            }
          else
            {
-             tree declarator;
+             cp_declarator *declarator;
              tree initializer;
              tree asm_specification;
              int ctor_dtor_or_conv_p;
@@ -12765,7 +13019,7 @@ cp_parser_member_declaration (cp_parser* parser)
 
              /* If something went wrong parsing the declarator, make sure
                 that we at least consume some tokens.  */
-             if (declarator == error_mark_node)
+             if (declarator == cp_error_declarator)
                {
                  /* Skip to the end of the statement.  */
                  cp_parser_skip_to_end_of_statement (parser);
@@ -12815,7 +13069,7 @@ cp_parser_member_declaration (cp_parser* parser)
                     for a pure-specifier; otherwise, we look for a
                     constant-initializer.  When we call `grokfield', it will
                     perform more stringent semantics checks.  */
-                 if (TREE_CODE (declarator) == CALL_EXPR)
+                 if (declarator->kind == cdk_function)
                    initializer = cp_parser_pure_specifier (parser);
                  else
                    /* Parse the initializer.  */
@@ -13352,8 +13606,9 @@ cp_parser_handler (cp_parser* parser)
 static tree
 cp_parser_exception_declaration (cp_parser* parser)
 {
+  tree decl;
   tree type_specifiers;
-  tree declarator;
+  cp_declarator *declarator;
   const char *saved_message;
 
   /* If it's an ellipsis, it's easy to handle.  */
@@ -13373,7 +13628,7 @@ cp_parser_exception_declaration (cp_parser* parser)
   type_specifiers = cp_parser_type_specifier_seq (parser);
   /* If it's a `)', then there is no declarator.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
-    declarator = NULL_TREE;
+    declarator = NULL;
   else
     declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
                                       /*ctor_dtor_or_conv_p=*/NULL,
@@ -13382,7 +13637,16 @@ cp_parser_exception_declaration (cp_parser* parser)
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
 
-  return start_handler_parms (type_specifiers, declarator);
+  if (type_specifiers)
+    {
+      decl = grokdeclarator (declarator, type_specifiers, CATCHPARM, 1, NULL);
+      if (decl == NULL_TREE)
+       error ("invalid catch parameter");
+    }
+  else
+    decl = NULL_TREE;
+
+  return decl;
 }
 
 /* Parse a throw-expression.
@@ -14028,73 +14292,68 @@ cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
 
 static bool
 cp_parser_check_declarator_template_parameters (cp_parser* parser,
-                                                tree declarator)
+                                               cp_declarator *declarator)
 {
   unsigned num_templates;
 
   /* We haven't seen any classes that involve template parameters yet.  */
   num_templates = 0;
 
-  switch (TREE_CODE (declarator))
+  switch (declarator->kind)
     {
-    case CALL_EXPR:
-    case ARRAY_REF:
-    case INDIRECT_REF:
-    case ADDR_EXPR:
-      {
-       tree main_declarator = TREE_OPERAND (declarator, 0);
-       return
-         cp_parser_check_declarator_template_parameters (parser,
-                                                         main_declarator);
-      }
-
-    case SCOPE_REF:
-      {
-       tree scope;
-       tree member;
-
-       scope = TREE_OPERAND (declarator, 0);
-       member = TREE_OPERAND (declarator, 1);
-
-       /* If this is a pointer-to-member, then we are not interested
-          in the SCOPE, because it does not qualify the thing that is
-          being declared.  */
-       if (TREE_CODE (member) == INDIRECT_REF)
-         return (cp_parser_check_declarator_template_parameters
-                 (parser, member));
-
-       while (scope && CLASS_TYPE_P (scope))
-         {
-           /* You're supposed to have one `template <...>'
-              for every template class, but you don't need one
-              for a full specialization.  For example:
-
-              template <class T> struct S{};
-              template <> struct S<int> { void f(); };
-              void S<int>::f () {}
-
-              is correct; there shouldn't be a `template <>' for
-              the definition of `S<int>::f'.  */
-           if (CLASSTYPE_TEMPLATE_INFO (scope)
-               && (CLASSTYPE_TEMPLATE_INSTANTIATION (scope)
-                   || uses_template_parms (CLASSTYPE_TI_ARGS (scope)))
-               && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
-             ++num_templates;
+    case cdk_id:
+      if (TREE_CODE (declarator->u.id.name) == SCOPE_REF)
+       {
+         tree scope;
+         tree member;
 
-           scope = TYPE_CONTEXT (scope);
-         }
-      }
+         scope = TREE_OPERAND (declarator->u.id.name, 0);
+         member = TREE_OPERAND (declarator->u.id.name, 1);
 
-      /* Fall through.  */
+         while (scope && CLASS_TYPE_P (scope))
+           {
+             /* You're supposed to have one `template <...>'
+                for every template class, but you don't need one
+                for a full specialization.  For example:
+
+                template <class T> struct S{};
+                template <> struct S<int> { void f(); };
+                void S<int>::f () {}
+
+                is correct; there shouldn't be a `template <>' for
+                the definition of `S<int>::f'.  */
+             if (CLASSTYPE_TEMPLATE_INFO (scope)
+                 && (CLASSTYPE_TEMPLATE_INSTANTIATION (scope)
+                     || uses_template_parms (CLASSTYPE_TI_ARGS (scope)))
+                 && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
+               ++num_templates;
+
+             scope = TYPE_CONTEXT (scope);
+           }
+       }
 
-    default:
       /* If the DECLARATOR has the form `X<y>' then it uses one
         additional level of template parameters.  */
-      if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+      if (TREE_CODE (declarator->u.id.name) == TEMPLATE_ID_EXPR)
        ++num_templates;
 
       return cp_parser_check_template_parameters (parser,
                                                  num_templates);
+
+    case cdk_function:
+    case cdk_array:
+    case cdk_pointer:
+    case cdk_reference:
+    case cdk_ptrmem:
+      return (cp_parser_check_declarator_template_parameters 
+             (parser, declarator->declarator));
+
+    case cdk_error:
+      return true;
+
+    default:
+      abort ();
+      return false;
     }
 }
 
@@ -14403,15 +14662,17 @@ cp_parser_function_definition_from_specifiers_and_declarator
   (cp_parser* parser,
    tree decl_specifiers,
    tree attributes,
-   tree declarator)
+   const cp_declarator *declarator)
 {
   tree fn;
   bool success_p;
 
   /* Begin the function-definition.  */
-  success_p = begin_function_definition (decl_specifiers,
-                                        attributes,
-                                        declarator);
+  success_p = start_function (decl_specifiers, declarator, attributes);
+
+  /* The things we're about to see are not directly qualified by any
+     template headers we've seen thus far.  */
+  reset_specialization ();
 
   /* If there were names looked up in the decl-specifier-seq that we
      did not check, check them now.  We must wait until we are in the
@@ -14421,8 +14682,7 @@ cp_parser_function_definition_from_specifiers_and_declarator
 
   if (!success_p)
     {
-      /* If begin_function_definition didn't like the definition, skip
-        the entire function.  */
+      /* Skip the entire function.  */
       error ("invalid function declaration");
       cp_parser_skip_to_end_of_block_or_statement (parser);
       fn = error_mark_node;
@@ -14707,7 +14967,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
 static tree
 cp_parser_save_member_function_body (cp_parser* parser,
                                     tree decl_specifiers,
-                                    tree declarator,
+                                    cp_declarator *declarator,
                                     tree attributes)
 {
   cp_token_cache *cache;
@@ -14881,8 +15141,8 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
 
       /* Let the front end know that we going to be defining this
         function.  */
-      start_function (NULL_TREE, member_function, NULL_TREE,
-                     SF_PRE_PARSED | SF_INCLASS_INLINE);
+      start_preparsed_function (member_function, NULL_TREE,
+                               SF_PRE_PARSED | SF_INCLASS_INLINE);
 
       /* Now, parse the body of the function.  */
       cp_parser_function_definition_after_declarator (parser,
@@ -15050,7 +15310,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
                                  type);
 
          /* Call grokdeclarator to figure out what type this is.  */
-         expr = grokdeclarator (NULL_TREE,
+         expr = grokdeclarator (NULL,
                                 type,
                                 TYPENAME,
                                 /*initialized=*/0,
index 1e23acbcf079adb2ae5d4969c76c8c8cc78e4eb8..e451a29fc20b57dda66c8fa7946b8dd952cb9e1c 100644 (file)
@@ -2161,21 +2161,20 @@ reduce_template_parm_level (tree index, tree type, int levels)
 }
 
 /* Process information from new template parameter NEXT and append it to the
-   LIST being built.  */
+   LIST being built.  This new parameter is a non-type parameter iff
+   IS_NON_TYPE is true.  */
 
 tree
-process_template_parm (tree list, tree next)
+process_template_parm (tree list, tree next, bool is_non_type)
 {
   tree parm;
   tree decl = 0;
   tree defval;
-  int is_type, idx;
+  int idx;
 
   parm = next;
   my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
   defval = TREE_PURPOSE (parm);
-  parm = TREE_VALUE (parm);
-  is_type = TREE_PURPOSE (parm) == class_type_node;
 
   if (list)
     {
@@ -2190,12 +2189,10 @@ process_template_parm (tree list, tree next)
   else
     idx = 0;
 
-  if (!is_type)
+  if (is_non_type)
     {
-      my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
-      /* is a const-param */
-      parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
-                            PARM, 0, NULL);
+      parm = TREE_VALUE (parm);
+
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       /* [temp.param]
@@ -2222,7 +2219,7 @@ process_template_parm (tree list, tree next)
   else
     {
       tree t;
-      parm = TREE_VALUE (parm);
+      parm = TREE_VALUE (TREE_VALUE (parm));
       
       if (parm && TREE_CODE (parm) == TEMPLATE_DECL)
        {
@@ -3757,7 +3754,7 @@ convert_template_argument (tree parm,
            }
        }
       else
-       val = groktypename (arg);
+       val = arg;
     }
   else
     {
@@ -6600,9 +6597,6 @@ tsubst_call_declarator_parms (tree parms,
      doesn't check TREE_PARMLIST.  */
   new_parms = tree_cons (defarg, type, new_parms);
 
-  /* And note that these are parameters.  */
-  TREE_PARMLIST (new_parms) = 1;
-  
   return new_parms;
 }
 
@@ -6852,7 +6846,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case TREE_LIST:
       {
-       tree purpose, value, chain, result;
+       tree purpose, value, chain;
 
        if (t == void_list_node)
          return t;
@@ -6882,14 +6876,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            && value == TREE_VALUE (t)
            && chain == TREE_CHAIN (t))
          return t;
-       if (TREE_PARMLIST (t))
-         {
-           result = tree_cons (purpose, value, chain);
-           TREE_PARMLIST (result) = 1;
-         }
-       else
-         result = hash_tree_cons (purpose, value, chain);
-       return result;
+       return hash_tree_cons (purpose, value, chain);
       }
     case TREE_VEC:
       if (type != NULL_TREE)
@@ -7179,20 +7166,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       }
 
     case INDIRECT_REF:
-      {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       if (e == error_mark_node)
-         return error_mark_node;
-       return make_pointer_declarator (type, e);
-      }
-
     case ADDR_EXPR:
-      {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       if (e == error_mark_node)
-         return error_mark_node;
-       return make_reference_declarator (type, e);
-      }
+    case CALL_EXPR:
+      abort ();
 
     case ARRAY_REF:
       {
@@ -7204,21 +7180,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
       }
 
-    case CALL_EXPR:
-      {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       tree e2 = (tsubst_call_declarator_parms
-                  (CALL_DECLARATOR_PARMS (t), args, complain, in_decl));
-       tree e3 = tsubst (CALL_DECLARATOR_EXCEPTION_SPEC (t), args,
-                         complain, in_decl);
-
-       if (e1 == error_mark_node || e2 == error_mark_node 
-           || e3 == error_mark_node)
-         return error_mark_node;
-
-       return make_call_declarator (e1, e2, CALL_DECLARATOR_QUALS (t), e3);
-      }
-
     case SCOPE_REF:
       {
        tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
@@ -8306,6 +8267,7 @@ tsubst_copy_and_build (tree t,
        (RECUR (TREE_OPERAND (t, 0)),
         RECUR (TREE_OPERAND (t, 1)),
         RECUR (TREE_OPERAND (t, 2)),
+        RECUR (TREE_OPERAND (t, 3)),
         NEW_EXPR_USE_GLOBAL (t));
 
     case DELETE_EXPR:
@@ -11198,7 +11160,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
       /* Set up context.  */
       import_export_decl (d);
-      start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
+      start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
 
       /* Create substitution entries for the parameters.  */
       subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d));
index 9e4b884c3b3b08942e1659cb1df51097db9e7a25..0d4f4a75a97df73fda5f98f42c4a31228d182120 100644 (file)
@@ -1900,23 +1900,6 @@ finish_fname (tree id)
   return decl;
 }
 
-/* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
-   and DECLARATOR.  Returns nonzero if the function-declaration is
-   valid.  */
-
-int
-begin_function_definition (tree decl_specs, tree attributes, tree declarator)
-{
-  if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))
-    return 0;
-
-  /* The things we're about to see are not directly qualified by any
-     template headers we've seen thus far.  */
-  reset_specialization ();
-
-  return 1;
-}
-
 /* Finish a translation unit.  */
 
 void 
@@ -1998,24 +1981,6 @@ check_template_template_default_arg (tree argument)
   return argument;
 }
 
-/* Finish a parameter list, indicated by PARMS.  If ELLIPSIS is
-   nonzero, the parameter list was terminated by a `...'.  */
-
-tree
-finish_parmlist (tree parms, int ellipsis)
-{
-  if (parms)
-    {
-      /* We mark the PARMS as a parmlist so that declarator processing can
-         disambiguate certain constructs.  */
-      TREE_PARMLIST (parms) = 1;
-      /* We do not append void_list_node here, but leave it to grokparms
-         to do that.  */
-      PARMLIST_ELLIPSIS_P (parms) = ellipsis;
-    }
-  return parms;
-}
-
 /* Begin a class definition, as indicated by T.  */
 
 tree