[gcjx] Patch: FYI: add intersection type

Tom Tromey tromey@redhat.com
Tue Oct 25 00:43:00 GMT 2005


I'm checking this in on the gcjx branch.

This adds a new intersection type, which is used by type inference.
It will also be used by capture conversion.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* Makefile.in: Rebuilt.
	* Makefile.am (headers): Added intersect.hh.
	(model_sources): Added intersect.cc.
	* unify.cc (compute_glb): Make a new model_intersection_type.
	* typedefs.hh: Include intersect.hh.
	* model/intersect.cc: New file.
	* model/intersect.hh: New file.

Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/Makefile.am,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 Makefile.am
--- Makefile.am 18 Oct 2005 22:16:55 -0000 1.1.2.8
+++ Makefile.am 25 Oct 2005 00:03:48 -0000
@@ -60,12 +60,12 @@
 model/iannotatable.hh model/icatcher.hh model/icontext.hh \
 model/identifier.hh model/ideprecatable.hh model/if.hh model/ilabel.hh \
 model/imember.hh model/imodifiable.hh model/import.hh model/iname.hh \
-model/init.hh model/instanceof.hh model/invoke.hh model/iscope.hh \
-model/javadoc.hh model/label.hh model/literal.hh model/loop.hh \
-model/memberref.hh model/method.hh model/modifier.hh model/newarray.hh \
-model/new.hh model/null.hh model/package.hh model/parameters.hh	\
-model/primitive.hh model/return.hh model/stmt.hh model/switch.hh \
-model/synchronized.hh model/this.hh model/throw.hh \
+model/init.hh model/instanceof.hh model/intersect.hh model/invoke.hh \
+model/iscope.hh model/javadoc.hh model/label.hh model/literal.hh \
+model/loop.hh model/memberref.hh model/method.hh model/modifier.hh \
+model/newarray.hh model/new.hh model/null.hh model/package.hh \
+model/parameters.hh model/primitive.hh model/return.hh model/stmt.hh \
+model/switch.hh model/synchronized.hh model/this.hh model/throw.hh \
 model/throwsclause.hh model/try.hh model/type.hh model/typemap.hh \
 model/typevar.hh model/unary.hh model/unit.hh model/value.hh \
 model/variable.hh model/varref.hh model/varstmt.hh model/void.hh \
@@ -81,26 +81,27 @@
 defassign.cc directory.cc dump.cc factory.cc fold.cc init.cc \
 location.cc name.cc owner.cc scope.cc unify.cc util.cc warnings.cc
 
-model_sources = model/annotation.cc model/annomember.cc model/annotype.cc \
-model/annovalue.cc model/arrayinit.cc model/arrayref.cc \
-model/arraytype.cc model/assert.cc model/assign.cc model/binary.cc \
-model/block.cc model/blockscope.cc model/break.cc model/bytecode.cc \
-model/cast.cc model/catch.cc model/class.cc model/classinst.cc \
-model/classref.cc model/cond.cc model/constructor.cc model/continue.cc \
-model/declstmt.cc model/do.cc model/empty.cc model/enum.cc \
-model/enumconst.cc model/expr.cc model/exprstmt.cc model/field.cc \
-model/fieldinit.cc model/fieldref.cc model/for.cc model/forenhanced.cc \
-model/fwdtype.cc model/iannotatable.cc model/identifier.cc model/if.cc \
-model/import.cc model/imodifiable.cc model/init.cc model/instanceof.cc \
-model/invoke.cc model/javadoc.cc model/label.cc model/literal.cc \
-model/memberref.cc model/method.cc model/modifier.cc model/newarray.cc \
-model/new.cc model/null.cc model/package.cc model/parameters.cc \
-model/primitive.cc model/return.cc model/stmt.cc model/switch.cc \
-model/synchronized.cc model/this.cc model/throw.cc model/throwsclause.cc \
-model/try.cc model/type.cc model/typemap.cc model/typevar.cc \
-model/unary.cc model/unit.cc model/value.cc model/variable.cc \
-model/varref.cc model/varstmt.cc model/void.cc model/while.cc \
-model/wildcard.cc
+model_sources = model/annotation.cc model/annomember.cc	\
+model/annotype.cc model/annovalue.cc model/arrayinit.cc	\
+model/arrayref.cc model/arraytype.cc model/assert.cc model/assign.cc \
+model/binary.cc model/block.cc model/blockscope.cc model/break.cc \
+model/bytecode.cc model/cast.cc model/catch.cc model/class.cc \
+model/classinst.cc model/classref.cc model/cond.cc \
+model/constructor.cc model/continue.cc model/declstmt.cc model/do.cc \
+model/empty.cc model/enum.cc model/enumconst.cc model/expr.cc \
+model/exprstmt.cc model/field.cc model/fieldinit.cc model/fieldref.cc \
+model/for.cc model/forenhanced.cc model/fwdtype.cc \
+model/iannotatable.cc model/identifier.cc model/if.cc model/import.cc \
+model/imodifiable.cc model/init.cc model/instanceof.cc \
+model/intersect.cc model/invoke.cc model/javadoc.cc model/label.cc \
+model/literal.cc model/memberref.cc model/method.cc model/modifier.cc \
+model/newarray.cc model/new.cc model/null.cc model/package.cc \
+model/parameters.cc model/primitive.cc model/return.cc model/stmt.cc \
+model/switch.cc model/synchronized.cc model/this.cc model/throw.cc \
+model/throwsclause.cc model/try.cc model/type.cc model/typemap.cc \
+model/typevar.cc model/unary.cc model/unit.cc model/value.cc \
+model/variable.cc model/varref.cc model/varstmt.cc model/void.cc \
+model/while.cc model/wildcard.cc
 
 bytecode_sources = bytecode/attribute.cc bytecode/block.cc \
 bytecode/bytegen.cc bytecode/classreader.cc bytecode/classwriter.cc \
Index: typedefs.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/typedefs.hh,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 typedefs.hh
--- typedefs.hh 3 Oct 2005 17:38:09 -0000 1.1.2.3
+++ typedefs.hh 25 Oct 2005 00:03:51 -0000
@@ -290,6 +290,7 @@
 
 #include "model/typevar.hh"
 #include "model/classinst.hh"
+#include "model/intersect.hh"
 
 #include "model/annotype.hh"
 typedef owner<model_annotation_type> ref_annotation_type;
Index: unify.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/unify.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 unify.cc
--- unify.cc 21 Oct 2005 21:45:17 -0000 1.1.2.2
+++ unify.cc 25 Oct 2005 00:03:51 -0000
@@ -185,8 +185,10 @@
 
   model_class *compute_glb (model_class *left, model_class *right)
   {
-    // FIXME
-    return left;
+    std::list<model_class *> classes;
+    classes.push_back (left);
+    classes.push_back (right);
+    return new model_intersection_type (where, classes);
   }
 
   // Compute the least containing type argument for a pair of classes.
Index: model/intersect.cc
===================================================================
RCS file: model/intersect.cc
diff -N model/intersect.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/intersect.cc 25 Oct 2005 00:03:51 -0000
@@ -0,0 +1,89 @@
+// An intersection type.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// gcjx is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// gcjx is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with gcjx; see the file COPYING.LIB.  If
+// not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#include "typedefs.hh"
+
+model_intersection_type::model_intersection_type (const location &w,
+						  const std::list<model_class *> &classes)
+  : model_class (w)
+{
+  std::list<ref_forwarding_type> ifaces;
+  model_class *my_super = NULL;
+
+  for (std::list<model_class *>::const_iterator i = classes.begin ();
+       i != classes.end ();
+       ++i)
+    {
+      // FIXME: if K is itself a model_intersection_type, should we
+      // crack it open and look at its bounds?  This might be
+      // convenient for type inference.
+      model_class *k = *i;
+      if (k->interface_p ())
+	ifaces.push_back (new model_forwarding_resolved (w, k));
+      else if (my_super == NULL || k->assignable_from_p (my_super))
+	my_super = k;
+      else if (! my_super->assignable_from_p (k))
+	{
+	  // FIXME: do we want an error here?  Consider type
+	  // inference... might we not prefer to just silently reject
+	  // the particular inference?
+	  std::cerr << error ("intersection type with incompatible "
+			      "bounds %1 and %2")
+	    % my_super % k;
+	}
+    }
+  if (my_super)
+    set_superclass (new model_forwarding_resolved (w, my_super));
+}
+
+model_type *
+model_intersection_type::erasure ()
+{
+  // FIXME: not sure this is correct.
+  if (superclass)
+    return superclass->type ()->erasure ();
+  if (! interfaces.empty ())
+    return interfaces.front ()->type ()->erasure ();
+  return global->get_compiler ()->java_lang_Object ();
+}
+
+bool
+model_intersection_type::assignable_from_p (model_type *other)
+{
+  if (other == null_type)
+    return true;
+  if (! other->reference_p ())
+    return false;
+  // The type must satisfy all our bounds.
+  if (superclass && ! superclass->type ()->assignable_from_p (other))
+    return false;
+  for (std::list<ref_forwarding_type>::const_iterator i = interfaces.begin ();
+       i != interfaces.end ();
+       ++i)
+    {
+      if (! (*i)->type ()->assignable_from_p (other))
+	return false;
+    }
+  // Any reference type that got to this point is ok.  If we don't
+  // have any bounds, then our erasure is Object, and the assignment
+  // is fine.
+  return true;
+}
Index: model/intersect.hh
===================================================================
RCS file: model/intersect.hh
diff -N model/intersect.hh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/intersect.hh 25 Oct 2005 00:03:51 -0000
@@ -0,0 +1,48 @@
+// An intersection type.
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// gcjx is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// gcjx is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with gcjx; see the file COPYING.LIB.  If
+// not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef GCJX_MODEL_INTERSECT_HH
+#define GCJX_MODEL_INTERSECT_HH
+
+/// This represents an intersection type.  An intersection type cannot
+/// be created in user source code, but can be created by capture
+/// conversion or type inference.  Intersection types are
+/// characterized by a list of bounds.
+class model_intersection_type : public model_class
+{
+  void compute_descriptor ()
+  {
+    // We override this method to avoid crashes if our superclass'
+    // method is called.  There's no sensible value here however.    
+  }
+
+public:
+
+  model_intersection_type (const location &, const std::list<model_class *> &);
+
+  model_type *erasure ();
+
+  bool assignable_from_p (model_type *);
+
+  void visit (visitor *);
+};
+
+#endif // GCJX_MODEL_INTERSECT_HH



More information about the Java-patches mailing list