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: cni header fixes


I'm checking this in on the gcjx branch.

This fixes some lingering bug in CNI header generation.
Now we reuse the AOT class wrapper vtable layout code, and generate
headers with Miranda methods properly in place.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* header/cni.cc (generate): Use aot class' vtable layout.
	(write_include): New method.
	(write_includes): Use it.  Added 'vtable' argument.
	* header/cni.hh (cni_code_generator::factory): New field.
	(cni_code_generator::write_include): Declare.
	(cni_code_generator::write_includes): Updated.

Index: header/cni.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/header/Attic/cni.cc,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 cni.cc
--- header/cni.cc 27 Apr 2005 17:30:40 -0000 1.1.2.8
+++ header/cni.cc 29 Apr 2005 02:56:32 -0000
@@ -21,6 +21,7 @@
 
 #include "typedefs.hh"
 #include "header/cni.hh"
+#include "aot/aotclass.hh"
 
 #include <fstream>
 
@@ -379,10 +380,24 @@
 }
 
 void
+cni_code_generator::write_include (std::ostream &out, model_class *klass)
+{
+  std::string cname = klass->get_fully_qualified_name ();
+  // Ugly...
+  for (unsigned int i = 0; i < cname.length (); ++i)
+    {
+      if (cname[i] == '.')
+	cname[i] = '/';
+    }
+  out << "#include <" << cname << ".h>" << std::endl;
+}
+
+void
 cni_code_generator::write_includes (std::ostream &out,
 				    model_class *klass,
 				    const method_iterator &methods_begin,
 				    const method_iterator &methods_end,
+				    const std::vector<model_method *> &vtable,
 				    const std::list<ref_field> &fields)
 {
   // These classes are chosen since they are already in 'compiler' and
@@ -400,21 +415,32 @@
   add (klass, class_set, array_seen, lang_package,
        util_package, io_package, super);
 
-  if (super)
+  write_include (out, super ? super : comp->java_lang_Object ());
+
+  // Add all our methods.
+  for (method_iterator i = methods_begin; i != methods_end; ++i)
     {
-      std::string cname = super->get_fully_qualified_name ();
-      // Ugly...
-      for (unsigned int i = 0; i < cname.length (); ++i)
-	{
-	  if (cname[i] == '.')
-	    cname[i] = '/';
-	}
-      out << "#include <" << cname
-	  << ".h>" << std::endl;
+      add ((*i)->get_return_type (), class_set, array_seen,
+	   lang_package, util_package, io_package, super);
+
+      std::list<ref_variable_decl> parms = (*i)->get_parameters ();
+      for (std::list<ref_variable_decl>::const_iterator j = parms.begin ();
+	   j != parms.end ();
+	   ++j)
+	add ((*j)->type (), class_set, array_seen,
+	     lang_package, util_package, io_package, super);
     }
 
-  for (method_iterator i = methods_begin; i != methods_end; ++i)
+  // Add information from Miranda methods.
+  for (std::vector<model_method *>::const_iterator i = vtable.begin ();
+       i != vtable.end ();
+       ++i)
     {
+      if ((*i)->get_declaring_class () != klass
+	  && ! (*i)->get_declaring_class ()->interface_p ())
+	continue;
+
+      // Ugly duplication here...
       add ((*i)->get_return_type (), class_set, array_seen,
 	   lang_package, util_package, io_package, super);
 
@@ -607,9 +633,18 @@
       << "#define " << cname << std::endl
       << std::endl;
 
+  // Get fields for future use.
   std::list<ref_field> fields = klass->get_fields ();
-  std::list<model_method *> methods = klass->get_sorted_methods ();
-  write_includes (out, klass, methods.begin (), methods.end (), fields);
+
+  // We share the vtable layout code with the runtime.  This ensures
+  // that the C++ compiler sees the same layout as gcj.
+  aot_class *aotk = factory.get_class (klass);
+  std::vector<model_method *> methods (aotk->get_vtable ());
+
+  // Emit all needed #includes and namespace declarations.
+  std::list<ref_method> local_methods = klass->get_methods ();
+  write_includes (out, klass, local_methods.begin (), local_methods.end (),
+		  methods, fields);
   out << std::endl;
 
   emit_actions (out, CNI_PREPEND, actions);
@@ -626,8 +661,9 @@
   modifier_t current_flags = ACC_ACCESS;
 
   std::set<std::string> method_names;
-  AllMethodsIterator end = klass->end_all_methods ();
-  for (AllMethodsIterator i = klass->begin_all_methods ();
+  std::set<model_method *> method_set;
+  std::vector<model_method *>::const_iterator end = methods.end ();
+  for (std::vector<model_method *>::const_iterator i = methods.begin ();
        i != end;
        ++i)
     {
@@ -640,8 +676,20 @@
       if ((*i)->get_declaring_class () != klass
 	  && ! (*i)->get_declaring_class ()->interface_p ())
 	continue;
-      write_method (out, (*i).get (), current_flags);
+      write_method (out, *i, current_flags);
       method_names.insert ((*i)->get_name ());
+      method_set.insert (*i);
+    }
+
+  // We have to make another pass to write out methods that don't
+  // appear in the vtable.
+  for (std::list<ref_method>::const_iterator i = local_methods.begin ();
+       i != local_methods.end ();
+       ++i)
+    {
+      if (method_set.find ((*i).get ()) == method_set.end ()
+	  && ! (*i)->static_initializer_p ())
+	write_method (out, (*i).get (), current_flags);
     }
 
   bool first = true;
Index: header/cni.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/header/Attic/cni.hh,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 cni.hh
--- header/cni.hh 17 Apr 2005 18:41:49 -0000 1.1.2.6
+++ header/cni.hh 29 Apr 2005 02:56:32 -0000
@@ -24,6 +24,7 @@
 
 #include "codegen.hh"
 #include "directory.hh"
+#include "aot/aotfactory.hh"
 
 class cni_code_generator : public code_generator
 {
@@ -41,7 +42,7 @@
 protected:
 
   // Handy typedefs.
-  typedef std::list<model_method *>::const_iterator method_iterator;
+  typedef std::list<ref_method>::const_iterator method_iterator;
   typedef std::list< std::pair<action, std::string> > action_item_list;
   typedef std::map<std::string, action_item_list> action_map_type;
 
@@ -57,14 +58,20 @@
   // True if we should emit headers for Object and Class.
   bool std_headers_ok;
 
+  // We use an AOT class factory to lay out the vtable for us.
+  aot_class_factory factory;
+
+
   bool keyword_p (const std::string &);
   std::string cxxname (model_type *, bool = true);
   void update_modifiers (std::ostream &, modifier_t, modifier_t &);
   void add (model_type *, std::set<model_class *> &,
 	    bool &, model_package *, model_package *,
 	    model_package *, model_class *);
+  void write_include (std::ostream &, model_class *);
   void write_includes (std::ostream &, model_class *,
 		       const method_iterator &, const method_iterator &,
+		       const std::vector<model_method *> &,
 		       const std::list<ref_field> &);
   void write_method (std::ostream &, model_method *, modifier_t &);
   void write_field (std::ostream &, model_field *, modifier_t &, bool &,


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