[gcjx] Patch: FYI: more annotations work
Tom Tromey
tromey@redhat.com
Sat Jan 22 07:56:00 GMT 2005
I'm checking this in on the gcjx branch.
This modifies how annotations are resolved, so that we don't get
incorrect circularity errors for meta-annotations.
It also fixes some bugs in reading and writing annotations.
Finally, there is an opportunistic fix for reading enums from class
files.
Annotations still can't really be tested as there is a circularity bug
when resolving a generic method in Enum.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* bytecode/classwriter.cc (write): Don't set ACC_SUPER for enum
classes.
* model/annotype.cc (element_compatible_p): Resolve members
before using annotation.
* bytecode/attribute.cc (emit_annotation_value): Write enum
constants.
* model/memberref.cc (resolve): New method.
(visit): New method.
* bytecode/classreader.cc (parse_parameter_annotations): Set
annotations on each parameter.
(parse_annotation_value): Create a model_memberref_enum.
(parse_self): Correctly handle ACC_SUPER when ACC_ENUM is set.
* model/memberref.hh (class model_memberref_base): New class.
(class model_memberref_forward): Derive from
model_memberref_base.
* model/variable.cc (resolve_classes): Use
resolve_annotation_classes.
(resolve): Call resolve_annotations.
* model/method.cc (resolve_classes): Use
resolve_annotation_classes.
(resolve): Call resolve_annotations.
* model/class.cc (do_resolve_classes): Use
resolve_annotation_classes.
(resolve_members): Call resolve_annotations.
* model/iannotatable.cc (resolve_annotation_classes): New method.
* model/iannotatable.hh (IAnnotatable::resolve_annotation_classes):
Declare.
* model/annotation.cc (resolve_classes): New method.
(resolve): Don't resolve 'name'.
* model/annotation.hh (model_annotation::resolve): Documented.
(model_annotation::resolve_classes): Declare.
Index: bytecode/attribute.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/attribute.cc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 attribute.cc
--- bytecode/attribute.cc 19 Jan 2005 00:00:42 -0000 1.1.2.3
+++ bytecode/attribute.cc 22 Jan 2005 07:50:44 -0000
@@ -292,9 +292,25 @@
}
else
{
- // The only remaining case is an enum constant.
- // FIXME: unwrap the member ref and write it.
- abort ();
+ model_memberref_forward *b
+ = assert_cast<model_memberref_forward *> (expr);
+ expr = b->get_real ();
+ model_field_ref *fr = assert_cast<model_field_ref *> (expr);
+ model_field *fld = fr->get_field ();
+
+ // FIXME: what about inner classes here?
+ int type_index
+ = pool->add_utf (fld->get_declaring_class ()->get_descriptor ());
+ int name_index = pool->add_utf (fld->get_name ());
+
+ if (writer)
+ {
+ writer->put ('e');
+ writer->put2 (type_index);
+ writer->put2 (name_index);
+ }
+
+ result += 5;
}
return result;
Index: bytecode/classreader.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/classreader.cc,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 classreader.cc
--- bytecode/classreader.cc 19 Jan 2005 19:49:11 -0000 1.1.2.5
+++ bytecode/classreader.cc 22 Jan 2005 07:50:45 -0000
@@ -160,8 +160,7 @@
ref_forwarding_type base = parse_field_descriptor (index);
uint16 fn_index = read_u2 ();
field_name = pool->get_utf8 (fn_index);
- // FIXME.
-// val = new model_enum_field_ref (where, base, field_name);
+ val = new model_memberref_enum (where, base, field_name);
}
break;
@@ -239,9 +238,9 @@
{
std::list<ref_annotation> annotations;
uint16 length = read_u2 ();
- for (uint16 i = 0; i < length; ++i)
+ for (uint16 j = 0; j < length; ++j)
annotations.push_back (parse_annotation ());
- // FIXME: do something with result
+ (*i)->set_annotations (annotations);
}
}
@@ -930,7 +929,12 @@
result->set_superclass (super);
}
- must_set |= ACC_SUPER;
+ // ACC_SUPER doesn't make sense for enums, but is required for
+ // ordinary classes.
+ if ((access_flags & ACC_ENUM) == 0)
+ must_set |= ACC_SUPER;
+ else
+ must_not_set |= ACC_SUPER;
must_not_set |= ACC_ANNOTATION;
if ((access_flags & ACC_ABSTRACT) != 0
Index: bytecode/classwriter.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/classwriter.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 classwriter.cc
--- bytecode/classwriter.cc 17 Jan 2005 00:05:04 -0000 1.1.2.2
+++ bytecode/classwriter.cc 22 Jan 2005 07:50:45 -0000
@@ -319,7 +319,7 @@
// only valid values are public and package-private.
if ((mods & ACC_ACCESS) != 0 && (mods & ACC_ACCESS) != ACC_PUBLIC)
mods &= ~ACC_ACCESS;
- if (! the_class->interface_p ())
+ if (! the_class->interface_p () && ! the_class->enum_p ())
{
// This should be set by all modern compilers.
mods |= ACC_SUPER;
Index: model/annotation.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/annotation.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 annotation.cc
--- model/annotation.cc 13 Jan 2005 03:18:35 -0000 1.1.2.1
+++ model/annotation.cc 22 Jan 2005 07:50:45 -0000
@@ -1,6 +1,6 @@
// Represent an annotation.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -22,10 +22,20 @@
#include "typedefs.hh"
void
-model_annotation::resolve (resolution_scope *scope)
+model_annotation::resolve_classes (resolution_scope *scope)
{
+ // FIXME: Resolution methods seem backwards on
+ // model_forwarding_type.
name->resolve (scope);
+ // The reason we call set_type() here is that we need to know the
+ // annotation's type when handling SuppressWarnings. This is
+ // moderately ugly.
+ set_type (name->type ());
+}
+void
+model_annotation::resolve (resolution_scope *scope)
+{
if (! name->type ()->annotation_p ())
throw name->error ("type %1 isn't an annotation type")
% name;
@@ -35,8 +45,6 @@
::resolve (scope, args);
anno_type->check_completeness (args, this);
-
- set_type (anno_type);
}
void
Index: model/annotation.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/annotation.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 annotation.hh
--- model/annotation.hh 13 Jan 2005 03:18:35 -0000 1.1.2.1
+++ model/annotation.hh 22 Jan 2005 07:50:45 -0000
@@ -1,6 +1,6 @@
// Represent an annotation.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -72,6 +72,13 @@
{
}
+ /// Resolve the "envelope" of this annotation. This simply means
+ /// that the type of the annotation is determined.
+ void resolve_classes (resolution_scope *);
+
+ /// Fully resolve the annotation. resolve_classes must have been
+ /// called first. This will resolve all the arguments and then do
+ /// error checking.
void resolve (resolution_scope *);
void visit (visitor *);
Index: model/annotype.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/annotype.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 annotype.cc
--- model/annotype.cc 19 Jan 2005 19:49:11 -0000 1.1.2.2
+++ model/annotype.cc 22 Jan 2005 07:50:45 -0000
@@ -136,6 +136,10 @@
}
else
{
+ // Make sure the (meta-)annotation expressions are all
+ // resolved at this point.
+ resolve_members ();
+
model_annotation_value *val = targ->find_annotation ("value");
assert (val);
model_expression *expr = val->get_value ();
@@ -153,8 +157,8 @@
++i)
{
model_expression *e = (*i).get ();
- model_memberref_forward *b
- = assert_cast<model_memberref_forward *> (e);
+ model_memberref_base *b
+ = assert_cast<model_memberref_base *> (e);
e = b->get_real ();
model_field_ref *fr = assert_cast<model_field_ref *> (e);
Index: model/class.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/class.cc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 class.cc
--- model/class.cc 19 Jan 2005 02:11:07 -0000 1.1.2.3
+++ model/class.cc 22 Jan 2005 07:50:46 -0000
@@ -1059,7 +1059,7 @@
resolve_hook (scope);
- resolve_annotations (scope);
+ resolve_annotation_classes (scope);
// Put the type parameters in scope. Note that we don't resolve
// them here, as that can lead to false circularity reports.
@@ -1307,6 +1307,8 @@
if (! superclass && ! interface)
compute_object_interface_methods ();
+ resolve_annotations (scope);
+
// Let the subclass modify behavior a little. This must come after
// compute_object_interface_methods().
resolve_member_hook (scope);
Index: model/iannotatable.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/iannotatable.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 iannotatable.cc
--- model/iannotatable.cc 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/iannotatable.cc 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Represent an annotatable object.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -35,6 +35,12 @@
}
void
+IAnnotatable::resolve_annotation_classes (resolution_scope *scope)
+{
+ ::resolve_classes (scope, annotations);
+}
+
+void
IAnnotatable::resolve_annotations (resolution_scope *scope)
{
::resolve (scope, annotations);
Index: model/iannotatable.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/iannotatable.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 iannotatable.hh
--- model/iannotatable.hh 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/iannotatable.hh 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Represent an annotatable object.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -45,6 +45,9 @@
virtual annotation_kind get_annotation_kind () const = 0;
+ /// Resolve the envelope of the annotations.
+ void resolve_annotation_classes (resolution_scope *);
+
/// Subclasses should call this when they are resolved in order to
/// resolve their annotations as well.
void resolve_annotations (resolution_scope *);
Index: model/memberref.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/memberref.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 memberref.cc
--- model/memberref.cc 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/memberref.cc 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Member references.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -50,3 +50,35 @@
real->resolve (scope);
set_type (real->type ());
}
+
+void
+model_memberref_enum::resolve (resolution_scope *scope)
+{
+ base_type->resolve (scope);
+ if (! base_type->type ()->enum_p ())
+ throw error ("type %1 not an %<enum%>") % base_type->type ();
+
+ model_class *klass = assert_cast<model_class *> (base_type->type ());
+ std::set<model_field *> result;
+ klass->find_members (field_name, result, scope->get_current_class (), NULL);
+ if (result.empty ())
+ throw error ("no %<enum%> constant named %1 in %2")
+ % field_name % klass;
+ else if (result.size () > 1)
+ throw error ("ambiguous reference to %<enum%> constant named %1 in %2")
+ % field_name % klass;
+
+ ref_field_ref rf = new model_field_ref (get_location ());
+ rf->set_field (field_name);
+ rf->set_field (*(result.begin ()));
+
+ real = rf;
+ set_type (klass);
+}
+
+void
+model_memberref_enum::visit (visitor *)
+{
+ // Not needed.
+ abort ();
+}
Index: model/memberref.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/memberref.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 memberref.hh
--- model/memberref.hh 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/memberref.hh 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Member references.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -22,19 +22,39 @@
#ifndef GCJX_MODEL_MEMBERREF_HH
#define GCJX_MODEL_MEMBERREF_HH
-// When parsing something like "a.b.c.d" or "a.b.c.d()", we won't know
-// until the analysis phase what we're looking at. For instance, "a"
-// might be a variable or a type, and likewise for the other elements.
-// This class represents an undetermined expression like the above.
-// It can also represent a simple variable reference.
-class model_memberref_forward : public model_expression
+/// The base class for all kinds of deferred member references.
+class model_memberref_base : public model_expression
{
- // The unresolved identifier sequence.
- std::list<std::string> ids;
+protected:
// The member reference to which we forward requests.
ref_expression real;
+ model_memberref_base (const location &w)
+ : model_expression (w)
+ {
+ }
+
+public:
+
+ // This is sort of ugly, see unary.cc to see its use.
+ // FIXME.
+ model_expression *get_real ()
+ {
+ return real.get ();
+ }
+};
+
+/// When parsing something like "a.b.c.d" or "a.b.c.d()", we won't know
+/// until the analysis phase what we're looking at. For instance, "a"
+/// might be a variable or a type, and likewise for the other elements.
+/// This class represents an undetermined expression like the above.
+/// It can also represent a simple variable reference.
+class model_memberref_forward : public model_memberref_base
+{
+ // The unresolved identifier sequence.
+ std::list<std::string> ids;
+
// True if a method call.
bool is_call;
@@ -55,7 +75,7 @@
// This constructor is used by the generic template subclass.
model_memberref_forward (const location &w)
- : model_expression (w),
+ : model_memberref_base (w),
is_call (false),
is_lhs (false),
is_compound (false)
@@ -65,7 +85,7 @@
public:
model_memberref_forward (const location &w, const std::list<std::string> &l)
- : model_expression (w),
+ : model_memberref_base (w),
ids (l),
is_call (false),
is_lhs (false),
@@ -101,13 +121,6 @@
return real->string_value ();
}
- // This is sort of ugly, see unary.cc to see its use.
- // FIXME.
- model_expression *get_real ()
- {
- return real.get ();
- }
-
/// Return true if this is a reference to a method call.
bool call_p () const
{
@@ -121,4 +134,35 @@
}
};
+/// This form of a deferred member reference is used only when reading
+/// an enum constant reference from a class file.
+class model_memberref_enum : public model_memberref_base
+{
+ // The enum class.
+ ref_forwarding_type base_type;
+
+ // The name of the enum constant.
+ std::string field_name;
+
+ bool compute_constant_p ()
+ {
+ return false;
+ }
+
+public:
+
+ model_memberref_enum (const location &w,
+ const ref_forwarding_type &base,
+ const std::string &fn)
+ : model_memberref_base (w),
+ base_type (base),
+ field_name (fn)
+ {
+ }
+
+ void resolve (resolution_scope *);
+
+ void visit (visitor *);
+};
+
#endif // GCJX_MODEL_MEMBERREF_HH
Index: model/method.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/method.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 method.cc
--- model/method.cc 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/method.cc 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Methods.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -536,6 +536,8 @@
void
model_method::resolve (resolution_scope *scope)
{
+ resolve_annotations (scope);
+
resolution_scope::push_warnings warn_holder (scope, this);
// Push the type parameters.
@@ -618,7 +620,7 @@
{
// Resolve annotations here since they seem like part of the
// envelope.
- resolve_annotations (scope);
+ resolve_annotation_classes (scope);
resolution_scope::push_warnings warn_holder (scope, this);
Index: model/variable.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/variable.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 variable.cc
--- model/variable.cc 13 Jan 2005 03:18:36 -0000 1.1.2.1
+++ model/variable.cc 22 Jan 2005 07:50:46 -0000
@@ -1,6 +1,6 @@
// Represent a variable.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -25,12 +25,13 @@
model_variable_decl::resolve_classes (resolution_scope *scope)
{
decltype->resolve (scope);
- resolve_annotations (scope);
+ resolve_annotation_classes (scope);
}
void
model_variable_decl::resolve (resolution_scope *scope)
{
+ resolve_annotations (scope);
decltype->resolve (scope); // fixme redundant for fields...
if (initializer)
{
More information about the Java-patches
mailing list