This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gccgo] More recursive type patches
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Wed, 08 Sep 2010 11:11:41 -0700
- Subject: [gccgo] More recursive type patches
Here are some more patches for recursive types in gccgo. For a
recursive pointer or function type, the recursion just uses
ptr_type_node. This patch checks for that when doing a pointer
indirection or function call, and insert a cast as needed so that
GENERIC/GIMPLE see the right type. This patch also makes sure that we
do not record the recursively found ptr_type_node when handling a
forwarding type. Committed to gccgo branch.
Ian
diff -r 0442a71e2d75 go/expressions.cc
--- a/go/expressions.cc Tue Sep 07 17:12:33 2010 -0700
+++ b/go/expressions.cc Wed Sep 08 11:08:53 2010 -0700
@@ -4002,6 +4002,15 @@
expr);
}
+ // If the type of EXPR is a recursive pointer type, then we
+ // need to insert a cast before indirecting.
+ if (TREE_TYPE(TREE_TYPE(expr)) == ptr_type_node)
+ {
+ Type* pt = this->expr_->type()->points_to();
+ tree ind = pt->get_tree(context->gogo());
+ expr = fold_convert_loc(loc, build_pointer_type(ind), expr);
+ }
+
return build_fold_indirect_ref_loc(loc, expr);
}
@@ -8382,6 +8391,16 @@
CALL_EXPR_STATIC_CHAIN(ret) = closure_tree;
}
+ // If this is a recursive function type which returns itself, as in
+ // type F func() F
+ // we have used ptr_type_node for the return type. Add a cast here
+ // to the correct type.
+ if (TREE_TYPE(ret) == ptr_type_node)
+ {
+ tree t = this->type()->get_tree(gogo);
+ ret = fold_convert_loc(location, t, ret);
+ }
+
if (excess_type != NULL_TREE)
{
// Calling convert here can undo our excess precision change.
diff -r 0442a71e2d75 go/types.cc
--- a/go/types.cc Tue Sep 07 17:12:33 2010 -0700
+++ b/go/types.cc Wed Sep 08 11:08:53 2010 -0700
@@ -781,9 +781,19 @@
{
if (this->tree_ == NULL)
{
- this->tree_ = this->do_get_tree(gogo);
- go_preserve_from_gc(this->tree_);
- }
+ tree t = this->do_get_tree(gogo);
+
+ // For a recursive function or pointer type, we will temporarily
+ // return ptr_type_node during the recursion. We don't want to
+ // record that for a forwarding type, as it may confuse us
+ // later.
+ if (t == ptr_type_node && this->forward_declaration_type() != NULL)
+ return t;
+
+ this->tree_ = t;
+ go_preserve_from_gc(t);
+ }
+
return this->tree_;
}