From ce4a03916c76227660f5d388bd93c221185cfd24 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 11 May 1998 00:07:25 +0000 Subject: [PATCH] cp-tree.h (finish_unary_op_expr): New function. * cp-tree.h (finish_unary_op_expr): New function. (finish_id_expr): Likewise. (begin_new_placement): Likewise. (finish_new_placement): Likewise. (finish_declarator): Likewise. (finish_translation_unit): Likewise. (finish_parmlist): Likewise. (begin_class_definition): Likewise. (finish_class_definition): Likewise. (finish_default_args): Likewise. (finish_inline_definitions): Likewise. * parse.y (GCC_ASM_KEYWORD): Remove. (TYPENAME_ELLIPSIS): Likewise. * parse.c: Regenerated. Use new functions in semantics.c in the actions for many rules. * gxx.gperf (GCC_ASM_KEYWORD): Just use ASM_KEYWORD. * hash.h: Regenerated. * semantics.c (finish_expr_stmt): Allow NULL expr. (finish_unary_op_expr): New function, containing code previously in parse.y. (finish_id_expr): Likewise. (begin_new_placement): Likewise. (finish_new_placement): Likewise. (finish_declarator): Likewise. (finish_translation_unit): Likewise. (finish_parmlist): Likewise. (begin_class_definition): Likewise. (finish_class_definition): Likewise. (finish_default_args): Likewise. (finish_inline_definitions): Likewise. From-SVN: r19660 --- gcc/cp/ChangeLog | 33 +++ gcc/cp/cp-tree.h | 11 + gcc/cp/gxx.gperf | 4 +- gcc/cp/hash.h | 7 +- gcc/cp/parse.y | 227 +++------------- gcc/cp/semantics.c | 286 ++++++++++++++++++++- gcc/testsuite/g++.old-deja/g++.other/new.C | 57 ++++ 7 files changed, 417 insertions(+), 208 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/new.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 315feea3bd5d..95fa40af7a9c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,36 @@ +Mon May 11 00:03:34 1998 Mark Mitchell + + * cp-tree.h (finish_unary_op_expr): New function. + (finish_id_expr): Likewise. + (begin_new_placement): Likewise. + (finish_new_placement): Likewise. + (finish_declarator): Likewise. + (finish_translation_unit): Likewise. + (finish_parmlist): Likewise. + (begin_class_definition): Likewise. + (finish_class_definition): Likewise. + (finish_default_args): Likewise. + (finish_inline_definitions): Likewise. + * parse.y (GCC_ASM_KEYWORD): Remove. + (TYPENAME_ELLIPSIS): Likewise. + * parse.c: Regenerated. + Use new functions in semantics.c in the actions for many rules. + * gxx.gperf (GCC_ASM_KEYWORD): Just use ASM_KEYWORD. + * hash.h: Regenerated. + * semantics.c (finish_expr_stmt): Allow NULL expr. + (finish_unary_op_expr): New function, containing + code previously in parse.y. + (finish_id_expr): Likewise. + (begin_new_placement): Likewise. + (finish_new_placement): Likewise. + (finish_declarator): Likewise. + (finish_translation_unit): Likewise. + (finish_parmlist): Likewise. + (begin_class_definition): Likewise. + (finish_class_definition): Likewise. + (finish_default_args): Likewise. + (finish_inline_definitions): Likewise. + Sun May 10 23:43:13 1998 Mark Mitchell * typeck.c (build_c_cast): Don't decay arrays and functions to diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 662ba152f969..f044553d9ff3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2634,10 +2634,21 @@ extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree)); extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree)); extern tree finish_globally_qualified_member_call_expr PROTO ((tree, tree)); extern tree finish_label_address_expr PROTO((tree)); +extern tree finish_unary_op_expr PROTO((enum tree_code, tree)); +extern tree finish_id_expr PROTO((tree)); +extern int begin_new_placement PROTO((void)); +extern tree finish_new_placement PROTO((tree, int)); extern int begin_function_definition PROTO((tree, tree)); extern tree begin_constructor_declarator PROTO((tree, tree)); +extern tree finish_declarator PROTO((tree, tree, tree, tree, int)); +extern void finish_translation_unit PROTO((void)); extern tree finish_template_type_parm PROTO((tree, tree)); extern tree finish_template_template_parm PROTO((tree, tree)); +extern tree finish_parmlist PROTO((tree, int)); +extern tree begin_class_definition PROTO((tree)); +extern tree finish_class_definition PROTO((tree, tree, tree, int)); +extern void finish_default_args PROTO((void)); +extern void begin_inline_definitions PROTO((void)); /* in sig.c */ extern tree build_signature_pointer_type PROTO((tree, int, int)); diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf index d9cad4a6255b..71538567c135 100644 --- a/gcc/cp/gxx.gperf +++ b/gcc/cp/gxx.gperf @@ -5,8 +5,8 @@ struct resword { char *name; short token; enum rid rid;}; %% __alignof, ALIGNOF, NORID __alignof__, ALIGNOF, NORID -__asm, GCC_ASM_KEYWORD, NORID -__asm__, GCC_ASM_KEYWORD, NORID +__asm, ASM_KEYWORD, NORID +__asm__, ASM_KEYWORD, NORID __attribute, ATTRIBUTE, NORID __attribute__, ATTRIBUTE, NORID __complex, TYPESPEC, RID_COMPLEX diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h index 720890fd4c88..1e31a354724a 100644 --- a/gcc/cp/hash.h +++ b/gcc/cp/hash.h @@ -1,5 +1,6 @@ /* C code produced by gperf version 2.5 (GNU C++ version) */ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gxx.gperf */ +/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../gcc/cp/gxx.gperf */ +/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ struct resword { char *name; short token; enum rid rid;}; #define TOTAL_KEYWORDS 103 @@ -72,7 +73,7 @@ is_reserved_word (str, len) {"",}, {"true", CXX_TRUE, NORID,}, {"",}, - {"__asm__", GCC_ASM_KEYWORD, NORID}, + {"__asm__", ASM_KEYWORD, NORID}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"this", THIS, NORID,}, {"",}, @@ -104,7 +105,7 @@ is_reserved_word (str, len) {"short", TYPESPEC, RID_SHORT,}, {"__imag__", IMAGPART, NORID}, {"delete", DELETE, NORID,}, - {"__asm", GCC_ASM_KEYWORD, NORID}, + {"__asm", ASM_KEYWORD, NORID}, {"xor", '^', NORID,}, {"not_eq", EQCOMPARE, NORID,}, {"xor_eq", ASSIGN, NORID,}, diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 074f640f0ee4..d9df9b8919fe 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -129,7 +129,7 @@ empty_parms () /* the reserved words */ /* SCO include files test "ASM", so use something else. */ %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT -%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF +%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF %token SIGOF %token ATTRIBUTE EXTENSION LABEL %token REALPART IMAGPART @@ -228,7 +228,7 @@ empty_parms () %type structsp typespecqual_reserved parm named_parm full_parm /* C++ extensions */ -%token TYPENAME_ELLIPSIS PTYPENAME +%token PTYPENAME %token PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL %token PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER %type component_constructor_declarator @@ -328,15 +328,7 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl) program: /* empty */ | extdefs - { - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! toplevel_bindings_p ()) - poplevel (0, 0, 0); - while (current_namespace != global_namespace) - pop_namespace (); - finish_file (); - } + { finish_translation_unit (); } ; /* the reason for the strange actions in this rule @@ -373,7 +365,6 @@ extension: asm_keyword: ASM_KEYWORD - | GCC_ASM_KEYWORD ; lang_extdef: @@ -1010,11 +1001,7 @@ unary_expr: | '~' cast_expr { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } | unop cast_expr %prec UNARY - { $$ = build_x_unary_op ($1, $2); - if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST) - TREE_NEGATED_INT ($$) = 1; - overflow_warning ($$); - } + { $$ = finish_unary_op_expr ($1, $2); } /* Refer to the address of a label as a pointer. */ | ANDAND identifier { if (pedantic) @@ -1075,13 +1062,15 @@ unary_expr: ; new_placement: - '(' nonnull_exprlist ')' - { $$ = $2; } - | '{' nonnull_exprlist '}' - { - $$ = $2; - pedwarn ("old style placement syntax, use () instead"); - } + '(' + { $$ = begin_new_placement (); } + nonnull_exprlist ')' + { $$ = finish_new_placement ($3, $1); } + | '{' + { cp_pedwarn ("old style placement syntax, use () instead"); + $$ = begin_new_placement (); } + nonnull_exprlist '}' + { $$ = finish_new_placement ($3, $1); } ; new_initializer: @@ -1112,13 +1101,11 @@ new_initializer: /* This is necessary to postpone reduction of `int ((int)(int)(int))'. */ regcast_or_absdcl: '(' type_id ')' %prec EMPTY - { $2.t = tree_cons (NULL_TREE, $2.t, void_list_node); - TREE_PARMLIST ($2.t) = 1; + { $2.t = finish_parmlist (build_tree_list (NULL_TREE, $2.t), 0); $$ = make_call_declarator (NULL_TREE, $2.t, NULL_TREE, NULL_TREE); check_for_new_type ("cast", $2); } | regcast_or_absdcl '(' type_id ')' %prec EMPTY - { $3.t = tree_cons (NULL_TREE, $3.t, void_list_node); - TREE_PARMLIST ($3.t) = 1; + { $3.t = finish_parmlist (build_tree_list (NULL_TREE, $3.t), 0); $$ = make_call_declarator ($$, $3.t, NULL_TREE, NULL_TREE); check_for_new_type ("cast", $3); } ; @@ -1272,10 +1259,10 @@ direct_notype_declarator: primary: notype_unqualified_id { - if (TREE_CODE ($$) == BIT_NOT_EXPR) - $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0)); - else if (TREE_CODE ($$) != TEMPLATE_ID_EXPR) - $$ = do_identifier ($$, 1); + if (TREE_CODE ($1) == BIT_NOT_EXPR) + $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($1, 0)); + else + $$ = finish_id_expr ($1); } | CONSTANT | boolean.literal @@ -2005,54 +1992,21 @@ structsp: /* C++ extensions, merged with C to avoid shift/reduce conflicts */ | class_head left_curly opt.component_decl_list '}' maybe_attribute - { + { int semi; - $$ = $1; -#if 0 - /* Need to rework class nesting in the - presence of nested classes, etc. */ - shadow_tag (CLASSTYPE_AS_LIST ($1)); */ -#endif if (yychar == YYEMPTY) yychar = YYLEX; semi = yychar == ';'; - /* finish_struct nukes this anyway; if - finish_exception does too, then it can go. */ - if (semi) - note_got_semicolon ($1); - - if (TREE_CODE ($1) == ENUMERAL_TYPE) - ; - else - { - $$ = finish_struct ($1, $3, $5, semi); - if (semi) note_got_semicolon ($$); - } - - pop_obstacks (); - if (! semi) - check_for_missing_semicolon ($1); - if (current_scope () == current_function_decl) - do_pending_defargs (); + $$ = finish_class_definition ($1, $3, $5, semi); } pending_defargs - { - if (pending_inlines - && current_scope () == current_function_decl) - do_pending_inlines (); - } + { finish_default_args (); } pending_inlines - { - $$.t = $6; + { $$.t = $6; $$.new_type_flag = 1; - if (current_class_type == NULL_TREE) - clear_inline_text_obstack (); - - /* Undo the begin_tree in left_curly. */ - end_tree (); - } + begin_inline_definitions (); } | class_head %prec EMPTY { $$.new_type_flag = 0; @@ -2334,92 +2288,7 @@ base_class_access_list: left_curly: '{' - { tree t = $0; - push_obstacks_nochange (); - end_temporary_allocation (); - - if (t == error_mark_node - || ! IS_AGGR_TYPE (t)) - { - t = $0 = make_lang_type (RECORD_TYPE); - pushtag (make_anon_name (), t, 0); - } - if (TYPE_SIZE (t)) - duplicate_tag_error (t); - if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t)) - { - t = make_lang_type (TREE_CODE (t)); - pushtag (TYPE_IDENTIFIER ($0), t, 0); - $0 = t; - } - if (processing_template_decl && TYPE_CONTEXT (t) - && TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL - && ! current_class_type) - push_template_decl (TYPE_STUB_DECL (t)); - pushclass (t, 0); - TYPE_BEING_DEFINED (t) = 1; - if (IS_AGGR_TYPE (t) && CLASSTYPE_USE_TEMPLATE (t)) - { - if (CLASSTYPE_IMPLICIT_INSTANTIATION (t) - && TYPE_SIZE (t) == NULL_TREE) - { - SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t); - if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL (t)); - } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t)) - cp_error ("specialization after instantiation of `%T'", t); - } - /* Reset the interface data, at the earliest possible - moment, as it might have been set via a class foo; - before. */ - /* Don't change signatures. */ - if (! IS_SIGNATURE (t)) - { - extern tree pending_vtables; - int needs_writing; - tree name = TYPE_IDENTIFIER (t); - - if (! ANON_AGGRNAME_P (name)) - { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X - (t, interface_unknown); - } - - /* Record how to set the access of this class's - virtual functions. If write_virtuals == 2 or 3, then - inline virtuals are ``extern inline''. */ - switch (write_virtuals) - { - case 0: - case 1: - needs_writing = 1; - break; - case 2: - needs_writing = !! value_member (name, pending_vtables); - break; - case 3: - needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t) - && CLASSTYPE_INTERFACE_KNOWN (t); - break; - default: - needs_writing = 0; - } - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing; - } -#if 0 - t = TYPE_IDENTIFIER ($0); - if (t && IDENTIFIER_TEMPLATE (t)) - overload_template_name (t, 1); -#endif - reset_specialization(); - - /* In case this is a local class within a template - function, we save the current tree structure so - that we can get it back later. */ - begin_tree (); - } + { $0 = begin_class_definition ($0); } ; self_reference: @@ -3497,8 +3366,7 @@ parmlist: } | complex_parmlist | type_id - { $$ = tree_cons (NULL_TREE, $1.t, void_list_node); - TREE_PARMLIST ($$) = 1; + { $$ = finish_parmlist (build_tree_list (NULL_TREE, $1.t), 0); check_for_new_type ("inside parameter list", $1); } ; @@ -3506,49 +3374,24 @@ parmlist: as it is ambiguous and must be disambiguated elsewhere. */ complex_parmlist: parms - { - $$ = chainon ($$, void_list_node); - TREE_PARMLIST ($$) = 1; - } + { $$ = finish_parmlist ($$, 0); } | parms_comma ELLIPSIS - { - TREE_PARMLIST ($$) = 1; - } + { $$ = finish_parmlist ($1, 1); } /* C++ allows an ellipsis without a separating ',' */ | parms ELLIPSIS - { - TREE_PARMLIST ($$) = 1; - } + { $$ = finish_parmlist ($1, 1); } | type_id ELLIPSIS - { - $$ = build_tree_list (NULL_TREE, $1.t); - TREE_PARMLIST ($$) = 1; - } + { $$ = finish_parmlist (build_tree_list (NULL_TREE, + $1.t), 1); } | ELLIPSIS - { - $$ = NULL_TREE; - } - | TYPENAME_ELLIPSIS - { - TREE_PARMLIST ($$) = 1; - } - | parms TYPENAME_ELLIPSIS - { - TREE_PARMLIST ($$) = 1; - } - | type_id TYPENAME_ELLIPSIS - { - $$ = build_tree_list (NULL_TREE, $1.t); - TREE_PARMLIST ($$) = 1; - } + { $$ = finish_parmlist (NULL_TREE, 1); } | parms ':' { /* This helps us recover from really nasty parse errors, for example, a missing right parenthesis. */ yyerror ("possibly missing ')'"); - $$ = chainon ($$, void_list_node); - TREE_PARMLIST ($$) = 1; + $$ = finish_parmlist ($1, 0); yyungetc (':', 0); yychar = ')'; } @@ -3558,8 +3401,8 @@ complex_parmlist: parse errors, for example, a missing right parenthesis. */ yyerror ("possibly missing ')'"); - $$ = tree_cons (NULL_TREE, $1.t, void_list_node); - TREE_PARMLIST ($$) = 1; + $$ = finish_parmlist (build_tree_list (NULL_TREE, + $1.t), 0); yyungetc (':', 0); yychar = ')'; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 5d526c017578..d58ba1db84b7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -66,19 +66,23 @@ void finish_expr_stmt (expr) tree expr; { - if (!processing_template_decl) + if (expr != NULL_TREE) { - emit_line_note (input_filename, lineno); - /* Do default conversion if safe and possibly important, - in case within ({...}). */ - if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE - && lvalue_p (expr)) - || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) - expr = default_conversion (expr); + if (!processing_template_decl) + { + emit_line_note (input_filename, lineno); + /* Do default conversion if safe and possibly important, + in case within ({...}). */ + if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE + && lvalue_p (expr)) + || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) + expr = default_conversion (expr); + } + + cplus_expand_expr_stmt (expr); + clear_momentary (); } - - cplus_expand_expr_stmt (expr); - clear_momentary (); + finish_stmt (); } @@ -993,6 +997,58 @@ finish_label_address_expr (label) return result; } +/* Finish an expression of the form CODE EXPR. */ + +tree +finish_unary_op_expr (code, expr) + enum tree_code code; + tree expr; +{ + tree result = build_x_unary_op (code, expr); + if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST) + TREE_NEGATED_INT (result) = 1; + overflow_warning (result); + return result; +} + +/* Finish an id-expression. */ + +tree +finish_id_expr (expr) + tree expr; +{ + if (TREE_CODE (expr) == IDENTIFIER_NODE) + expr = do_identifier (expr, 1); + + return expr; +} + +/* Begin a new-placement. */ + +int +begin_new_placement () +{ + /* The arguments to a placement new might be passed to a + deallocation function, in the event that the allocation throws an + exception. Since we don't expand exception handlers until the + end of a function, we must make sure the arguments stay around + that long. */ + return suspend_momentary (); +} + +/* Finish a new-placement. The ARGS are the placement arguments. The + COOKIE is the value returned by the previous call to + begin_new_placement. */ + +tree +finish_new_placement (args, cookie) + tree args; + int cookie; +{ + resume_momentary (cookie); + return args; +} + /* Begin a function defniition declared with DECL_SPECS and DECLARATOR. Returns non-zero if the function-declaration is legal. */ @@ -1031,6 +1087,35 @@ begin_constructor_declarator (scope, name) return result; } +/* Finish an init-declarator. Returns a DECL. */ + +tree +finish_declarator (declarator, declspecs, attributes, + prefix_attributes, initialized) + tree declarator; + tree declspecs; + tree attributes; + tree prefix_attributes; + int initialized; +{ + return start_decl (declarator, declspecs, initialized, attributes, + prefix_attributes); +} + +/* Finish a transltation unit. */ + +void +finish_translation_unit () +{ + /* In case there were missing closebraces, + get us back to the global binding level. */ + while (! toplevel_bindings_p ()) + poplevel (0, 0, 0); + while (current_namespace != global_namespace) + pop_namespace (); + finish_file (); +} + /* Finish a template type parameter, specified as AGGR IDENTIFIER. Returns the parameter. */ @@ -1067,3 +1152,182 @@ finish_template_template_parm (aggr, identifier) return finish_template_type_parm (aggr, tmpl); } + +/* Finish a parameter list, indicated by PARMS. If ELLIPSIS is + non-zero, the parameter list was terminated by a `...'. */ + +tree +finish_parmlist (parms, ellipsis) + tree parms; + int ellipsis; +{ + if (!ellipsis) + chainon (parms, void_list_node); + /* We mark the PARMS as a parmlist so that declarator processing can + disambiguate certain constructs. */ + if (parms != NULL_TREE) + TREE_PARMLIST (parms) = 1; + + return parms; +} + +/* Begin a class definition, as indicated by T. */ + +tree +begin_class_definition (t) + tree t; +{ + tree new_type = t; + + push_obstacks_nochange (); + end_temporary_allocation (); + + if (t == error_mark_node + || ! IS_AGGR_TYPE (t)) + { + t = new_type = make_lang_type (RECORD_TYPE); + pushtag (make_anon_name (), t, 0); + } + if (TYPE_SIZE (t)) + duplicate_tag_error (t); + if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t)) + { + t = make_lang_type (TREE_CODE (t)); + pushtag (TYPE_IDENTIFIER (t), t, 0); + new_type = t; + } + if (processing_template_decl && TYPE_CONTEXT (t) + && TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL + && ! current_class_type) + push_template_decl (TYPE_STUB_DECL (t)); + pushclass (t, 0); + TYPE_BEING_DEFINED (t) = 1; + if (IS_AGGR_TYPE (t) && CLASSTYPE_USE_TEMPLATE (t)) + { + if (CLASSTYPE_IMPLICIT_INSTANTIATION (t) + && TYPE_SIZE (t) == NULL_TREE) + { + SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t); + if (processing_template_decl) + push_template_decl (TYPE_MAIN_DECL (t)); + } + else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t)) + cp_error ("specialization after instantiation of `%T'", t); + } + /* Reset the interface data, at the earliest possible + moment, as it might have been set via a class foo; + before. */ + /* Don't change signatures. */ + if (! IS_SIGNATURE (t)) + { + extern tree pending_vtables; + int needs_writing; + tree name = TYPE_IDENTIFIER (t); + + if (! ANON_AGGRNAME_P (name)) + { + CLASSTYPE_INTERFACE_ONLY (t) = interface_only; + SET_CLASSTYPE_INTERFACE_UNKNOWN_X + (t, interface_unknown); + } + + /* Record how to set the access of this class's + virtual functions. If write_virtuals == 2 or 3, then + inline virtuals are ``extern inline''. */ + switch (write_virtuals) + { + case 0: + case 1: + needs_writing = 1; + break; + case 2: + needs_writing = !! value_member (name, pending_vtables); + break; + case 3: + needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t) + && CLASSTYPE_INTERFACE_KNOWN (t); + break; + default: + needs_writing = 0; + } + CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing; + } +#if 0 + t = TYPE_IDENTIFIER ($0); + if (t && IDENTIFIER_TEMPLATE (t)) + overload_template_name (t, 1); +#endif + reset_specialization(); + + /* In case this is a local class within a template + function, we save the current tree structure so + that we can get it back later. */ + begin_tree (); + + return new_type; +} + +/* Finish a class definition T, with the indicated COMPONENTS, and + with the indicate ATTRIBUTES. If SEMI, the definition is + immediately followed by a semicolon. Returns the type. */ + +tree +finish_class_definition (t, components, attributes, semi) + tree t; + tree components; + tree attributes; + int semi; +{ +#if 0 + /* Need to rework class nesting in the presence of nested classes, + etc. */ + shadow_tag (CLASSTYPE_AS_LIST (t)); */ +#endif + + /* finish_struct nukes this anyway; if finish_exception does too, + then it can go. */ + if (semi) + note_got_semicolon (t); + + if (TREE_CODE (t) == ENUMERAL_TYPE) + ; + else + { + t = finish_struct (t, components, attributes, semi); + if (semi) + note_got_semicolon (t); + } + + pop_obstacks (); + + if (! semi) + check_for_missing_semicolon (t); + if (current_scope () == current_function_decl) + do_pending_defargs (); + + return t; +} + +/* Finish processing the default argument expressions cached during + the processing of a class definition. */ + +void +finish_default_args () +{ + if (pending_inlines + && current_scope () == current_function_decl) + do_pending_inlines (); +} + +/* Finish processing the inline function definitions cached during the + processing of a class definition. */ + +void +begin_inline_definitions () +{ + if (current_class_type == NULL_TREE) + clear_inline_text_obstack (); + + /* Undo the begin_tree in begin_class_definition. */ + end_tree (); +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/new.C b/gcc/testsuite/g++.old-deja/g++.other/new.C new file mode 100644 index 000000000000..829db70e868e --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/new.C @@ -0,0 +1,57 @@ +// Build don't link: + +typedef unsigned int size_t; +inline void * +operator new(size_t alloc_sz, const char *fname, unsigned lineno) +{ +} +inline void * +operator new[](size_t alloc_sz, const char *fname, unsigned lineno) +{ +} +inline void +operator delete(void *ptr, const char *fname, unsigned lineno) +{ +} +inline void +operator delete[](void *ptr, const char *fname, unsigned lineno) +{ +} + +class DEF { +public: + DEF( DEF *parent=0, const char *name=0 ); +}; + +class ABC +{ +public: + enum stuff { ID0, ID1 }; + ABC( stuff, DEF *parent=0, const char *name=0 ); +}; + +class GHI : public DEF +{ +}; + +class LMNFrame; +class LMN : public DEF +{ + friend class LMNFrame; + public: +public: + LMN(); +private: + LMNFrame *draw_area; + + ABC *scroll_h; +}; +class LMNFrame : public GHI { +}; +LMN::LMN() +{ + draw_area = new ("abc", 69) LMNFrame; + + scroll_h = new ("def", 71) ABC(ABC::ID0, this); +} + -- 2.39.5