summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1997-05-19 18:01:45 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1997-05-19 18:01:45 +0000
commitdc9c6fd71a7b669dbab2159324cf3c79efd64ff8 (patch)
tree5456ebde32295223ef5435b92a3ed2b969b93ddf
parente5530d32ed3cd9e71674c4d3d070961649634a7e (diff)
downloadgcc-dc9c6fd71a7b669dbab2159324cf3c79efd64ff8.tar.gz
91th Cygnus<->FSF quick merge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14098 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog33
-rw-r--r--gcc/cp/cp-tree.def2
-rw-r--r--gcc/cp/decl.c37
-rw-r--r--gcc/cp/method.c7
-rw-r--r--gcc/cp/pt.c68
5 files changed, 109 insertions, 38 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e0d0e785053..79e655cebde 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,36 @@
+Sat May 17 10:48:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Oops.
+
+Fri May 16 14:23:57 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add TAG_DEFN.
+ * pt.c (tsubst_enum): New fn.
+ (instantiate_class_template): Use it.
+ (tsubst_expr): Support TAG_DEFN.
+ (tsubst): Support local enums.
+ (tsubst_copy): Likewise.
+ * decl.c (finish_enum): Likewise.
+ (start_enum): If this is a local enum, switch to permanent_obstack.
+
+Wed May 14 19:08:28 1997 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Set last_parm_cleanup_insn here.
+ (finish_function): Put the base init code for constructors just
+ after the parm cleanup insns.
+ (struct cp_function): Add last_parm_cleanup_insn.
+ (push_cp_function_context): Likewise.
+ (pop_cp_function_context): Likewise.
+
+Tue May 13 15:51:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_copy): Handle BIT_NOT_EXPR.
+
+Wed May 7 11:17:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * method.c (emit_thunk) [ASM_OUTPUT_MI_THUNK]: Build up the RTL
+ for THUNK_FNDECL before we switch to temporary allocation.
+
Mon May 5 14:46:53 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_new_op): Handle null arg2 for ?:.
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index be97b02ca95..39ccfae59d8 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -152,3 +152,5 @@ DEFTREECODE (REF_BIND, "ref_bind", "e", 1)
DEFTREECODE (USER_CONV, "user_conv", "e", 4)
DEFTREECODE (AMBIG_CONV, "ambig_conv", "e", 1)
DEFTREECODE (RVALUE_CONV, "rvalue_conv", "e", 1)
+
+DEFTREECODE (TAG_DEFN, "tag_defn", "e", 0)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6721d0b0021..0ed77d49cfa 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -268,6 +268,12 @@ tree dtor_label;
static rtx last_dtor_insn;
+/* In a constructor, the last insn emitted after the start of the
+ function and the parms, but before the start of the exception
+ specification. */
+
+static rtx last_parm_cleanup_insn;
+
/* In a constructor, the point at which we are ready to return
the pointer to the initialized object. */
@@ -10579,6 +10585,9 @@ start_enum (name)
register tree enumtype = NULL_TREE;
struct binding_level *b = inner_binding_level;
+ if (processing_template_decl && current_function_decl)
+ end_temporary_allocation ();
+
/* If this is the real definition for a previous forward reference,
fill in the contents in the same object that used to be the
forward reference. */
@@ -10657,7 +10666,14 @@ finish_enum (enumtype, values)
TYPE_VALUES (enumtype) = nreverse (values);
if (processing_template_decl)
- return enumtype;
+ {
+ if (current_function_decl)
+ {
+ add_tree (build_min (TAG_DEFN, enumtype));
+ resume_temporary_allocation ();
+ }
+ return enumtype;
+ }
{
int unsignedp = tree_int_cst_sgn (minnode) >= 0;
@@ -11417,6 +11433,8 @@ store_parm_decls ()
expand_start_bindings (0);
}
+ last_parm_cleanup_insn = get_last_insn ();
+
if (! processing_template_decl && flag_exceptions)
{
/* Do the starting of the exception specifications, if we have any. */
@@ -11819,19 +11837,9 @@ finish_function (lineno, call_poplevel, nested)
insns = get_insns ();
end_sequence ();
- /* This is where the body of the constructor begins.
- If there were no insns in this function body, then the
- last_parm_insn is also the last insn.
-
- If optimization is enabled, last_parm_insn may move, so
- we don't hold on to it (across emit_base_init). */
- last_parm_insn = get_first_nonparm_insn ();
- if (last_parm_insn == NULL_RTX)
- last_parm_insn = get_last_insn ();
- else
- last_parm_insn = previous_insn (last_parm_insn);
+ /* This is where the body of the constructor begins. */
- emit_insns_after (insns, last_parm_insn);
+ emit_insns_after (insns, last_parm_cleanup_insn);
end_protect_partials ();
@@ -12480,6 +12488,7 @@ struct cp_function
tree ctor_label;
tree dtor_label;
rtx last_dtor_insn;
+ rtx last_parm_cleanup_insn;
tree base_init_list;
tree member_init_list;
tree base_init_expr;
@@ -12518,6 +12527,7 @@ push_cp_function_context (context)
p->ctor_label = ctor_label;
p->dtor_label = dtor_label;
p->last_dtor_insn = last_dtor_insn;
+ p->last_parm_cleanup_insn = last_parm_cleanup_insn;
p->assigns_this = current_function_assigns_this;
p->just_assigned_this = current_function_just_assigned_this;
p->parms_stored = current_function_parms_stored;
@@ -12558,6 +12568,7 @@ pop_cp_function_context (context)
ctor_label = p->ctor_label;
dtor_label = p->dtor_label;
last_dtor_insn = p->last_dtor_insn;
+ last_parm_cleanup_insn = p->last_parm_cleanup_insn;
current_function_assigns_this = p->assigns_this;
current_function_just_assigned_this = p->just_assigned_this;
current_function_parms_stored = p->parms_stored;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 2588d44fca8..640b1bfa903 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1674,10 +1674,9 @@ make_thunk (function, delta)
int delta;
{
char buffer[250];
- tree thunk_fndecl, thunk_id;
+ tree thunk_id;
tree thunk;
char *func_name;
- static int thunk_number = 0;
tree func_decl;
if (TREE_CODE (function) != ADDR_EXPR)
abort ();
@@ -1739,10 +1738,12 @@ emit_thunk (thunk_fndecl)
#ifdef ASM_OUTPUT_MI_THUNK
char *fnname;
current_function_decl = thunk_fndecl;
+ /* Make sure we build up its RTL before we go onto the
+ temporary obstack. */
+ make_function_rtl (thunk_fndecl);
temporary_allocation ();
DECL_RESULT (thunk_fndecl)
= build_decl (RESULT_DECL, 0, integer_type_node);
- make_function_rtl (thunk_fndecl);
fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
assemble_start_function (thunk_fndecl, fnname);
ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 03d27adbb6e..823116ca18c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -72,6 +72,7 @@ static int comp_template_args PROTO((tree, tree));
tree most_specialized_class PROTO((tree, tree));
static tree get_class_bindings PROTO((tree, tree, tree));
tree make_temp_vec PROTO((int));
+static tree tsubst_enum PROTO((tree, tree *, int));
/* We've got a template header coming up; push to a new level for storing
the parms. */
@@ -1198,36 +1199,22 @@ instantiate_class_template (type)
{
tree name = TREE_PURPOSE (t);
tree tag = TREE_VALUE (t);
- tree newtag;
/* These will add themselves to CLASSTYPE_TAGS for the new type. */
if (TREE_CODE (tag) == ENUMERAL_TYPE)
- newtag = start_enum (name);
- else
- newtag = tsubst (tag, &TREE_VEC_ELT (args, 0),
- TREE_VEC_LENGTH (args), NULL_TREE);
-
- if (TREE_CODE (tag) == ENUMERAL_TYPE)
{
- tree e, values = NULL_TREE, *last = &values;
-
- for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
- {
- tree elt = build_enumerator
- (TREE_PURPOSE (e),
- tsubst_expr (TREE_VALUE (e), &TREE_VEC_ELT (args, 0),
- TREE_VEC_LENGTH (args), NULL_TREE));
- DECL_FIELD_CONTEXT (TREE_VALUE (elt)) = type;
- *last = elt;
- last = &TREE_CHAIN (elt);
- }
-
- finish_enum (newtag, values);
+ tree e, newtag = tsubst_enum (tag, &TREE_VEC_ELT (args, 0),
+ TREE_VEC_LENGTH (args));
+ for (e = TYPE_VALUES (newtag); e; e = TREE_CHAIN (e))
+ DECL_FIELD_CONTEXT (TREE_VALUE (e)) = type;
*field_chain = grok_enum_decls (newtag, NULL_TREE);
while (*field_chain)
field_chain = &TREE_CHAIN (*field_chain);
}
+ else
+ tsubst (tag, &TREE_VEC_ELT (args, 0),
+ TREE_VEC_LENGTH (args), NULL_TREE);
}
/* Don't replace enum constants here. */
@@ -1411,6 +1398,8 @@ tsubst (t, args, nargs, in_decl)
tree ctx = tsubst (TYPE_CONTEXT (t), args, nargs, in_decl);
if (ctx == NULL_TREE)
return t;
+ else if (ctx == current_function_decl)
+ return lookup_name (TYPE_IDENTIFIER (t), 1);
else
return lookup_nested_type_by_name (ctx, TYPE_IDENTIFIER (t));
}
@@ -2000,7 +1989,9 @@ tsubst_copy (t, args, nargs, in_decl)
if (DECL_CONTEXT (t))
{
tree ctx = tsubst (DECL_CONTEXT (t), args, nargs, in_decl);
- if (ctx != DECL_CONTEXT (t))
+ if (ctx == current_function_decl)
+ return lookup_name (DECL_NAME (t), 0);
+ else if (ctx != DECL_CONTEXT (t))
return lookup_field (ctx, DECL_NAME (t), 0, 0);
}
return t;
@@ -2033,6 +2024,7 @@ tsubst_copy (t, args, nargs, in_decl)
case POSTINCREMENT_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
case ADDR_EXPR:
case CONVERT_EXPR: /* Unary + */
case SIZEOF_EXPR:
@@ -2491,6 +2483,13 @@ tsubst_expr (t, args, nargs, in_decl)
do_poplevel ();
break;
+ case TAG_DEFN:
+ lineno = TREE_COMPLEXITY (t);
+ t = TREE_TYPE (t);
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ tsubst_enum (t, args, nargs);
+ break;
+
default:
return build_expr_from_tree (tsubst_copy (t, args, nargs, in_decl));
}
@@ -3578,3 +3577,28 @@ add_maybe_template (d, fns)
maybe_template_tail = &TREE_CHAIN (*maybe_template_tail);
DECL_MAYBE_TEMPLATE (d) = 1;
}
+
+/* Instantiate an enumerated type. Used by instantiate_class_template and
+ tsubst_expr. */
+
+static tree
+tsubst_enum (tag, args, nargs)
+ tree tag, *args;
+ int nargs;
+{
+ tree newtag = start_enum (TYPE_IDENTIFIER (tag));
+ tree e, values = NULL_TREE;
+
+ for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
+ {
+ tree elt = build_enumerator (TREE_PURPOSE (e),
+ tsubst_expr (TREE_VALUE (e), args,
+ nargs, NULL_TREE));
+ TREE_CHAIN (elt) = values;
+ values = elt;
+ }
+
+ finish_enum (newtag, values);
+
+ return newtag;
+}