This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gcjx] Patch: FYI: enum fixes


I'm checking this in on the gcjx branch.

This makes it simpler to find an enum constant given an expression
that (supposedly) refers to it.  This fix is needed for annotation
processing, we were incorrectly unwrapping enum constant references
there.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* model/new.hh (model_new_enum::enum_const): New field.
	(model_new_enum): Added argument.
	(model_new_enum::get_enum_constant): New method.
	* model/enum.cc (add_enum): Indentation fix.  Updated for change
	to model_new_enum.
	* model/switch.cc (resolve): Use unwrap_enum_constant.
	* conversions.cc (unwrap_enum_constant): New function.
	(annotation_commensurate_p): Use it.  Peel forwarding reference.
	* conversions.hh (unwrap_enum_constant): Declare.

Index: conversions.cc
===================================================================
--- conversions.cc	(revision 107604)
+++ conversions.cc	(working copy)
@@ -729,11 +729,42 @@
       if (type->primitive_p ()
 	  || type == global->get_compiler ()->java_lang_String ())
 	return expr->constant_p ();
+
+      // FIXME: this is anti-OO.
+      if (dynamic_cast<model_memberref_forward *> (expr))
+	{
+	  model_memberref_forward *mem
+	    = dynamic_cast<model_memberref_forward *> (expr);
+	  expr = mem->get_real ();
+	}
+
       if (type->erasure () == global->get_compiler ()->java_lang_Class ())
 	return dynamic_cast<model_class_ref *> (expr) != NULL;
       if (type->enum_p ())
-	return dynamic_cast<model_enum_constant *> (expr);
+	return unwrap_enum_constant (expr);
     }
 
   return false;
 }
+
+model_enum_constant *
+unwrap_enum_constant (model_expression *expr)
+{
+  if (dynamic_cast<model_memberref_forward *> (expr) != NULL)
+    {
+      model_memberref_forward *mem
+	= assert_cast<model_memberref_forward *> (expr);
+      expr = mem->get_real ();
+    }
+  if (dynamic_cast<model_field_ref *> (expr) == NULL)
+    return NULL;
+  model_field_ref *fref = assert_cast<model_field_ref *> (expr);
+  model_field *fld = fref->get_field ();
+  if (! fld->get_declaring_class ()->enum_p ())
+    return NULL;
+  model_expression *init_expr = fld->get_initializer ().get ();
+  if (! init_expr || ! dynamic_cast<model_new_enum *> (init_expr))
+    return NULL;
+  model_new_enum *nexpr = assert_cast<model_new_enum *> (init_expr);
+  return nexpr->get_enum_constant ();
+}
Index: conversions.hh
===================================================================
--- conversions.hh	(revision 107604)
+++ conversions.hh	(working copy)
@@ -109,4 +109,10 @@
 /// is used for checking whether annotation values are valid.
 bool annotation_commensurate_p (model_type *, model_expression *);
 
+/// Unwrap a reference to an enum constant.  The argument should be a
+/// fieldref to a field whose initializer is a 'new' of an enum
+/// constant type.  A forwarding reference is also permitted.  This
+/// returns NULL if the argument does not wrap an enum.
+model_enum_constant *unwrap_enum_constant (model_expression *);
+
 #endif // GCJX_CONVERSIONS_HH
Index: model/switch.cc
===================================================================
--- model/switch.cc	(revision 107604)
+++ model/switch.cc	(working copy)
@@ -1,6 +1,6 @@
 // switch statement.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -47,33 +47,13 @@
       jint val;
       if (is_enum)
 	{
-	  // An expression of enum type must be a fieldref to a field
-	  // whose initializer is a `new' of an enum constant type.
-	  // So, we unwrap it and check for errors at appropriate
-	  // places along the way.  Note that we don't fold the
-	  // expression in this branch.  The reason for this is that
-	  // we need to only accept class references, not other
-	  // things.
+	  // Note that we don't fold the expression in this branch.
+	  // The reason for this is that we need to only accept class
+	  // references, not other things.
 
-	  model_expression *wrap = (*i).get ();
-	  if (dynamic_cast<model_memberref_forward *> (wrap) == NULL)
+	  model_enum_constant *enumc = unwrap_enum_constant ((*i).get ());
+	  if (enumc == NULL)
 	    throw error ("case expression not enum constant");
-	  model_memberref_forward *mem
-	    = assert_cast<model_memberref_forward *> (wrap);
-	  if (dynamic_cast<model_field_ref *> (mem->get_real ()) == NULL)
-	    throw error ("case expression not enum constant");
-	  model_field_ref *fref
-	    = assert_cast<model_field_ref *> (mem->get_real ());
-	  model_field *fld = fref->get_field ();
-	  assert (fld->get_declaring_class ()->enum_p ());
-	  model_expression *init_expr = fld->get_initializer ().get ();
-	  if (! init_expr || ! dynamic_cast<model_new *> (init_expr))
-	    throw error ("case expression not enum constant");
-	  model_type *new_type = init_expr->type ();
-	  if (! dynamic_cast<model_enum_constant *> (new_type))
-	    throw error ("case expression not enum constant");
-	  model_enum_constant *enumc
-	    = assert_cast<model_enum_constant *> (new_type);
 	  val = enumc->get_ordinal ();
 	}
       else
Index: model/enum.cc
===================================================================
--- model/enum.cc	(revision 107604)
+++ model/enum.cc	(working copy)
@@ -98,10 +98,11 @@
     = new model_int_literal (new_constant->get_location (),
 			     jint (new_constant->get_ordinal ()));
 
-  model_class *what = (new_constant->has_body_p () ?
-		       (model_class *) new_constant.get ()
+  model_class *what = (new_constant->has_body_p ()
+		       ? (model_class *) new_constant.get ()
 		       : (model_class *) this);
-  ref_new init = new model_new_enum (new_constant->get_location (), what);
+  ref_new init = new model_new_enum (new_constant->get_location (), what,
+				     new_constant.get ());
   if (new_constant->has_body_p ())
     init->set_anonymous (new_constant);
 
Index: model/new.hh
===================================================================
--- model/new.hh	(revision 107604)
+++ model/new.hh	(working copy)
@@ -22,6 +22,8 @@
 #ifndef GCJX_MODEL_NEW_HH
 #define GCJX_MODEL_NEW_HH
 
+class model_enum_constant;
+
 class model_new : public model_invocation_base
 {
 protected:
@@ -132,6 +134,9 @@
 {
 protected:
 
+  /// The underlying enum constant.
+  model_enum_constant *enum_const;
+
   void check_instantiation (model_class *)
   {
     // Nothing.
@@ -139,10 +144,18 @@
 
 public:
 
-  model_new_enum (const location &w, model_type *t)
-    : model_new (w, t)
+  model_new_enum (const location &w, model_type *t,
+		  model_enum_constant *econst)
+    : model_new (w, t),
+      enum_const (econst)
   {
   }
+
+  /// Return the enum constant we initialize.
+  model_enum_constant *get_enum_constant () const
+  {
+    return enum_const;
+  }
 };
 
 /// These typedefs are used to represent 'new' expressions with


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]