diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f0e5c58e0ef6..0db3c9029cdf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 1999-08-26 Mark Mitchell + * decl.c (lookup_label): Build labels on the permanent obstack + when building statement trees. Don't build RTL for labels when + building statement trees. + * semantics.c (finish_goto_stmt): Use LABEL_DECLs even when + building statement trees. + (finish_label_stmt): Likewise. + (expand_stmt): Adjust accordingly. + * pt.c (tsubst_expr); Likewise. + (do_decl_instantiation): Robustify. + * cp-tree.h (AGGR_INIT_VIA_CTOR_P): New macro. * tree.c (build_cplus_new): Set it. * expr.c (cplus_expand_expr): Use it. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f25400a4af07..b04673c7cece 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4829,10 +4829,14 @@ lookup_label (id) return decl; } + if (building_stmt_tree ()) + push_permanent_obstack (); decl = build_decl (LABEL_DECL, id, void_type_node); - - /* Make sure every label has an rtx. */ - label_rtx (decl); + if (building_stmt_tree ()) + pop_obstacks (); + else + /* Make sure every label has an rtx. */ + label_rtx (decl); /* A label not explicitly declared must be local to where it's ref'd. */ DECL_CONTEXT (decl) = current_function_decl; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c8e1e60751ee..f5c72b076c89 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7401,11 +7401,13 @@ tsubst_expr (t, args, complain, in_decl) case GOTO_STMT: lineno = STMT_LINENO (t); t = GOTO_DESTINATION (t); - if (TREE_CODE (t) != IDENTIFIER_NODE) + if (TREE_CODE (t) != LABEL_DECL) /* Computed goto's must be tsubst'd into. On the other hand, non-computed gotos must not be; the identifier in question will have no binding. */ t = tsubst_expr (t, args, complain, in_decl); + else + t = DECL_NAME (t); finish_goto_stmt (t); break; @@ -9132,7 +9134,11 @@ do_decl_instantiation (declspecs, declarator, storage) tree result = NULL_TREE; int extern_p = 0; - if (! DECL_LANG_SPECIFIC (decl)) + if (!decl) + /* An error ocurred, for which grokdeclarator has already issued + an appropriate message. */ + return; + else if (! DECL_LANG_SPECIFIC (decl)) { cp_error ("explicit instantiation of non-template `%#D'", decl); return; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6adc5ae48a82..b9457c064a93 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -599,17 +599,19 @@ void finish_goto_stmt (destination) tree destination; { + if (TREE_CODE (destination) == IDENTIFIER_NODE) + destination = lookup_label (destination); + if (building_stmt_tree ()) add_tree (build_min_nt (GOTO_STMT, destination)); else { emit_line_note (input_filename, lineno); - if (TREE_CODE (destination) == IDENTIFIER_NODE) + if (TREE_CODE (destination) == LABEL_DECL) { - tree decl = lookup_label (destination); - TREE_USED (decl) = 1; - expand_goto (decl); + TREE_USED (destination) = 1; + expand_goto (destination); } else expand_computed_goto (destination); @@ -914,23 +916,12 @@ void finish_label_stmt (name) tree name; { - tree decl; + tree decl = define_label (input_filename, lineno, name); if (building_stmt_tree ()) - { - push_permanent_obstack (); - decl = build_decl (LABEL_DECL, name, void_type_node); - pop_obstacks (); - DECL_SOURCE_LINE (decl) = lineno; - DECL_SOURCE_FILE (decl) = input_filename; - add_tree (decl); - } - else - { - decl = define_label (input_filename, lineno, name); - if (decl) - expand_label (decl); - } + add_tree (decl); + else if (decl) + expand_label (decl); } /* Create a declaration statement for the declaration given by the @@ -2129,10 +2120,9 @@ expand_stmt (t) break; case LABEL_DECL: - t = define_label (DECL_SOURCE_FILE (t), DECL_SOURCE_LINE (t), - DECL_NAME (t)); - if (t) - expand_label (t); + input_filename = DECL_SOURCE_FILE (t); + lineno = DECL_SOURCE_LINE (t); + finish_label_stmt (DECL_NAME (t)); break; case GOTO_STMT: